Shadcn React Table

Search documentation

Search the docs

useDataTable options

useDataTable(options) accepts everything TanStack's TableOptions accepts (controlled state, on*Change, manual* flags, getRowId, getSubRows, initialState, row models, …) plus the data-table options below. The table below is generated from the source types; defaults come from the hook implementation.

OptionTypeDefaultDescription
localization?Partial<DataTableLocalization>
icons?Partial<DataTableIcons>Override any subset of the table's icons.
defaultDensity?Density"comfortable"Initial density. Uncontrolled.
defaultShowColumnFilters?booleanfalseInitially show the filter row. Uncontrolled.
isLoading?booleanfalseShow the loading affordances (progress bar; skeletons when empty; a dimming overlay over existing rows). Toggle each independently below.
isSaving?booleanfalseShow the progress bar for an in-flight save/mutation. Defaults the progress bar on without replacing rows with skeletons.
showProgressBars?booleanShow the top progress bar. Default: `isLoading || isSaving`.
showSkeletons?booleanReplace the body with skeleton rows while empty. Default: `isLoading`.
showLoadingOverlay?booleanDim existing rows with an overlay while loading. Default: `isLoading`.
enableFacetedValues?booleantrueCompute faceted unique values / min-max (auto select options + range bounds). Default true; disable to skip the faceted row models.
enableColumnActions?booleantrue
enableColumnFilterModes?booleantrueShow the filter-mode menu adornment on filter fields. Default true.
enableFilterMatchHighlighting?booleantrueHighlight matched substrings in cells. Default true.
enableGlobalFilter?booleantrueShow the expandable global search in the toolbar. Default true.
enableGlobalFilterModes?booleantrueShow the global search mode menu (fuzzy/contains/…). Default true.
enableGlobalFilterRankedResults?booleanfalseWhile the global search is in fuzzy mode, order rows by best match (most relevant first) until the user applies their own sort. Default false — MRT defaults this on, but the data table keeps it off so searching never silently reorders rows unless opted in. Ignored for non-fuzzy modes, when grouping or expanded, or under manual sorting/filtering.
defaultGlobalFilterMode?GlobalFilterMode"fuzzy"Initial global search mode. Default "fuzzy".
density?DensityControlled density. Pair with `onDensityChange`; omit for uncontrolled (seed the initial value with `defaultDensity`).
onDensityChange?(density: Density) => voidCalled whenever the density changes (toolbar toggle or programmatic).
isFullscreen?booleanControlled full-screen state. Pair with `onIsFullscreenChange`.
onIsFullscreenChange?(isFullscreen: boolean) => voidCalled whenever the full-screen state is toggled.
showColumnFilters?booleanControlled filter-row visibility. Pair with `onShowColumnFiltersChange`; omit for uncontrolled (seed with `defaultShowColumnFilters`).
onShowColumnFiltersChange?(showColumnFilters: boolean) => voidCalled whenever the filter row is shown or hidden.
enableAdvancedFilter?booleanfalseEnable the advanced filter panel: compound rules joined by AND/OR, applied on top of the per-column filters. A toolbar button opens the panel and shows the active-rule count. Default false.
advancedFilter?AdvancedFilterGroupControlled advanced filter. Pair with `onAdvancedFilterChange`; omit for uncontrolled (seed with `defaultAdvancedFilter`).
defaultAdvancedFilter?AdvancedFilterGroupInitial advanced filter for uncontrolled usage.
onAdvancedFilterChange?(filter: AdvancedFilterGroup) => voidCalled whenever the advanced filter changes.
globalFilterMode?GlobalFilterModeControlled global search mode. Pair with `onGlobalFilterModeChange`; omit for uncontrolled (seed with `defaultGlobalFilterMode`).
onGlobalFilterModeChange?(mode: GlobalFilterMode) => voidCalled whenever the global search mode changes.
enableColumnOrdering?booleanfalseDrag-and-drop column reordering (adds a grip to each header).
enableColumnPinning?booleanfalseColumn pinning (left/right) via the column-actions menu + sticky columns.
enableColumnResizing?booleanfalseColumn resizing via an edge drag handle.
enableColumnAutosize?booleanDouble-clicking a column's resize handle auto-sizes it to fit its widest value. Defaults to `enableColumnResizing`. When off, double-click resets the column to its default size instead.
enableRowOrdering?booleanfalseDrag-and-drop row reordering (adds a drag-handle column).
enableRowPinning?booleanfalseRow pinning (top) via a pin toggle in the row-number column.
enableRowNumbers?booleanfalseAdds a leading row-number column.
rowNumberMode?"static" | "original""static""static" tracks the current view (page-aware); "original" uses source index.
onRowOrderChange?(activeRowId: string, overRowId: string) => voidCalled on a row drag-and-drop reorder; the consumer reorders its data.
enableGrouping?booleanfalseRow grouping (group-by menu + drop-to-group zone + aggregated group rows).
enableExpanding?booleanRow expansion (tree sub-rows and/or detail panels). Auto-on with grouping or when `renderDetailPanel`/`getSubRows` is provided.
enableStickyFooter?booleantruePin the footer (aggregation/footer cells) to the bottom of the surface. Default true (matches the sticky header).
renderDetailPanel?(props: { row: Row<TData> table: DataTableInstance<TData> }) => React.ReactNodeRender an expanding detail panel for each row.
enableEditing?booleanfalseEnable inline editing.
editDisplayMode?EditDisplayMode"cell"How edits are surfaced. Default "cell".
createDisplayMode?CreateDisplayMode"modal"How the create form is surfaced, independent of `editDisplayMode`: `"modal"` (dialog, default), `"row"` (an inline editable row at the top of the table), or `"custom"` (you render it from `isCreating` + `rowDraft`).
createRowDefaults?Record<string, unknown>Default values for the create form, keyed by column id.
enableClickToCopy?booleanfalseShow a click-to-copy affordance on all cells (per-column override via meta).
onEditCellSave?(props: { row: Row<TData> column: Column<TData, unknown> value: unknown table: DataTableInstance<TData> }) => void
onSaveRow?(props: { row: Row<TData> values: Record<string, unknown> table: DataTableInstance<TData> exit: () => void }) => void
onCreateRow?(props: { values: Record<string, unknown> table: DataTableInstance<TData> exit: () => void }) => void
renderRowActions?(props: { row: Row<TData> table: DataTableInstance<TData> }) => React.ReactNode
renderCellActionMenuItems?(props: { cell: Cell<TData, unknown> row: Row<TData> table: DataTableInstance<TData> }) => React.ReactNode
renderRowActionMenuItems?(props: { row: Row<TData> table: DataTableInstance<TData> }) => React.ReactNodeRender a kebab menu in the row-actions column. Returns the menu items (e.g. `<DropdownMenuItem>`); injects the actions column automatically.
renderColumnActionsMenuItems?(props: { column: Column<TData, unknown> table: DataTableInstance<TData> }) => React.ReactNodeAppend custom items to the bottom of every column-actions menu. Returns the items (e.g. `<DropdownMenuItem>`); a separator is added before them.
renderColumnFilterModeMenuItems?(props: { column: Column<TData, unknown> modes: FilterMode[] currentMode: FilterMode onSelect: (mode: FilterMode) => void table: DataTableInstance<TData> }) => React.ReactNodeReplace the radio items in a column's filter-mode menu. Render your own items and call `onSelect(mode)` to switch; `modes` is the allowed set.
renderGlobalFilterModeMenuItems?(props: { modes: GlobalFilterMode[] currentMode: GlobalFilterMode onSelect: (mode: GlobalFilterMode) => void table: DataTableInstance<TData> }) => React.ReactNodeReplace the radio items in the global-search mode menu. Render your own items and call `onSelect(mode)` to switch; `modes` is the allowed set.
onRowClick?(props: RowEvent<TData>) => voidFired when a body row is clicked / double-clicked.
onRowDoubleClick?(props: RowEvent<TData>) => void
onCellClick?(props: CellEvent<TData>) => voidFired when a body cell is clicked / double-clicked.
onCellDoubleClick?(props: CellEvent<TData>) => void
enableRowVirtualization?booleanfalseVirtualize body rows for large datasets (recommended past ~100 rows). The table surface becomes the scroll container — give it a bounded height via `className`/`style` (defaults to `max-h-[600px]`). Disables row DnD.
enableColumnVirtualization?booleanfalseVirtualize columns for very wide tables. Applies fixed column widths and is not combined with column pinning/ordering.
estimateRowHeight?number52Estimated row height (px) for the virtualizer. Default 52.
virtualOverscan?number8Extra rows rendered above/below the viewport. Default 8.
rowVirtualizerOptions?RowVirtualizerOptions<TData>Partial `@tanstack/react-virtual` options merged into the row virtualizer (overrides the built-in `count`/`estimateSize`/`overscan`/`measureElement`). Accepts an object or a `({ table }) => options` function.
columnVirtualizerOptions?ColumnVirtualizerOptions<TData>Partial `@tanstack/react-virtual` options merged into the column virtualizer. Accepts an object or a `({ table }) => options` function.
rowVirtualizerInstanceRef?React.RefObject<DataTableRowVirtualizer | null>Ref populated with the row `Virtualizer` instance for imperative control (e.g. `scrollToIndex`). Only set when `enableRowVirtualization`.
columnVirtualizerInstanceRef?React.RefObject<DataTableColumnVirtualizer | null>Ref populated with the column `Virtualizer` instance. Only set when `enableColumnVirtualization`.
enableExport?booleanfalseShow a CSV/Excel export menu in the toolbar.
exportFileName?stringBase file name for exports (no extension). Default "export".
enableStickyHeader?booleantrue
enablePagination?booleantrue
positionPagination?"top" | "bottom" | "both" | "none""bottom"Where the pagination controls render. Default "bottom". "none" keeps pagination active but hides the controls.
paginationDisplayMode?PaginationDisplayMode"default"Pagination control style: `"default"` (range label + first/prev/next/last buttons), `"pages"` (numbered page buttons), or `"custom"` (render your own via `renderBottomToolbarCustomActions`). Default "default".
columnFilterDisplayMode?ColumnFilterDisplayMode"subheader"Where column filter inputs live: `"subheader"` (a filter row under the header, default), `"popover"` (per-column popovers opened from the column header), or `"custom"` (you render them).
positionGlobalFilter?"left" | "right" | "none""right"Which toolbar region the global search renders in. Default "right" (the internal-actions cluster). "left" places it next to the title/actions; "none" hides it (same as `enableGlobalFilter: false`).
positionToolbarAlertBanner?"top" | "bottom" | "none""top"Where the row-selection alert banner renders. Default "top".
positionToolbarDropZone?"top" | "bottom" | "both" | "none""top"Where the group-by drop zone renders (grouping only). Default "top".
positionActionsColumn?"first" | "last""last"Position of the auto-injected row-actions column. Default "last".
positionExpandColumn?"first" | "last""first"Position of the auto-injected expand column (tree / detail panel). Default "first".
selectAllMode?"page" | "all""page"Select-all scope for the header checkbox: the current page ("page", default) or every row ("all").
enableSelectAll?booleantrueShow the select-all checkbox in the selection column header. Default true.
enableTopToolbar?booleantrue
enableBottomToolbar?booleantrue
enableDensityToggle?booleantrueShow the density toggle in the toolbar. Default true.
enableFullscreenToggle?booleantrueShow the full-screen toggle in the toolbar. Default true.
enableToolbarInternalActions?booleantrueShow the toolbar's internal icon-action cluster (search, filters, column visibility, export, density, full screen). Default true. Hides the whole cluster at once; use the per-item flags for finer control.
enableKeyboardNavigation?booleantrue
title?React.ReactNode
renderToolbarActions?(props: DataTableSlotProps<TData>) => React.ReactNodeCustom content rendered in the top toolbar's left region (next to the title), e.g. bulk-action buttons.
renderTopToolbar?(props: DataTableSlotProps<TData>) => React.ReactNodeReplace the entire top toolbar with custom content.
renderBottomToolbar?(props: DataTableSlotProps<TData>) => React.ReactNodeReplace the entire bottom toolbar (pagination region) with custom content.
renderToolbarInternalActions?( props: DataTableSlotProps<TData> ) => React.ReactNodeReplace the top toolbar's internal icon-action cluster with custom content.
renderBottomToolbarCustomActions?( props: DataTableSlotProps<TData> ) => React.ReactNodeCustom content rendered in the bottom toolbar's left region (next to pagination), e.g. summary text or actions.
renderCaption?(props: DataTableSlotProps<TData>) => React.ReactNodeRender a `<caption>` for the table (e.g. an accessible summary).
renderEmpty?(props: DataTableSlotProps<TData>) => React.ReactNode

Pass-through options

Options not listed here (e.g. data, columns, state, manualPagination, rowCount, enableRowSelection, enableMultiSort) are standard TanStack Table options and behave exactly as documented there.