Components · Data display
Table
BetaShows rows of data, such as payments.
- Source
components/ui/table.tsx - shadcn/ui Table
- Figma: not linked yet (Q13)
| Invoice | Client | Issued | Status | Amount |
|---|---|---|---|---|
| INV-1042 | Sara Al-Otaibi | 12 Oct 2026 | Paid | SAR 450 |
| INV-1043 | Omar Haddad | 14 Oct 2026 | Due in 3 days | SAR 1,215 |
| INV-1044 | Lina Farouk | 2 Oct 2026 | Overdue | $120 |
| Total in SAR | SAR 1,665 | |||
When to use
- To show rows of the same kind of data that coaches compare: invoices, check-ins, payouts.
- When the columns matter: amounts, dates, statuses side by side.
When not to use
- For sorting, filtering, selection or pagination: use the data table (Phase 4), built on this one.
- For a few items with rich content: use Cards or a list.
- For layout. Tables are for data only.
Anatomy
| Client | Weight |
|---|---|
| Sara | 82.5 kg |
- 1. Header cell: column name
- 2. Body cell
- 3. Numeric cell: aligned to the end, tabular numbers
- 4. Caption: what the table shows
Variants
One style, with optional parts: a caption, a footer for totals, and a horizontal scroll container on small screens (built in).
States
| State | What changes | Token |
|---|---|---|
| Row hover | Light fill, to follow a row across | bg-muted/50 |
| Row selected | Muted fill (data-state="selected") | bg-muted |
Usage guidelines
- Align text to the start and numbers to the end, with
tabular-nums, so digits line up. - Put units in the header or the cell consistently: "Amount" with "SAR 450" in each cell.
- Use Badges for statuses; never color a whole row.
- Keep the first column the identifier the coach scans for: client or invoice.
| Omar | SAR 1,215 |
| Sara | SAR 450 |
| Omar | SAR 1,215 |
| Sara | SAR 450 |
Content guidelines
- Header labels are short nouns: "Client", "Issued", "Amount".
- Dates follow the Content rules: "12 Oct 2026".
- Empty cells show "—", not blank.
Accessibility
- A native
<table>with<th>header cells: screen readers announce the column name with each cell ("Amount, SAR 450"). - Always add a caption (visible, or
sr-only) that says what the table holds. - Identifiers like invoice numbers are
dir="ltr"inside Arabic tables.
RTL
Columns run right to left and the first column is on the right. Start and end alignment (text-start, text-end) follows; the upstream component used text-left for headers, which is changed to text-start.
Tokens used
Read from components/ui/table.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.
| Token | Utilities | SuperCoach | Coach |
|---|---|---|---|
| --foreground | text-foreground | neutral-950 | neutral-950 |
| --muted | bg-muted/50 bg-muted | neutral-100 | neutral-100 |
| --muted-foreground | text-muted-foreground | neutral-600 | neutral-600 |
| --ring | ring-ring | brand-600 | orange-500 |
- Radius
rounded-sm - Type
font-medium - Type
text-sm
Props
<Table>
Also takes every prop of <table>
No props of its own.
<TableHeader>
Also takes every prop of <thead>
No props of its own.
<TableBody>
Also takes every prop of <tbody>
No props of its own.
<TableFooter>
Also takes every prop of <tfoot>
No props of its own.
<TableRow>
Also takes every prop of <tr>
No props of its own.
<TableHead>
Also takes every prop of <th>
No props of its own.
<TableCell>
Also takes every prop of <td>
No props of its own.
<TableCaption>
Also takes every prop of <caption>
No props of its own.
Replaces in coach-admin
From the read-only audit of coach-admin: 93 style values, 124 uses.
Classes and selectors
th35thead th8.table-actions8td8.table-link4th, td3.table-bordered thead th, .table-bordered thead td, tbody, t2.table-actions img2tbody td2tbody tr:hover td1.ant-table-tbody .sc-invoices__invoice-row--due:hover td1.ant-table-tbody .sc-invoices__invoice-row--due td1
Files
src/reusableComponents/cells/matrix-cell.scss21src/reusableComponents/cells/reorder-cell.scss10src/reusableComponents/cells/exercise-cell/exercise-cell.scss8src/reusableComponents/cells/ReactGridWidget.tsx3src/reusableComponents/cells/DisabledTextCell.tsx2
The inventory lists the first 12 locations of each value, so file counts are a lower bound.
SCSS variables in these styles
$invoice-section-line→ nearest neutral-200 (no semantic token)$invoice-ink-secondary→--foreground-secondary$invoice-surface-bg→ nearest neutral-50 (no semantic token)$border-color→--border$input-border-colornot a color: spacing, size or layout$blacknot a color: spacing, size or layout$invoice-due-row-bg→--warning-subtle$scpay-neutral-bg→--muted$table-border-colornot a color: spacing, size or layout