Table

Basic Example


<vega-table show-header="false"></vega-table>
 

const table = document.querySelector('vega-table');
			table.columns = [
        {
          label: 'Date',
          prop: 'date',
        },
        {
          label: 'Amount',
          prop: 'amount',
        },
        {
          label: 'Balance',
          prop: 'balance',
        },
      ];

			table.dataSource =  [
        {
          key: '1',
          date: '01/01/2022',
          amount: 100,
          balance: '$100',
          status: 'In Progress',
        },
        {
          key: '2',
          date: '01/02/2022',
          amount: 300,
          balance: '$200',
          status: 'In Progress',
        },
        {
          key: '3',
          date: '01/03/2022',
          amount: 400,
          balance: '$300',
          status: 'Not Started',
        },
        {
          key: '4',
          date: '01/04/2022',
          amount: 200,
          balance: '$400',
          status: 'Pending',
        },
      ];

Basic Example with Template


<vega-table id="basic-table-template">
  <vega-table-head>
    <vega-table-head-row>
      <vega-table-head-cell>
        Date
      </vega-table-head-cell>
      <vega-table-head-cell>
        Amount
      </vega-table-head-cell>
      <vega-table-head-cell text-align="right">
        Balance
      </vega-table-head-cell>
    </vega-table-head-row>
  </vega-table-head>
  <vega-table-body>
    <vega-table-row row-key="1">
      <vega-table-cell>
        01/01/2022
      </vega-table-cell>
      <vega-table-cell>
        100
      </vega-table-cell>
      <vega-table-cell text-align="right">
        100
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="2">
      <vega-table-cell>
        01/02/2022
      </vega-table-cell>
      <vega-table-cell>
        300
      </vega-table-cell>
      <vega-table-cell text-align="right">
        200
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="3">
      <vega-table-cell>
        01/03/2022
      </vega-table-cell>
      <vega-table-cell>
        400
      </vega-table-cell>
      <vega-table-cell text-align="right">
        300
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="4">
      <vega-table-cell>
        01/04/2022
      </vega-table-cell>
      <vega-table-cell>
        200
      </vega-table-cell>
      <vega-table-cell text-align="right">
        400
      </vega-table-cell>
    </vega-table-row>
  </vega-table-body>
</vega-table>

Example with Custom Columns

To render a custom table cell use the following:

render: (createElement: VegaTableCreateElementFunction, value: string, record: VegaTableDataSourceItem) => {}


<vega-table></vega-table>
 

const table = document.querySelector('vega-table');
			table.columns = [
        {
          label: 'Date',
          prop: 'date',
        },
        {
          label: 'Amount',
          prop: 'amount',
        },
        {
          label: 'Balance',
          prop: 'balance',
        },
        {
          label: 'Status',
          prop: 'status',
          render: (createElement, value) => {
            let bgColor;
            let textColor;
            switch (value) {
                case 'In Progress':
                    bgColor = 'bg-accent5-secondary';
                    textColor = 'text-primary';
                    break;
                case 'Pending':
                    bgColor = 'bg-status-warning';
                    textColor = 'text-black';
                    break;
                default:
                    bgColor = 'bg-brand';
                    textColor = 'text-inverted-primary';
            }
            return createElement('vega-badge', { size: 'small', text: value, bgColor: bgColor, textColor: textColor });
         },
        },
        {
        label: 'Action',
        render: (createElement, value, record) => {
            return createElement(
                'vega-flex',
                {
                    gap: 'size-8',
                },
                [
                    createElement(
                        'vega-button',
                        {
                            'data-shrink': 0,
                            'size': 'small',
                            'onVegaClick': () => {
                                alert(`Row [Key: ${value}] - Edit button click`);
                            },
                        },
                        'Edit',
                    ),
                    createElement(
                        'vega-button',
                        {
                            'data-shrink': 0,
                            'size': 'small',
                            'danger': true,
                            'onVegaClick': () => {
                                alert(`Row [Key: ${value}, Date: ${record['date']}] - Delete button click`);
                            },
                        },
                        'Delete',
                    ),
                ],
            );
        },
      },
      ];

			table.dataSource =  [
        {
          key: '1',
          date: '01/01/2022',
          amount: 100,
          balance: '$100',
          status: 'In Progress',
        },
        {
          key: '2',
          date: '01/02/2022',
          amount: 300,
          balance: '$200',
          status: 'In Progress',
        },
        {
          key: '3',
          date: '01/03/2022',
          amount: 400,
          balance: '$300',
          status: 'Not Started',
        },
        {
          key: '4',
          date: '01/04/2022',
          amount: 200,
          balance: '$400',
          status: 'Pending',
        },
      

      ];

Custom Column with Template

<vega-table id="table-with-actions">
  <vega-table-head>
    <vega-table-head-row>
      <vega-table-head-cell>
        Date
      </vega-table-head-cell>
      <vega-table-head-cell>
        Amount
      </vega-table-head-cell>
      <vega-table-head-cell>
        Balance
      </vega-table-head-cell>
      <vega-table-head-cell>
        Status
      </vega-table-head-cell>
      <vega-table-head-cell>
        Action
      </vega-table-head-cell>
    </vega-table-head-row>
  </vega-table-head>
  <vega-table-body>
    <vega-table-row row-key="1">
      <vega-table-cell>
        01/01/2022
      </vega-table-cell>
      <vega-table-cell>
        100
      </vega-table-cell>
      <vega-table-cell>
        100
      </vega-table-cell>
      <vega-table-cell>
        <vega-chip
          bg-color="bg-status-warning"
          size="small"
          text="In Progress"
          text-color="text-black"
        />
      </vega-table-cell>
      <vega-table-cell>
        <vega-flex gap="size-4">
          <vega-button-circle
            icon="edit-line"
            size="small"
            variant="icon-only"
          />
          <vega-button-circle
            danger
            icon="delete-bin"
            size="small"
            variant="icon-only"
          />
        </vega-flex>
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="2">
      <vega-table-cell>
        01/02/2022
      </vega-table-cell>
      <vega-table-cell>
        300
      </vega-table-cell>
      <vega-table-cell>
        200
      </vega-table-cell>
      <vega-table-cell>
        <vega-chip
          bg-color="bg-status-warning"
          size="small"
          text="In Progress"
          text-color="text-black"
        />
      </vega-table-cell>
      <vega-table-cell>
        <vega-flex gap="size-4">
          <vega-button-circle
            icon="edit-line"
            size="small"
            variant="icon-only"
          />
          <vega-button-circle
            danger
            icon="delete-bin"
            size="small"
            variant="icon-only"
          />
        </vega-flex>
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="3">
      <vega-table-cell>
        01/03/2022
      </vega-table-cell>
      <vega-table-cell>
        400
      </vega-table-cell>
      <vega-table-cell>
        300
      </vega-table-cell>
      <vega-table-cell>
        <vega-chip
          bg-color="bg-accent5-secondary"
          size="small"
          text="To Do"
          text-color="text-primary"
        />
      </vega-table-cell>
      <vega-table-cell>
        <vega-flex gap="size-4">
          <vega-button-circle
            icon="edit-line"
            size="small"
            variant="icon-only"
          />
          <vega-button-circle
            danger
            icon="delete-bin"
            size="small"
            variant="icon-only"
          />
        </vega-flex>
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="4">
      <vega-table-cell>
        01/04/2022
      </vega-table-cell>
      <vega-table-cell>
        200
      </vega-table-cell>
      <vega-table-cell>
        400
      </vega-table-cell>
      <vega-table-cell>
        <vega-chip
          bg-color="bg-brand"
          size="small"
          text="Done"
          text-color="text-inverted-primary"
        />
      </vega-table-cell>
      <vega-table-cell>
        <vega-flex gap="size-4">
          <vega-button-circle
            icon="edit-line"
            size="small"
            variant="icon-only"
          />
          <vega-button-circle
            danger
            icon="delete-bin"
            size="small"
            variant="icon-only"
          />
        </vega-flex>
      </vega-table-cell>
    </vega-table-row>
  </vega-table-body>
</vega-table>

Examples with Selection

You can make rows selectable by setting table.rowSelection.

To make a single row selectable, set table.rowSelection = { type: 'single' }.

To make mutliple rows selectable, set table.rowSelection = { type: 'multiple' }

Single Row Selection Example


<vega-table id="table-with-single-row-selection"></vega-table>

const mockDataSource = (total = 100) => {
		const data = [];
		for (let i = 0; i < total; i++) {
			const amount = 100 + i;
			data.push({
				key: i.toString(),
				date: '01/01/2022',
				amount: amount,
				balance: amount * 2,
				status: 1,
				desc: 'Test text description',
			});
		}
		return data;
	};
    const dataSource = mockDataSource(10);
    const table = document.querySelector('#table-with-single-row-selection');
    table.columns = [
      {
        label: 'Date',
        prop: 'date',
      },
      {
        label: 'Amount',
        prop: 'amount',
      },
      {
        label: 'Balance',
        prop: 'balance',
    	},
    ];
    table.dataSource = dataSource;
    table.rowSelection = { type: 'single' };
    table.setSelection([dataSource[0].key]);

Multiple Row Selection Example


<vega-table id="table-with-multiple-row-selection"></vega-table>

const mockDataSource = (total = 100) => {
		const data = [];
		for (let i = 0; i < total; i++) {
			const amount = 100 + i;
			data.push({
				key: i.toString(),
				date: '01/01/2022',
				amount: amount,
				balance: amount * 2,
				status: 1,
				desc: 'Test text description',
			});
		}
		return data;
	};
    const dataSource = mockDataSource(10);
    const table = document.querySelector('#table-with-multiple-row-selection');
    table.columns = [
      {
        label: 'Date',
        prop: 'date',
      },
      {
        label: 'Amount',
        prop: 'amount',
      },
      {
        label: 'Balance',
        prop: 'balance',
    	},
    ];
    table.dataSource = dataSource;
    table.rowSelection = { type: 'multiple' };
    table.setSelection([dataSource[0].key]);

Selection with Template


			<vega-flex gap="size-12" class="v-mb-size-12">
				<vega-button class="vega-flex-shrink-0 v-min-w-min" size="small" id="clearSelection">
					Clear Selection
				</vega-button>
			</vega-flex>
			<vega-table id="table-with-selection">
				<vega-table-head>
					<vega-table-head-row>
						<vega-table-head-cell>Date</vega-table-head-cell>
						<vega-table-head-cell>Amount</vega-table-head-cell>
						<vega-table-head-cell>Balance</vega-table-head-cell>
					</vega-table-head-row>
				</vega-table-head>
				<vega-table-body>

						<vega-table-row row-key=1>
							<vega-table-cell>01/01/2022</vega-table-cell>
							<vega-table-cell>100</vega-table-cell>
							<vega-table-cell>100</vega-table-cell>
						</vega-table-row>

            <vega-table-row row-key=2>
							<vega-table-cell>01/02/2022</vega-table-cell>
							<vega-table-cell>300</vega-table-cell>
							<vega-table-cell>200</vega-table-cell>
						</vega-table-row>

            <vega-table-row row-key=3>
							<vega-table-cell>01/03/2022</vega-table-cell>
							<vega-table-cell>400</vega-table-cell>
							<vega-table-cell>300</vega-table-cell>
						</vega-table-row>

				</vega-table-body>
			</vega-table>
      <div class="v-bg-primary v-text-primary">
			<div class="v-mt-size-12">
				<div class="v-font-field-label v-text-success v-mb-size-8">onVegaSelectChange:</div>
				<div class="v-font-field-label">
					Record:
					<span class="v-px-size-8" id="selectedRowRecords"></span>
				</div>
				<div class="v-font-field-label">
					Selected:
					<span class="v-px-size-8" id="isSelected"></span>
				</div>
				<div class="v-font-field-label">
					selectedRows:
					<span class="v-px-size-8" id="selectedRows"></span>
				</div>
			</div>
			<div class="v-mt-size-12">
				<div class="v-font-field-label v-text-success v-mb-size-8">onVegaSelectAllChange:</div>
				<div class="v-font-field-label">
					All Selected:
					<span class="v-px-size-8" id="selectedAll-selected"></span>
				</div>
				<div class="v-font-field-label">
					selectedRows:
					<span class="v-px-size-8" id="selectedAll-selectedRows"></span>
				</div>
			</div>
      </div>
	

	setTimeout(() => {
		const tableWithSelection = document.getElementById('table-with-selection');
		tableWithSelection.rowSelection = { type: 'multiple' };
		tableWithSelection.addEventListener('vegaSelectChange', e => {
			document.getElementById('selectedRows').innerText = JSON.stringify(
				e.detail.selectedRows.map(item => item['key']),
			);
			document.getElementById('selectedRowRecords').innerText = JSON.stringify(e.detail.record);
			document.getElementById('isSelected').innerText = e.detail.selected;
		});
		tableWithSelection.addEventListener('vegaSelectAllChange', e => {
			document.getElementById('selectedAll-selected').innerText = e.detail.selected;
			document.getElementById('selectedAll-selectedRows').innerText = JSON.stringify(
				e.detail.selectedRows,
			);
		});
		document.querySelector('#clearSelection').addEventListener('vegaClick', () => {
			tableWithSelection.clearSelection();
		});
	});

Expandable Row Example

To make rows expandable, set rowExpandable: true, mark the vega-table-expand-row-${rowKey} for each expandable row slot so that rowKey is equal to dataSource[i].key or the primary rowKey of dataSource.

<vega-table row-expandable="true" id="table-with-expandable-row">
</vega-table>
const table = document.querySelector('#table-with-expandable-row');
table.columns = [
{
        label: 'Date',
        prop: 'date'
      },
      {
        label: 'Amount',
        prop: 'amount',
      },
      {
        label: 'Balance',
        prop: 'balance'
      },
      { 
        label: 'Action',
        render: (createElement, value, record) => {
						return createElement(
							'vega-button',
							{
								'data-shrink': 0,
								'icon': 'chevron-down',
								'size': 'small',
								'onVegaClick': () => {
									table.toggleExpandRow(record.key);
								},
							},
							'Detail',
						);
					},

      }
];
table.dataSource = [
     {
          amount: 100,
          balance: '$100',
          date: '01/01/2022',
          key: '1',
          status: 'In Progress'
        },
        {
          amount: 300,
          balance: '$200',
          date: '01/02/2022',
          key: '2',
          status: 'In Progress'
        },
        {
          amount: 400,
          balance: '$300',
          date: '01/03/2022',
          key: '3',
          status: 'Not Started'
        },
        {
          amount: 200,
          balance: '$400',
          date: '01/04/2022',
          key: '4',
          status: 'Pending'
        }
];
   const expandRows = table.dataSource.map((item) => {
      const rowKey = item.key;
      const slotDiv = document.createElement('div');
      slotDiv.setAttribute('slot', `vega-table-expand-row-${item.key}`);
      slotDiv.innerHTML = `<div class="v-text-primary v-font-p2-short v-p-size-24" key="slot-${rowKey}">
            <h2>Detail</h2>
            <div>
              <p>This is some example text, to demonstrate how content is displayed in the details.  Incidentally this is associated with key ${item['key']}.
            </div>

            <div>Status: ${item['status']}</div>
          </div>`
      return slotDiv;
    });
    table.append(...expandRows);
    

Expandable Row using Template


<vega-table id="table-with-expandable-row" row-expandable="true">
    <vega-table-head>
        <vega-table-head-row>
            <vega-table-head-cell>Date</vega-table-head-cell>
            <vega-table-head-cell>Amount</vega-table-head-cell>
            <vega-table-head-cell>Balance</vega-table-head-cell>
        </vega-table-head-row>
    </vega-table-head>
    <vega-table-body>
        <vega-table-row row-key="1">
            <vega-table-cell>01/01/2022</vega-table-cell>
            <vega-table-cell>100</vega-table-cell>
            <vega-table-cell>$100</vega-table-cell>
        </vega-table-row>
        <vega-table-expand-row row-key="1">
            <div class="v-px-size-12 v-py-size-24 v-text-primary">
                <div class="v-font-h3 v-mb-size-8">Detail</div>
                <vega-grid column="4">
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Date</div>
                        <div class="v-font-field-value">01/01/2022</div>
                    </vega-flex>
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Amount</div>
                        <div class="v-font-field-value">100</div>
                    </vega-flex>
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Balance</div>
                        <div class="v-font-field-value">$100</div>
                    </vega-flex>
                </vega-grid>
            </div>
        </vega-table-expand-row>
        <vega-table-row row-key="2">
            <vega-table-cell>01/01/2022</vega-table-cell>
            <vega-table-cell>100</vega-table-cell>
            <vega-table-cell>$100</vega-table-cell>
        </vega-table-row>
        <vega-table-expand-row row-key="2">
            <div class="v-px-size-12 v-py-size-24 v-text-primary">
                <div class="v-font-h3 v-mb-size-8">Detail</div>
                <vega-grid column="4">
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Date</div>
                        <div class="v-font-field-value">01/01/2022</div>
                    </vega-flex>
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Amount</div>
                        <div class="v-font-field-value">100</div>
                    </vega-flex>
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Balance</div>
                        <div class="v-font-field-value">$100</div>
                    </vega-flex>
                </vega-grid>
            </div>
        </vega-table-expand-row>
        <vega-table-row row-key="3">
            <vega-table-cell>01/01/2022</vega-table-cell>
            <vega-table-cell>100</vega-table-cell>
            <vega-table-cell>$100</vega-table-cell>
        </vega-table-row>
        <vega-table-expand-row row-key="3">
            <div class="v-px-size-12 v-py-size-24 v-text-primary">
                <div class="v-font-h3 v-mb-size-8">Detail</div>
                <vega-grid column="4">
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Date</div>
                        <div class="v-font-field-value">01/01/2022</div>
                    </vega-flex>
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Amount</div>
                        <div class="v-font-field-value">100</div>
                    </vega-flex>
                    <vega-flex use-native-flex="true" direction="col">
                        <div class="v-font-field-label">Balance</div>
                        <div class="v-font-field-value">$100</div>
                    </vega-flex>
                </vega-grid>
            </div>
        </vega-table-expand-row>
    </vega-table-body>
</vega-table>

Clickable Row Example

To make a row clickable, set the rowClickable property. Clicking anywhere on the row will trigger a click event.

<vega-table 
  row-clickable="true" 
  id="table-with-clickable-row">
</vega-table>

		<div class="v-bg-primary v-text-primary">
			<p class="v-font-h4 ">Try to click a row</p>
			
			<div>
				<label class="v-font-field-label">Clicked Row Record:</label>
				<p id="clicked-row-record"></p>
				<label class="v-font-field-label">Clicked Row Index:</label>
				<p id="clicked-row-index"></p>
			</div>
			<vega-modal id="table-row-detail-modal">Test</vega-modal>
		</div>
const table = document.querySelector('#table-with-clickable-row');
			table.columns = [
          {
          label: 'Date',
          prop: 'date'
        },
        {
          label: 'Amount',
          prop: 'amount'
        },
        {
          label: 'Balance',
          prop: 'balance'
        },
      ];

			table.dataSource =  [
        {
          key: '1',
          date: '01/01/2022',
          amount: 100,
          balance: '$100',
          status: 'In Progress',
        },
        {
          key: '2',
          date: '01/02/2022',
          amount: 300,
          balance: '$200',
          status: 'In Progress',
        },
        {
          key: '3',
          date: '01/03/2022',
          amount: 400,
          balance: '$300',
          status: 'Not Started',
        },
        {
          key: '4',
          date: '01/04/2022',
          amount: 200,
          balance: '$400',
          status: 'Pending',
        },
      ];


setTimeout(() => {
		const tableRowClickableTemplate = document.querySelector('#table-with-clickable-row');
		table.addEventListener('vegaRowClick', e => {
			document.querySelector('#clicked-row-record').innerHTML = JSON.stringify(e.detail.record);
			document.querySelector('#clicked-row-index').innerHTML = e.detail.index;
		});
	});


Clickable Row with Template

		<vega-table id="table-row-clickable-template" row-clickable="true">
			<vega-table-head>
				<vega-table-head-row>
					<vega-table-head-cell>Date</vega-table-head-cell>
					<vega-table-head-cell>Amount</vega-table-head-cell>
					<vega-table-head-cell>Balance</vega-table-head-cell>
				</vega-table-head-row>
			</vega-table-head>
			<vega-table-body>

			</vega-table-body>
		</vega-table>
		<div class="v-mt-size-12 v-bg-primary v-text-primary">
			<label class="v-font-field-label">Clicked Row Record:</label>
			<pre id="clicked-row-record"></pre>
			<label class="v-font-field-label">Clicked Row Index:</label>
			<p id="clicked-row-index"></p>
		</div>

  const dataSource = [
        {
          key: '1',
          name: 'Jon Snow',
          date: '01/01/2022',
          amount: 100,
          balance: 100,
          status: 1,
          desc: 'Test text description',
          address: 'New_York_No._1_Lake_Park',
          time: '23:35',
        },
        {
          key: '2',
          name: 'Jeremiah Graham',
          date: '01/02/2022',
          amount: 300,
          balance: 200,
          status: 1,
          desc: 'Test text description Test text description',
          address: 'New York No. 2 Lake Park',
          time: '12:00',
        },
        {
          key: '3',
          name: 'Jaime Stark',
          date: '01/03/2022',
          amount: 400,
          balance: 300,
          status: 0,
          desc: 'Test text description Test text description Test text description',
          address: 'New York No. 3 Lake Park',
        },
			];
      function renderData(dataSource) {
        document.querySelector("vega-table-body").innerHTML = dataSource
          .map((item) => {
            return `<vega-table-row row-key='${item.key}'>
						<vega-table-cell>${item.date}</vega-table-cell>
						<vega-table-cell>${item.amount}</vega-table-cell>
						<vega-table-cell>${item.balance}</vega-table-cell>
					</vega-table-row>`;
          })
          .join("");
      }

      renderData(dataSource);

			document.querySelectorAll('vega-table-row').forEach((row, index) => {
				row.addEventListener('vegaClick', () => {
          document.querySelector('#clicked-row-record').innerHTML = JSON.stringify(dataSource[index], null, 2);
					document.querySelector('#clicked-row-index').innerHTML = index;
				});
			});

Sortable Row Example


<vega-table id="vega-table-js-example"></vega-table>

const table = document.getElementById('vega-table-js-example');
table.columns = [
          {
          label: 'Date',
          prop: 'date'
        },
        {
          label: 'Amount',
          prop: 'amount',
          sorter: (a, b) => {
            return a.amount - b.amount;
          }  
          
        },
        {
          label: 'Balance',
          prop: 'balance',
        },
      ];

			table.dataSource =  [
        {
          key: '1',
          date: '01/01/2022',
          amount: 100,
          balance: '$100',
          status: 'In Progress',
        },
        {
          key: '2',
          date: '01/02/2022',
          amount: 300,
          balance: '$200',
          status: 'In Progress',
        },
        {
          key: '3',
          date: '01/03/2022',
          amount: 400,
          balance: '$300',
          status: 'Not Started',
        },
        {
          key: '4',
          date: '01/04/2022',
          amount: 200,
          balance: '$400',
          status: 'Pending',
        },
      ];

table.addEventListener('vegaChange', function (e) {
        const sorters = e.detail.sorters;
    });

Sort with Template


 <vega-table>
      <vega-table-head>
        <vega-table-head-row>
          <vega-table-head-cell> Date </vega-table-head-cell>
          <vega-table-head-cell sorter="event"> Amount </vega-table-head-cell>
          <vega-table-head-cell> Balance </vega-table-head-cell>
        </vega-table-head-row>
      </vega-table-head>
      <vega-table-body></vega-table-body>
    </vega-table>

function renderData(dataSource) {
        document.querySelector("vega-table-body").innerHTML = dataSource
          .map((item) => {
            return `<vega-table-row row-key='${item.key}'>
						<vega-table-cell>${item.date}</vega-table-cell>
						<vega-table-cell>${item.amount}</vega-table-cell>
						<vega-table-cell>${item.balance}</vega-table-cell>
					</vega-table-row>`;
          })
          .join("");
      }

      const data = [
        {
          key: "1",
          name: "Jon Snow",
          date: "01/01/2022",
          amount: 100,
          balance: 100,
          status: 1,
          desc: "Test text description",
          address: "New_York_No._1_Lake_Park",
          time: "23:35"
        },
        {
          key: "2",
          name: "Jeremiah Graham",
          date: "01/02/2022",
          amount: 300,
          balance: 200,
          status: 1,
          desc: "Test text description Test text description",
          address: "New York No. 2 Lake Park",
          time: "12:00"
        },
        {
          key: "3",
          name: "Jaime Stark",
          date: "01/03/2022",
          amount: 400,
          balance: 300,
          status: 0,
          desc:
            "Test text description Test text description Test text description",
          address: "New York No. 3 Lake Park"
        },
        {
          key: "4",
          name: "Enrique Brewer",
          date: "01/04/2022",
          amount: 200,
          balance: 400,
          status: 2,
          desc:
            "Test text description Test text description Test text description Test text description Test text description",
          address: "New York No. 4 Lake Park"
        }
      ];

      const vegaTable = document.querySelector("vega-table");

      const headCellEl = document.querySelector(
        'vega-table-head-cell[sorter="event"]'
      );
      headCellEl.addEventListener("vegaClick", (e) => {
        const sortedProp = "amount";
        const sortOrder = e.detail.sortOrder;
        let sortedDataSource = [...data];

        sortedDataSource =
          sortOrder === null
            ? [...data]
            : sortedDataSource.sort((a, b) => {
                const compareResult = a[sortedProp] - b[sortedProp];
                return sortOrder === "asc" ? compareResult : -compareResult;
              });
        renderData(sortedDataSource);
      });

      renderData(data);
    

Overflow columns with Ellipsis

To replace overflow text in a column with an ellipsis, set column.ellipsis: true.


<vega-table id="ellipsis-column"></vega-table>
    const table = document.querySelector('#ellipsis-column');
    
      table.columns=[
      {
        label: 'Full_Name',
        prop: 'name',
        width: '10%'
      },
      {
        label: 'Date',
        prop: 'date',
        width: '10%'
      },
      {
        label: 'Address',
        prop: 'address',
        width: '15%'
      },
      {
        label: 'Amount',
        prop: 'amount',
        width: '10%'
      },
      {
        label: 'Balance',
        prop: 'balance',
        width: '15%'
      },
      {
        ellipsis: true,
        label: 'Description',
        prop: 'desc'
      }
    ]
    table.dataSource=[
      {
        address: 'New_York_No._1_Lake_Park',
        amount: 100,
        balance: '$100',
        date: '01/01/2022',
        desc: 'Test text description',
        key: '1',
        name: 'Jon Snow',
        status: 'In Progress'
      },
      {
        address: 'New York No. 2 Lake Park',
        amount: 300,
        balance: '$200',
        date: '01/02/2022',
        desc: 'Test text description Test text description',
        key: '2',
        name: 'Jeremiah Graham',
        status: 'In Progress'
      },
      {
        address: 'New York No. 3 Lake Park',
        amount: 400,
        balance: '$300',
        date: '01/03/2022',
        desc: 'Test text description Test text description Test text description',
        key: '3',
        name: 'Jaime Stark',
        status: 'Not Started'
      },
      {
        address: 'New York No. 4 Lake Park',
        amount: 200,
        balance: '$400',
        date: '01/04/2022',
        desc: 'Test text description Test text description Test text description Test text description Test text description',
        key: '4',
        name: 'Enrique Brewer',
        status: 'Pending'
      }
    ]

Ellipsis with Template


<vega-table id="ellipsis-column-template">
  <vega-table-head>
    <vega-table-head-row>
      <vega-table-head-cell>
        Date
      </vega-table-head-cell>
      <vega-table-head-cell>
        Amount
      </vega-table-head-cell>
      <vega-table-head-cell>
        Balance
      </vega-table-head-cell>
      <vega-table-head-cell>
        Description
      </vega-table-head-cell>
    </vega-table-head-row>
  </vega-table-head>
  <vega-table-body>
    <vega-table-row row-key="1">
      <vega-table-cell>
        01/01/2022
      </vega-table-cell>
      <vega-table-cell>
        100
      </vega-table-cell>
      <vega-table-cell>
        100
      </vega-table-cell>
      <vega-table-cell overflow="ellipsis">
        Test text description
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="2">
      <vega-table-cell>
        01/02/2022
      </vega-table-cell>
      <vega-table-cell>
        300
      </vega-table-cell>
      <vega-table-cell>
        200
      </vega-table-cell>
      <vega-table-cell overflow="ellipsis">
        Test text description Test text description
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="3">
      <vega-table-cell>
        01/03/2022
      </vega-table-cell>
      <vega-table-cell>
        400
      </vega-table-cell>
      <vega-table-cell>
        300
      </vega-table-cell>
      <vega-table-cell overflow="ellipsis">
        Test text description Test text description Test text description
      </vega-table-cell>
    </vega-table-row>
    <vega-table-row row-key="4">
      <vega-table-cell>
        01/04/2022
      </vega-table-cell>
      <vega-table-cell>
        200
      </vega-table-cell>
      <vega-table-cell>
        400
      </vega-table-cell>
      <vega-table-cell overflow="ellipsis">
        Test text description Test text description Test text description Test text description Test text description
      </vega-table-cell>
    </vega-table-row>
  </vega-table-body>
</vega-table>

Example with Pagination and Dividers

To add pagination to a table, set pagination and specify the pageSize. To add dividers, add column-divider and/or row-divider properties to the vega-table element.


<vega-table id="table-with-pagination" column-divider row-divider striped>
</vega-table>

  const table = document.querySelector('#table-with-pagination');

  table.columns=[
    {
      label: 'Date',
      prop: 'date'
    },
    {
      label: 'Amount',
      prop: 'amount'
    },
    {
      align: 'right',
      label: 'Balance',
      prop: 'balance'
    }
  ]
  table.dataSource=[
    {
      address: 'New_York_No._1_Lake_Park',
      amount: 100,
      balance: '$100',
      date: '01/01/2022',
      desc: 'Test text description',
      key: '1',
      name: 'Jon Snow',
      status: 'In Progress'
    },
    {
      address: 'New York No. 2 Lake Park',
      amount: 300,
      balance: '$200',
      date: '01/02/2022',
      desc: 'Test text description Test text description',
      key: '2',
      name: 'Jeremiah Graham',
      status: 'In Progress'
    },
    {
      address: 'New York No. 3 Lake Park',
      amount: 400,
      balance: '$300',
      date: '01/03/2022',
      desc: 'Test text description Test text description Test text description',
      key: '3',
      name: 'Jaime Stark',
      status: 'Not Started'
    },
    {
      address: 'New York No. 4 Lake Park',
      amount: 200,
      balance: '$400',
      date: '01/04/2022',
      desc: 'Test text description Test text description Test text description Test text description Test text description',
      key: '4',
      name: 'Enrique Brewer',
      status: 'Pending'
    },
    {
      address: 'New York No. 5 Lake Park',
      amount: 300,
      balance: '$200',
      date: '01/02/2022',
      desc: 'Test text description Test text description',
      key: '2',
      name: 'Jeremiah Graham',
      status: 'In Progress'
    },
    {
      address: 'New York No. 6 Lake Park',
      amount: 400,
      balance: '$300',
      date: '01/03/2022',
      desc: 'Test text description Test text description Test text description',
      key: '3',
      name: 'Jaime Stark',
      status: 'Not Started'
    },
    {
      address: 'New York No. 7 Lake Park',
      amount: 200,
      balance: '$400',
      date: '01/04/2022',
      desc: 'Test text description Test text description Test text description Test text description Test text description',
      key: '4',
      name: 'Enrique Brewer',
      status: 'Pending'
    },
    {
      address: 'New York No. 8 Lake Park',
      amount: 200,
      balance: '$400',
      date: '01/04/2022',
      desc: 'Test text description Test text description Test text description Test text description Test text description',
      key: '4',
      name: 'Enrique Brewer',
      status: 'Pending'
    },
    {
      address: 'New York No. 9 Lake Park',
      amount: 300,
      balance: '$200',
      date: '01/02/2022',
      desc: 'Test text description Test text description',
      key: '2',
      name: 'Jeremiah Graham',
      status: 'In Progress'
    },
    {
      address: 'New York No. 10 Lake Park',
      amount: 400,
      balance: '$300',
      date: '01/03/2022',
      desc: 'Test text description Test text description Test text description',
      key: '3',
      name: 'Jaime Stark',
      status: 'Not Started'
    },
    {
      address: 'New York No. 11 Lake Park',
      amount: 200,
      balance: '$400',
      date: '01/04/2022',
      desc: 'Test text description Test text description Test text description Test text description Test text description',
      key: '4',
      name: 'Enrique Brewer',
      status: 'Pending'
    }
  ]
table.pagination = {
   pageSize: 5
}


Density Examples

You may set table density to one three values: default, compact, or relaxed. You may also use a ResponsiveType to render the density dependent on screen size.

  <div class="v-font-h4 v-text-primary">
    Default
  </div>

<vega-table id="table-default" density="default">
</vega-table>
  const table = document.querySelector('#table-default');

  table.columns = [
      {
        label: 'Date',
        prop: 'date'
      },
      {
        label: 'Amount',
        prop: 'amount'
      },
      {
        label: 'Balance',
        prop: 'balance'
      }
    ]
    table.dataSource=[
      {
        address: 'New_York_No._1_Lake_Park',
        amount: 100,
        balance: '$100',
        date: '01/01/2022',
        desc: 'Test text description',
        key: '1',
        name: 'Jon Snow',
        status: 'In Progress'
      },
      {
        address: 'New York No. 2 Lake Park',
        amount: 300,
        balance: '$200',
        date: '01/02/2022',
        desc: 'Test text description Test text description',
        key: '2',
        name: 'Jeremiah Graham',
        status: 'In Progress'
      },
      {
        address: 'New York No. 3 Lake Park',
        amount: 400,
        balance: '$300',
        date: '01/03/2022',
        desc: 'Test text description Test text description Test text description',
        key: '3',
        name: 'Jaime Stark',
        status: 'Not Started'
      },
      {
        address: 'New York No. 4 Lake Park',
        amount: 200,
        balance: '$400',
        date: '01/04/2022',
        desc: 'Test text description Test text description Test text description Test text description Test text description',
        key: '4',
        name: 'Enrique Brewer',
        status: 'Pending'
      }
    ]

  <div class="v-font-h4 v-text-primary">
    Compact
  </div>

<vega-table id="table-compact" density="compact">
</vega-table>
  const table = document.querySelector('#table-compact');

  table.columns = [
      {
        label: 'Date',
        prop: 'date'
      },
      {
        label: 'Amount',
        prop: 'amount'
      },
      {
        label: 'Balance',
        prop: 'balance'
      }
    ]
    table.dataSource=[
      {
        address: 'New_York_No._1_Lake_Park',
        amount: 100,
        balance: '$100',
        date: '01/01/2022',
        desc: 'Test text description',
        key: '1',
        name: 'Jon Snow',
        status: 'In Progress'
      },
      {
        address: 'New York No. 2 Lake Park',
        amount: 300,
        balance: '$200',
        date: '01/02/2022',
        desc: 'Test text description Test text description',
        key: '2',
        name: 'Jeremiah Graham',
        status: 'In Progress'
      },
      {
        address: 'New York No. 3 Lake Park',
        amount: 400,
        balance: '$300',
        date: '01/03/2022',
        desc: 'Test text description Test text description Test text description',
        key: '3',
        name: 'Jaime Stark',
        status: 'Not Started'
      },
      {
        address: 'New York No. 4 Lake Park',
        amount: 200,
        balance: '$400',
        date: '01/04/2022',
        desc: 'Test text description Test text description Test text description Test text description Test text description',
        key: '4',
        name: 'Enrique Brewer',
        status: 'Pending'
      }
    ]

  <div class="v-font-h4 v-text-primary">
    Relaxed
  </div>

<vega-table id="table-relaxed" density="relaxed">
</vega-table>
  const table = document.querySelector('#table-relaxed');

  table.columns = [
      {
        label: 'Date',
        prop: 'date'
      },
      {
        label: 'Amount',
        prop: 'amount'
      },
      {
        label: 'Balance',
        prop: 'balance'
      }
    ]
    table.dataSource=[
      {
        address: 'New_York_No._1_Lake_Park',
        amount: 100,
        balance: '$100',
        date: '01/01/2022',
        desc: 'Test text description',
        key: '1',
        name: 'Jon Snow',
        status: 'In Progress'
      },
      {
        address: 'New York No. 2 Lake Park',
        amount: 300,
        balance: '$200',
        date: '01/02/2022',
        desc: 'Test text description Test text description',
        key: '2',
        name: 'Jeremiah Graham',
        status: 'In Progress'
      },
      {
        address: 'New York No. 3 Lake Park',
        amount: 400,
        balance: '$300',
        date: '01/03/2022',
        desc: 'Test text description Test text description Test text description',
        key: '3',
        name: 'Jaime Stark',
        status: 'Not Started'
      },
      {
        address: 'New York No. 4 Lake Park',
        amount: 200,
        balance: '$400',
        date: '01/04/2022',
        desc: 'Test text description Test text description Test text description Test text description Test text description',
        key: '4',
        name: 'Enrique Brewer',
        status: 'Pending'
      }
    ]

  <div class="v-font-h4 v-text-primary">
    Responsive
  </div>

<vega-table id="table-responsive" density="relaxed">
</vega-table>
  const table = document.querySelector('#table-responsive');

  table.columns = [
      {
        label: 'Date',
        prop: 'date'
      },
      {
        label: 'Amount',
        prop: 'amount'
      },
      {
        label: 'Balance',
        prop: 'balance'
      }
    ]
    table.dataSource=[
      {
        address: 'New_York_No._1_Lake_Park',
        amount: 100,
        balance: '$100',
        date: '01/01/2022',
        desc: 'Test text description',
        key: '1',
        name: 'Jon Snow',
        status: 'In Progress'
      },
      {
        address: 'New York No. 2 Lake Park',
        amount: 300,
        balance: '$200',
        date: '01/02/2022',
        desc: 'Test text description Test text description',
        key: '2',
        name: 'Jeremiah Graham',
        status: 'In Progress'
      },
      {
        address: 'New York No. 3 Lake Park',
        amount: 400,
        balance: '$300',
        date: '01/03/2022',
        desc: 'Test text description Test text description Test text description',
        key: '3',
        name: 'Jaime Stark',
        status: 'Not Started'
      },
      {
        address: 'New York No. 4 Lake Park',
        amount: 200,
        balance: '$400',
        date: '01/04/2022',
        desc: 'Test text description Test text description Test text description Test text description Test text description',
        key: '4',
        name: 'Enrique Brewer',
        status: 'Pending'
      }
    ]
    table.density = { default: 'default', S: 'compact', M: 'default', L: 'relaxed' };

Horizontal Padding Example

Default padding on tables is set at 8px, however this can be modified using the paddingX property. The below example shows left padding = 72px and right padding = 8px.

<vega-table id="with-padding" density="relaxed">
</vega-table>
const table = document.querySelector('#with-padding')

table.columns=[
        {
          label: 'Date',
          prop: 'date'
        },
        {
          label: 'Amount',
          prop: 'amount'
        },
        {
          align: 'right',
          label: 'Balance',
          prop: 'balance'
        }
      ]
      table.dataSource=[
        {
          address: 'New_York_No._1_Lake_Park',
          amount: 100,
          balance: '$100',
          date: '01/01/2022',
          desc: 'Test text description',
          key: '1',
          name: 'Jon Snow',
          status: 'In Progress'
        },
        {
          address: 'New York No. 2 Lake Park',
          amount: 300,
          balance: '$200',
          date: '01/02/2022',
          desc: 'Test text description Test text description',
          key: '2',
          name: 'Jeremiah Graham',
          status: 'In Progress'
        },
        {
          address: 'New York No. 3 Lake Park',
          amount: 400,
          balance: '$300',
          date: '01/03/2022',
          desc: 'Test text description Test text description Test text description',
          key: '3',
          name: 'Jaime Stark',
          status: 'Not Started'
        },
        {
          address: 'New York No. 4 Lake Park',
          amount: 200,
          balance: '$400',
          date: '01/04/2022',
          desc: 'Test text description Test text description Test text description Test text description Test text description',
          key: '4',
          name: 'Enrique Brewer',
          status: 'Pending'
        }
      ]
table.paddingX=[
        '72px',
        '8px'
      ]

Basic Editable Table Example

<div id="editable-template-basic">
    <vega-card padding="size-20">
        <vega-table></vega-table>
        <div class="v-mt-size-12">
            <vega-button-link id="add" size="small" icon="plus-sign"> Add New </vega-button-link>
        </div>
    </vega-card>
    <div class="v-mt-size-12">
        <vega-flex gap="size-8">
            <vega-button id="save-btn">Get All Rows Data & Save</vega-button>
        </vega-flex>
    </div>
    <div class="v-mt-size-8 v-text-primary">
        <div class="v-font-field-label v-text-success">Saved Data:</div>
        <div id="result" class="v-font-field-label" id="result"></div>
    </div>
</div>

const tableRef = document.querySelector('#editable-template-basic vega-table');
    const printDataResult = data => {
        document.querySelector('#editable-template-basic #result').innerHTML = JSON.stringify(data, null, 2);
    };
    const editTableDataSource = [
        {
            key: '1',
            employeeId: '1',
            name: 'Employee 1',
            balance: 100,
        },
        {
            key: '2',
            employeeId: '2',
            name: 'Employee 2',
            balance: 300,
        },
    ];
    const onAddListener = () => {
        document.querySelector('#editable-template-basic #add').addEventListener('vegaClick', async () => {
            await tableRef.addNewRow();
        });
    };
    const onSaveListener = () => {
        const saveBtn = document.querySelector('#editable-template-basic #save-btn');
        saveBtn.addEventListener('vegaClick', async () => {
            const rowData = await tableRef.getRowsData();
            printDataResult(rowData);
            await tableRef.saveAllEditRows();
        });
    };
    tableRef.columns = [
        {
            label: 'ID #',
            prop: 'employeeId',
            editable: true,
        },
        {
            label: 'Name',
            prop: 'name',
            editable: true,
        },
        {
            label: 'Balance',
            prop: 'balance',
            editable: true,
        },
        {
            label: 'Actions',
            width: '120px',
            renderFormItem: (createElement, rowKey, record, index, { rowForm, isNewRow }) => {
                return createElement('div', {}, [
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'checkmark',
                        onVegaClick: async () => {
                            tableRef.saveEditRow(rowKey);
                            const data = await tableRef.getRowData(rowKey);
                            printDataResult(data);
                        },
                    }),
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'close',
                        class: !isNewRow ? '' : 'v-hidden',
                        onVegaClick: () => {
                            tableRef.stopRowEditMode(rowKey);
                        },
                    }),
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'delete-bin',
                        class: isNewRow ? '' : 'v-hidden',
                        danger: true,
                        onVegaClick: () => {
                            if (confirm('Are you sure you want to delete this row?')) {
                                tableRef.removeRow(record.key);
                            }
                        },
                    }),
                ]);
            },
            render: (h, rowKey) => {
                return h('div', {}, [
                    h('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'edit-line',
                        onVegaClick: () => {
                            tableRef.startRowEditMode(rowKey);
                        },
                    }),
                    h('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'delete-bin',
                        danger: true,
                        onVegaClick: async () => {
                            if (confirm('Are you sure you want to delete this row?')) {
                                await tableRef.removeRow(rowKey);
                            }
                        },
                    }),
                ]);
            },
        },
    ];
    tableRef.dataSource = editTableDataSource;
    onAddListener();
    onSaveListener();

Complex Editable Table Example

<div id="editable-template-1">
    <vega-card padding="size-20">
        <vega-table></vega-table>
        <div class="v-mt-size-12">
            <vega-button-link id="add" size="small" icon="plus-sign"> Add New </vega-button-link>
        </div>
    </vega-card>
    <div class="v-mt-size-12">
        <vega-flex gap="size-8">
            <vega-button id="save-btn" disabled="true"> Save </vega-button>
        </vega-flex>
    </div>
    <div class="v-mt-size-8 v-text-primary">
        <div class="v-font-field-label v-text-success">Saved Data:</div>
        <div id="result" class="v-font-field-label" id="result"></div>
    </div>
</div>
const tableRef = document.querySelector('#editable-template-1 vega-table');
    const employeeList = [
        {
            employeeId: '1',
            name: 'Employee 1',
            role: ['1'],
        },
        {
            employeeId: '2',
            name: 'Employee 2',
            role: ['2'],
        },
        {
            employeeId: '3',
            name: 'Employee 3',
            role: ['0'],
        },
        {
            employeeId: '4',
            name: 'Employee 4',
            role: ['1'],
        },
    ];
    const editTableDataSource = [
        {
            key: '1',
            employeeId: '1',
            name: 'Employee 1',
            date: '01/01/2022',
            amount: 100,
            balance: 100,
            status: 1,
            role: ['1'],
            desc: 'Test text description',
            address: 'New_York_No._1_Lake_Park',
            time: '23:35',
            createAt: '01/01/2023',
            notifications: true,
        },
        {
            key: '3',
            employeeId: '3',
            name: 'Employee 3',
            date: '01/03/2022',
            amount: 400,
            balance: 300,
            status: 1,
            role: ['1', '2'],
            desc: 'Test text description Test text description Test text description',
            address: 'New York No. 3 Lake Park',
            createAt: '01/01/2023',
        },
    ];
    const mockSaveAllRowsData = values => {
        return new Promise(function (resolve) {
            setTimeout(function () {
                if (values) {
                    // call api to save all rows data and update the dataSource
                    tableRef.dataSource = values;
                }
                resolve();
            }, 1000);
        });
    };
    const mockSaveRowData = () => {
        return new Promise(function (resolve) {
            setTimeout(function () {
                // call api to save the row data, not update the dataSource
                resolve();
            }, 1000);
        });
    };
    const printDataResult = data => {
        document.querySelector('#editable-template-1 #result').innerHTML = JSON.stringify(data, null, 2);
    };
    const canSaveCheck = async () => {
        const saveBtn = document.querySelector('#editable-template-1 #save-btn');
        saveBtn.disabled = (await tableRef.getEditingRowsKey()).length === 0;
    };
    const onSaveListener = () => {
        const saveBtn = document.querySelector('#editable-template-1 #save-btn');
        saveBtn.addEventListener('vegaClick', async () => {
            const rowsData = await tableRef.getRowsData();
            const tableForm = await tableRef.getFormRef();
            const { isValid } = await tableForm.valid();
            if (isValid && rowsData.length > 0) {
                saveBtn.disabled = true;
                const loaderId = window.VegaLoader.load({
                    containerSelector: '#editable-template-1 vega-table',
                    indicatorOptions: {
                        size: 'small',
                    },
                });
                mockSaveAllRowsData(rowsData).then(() => {
                    window.VegaNotify.open({
                        type: 'success',
                        message: 'Success',
                    });
                    window.VegaLoader.close(loaderId);
                    printDataResult(rowsData);
                });
            }
        });
    };
    const onAddListener = () => {
        document.querySelector('#editable-template-1 #add').addEventListener('vegaClick', async () => {
            await tableRef.addNewRow({
                key: `new_row_${(Math.random() * 1000000).toFixed(0)}`,
                date: '01/01/2023',
            });
            canSaveCheck();
        });
    };
    tableRef.columns = [
        {
            label: 'ID #',
            prop: 'employeeId',
            width: '10%',
            editable: true,
            formItemType: 'input-select',
            formItemProps: rowForm => {
                return {
                    placeholder: 'ID',
                    required: true,
                    source: employeeList.map(item => ({
                        displayName: item.employeeId,
                        id: item.employeeId,
                    })),
                    onVegaChange: async e => {
                        const employee = employeeList.find(item => item.employeeId === e.detail);
                        if (employee) {
                            rowForm.setValue({
                                ...employee,
                            });
                        }
                    },
                };
            },
        },
        {
            label: 'Name',
            prop: 'name',
            width: '15%',
            editable: true,
            formItemProps: () => ({ disabled: true }),
        },
        {
            label: 'Role',
            prop: 'role',
            formItemType: 'combo-box',
            editable: true,
            formItemProps: () => {
                return {
                    source: [
                        {
                            label: 'Guest',
                            key: '0',
                        },
                        {
                            label: 'Developer',
                            key: '1',
                        },
                        {
                            label: 'Reporter',
                            key: '2',
                        },
                    ],
                };
            },
            render: (h, values) => {
                const getStyles = value => {
                    let bgColor;
                    let textColor;
                    switch (value.toString()) {
                        case '0':
                            bgColor = 'bg-brand';
                            textColor = 'text-inverted-primary';
                            break;
                        case '1':
                            bgColor = 'bg-status-warning';
                            textColor = 'text-black';
                            break;
                        case '2':
                            bgColor = 'bg-accent5-secondary';
                            textColor = 'text-primary';
                            break;
                        default:
                            bgColor = 'bg-brand';
                            textColor = 'text-inverted-primary';
                    }
                    return { bgColor, textColor };
                };
                const formatRole = status => {
                    switch (Number(status)) {
                        case 0:
                            return 'Guest';
                        case 1:
                            return 'Developer';
                        case 2:
                            return 'Reporter';
                        default:
                            return 'Guest';
                    }
                };
                return h(
                    'vega-flex',
                    { gap: 'size-4' },
                    values &&
                        values.map(item =>
                            h('vega-chip', {
                                text: formatRole(item),
                                bgColor: getStyles(item).bgColor,
                                textColor: getStyles(item).textColor,
                                size: 'small',
                            }),
                        ),
                );
            },
        },
        {
            label: 'Balance',
            prop: 'balance',
            width: '15%',
            editable: true,
            render: (h, value) => (value ? `$${value}` : '--'),
        },
        {
            label: 'Date',
            prop: 'date',
            width: '15%',
            editable: true,
            formItemType: 'date-picker',
        },
        {
            label: 'Actions',
            renderFormItem: (createElement, rowKey, record, index, { rowForm, isNewRow }) => {
                return createElement('div', {}, [
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'checkmark',
                        class: !isNewRow ? '' : 'v-hidden',
                        onVegaClick: async () => {
                            const { isValid } = await rowForm.valid();
                            if (isValid) {
                                const loaderId = window.VegaLoader.load({
                                    containerSelector: '#editable-template-1 vega-table',
                                    indicatorOptions: {
                                        size: 'small',
                                    },
                                });
                                const data = await tableRef.getRowData(rowKey);
                                mockSaveRowData().then(() => {
                                    tableRef.saveEditRow(rowKey); // Will only update one row data in the table
                                    canSaveCheck();
                                    window.VegaNotify.open({
                                        type: 'success',
                                        message: 'Success',
                                    });
                                    window.VegaLoader.close(loaderId);
                                    printDataResult(data);
                                });
                            }
                        },
                    }),
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'close',
                        class: !isNewRow ? '' : 'v-hidden',
                        onVegaClick: () => {
                            tableRef.stopRowEditMode(rowKey);
                            canSaveCheck();
                        },
                    }),
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'delete-bin',
                        class: isNewRow ? '' : 'v-hidden',
                        danger: true,
                        onVegaClick: () => {
                            if (confirm('Are you sure you want to delete this row?')) {
                                tableRef.removeRow(rowKey);
                                canSaveCheck();
                            }
                        },
                    }),
                ]);
            },
            render: (createElement, rowKey) => {
                return createElement('div', {}, [
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'edit-line',
                        onVegaClick: () => {
                            tableRef.startRowEditMode(rowKey);
                            canSaveCheck();
                        },
                    }),
                    createElement('vega-button-circle', {
                        variant: 'icon-only',
                        icon: 'delete-bin',
                        danger: true,
                        onVegaClick: () => {
                            if (confirm('Are you sure you want to delete this row?')) {
                                tableRef.removeRow(rowKey);
                                canSaveCheck();
                            }
                        },
                    }),
                ]);
            },
        },
    ];
    tableRef.dataSource = editTableDataSource;
    onAddListener();
    onSaveListener();

Note: The above examples use Vanilla JS. If you would like to use React, Angular, or Vue, please consult Storybook.

Usage

Tables are used for displaying data. They are compact utilitarian methods for showing a dataset that may have many different variables, and in some cases easier for users to understand than written descriptions.

The advantages of using tables are that they are far more scalable for presenting data, particularly if a dataset changes; one simply needs to add more rows or columns to represent the information.

They are also particularly useful when users need to be able to compare one set of information with another; they require less eye movement than using items such as cards for displaying data.

Properties

Name Description Default
dataSource Data record of array to be displayed: Array<{ label: string, prop: string, render: (createElement: (sel: string, props: {}, children: []) => {}, value: string, record: DataSourceItemType) => {}}> []
row-expandable Enables using expandable rows Boolean false
row-clickable Enables clickable rows Boolean false
row-divider Adds a horizontal divider between rows Boolean false
column-divider Adds a vertical divider between columns Boolean false
striped Toggles row striping Boolean true
density Density of cells within the table. Values: compact, default, relaxed default
paddingX Horizontal padding of table Object: [string, string] [8px, 8px]
show-header Indicates whether to show table header. Boolean true
emptyDescription Allows customizing the description if no data is returned. string []
row-key The unique key for the row. string key
scroll-config Configuration for scrollable containers. Enables creation of a fixed header. If maxHeight exists, and fixedHeader is not false, the table header will be fixed. {maxHeight?: number OR string; fixedHeader?: boolean OR undefined;}
columns
columns Columns of table: VegaTableColumnConfig[] []
column
key Unique key for this column; you can ignore this property if you’ve set a unique column.prop string
label Label for this column string
prop Display field of the data record string
sorter This will make a column sortable. Sort function for local sort, see Array.sort’s compareFunction If you need remote sorting from backend, set to ‘event’ VegaTableSortCompareFunction`` 'event' -
breakpoint The breakpoint at which the column will be hidden. Always visible if not set. SMLXL -
align The specify which way that column is aligned: left, right, or center -
render Renderer of the table cell. The return value should be a ReactNode (createElement, value, record, index) => {}
width Sets the width of a column string
elipsis Allows replacing overflowed text with an elipsis boolean
editable Indicates whether cells can be editable
boolean
formItemType Type of the editable cell’s internal component.
input, input-select, stepper, checkbox, textarea, combo-box, date-picker, time-picker
formItemProps Properties of editable table cell items.
(form: HTMLVegaFormElement, payload: {record: VegaTableDataSourceItem; index: number;}) => Record<string, unknown>
renderFormItem Used to customize editable cells in editing mode.
(createElement: VegaTableCreateElementFunction, value: unknown, record: VegaTableDataSourceItem, index: number, rowPayload: { rowForm: HTMLVegaFormElement; isNewRow: boolean }) => {}
rowSelection
rowSelection Selection of table row ""
rowSelection
hideSelectAll Hide the selectAll checkbox boolean false
type checkbox checkbox checkbox
vegaSelectChange Callback executed when select/deselect one row (selected, record, selectedRows) => {} ""
vegaSelectAllChange Callback executed when select/deselect all rows (selected, selectedRows) => {} ""
event
onVegaRowClick Callback executed when vega-table row is clicked. (e: CustomEvent<VegaTableRowClickPropType>) => {}
onVegaChange Callback executed when vega-table change (e: CustomEvent<VegaTableChangePropType>) => {}
Methods
openExpandRow Opens expandable row by rowKey (rowKey: string) => Promise<void>
closeExpandRow Closes expandable row by rowKey (rowKey: string) => Promise<void>
closeAllExpandRow Closes all expanded rows () => Promise<void>
toggleExpandRow toggles an expandable row by rowKey (rowKey: string) => Promise<void>
clearSelection Clears the user selection () => Promise<void
getSelection Returns the currently selected rows key (keys: string[], selected: boolean = null) => Promise<void>
setSelection Set selected row keys (keys: string[]) => Promise<void>
Pagination
pagination Pagination configuration. object
position Specify the pagnation position 'bottom-left' 'bottom-center' 'bottom-right' bottom-right
pageSize Number of data items per page. number 10

Important Notes

rowKey

In order for tables to render properly, each item with in dataSource must have a unique key property. Alternately, you may specify the primary key of the dataSource using rowKey.

<!-- primary key is uid -->
<vega-table row-key="uid"></vega-table>;

If a unique key or rowKey is not supplied, the dataSource may not render.

Column property nesting path

You may nest data within the column object by using a string.

const dataSource = [
    {
        key: '1',
        date: '01/01/2022',
        user: {
            name: 'user1',
            account: 'account1',
        },
    },
];

const columns = [
    {
        label: 'Name',
        prop: 'user.name',
    },
    {
        label: 'Date',
        prop: 'date',
    },
];

For more details, view in Storybook.

Accessibility

  • Required ARIA attributes must be provided
  • ARIA roles used must conform to valid values
  • Elements must have sufficient color contrast
  • id attribute value must be unique
  • Interactive controls must not be nested
  • Table cells that use the headers attribute must only refer to cells in the same table
  • Table headers in a data table must refer to data cells

Best Practices

When presenting data in tabular format, it’s best to make the first column be something that is normally readable by a human, and not a random data identifier used by a computer.

For large tables, it’s wise to freeze the header row to the screen, so that users who scroll understand what it is they are looking at.

Zebra striping of tables helps with readability, as does hover-triggered highlighting.

For large tables, it is generally helpful to allow users to hide and/or reorder columns to create personalized layouts.

If tables are editable, this should be possible at the row level, if not at the individual cell level. Avoid using modal popups for table editing, as the modal will often obscure or hide adjacent rows which may be necessary for reference.

Row-based actions (e.g. delete, select, edit, etc.) should be possible, however it’s wise to try to avoid placing too many actions within one cell, as this can cause layout problems. If using icons in these cases, use tooltips for providing textual information for what each icon represents.

Do

  • Do make table columns resizable
  • Do allow users to sort and filter
  • Do allow reordering columns
  • Do allow inline editing
  • Do use zebra striping

Don’t

  • Don’t design large complex tables for mobile environments. Provide an alternate method for obtaining information

Designer Best Practices

While it is possible to break the components to make changes to things such as the header, this is not recommended, as this will cause the table component to not be updatable or scalable for any changes in the future

Corner rounding is set at a specific 4px radius; this cannot be changed without breaking the component. For the same reason, it’s best to keep the component as created using the plugin, and not to break the component to make custom changes.

There should only be one checkbox per table row.