Loading
Placeholder rows, one bar per cell, sit under the real header so the page never jumps.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },
]}
data={[]}Interactive table — sort, select, expand, and click through rows of data.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },
]}
data={[Do not use DataTable for a simple static comparison.
Don’t
<DataTable />Do
<Table aria-label="Plan comparison">
<Table.Head>
<Table.Row>
<Table.HeaderCell>Plan</Table.HeaderCell>
<Table.HeaderCell>Price</Table.HeaderCell>
</Table.Row>
</Table.Head>
<Table.Body>
<Table.Row>
<Table.Cell>Starter</Table.Cell>
<Table.Cell>$0</Table.Cell>
</Table.Row>
</Table.Body>
</Table>pnpm add @usefragments/uiImport styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.
@tanstack/react-table — Optional — powers sorting, selection, and expansion; without it DataTable renders a static, non-interactive table.pnpm add @tanstack/react-tableImport DataTable once, then compose its parts with dot notation.
DataTable.ColumnsDataTable.preloadPlaceholder rows, one bar per cell, sit under the real header so the page never jumps.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },
]}
data={[]}A cell renderer drops any component — avatar, badge — straight into the column.
<DataTable
columns={[
{
accessorKey: "name",
header: "Name",
cell: ({ row }) => (Click a header to sort; click it again to reverse.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "amount", header: "Amount" },
]}
data={[The header checkbox toggles every row at once.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },
]}
data={[Children fold away under their parent, like a file tree; depth shows by indent alone.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "type", header: "Type" },
]}
data={[Filter controls sit outside the table; you own the filtering.
<Stack gap="sm">
<Input type="search" aria-label="Search users" placeholder="Search..." />
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },Mouse or keyboard opens the row; getRowProps supplies its name.
<DataTable
columns={[
{ accessorKey: "method", header: "Method" },
{ accessorKey: "path", header: "Path" },
]}
data={[{ method: "GET", path: "/v1/components" }]}A compact EmptyState replaces the rows and keeps the headers in place.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },
]}
data={[]}A failed load shows the error box under the real header, with one way out.
<DataTable
columns={[
{ accessorKey: "name", header: "Name" },
{ accessorKey: "status", header: "Status" },
]}
data={[]}Oversized values scroll inside the table instead of stretching the page.
<DataTable
columns={[
{ accessorKey: "name", header: "Administrator" },
{ accessorKey: "status", header: "Recovery policy" },
]}
data={[Prop | Type | Default | Description |
|---|---|---|---|
bordered | boolean | undefined | Not set | Draw the sheet: the surface plane, a hairline border and the surface radius |
caption | string | undefined | Not set | Visible caption for the table (recommended for accessibility) |
captionHidden | boolean | undefined | Not set | Hide the caption visually but keep it for screen readers |
columnsRequired | DataTableColumn<T>[] | Not set | Column definitions |
dataRequired | T[] | Not set | Data array |
DataTableVirtual.bordered | boolean | undefined | Not set | Draw the sheet: the surface plane, a hairline border and the surface radius, framing the scrolling wrapper. Without it the table sits flush in the surface around it. |
DataTableVirtual.caption | React.ReactNode | Not set | — |
DataTableVirtual.captionHidden | boolean | undefined | Not set | — |
DataTableVirtual.Cell.align | TableCellAlign | undefinedcenterstartend | Not set | Align the cell's content; give the column's Table.HeaderCell the same. |
DataTableVirtual.Cell.children | React.ReactNode | Not set | — |
DataTableVirtual.Cell.tabularNums | boolean | undefined | Not set | Use tabular (fixed-width) numerals so digits align in columns. Ideal for numeric columns that update — counts, timestamps, currency. |
DataTableVirtual.colSpanRequired | number | Not set | — |
DataTableVirtual.headerRequired | React.ReactNode | Not set | — |
DataTableVirtual.HeaderCell.align | TableCellAlign | undefinedcenterstartend | Not set | Align the header with its column: `end` over numbers. |
DataTableVirtual.HeaderCell.children | React.ReactNode | Not set | — |
DataTableVirtual.HeaderCell.scope | string | undefined | Not set | Scope for the header cell |
DataTableVirtual.maxHeight | string | number | undefined | Not set | Bound the table's height. The wrapper then scrolls on both axes and the head sticks to its top; without it the page scrolls the rows and the head scrolls with them. |
DataTableVirtual.paddingBottomRequired | number | Not set | — |
DataTableVirtual.paddingTopRequired | number | Not set | — |
DataTableVirtual.renderRowRequired | (row: VirtualTableRow<TItem>) => React.ReactNode | Not set | — |
DataTableVirtual.Row.children | React.ReactNode | Not set | — |
DataTableVirtual.Row.selected | boolean | undefined | Not set | Mark the row as chosen: the selection wash plus its 1px inset ring. |
DataTableVirtual.virtualRowsRequired | VirtualTableRow<TItem>[] | Not set | — |
DataTableVirtual.wrapperClassName | string | undefined | Not set | Class applied to the wrapper element that scrolls a wide table |
DataTableVirtual.wrapperProps | React.HTMLAttributes<HTMLDivElement> | undefined | Not set | Props applied to the wrapper element that scrolls a wide table |
emptyState | React.ReactNode | Not set | What an empty result says: EmptyState parts (`EmptyState.Title`, `EmptyState.Description`, `EmptyState.Actions`) rendered in a compact EmptyState under the real header. Defaults to a one-line "No data". |
error | React.ReactNode | Not set | A failed load: what went wrong and what to do, shown in an error box under the real header. Ignored while `loading`. |
expanded | ExpandedState | undefined | Not set | Controlled expanded state |
getRowId | ((row: T) => string) | undefined | Not set | Unique key extractor for each row |
getRowProps | ((row: T) => React.HTMLAttributes<HTMLTableRowElement>) | undefined | Not set | Props applied to each rendered data row. Use this for row-level ARIA labels, roles, and data attributes. |
getSubRows | ((row: T) => T[] | undefined) | undefined | Not set | Extract sub-rows from a row for expandable tree tables |
hideHeader | boolean | undefined | Not set | Hide the column header row (e.g. stacked per-group tables share one). |
loading | boolean | undefined | Not set | When true, render placeholder rows (one bar per cell) instead of data. |
maxHeight | string | number | undefined | Not set | Bound the table's height: the rows scroll inside it and the head sticks |
onExpandedChange | OnChangeFn<ExpandedState> | undefined | Not set | Expanded state change handler |
onRetry | (() => void) | undefined | Not set | Retry the failed load. Shows a retry button in the error box. |
onRowClick | ((row: T, event: DataTableRowClickEvent) => void) | undefined | Not set | Row click handler |
onRowSelectionChange | OnChangeFn<RowSelectionState> | undefined | Not set | Selection change handler |
onSortingChange | OnChangeFn<SortingState> | undefined | Not set | Sorting change handler |
retryLabel | string | undefined | "Retry" | Label for the retry button. |
rowSelection | RowSelectionState | undefined | Not set | Controlled selection state |
selectable | boolean | undefined | Not set | Enable row selection |
showCheckbox | boolean | undefined | Not set | Show checkbox column for row selection |
skeletonRows | number | undefined | Not set | Number of placeholder rows to show while loading (default 6). |
sortable | boolean | undefined | Not set | Enable sorting |
sorting | SortingState | undefined | Not set | Controlled sorting state |
wrapperClassName | string | undefined | Not set | Additional class name for the outer wrapper div |
wrapperProps | React.HTMLAttributes<HTMLDivElement> | undefined | Not set | Props forwarded to the outer wrapper div |