A bare data table: describe `columns` once (a `title` plus a `dataIndex` or a custom `render`), pass `data`, get a `<table>` back. No sorting, pagination or empty state — add those around it.

pnpm add @behivetech/atoms.table

This is the snapshot of v0.2.5, the current version, as recorded on 2026-11-10. The live page runs its examples →

Examples of v0.2.5 are shown as code; only the latest version runs live. Open the live examples →

Basic Table
1interface Invoice {
2 id: string;
3 customer: string;
4 amount: number;
5 status: "paid" | "overdue";
6}
7
8const invoices: Invoice[] = [
9 { id: "inv-1", customer: "Acme Co", amount: 240, status: "paid" },
10 { id: "inv-2", customer: "Globex", amount: 90, status: "overdue" },
11 { id: "inv-3", customer: "Initech", amount: 512, status: "paid" },
12];
13
14const basicColumns: TableColumn<Invoice>[] = [
15 { key: "customer", title: "Customer", dataIndex: "customer" },
16 { key: "amount", title: "Amount", dataIndex: "amount" },
17];
18
19const BasicTable = () => (
20 <Table columns={basicColumns} data={invoices} rowKey={(row) => row.id} />
21);
22
23render(<BasicTable />);
Table With Custom Cells
1interface Invoice {
2 id: string;
3 customer: string;
4 amount: number;
5 status: "paid" | "overdue";
6}
7
8const invoices: Invoice[] = [
9 { id: "inv-1", customer: "Acme Co", amount: 240, status: "paid" },
10 { id: "inv-2", customer: "Globex", amount: 90, status: "overdue" },
11 { id: "inv-3", customer: "Initech", amount: 512, status: "paid" },
12];
13
14const richColumns: TableColumn<Invoice>[] = [
15 { key: "customer", title: "Customer", dataIndex: "customer" },
16 {
17 key: "amount",
18 title: "Amount",
19 dataIndex: "amount",
20 render: (value) => `$${value}`,
21 },
22 {
23 key: "status",
24 title: "Status",
25 render: (_value, row) =>
26 row.status === "overdue" ? "⚠️ overdue" : "✓ paid",
27 },
28];
29
30const TableWithCustomCells = () => (
31 <Table columns={richColumns} data={invoices} rowKey={(row) => row.id} />
32);
33
34render(<TableWithCustomCells />);
Empty Table
1interface Invoice {
2 id: string;
3 customer: string;
4 amount: number;
5 status: "paid" | "overdue";
6}
7
8const basicColumns: TableColumn<Invoice>[] = [
9 { key: "customer", title: "Customer", dataIndex: "customer" },
10 { key: "amount", title: "Amount", dataIndex: "amount" },
11];
12
13const EmptyTable = () => (
14 <Table columns={basicColumns} data={[]} rowKey={(row) => row.id} />
15);
16
17render(<EmptyTable />);