Table
shadcn/ui table on DESIGN.md tokens. Row height and text size follow the density of the region it sits in: 52px rows at body size, 40px rows at 13px in data-density="compact". Header 13/500 muted, sentence case. Hairlines between rows; hover on surface-2; selected on primary-soft with a 2px primary edge. numeric on a head and its cells right-aligns tabular figures; sort plus onSort puts the column label on a real button. The container is a focusable region named by containerLabel, and it is what a sticky header pins against — bound it with containerClassName. Add filtering, paging and column visibility on top and it is a Data table.
<Table containerLabel="Recent orders" caption="A list of your recent orders.">
<TableHeader><TableRow><TableHead>Order</TableHead>…<TableHead numeric sort={sort} onSort={…}>Amount</TableHead></TableRow></TableHeader>
<TableBody><TableRow><TableHead scope="row">SL-2026-0412</TableHead>…<TableCell numeric>…</TableCell></TableRow></TableBody>
<TableFooter><TableRow><TableCell colSpan={3}>Total</TableCell><TableCell numeric>…</TableCell></TableRow></TableFooter>
</Table>Orders
Caption below the table, status as a badge, amounts numeric, and a footer row carrying the total on surface-2.
| Order | Status | Buyer | Amount |
|---|---|---|---|
| SL-2026-0412 | Nordic Retail AB | €2,340.00 | |
| SL-2026-0413 | Tilburg Trading BV | €1,180.50 | |
| SL-2026-0414 | Rhine Outlet GmbH | €3,560.00 | |
| SL-2026-0415 | Antwerp Stock NV | €4,920.00 | |
| SL-2026-0416 | Baltic Goods OÜ | €2,750.00 | |
| SL-2026-0417 | Iberia Surplus SL | €1,960.00 | |
| SL-2026-0418 | Nordic Retail AB | €3,080.00 | |
| Total | €19,790.50 | ||
A list of your recent orders.
Row actions
An icon-xs ghost trigger in a fixed-width last column opens the row menu. The column head is visually empty but still labelled for screen readers. Every item acts: Open and Copy ID report back, and Cancel order confirms in an Alert dialog before it removes the row.
| Order | Status | Amount | Actions |
|---|---|---|---|
| SL-2026-0412 | €2,340.00 | ||
| SL-2026-0413 | €1,180.50 | ||
| SL-2026-0414 | €3,560.00 | ||
| SL-2026-0415 | €4,920.00 |
Selection, sticky header, sort
Only the checkbox selects — never a row click. The header pins because the container is bounded (max-h-64 overflow-y-auto), and the Amount label is a real button, so the sort is reachable by keyboard.
| Order | Status | ||
|---|---|---|---|
| SL-2026-0412 | €2,340.00 | ||
| SL-2026-0413 | €1,180.50 | ||
| SL-2026-0414 | €3,560.00 | ||
| SL-2026-0415 | €4,920.00 | ||
| SL-2026-0416 | €2,750.00 | ||
| SL-2026-0417 | €1,960.00 | ||
| SL-2026-0418 | €3,080.00 |
2 of 7 selected
Empty and loading
Zero results is a TableEmpty whose one button clears the filter that caused it; fetching is skeleton rows in a tbody marked aria-busy with an sr-only line.
zzz| Order | Status | Buyer | Amount |
|---|---|---|---|
No orders match “zzz”Every order is still here — the filter is hiding them. | |||
Currency column
The symbol sits at the start of the cell, the amount at the end, both tabular — a negative amount keeps its minus sign with the number, and a grouped amount still aligns.
| Item | Amount |
|---|---|
| Order payout, SL-2026-0412 | €2,340.00 |
| Platform fee | €−46.80 |
| Full container payout | €125,000.00 |
| Packaging surcharge | €38.50 |
RTL
Under DirectionProvider dir="rtl" with dir="rtl" on the container. Heads and numeric cells use logical alignment, so RTL needs no per-cell classes. SL-2026-0420 is shown selected: its 2px primary edge mirrors to the row's leading side, which in RTL is the right. Money is a flex cell, so it flips on its own.
| الطلب | الحالة | المشتري | المبلغ |
|---|---|---|---|
| SL-2026-0419 | قيد الانتظار | Nordic Retail AB | €٢٬٣٤٠٫٠٠ |
| SL-2026-0420 | قيد الشحن | Tilburg Trading BV | €١٬١٨٠٫٥٠ |
| SL-2026-0421 | ملغى | Rhine Outlet GmbH | €٣٬٥٦٠٫٠٠ |
قائمة بطلباتك الأخيرة.