Installation
Usage
"use client"
import { DataTable } from "@/components/data-table"
type User = { id: string; name: string; role: string; joined: Date }
const users: User[] = [
{ id: "1", name: "Ada Lovelace", role: "Admin", joined: new Date("2026-01-12") },
{ id: "2", name: "Grace Hopper", role: "Editor", joined: new Date("2026-03-04") },
]
export function Users() {
return (
<DataTable
caption="Team members"
data={users}
getRowId={(u) => u.id}
selectable
columns={[
{ id: "name", header: "Name", sortable: true },
{ id: "role", header: "Role", sortable: true },
{ id: "joined", header: "Joined", sortable: true, searchable: false },
]}
/>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| data | T[] | — | Rows. |
| columns | DataTableColumn<T>[] | — | id, header, accessor?, cell?, sortable?, searchable?, align?, width?. |
| getRowId | (row: T) => string | row.id | Stable id per row, used for selection and as the React key. |
| caption | string | — | Names the table (shown with showCaption). |
| pageSize | number | 10 | Rows per page; 0 shows all. |
| selectable | boolean | false | Row checkboxes and select-all. |
| selected / onSelectedChange | string[] / (ids) => void | — | Control selection yourself. |
| defaultSort | { id; direction } | — | Initial sort. |
| selectionActions | (rows: T[]) => ReactNode | — | Toolbar content while rows are selected. |
| --table-accent | CSS variable | --primary | Selection colour. |
| toolbar | boolean | true | Show the search box and row count; turn off for small fixed tables. |
| density | "comfortable" | "compact" | "comfortable" | Row height. |
Accessibility
- A real <table> with a caption, column headers and aria-sort on sortable columns.
- Sort controls are buttons; sorting, page changes and search result counts are announced.
- Row checkboxes are labelled by the row; select-all becomes indeterminate for partial pages.
- Wide tables scroll inside a keyboard-focusable, labelled region.
- Checkboxes are native inputs (drawn over, not replaced); sort glides are skipped under prefers-reduced-motion.
Changelog
- v1.0.0Latest
First release.