Skip to content

Hooks

Custom React hooks for table functionality including useDataTable, useDebounce, and more.

Custom React hooks for table functionality.

Hook to access the table instance and context from any child component.

import { useDataTable } from "@/components/niko-table/core/data-table-context"
export function CustomComponent() {
const { table, isLoading, columns } = useDataTable()
const rowCount = table.getFilteredRowModel().rows.length
const pageCount = table.getPageCount()
return (
<div>
<p>Showing {rowCount} rows</p>
<p>
Page {table.getState().pagination.pageIndex + 1} of {pageCount}
</p>
</div>
)
}
Property Type Description
table Table<TData> The TanStack Table instance.
columns DataTableColumnDef<TData>[] Column definitions array.
isLoading boolean Whether the table is in a loading state.
setIsLoading (isLoading: boolean) => void Function to update loading state.

Hook to debounce a value, useful for search inputs and filters.

import { useDebounce } from "@/components/niko-table/hooks/use-debounce"
function SearchFilter() {
const [search, setSearch] = useState("")
const debouncedSearch = useDebounce(search, 500)
useEffect(() => {
// This only runs after user stops typing for 500ms
console.log("Searching for:", debouncedSearch)
}, [debouncedSearch])
return (
<input
value={search}
onChange={e => setSearch(e.target.value)}
placeholder="Search..."
/>
)
}
Name Type Default Description
value T - The value to debounce (required).
delay number 300 The delay in milliseconds before updating.

The debounced value of type T.

Hook that derives the title for a column filter component.

import { useDerivedColumnTitle } from "@/components/niko-table/hooks/use-derived-column-title"
function ColumnHeader({ column }: { column: Column<Product> }) {
// Priority: title prop → column.meta.label → formatted accessorKey
const title = useDerivedColumnTitle(column, "first_name")
// Returns "First Name" (formatted from accessorKey)
const titleWithMeta = useDerivedColumnTitle(column, "firstName")
// Returns column.columnDef.meta.label if set, otherwise "First Name"
const titleWithOverride = useDerivedColumnTitle(column, "firstName", "Custom Title")
// Returns "Custom Title" (explicit title always wins)
return <span>{title}</span>
}
Name Type Description
column Column<TData> The table column.
accessorKey string The accessor key of the column.
title string Optional title override.

The derived title string (priority: title prop → column.meta.label → formatted accessorKey).

Hook to generate options for select/multiSelect columns from table data.

import { useGeneratedOptions } from "@/components/niko-table/hooks/use-generated-options"
function FilterPanel({ table }: { table: Table<Product> }) {
const optionsByColumn = useGeneratedOptions(table, {
showCounts: true,
dynamicCounts: true,
limitToFilteredRows: true,
includeColumns: ["category", "brand"],
})
// optionsByColumn.category → [{ value: "electronics", label: "Electronics", count: 42 }, ...]
// optionsByColumn.brand → [{ value: "apple", label: "Apple", count: 18 }, ...]
return (
<div>
{Object.entries(optionsByColumn).map(([columnId, options]) => (
<FacetedFilter key={columnId} columnId={columnId} options={options} />
))}
</div>
)
}
Name Type Default Description
table Table<TData> - TanStack Table instance (required).
config GenerateOptionsConfig - Configuration object.
config.showCounts boolean true Include counts for each option.
config.dynamicCounts boolean true Recompute counts based on filtered rows.
config.limitToFilteredRows boolean true Generate options from filtered rows only.
config.includeColumns string[] - Only generate options for these column ids.
config.excludeColumns string[] - Exclude these column ids from generation.
config.limitPerColumn number - Limit number of generated options per column.

A record mapping column IDs to arrays of Option objects.

Hook for managing keyboard shortcuts with fine-grained control.

import { useKeyboardShortcut } from "@/components/niko-table/hooks/use-keyboard-shortcut"
useKeyboardShortcut({
key: "f",
onTrigger: () => setFilterOpen(true),
condition: () => !isInputFocused,
})
useKeyboardShortcut({
key: "f",
requireShift: true,
onTrigger: () => clearAllFilters(),
})
Name Type Default Description
key string - The key to listen for (required).
onTrigger () => void - Function to call when shortcut is triggered.
enabled boolean true Whether the shortcut is enabled.
requireShift boolean false Whether to require Shift key.
requireCtrl boolean false Whether to require Ctrl/Cmd key.
requireAlt boolean false Whether to require Alt key.
preventDefault boolean true Whether to prevent default browser behavior.
stopPropagation boolean false Whether to stop event propagation.
condition () => boolean - Condition function to determine if shortcut should trigger.

Batch version of useKeyboardShortcut for managing multiple keyboard shortcuts at once with a single event listener.

import { useKeyboardShortcuts } from "@/components/niko-table/hooks/use-keyboard-shortcut"
useKeyboardShortcuts([
{ key: "f", onTrigger: () => setFilterOpen(true) },
{ key: "s", onTrigger: () => setSortOpen((prev) => !prev) },
{ key: "f", requireShift: true, onTrigger: () => clearFilters() },
])
Name Type Description
shortcuts UseKeyboardShortcutOptions[] Array of shortcut configs (same as useKeyboardShortcut).

Convenience wrapper around useGeneratedOptions that generates options for a single column.

import { useGeneratedOptionsForColumn } from "@/components/niko-table/hooks/use-generated-options"
const categoryOptions = useGeneratedOptionsForColumn(table, "category", {
showCounts: true,
dynamicCounts: true,
})
Name Type Description
table Table<TData> TanStack Table instance (required).
columnId string The column ID to generate options for.
config GenerateOptionsConfig Optional configuration object.

An array of Option objects for the specified column.


  • Fix: Column definitions reactivity — The hook now properly tracks changes to column definitions passed to the table. Previously, the internal columns memo only depended on the table reference, which is stable across renders in TanStack Table. This caused the hook to return stale options when column definitions were dynamically updated (e.g., server-side facets updating meta.options). The fix adds table.options.columns as a memo dependency so the hook recomputes whenever column definitions change.