Table
Shows records in rows and columns, with a summary below. In Single selection, people pick one row.
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
Usage
Import the component and render it.
import { Table } from 'src/components/Table/Table';
import { CheckCircleIcon } from '@phosphor-icons/react';
<Table
density="compact"
selection="none"
text="truncate"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
caption="Showing 4 of 24 records"
/>Accessibility
Role: table named by `label`; with Selection=Single, a grid whose rows are selectable (aria-selected).
| Key | Action |
|---|---|
| Tab | Moves into the rows (to the selected row, else the first) and out again (Selection=Single) |
| ↑ / ↓ | Previous / next row |
| Home / End | First / last row |
| Enter / Space | Selects the focused row |
- Column headers (th scope="col") and the first cell of each row (th scope="row") name every cell.
- When the columns do not fit, the table scrolls sideways; the scrolling area then becomes focusable so it can be scrolled with the keyboard.
- The Caption is plain text after the table; put what it says in the page if it matters (e.g. with Pagination).
Density
Set the density prop: Compact is "compact", Comfortable is "comfortable".
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
<Table
density="compact"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
/>
<Table
density="comfortable"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
/>Selection
Set the selection prop: None is "none", Single is "single".
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
<Table
selection="none"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
/>
<Table
selection="single"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
/>Text
Set the text prop: Truncate is "truncate", Wrap is "wrap".
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
| Name | Role | Status | Updated | |
|---|---|---|---|---|
| Olivia Martin | olivia.martin@example.com | Product Designer and Accessibility Lead | Active | 2 min ago |
| Noah Williams | noah.williams@example.com | Engineer | Active | 18 min ago |
| Sophia Chen | sophia.chen@example.com | Researcher | Active | 1 hr ago |
| Mateo Rossi | mateo.rossi@example.com | Product Manager | Active | Yesterday |
<Table
text="truncate"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
/>
<Table
text="wrap"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer and Accessibility Lead","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
/>Composition
Use the following composition to build a Table:
Table
├── TableHeader
├── TableRow
│ └── Badge
└── BadgeTableHeader
The Table’s column headers, on a raised surface. Only used inside Table.
| Name | Role | Status | Updated |
|---|
<TableHeader columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]} />TableRow
One row of the Table: a cell per column; the first one names the row. Only used inside Table.
| Olivia Martin | olivia.martin@example.com | Product Designer | Active | 2 min ago |
|---|
<TableRow
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
row={{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"}}
/>Actions
Pass callbacks to respond to the component.
import { Table } from 'src/components/Table/Table';
import { CheckCircleIcon } from '@phosphor-icons/react';
<Table
density="compact"
selection="none"
text="truncate"
label="Team members"
columns={[{"key":"name","header":"Name","width":220},{"key":"email","header":"Email","width":300},{"key":"role","header":"Role","width":180},{"key":"status","header":"Status","width":140},{"key":"updated","header":"Updated","width":120}]}
rows={[{"id":"olivia","name":"Olivia Martin","email":"olivia.martin@example.com","role":"Product Designer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"2 min ago"},{"id":"noah","name":"Noah Williams","email":"noah.williams@example.com","role":"Engineer","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"18 min ago"},{"id":"sophia","name":"Sophia Chen","email":"sophia.chen@example.com","role":"Researcher","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"1 hr ago"},{"id":"mateo","name":"Mateo Rossi","email":"mateo.rossi@example.com","role":"Product Manager","status":{"badge":"Active","status":"success","icon":<CheckCircleIcon />},"updated":"Yesterday"}]}
caption="Showing 4 of 24 records"
onValueChange={(value) => console.log(value)}
/>| Callback | When |
|---|---|
onValueChange | Called with the id of the row people select. |
