useDataTable

State manager for data tables from @clerk/headless. Tracks pagination, sorting, column filters, global filter, and row selection. Each state slice supports the controlled/uncontrolled pattern. Designed for server-side data: you supply the already-fetched page of rows, and the hook tracks which page, sort, and filters to request next.

Usage

import { useDataTable } from '@clerk/headless/hooks';

const {
  rows,
  pagination,
  nextPage,
  previousPage,
  getPageCount,
  rowSelection,
  toggleAllRowsSelected,
} = useDataTable({
  data: pageOfData,        // current page fetched from the server
  getRowId: row => row.id,
  totalCount: 1000,
  defaultPagination: { pageIndex: 0, pageSize: 20 },
  onPaginationChange: newPagination => {
    // re-fetch with the new page/size
  },
});

Options

PropTypeDefaultDescription
dataTData[]requiredCurrent page of rows
getRowId(row, index) => stringString(index)Stable row identifier
totalCountnumberTotal record count (used to compute page count)
sortingSortingStateControlled sort state
defaultSortingSortingState[]Initial uncontrolled sort
onSortingChangeOnChangeFn<SortingState>Called when sort changes
columnFiltersColumnFiltersStateControlled column filters
defaultColumnFiltersColumnFiltersState[]Initial uncontrolled column filters
onColumnFiltersChangeOnChangeFn<ColumnFiltersState>Called when column filters change
globalFilterstringControlled global search string
defaultGlobalFilterstring''Initial uncontrolled global filter
onGlobalFilterChangeOnChangeFn<string>Called when global filter changes
paginationPaginationStateControlled pagination
defaultPaginationPaginationState{ pageIndex: 0, pageSize: 10 }Initial uncontrolled pagination
onPaginationChangeOnChangeFn<PaginationState>Called when pagination changes
rowSelectionRowSelectionStateControlled row selection
defaultRowSelectionRowSelectionState{}Initial uncontrolled row selection
onRowSelectionChangeOnChangeFn<RowSelectionState>Called when selection changes

Return

Rows

ValueTypeDescription
rowsDataTableRow<TData>[]data mapped to row objects

Each DataTableRow has:

FieldTypeDescription
idstringStable row identifier
originalTDataOriginal data item
getIsSelected()() => booleanWhether this row is selected
toggleSelected()() => voidToggle selection for this row

Pagination

ValueTypeDescription
paginationPaginationStateCurrent { pageIndex, pageSize }
setPaginationOnChangeFn<PaginationState>Set pagination state
nextPage()() => voidAdvance one page
previousPage()() => voidGo back one page
setPageSize(n)(size: number) => voidChange page size and reset to page 0
getCanNextPage()() => booleanWhether a next page exists
getCanPreviousPage()() => booleanWhether a previous page exists
getPageCount()() => numberceil(totalCount / pageSize)

Sorting

ValueTypeDescription
sortingSortingStateCurrent sort: Array<{ id: string; desc: boolean }>
setSortingOnChangeFn<SortingState>Set sort state

Filters

ValueTypeDescription
columnFiltersColumnFiltersStateCurrent column filters
setColumnFiltersOnChangeFn<ColumnFiltersState>Set column filters
globalFilterstringCurrent global search string
setGlobalFilterOnChangeFn<string>Set global filter

Row Selection

ValueTypeDescription
rowSelectionRowSelectionStateRecord<string, boolean> keyed by row id
setRowSelectionOnChangeFn<RowSelectionState>Set selection state
getIsAllRowsSelected()() => booleanAll current rows are selected
getIsSomeRowsSelected()() => booleanSome (not all) rows are selected
toggleAllRowsSelected()() => voidSelect all; clear if all already selected

Types

type SortingState       = Array<{ id: string; desc: boolean }>;
type ColumnFiltersState = Array<{ id: string; value: unknown }>;
type PaginationState    = { pageIndex: number; pageSize: number };
type RowSelectionState  = Record<string, boolean>;
type Updater<T>         = T | ((old: T) => T);
type OnChangeFn<T>      = (updaterOrValue: Updater<T>) => void;