API Reference

Complete reference for every public component, configuration interface, hook, and type exported by TableCraft. For conceptual background on how these pieces fit together see Core Concepts.

Components

ClientSideTable

Import: import { ClientSideTable } from "@/components/table/client-side-table"

High-level wrapper and the recommended entry point for most use cases. ClientSideTable accepts the same props as DataTable and adds automatic row-number prepending via the withIndex prop. When withIndex is true (the default), a non-sortable, non-hideable # column is prepended that calculates the correct ordinal across pages: pageIndex * pageSize + rowIndex + 1. The column header is translated via the row-number key so it respects the active locale automatically.

PropTypeRequiredDefaultDescription
dataTData[]YesArray of row data objects. Each element becomes one table row.
columnsColumnDef<TData, TValue>[]YesTanStack Table column definitions. Use DataTableColumnHeader for sortable columns.
pageCountnumberNoTotal number of pages. Used by the pagination footer to compute navigation state. Optional when using cursor-based pagination.
pageSizenumberNoconfig defaultInitial rows per page. Falls back to config.pagination.defaultPageSize when omitted.
withIndexbooleanNotrueWhen true, prepends an auto-numbered index column that calculates position across pages.
showFilterbooleanNoconfig defaultShow the toolbar containing search inputs and filter dropdowns. Controlled by config.features.filter when omitted.
showPaginationbooleanNoconfig defaultShow the pagination footer bar. Controlled by config.features.pagination when omitted.
isLoadingbooleanNofalseWhen true, renders skeleton placeholder rows instead of real data rows.
searchableColumnsDataTableSearchableColumn[]No[]Client-side searchable column configs. Each entry maps a column id to a display title and optional input type.
filterableColumnsDataTableFilterableColumn[]No[]Client-side filterable column configs. Each entry declares the column id, label, and selectable options array.
configTableConfigInputNoPer-instance config overrides. Deep-merged on top of global provider config. Every property is optional.
Server-side discriminated unions
ClientSideTable also accepts four families of server-side props via discriminated unions: isQuerySearch / searchableQuery for server-driven search, isQueryFilter / handleFilterChange / filterableQuery / currentFilters / onClearFilters for server-driven filtering, isQueryPagination / paginationData for offset-based server-driven pagination, and isCursorPagination / cursorPaginationData for cursor-based pagination (GraphQL Relay, Stripe, keyset APIs). Pass only one variant per category — mixing local, query, and cursor props for the same category produces a TypeScript error.

DataTable

Import: import { DataTable } from "@/components/table/data-table"

The core table component. Use DataTable directly when you need full control over column composition or when you do not want automatic row numbering. It accepts all the same props as ClientSideTable except withIndex, plus the three additional props listed below.

Internally, DataTable creates a useReactTable instance with all TanStack Table row models (core, filtered, paginated, sorted, faceted), syncs its state with the URL on mount by reading ?page, ?per_page, ?sort, and per-column filter params, and debounces search filter writes back to the URL using config.search.debounceMs. It renders DataTableToolbar on desktop, DataTableMobileToolbar on mobile, the Table body, and DataTablePagination in the footer.

PropTypeRequiredDefaultDescription
floatingBarbooleanNoconfig defaultShow the floating selection bar at the bottom of the viewport when one or more rows are selected. Controlled by config.features.floatingBar when omitted.
deleteRowsActionMouseEventHandler<HTMLButtonElement>NoCallback invoked when the bulk-delete button in the floating bar or toolbar is clicked. Receives the click event.
newRowLinkstringNoURL for a New Row link button rendered in the toolbar. Navigates to the path using Next.js router.

DataTableColumnHeader

Import: import { DataTableColumnHeader } from "@/components/table/data-table-column-header"

Interactive column header button used inside the header render function of a ColumnDef. When clicked, it opens a small dropdown with three options: Sort Ascending (calls column.toggleSorting(false)), Sort Descending (calls column.toggleSorting(true)), and Hide Column (calls column.toggleVisibility(false)). The button displays an ArrowUp icon when the column is sorted ascending, ArrowDown when sorted descending, and a neutral SortAsc icon when unsorted. An accessible aria-label describes the current sort state (sorted-asc, sorted-desc, or not-sorted).

PropTypeRequiredDefaultDescription
columnColumn<TData, TValue>YesThe TanStack Table column instance passed from the header render function context.
titlestringYesHuman-readable column label displayed in the header button.
classNamestringNoAdditional CSS class names applied to the header button element.

TableActionsRow

Import: import TableActionsRow from "@/components/table/table-actions-row"

Row-level action buttons component designed for use inside a display column with id "actions". It ships with pre-wired slots for common CRUD operations (edit, view, delete, cancel, download) and an escape hatch for arbitrary customButtons. The useDropdown prop controls rendering mode: when true (the default), all actions are collapsed into a single ... dropdown menu; when false, each action renders as an individual icon button inline in the cell, with any dropMoreActions entries still in an overflow dropdown. Each built-in action slot accepts action (click handler), disabled (boolean), and tooltip (string) sub-properties.

Config System

TableConfig

The root configuration interface. Every property is optional at the consumer level via the TableConfigInput alias (DeepPartial<TableConfig>). The full resolved config is always complete because library defaults fill in every missing key before use.

TableConfig interface
interface TableConfig {
  features:    TableFeatureFlags
  pagination:  TablePaginationConfig
  search:      TableSearchConfig
  i18n:        TableI18nConfig
  performance: TablePerformanceConfig
  enterprise:  TableEnterpriseConfig
  dev:         TableDevConfig
  plugins:     TablePlugin[]
}

The following sub-configs make up the full TableConfig shape:

  • TableFeatureFlags — flat boolean map that gates every discrete table capability. Fields include search, filter, pagination, columnVisibility, csvExport, rowSelection, viewToggle, floatingBar, advancedFilter, and sorting. When a flag is false, the corresponding DOM nodes and event listeners are completely removed.
  • TablePaginationConfig — controls defaultPageSize (default 10) and pageSizeOptions (default [10, 20, 30, 40, 50]).
  • TableSearchConfig — controls debounceMs (default 500) and minSearchLength (default 0). The debounce applies to writes back to the URL to prevent excessive history entries while the user is still typing.
  • TableI18nConfig — controls locale, direction ('ltr' | 'rtl' | 'auto'), translationFn, and namespace. When translationFn is provided it is used directly, bypassing next-intl. Direction 'auto' derives RTL from the active locale.
  • TablePerformanceConfig — controls memoStrategy ('smart' | 'aggressive' | 'manual'), virtualizationOverscan, and batchUpdates.
Four-layer config merge
Config is resolved by deep-merging four layers in order: (1) library built-in defaults, (2) global TableCraftProvider config, (3) per-instance config prop, and (4) plugin contributions. Each layer overrides only the keys it sets explicitly. Arrays are replaced rather than concatenated (except plugins, which accumulate across layers). See the Core Concepts page for a full annotated example.

Hooks

useTableConfig()

Consumer hook for reading the resolved table configuration. Accepts an optional selector function to subscribe to a specific slice of config. When a selector is provided, the component only re-renders when the selected value changes (shallow equality), which avoids unnecessary re-renders when unrelated config keys update.

useTableConfig — selector pattern
// Full config — re-renders on any config change
const config = useTableConfig()

// Selector pattern — re-renders only when the selected slice changes
const features   = useTableConfig(c => c.features)
const debounceMs = useTableConfig(c => c.search.debounceMs)
const isRtl      = useTableConfig(c => c.i18n.direction === 'rtl')

Returns: TableConfig when called with no argument, or T when called with a selector of type (config: TableConfig) => T. Reads from the nearest TableCraftProvider in the React tree, or falls back toDEFAULT_TABLE_CONFIG if no provider is present.

useTableTranslations()

Translation bridge hook. Returns a translate function (key: string) => string that resolves UI labels for table controls. When config.i18n.translationFn is provided it delegates directly to that function. Otherwise it calls useTranslations(config.i18n.namespace) from next-intl, which requires a next-intl messages provider in the tree.

useTableTranslations — usage and custom bridge
const t = useTableTranslations()

t("edit")    // "Edit"    (en)  |  "تعديل"  (ar)
t("delete")  // "Delete"  (en)  |  "حذف"    (ar)
t("search")  // "Search"  (en)  |  "بحث"    (ar)

// Custom translation function via provider
<TableProvider config={{
  i18n: {
    translationFn: (key) => myI18nLibrary.t(`table.${key}`),
  }
}}>
  {children}
</TableProvider>
Non-Next.js consumers
If you are not using next-intl, provide a custom translationFn in the provider config to route translation calls to your own i18n library. The hook signature is identical regardless of which resolution path is taken.

useDebounce()

Generic debounce hook used internally to delay propagating search-input changes to the URL and to the TanStack Table filter state. Prevents excessive URL history entries and re-renders while the user is actively typing.

useDebounce
const debouncedSearch = useDebounce(searchTerm, 500)
// debouncedSearch updates 500 ms after the user stops typing

Signature: useDebounce<T>(value: T, delay: number): T. The returned debounced value updates only after delay milliseconds of inactivity. The default search debounce delay is controlled by config.search.debounceMs (default: 500).

Types

The following TypeScript types are part of the public API surface. Import them from @/components/table/types (or the library package root if consuming as a package).

  • DataTableSearchableColumn<TData> — Describes a column that can be searched via a toolbar input. Fields: id: keyof TData, title: string, and optional type ('text' | 'number' | 'checkbox' | 'date') which controls the input widget rendered.
  • DataTableFilterableColumn<TData> — Describes a column that can be filtered via a toolbar dropdown. Fields: id: keyof TData, title: string, options: Option[], and optional isSingleSelect: boolean (defaults to multi-select faceted behavior when false).
  • Option — A single selectable value in a filter dropdown: { label: string; value: string; icon?: React.ComponentType }. The optional icon is rendered alongside the label in the dropdown list.
  • ViewMode'table' | 'cards'. Determines whether the data is rendered as a standard table grid or as a responsive card layout.
  • Pagination — Matches a standard Laravel-style paginated API response. Contains a meta object with current_page, last_page, per_page, total, from, and to, plus an optional links object with first, last, prev, and next URL strings.
  • CursorPaginationInfo — describes the current cursor state returned by your API. Fields: hasNextPage: boolean, hasPreviousPage: boolean, optional startCursor: string | null, optional endCursor: string | null, and optional totalCount: number (displayed as a record count when provided).
  • CursorPaginationData — the prop shape passed to cursorPaginationData when using isCursorPagination. Fields: pageInfo: CursorPaginationInfo, onNextPage: () => void, onPreviousPage: () => void, onPageSizeChange: (size: number) => void, and optional pageSize: number.
  • FilterOptions { [key: string]: string | number | undefined }. Generic key-value map for tracking server-side filter state when using isQueryFilter={true}.
  • CustomButtonProps — Config object for arbitrary toolbar buttons: accepts text, function (click handler), className, icon (ReactElement), attr (spread onto the underlying Button), children, and toolTip.
  • DeepPartial<T> — Utility type that makes all properties of T optional recursively. Arrays are preserved as full arrays rather than having their elements made partial. Used as the basis for TableConfigInput.