Foundation component · Data display
Data Table
A compact, read-only table for comparing records and scanning summaries.
Live playground
| Platform3 | ||||
|---|---|---|---|---|
| AAda Lovelaceada | [email protected] | Workspace admin | ||
| AAlan Turingalan | [email protected] | Member | ||
| GGrace Hoppergrace | [email protected] | Member | ||
| Research3 | ||||
| DDonald Knuthdonald | [email protected] | Guest | ||
| KKatherine Johnsonkatherine | [email protected] | Member | ||
| MMargaret Hamiltonmargaret | [email protected] | Member | ||
When to use it
- Use Data Table for records with stable column headings and several comparable rows.
- Keep row selection optional. When enabled, a quiet full-row fill and the shared Selection Toolbar make the selected set clear without turning each cell into a separate tile.
- Data rows have no inter-row gap. Group surfaces have 2px above and below; adjacent selected rows form one surface with rounded corners only at the outer boundary.
- Render each data group in its own
DataTable.Bodywith aDataTable.GroupRow. The Consumer decides group membership and counts. Keep row data, optional selection, sorting, filtering, and summaries in the Consumer. The shared component owns table semantics, compact cell geometry, pinned columns, and column resizing.
Use Description List for facts about a single object. Use Data Grid when cells need editing or two-dimensional keyboard navigation.
Interaction and layout
Pin only a leading set of columns. At narrow widths, the remaining columns scroll horizontally.
Resizable column separators support pointer drag and Left/Right arrow keys. Give each separator a meaningful label.
- A sortable
DataTable.Headshows a compact hover/focus surface. PassonSort,sortDirection, andsortLabel; the Consumer owns the ordering. - For a row-actions column, keep the header cell and give it an accessible name with
aria-label. Leave its visible content empty by default; render a label when the product needs one. - Reveal row selection and row actions on hover or keyboard focus, and keep them visible for selected rows. On touch, keep these controls visible.
Header and footer remain visible within a height-constrained table. Put calculated values or actions in footer cells only when they help compare the collection.
Implementation
The Consumer supplies data and controls selection. Column widths and pinned offsets stay aligned as a user resizes.
import { DataTable } from "@lenso/ui/data-table";
const columns = [
{ id: "name", width: 240, minWidth: 160, pinned: true },
{ id: "status", width: 160 },
];
<DataTable.Root columns={columns} label="Projects" maxHeight={480}>
<DataTable.Header>
<DataTable.Row>
<DataTable.Head columnId="name" resizable resizeLabel="Resize Name column">
Name
</DataTable.Head>
<DataTable.Head columnId="status">Status</DataTable.Head>
</DataTable.Row>
</DataTable.Header>
<DataTable.Body>
<DataTable.GroupRow label="Active" count={1} />
<DataTable.Row>
<DataTable.Cell columnId="name">Atlas</DataTable.Cell>
<DataTable.Cell columnId="status">Active</DataTable.Cell>
</DataTable.Row>
</DataTable.Body>
</DataTable.Root>;