zynactradocs

Data table

Search, sort, select and page through records, built from Table, Checkbox, Input Group, Dropdown Menu, Badge and Empty.

There is no data table component on purpose: every app's data is different. This pattern is the markup and behaviour to copy into your app, as components/<thing>-table.tsx. It uses plain React state, which is plenty for a few hundred rows loaded at once.

DepartmentStatusActions
Chamara RathnayakeFinanceOn leave265,000
Dilani FernandoFinanceActive320,000
Kasun SilvaOperationsActive210,000
Nimali PereraFinanceActive285,000
Ruwan BandaraOperationsActive178,000
0 of 7 selected
Page 1 of 2

How it's built

PartBuilt with
SearchInputGroup with a search icon and an aria-label
Sortable columnA plain <button> in the TableHead, so the label keeps the header's type and lines up with its column; an arrow for the direction, aria-sort on the header
SelectionCheckbox per row; the header one is indeterminate when some rows are selected
Selected rowdata-state="selected" on the TableRow. The theme colors it (brand-soft in Zynactra)
StatusBadge success or warning, with a word, never color alone
Numbersfont-mono tabular-nums, right-aligned
Row actionsOne DropdownMenu per row behind an icon button named for the row; destructive last
No resultsEmpty across all columns, saying what wasn't found
PagingMono page count and outline Previous and Next buttons

Bigger tables

  • Server data. When the server searches and pages, follow the server data table pattern: debounced, cancellable requests, skeleton rows, cursor paging.
  • More features (column visibility, resizing, grouping, virtual rows): use TanStack Table for the logic and keep this markup. Version 9 changed the API from v8 (useTable with registered features); follow the guides it ships in node_modules/@tanstack/react-table/skills/.
  • Bulk actions. When rows are selected, show the actions above the table, with the count ("3 selected").

Guidelines

  • No brand in a table: selection, sorting and status are state, not the primary action. The page's primary action ("Add employee") sits above the table.
  • Wrap the table in border border-border; don't add a shadow or a card around it.
  • Five to seven columns. Put the rest in the row's detail view (Sheet).
Edit on GitHub

On this page