One table, done right — everywhere.
1 The rules — your standard, baked in
More than 3 columns and 3 rows? A search box shows automatically. Small tables stay clean.
auto · > 3 × 3Any table bigger than 2×2 gets click-to-sort headers — 3-state, ascending descending off.
auto · > 2 × 2A header checkbox selects everything (with an indeterminate middle state); shift-click selects a range.
single & multiThe moment a row is checked, an action bar slides in: Copy, Export, Share, Tag, Archive.
bulk actions2 The table — live, try everything
3 My recommendation
One component, two presets — not two codebases
A single pure-table.js where every capability is a module you switch on or off. "Two types" becomes two saved presets of the same component — so there's one thing to maintain, one set of bugs to fix, one a11y pass.
Data Grid heavy
Search · sort · multi-select · bulk bar · pagination · density · column show/hide. For registries & admin lists — Site Control, Boneyard, Security Posture, Audit Log, Products, Rate Limits.
Simple List light
Sort only, compact, zebra, no selection. For read-only summaries on dashboards, drawers, and embeds where bulk actions would be noise.
Each surface gets a row keyed by its name. The control deck above writes exactly this object. Admins (and the Brand Manager for tokens) edit it in Table Studio — role-gated, audited, reversible.
Reads via PureLive.rpc with the Sample badge until Code wires the data — same pattern as Security Posture & Boneyard.
Real <table> semantics, aria-sort, keyboard select, and auto-collapse to stacked cards on phones — built in, not per-page.
Live config — this surface
The object the deck is building right now. This is what a pure_table_configs row looks like.