API and Development
DataTable displays large datasets in a tabular format with built-in features for sorting, filtering, pagination, row selection, and expandable rows, powered by TanStack Table.
DataTable provides a full-featured data table component built on top of the basic Table component from ui-core. It includes advanced functionality like column sorting, global filtering, pagination controls, row expansion, multi-select with bulk actions, action menus, and infinite scroll. Built using TanStack Table for robust table state management, it's designed for displaying and interacting with large, dynamic datasets.
Filter chrome (Filter, SortControl, and related hooks) lives in @prepared911/ui-filters. Prefer importing from that package. @prepared911/ui-data-table may still re-export Filter temporarily (CORE-555).
It also integrates seamlessly with @prepared911/ui-drawer, automatically adding horizontal scroll space when drawers are open to ensure all columns remain accessible.
Use DataTable (from @prepared911/ui-data-table) when you need:
Use Table (from @prepared911/ui-core) when you need:
| Name | Default | Description |
|---|---|---|
columns | required | Array of column definitions specifying how data should be displayed. |
data | required | Array of data objects to display in the table. Each object must have an id property. |
loading | false | Whether the table is currently loading data. Shows skeleton loaders. |
showLoadingFooter | false | Whether to show a loading indicator at the bottom of the table (useful for infinite scroll). |
tableRef | Ref to access the table instance and methods. | |
hidePagination | false | Whether to hide the pagination controls. |
pageSize | 50 | Number of rows to display per page. |
initialPage | 0 | Initial page index to display. |
manualPagination | false | Whether pagination is handled server-side. When true, you must provide pages and rowCount. |
pages | Total number of pages. Required when using server-side pagination. Set to -1 for unknown page count (cursor-based pagination). | |
rowCount | Total number of rows across all pages. Required when using server-side pagination. | |
manualFiltering | false | Whether filtering is handled server-side. |
manualSorting | false | Whether sorting is handled server-side. |
onSortingChange | Callback when sorting changes: (sorting: Array<{ id: string; desc: boolean }>) => void. | |
columnVisibility | Record mapping column IDs to their visibility state. Columns not in this object default to visible. | |
onReady | Callback when the table is ready: (ready: boolean) => void. | |
onPageChange | Callback when page changes: (pagination: DataTablePaginationState) => void. | |
onScrollEnd | Callback when table is scrolled to the end. Useful for infinite scroll. | |
expandIconClosed | SVGAsset.ChevronDown | Icon to display for collapsed expandable rows. |
expandIconOpen | SVGAsset.ChevronUp | Icon to display for expanded rows. |
actionMenu | Function that receives row data and returns MenuItem components for an action menu. | |
onRowClick | Callback when a row is clicked: (row: TData) => void. | |
selectedRowId | ID of the row to highlight as selected. | |
multiSelect | false | Whether to enable multi-row selection with checkboxes. |
showCheckboxes | false | When true and multiSelect is enabled, header and row checkboxes stay visible without hovering the table. Mirrored as data-show-checkboxes on the table root when both apply. |
showActionMenuTriggers | false | When true and actionMenu is provided, each row's action menu trigger stays visible without row hover. Mirrored as data-show-action-menu-triggers on the root when both apply. |
fluidWidth | false | When true, column layout uses only fluid units (% / flex weights); column minWidth/maxWidth and table minWidth do not constrain layout, and px/rem column widths are treated like unspecified flex columns. Root gets data-fluid-width. |
floatingToolbarConfig | Configuration for the floating toolbar with bulk actions when using the built-in toolbar. With multiSelect, may be omitted when bulk UI lives outside the table. | |
initialSorting | [] | Initial sorting state: [{ id: "columnId", desc: true }] for descending, [{ id: "columnId", desc: false }] for ascending. |
autoResetPageIndex | true | Whether to reset the page index when data changes. |
Show loading indicators while data is being fetched.
Display skeleton screens during initial load.
Show a loading indicator for additional data (infinite scroll).
Implement infinite scroll for continuous data loading.
With summaryDisplay, summaryFallback appears only when no value is selected; selected option labels remain visible even when an option label matches the filter label. With two or more selected options, the value reads as the first option label plus +N (for example Status: Draft + 3). A hover tooltip lists the overflow labels; keyboard users discover the full selection by opening the filter menu. Category filter pills use the same helper with a visible count of two (first, second + N).
The Filter component uses a reducer/dispatch pattern with typed events:
Enable column sorting for better data organization.
Users can click column headers to sort. Click again to reverse sort direction, and a third time to clear sorting.
Note: Columns with empty headers (null, undefined, empty string, or whitespace) automatically have sorting disabled to prevent sorting on checkbox or action columns.
Set an initial sort order when the table loads.
Handle sorting on the server for large datasets.
Control how data is paginated.
Paginate data on the client (default behavior).
The table automatically handles pagination for the provided dataset.
Handle pagination on the server for large datasets.
For cursor-based pagination where total pages are unknown, set pages to -1.
When pages is -1, TanStack Table's getCanNextPage() and getCanPreviousPage() will not prematurely disable navigation buttons.
Remove pagination controls for scrollable tables.
Define columns with custom renderers and sizing.
Define column structure and sizing.
Column size represents the percentage of total table width. Sizes are automatically normalized to sum to 100% across all visible columns.
Customize how cell data is displayed.
Add icons to cells for visual enhancement.
Add metadata for loading states and alignment.
Exclude specific columns from global filtering.
Add action menus to each row for row-specific operations.
Action menus appear as three-dot menu buttons on hover.
Handle row clicks for navigation or detail views.
Rows become clickable and display hover states.
Highlight a specific row by ID.
Create expandable rows for additional details or nested content.
Expand icons appear in the first column for rows with expandable content.
Display parent-child relationships in tree structures.
Child rows are indented and can be expanded/collapsed.
DataTable automatically handles horizontal scrolling when used alongside drawers from @prepared911/ui-drawer. When a right-anchored drawer opens, the table detects it and adds extra horizontal space to allow users to scroll and view columns that would otherwise be hidden behind the drawer.
This integration works automatically with no additional configuration required:
useDrawerSpacing hook listens to the drawer store from @prepared911/ui-drawerspacing = drawerWidth - (viewportRight - tableRight)-drawer-spacing) and used to extend the scrollable areauseHorizontalScrollSync hook keeps header and body scroll positions synchronizedThe table uses the native scrollend event for reliable infinite scroll detection:
The onScrollEnd callback fires when the user scrolls within 50 pixels of the bottom, enabling smooth infinite scroll experiences.
Access table instance for programmatic control.
The Filter component provides a comprehensive filtering UI with search, category filters, quick filters, and column visibility controls.
| Name | Default | Description |
|---|---|---|
onChange | Unified callback for all filter changes. Uses a reducer/dispatch pattern with typed events. | |
searchValue | Current search value for controlled mode. | |
hideSearchValue | false | Whether to hide the search input. |
categories | [] | Array of filter categories to display in the filter menu. |
quickFilters | [] | Array of quick filters to display as pill buttons. |
appliedFilters | Array of currently applied filters for controlled mode. | |
segmentedControlOptions | Options for the segmented control (view mode switching). | |
segmentedControlValue | Current value of the segmented control. | |
renderCustomInput | Function to render custom input components for filter categories. | |
showClearButton | true | Whether to show the "Clear Filters" button. |
columns | Array of table columns for column visibility menu. | |
columnVisibility | Record mapping column IDs to visibility state. | |
manualFiltering | false | Whether filtering is handled server-side. |
debounceSearchMs | omit / 0 | Debounce delay for search input in milliseconds. Omit or 0 for immediate updates. |
The useFilteredData hook provides declarative filtering with zero custom code.
The filterConfig object supports:
For complex filtering logic, provide a custom filter function.
Render custom input components for quick filters (e.g., date pickers).
Switch between different data views while preserving applicable filters.
Enable users to show/hide columns via the column visibility menu.
The first column is always visible and cannot be hidden.
For simple search without category filters, use DataTableGlobalFilter.
Enable multi-select with bulk operations.
When rows are selected, a floating toolbar appears with the configured bulk actions.
Available bulk action types:
BulkActionType.DeleteBulkActionType.ArchiveBulkActionType.EditBulkActionType.ExportBulkActionType.ApproveBulkActionType.RejectBulkActionType.AssignBulkActionType.MoveBulkActionType.CopyBulkActionType.CustomThe clearSelectionAfterAction property controls whether row selections are cleared after the action completes. Defaults to true for destructive actions.
Individual rows can be made non-selectable by setting selectable: false on the row data.
On this page