Components
Table
Styled table primitives in the look of Motion’s database table: 36px rows, hairline rules, a quiet header. The table scrolls inside its own container on small screens.
Usage
Use it for:
- Static or hand-assembled tabular data (invoices, a pricing table).
- Building your own data grid with custom rows.
Avoid it when:
- You need sorting, selection, loading and empty states from data: use DataTable.
- Layout that is not tabular: use Grid or Stack.
Installation
Install the package (React 19):
terminal
terminal
terminal
Import the styles once, in your app entry or root layout:
/src/main.tsx
Examples
Sortable header and footer
A header with onSort becomes a button and its cell gets aria-sort. Sorting itself is yours; DataTable does it for you.
| Invoice | Client | Status | |
|---|---|---|---|
| INV-208 | Acme Corp | Paid | $4,200.00 |
| INV-209 | Globex | Due Nov 2 | $1,850.00 |
| INV-210 | Initech | Overdue | $960.00 |
| Total | $7,010.00 | ||
Comfortable density
| Name | Role | Hours |
|---|---|---|
| Ada Lovelace | Engineering | 34 |
| Grace Hopper | Design | 28 |
API Reference
Table.Root
The <table> (ref and <table> props), wrapped in a horizontal scroll container.
| Prop | Type | Default |
|---|---|---|
density | "compact""comfortable" | "compact" |
containerClassName | string | |
containerStyle | CSSProperties | |
aria-label | string | |
className | string |
Table.Header / Body / Footer
<thead>, <tbody>, <tfoot>. Header cells stick to the top of the scroll container.
| Prop | Type | Default |
|---|---|---|
className | string |
Table.Row
<tr>; other <tr> props are forwarded.
| Prop | Type | Default |
|---|---|---|
selected | boolean | false |
onClick | (event) => void | |
focusable | boolean | true |
className | string |
Table.Head
<th scope="col">; other <th> props are forwarded.
| Prop | Type | Default |
|---|---|---|
align | "start""center""end" | "start" |
sort | "asc""desc"false | |
onSort | () => void | |
className | string |
Table.Cell
<td>; other <td> props are forwarded. Cells do not wrap (the table scrolls instead, like the database table); add whitespace-normal for long text.
| Prop | Type | Default |
|---|---|---|
align | "start""center""end" | "start" |
className | string |
Accessibility
Keyboard:
- Tab: reaches sort buttons, and the scroll container when the table is wider than the screen (then ← → scroll it).
- Enter / Space: on a sort button, sorts; on a clickable row (
onClick,focusable), activates it.
ARIA and semantics:
- Native table semantics:
<table>,<th scope="col">,<td>, so screen readers announce headers with each cell. - Sortable headers expose
aria-sort(none,ascending,descending) on the<th>; the sort control is a real<button>. - When content overflows, the container becomes
role="region"with a label andtabIndex=0, so keyboard users can scroll it. - Name the table with
aria-label(or a<caption>).
© 2026 Motion. Internal documentation.