Table
A real table, styled and made to scroll on narrow screens. Compound down to the cell, so the consumer decides what goes in each one.
API
Props
The container: border, radius, horizontal scroll, and the table element itself. Every part below takes the same three props, each defaulting to the element it stands for.
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "table" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Table.Head
The header band, on its own background and separated by a rule.
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "thead" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Table.Body
The rows, aligned to the top of their cells.
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "tbody" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Table.Row
One row, carrying the separator below it — dropped on the last one.
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "tr" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Table.HeadCell
A header cell.
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "th" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Table.Cell
A body cell.
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "td" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Examples
Usage
<Table>
<Table.Head>
<Table.Row>
<Table.HeadCell>prop</Table.HeadCell>
<Table.HeadCell>type</Table.HeadCell>
</Table.Row>
</Table.Head>
<Table.Body>
<Table.Row>
<Table.Cell>guardIf</Table.Cell>
<Table.Cell>boolean</Table.Cell>
</Table.Row>
</Table.Body>
</Table>| prop | type | default |
|---|---|---|
| active | boolean | false |
| as | ElementType | "div" |
Details
Compound down to the cell
The kit could have taken columns and rows as data and rendered the markup for you. It does not, because the moment one cell needs a chip, a link or a second line, a data-driven table either grows a render prop per column or stops being usable. Here the cells are yours from the start.
Mapping is therefore explicit, and pairs naturally with List — an empty array renders an empty body rather than a broken table.
<Table.Body>
<List
array={rows}
itemExtractor={({ row }) => (
<Table.Row key={row.id}>
<Table.Cell>{row.name}</Table.Cell>
</Table.Row>
)}
/>
</Table.Body>Cells do not wrap
Cells are whitespace-nowrap by default. A table that wraps its cells turns into a block of ragged text at the first narrow column, and the row loses the alignment that made it a table. When a column is genuinely prose — a description, a message — opt that one back into wrapping.
<Table.Cell className="whitespace-normal">{row.description}</Table.Cell>Narrow screens
The container scrolls horizontally on its own, so a wide table never pushes the page sideways: the overflow belongs to the table and stops there. Beyond that, dropping a column is a decision only the consumer can make, since only the consumer knows which one is expendable.
<Table.HeadCell className="max-640:hidden" />
<Table.Cell className="max-640:hidden">{row.description}</Table.Cell>That is what the props tables on this site do below 640: the description leaves and the three technical columns stay.
It stays a table
Each part renders its real element — table, thead, tbody, tr, th, td — rather than divs with a grid. Screen readers announce row and column positions, the browser handles headers, and none of that has to be reimplemented with aria attributes.