Patterns & Recipes
How do I build a table?
TanStack Table, via ui-kit's DataTable — the one true table.
Prescribed: TanStack Table via DataTable. Don't
reach for another table library or hand-roll sort/pagination state — DataTable already wraps
TanStack's headless engine with this design system's responsive layout (a real <table> on
desktop, stacked cards on phone), sortable headers with correct aria-sort, and built-in
loading/error states.
The approved implementation
Define your rows' shape and a plain TanStack ColumnDef[], then hand both to DataTable with an
accessible caption. Sorting, responsive column hiding (via each column's meta.responsiveClassName),
and the loading/error states all come for free — you don't wire any of it yourself.
| First Passage to the West | 2 | GoldLeaf |
| Journey through the Clouds | 2 | SilverLeaf |
| Rainforest to Gold Rush | 2 | GoldLeaf |
- RouteFirst Passage to the WestDays2ServiceGoldLeaf
- RouteJourney through the CloudsDays2ServiceSilverLeaf
- RouteRainforest to Gold RushDays2ServiceGoldLeaf
When to reach for something else
- Rows can be selected (bulk actions, checkboxes) →
SelectableDataTablebuilds on the sameDataTableengine with a selection column already wired. - Just showing a handful of static key/value rows, no sorting or responsiveness needed → the
plain
Tableprimitives are lighter-weight and enough. - Metric/KPI rows with a trend column →
MetricTablecomposesDataTablewith aDeltaTextchange column already built in.
Do / Don't
- Do pass a real, accessible
caption— it's rendered as a visually-hidden<caption>, not decoration. - Do use
isLoading/error/onRetryfor anything backed by a real fetch — see the Data-fetching recipe for the server side of this. - Don't implement your own sort state, pagination, or a second table component for "just this
one case" — extend
DataTable'scolumnsinstead; that's exactly what itsmetaescape hatch is for.