Component reference
DataTable
Filtering, sorting, selection and pagination for straightforward datasets.
Preview
Live previewOptional six-digit hex. Clear to restore the preset. Check contrast with your brand color.
Changes apply to this preview only.
Loading the interactive example?
Width adapts to the available space
"use client";
import { useState } from "react";
import { DataTable } from "@pimolu/react";
export function DataTableExample() {
const [selected, setSelected] = useState<string[]>([]);
const rows = [
{ id: "atlas", name: "Atlas", owner: "Maya" },
{
id: "orbit",
name: "Orbit",
owner: "Noah"
},
{
id: "forma",
name: "Forma",
owner: "Alice"
}
];
return (
<div className="space-y-4">
<DataTable
data={rows}
columns={[
{ id: "name", header: "Project", sortable: true },
{
id: "owner",
header: "Owner",
sortable: true
}
]}
getRowId={(row) => row.id}
getRowLabel={(row) => `Select ${row.name}`}
caption="Project portfolio"
pageSize={2}
selectable
selectedRowIds={selected}
onSelectionChange={setSelected}
/>
<p role="status">{selected.length} project{selected.length === 1 ? "" : "s"} selected.</p>
</div>
);
}More examples
Different configurations and compositions using the real Pimolu API. Each preview runs independently and follows the site appearance.
Team directory
Filter across every column, sort by any sortable header, select a page of rows and paginate. The header checkbox reflects the visible page and becomes indeterminate when only some rows are selected.
Controlled selection
selectedRowIds and onSelectionChange keep the selection in the page so a bulk action can react to it. The table still owns the select-all checkbox and the indeterminate state.
Recent orders
The same API drives a denser order table: currency and date cells are formatted with custom accessors while sortValue keeps the raw numeric and ISO values.
Usage
Provide stable column ids, data and getRowId. A cell renderer can return React content; use searchValue and sortValue when its visual output does not expose the raw value.
Choose DataTable for a simpler client-side table. Use DataGrid when you need server ownership, grouping, column visibility or resizing. Pages start at 1.
API reference
Generated from the public TypeScript declarations. Native HTML attributes are inherited where the component extends them; this reference includes Pimolu props and selected common native attributes.
PimoluDataTableSort
Type source| Name | Type | Default | Description |
|---|---|---|---|
columnIdRequired | string | — | Id of the sorted column. |
directionRequired | PimoluDataTableSortDirection | — | Active direction. |
columnIdRequiredstringNo default extracted.
Id of the sorted column.
directionRequiredPimoluDataTableSortDirectionNo default extracted.
Active direction.
PimoluDataTableColumn
Type source| Name | Type | Default | Description |
|---|---|---|---|
idRequired | string | — | Stable column id, also used as the fallback row property key. |
headerRequired | ReactNode | — | Visible header content. |
accessor | ((row: T) => ReactNode) | undefined | — | Renders the cell content. |
cell | ((row: T) => ReactNode) | undefined | — | Renders the cell content; takes precedence over `accessor`. |
sortable | boolean | undefined | — | Enables the sort button on this column. |
align | PimoluDataTableAlign | undefined | "start" | Cell and header alignment. Defaults to "start". |
width | Property.Width<string | number> | undefined | — | Optional fixed width (number of pixels or any CSS width). |
searchValue | ((row: T) => string | number | null | undefined) | undefined | — | Raw value used by the global filter. |
sortValue | ((row: T) => string | number | null | undefined) | undefined | — | Raw value used for sorting. |
idRequiredstringNo default extracted.
Stable column id, also used as the fallback row property key.
headerRequiredReactNodeNo default extracted.
Visible header content.
accessor((row: T) => ReactNode) | undefinedNo default extracted.
Renders the cell content.
cell((row: T) => ReactNode) | undefinedNo default extracted.
Renders the cell content; takes precedence over `accessor`.
sortableboolean | undefinedNo default extracted.
Enables the sort button on this column.
alignPimoluDataTableAlign | undefinedDefault: "start"
Cell and header alignment. Defaults to "start".
widthProperty.Width<string | number> | undefinedNo default extracted.
Optional fixed width (number of pixels or any CSS width).
searchValue((row: T) => string | number | null | undefined) | undefinedNo default extracted.
Raw value used by the global filter.
sortValue((row: T) => string | number | null | undefined) | undefinedNo default extracted.
Raw value used for sorting.
PimoluDataTableLabels
Type source| Name | Type | Default | Description |
|---|---|---|---|
filterRequired | string | — | Accessible label of the filter input. |
filterPlaceholderRequired | string | — | Placeholder of the filter input. |
selectAllRequired | string | — | Accessible label of the header select-all checkbox. |
selectRowRequired | (rowId: string) => string | — | Accessible label of a row checkbox. |
emptyRequired | string | — | Shown when there is no row to display. |
loadingRequired | string | false | Announced while loading. |
clearSelectionRequired | string | — | Label of the clear-selection button. |
filterRequiredstringNo default extracted.
Accessible label of the filter input.
filterPlaceholderRequiredstringNo default extracted.
Placeholder of the filter input.
selectAllRequiredstringNo default extracted.
Accessible label of the header select-all checkbox.
selectRowRequired(rowId: string) => stringNo default extracted.
Accessible label of a row checkbox.
emptyRequiredstringNo default extracted.
Shown when there is no row to display.
loadingRequiredstringDefault: false
Announced while loading.
clearSelectionRequiredstringNo default extracted.
Label of the clear-selection button.
PimoluDataTableProps
Type source| Name | Type | Default | Description |
|---|---|---|---|
dataRequired | readonly T[] | — | Rows to display. Never mutated. |
columnsRequired | readonly PimoluDataTableColumn<T>[] | — | Column definitions. |
getRowIdRequired | (row: T) => string | — | Stable identity for a row, used by selection. |
getRowLabel | ((row: T) => string) | undefined | the localised "Select row <id>" label | Full accessible label of a row checkbox. Defaults to the localised "Select row <id>" label. |
caption | ReactNode | — | Visible table caption, also used as the accessible name. |
ariaLabel | string | undefined | — | Accessible name when no caption is rendered. |
filterable | boolean | undefined | true | Shows the global filter input. Defaults to true. Matching is case-insensitive across `searchValue`, the rendered cell text and the primitive `row[column.id]` value. |
filter | string | undefined | — | Controlled filter value. |
defaultFilter | string | undefined | "" | Initial filter value when uncontrolled. |
onFilterChange | ((value: string) => void) | undefined | — | Called with the next filter value. |
sort | PimoluDataTableSort | null | undefined | — | Controlled sort. Pass `null` to clear. |
defaultSort | PimoluDataTableSort | null | undefined | null | Initial sort when uncontrolled. |
onSortChange | ((sort: PimoluDataTableSort | null) => void) | undefined | — | Called with the next sort; `null` when the sort is cleared. |
selectable | boolean | undefined | false | Adds the selection column and the selection bar. The header checkbox selects the visible page only. |
selectedRowIds | readonly string[] | undefined | — | Controlled selected row ids. |
defaultSelectedRowIds | readonly string[] | undefined | — | Initial selection when uncontrolled. |
onSelectionChange | ((selectedRowIds: string[]) => void) | undefined | — | Called with the next selection, ordered like `data`. Selection persists across pages and filtering. |
pageSize | number | undefined | 10 | Rows per page. Defaults to 10. |
page | number | undefined | — | Controlled page, starting at 1. Filtering and sorting reset the internal page but never call `onPageChange` on your behalf. |
defaultPage | number | undefined | 1 | Initial page when uncontrolled. Defaults to 1. |
onPageChange | ((page: number) => void) | undefined | — | Called with the next page. |
pagination | boolean | undefined | true | Shows the footer and the pagination. Defaults to true. |
stickyHeader | boolean | undefined | false | Keeps the header visible while the table body scrolls. |
loading | boolean | undefined | false | Dims the table and announces a busy state. |
labels | Partial<PimoluDataTableLabels> | undefined | — | Overrides individual chrome labels. |
emptyState | ReactNode | — | Replaces the default empty message. |
className | string | undefined | — | Additional class names on the root. |
rowClassName | ((row: T, index: number) => string | undefined) | undefined | — | Additional class names per row. |
dataRequiredreadonly T[]No default extracted.
Rows to display. Never mutated.
columnsRequiredreadonly PimoluDataTableColumn<T>[]No default extracted.
Column definitions.
getRowIdRequired(row: T) => stringNo default extracted.
Stable identity for a row, used by selection.
getRowLabel((row: T) => string) | undefinedDefault: the localised "Select row <id>" label
Full accessible label of a row checkbox. Defaults to the localised "Select row <id>" label.
captionReactNodeNo default extracted.
Visible table caption, also used as the accessible name.
ariaLabelstring | undefinedNo default extracted.
Accessible name when no caption is rendered.
filterableboolean | undefinedDefault: true
Shows the global filter input. Defaults to true. Matching is case-insensitive across `searchValue`, the rendered cell text and the primitive `row[column.id]` value.
filterstring | undefinedNo default extracted.
Controlled filter value.
defaultFilterstring | undefinedDefault: ""
Initial filter value when uncontrolled.
onFilterChange((value: string) => void) | undefinedNo default extracted.
Called with the next filter value.
sortPimoluDataTableSort | null | undefinedNo default extracted.
Controlled sort. Pass `null` to clear.
defaultSortPimoluDataTableSort | null | undefinedDefault: null
Initial sort when uncontrolled.
onSortChange((sort: PimoluDataTableSort | null) => void) | undefinedNo default extracted.
Called with the next sort; `null` when the sort is cleared.
selectableboolean | undefinedDefault: false
Adds the selection column and the selection bar. The header checkbox selects the visible page only.
selectedRowIdsreadonly string[] | undefinedNo default extracted.
Controlled selected row ids.
defaultSelectedRowIdsreadonly string[] | undefinedNo default extracted.
Initial selection when uncontrolled.
onSelectionChange((selectedRowIds: string[]) => void) | undefinedNo default extracted.
Called with the next selection, ordered like `data`. Selection persists across pages and filtering.
pageSizenumber | undefinedDefault: 10
Rows per page. Defaults to 10.
pagenumber | undefinedNo default extracted.
Controlled page, starting at 1. Filtering and sorting reset the internal page but never call `onPageChange` on your behalf.
defaultPagenumber | undefinedDefault: 1
Initial page when uncontrolled. Defaults to 1.
onPageChange((page: number) => void) | undefinedNo default extracted.
Called with the next page.
paginationboolean | undefinedDefault: true
Shows the footer and the pagination. Defaults to true.
stickyHeaderboolean | undefinedDefault: false
Keeps the header visible while the table body scrolls.
loadingboolean | undefinedDefault: false
Dims the table and announces a busy state.
labelsPartial<PimoluDataTableLabels> | undefinedNo default extracted.
Overrides individual chrome labels.
emptyStateReactNodeNo default extracted.
Replaces the default empty message.
classNamestring | undefinedNo default extracted.
Additional class names on the root.
rowClassName((row: T, index: number) => string | undefined) | undefinedNo default extracted.
Additional class names per row.
Accessibility
- Provide caption or ariaLabel and useful row labels when selection is enabled.
- Selection persists across filtering and pages; the header checkbox selects the visible page. Test this behavior in your workflow.