Table
Native table primitives for structured data, sorting, selection, density, and responsive overflow.
Use Table for data whose row and column relationships are meaningful. Use layout primitives rather than a table when content does not have tabular semantics.
Default
| Role | Status | Updated | |
|---|---|---|---|
| Ada Lovelace | Owner | Active | 2m ago |
| Alan Turing | Admin | Active | 12m ago |
| Grace Hopper | Member | Invited | 1h ago |
| Katherine Johnson | Member | Active | 3h ago |
| Linus Torvalds | Member | Paused | 5d ago |
Bordered container
| Name | Role | Status | Updated |
|---|---|---|---|
| Ada Lovelace | Owner | Active | 2m ago |
| Alan Turing | Admin | Active | 12m ago |
| Grace Hopper | Member | Invited | 1h ago |
Compact
| Name | Role | Status | Updated |
|---|---|---|---|
| Ada Lovelace | Owner | Active | 2m ago |
| Alan Turing | Admin | Active | 12m ago |
| Grace Hopper | Member | Invited | 1h ago |
Empty
| Name | Role | Status | Updated |
|---|---|---|---|
No entries yetAdd an entry to see it here. | |||
Installation
The copied source is available in the registry JSON. The canonical implementation lives in packages/react/src/components/table.tsx.
Usage
<Table>
<TableHeader>
<TableRow>
<TableHead>Plan</TableHead>
<TableHead align="right">Price</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Team</TableCell>
<TableCell align="right">$49</TableCell>
</TableRow>
</TableBody>
</Table>Every part renders its corresponding native table element, so browser table semantics and native attributes are preserved.
Structural behavior
- The header provides the primary column divider. Body rows use quiet horizontal dividers.
- Numeric cells should use
align="right", which also enables tabular numerals. - Sorting state belongs on
aria-sortonTableHead;TableSortButtonprovides the interactive control and direction icon. - Selected rows expose
aria-selected. Useinteractiveon the root when rows are actionable. TableEmptymust span the visible columns throughcolSpan.
API reference
The primitives accept their corresponding native table attributes. The entries below cover behavior added by Patch UI. See the canonical source for exhaustive TypeScript definitions.
| Prop | Type | Default | Description |
|---|---|---|---|
| Table.bordered | boolean | false | Adds a radius-12 layer surface with an outer hairline. |
| Table.size | "sm" | "md" | "md" | Selects compact or standard row density. |
| Table.interactive | boolean | false | Adds the shared hover treatment to actionable body rows. |
| Table.scrollable | boolean | true | Provides horizontal overflow. Disable it when an external container owns scrolling. |
| Table.stickyHeader | boolean | false | Pins header cells inside a fixed-height scrolling container. |
| TableRow.selected | boolean | false | Applies the selected treatment and sets aria-selected. |
| TableSortButton.direction | "asc" | "desc" | "none" | "none" | Controls the direction icon. Sorting state remains application-owned. |
Accessibility
- Keep
TableHead,TableBody,TableRow, and cell parts in valid native table order. - Add a
TableCaptionwhen surrounding content does not already identify the table. - Put
aria-sort="ascending"oraria-sort="descending"on the sortedTableHead, not on the sort button. - Do not add row click behavior without an accessible interactive control or an established composite-widget keyboard model.
- Preserve horizontal scrolling on narrow screens rather than compressing columns until content becomes unreadable.
Responsive behavior
Table scrolls horizontally by default. Set scrollable={false} only when a parent owns overflow, such as a fixed-height container used with stickyHeader.