DataTable

Task
Assignee
Priority
Status
Progress
Due Date
Migrate database to PostgreSQL 16Alice ChenCriticalIn Progress
65%
28/03/2024 17:00
Implement OAuth2 SSOBob MartinezHighIn Progress
40%
01/04/2024 17:00
Design new onboarding flowCarol WhiteHighIn Review
90%
25/03/2024 17:00
Fix payment webhook retry logicAlice ChenCriticalDone
100%
20/03/2024 17:00
Add dark mode supportDavid KimMediumIn Progress
55%
05/04/2024 17:00
Write API documentationEva JohanssonLowBacklog
0%
15/04/2024 17:00
Optimize image pipelineBob MartinezMediumIn Review
85%
27/03/2024 17:00
Set up CI/CD for stagingHiro TanakaHighDone
100%
18/03/2024 17:00
Refactor notification serviceAlice ChenMediumBacklog
0%
10/04/2024 17:00
Audit third-party dependenciesFrank DuboisHighIn Progress
30%
29/03/2024 17:00
Create user analytics dashboardCarol WhiteMediumIn Progress
50%
08/04/2024 17:00
Fix CORS issue on stagingHiro TanakaCriticalDone
100%
19/03/2024 17:00
Implement rate limitingBob MartinezHighBlocked
20%
02/04/2024 17:00
Update privacy policy pageDavid KimLowDone
100%
22/03/2024 17:00
Add CSV export to reportsEva JohanssonMediumIn Progress
70%
30/03/2024 17:00
Performance test checkout flowFrank DuboisHighBacklog
0%
12/04/2024 17:00
Migrate email templates to MJMLCarol WhiteLowIn Progress
35%
14/04/2024 17:00
Fix timezone bug in schedulerAlice ChenCriticalIn Review
95%
24/03/2024 17:00
Add 2FA to admin panelHiro TanakaHighIn Progress
60%
03/04/2024 17:00
Create component library docsDavid KimLowBacklog
10%
20/04/2024 17:00
Upgrade Next.js to v15Bob MartinezMediumBlocked
15%
07/04/2024 17:00
Implement search autocompleteEva JohanssonMediumIn Progress
45%
04/04/2024 17:00
Add Sentry error trackingHiro TanakaHighDone
100%
21/03/2024 17:00
Design mobile navigationCarol WhiteMediumIn Review
80%
26/03/2024 17:00
Set up load balancer failoverFrank DuboisCriticalIn Progress
75%
31/03/2024 17:00

DataTable

A flexible data table with sorting, filtering, pagination, row selection, column visibility, and CSV/XLSX export.

Usage

import { DataTable, ColumnMetadata } from "@/components/ui/data-table"

type Row = { name: string; status: string; cost: number }

const columnsMetadata = [
  { columnId: "name", title: "Name", type: "text", sortable: true, filters: { text: true } },
  { columnId: "status", title: "Status", type: "text", inferOptions: true, filters: { checkboxSearch: { multiple: false } } },
  { columnId: "cost", title: "Cost", type: "number", sortable: true, filters: { number: true } },
] as const satisfies ColumnMetadata<Row>[]

<DataTable<Row>
  columnsMetadata={columnsMetadata}
  data={data}
  bordered
  enablePagination
  paginationDisplayTop
/>

DataTable props

PropTypeDefaultDescription
data*TData[]The row data array.
columnsMetadatareadonly ColumnMetadata<TData>[]Declarative column config. When provided, columns are built automatically from this.
persistColumnOrderbooleanfalsePersists column visibility/order to localStorage (requires tableName).
tableNamestringBase filename for CSV/XLSX exports (e.g. "usage_overview" → usage_overview-2026-03-16.csv). Also used as the localStorage key when persistColumnOrder is true.
enableRowSelectionbooleanfalseEnables per-row checkboxes and bulk editor toolbar.
enableRowActionsbooleanfalseRenders an actions column at the end of each row.
enablePaginationbooleantrueEnables pagination controls.
pageSizenumber25Initial number of rows per page.
enablePageSizeSelectbooleantrueShows a page-size selector in the pagination bar.
paginationDisplayTopbooleanfalseRenders pagination above the table instead of below.
language"en" | "pt""en"UI locale for labels and messages.
enableTextSelectionbooleantrueAllows text selection inside cells. Set to false to prevent accidental selection on click.
enableFullscreenbooleanfalseAdds a fullscreen toggle button to the toolbar. Opens the table in a fixed overlay covering the entire viewport via a React portal. Press Escape or click the button again to exit.
enableDownloadbooleantrueShows or hides the Export dropdown button in the toolbar. When false, the CSV/XLSX download options are not rendered.
borderedbooleanfalseWraps the table in a rounded border.
tableStyle"default" | "ghost""default"Visual style preset. "ghost" removes all background colors and row dividers, keeping only the outer border when bordered is true.
accentColorstringAccent color applied to active filter button backgrounds, filter value labels, the row-selection indicator bar, and the clear-filters button. Accepts a Tailwind color token (e.g. "blue-600") or any CSS color value (e.g. "#3b82f6"). Defaults to zinc-800.
onRowAction{ onAdd?: (row: TData) => void; onEdit?: (row: TData) => void; onDelete?: (row: TData) => void }Callbacks for the per-row action dropdown (requires enableRowActions). Only menu items with a corresponding callback are rendered.
onBulkAction{ onEdit?: (rows: TData[]) => void; onDelete?: (rows: TData[]) => void }Callbacks for the bulk editor toolbar (requires enableRowSelection). Edit and Delete commands are disabled when the corresponding callback is not provided.

ColumnMetadata fields

PropTypeDefaultDescription
columnId*keyof TData & stringKey of the row data object this column maps to.
title*stringColumn header label.
type*"text" | "number" | "date"Data type — drives which filter controls and sort logic are applied.
subtitlestringSecondary label shown below the title in the column header.
descriptionstringTooltip text shown on the column header info icon.
sortablebooleanfalseEnables click-to-sort on the column header.
hideablebooleantrueControls whether the column appears in the visibility toggle menu.
aligned"left" | "center" | "right""left"Horizontal alignment of both header and cell content.
optionsOptionItem[]Explicit list of { value, label } pairs for select/checkbox filters.
inferOptionsbooleanfalseAuto-derives filter options from the unique values in the data array. Overrides options.
filtersFilterConfigWhich filter controls to activate for this column. See FilterConfig below.
formatter(value: unknown) => ReactNodeCustom cell renderer for the display value (e.g. currency, badges).
filterValueFormatter(value: number) => stringFormats numeric values shown inside active number/percentage filter pills.
cell(props: CellContext<TData, unknown>) => ReactNodeFull TanStack cell render override — use when you need access to the full row context.
header(props: HeaderContext<TData, unknown>) => ReactNodeFull TanStack header render override.

FilterConfig fields

PropTypeDefaultDescription
textbooleanDebounced free-text search input. Works with type: "text".
textColumnsstring[]Additional column IDs to search alongside the primary text column. When set, a single input matches any of the listed columns. The placeholder updates automatically to list all searchable column titles.
checkboxbooleanMulti-select checkbox filter (arrIncludesSome). Requires options or inferOptions: true.
checkboxSearchboolean | { multiple?: boolean }Checkbox list with a search box. Set multiple: false for single-select (radio-style). Requires options or inferOptions: true.
selectbooleanSingle-value dropdown filter. Requires options or inferOptions: true.
numberbooleanCondition + value filter (e.g. > 100, between 50–200). Works with type: "number".
percentagebooleanDual-thumb range slider from 0–100. Works with type: "number" where values are percentages.
datebooleanDate range picker (start/end). Works with type: "date".