Kanshō/Data table

Operator data table

General-purpose operator table. Sortable headers, typed cells, optional row click, and an empty-state row. Used for runs, fleet, secrets, audit, and other ledgers.

Included in the single kansho full pack. Components are not offered as separate installs.

Runs ledger

StatusCostDurationBranch
R-1041Audit log compactioncode-agentRunning182,000$1.928m 12saudit/m-2014
R-1040Renew webhook signing keyops-agentSuccess14,000$0.181m 04smain
R-1039Postmortem draft — INC-218writer-agentSuccess92,000$1.104m 33swrites/inc-218
R-1038Rotate sandbox secretsops-agentFailed8,400$0.1127smain
R-1037Refresh embeddings (docs)embed-agentPaused220,000$2.4012m 41sembed/refresh
R-1036Summarise weekly intakewriter-agentSkipped0$0.00writes/weekly

Interactive rows

Use full-row activation for inspect/navigation flows; keep destructive or mutating actions as explicit cell buttons
RunTitleStatus
R-1041Audit log compactionRunning
R-1040Renew webhook signing keySuccess
R-1039Postmortem draft — INC-218Success
R-1038Rotate sandbox secretsFailed

Click a row or focus and press Enter / Space.

Compact, no hover

Settings-style read-only listing
SettingValue
Regioneu-west-1
Modelsonnet-4.6
Concurrency8
Budget cap$500 / day

Row selection

Leading checkbox column; header toggles all with an indeterminate mid-state. Selection is keyed by row id, so it survives sorting.
StatusCost
R-1041Audit log compactionRunning$1.92
R-1040Renew webhook signing keySuccess$0.18
R-1039Postmortem draft — INC-218Success$1.10
R-1038Rotate sandbox secretsFailed$0.11
R-1037Refresh embeddings (docs)Paused$2.40
R-1036Summarise weekly intakeSkipped$0.00

1 selected: R-1041

Loading

Skeleton rows matching the column count while data resolves
RunTitleStatusCost

Usage

Guidance
Do
  • Use onRowClick for opening or navigating to a row's detail.
  • Keep side effects in dedicated action cells (Retry, Delete, Approve).
  • Pass getRowId so selection and sort survive re-ordering.
Don't
  • Put a mutating action on the row body alongside onRowClick.
  • Rely on colour alone for status — the cell holds a StatusPill.
When to use
Any tabular ledger: runs, fleet, secrets, audit trails, settings.
When not to
Free-form cards or a single record — reach for a definition list or card instead.

Accessibility

Keyboard & screen reader

Keyboard

Tab
Move focus across sortable headers and interactive rows.
EnterSpace
Activate the focused row (onRowClick) or toggle a sort header.

Announces

  • Interactive rows announce getRowLabel, not a bare 'row'.
  • Sort direction is exposed on the header via aria-sort.
  • The selection checkbox column carries an indeterminate mid-state.

Not supported

  • Load-error state — surface errors above or below the table for now.

Props

API reference
PropTypeDefaultDescription
columnsrequiredDataTableColumn<T>[]Column definitions: id, header, cell renderer, plus width / align / sortable / monospace.
rowsrequiredT[]Row data. Empty renders the empty state.
getRowId(row, i) => stringStable key for a row; falls back to row.id / row.key / index.
density'comfortable' | 'compact''comfortable'Row height preset.
hoverbooleantrueRow hover affordance. Turn off for read-only listings.
onRowClick(row) => voidMakes rows interactive (focusable, Enter / Space activated).
getRowLabel(row) => stringAccessible activation label folded into the interactive row's name.
loadingnumber | booleanSkeleton rows while data resolves; true renders 5.
selectablebooleanfalseOpt-in leading checkbox column; selection is keyed by row id.
selectedKeysRowKey[]Controlled selection set.
onSelectionChange(keys) => voidFires when the selection set changes.
sortBy{ id, direction }Controlled sort state.
onSort(id) => voidFires when a sortable header is activated.
emptyLabelstringCopy for the empty-state row.
onEmptyAction() => voidOptional empty-state action, paired with emptyActionLabel.
footerReactNodeContent rendered below the table, inside the outer border.
stickyFirstColumnbooleanfalsePin the first column on horizontal scroll.

Component documentation

Data Table

components/surfaces/data-table.tsx

Purpose

Renders typed column definitions and rows as a sortable, selectable data table.

Appropriate use

Use for structured datasets whose columns, row identity, and interaction model are known in advance.

Example

components/surfaces/data-table.tsx has a representative live example in the "Runs ledger" section on /components/data-table.

States

Supports comfortable or compact density, hover styling, interactive rows, loading placeholders, empty state, controlled sorting, controlled row selection, a footer, and a sticky first column.

API and props

DataTable accepts columns, rows, getRowId, density, hover, onRowClick, getRowLabel, loading, selectable, selectedKeys, onSelectionChange, sortBy, onSort, empty labels and action, caption, footer, stickyFirstColumn, and className.

Dependencies

React, Lucide icons, Checkbox, Skeleton, and the Kansho cn utility.

Accessibility

Uses native table structure and caption, exposes aria-sort, names selection checkboxes, and makes clickable rows keyboard-operable with a caller-supplied row label.

Limitations

Sorting, selection, pagination, data fetching, and row-action side effects remain controlled by the caller; large datasets are not virtualized.

Source

Source: components/surfaces/data-table.tsx.

Full pack

components/surfaces/data-table.tsx is documented at /components/data-table and installs only through the single Kansho full pack; no individual component install is offered.