Data Table
A sortable project table with typed columns, active rows, row actions and empty states.
Purpose
DataTable adds typed columns, sorting, active-row behavior, and empty states to the Siteplane UI Table primitive. Use Table directly for static markup.
Sortable invoices
Installation
With the Siteplane registry alias configured, add the component and import the installed source from your app.
CLI
pnpm dlx shadcn@4.16.1 add @siteplane/data-tableImport
import { DataTable } from "@/components/ui/data-table";
import type { DataTableColumn } from "@/components/ui/data-table";Need the machine-readable source metadata? View registry JSON.
Usage
Use Data Table when a table needs managed sorting. Use Table directly for static tabular data.
"use client";
import { useState } from "react";
import { DataTable, type DataTableColumn, type DataTableSort } from "@/components/ui/data-table";
export function Example() {
const [sort, setSort] = useState<DataTableSort | null>({ id: "customer", direction: "asc" });
return <DataTable columns={columns} data={rows} sort={sort} onSortChange={setSort} />;
}Examples
Sorting modes, row interaction, empty states, caption, footer and the card variant are props of the same component.
Sorting disabled
Columns with sortable: false keep a plain header without a sort button.
Initial sort
initialSort sets the uncontrolled start state; header clicks take over from there.
Full-cell sort area
sortClickArea="cell" makes the whole header cell clickable instead of only label and icon.
Clickable rows
onRowClick makes rows keyboard-focusable; activeRowId highlights the current row.
Empty state
Card variant
API Reference
The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.
- Accessor columns are sortable by default. Set
sortable: falsewhen sorting has no product meaning. - Use
sortwithonSortChangefor controlled sorting orinitialSortfor uncontrolled initial state. column.alignaccepts"left","center", or"right".- Without a custom
cell, Date values usetoLocaleDateString(), nullish values render empty, and other values useString(value). - When
emptyStateis omitted, DataTable renders its built-in “No results” state. onRowClick,getRowId,activeRowId, andgetRowAriaLabelcreate an accessible active-row flow.- Row clicks ignore links, buttons, inputs, selects, textareas,
[role=button],[role=link], and elements markeddata-row-click-ignore="true". sortClickArea="cell"makes the complete sortable header cell interactive; the default is"content".
Motion
Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.
- DataTable adds no mount, exit, or sorting animation.
- Sort-header Buttons disable scale so header text remains stationary.
- Row hover and active styling come from Table.
Accessibility
- Sortable headers expose
aria-sort; their icons are decorative. - Clickable rows require a stable accessible label and support Enter and Space.
- Interactive cell controls remain independent of the row action and must keep visible focus.
- Active row state is contextual selection, not a substitute for checkbox-based bulk selection.
- Empty states need a short explanation and, when possible, a useful next action.
Implementation Guidance
- Keep Table as the native rendering layer and DataTable as the small typed behavior layer; do not add a TanStack dependency.
- Define behavior in
DataTableColumnrather than duplicating sorting in feature components. - Use row clicks only for opening or activating row context.