Table
Sortable, selectable records that follow the density setting.
Components<table>Checkbox
Preview theme
Playground
Click a header to sort (ascending, descending, then back to unsorted). Rows follow the row height token, so density changes every row at once. Scroll sideways on a phone: the company column stays pinned.
Preview
Demo data
Props
Density
example.tsxtsx
1import { DataTable, type Column } from "@/components/design-system/components/table/data-table"23const columns: Column<Invoice>[] = [4 { id: "company", header: "Company", cell: (r) => r.company, sortValue: (r) => r.company },5 { id: "status", header: "Status", cell: (r) => <StatusTag status={r.status} />, sortValue: (r) => order[r.status] },6 { id: "amount", header: "Amount", align: "right", cell: (r) => formatCurrency(r.amount), sortValue: (r) => r.amount },7]89<DataTable10 label="Invoices"11 columns={columns}12 rows={invoices}13 getRowId={(r) => r.id}14 selectable15 stickyHeader16/>States
Row states at rest. Selection and status tints are opaque colour mixes, so pinned cells never show content scrolling underneath.
States
Northwind Pending $7,250 Globex Pending $32,900 Defaultrest, data-selectedNorthwind Pending $7,250 Hovertr:hoverNorthwind Pending $7,250 Focuscheckbox :focus-visible- Loading
aria-busy Soylent Archived $2,980 Disabledaria-disabledInitech $4,120 Errordata-status=errorAcme Corporation Saved $18,400 Successdata-status=saved
Examples
A working invoices view. Search or filter until nothing matches to see the empty state. Select rows and mark them as paid: Initech fails once so the error and retry path is visible. Delete offers undo.
Invoices
Demo data
10 of 10 invoicesTotal $164,780
Keyboard
- Move between sort buttons, checkboxes and row actions
- Tab
- Sort by the focused column
- EnterorSpace
- Toggle the focused checkbox
- Space
- Move back
- Shift+Tab
Semantics and ARIA
- Native
<table>markup withscope="col"headers, so screen readers announce the column for every cell. - Sortable headers carry
aria-sort(ascending,descendingornone) and contain a real button named after the column. - The header checkbox reports
aria-checked="mixed"when some rows are selected and shows a minus glyph, not a tick. - Selection changes are announced through a polite live region, and the bulk bar is a labelled
region. - Skeleton rows set
aria-busyon the table; a saving row sets it on the row. The retry button names the invoice it retries. - Money is right-aligned with tabular numerals, so digits line up and columns can be scanned.