Components · Data table

Selection & sort

Controlled sort and selection on one grid. Clicking a sortable header cycles its SortState { key, dir } — the active column keeps its asc/desc caret while the rest stay quiet (a faint hint appears on hover). Leading checkboxes drive a ReadonlySet of row ids under an indeterminate select-all; while any are ticked the BulkActionBar slides in with the live count and actions.

DataGrid · sorted by Last active ↓ · 2 of 6 selected
Volunteer Team Status Last active
HBHannah Bergström
Community outreach Active 1h ago
MRMarisol Reyes
Transport Active 2h ago
DFDiego Fuentes
Medical Active 4h ago
DWDarnell Washington
Foster network Onboarding 5h ago
WCWei Chen
Transport Active 6h ago
PVPriya Venkatesan
Intake & triage Paused Yesterday
2selected

Last active is the active sort (dir:"desc", caret down); Volunteer is pinned :hover showing the faint sort hint. Two rows carry is-selected — accent-tinted with a left accent bar — the header check reads indeterminate, and the BulkActionBar mirrors the count of 2.

SortState
{ key, dir: "asc" | "desc" } | null. A header click emits its key; the host owns the comparator and feeds back sorted rows. Only the active column shows a caret.
selected
A controlled ReadonlySet<string> of row ids via getRowId; onSelectedChange emits the next set. Selected rows get is-selected — tint + left accent bar.
select-all
The header checkbox is checked when the page is fully selected, indeterminate on a partial set (shown), unchecked at zero — one click toggles the visible page.
BulkActionBar
Renders only while count > 0: the count pill, the action children operating on the selected set, and an onClear that empties the selection.

Source · RescuersTable.tsx (TanStack rowSelection + sorting, header select-all, SortAsc/SortDesc carets, selected-row tint) · @phauna/ds/grid DataGrid controlled sort/selected + BulkActionBar.