Search...

Search documentation...

Data Table

Data Table

A TanStack Table wrapper — sorting, column filters, global search, column visibility, pinning, drag-to-reorder, drag-to-resize, row selection, and pagination, all controllable or left uncontrolled. columns uses TanStack's own ColumnDef shape.

import {
  DataTable,
  DataTableColumnHeader,
  type ColumnDef,
} from "@pompeitech/vesuvius-ui";

Default

ORD-001Ada Lovelacedelivered$128.50
ORD-002Grace Hopperprocessing$64.00
ORD-003Alan Turingpending$245.75
ORD-004Margaret Hamiltonshipped$89.99
4 row(s) total.
Rows per page
Page 1 of 1

Click a column header to sort — it cycles ascending → descending → unsorted.

Building on it

PieceAdds
createSelectionColumn()A checkbox column for row selection — prepend it to columns.
DataTableToolbarGlobal search input + a "Columns" visibility menu, above the table.
DataTableFacetedFilterA faceted multi-select filter for one column, dropped into the toolbar.
DataTableColumnHeaderSortable header cell — click to sort, includes the sort direction icon.
DataTablePaginationPage size + prev/next controls, below the table.
useDataTable(props)The hook DataTable itself uses — call it directly for full control over the table instance (e.g. to drive DataTableToolbar/DataTablePagination yourself around a custom layout).

API

DataTable

PropTypeDescription
columnsColumnDef<TData>[]Required — TanStack's own column definition shape.
dataTData[]Required.
getRowId(row: TData) => stringStable row identity across re-sorts/re-filters — without it, TanStack falls back to row index, which breaks selection/pinning state when the row order changes.
enableRowSelectionbooleanRequired alongside createSelectionColumn() for checkboxes to actually toggle.
enableColumnPinningboolean
enableColumnResizingbooleanTurns on the drag-to-resize handle on column borders.
manualSorting / manualFilteringbooleanSet when sorting/filtering happens server-side — TanStack then stops sorting/filtering data itself and just tracks the requested state for you to act on.
enableExportbooleanAdds an Export CSV action for the visible, filtered rows.
exportFilenamestringFilename used by the CSV download. Defaults to export.csv.
exportSelectedOnlybooleanExports selected rows instead of all filtered rows.
bulkActionsReactNode | ({ rows, table }) => ReactNodeActions shown when one or more rows are selected.

Each of the following follows the same uncontrolled/controlled pair shape — a default* prop for the initial value, plus */on*Change for a fully controlled version (same pattern as Select's defaultValue/value/onValueChange):

The table always fills the width of its parent. If the sum of the column widths is larger than the available space, only the table viewport scrolls horizontally; the surrounding page keeps its layout.

StateUncontrolled propControlled propChange handler
SortingdefaultSortingsortingonSortingChange
Column filtersdefaultColumnFilterscolumnFiltersonColumnFiltersChange
Global searchdefaultGlobalFilterglobalFilteronGlobalFilterChange
Column visibilitydefaultColumnVisibilitycolumnVisibilityonColumnVisibilityChange
Column pinningdefaultColumnPinningcolumnPinningonColumnPinningChange
Column orderdefaultColumnOrdercolumnOrderonColumnOrderChange
Column sizingdefaultColumnSizingcolumnSizingonColumnSizingChange
Row selectiondefaultRowSelectionrowSelectiononRowSelectionChange
PaginationdefaultPaginationpaginationonPaginationChange

Accessibility

Renders a real <table> underneath (same semantics as Table). The resize handle on each column border is a genuine role="slider" element with aria-valuenow/aria-valuemin/aria-valuemax and a descriptive aria-label — column resizing isn't pointer-only, unlike drag-to-reorder, which currently has no keyboard equivalent; column order is just state though, not the only way to reach a column's data, so a fixed order remains fully usable.