What's new in v8

v8 is a full rewrite built around a new headless hook architecture. Every major feature is now composable and usable independently of <DataTable>. Here's what changed.

Column filtering

A new built-in filter popup per column. Set filterable: true on any column to add a filter icon to its header. The filter type ("text", "number", "date") controls the available operators and input widget.

const columns: TableColumn<Row>[] = [
  { name: 'Name',   selector: r => r.name,   filterable: true, filterType: 'text' },
  { name: 'Salary', selector: r => r.salary, filterable: true, filterType: 'number' },
  { name: 'Hired',  selector: r => r.hired,  filterable: true, filterType: 'date' },
];

Filters use a structured FilterState with two independent conditions joined by AND or OR. Supply a custom filterFunction on a column to override the built-in operator logic. → Column filtering docs

Column groups

Span a label across multiple adjacent columns using the new columnGroups prop. Groups render as a second header row above the regular column headers.

<DataTable
  columnGroups={[
    { name: 'Personal',    columnIds: ['first', 'last'] },
    { name: 'Employment',  columnIds: ['role', 'dept', 'salary'] },
  ]}
  columns={columns}
  data={data}
/>

Column groups docs

Drag-to-reorder columns and groups

Users can drag column headers to reorder them. Set reorder: true on each column that should be draggable. Column groups can be dragged as a unit too. Set reorder: true on the group and the entire block moves together.

const columns = [
  { id: 'name', name: 'Name', reorder: true, selector: r => r.name },
  { id: 'dept', name: 'Dept', reorder: true, selector: r => r.dept },
];

<DataTable
  columns={columns}
  onColumnOrderChange={cols => setColumns(cols)}
  data={data}
/>

Column reordering docs

Column visibility hook

useColumnVisibility is a new headless hook for managing a show/hide column picker. It returns a columns array with omit pre-set. Pass it directly to <DataTable>.

const { columns, visibility, toggle, setAll } = useColumnVisibility(rawColumns);

Column visibility docs

Improved loading state

progressPending now distinguishes between initial load and re-fetch:

  • Initial load (no data yet): renders shimmer skeleton rows that match your column layout.
  • Re-fetch (data already showing): dims existing rows and overlays a centered spinner, preserving table structure.

The column header always stays visible in both states. → Loading state docs

Row animations

Set animateRows to stagger row entrances and animate sort transitions. Automatically suppressed when the user has prefers-reduced-motion enabled.

<DataTable animateRows columns={columns} data={data} />

Animations docs

Column separators

Two new props control vertical lines between columns independently for body rows and headers.

<DataTable
  columnSeparator="subtle"   // body: inset 60%-height line
  headerSeparator="full"     // header: full-height line
  columns={columns}
  data={data}
/>

Column separators docs

Headless hooks

All internal logic is now exposed as composable hooks. Use them to build fully custom table markup while keeping the library's sort, pagination, and filter engines.

HookPurpose
useColumnsResolve column definitions and defaults
useTableStateManage sort, page, and selection state
useTableDataSort, paginate, and slice rows
useColumnFilterPer-column filter values and predicate application
useColumnVisibilityShow/hide column state

Headless hooks docs

Imperative ref API

Attach a ref to <DataTable> to call imperative methods. The clearSelectedRows prop is now deprecated in favour of this API.

const ref = useRef<DataTableHandle>(null);
ref.current?.clearSelectedRows();

<DataTable ref={ref} selectableRows columns={columns} data={data} />

New row events

onRowMiddleClicked fires on scroll-click. Use it with onRowClicked to implement open-in-new-tab behavior.

<DataTable
  onRowClicked={row => navigate(`/users/${row.id}`)}
  onRowMiddleClicked={row => window.open(`/users/${row.id}`, '_blank')}
  columns={columns}
  data={data}
/>

Upgrading from v7?

See the Migration guide for a full list of breaking changes and how to update your code.