Data Table

A feature-rich data table built on TanStack Table and shadcn/ui's Table primitives. Supports sorting, column filtering, pagination, row selection, column visibility toggling, and row actions out of the box.

Demo

All features active: type in the filter box to search by email, click column headers to sort, open the Columns menu to toggle visibility, tick checkboxes to select rows, and use the button on any row for row-level actions.

Amount
pendingalice@example.com
$100.00
processingbob@example.com
$125.00
successcarol@example.com
$250.00
faileddave@example.com
$85.00
successeve@example.com
$310.00
pendingfrank@example.com
$45.00
processinggrace@example.com
$780.00
successheidi@example.com
$200.00
failedivan@example.com
$55.00
pendingjudy@example.com
$430.00

0 of 12 row(s) selected.

Page 1 of 2

Design Guidelines

Do

  • Define columns outside the component. Placing columns outside the render function prevents the array reference from changing on every render.
  • Use server-side models for large datasets. Pass manualPagination and manualSorting to TanStack Table and fetch data from a server action or API route.
  • Provide stable row IDs. Use getRowId to keep selection state stable across pagination and re-fetches.

Don't

  • Don't define columns inline. Inline column definitions recreate the array on every render, causing unnecessary reconciliation work.
  • Don't load thousands of rows client-side. Client-side filtering and sorting works well for small datasets; switch to server-side models for large ones.
  • Don't skip accessible labels on icon buttons. Checkbox columns and icon-only action buttons need aria-label or sr-only text.

Developer Reference

DataTable Props

data
Array of row data objects.
columns
TanStack ColumnDef<TData, TValue>[] array.
filterColumn?
Accessor key of the column to filter on.
filterPlaceholder?
Placeholder text for the filter input. Default: "Filter..."

Built-in Column Features

  • Sorting — call column.toggleSorting() in the header render function.
  • Column hiding — set enableHiding: false to pin a column in the Columns menu.
  • Row selection — use id: "select" with enableSorting: false and enableHiding: false.
  • Row actions — use id: "actions" with a DropdownMenu in the cell renderer.