- ds
- Components
- Data table
Data table
Sort, select, filter and act on many rows.
| State | Actions | ||||||
|---|---|---|---|---|---|---|---|
| load_orders | data-platform | Failing | 96 | 4m 12s | 4 min ago | ||
| customers_daily | growth | Healthy | 1 | 30m 40s | 6 h ago | ||
| events_to_lake | data-platform | Healthy | 288 | 41s | 1 min ago | ||
| refunds_sync | payments | Slow | 24 | 15m 11s | 38 min ago | ||
| inventory_snapshot | supply | Healthy | 4 | 10m 10s | 2 h ago | ||
| marketing_attribution | growth | Paused | 0 | – | 9 days ago | ||
| fx_rates | payments | Healthy | 24 | 12s | 22 min ago |
1–7 of 7
Show code
<div class="dtable">
<div class="dt-bar">…search, filter chips, <button class="btn sm end">Columns</button></div>
<div class="dt-bar bulk" hidden><b>3 selected</b> … <button class="btn sm ghost end">Clear selection</button></div>
<div class="dt-scroll" style="--dt-h: 24rem">
<table>
<thead><tr>
<th class="sel"><input type="checkbox" aria-label="Select all" /></th>
<th aria-sort="ascending"><button>Pipeline</button></th>
<th class="n"><button>p95</button></th>
<th class="act"><span class="sr-only">Actions</span></th>
</tr></thead>
<tbody>
<tr aria-selected="true">
<td class="sel"><input type="checkbox" checked aria-label="Select load_orders" /></td>
<td><b class="mono">load_orders</b></td>
<td class="n">4m 12s</td>
<td class="act"><button class="btn icon xs ghost" aria-label="Actions for load_orders">…</button></td>
</tr>
</tbody>
</table>
</div>
<div class="dt-foot"><label>Rows per page <select class="inp sm">…</select></label><span>1–25 of 312</span><div class="btn-row">…</div></div>
</div>The table with the parts a working list needs. The toolbar holds the search, active filters as chips and the column menu. Selecting rows swaps it for a bulk bar in the accent wash, so the actions appear where people are already looking. The head sticks while the body scrolls inside --dt-h.
Column heads that sort are buttons. The sorted column is in ink with an arrow; others show a faint pair of arrows on hover. Numbers are mono and right-aligned, and so are their heads. Row actions fade in on hover and are always visible on touch. Try sorting, filtering and selecting.
Compact, empty
| Query | User | Rows | Took |
|---|---|---|---|
| select * from fct_orders where … | priya | 1,204 | 0.8s |
| select count(*) from events_raw | sameer | 1 | 14.2s |
| Pipeline | Owner | Runs |
|---|---|---|
| No pipelines match owner:finance. Clear filters | ||
Show code
<div class="dtable compact">
<table>
<thead><tr><th>Query</th><th>User</th><th class="n">Rows</th><th class="n">Took</th></tr></thead>
<tbody>
<tr><td class="mono">select * from fct_orders where …</td><td>priya</td><td class="n">1,204</td><td class="n">0.8s</td></tr>
<tr><td class="mono">select count(*) from events_raw</td><td>sameer</td><td class="n">1</td><td class="n">14.2s</td></tr>
</tbody>
</table>
</div>
<div class="dtable" style="margin-top:1rem">
<table>
<thead><tr><th>Pipeline</th><th>Owner</th><th class="n">Runs</th></tr></thead>
<tbody><tr class="dt-empty"><td colspan="3">No pipelines match <b class="mono">owner:finance</b>. <a href="#">Clear filters</a></td></tr></tbody>
</table>
</div>API
| Class | On | What it does |
|---|---|---|
.dtable | div | The frame. A real <table> inside, optionally in .dt-scroll. |
.dt-bar | div | Toolbar. .end on a child pushes it right. .bulk for the selection bar. |
.dt-scroll | div | Scrolls the table; the head sticks. --dt-h caps the height. |
th > button | th | A sortable head. Put aria-sort on the th. |
.n | th, td | Numeric: right-aligned, mono in cells. |
.sel | th, td | The checkbox column. |
aria-selected="true" | tr | A selected row, washed in the accent. |
.act | td | Row actions, faded until hover. |
.dt-foot | div | Rows per page, the range, page buttons. |
.dt-empty | tr | The row shown when nothing matches. |
.compact | .dtable | Tighter rows. |
Do
- Say the range and the total: 1–25 of 312.
- Keep selection when the sort changes, clear it when the filter does.
- Units in the head when every row shares them.
Don't
- Centred numbers.
- Zebra stripes. Hairlines are enough, and hover shows the row.
- Hiding the column that people filter by.
Accessibility
aria-sortgoes on the th, not the button, and only on the sorted column.- The select-all checkbox becomes indeterminate when some rows are selected; announce the count in the bulk bar, which is a live region.
- Every row checkbox and action button is labelled with the row's name.