Table
Composable primitives for tabular data. The shell is bordered and scrolls on overflow, the header speaks in the label voice, and every surface reads from tokens.
import from ~/components/ui/table
Open positions
header, body, footer, caption
A caption names the table for everyone. Header cells carry scope="col" so a screen reader can say which column a value belongs to.
Empty table
filtered to nothing
Table has no empty prop, so the call site fills one full-width row. The header stays put, which tells the user the columns are still there and the filter is what emptied them.
Rules
Do
Use for tabular data: comparable rows and a stable set of columns.
Give every table a TableCaption. It names the table and its as-of date for everyone reading it.
Put scope="col" on every TableHead so assistive tech can pair a value with its column.
Right-align numeric columns and give them tabular figures so the digits line up down the column.
Compose the whole tree in one React file. Split across islands, the parts never meet.
Don't
Do not use a table for layout, or for a handful of key/value pairs. That is a definition list.
Do not ship a header-only table when the rows are empty. Fill one full-width row with an EmptyState.
Do not pass color, font or border classes to a cell. Alignment and column width are the only call-site business.