Data Table
Config-driven table from @tollerud/ui: search, segmented or combobox filters, sort, selection, bulk actions, per-row menus, pagination with optional rows-per-page selector, loading skeletons, and horizontal scroll with pinned columns.
Props
Auto-generated from DataTableProps. Rich mode activates with searchable, selectable, pageSize, pageSizeOptions, rowMenu, filter, and related props.
DataTableProps| Prop | Type |
|---|---|
columns | Column<T>[] |
data? | T[] |
rows? | T[] |
rowKey? | keyof T | ((row: T) => string | number) |
onRowClick? | (row: T) => void |
className? | string |
emptyMessage? | string |
searchable? | boolean |
searchKeys? | (keyof T | string)[] |
searchPlaceholder? | string |
filter? | DataTableFilter |
selectable? | boolean |
pageSize? | number |
pageSizeOptions? | number[] |
bulkActions? | DataTableBulkAction[] |
rowMenu? | (row: T) => DataTableRowMenuItem[] |
toolbarRight? | ReactNode |
emptyState? | ReactNode |
loading? | boolean |
skeletonRows? | number |
striped? | boolean |
pinColumns? | boolean |
footer? | ReactNode |
Simple table
Bordered table with sortable headers. Add filterable: true on columns for per-column text filters (simple mode).
| Host↕ | Status |
|---|---|
| emma.tollerud.no | online |
| pia.tollerud.no | offline |
| iris.tollerud.no | online |
Column filters
Simple mode (no searchable / pageSize) adds a filter row under the headers. Rich mode uses global search and segmented filter instead.
| Host↕ | Region↕ | Status |
|---|---|---|
| — | eu-north | online |
| — | eu-north | online |
| — | eu-west | warning |
| — | us-east | online |
| — | us-east | offline |
| — | eu-west | online |
| — | eu-north | warning |
| — | us-west | online |
Filter control
Rich-mode filter uses Segmented by default. Set filter.variant to combobox for a searchable dropdown — better when there are many values or on narrow viewports.
Segmented (default)
| Host | Region | Status |
|---|---|---|
| emma | eu-north | online |
| pia | eu-north | online |
| iris | eu-west | warning |
| miriam | us-east | online |
| victoria | us-east | offline |
Combobox
| Host | Region | Owner |
|---|---|---|
| emma | eu-north | Tia |
| pia | eu-north | Emma |
| iris | eu-west | Tia |
| miriam | us-east | Pia |
| victoria | us-east | Emma |
Servers
Full rich table — the canonical pattern for homelab and ops lists. Multiple bulk actions fuse in ButtonGroup; use toolbarRight for your own ButtonGroup or single buttons.
| Host | Status | Region | CPU | Load · 7d | Containers | Owner | ||
|---|---|---|---|---|---|---|---|---|
emma 10.0.10.10 | online | eu-north | 23% | 4 | Tia | |||
pia 10.0.10.11 | online | eu-north | 51% | 2 | Emma | |||
iris 10.0.10.12 | warning | eu-west | 88% | 6 | Tia | |||
miriam 10.0.10.13 | online | us-east | 34% | 3 | Pia | |||
victoria 10.0.10.14 | offline | us-east | 0% | 0 | Emma |
Pagination
Pass pageSize to enable client-side pagination. Add pageSizeOptions for a footer Rows selector. DataTable owns page state — search and filter reset to page 1. Row selection persists across pages.
Fixed page size
| Host | Region | Owner |
|---|---|---|
| emma | eu-north | Tia |
| pia | eu-north | Emma |
| iris | eu-west | Tia |
| miriam | us-east | Pia |
| victoria | us-east | Emma |
Rows per page selector
| Host | Region |
|---|---|
| emma | eu-north |
| pia | eu-north |
| iris | eu-west |
| miriam | us-east |
| victoria | us-east |
| embla | eu-west |
| sigrid | eu-north |
| astrid | us-west |
Mobile and horizontal scroll
On narrow viewports the table scrolls horizontally inside a focusable region. pinColumns (default in rich mode) keeps the first column and row ⋮ menu visible while you scroll — WCAG allows horizontal scroll for data tables when content cannot reflow.
Design note
Prefer fewer columns on mobile when you can. When comparison matters, horizontal scroll with a pinned anchor column beats squashing cells or hiding critical context.
| Host | Status | Region | CPU | Load · 7d | Containers | Owner | ||
|---|---|---|---|---|---|---|---|---|
emma 10.0.10.10 | online | eu-north | 23% | 4 | Tia | |||
pia 10.0.10.11 | online | eu-north | 51% | 2 | Emma | |||
iris 10.0.10.12 | warning | eu-west | 88% | 6 | Tia | |||
miriam 10.0.10.13 | online | us-east | 34% | 3 | Pia |