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 BeckerActiveDana WhitfieldSam Cho
Erin LattimoreReviewMarcus ReyesMarcus Reyes
Hassan AliActivePriya AnandDana Whitfield
Grace NimoyInactiveDana WhitfieldLena Ortiz
Victor PangActiveSam ChoSam Cho
Aisha BelloActiveLena OrtizPriya Anand
Owen FryeReviewMarcus ReyesDana Whitfield
Maya IversonActivePriya AnandSam 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

A sortable, selectable tabletsx
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.
  • /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.