Components
DataTable
Generic, token-driven table that renders native semantics and composes cell content per column.
How it works
DataTable renders real <table> semantics (thead / th[scope] / tbody /
td), so it is accessible without ARIA shims. The table owns structure and
styling only — each column's cell(row) composes its own content, so you can
drop a Badge, a colored amount, or a stacked
name/sub-label into any cell. It is generic over the row type T.
Usage
import { DataTable, type DataTableColumn } from '@cajon-ui/react';
interface Txn { name: string; amount: string; status: string; tone: 'success' | 'warning' }
const columns: DataTableColumn<Txn>[] = [
{ key: 'name', header: 'Transaction' },
{ key: 'amount', header: 'Amount', align: 'right' },
{ key: 'status', header: 'Status', align: 'right', cell: (t) => <Badge tone={t.tone}>{t.status}</Badge> },
];
<DataTable columns={columns} rows={txns} caption="Recent transactions" />When a column has no cell, the table reads row[key] directly.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
columns | DataTableColumn<T>[] | — | Column definitions, in display order |
rows | T[] | — | Row data |
rowKey | (row: T, i: number) => string | number | row index | Stable key per row |
dense | boolean | false | Tighter row padding |
dividers | boolean | true | Hairline dividers between rows |
caption | ReactNode | — | Accessible name, rendered as a <caption> |
DataTableColumn<T>
| Field | Type | Default | Notes |
|---|---|---|---|
key | string | — | Unique key; also reads row[key] when no cell is given |
header | ReactNode | — | Header cell content |
align | left | center | right | left | Cell text alignment |
width | string | number | — | Fixed column width |
cell | (row: T) => ReactNode | — | Custom cell renderer |