Components
Data table
The canonical data grid. Built on @tanstack/react-table — the library owns the column model, sorting, filtering, selection, and pagination; we render every cell and bring the color. It's the same v8 ColumnDef API the client app already standardized on, so your tables can move over with their columns intact — on tokens instead of Bootstrap. The grid sits on a flat, solid card with a soft warm shadow: sticky header, gold sort caret, checkbox selection, gold focus ring. (Glass and engraving belong to the proposed system — none of that here.)
Live demo
Sort a column, search, filter by status, drag a column edge to resize, select rows for the bulk bar, and jump pages with the footer (first / prev / page input / next / last). Clear resets the search + filters. State is internal here unless you control it (status is controlled to drive the Selector).
| Tom Becker | Active | Dana Whitfield | Sam Cho | |||
| Erin Lattimore | Review | Marcus Reyes | Marcus Reyes | |||
| Hassan Ali | Active | Priya Anand | Dana Whitfield | |||
| Grace Nimoy | Inactive | Dana Whitfield | Lena Ortiz | |||
| Victor Pang | Active | Sam Cho | Sam Cho | |||
| Aisha Bello | Active | Lena Ortiz | Priya Anand | |||
| Owen Frye | Review | Marcus Reyes | Dana Whitfield | |||
| Maya Iverson | Active | Priya Anand | Sam Cho |
What the library owns vs. what we paint
- TanStack Table
- Column model, sorting, global filter, row selection, pagination (client + manual/server), column resizing. Controlled or internal state.
- surface
- A flat, solid card with a soft warm shadow — no glass, no engraving; those belong to the proposed system. A toolbar, the scrolling table, and a footer; the header sticks as you scroll.
- selection
- The checkbox column is our Checkbox; a selected row picks up a solid highlight and a bulk-action bar pops in. Selecting never triggers row navigation.
- sort + resize
- Click a header to sort — the caret goes gold on the active column. Drag the right edge to resize (gold handle).
Props
- columns / data
- Standard TanStack ColumnDef[] (with optional meta.align) and your row array. Re-export: import { ColumnDef } from "@halo-compliance/ui".
- enableSelection / bulkActions
- Adds the checkbox column + select-all; bulkActions(rows) renders in the bar when ≥1 row is selected.
- enableColumnResize
- Drag column edges; widths live in table state (table-layout switches to fixed).
- rowCount
- Set the server total to switch to manual sorting / filtering / pagination — you fetch each page; the table stops doing it client-side.
- columnFilters / toolbar
- Render filter controls (a status Selector, a date range) in the toolbar slot wired to a column's setFilterValue, or control columnFilters directly. A Clear button appears whenever the search or any filter is active. The footer is a full pager — first / prev / page-jump input / next / last.
- onRowClick / loading / emptyState
- Row click → navigation (rows become focusable); loading shows skeleton rows; emptyState overrides the empty text.
- labels
- All visible strings (search, select, pager, range, selected, empty) are overridable for i18n — defaults are English.
Usage
import { DataTable, type ColumnDef } from '@halo-compliance/ui'
const columns: ColumnDef<Officer, unknown>[] = [
{ accessorKey: 'name', header: 'Name' },
{ accessorKey: 'status', header: 'Status', cell: ({ getValue }) => <StatusPill value={getValue()} /> },
{ accessorKey: 'volume', header: 'Volume', meta: { align: 'end' } },
]
<DataTable
columns={columns}
data={officers}
getRowId={(r) => r.id}
enableSelection
enableColumnResize
bulkActions={(rows) => <Button onClick={() => exportRows(rows)}>Export {rows.length}</Button>}
/>Coming next
On the same component:
- Virtual mode — mode="virtual" via @tanstack/react-virtual for thousands of rows in one scroll.
- Column visibility — a toolbar menu to show / hide columns.
Related
- /collection — the view family (toolbar + table / cards / board) this table is the grid view of.
- /checkbox — the selection control in the checkbox column.
- /selector — the option picker used for table filters.
- /tokens — the radius / shadow / focus-ring tokens behind the surface.