Cajón Design System
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

PropTypeDefaultNotes
columnsDataTableColumn<T>[]Column definitions, in display order
rowsT[]Row data
rowKey(row: T, i: number) => string | numberrow indexStable key per row
densebooleanfalseTighter row padding
dividersbooleantrueHairline dividers between rows
captionReactNodeAccessible name, rendered as a <caption>

DataTableColumn<T>

FieldTypeDefaultNotes
keystringUnique key; also reads row[key] when no cell is given
headerReactNodeHeader cell content
alignleft | center | rightleftCell text alignment
widthstring | numberFixed column width
cell(row: T) => ReactNodeCustom cell renderer