# useDocyrusDataTable URL: /docs/web/hooks/use-docyrus-data-table One-call wiring of a Docyrus data source to a fully configured DataTable + toolbar (DataGridViewSelect, search, filters, group, sort) — including row fetching with view-derived query parameters and an optional side-panel filter rail. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/hooks-use-docyrus-data-table ``` ## Overview `useDocyrusDataTable` is the table-flavored sibling of [`useDocyrusDataGrid`](/docs/web/hooks/use-docyrus-data-grid). It produces a TanStack Table instance + toolbar wired to the same Docyrus saved-views, filter, and items endpoints, but renders rows through ` | Option | Type | Default | Description | |--------|------|---------|-------------| | `data` | `Array` | — | Pre-resolved rows. Skips the internal items query. | | `collection` | `{ list: (params?) => Promise<…> }` | — | TanStack DB collection. `list(resolvedListParams)` is called inside `useQuery`. | | `listParams` | `DocyrusDataGridListParams` | — | Extra query params merged on top of the view-derived payload. | | `defaultLimit` | `number` | `100` | Default page size when no `limit` is supplied via `listParams`. | | `enableItemsQuery` | `boolean` | `true` when no `data` | Toggle the internal items query. | | `showSelectColumn` | `boolean` | `true` | Show the row-select checkbox column as the **first** column. | | `enableRowNumbers` | `boolean` | `true` | Show 1-based row numbers on the select column when not selected. | | `selectColumn` | `ColumnDef` | — | Override the default select column entirely. | | `actionsColumn` | `ColumnDef` | — | Optional actions column rendered as the **second** column. | | `extraColumns` | `Array>` | — | Extra columns prepended after the select + actions columns. | | `inferColumnsFromData` | `boolean` | `false` | Derive table columns from the loaded rows when the data source exposes **no schema fields** (e.g. system data sources, typically paired with `enabled: false`) and no `extraColumns` are supplied. Columns are built from the union of keys in the first rows; identity/label keys (`id`, `name`, `title`, …) lead and audit keys (`created_on`, …) trail. Ignored when schema fields or `extraColumns` exist. | | `mapColumn` | `(field, defaultColumn) => ColumnDef \| null` | — | Per-field column override. Return `null` to skip a field. | | `enableViewSelect` / `enableSearchInput` / `enableFilterMenu` / `enableGroupMenu` / `enableSortMenu` / `enableReloadButton` | `boolean` | `true` | Toggle individual toolbar items. The toolbar filter menu (`enableFilterMenu`) and the side filter panel (`enableSideFilters`) are independent — both can be active at the same time. | | `enableSideFilters` | `boolean` | `false` | Activate the side-panel filter rail rendered alongside the table. When `true`, the hook returns a ready-to-render `sideFilters` element wired to `` and merges its emitted `RuleGroupType` into the items request alongside the saved view filter and toolbar filter rules. Requires `sideFiltersConfig`. | | `sideFiltersConfig` | `DocyrusDataTableSideFiltersConfig` | — | Configuration for the side panel. Required when `enableSideFilters` is `true`. See [Side panel filters](#side-panel-filters). | | `sideFiltersDefaultExpanded` | `boolean` | `true` | Initial expanded state. When `false`, the panel mounts collapsed and renders a thin vertical rail with a 90°-rotated "Filters" label that re-expands the panel on click. | | `sideFiltersExpanded` | `boolean` | — | Controlled expanded state. Pair with `onSideFiltersExpandedChange`. | | `onSideFiltersExpandedChange` | `(expanded: boolean) => void` | — | Called when the user toggles the panel via the close icon (top right of the panel header) or the rotated rail button. | | `sideFiltersWidth` | `number \| string` | `280` | Width of the side panel when expanded. Number → px. | | `enableServerExportMenu` | `boolean` | `true` | Show the server-side data export dropdown in the toolbar. | | `serverExportLimit` | `number` | `10000` | Row cap forwarded to the server export endpoint. | | `onReload` | `() => void` | — | Called when the reload button is clicked, after the items query refetches. | | `searchPlaceholder` | `string` | `'Search...'` | Placeholder for the toolbar search input. | | `searchDebounceMs` | `number` | `300` | Debounce in ms before the search input is sent as `filterKeyword`. | | `toolbarClassName` | `string` | — | Extra className for the toolbar root. | | `toolbarStartContent` / `toolbarEndContent` | `ReactNode` | — | Custom nodes prepended/appended to the built-in toolbar. | | `tableClassName` / `tableContainerClassName` | `string` | — | Forwarded to ``. | | `emptyText` | `string` | — | Empty-state text forwarded to ``. | ### Return Value | Property | Type | Description | |----------|------|-------------| | `table` | `Table` | TanStack Table instance — pass to ``. | | `tableProps` | `Omit` | Spread onto ``. | | `toolbar` | `ReactNode` | Pre-wired toolbar element ready to render above the table. | | `sidePanel` | `ReactNode` | Vertical view-picker panel. `null` for `'horizontal-tabs'`/`'dropdown'` view variants. | | `sideFilters` | `ReactNode` | Side-panel filter rail. `null` when `enableSideFilters` is `false`. Renders the full `` panel (with a panel-close icon in the header) when expanded, and a thin vertical rail (with a 90°-rotated "Filters" label) when collapsed. | | `sideFiltersExpanded` | `boolean` | Current expanded state of the side filter panel. | | `setSideFiltersExpanded` | `(expanded: boolean) => void` | Programmatically toggle the side filter panel. | | `sideFiltersQuery` | `RuleGroupType \| undefined` | Current `RuleGroupType` emitted by the side panel — already merged into `resolvedListParams.filters`. | | `items` | `Array` | Resolved rows passed to the table. | | `resolvedListParams` | `DocyrusDataGridListParams` | The list params actually sent to the backend (after merging view state, search, side panel filters, and `listParams`). | | `pagingMode` | `'standard' \| 'virtual-scroll' \| undefined` | Resolved paging mode for the active view. | | `reload` | `() => void` | Triggers refetch of the data source, views, and items queries plus the optional `onReload` callback. | | `views` | `SavedDataGridView[]` | Saved views mapped from the backend shape. | | `fields` | `FullField[]` | Fields mapped for `react-querybuilder` filter editor. | | `dataSource` | `DataSource \| undefined` | Raw data source metadata response. | | `activeViewId` | `string` | Id of the currently active view. | | `setActiveViewId` | `(viewId: string) => void` | Programmatically switch views. Persisted per user (follows `persistState` storage when enabled, `localStorage` otherwise). | | `isLoading` | `boolean` | `true` until all queries (data source, views, items) have resolved. | | `error` | `Error \| null` | First error from any of the queries. | | `refetch` | `() => void` | Alias for `reload`. | ## Side panel filters When `enableSideFilters` is `true`, the hook renders a [``](/docs/web/components/data-table-side-filters) rail alongside the table. The panel emits a `RuleGroupType` whenever the user adjusts a filter; the hook ANDs it onto the saved view's `filterQuery` and any toolbar filter menu rules before sending the items request — so side filters, toolbar filters, and the saved view all stack. The toolbar filter menu (`enableFilterMenu`) is **not** auto-hidden; both can be active at the same time. ### Collapse / expand - `sideFiltersDefaultExpanded` controls the initial state. Default `true`. - When **expanded**, a panel-close icon (top right of the panel header) collapses it to a vertical rail. - When **collapsed**, the rail shows a 90°-rotated "Filters" label (with the active-filter count appended) that re-expands the panel on click. - For controlled collapse state, pass `sideFiltersExpanded` + `onSideFiltersExpandedChange`. ### `DocyrusDataTableSideFiltersConfig` | Field | Type | Default | Description | |-------|------|---------|-------------| | `columnsConfig` | `ReadonlyArray>` | — | **Required.** Filter columns for the panel. Mirrors the `columnsConfig` accepted by `useDataTableFilters` / `useDataTableSideFilters`. | | `strategy` | `'server' \| 'client'` | `'server'` | Filter strategy. Server-paged tables should use `'server'` so values surface as `RuleGroupType` rules; `'client'` filters the in-memory dataset. | | `defaults` | `SideFilterDefaults` | — | Per-column UI hints (`collapsed`, `mode`, `showMoreThreshold`, `hidden`, `sticky`, etc.). | | `sections` | `ReadonlyArray` | — | Optional grouping of filter sections into named blocks. | | `variant` | `'default' \| 'bordered' \| 'compact'` | `'default'` | Visual variant for the panel container. | | `title` | `ReactNode` | `'Filters'` | Header title. Pass `null` to hide. | | `showActiveChips` | `boolean` | `true` | Show the active-filter chip strip below the header. | | `showClearAll` | `boolean` | `true` | Show the "Clear all" button next to the title when any filter is active. | | `searchable` | `boolean \| string` | `false` | Render a search input above the sections that drives the first text-typed column (or a column id you pass explicitly). | | `clearAllLabel` | `string` | `'Clear all'` | Override for the "Clear all" label. | | `clearLabel` | `string` | `'Clear'` | Override for the per-section "Clear" label. | | `locale` | `Locale` | `'en'` | Locale forwarded to the underlying filter UI. | | `className` | `string` | — | Extra className for the panel root. | | `collapseAriaLabel` | `string` | `'Collapse filters'` | Override for the collapse-button accessible label. | | `expandAriaLabel` | `string` | `'Expand filters'` | Override for the expand-button accessible label. | | `collapsedWidth` | `number \| string` | `36` | Width of the collapsed rail. Number → px. | ### Usage ```tsx 'use client'; import { useDocyrusAuth } from '@docyrus/signin'; import { DataTable } from '@docyrus/ui/components/data-table'; import { useDocyrusDataTable } from '@docyrus/ui/library/hooks/use-docyrus-data-table'; import { createColumnConfigHelper } from '@docyrus/ui/components/data-table-filter'; type OrganizationRow = { id: string; name: string; status: 'active' | 'archived' }; const dtf = createColumnConfigHelper(); const sideFilterColumns = [ dtf .text() .id('name') .accessor(row => row.name) .displayName('Name') .build(), dtf .option() .id('status') .accessor(row => row.status) .displayName('Status') .options([ { value: 'active', label: 'Active' }, { value: 'archived', label: 'Archived' } ]) .build() ] as const; export function OrganizationsTable() { const { client } = useDocyrusAuth(); if (!client) return null; const { table, tableProps, toolbar, sideFilters } = useDocyrusDataTable({ client, appSlug: 'crm', dataSourceSlug: 'organization', enableSideFilters: true, sideFiltersDefaultExpanded: true, sideFiltersWidth: 280, sideFiltersConfig: { columnsConfig: sideFilterColumns, strategy: 'server', defaults: { status: { mode: 'inline-checkbox' } } } }); return (
{toolbar}
{sideFilters}
); } ```