TableOptions
The configuration object passed to createTable() or useTable().
Required
| Option | Type | Description |
|---|
data | TData[] | The data array to display |
columns | ColumnDef<TData, any>[] | Column definitions |
State Management
| Option | Type | Description |
|---|
state | Partial<TableState> | Controlled state (merged with internal state) |
onStateChange | OnChangeFn<TableState> | Called when any state changes |
initialState | Partial<TableState> | Initial state values |
Row Identity
| Option | Type | Default | Description |
|---|
getRowId | (row, index, parent?) => string | String(index) | Custom row ID generator |
Sorting Options
| Option | Type | Default | Description |
|---|
enableSorting | boolean | true | Enable sorting globally |
enableMultiSort | boolean | true | Allow multi-column sorting |
enableSortingRemoval | boolean | true | Allow removing sort on third click |
maxMultiSortColCount | number | Infinity | Max simultaneous sort columns |
manualSorting | boolean | false | Disable client-side sorting (for server-side) |
sortingFns | Record<string, SortingFn> | -- | Additional named sorting functions |
onSortingChange | OnChangeFn<SortingState> | -- | Sorting state change callback |
postSortRows | (rows) => Row[] | void | -- | Reorder the final sorted rows before render (AG-parity) |
isMultiSortEvent | (e) => boolean | Shift key | Multi-sort modifier key test |
Filtering Options
| Option | Type | Default | Description |
|---|
enableFilters | boolean | true | Enable all filtering |
enableColumnFilters | boolean | true | Enable per-column filters |
enableGlobalFilter | boolean | true | Enable global search |
manualFiltering | boolean | false | Disable client-side filtering |
filterFns | Record<string, FilterFn> | -- | Additional named filter functions |
globalFilterFn | FilterFnOption | -- | Custom global filter function |
onColumnFiltersChange | OnChangeFn<ColumnFiltersState> | -- | Column filters change callback |
onGlobalFilterChange | OnChangeFn<string> | -- | Global filter change callback |
getColumnCanGlobalFilter | (column) => boolean | -- | Per-column global filter opt-out |
| Option | Type | Default | Description |
|---|
manualPagination | boolean | false | Disable client-side pagination |
pageCount | number | -- | Total page count (server-side) |
rowCount | number | -- | Total row count (server-side) |
autoResetPageIndex | boolean | true | Reset to page 0 on data change |
onPaginationChange | OnChangeFn<PaginationState> | -- | Pagination change callback |
Server State
Server-backed tables use the same columns and table components as local tables. The difference is
where row-model work happens: local mode lets Yable sort/filter/page in memory; server mode controls
those state slices and fetches data from your API.
const table = useTable({
data: rows,
columns,
state: { sorting, columnFilters, globalFilter, pagination },
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
onGlobalFilterChange: setGlobalFilter,
onPaginationChange: setPagination,
manualSorting: true,
manualFiltering: true,
manualPagination: true,
rowCount,
})
React users can use the higher-level useServerTable controller for cursor loading, infinite scroll,
and optimistic row updates:
const serverTable = useServerTable({
columns,
getRowId: (row) => row.id,
fetchData: async ({ sorting, globalFilter, cursor, signal }) => {
const result = await api.accounts.list({ sorting, q: globalFilter, cursor, signal })
return {
rows: result.rows,
cursor: result.nextCursor,
hasMore: result.hasMore,
rowCount: result.total,
}
},
updateRow: async ({ rowId, patch, signal }) => {
return api.accounts.update(rowId, patch, { signal })
},
})
return <Table table={serverTable.table} />
| API | Description |
|---|
useServerTable().table | Normal Yable table instance configured for manual server state |
useServerTable().rows | Current loaded server window |
useServerTable().refresh() | Replace the loaded window using current sorting/filtering/pagination state |
useServerTable().loadMore() | Append the next cursor/page for infinite-scroll flows |
useServerTable().updateRow() | Optimistically patch a row, call the server, then merge or roll back result |
Selection Options
| Option | Type | Default | Description |
|---|
enableRowSelection | boolean | (row) => boolean | true | Enable row selection |
enableMultiRowSelection | boolean | (row) => boolean | true | Allow selecting multiple rows |
enableSubRowSelection | boolean | (row) => boolean | true | Auto-select sub-rows |
onRowSelectionChange | OnChangeFn<RowSelectionState> | -- | Selection change callback |
Visibility Options
| Option | Type | Default | Description |
|---|
enableHiding | boolean | true | Enable column visibility toggling |
onColumnVisibilityChange | OnChangeFn<VisibilityState> | -- | Visibility change callback |
Column Ordering
| Option | Type | Description |
|---|
onColumnOrderChange | OnChangeFn<ColumnOrderState> | Column order change callback |
Column Pinning
| Option | Type | Default | Description |
|---|
enableColumnPinning | boolean | -- | Enable column pinning |
onColumnPinningChange | OnChangeFn<ColumnPinningState> | -- | Pinning change callback |
Column Sizing
| Option | Type | Default | Description |
|---|
enableColumnResizing | boolean | true | Enable column drag-to-resize |
columnResizeMode | 'onChange' | 'onEnd' | 'onChange' | When to update widths |
columnResizeDirection | 'ltr' | 'rtl' | 'ltr' | Resize direction |
onColumnSizingChange | OnChangeFn<ColumnSizingState> | -- | Sizing change callback |
onColumnSizingInfoChange | OnChangeFn<ColumnSizingInfoState> | -- | Resize info change callback |
Use column definition sizing options (size, minSize, maxSize,
enableResizing) or defaultColumnDef to configure column widths. The React
renderer keeps header and body widths synchronized internally, including during
horizontal scroll, so consumers should not need custom CSS width overrides or
manual <colgroup> synchronization.
Configuration Profiles
React exports a layered config API for site-wide defaults, named table profiles,
and reusable named cell configs.
import { YableProvider, createYableConfig, useTable, Table } from '@zvndev/yable-react'
const yableConfig = createYableConfig({
table: { theme: 'midnight', striped: true, stickyHeader: true },
columns: {
default: { size: 160, minSize: 80, maxSize: 420, enableResizing: true },
},
rows: { className: 'row-comfortable' },
cells: {
named: {
RichItem: {
cellStyle: { whiteSpace: 'normal', lineHeight: 1.35, fontWeight: 600 },
},
},
},
profiles: {
compactVariant: {
table: { theme: 'compact', compact: true, stickyHeader: false },
columns: { default: { size: 112, minSize: 56 } },
rows: { className: 'row-compact' },
},
},
})
function App() {
return (
<YableProvider config={yableConfig}>
<OrdersTable />
</YableProvider>
)
}
function OrdersTable() {
const table = useTable({
data,
columns: [columnHelper.accessor('name', { header: 'Name', cellConfig: 'RichItem' })],
configProfile: 'compactVariant',
})
return <Table table={table} configProfile="compactVariant" />
}
Precedence is intentionally local-friendly: global defaults are lowest, named
profiles sit above them, table defaultColumnDef sits above profile defaults,
named cellConfig is applied per column, and explicit column definition fields
or explicit <Table> props always win. Use a provider for site-wide consistency,
named profiles for reusable variants, and inline column config for one-off cells.
Selection APIs
Row selection lives in table.getState().rowSelection. Use
onRowSelectionChange for controlled state, table.events.on('selection:change', handler) for event-style subscriptions, and table.getSelectedRowModel() when
you need the current selected rows.
const table = useTable({
data,
columns,
enableRowClickSelection: true,
enableCellSelection: true,
onRowSelectionChange: setRowSelection,
state: { rowSelection },
})
table.events.on('selection:change', ({ selection, selectedRows }) => {
console.log(selection, selectedRows)
})
Checkbox columns are opt-in. Add one with selectColumn(); it renders a larger
click target, supports selected-state sorting, and does not appear unless you add
it to columns.
const columns = [selectColumn<Order>(), columnHelper.accessor('name', { header: 'Name' })]
Cell range selection can be disabled globally or for specific columns:
const table = useTable({ data, columns, enableCellSelection: false })
columnHelper.accessor('actions', {
header: 'Actions',
enableCellSelection: false,
})
Expanding Options
| Option | Type | Default | Description |
|---|
enableExpanding | boolean | true | Enable row expanding |
getSubRows | (row, index) => TData[] | undefined | -- | Return child rows for tree data |
getRowCanExpand | (row) => boolean | -- | Custom expand-ability check |
manualExpanding | boolean | false | Disable client-side expansion |
paginateExpandedRows | boolean | -- | Include expanded rows in pagination |
renderDetailPanel | (row) => unknown | -- | Detail panel renderer |
onExpandedChange | OnChangeFn<ExpandedState> | -- | Expanded state change callback |
Row Pinning Options
| Option | Type | Default | Description |
|---|
enableRowPinning | boolean | (row) => boolean | false | Enable row pinning |
keepPinnedRows | boolean | -- | Keep pinned rows when filtering |
onRowPinningChange | OnChangeFn<RowPinningState> | -- | Row pinning change callback |
Grouping Options
| Option | Type | Default | Description |
|---|
enableGrouping | boolean | false | Enable row grouping |
manualGrouping | boolean | false | Disable client-side grouping |
onGroupingChange | OnChangeFn<GroupingState> | -- | Grouping change callback |
Cell Editing Options
| Option | Type | Default | Description |
|---|
enableCellEditing | boolean | -- | Enable cell editing globally |
onEditingChange | OnChangeFn<EditingState> | -- | Editing state change callback |
onEditCommit | (changes: Record<string, Partial<TData>>) => void | -- | Called when edits are committed |
Event Handlers
| Option | Type | Description |
|---|
onCellClick | (event: CellClickEvent) => void | Cell click handler |
onCellDoubleClick | (event: CellClickEvent) => void | Cell double-click handler |
onCellContextMenu | (event: CellClickEvent) => void | Cell right-click handler |
onRowClick | (event: RowClickEvent) => void | Row click handler |
onRowDoubleClick | (event: RowClickEvent) => void | Row double-click handler |
onRowContextMenu | (event: RowClickEvent) => void | Row right-click handler |
onHeaderClick | (event: HeaderClickEvent) => void | Header click handler |
onHeaderContextMenu | (event: HeaderClickEvent) => void | Header right-click handler |
Export Options
| Option | Type | Default | Description |
|---|
enableExport | boolean | -- | Enable export functionality |
Styling
| Option | Type | Description |
|---|
rowClassName | string | (row) => string | undefined | CSS class for rows |
rowStyle | CSSProperties | (row) => CSSProperties | Inline style for rows |