Data Table

Browses, filters and acts on a set of rows.

1–5 of 24 customers

Installation

pnpm dlx shadcn@latest add @paneui/data-table

Usage

Examples

Empty State

What it adds to Table

It builds on Table. Columns are Table columns plus label and hideable, and toolbar adds your own controls.

Data flow

Everything runs on the client: filter → search → sort → page. Selection survives paging. For server-side data, page and filter on the server and render Table directly.

Narrow containers

The toolbar follows the table's own width, not the window's. Below 40rem the search takes its own row, and when the filter buttons can't share a row with your toolbar controls they fold into one Filter menu. Below 28rem the pager switches to its compact form.

Row actions

Put DataTableRowActions with MenuItems in an actions column; clicks inside it don't trigger onRowClick.

API Reference

DataTable

data*
readonly T[]
All rows.
columns*
readonly DataTableColumn<T>[]
Table columns plus label (menu name) and hideable.
getRowId*
(row: T, index: number) => string
Stable id per row.
searchText
((row: T) => string) | false
Text the search matches. Default: every string / number field. false hides search.
searchPlaceholder= "Search…"
string
Also its accessible name.
filters
DataTableFilter<T>[]
Faceted multi-select filters, each { key, label, options, accessor? }.
defaultSort
SortState
Starting sort.
defaultHiddenColumns
string[]
Columns hidden at first.
defaultPageSize= 10
number
Rows per page.
pageSizeOptions= [10, 20, 50]
number[]
Rows-per-page choices.
selectable= false
boolean
Checkbox column and selection bar.
selectedRowIds / onSelectionChange
string[] / (ids) => void
Controlled selection.
bulkActions
(rows: T[], clear: () => void) => ReactNode
Controls in the selection bar.
toolbar
ReactNode
Extra controls at the end of the toolbar.
emptyState
ReactNode
Shown when data is empty.
noun= "rows"
string
Used in the footer and empty copy.
rowHeight= 48
number
Row height in px.
onRowClick
(ctx, event) => void
Row click, e.g. to open a detail drawer.
PropTypeDefaultDescription
data*readonly T[]—All rows.
columns*readonly DataTableColumn<T>[]—Table columns plus label (menu name) and hideable.
getRowId*(row: T, index: number) => string—Stable id per row.
searchText((row: T) => string) | false—Text the search matches. Default: every string / number field. false hides search.
searchPlaceholderstring"Search…"Also its accessible name.
filtersDataTableFilter<T>[]—Faceted multi-select filters, each { key, label, options, accessor? }.
defaultSortSortState—Starting sort.
defaultHiddenColumnsstring[]—Columns hidden at first.
defaultPageSizenumber10Rows per page.
pageSizeOptionsnumber[][10, 20, 50]Rows-per-page choices.
selectablebooleanfalseCheckbox column and selection bar.
selectedRowIds / onSelectionChangestring[] / (ids) => void—Controlled selection.
bulkActions(rows: T[], clear: () => void) => ReactNode—Controls in the selection bar.
toolbarReactNode—Extra controls at the end of the toolbar.
emptyStateReactNode—Shown when data is empty.
nounstring"rows"Used in the footer and empty copy.
rowHeightnumber48Row height in px.
onRowClick(ctx, event) => void—Row click, e.g. to open a detail drawer.

DataTableRowActions

⋯ menu for a row; children are MenuItems.

label= "Row actions"
string
Accessible name of the trigger.
PropTypeDefaultDescription
labelstring"Row actions"Accessible name of the trigger.