Default
Click a column header to sort ascending; click again to sort descending. Use the filter input to search across all columns.
const columns = [
{ key: 'name', label: 'Language', sortable: true },
{ key: 'paradigm', label: 'Paradigm', sortable: true },
{ key: 'year', label: 'First appeared', sortable: true, align: 'right' },
{ key: 'typing', label: 'Type system', sortable: true },
{ key: 'weekly', label: 'Weekly downloads', sortable: true, align: 'right' },
]
<DataTable columns={columns} data={languages} rowsPerPage={5} />
Striped rows + hover highlight
striped accepts true (same as 'odd'), 'odd', or 'even' to control which rows are shaded.
{/* striped="odd" and striped={true} are equivalent */}
<DataTable columns={columns} data={data} rowsPerPage={5} striped highlightOnHover />
<DataTable columns={columns} data={data} rowsPerPage={5} striped="even" />
Borders
Add an outer table border, column dividers, or remove the default row borders.
<DataTable columns={columns} data={data} withTableBorder withColumnBorders />
{/* Remove the default row borders */}
<DataTable columns={columns} data={data} withRowBorders={false} />
{/* Custom border color */}
<DataTable columns={columns} data={data} withTableBorder borderColor="var(--dv-color-primary-filled)" />
Cell spacing
Control the padding inside cells with horizontalSpacing and verticalSpacing. Accepts any theme size token or a CSS string.
<DataTable
columns={columns}
data={data}
horizontalSpacing="lg"
verticalSpacing="md"
/>
No pagination
Set rowsPerPage={0} to show all rows at once without pagination controls.
<DataTable columns={columns} data={data} rowsPerPage={0} />
Scoped filter
By default the filter searches across all column keys. Pass filterKeys to limit which columns are matched.
{/* Filter only matches name and paradigm, not year/downloads */}
<DataTable columns={columns} data={data} filterKeys={['name', 'paradigm']} />
Without filter
Set withFilter={false} to hide the search input entirely.
<DataTable columns={columns} data={data} withFilter={false} />
Caption
Captions render below the table by default. Set captionSide="top" to place the caption above.
<DataTable
columns={columns}
data={data}
caption="Programming languages by type system"
captionSide="top"
/>
Fixed layout with column widths
layout="fixed" switches to CSS table-layout: fixed. Column widths are determined by the first row rather than cell content, so the browser can render without scanning every cell — useful for large datasets. Use the width field on each column definition for precise control.
const columns = [
{ key: 'name', label: 'Language', sortable: true, width: '40%' },
{ key: 'paradigm', label: 'Paradigm', sortable: true, width: '35%' },
{ key: 'typing', label: 'Typing', sortable: true, width: '25%' },
]
<DataTable columns={columns} data={data} layout="fixed" />
Row selection
Add selectable to enable a checkbox column. The select-all header checkbox operates on all filtered rows, not just the current page. The toolbar count switches to "N of M selected" while rows are selected. Provide rowKey when your data has a stable unique field — omitting it uses row object reference which is safe as long as the data array doesn't change.
<DataTable columns={columns} data={data} selectable rowKey="name" />
Listening for selection changes
The dv-row-select event fires on the component root whenever the selection changes. event.detail.keys contains the selected key values; event.detail.rows contains the full matching row objects.
<DataTable id="lang-table" columns={columns} data={data} selectable rowKey="name" />
<script>
document.getElementById('lang-table').addEventListener('dv-row-select', (e) => {
const { keys, rows } = e.detail
console.log('Selected keys:', keys) // ['TypeScript', 'Rust']
console.log('Selected rows:', rows) // [{ name: 'TypeScript', ... }, ...]
})
</script>
Props
| Prop | Type | Default | Description |
|---|
columns | DataTableColumn[] | — | Column definitions — see table below |
data | Record<string, unknown>[] | [] | Row objects — values are coerced to strings for display |
rowsPerPage | number | 10 | Rows per page. Set to 0 to disable pagination |
filterKeys | string[] | all columns | Which column keys the text filter searches |
withFilter | boolean | true | Show or hide the text filter input |
striped | boolean | 'odd' | 'even' | false | Alternating row shading. true is equivalent to 'odd' |
highlightOnHover | boolean | false | Highlight rows on mouse-over |
withTableBorder | boolean | false | Adds a border around the entire table |
withColumnBorders | boolean | false | Adds vertical borders between columns |
withRowBorders | boolean | true | Shows horizontal borders between rows |
borderColor | string | — | CSS color value applied to all table border lines |
horizontalSpacing | UiSpacing | — | Padding applied to the left and right of each cell |
verticalSpacing | UiSpacing | — | Padding applied to the top and bottom of each cell |
caption | string | — | Accessible table caption text |
captionSide | 'top' | 'bottom' | 'bottom' | Which edge the caption renders on |
layout | 'auto' | 'fixed' | 'auto' | CSS table-layout algorithm. 'fixed' sizes columns from the first row and renders faster for large tables; pair with explicit column width styles for full control. |
selectable | boolean | false | Enables a checkbox column and row selection state |
rowKey | string | — | Row object key used as a unique identifier for selection tracking. Defaults to row object reference — safe when data is a static prop. |
emptyLabel | string | 'No results found' | Message shown when no rows match the filter |
DataTableColumn
| Field | Type | Description |
|---|
key | string | Object key to read from each row |
label | string | Column header text |
sortable | boolean | Enable click-to-sort on this column header |
align | 'left' | 'center' | 'right' | Text alignment for both header and cells |
width | number | string | Fixed column width — pixel number or any CSS string (e.g. '20%'). Most predictable with layout="fixed". |
Custom events
| Event | Detail | Description |
|---|
dv-row-select | { keys: unknown[], rows: Record<string, unknown>[] } | Fires when selection changes. keys are the rowKey values (or row object references); rows are the full matching row objects. |