Skip to main content

@topgrid/grid-core

TanStack Table abstraction wrapper + useGridState core hook · Free (MIT)

Auto-generated

This page is auto-generated from the source code's TSDoc comments (internal markers scrubbed). For a curated getting-started summary, see the API Reference.

109 public exports — 24 functions · 8 hooks · 15 components · 58 types · 4 constants.

Components

BaseGrid

BaseGrid(props: BaseGridProps<TData>): Element

ColumnMenu

Per-column header menu. Returns null if the column exposes no applicable actions.

ColumnMenu(__namedParameters: ColumnMenuProps<TData>): null | Element

ColumnPinGrid

ColumnPinGrid(props: ColumnPinGridProps<TData>): Element

ColumnVisibilityMenu

Column visibility toggle dropdown menu.

ColumnVisibilityMenu(props: ColumnVisibilityMenuProps<TData>): Element
ParameterTypeDescription
propsColumnVisibilityMenuProps<TData>{ table }.

Returns — a <details>-based column visibility toggle UI.

Example

// Inside Grid.tsx — rendered only when columnPersistence is provided
{props.columnPersistence !== undefined && (
<ColumnVisibilityMenu table={table} />
)}

See- ColumnPersistenceOptions

DropIndicator

The blue vertical-line indicator rendered at the drag drop position.

DropIndicator(__namedParameters: {}): null | Element

Grid

Grid(props: GridProps<TData> & {}): ReactElement

GridPagination

Pagination UI container component.

GridPagination(__namedParameters: GridPaginationProps<TData>): Element

GroupedHeaderGrid

GroupedHeaderGrid(props: GroupedHeaderGridProps<TData>): Element

PageSizeSelect

PageSizeSelect(props: PageSizeSelectProps): ReactNode

RowPinButton

RowPinButton(__namedParameters: RowPinButtonProps<TData>): Element

SortBadge

Multi-sort priority badge — grid-core canonical source.

SortBadge(__namedParameters: SortBadgeProps): null | Element

SortClearButton

A button that clears the entire current sort state. Wire table.setSorting([]) to the onClear callback.

SortClearButton(__namedParameters: SortClearButtonProps): Element

Example

<SortClearButton onClear={() => table.setSorting([])} />

SeeSortClearButtonProps

TotalCount

TotalCount(props: TotalCountProps): ReactNode

TreeGrid

TreeGrid(props: TreeGridProps<TData>): Element

VirtualGrid

VirtualGrid(props: VirtualGridProps<TData>): Element

Hooks

useColumnDrag

Column reorder hook built on the HTML5 Drag and Drop API.

useColumnDrag(props: UseColumnDragProps<TData>): UseColumnDragReturn
ParameterTypeDescription
propsUseColumnDragProps<TData>UseColumnDragProps

Returns — UseColumnDragReturn

useColumnOrderPersist

Hook that saves/restores column order to localStorage.

  • Returns: { saveOrder } — called from handleColumnOrderChange inside useColumnDrag
  • On mount: localStorage.getItem → JSON.parse → table.setColumnOrder (restore)
  • How to save: call saveOrder(order) → localStorage.setItem
  • All localStorage access: the adapter wraps it in try/catch
  • SSR guard: handled by the adapter
  • QuotaExceededError: adapter console.warn + silent skip
useColumnOrderPersist(__namedParameters: UseColumnOrderPersistProps<TData>): {}

useColumnPersistence

Hook that persists column visibility + order to localStorage.

useColumnPersistence(table: Table<TData>, options: ColumnPersistenceOptions): void
ParameterTypeDescription
tableTable<TData>The Table instance returned by useReactTable.
optionsColumnPersistenceOptionsPersistence options (ColumnPersistenceOptions).

Example

// Inside Grid.tsx — Rules of Hooks compliant: always called (no conditional call)
useColumnPersistence(table, props.columnPersistence ?? { storageKey: '' });

See- ColumnPersistenceOptions

useFullRowEdit

useFullRowEdit(__namedParameters: UseFullRowEditOptions<T>): FullRowEditApi<T>

useGridState

A unified hook that returns all 8 standard TanStack states + setters at once.

Replaces the 5–7 useState<StateType> calls that each variant (BaseGrid/VirtualGrid/...) used to declare separately with a single line.

** Extensions (controlled/uncontrolled/initialState)**:

  • When options is omitted, behavior is identical (all state uncontrolled, defaults).
  • initialState: sets the initial value of a specific key in uncontrolled mode.
  • state: per-key controlled mode (if state.sorting is present, sorting is controlled, the rest uncontrolled).
  • onStateChange(next, key): notified on state change — called in both controlled and uncontrolled modes.

** (controlled + initialState both provided)**: when state is provided, the initialState for that key is ignored (controlled takes precedence).

useGridState(options: UseGridStateOptions<TData>): GridState<TData>

ReturnsGridState<TData> — an object of 8 state values + 8 OnChangeFn<StateType> setters.

Example

// G-001 compatible (no parameters)
const s = useGridState<User>();

// uncontrolled + initialState (G-002)
const s = useGridState<Slip>({
initialState: { sorting: [{ id: 'date', desc: true }], pagination: { pageIndex: 0, pageSize: 20 } },
});

// controlled mode — Redux integration (G-002)
const s = useGridState<Attendance>({
state: { sorting: externalSorting },
onStateChange: (next, key) => {
if (key === 'sorting') dispatch(setGridSorting(next.sorting));
},
});

// Consumed directly by TanStack useReactTable
const table = useReactTable<User>({
data,
columns,
state: {
sorting: s.sorting,
columnFilters: s.columnFilters,
rowSelection: s.rowSelection,
pagination: s.pagination,
},
onSortingChange: s.setSorting,
onColumnFiltersChange: s.setColumnFilters,
onRowSelectionChange: s.setRowSelection,
onPaginationChange: s.setPagination,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
});

G-004 extensions (resetState / resetSection / clearSelectionKey):

  • resetState(): restores all 8 states to initialState (or defaultValues).
  • resetSection(key): selectively restores only the state(s) of a single or array key (Set dedup, idempotent).
  • options.clearSelectionKey: auto-resets rowSelection when an external trigger (string | number) changes. Absorbs the XxgridTable clearSelectionKey pattern (R-A). No reset on mount (isFirstClearRender flag).

See- GridState, - UseGridStateOptions

useStoragePersist

Options helper that syncs GridStateValueslocalStorage / sessionStorage.

  • On state change, saves to storage after debounceMs (default 300ms)
  • On mount, reverse hydration from storage → state (onHydrate callback — )
  • version mismatch / parse failure → removeItem + onHydrate not called
  • SSR safe (typeof window guard inside useEffect body — )
  • Fully compliant: option 3 (eslint-disable) 0 lines (Option A saveRef pattern — )
useStoragePersist(state: GridStateValues<TData>, options: UseStoragePersistOptions<TData>): void
ParameterTypeDescription
stateGridStateValues<TData>GridStateValues from useGridState or any other source
optionsUseStoragePersistOptions<TData>UseStoragePersistOptions (storageKey required)

Example

const state = useGridState();
useStoragePersist(state, {
storageKey: 'my-grid-v1',
version: 1,
onHydrate: (partial) => {
if (partial.sorting) state.setSorting(partial.sorting);
if (partial.columnFilters) state.setColumnFilters(partial.columnFilters);
},
});

useUrlSync

Options helper that syncs an arbitrary subset of GridStateValues to URL search params.

  • On state change, updates the URL via window.history.replaceState
  • On mount, reverse hydration from URL → state (onHydrate callback — )
  • debounce support (debounceMs option — reuses useDebouncedCallback)
  • No router-library dependency
  • SSR safe (: the typeof window check is inside the useEffect body)
useUrlSync(state: GridStateValues<TData>, options: UseUrlSyncOptions<TData>): void
ParameterTypeDescription
stateGridStateValues<TData>GridStateValues from useGridState or any other source
optionsUseUrlSyncOptions<TData>UseUrlSyncOptions (all optional)

Example

const state = useGridState();
useUrlSync(state, {
keys: ['sorting', 'columnFilters'],
onHydrate: (partial) => {
if (partial.sorting) state.setSorting(partial.sorting);
if (partial.columnFilters) state.setColumnFilters(partial.columnFilters);
},
});

useViewStatePersistence

Persist a single serializable view-state value to Web Storage (versioned envelope).

useViewStatePersistence(options: UseViewStatePersistenceOptions<T>): [T, ViewStateSetter<T>]

Returns[value, setValue]setValue writes through to storage.

Functions

applyRowDraft

applyRowDraft — merges a row-edit draft (a set of changed cells) into the original row.

Pure function (node-verified). The commit unit of full-row editing = the core all-or-nothing transform for the whole row. It overrides only the fields present in the draft and returns a new object (input immutable, isomorphic to applyRowTransaction/moveRow).

applyRowDraft(row: T, draft: Record<string, unknown>): T
ParameterTypeDescription
rowTThe original row object.
draftRecord<string, unknown>Changed cells { [field]: value }. An empty object yields an equal copy of the original.

Returns — the merged new row ({...row,...draft }). The original is unchanged.

applyRowTransaction

Apply a RowTransaction to data, returning a NEW array (input never mutated). Order = remove → update → add (XX Grid semantics). Updates/removes for ids not present are ignored (no throw). update rows are matched by getRowId and replace the existing row in place.

applyRowTransaction(data: readonly TData[], txn: RowTransaction<TData>, getRowId: GetRowId<TData>): TData[]

blankToUndefined

Wrap an accessor so blank values (null/undefined/empty-or-whitespace string) become undefined, letting sortUndefined place them. Real falsy values (0, false) pass through unchanged — the classic bug is treating those as blank.

blankToUndefined(accessor: () =>): () =>

buildTreeFromPaths

Converts each row of data into a hierarchical tree by its getDataPath path (pure). Rows with an empty path are skipped.

buildTreeFromPaths(data: readonly TData[], getDataPath: () =>): TreeNode<TData>[]

compareLocale

Locale-aware comparison of two cell values. Nullish coerces to '' (placement of nulls is a separate concern — ). numeric: true gives natural number ordering within strings (a2 < a10); sensitivity: 'variant' keeps accents significant.

compareLocale(a: unknown, b: unknown, locale: string | string[]): number

createAutoGroupColumn

Build a ready-made auto group column: indent-by-depth + expand/collapse chevron (only on expandable rows) + the node value. Sorting/filtering disabled.

createAutoGroupColumn(options: AutoGroupColumnOptions<TData>): ColumnDef<TData, unknown>

createColumns

Takes TopgridColumnDef<TData>[] | ColumnInfo[] and returns ColumnDef<TData>[].

  • Automatic renderer branching based on the type field (rendererRegistry lookup)
  • 'checkbox' type → DisplayColumnDef (no accessorKey, enableSorting forced false)
  • Type not registered in the registry → plain text fallback + console.warn
  • On ColumnInfo[] input, internally narrows to TopgridColumnDef
  • Standard mapping of width, enableSorting, enableResizing, meta
createColumns(defs: TopgridColumnDef<TData>[] | ColumnInfo[]): ColumnDef<TData>[]
ParameterTypeDescription
defsTopgridColumnDef<TData>[] | ColumnInfo[]Column definition array. TopgridColumnDef<TData>[] or ColumnInfo[].

Returns — TanStack ColumnDef<TData>[] — can be injected directly into useReactTable({ columns }).

Example

// Using TopgridColumnDef directly (recommended)
const defs: TopgridColumnDef<User>[] = [
{ id: 'name', name: '이름', type: 'text', align: 'left', width: '150' },
{ id: 'salary', name: '급여', type: 'number', align: 'right', width: '120' },
{ id: 'sel', name: '', type: 'checkbox', align: 'center', width: '50' },
];
const columns = createColumns<User>(defs);

// Legacy ColumnInfo[] compatibility (AC-005)
const legacyDefs: ColumnInfo[] = [...];
const columns = createColumns(legacyDefs);

See- TopgridColumnDef, - ColumnInfo, - defaultRendererRegistry

createGroupedColumns

Takes TopgridColumnGroup<TData>[] rest args and returns ColumnDef<TData>[].

createGroupedColumns(groups: TopgridColumnGroup<TData>[]): ColumnDef<TData>[]
ParameterTypeDescription
groupsTopgridColumnGroup<TData>[]Group column definition rest args. Each item is of the form { header, columns }.

Returns — TanStack ColumnDef<TData>[] — can be injected directly into useReactTable({ columns }).

Example

// 2-level multi-tier header (payment-items group)
const columns = createGroupedColumns<Payroll>(
{
header: '지급항목',
columns: createColumns<Payroll>([
{ id: 'basePay', name: '기본급', type: 'number', align: 'right', width: '120' },
{ id: 'bonus', name: '상여', type: 'number', align: 'right', width: '100' },
{ id: 'totalPay', name: '합계', type: 'number', align: 'right', width: '120' },
]),
},
);

// Multiple groups (basic info + payroll details)
const columns = createGroupedColumns<Employee>(
{
header: '기본 정보',
columns: createColumns<Employee>([
{ id: 'empNo', name: '사번', type: 'text', align: 'center' },
{ id: 'name', name: '성명', type: 'text', align: 'left' },
]),
},
{
header: '급여 내역',
columns: createColumns<Employee>([
{ id: 'basePay', name: '기본급', type: 'number', align: 'right' },
{ id: 'bonus', name: '상여', type: 'number', align: 'right' },
{ id: 'totalPay', name: '합계', type: 'number', align: 'right' },
]),
},
);

See- TopgridColumnGroup, - createColumns, - GroupedHeaderGrid

createTopgridColumnHelper

createTopgridColumnHelper(): ColumnHelper<TData>

createTransactionBatcher

: an applyTransactionAsync analogue. enqueue accumulates transactions and arms a single schedule(flush); flush applies them all to the current data in order and commits via setData exactly once (batched). Re-arming happens on the next enqueue after a flush.

createTransactionBatcher(deps: TransactionBatcherDeps<TData>): TransactionBatcher<TData>

deserializeViewState

Parse a versioned envelope back to its value. Returns null when:

  • raw is null,
  • JSON parse fails,
  • the shape is not {v,p},
  • the version does not match (stale schema).
deserializeViewState(raw: null | string, version: number): null | T

isBlank

True for null, undefined, or a string that is empty or all whitespace. NOT for 0 / false.

isBlank(value: unknown): boolean

localeSortingFn

localeSortingFn(rowA: Row<unknown>, rowB: Row<unknown>, columnId: string): number

makeLocaleSortingFn

Build a TanStack sortingFn that collates with localeCompare. Use per column: { accessorKey: 'name', sortingFn: makeLocaleSortingFn('ko') }.

makeLocaleSortingFn(locale: string | string[]): () =>

moveRow

@topgrid/grid-core — pure row-reorder transform.

Moves the element at from so it ends up at index to in the result array. splice remove→insert naturally handles the index adjustment for down/up moves (when from<to, removing pulls the trailing indices forward, so to becomes the final position). No-op / boundary cases return an immutable copy of the original. The consumer applies it to its own data in the onRowReorder(from,to) callback.

moveRow(rows: readonly T[], from: number, to: number): T[]

registerRenderer

Function to register an external renderer.

L2: references the XX Grid components injection pattern (R-A). Uses Map.set — no any.

The @topgrid/grid-renderers/wireRegistry.ts of wires 8 slots (text/number/date/dateTime/badge/link/tag/progress) via this function. User custom renderers can override through the same API (the last call wins).

registerRenderer(type: TopgridColumnType, fn: RendererFn<TData>, registry: RendererRegistry<TData>): void
ParameterTypeDescription
typeTopgridColumnTypeThe TopgridColumnType to register
fnRendererFn<TData>Cell renderer function
registryRendererRegistry<TData>Target registry (default: defaultRendererRegistry)

Example

// User custom renderer
registerRenderer('number', (info) => {
const value = info.getValue();
return typeof value === 'number' ? value.toLocaleString() : String(value ?? '');
});

See- defaultRendererRegistry, - ADR-MOD-GRID-REFACTOR-2026-05-17-002

reorderColumnOrder

@topgrid/grid-core — reorderColumnOrder ( / ).

Canonical column-order reorder math, extracted from useColumnDrag.onDrop (which now calls this) so header-drag and any other reorder affordance (e.g. the tool-panel drag) converge on ONE semantics.

Semantics = insert-before: sourceId is removed, then re-inserted at the index targetId currently occupies in the source-removed array — i.e. source lands immediately before the target. This matches the prior inline onDrop math (byte-identical) and the list-reorder convention.

No-op cases return the SAME baseOrder reference (callers detect via ===):

  • sourceId === targetId (dropped onto itself),
  • targetId absent from baseOrder.
reorderColumnOrder(baseOrder: string[], sourceId: string, targetId: string): string[]

resolveIcons

Merge a partial override over the complete default icon set (missing keys fall back).

resolveIcons(overrides: Partial<GridIcons>): GridIcons

resolveLocale

Merge a partial override over the complete default locale (missing keys fall back).

resolveLocale(overrides: Partial<GridLocale>): GridLocale

serializeViewState

Wrap a value in a versioned envelope string.

serializeViewState(value: T, version: number): string

themeToVars

Map a partial theme to the CSS-custom-property object applied (inline) on the grid root. Emits ONLY provided keys — absent keys carry no var, so surfaces fall back to their literal default. Returns {} for no theme (root stays var-free → default-on byte-identical).

themeToVars(theme: Partial<GridTheme>): Record<string, string>

toGridCell

TanStack Cell → GridCellContext. Use inside onCellClick / onCellKeyDown / getCellTooltip to read cell data without TanStack knowledge — e.g. const c = toGridCell(cell) then read c.value / c.rowId / c.row.

toGridCell(cell: CellLike<TData>): GridCellContext<TData>

toGridFilterColumn

TanStack filter Column → GridFilterColumn (value + setValue, no method spelunking).

toGridFilterColumn(column: FilterColumnLike): GridFilterColumn

transferRow

@topgrid/grid-core — transferRow ( / ).

Move one row (by id) from a source array to the end of a target array — the pure spine of drag-between-grids. The dragged row's identity is owned by the consumer (lifted above both grids); this helper just applies the move (no dataTransfer, no React) so it is node-testable and the DnD wiring stays thin.

No-op (rowId not found in source) returns the SAME source/target references (callers may detect via ===); originals are never mutated.

transferRow(source: readonly T[], target: readonly T[], rowId: string, getId: () =>): {}

Types & Interfaces

AutoGroupColumnOptions

Options for createAutoGroupColumn.

PropertyTypeDescription
getValue?(…) => …Render the node's display value (default: nothing).
header?ReactNodeHeader content (default 'Group').
indentUnit?numberPixels of indent per depth level (default 16).
size?numberColumn width (default 240).

BaseGridProps

BaseGridProps<TData> — the shared props signature of the 5 legacy aliases.

Identical in signature to the AS-IS legacy grid types — newly defined for alias compatibility within the package (0 external dependencies). This interface is used by legacy/BaseGrid.tsx + legacy/VirtualGrid.tsx (extends).

PropertyTypeDescription
className?string
columnsColumnDef<TData, unknown>[]
dataTData[]
emptyText?string
loading?boolean
onRowClick?(…) => …
onRowDoubleClick?(…) => …
pagination?GridPaginationOptions
rowSelection?GridRowSelectionOptions<TData>

CellLike

Minimal structural view of a TanStack Cell (it satisfies this — we read only these).

PropertyTypeDescription
column{ … }
getValue(…) => …
row{ … }

ColumnInfo

DataTable-compatible ColumnInfo interface.

Same shape as the legacy DataTable data-table-types.ts. New code should prefer TopgridColumnDef<TData>.

createColumns narrows ColumnInfo[] input to TopgridColumnDef internally:

  • If the type field is one of the 9 TopgridColumnType union members, it is used as-is
  • Any other string falls back to 'text'
PropertyTypeDescription
alignstringAlignment direction (string — 'left'|'center'|'right' recommended)
etc?stringColumnInfo compatibility: sets meta.primary based on whether 'primary' is included. See reference.
idstringcolumn accessor key
namestringDisplay header name
typestringColumn type (string — not a union). Narrowed to the TopgridColumnType union inside createColumns. Values outside the 9 fall back to 'text'.
visibility?booleanIf false, the column is hidden. Default true.
widthstringWidth string in pixels ('100', '200', etc.)

ColumnMenuProps

PropertyTypeDescription
columnColumn<TData, unknown>The TanStack Column this menu acts on.
label?stringTrigger glyph/label.

ColumnPersistenceOptions

Column visibility + order localStorage persistence options.

Passed to the <Grid columnPersistence={...} /> prop.

PropertyTypeDescription
persist?PersistTarget[]State targets to persist (default ['visibility', 'order']). - 'visibility': column show/hide (VisibilityState). - 'order': column order (ColumnOrderState).
storageKeystringlocalStorage key. When an empty string (''), no localStorage access (no-op, NFR-006). A value unique within the app is recommended (e.g. 'hr-grid-v1').
version?numberStorage format version (default 1). Raise the value when the column structure changes to invalidate previously stored entries. On mismatch, the existing entry is removed + state restoration is skipped.

ColumnPinGridProps

ColumnPinGridProps<TData> — AS-IS shape preserved (ColumnPinGrid.tsx L14-26).

PropertyTypeDescription
className?string
columnsColumnDef<TData>[]
dataTData[]
emptyText?string
loading?boolean
onRowClick?(…) => …
pagination?GridPaginationOptions
pinLeft?string[]Array of left-side sticky pinned column ids (default []).
pinRight?string[]Array of right-side sticky pinned column ids (default []).
rowSelection?GridRowSelectionOptions<TData>

ColumnVisibilityMenuProps

<ColumnVisibilityMenu> props.

PropertyTypeDescription
className?stringAdditional className for the root <details>.
menuLabel?stringMenu top label.
tableTable<TData>The Table instance returned by useReactTable. Uses getAllLeafColumns + column.getCanHide + column.toggleVisibility.
triggerLabel?stringTrigger button text.

DragThProps

Drag props to pass to a header <th> DOM element.

HTML5 DragEvent handlers (: no external library used). Grid.tsx receives a React.DragEvent<HTMLTableCellElement>, extracts the DOM DragEvent via .nativeEvent, and passes it to these handlers.

PropertyTypeDescription
draggablebooleanpinned=true → false, enabled=true → true (/).
onDragEnd(…) => …
onDragLeave(…) => …
onDragOver(…) => …
onDragStart(…) => …
onDrop(…) => …

FilterColumnLike

Minimal structural view of a TanStack Column (filter side).

PropertyTypeDescription
getFilterValue(…) => …
idstring
setFilterValue(…) => …

FullRowEditApi

PropertyTypeDescription
cancelRow(…) => …Cancel row — discard draft, 0 emits.
commitRow(…) => …Commit row — a single onRowEdit followed by exit, if validateRow passes.
editingRowIdnull | stringThe id of the row currently being edited (null if none).
getDraftValue(…) => …Current value for rendering (draft first, else the original rowValue).
isRowEditing(…) => …Whether this row is being edited.
setDraftCell(…) => …Update a draft cell (field = row key).
startRowEdit(…) => …Start editing this row (initialize draft).

GridCellContext

Clean cell context — what a consumer actually needs in onCellClick/onCellKeyDown/getCellTooltip.

PropertyTypeDescription
columnIdstringColumn id.
rowTDataThe original row object.
rowIdstringStable row id (from getRowId, or the array index fallback).
valueunknownThe cell's value.

GridFilterColumn

Clean filter column — normalises TanStack getFilterValue/setFilterValue to value/setValue.

PropertyTypeDescription
idstring
setValue(…) => …
valueunknown

GridHandle

The imperative handle exposed via the <Grid> ref.

PropertyTypeDescription
addRow(…) => …Add row — delegates to the props.onAddRow(seed?) callback. When no callback is provided, a one-time dev-mode console.warn + no-op.
clearSelection(…) => …Clear all selection — delegates to table.setRowSelection({}). Equivalent to AG api.deselectAll.
deleteRow(…) => …Delete row — delegates to the props.onDeleteRow(rowId) callback. rowId = TanStack row.id (default = row index string).
getSelection(…) => …Returns the currently selected row data array — delegates to table.getSelectedRowModel.rows.map(r => r.original). Empty array = no selection.
refresh(…) => …Recompute internal state — delegates to table.resetRowSelection.
scrollTo(…) => …Scroll to the row at index. - When enableVirtualization=true, delegates to virtualizer.scrollToIndex(index, options) (@tanstack/react-virtual API). - When enableVirtualization=false, native DOM tbody tr[data-index="N"].scrollIntoView({...}) fallback. - Negative / index exceeding data.length → clamped to [0, data.length-1] + dev console.warn.
updateRow(…) => …Partial row update — delegates to the props.onUpdateRow(rowId, patch) callback.
collapseAll?unknown
expandAll?unknown
startEditing?unknown

GridIcons

Grid chrome icon glyphs (sort indicators).

PropertyTypeDescription
sortAscendingstring
sortDescendingstring
sortNonestring

GridLocale

Localizable grid chrome strings. Parametrized entries are functions.

PropertyTypeDescription
emptyTextstringEmpty-state default text.
firstPagestringPagination nav button aria-labels — screen-reader heard ( audience).
lastPagestring
nextPagestring
prevPagestring
rowsPerPagestringPagination "rows per page" label.
selectionMessage(…) => …Screen-reader selection-change announcement.
sortMessage(…) => …Screen-reader sort-change announcement.
totalCount(…) => …Pagination total-count text (e.g. 전체 N건).

GridPaginationOptions

Pagination options.

Takes effect only when enablePagination=true. When manual=true, server-side pagination (the consumer is responsible for controlling the external totalCount + pageIndex).

PropertyTypeDescription
autoPageSize?booleanAuto-computes pageSize to fit the viewport (grid body) height. Default false. When active, the pageSize/pageSizeOptions select is ignored and hidden (to avoid conflict).
enableGoToPage?booleanShows a numeric input UI to jump to a specific page. Default false. Jumps directly to a distant page that the sliding buttons cannot reach.
enableKeyboardNav?booleanEnables Alt+← / Alt+→ keyboard page navigation. Wired to the enableKeyboardNav prop of the GridPagination component. Default false.
manual?booleanServer-side pagination mode. When true, TanStack manualPagination: true + external totalCount required.
mode?PaginationModePagination behavior mode (convenience shorthand). - 'client'manual: false + enablePagination auto-enabled - 'server'manual: true + enablePagination auto-enabled - 'none' → pagination disabled (enablePagination ignored) When mode and manual are both specified, mode takes precedence.
onPaginationChange?OnChangeFn<PaginationState>Controlled pageIndex change handler.
pageCount?numberTotal page count in server mode (mode: 'server' or manual: true). Computed automatically from totalCount and pageSize, but overridden if specified directly.
pageIndex?numberControlled pageIndex (controlled mode).
pageNumberFormat?(…) => …Formatter for page-number button labels (e.g. thousands separators n => n.toLocaleString). Raw integer when unspecified. The aria-label (accessibility) keeps the original integer. For total-count formatting, see localeText.totalCount.
pageSize?numberDefault pageSize (default 20).
pageSizeOptions?number[]Rows-per-page select options (default [10, 20, 50, 100]).
showTotalCount?booleanWhether to show the total count. Default true. When set to false, the "total N items" UI is hidden.
totalCount?numberTotal row count in server mode (required when manual=true).

GridPaginationProps

GridPagination<TData> props.

PropertyTypeDescription
enableGoToPage?booleanShows a numeric input UI to jump to a specific page. Default false.
enableKeyboardNav?booleanEnables Alt+← / Alt+→ keyboard page navigation. Registers event listeners in the container ref scope. Default false.
mode?PaginationModePagination behavior mode ('client' | 'server' | 'none').
navLabels?{ … }Navigation button aria-labels (i18n — ). Korean default when unspecified.
onPaginationChange?OnChangeFn<PaginationState>Page change callback.
pageCount?numberTotal page count in server mode.
pageNumberFormat?(…) => …Page-number label formatter. Passed through to PageNumbers.
pageSizeOptions?number[]List of rows-per-page options (default [10, 20, 50, 100]).
rowsPerPageLabel?string"Rows per page:" label (i18n — ).
showTotalCount?booleanWhether to show the total count. Default true. When set to false, the "total N items" UI is hidden.
tableTable<TData>TanStack Table instance — access to pagination state + API.
totalCount?numberTotal row count in server mode.
totalCountFormat?(…) => …Total-count text formatter (i18n — ).

GridProps

<Grid> component props.

PropertyTypeDescription
alwaysMultiSort?booleanAccumulate multi-sort even on a plain click. Use together with enableMultiSort. By default Shift+click is the multi-sort key, but when true you accumulate by clicking columns in sequence without Shift. (TanStack isMultiSortEvent: => true passthrough.)
autoSelectFirstRow?booleanAuto-select the first row after data load (default false).
cellClassName?CellClassNameCallback<TData>Per-cell className generation callback. Called on every cell render. The returned string is appended to the default className of <td>. canonical: this callback type is owned by grid-core. grid-renderers is a type-only re-export. Usage example (equivalent to publish/organizeSchedule): tsx cellClassName={(cell) => { if (!cell.column.id.startsWith('d')) return ''; const isSelected = cell.row.getIsSelected; const hasValue = cell.getValue != null && cell.getValue !== ''; return [ isSelected && 'bg-indigo-100', !isSelected && hasValue && 'bg-yellow-50', ].filter(Boolean).join(' '); }} Performance note: called on every cell render — beware the callback's internal computation cost with large datasets (useMemo or a stable callback recommended).
className?stringOuter wrapper className (Tailwind).
columnOrderStorageKey?stringlocalStorage key to use when persistColumnOrder=true. When an empty string ('') is passed, no localStorage access. When unspecified, save is skipped even if persistColumnOrder=true.
columnPersistence?ColumnPersistenceOptionsColumn visibility + order localStorage persistence options. - When provided, the <ColumnVisibilityMenu> UI is auto-rendered + useColumnPersistence activated. - When omitted (undefined), persistence is disabled + the menu is not shown ( backward compat). - When storageKey: '', no localStorage access (NFR-006).
columnResizeMode?GridColumnResizeModeColumn resize mode (default 'onChange'). Takes effect only when enableColumnResizing=true.
columnsColumnDef<TData, unknown>[]Column definitions (TanStack ColumnDef).
dataTData[]Row data array.
debug?booleanExposes the TanStack debugTable option (default false).
defaultColumnPinning?ColumnPinningStateUncontrolled initial value for column pinning ({ left: string[]; right: string[] }). The entry point for mapping the ColumnPinGrid pinLeft / pinRight aliases.
defaultColumnSizing?ColumnSizingStateUncontrolled initial value for column width (column id → px). Used as the initial value of the internal columnSizing state on mount (uncontrolled pattern).
defaultExpanded?false | ExpandedStateInitial value of expanded state when enableExpanding=true (uncontrolled). - true = fully expanded - Record<string, boolean> = expand only specific row ids - unspecified = {} (fully collapsed) — the entry point compatible with the TreeGrid alias expandAll={true}. Preserves the AS-IS TreeGrid.tsx:35 useState<ExpandedState>(initialExpandAll ? true : {}) initial-seed pattern.
emptyState?ReactNodeEmpty-result state ReactNode slot. When provided, rendered in preference to emptyText ( — slot → text → defaultText order).
emptyText?stringEmpty-result guidance text (default '데이터가 없습니다.').
enableCellChangeFlash?booleanBriefly highlights a cell on value change (change-flash). When data changes, applies a ~0.9s background highlight to cells whose value actually changed (diffed by row identity — reordering is not highlighted). For stable highlighting, specifying getRowId together is recommended (when unspecified, the diff is index-based → reordering is also highlighted).
enableColumnPinning?booleanActivates column pinning state (default false). This activates only the state.columnPinning state. The sticky CSS appearance is out of scope.
enableColumnReorder?booleanActivates column drag reorder (default false). Built on the HTML5 Drag and Drop API — no external dnd library. :.
enableColumnResizing?booleanActivates column resizing state (default false). The resize handle UI is out of scope.
enableColumnVirtualization?booleanActivates column (horizontal) virtualization. When true, off-screen center columns are not rendered and left/right padding cells preserve only the horizontal scroll width — cutting the render cost of 100+ columns. Pinned columns are not virtualized and are always rendered regardless of horizontal scroll. unspecified/false → all columns rendered (byte-identical to prior behavior). v1 constraint: flat (single-row) headers only — with grouped/multi-tier headers (getHeaderGroups.length > 1) it auto-disables (all columns rendered) due to colSpan accounting complexity. Grouped-header virtualization is v2. Layout: when true, the <table> is fixed to table-layout: fixed + the total column width (ΣgetSize), so columns keep their explicit widths exactly (aligned with the pad px). As a side effect, cell content that exceeds the column width is clipped — normal behavior for a virtualized grid. The horizontal scroll container is provided by the existing overflow-x-auto (or the row-virtualization overflow:auto), so consumers not using Tailwind must set overflow-x on the container directly. ⚠️ Experimental: body+header virtualization wiring + chromium alignment matrix complete (Commit C). off = byte-identical to prior; on SSR/unmeasured, all columns rendered (safe fallback).
enableExpanding?booleanActivates row expanding state (default false) — TreeGrid absorbed. Use together with getSubRows.
enableFilter?booleanActivates column filtering (default false) — getFilteredRowModel wiring.
enableMultiSort?booleanActivates multi-sort (default false) — delegates to TanStack enableMultiSort.
enablePagination?booleanActivates pagination (default false) — getPaginationRowModel wiring.
enableRowClickSelection?booleanSelect by clicking the row body. Works only when rowSelection is 'single'/'multi'. - plain click → selects only that row (others deselected). ctrl/cmd+click → toggle (accumulate multiple). (shift range = ) - coexists independently with the existing onRowClick callback — onRowClick is still called while selecting. - Clicks on the checkbox cell (__select__) do not take this path due to stopPropagation (existing behavior preserved).
enableRowPinning?booleanRow pinning. The user pins data rows to the top/bottom (row.pin('top'|'bottom')). Pinned rows stay fixed via sticky during scroll and are excluded from the center rows. Non-virtualized only (virtualization+pinning=vN). Place the RowPinButton component in a cell for the UI control.
enableRowReorder?booleanActivates row drag reorder (default false). Makes data rows draggable and calls onRowReorder(from, to) on drop (the consumer applies it to its own data via moveRow(data, from, to)). Auto-disabled when sort/filter is active (display order ≠ data order makes reordering ambiguous) + non-virtualized only (virtualization synthesis = vN). HTML5 drag.
enableSort?booleanActivates sorting (default false) — getSortedRowModel wiring.
enableVirtualization?booleanActivates virtualization (default false) — opt-in only. When true, useGridVirtualizer wiring + the tbody padding-row pattern are applied. When false, ~ markup as-is ( sticky/pinning preserved).
floatingBottomRows?TData[]Consumer-supplied row data to pin at the bottom of the grid. Same convention as floatingTopRows (bottom sticky).
floatingTopRows?TData[]Consumer-supplied row data to pin at the top of the grid. Isomorphic to XX Grid's pinnedTopRowData — extra rows outside the data model (totals/summaries, etc.). They pass through the column cell renderers (columnDef.cell) and are shown identically to body rows, staying fixed via position: sticky even as the body scrolls. No aggregation computed: the consumer supplies the total object directly (automatic aggregation is @topgrid/grid-pro-agg/Pro). Not an interactive pin: separate from the feature where a user pins existing rows (@topgrid/grid-pro-master/Pro). unspecified/empty array → no render (existing behavior unchanged).
getCellTooltip?(…) => …Cell tooltip. Called per cell and its returned string is applied as <td title> (native hover tooltip) — showing clipped content, extra descriptions, etc. When undefined/null/'' is returned, no title is applied to that cell. grid-core 1.0 : (cell, row)(ctx) (clean GridCellContext).
getRowId?(…) => …Stable row identifier. When unspecified, the row key = array index. When provided, all row-key states such as rowSelection·expanded are keyed by this id rather than the index, so the same logical row is tracked across data reorder/replacement (selection follows identity, not position). It is the foundation by which cell change flash identifies "the same row".
getSubRows?(…) => …TanStack getSubRows — used when enableExpanding=true.
icons?Partial<GridIcons>Sort-indicator icon glyph override (partial). Unspecified falls back to the default (▲▼⇅).
loading?booleanLoading state. When true, only the <tbody> area is replaced with skeleton rows (thead preserved — ).
loadingOverlay?booleanLoading overlay (default false). Unlike loading (skeleton replacement), it leaves the existing data rows in place and covers them with a translucent overlay (indicating a refresh in progress while keeping existing data). aria-busy + pointer-events blocked (blocks interaction underneath). Independent and additive to loading (skeleton) — both leave existing behavior unchanged.
loadingRowCount?numberNumber of skeleton rows to show while loading. When unspecified, falls back to pagination.pageSize ?? 5 ( — compatible with the BaseGrid L123 hardcoded 5).
localeText?Partial<GridLocale>Localizes grid chrome strings — partial override. Unspecified keys fall back to the Korean default (never emits raw key/undefined). English example: { emptyText: 'No data', rowsPerPage: 'Rows per page:', totalCount: (n) => ${n} rows }. You can also import defaultGridLocale and spread over it.
manualFiltering?booleanServer filtering: when true, disables client filtering (getFilteredRowModel skip + manualFiltering). Default false.
manualSorting?booleanServer sorting: when true, disables client sorting (getSortedRowModel skip + manualSorting). The sort UI/state is retained (header click → onSortingChange) but the actual sorting is delegated to the server. Default false.
maxMultiSortColCount?numberMaximum number of columns that can be sorted simultaneously. Passed directly to TanStack maxMultiSortColCount. Unlimited when unset. Ignored when enableMultiSort=false.
onAddRow?(…) => …Add-row callback — invoked when ref.current.addRow(seed?) is called. Controlled-data policy: the parent is responsible for appending the new row to the props.data array.
onCellClick?(…) => …Cell click handler — exposes the intent to branch at the column level. grid-core 1.0 : (cell, row, event)(ctx, event). ctx is a clean GridCellContext — ctx.columnId·ctx.value·ctx.rowId·ctx.row(= old row.original).
onCellKeyDown?(…) => …Cell keyboard event handler — wired via <td onKeyDown>. grid-core 1.0 : (cell, row, event)(ctx, event) (clean GridCellContext).
onColumnFiltersChange?OnChangeFn<ColumnFiltersState>ColumnFilters state change callback (for deriving server filter parameters; also updates internal state).
onColumnOrderChange?(…) => …Callback invoked after column order change completes. The parent can sync external state. : F-07-06 absorbed.
onColumnPinningChange?OnChangeFn<ColumnPinningState>ColumnPinning state change callback (for external persistence or a controlled mirror).
onColumnSizingChange?OnChangeFn<ColumnSizingState>ColumnSizing state change callback (for external persistence or a controlled mirror).
onDeleteRow?(…) => …Delete-row callback — invoked when ref.current.deleteRow(rowId) is called. rowId = TanStack row.id (default = row index string).
onRowClick?(…) => …Row click handler.
onRowDoubleClick?(…) => …Row double-click handler — same signature policy as onRowClick.
onRowDragStart?(…) => …Drag-between-grids — drag source (default none = disabled). When provided, data rows become draggable and onRowDragStart(rowId) is called on dragstart (rowId = TanStack row.id). The consumer lifts the dragged row id into state above both grids and holds it (consumer-owns-payload, no dataTransfer). Paired with the target grid's onRowDrop. A separate opt-in from enableRowReorder (mixing within the same grid is forbidden = vN). When OFF, byte-identical.
onRowDrop?(…) => …Drag-between-grids — drop target (default none = disabled). When provided, the grid body area becomes a drop target and onRowDrop is called (on drop). The consumer reads its own dragged id and applies source→target data via the pure transferRow. When OFF, byte-identical.
onRowReorder?(…) => …Row-reorder drop callback — display index fromto. The consumer applies the data via moveRow.
onSortingChange?OnChangeFn<SortingState>Sorting state change callback (for deriving server sort parameters; also updates internal state).
onStartEditing?(…) => …Programmatic edit-start callback — invoked when ref.current.startEditing(rowId, colId) is called. Same policy as the callback-delegating pattern of : the Grid does not own the editing state, and the application is responsible for updating the EditableCell isEditing.
onUpdateRow?(…) => …Partial row update callback — invoked when ref.current.updateRow(rowId, patch) is called.
pagination?GridPaginationOptionsPagination detail options (effective when enablePagination=true).
persistColumnOrder?booleanActivates column-order localStorage persistence. When true + columnOrderStorageKey is specified, saves to localStorage after drag/keyboard completes. Restores the saved order on mount (table.setColumnOrder).
renderFloatingFilter?(…) => …Floating filter row render callback. When specified, draws an always-visible filter input row below the leaf header row (prop present = active, mirroring the cellClassName convention). Called once per column — usually returns a floating input component from grid-features (column.setValue shares the same state as the popover). grid-core provides only the structural row + column window (virtualization) · pin sticky · ARIA consistency (no grid-features dependency = MIT). null return = empty cell. grid-core 1.0 : Column<TData,unknown> → clean GridFilterColumn (id·value·setValue — no TanStack types).
rowClassName?RowClassNameCallback<TData>Per-row className generation callback. Called on every row render. The returned string is appended to the default className of <tr>. virtualization note: when enableVirtualization=true, <tr ref={measureElement}> measures the row height — if rowClassName causes a dynamic height change, measureElement reflows repeatedly (performance degradation). A static className is recommended.
rowSelection?RowSelectionMode | GridRowSelectionOptions<TData>Row selection options. Supports both the shorthand notation ('multi') and the object notation. With 'single'/'multi', a checkbox column (__select__) is auto-prepended as the leftmost column.
showSortClearButton?booleanWhether to show the sort-reset button. When true and enableMultiSort=true, renders <SortClearButton> in the toolbar. When unset (default), no DOM structure change.
sortDescFirst?booleanMake the first-click sort direction descending. (TanStack sortDescFirst passthrough — when unspecified, per-type default: number = desc-first, string = asc-first.)
theme?Partial<GridTheme>Grid chrome color theme (partial override). Only the provided colors are applied to the root as inline --topgrid-* vars, and each surface reads them via var(--topgrid-x, <default hex>). Unspecified keys fall back to the default color. For presets such as dark, import { darkTheme } then spread. ⚠ CSS vars are inert under forced-colors (high contrast) (an HC-safe selection indicator is a separate mechanism).
virtualizerOptions?{ … }useVirtualizer option override. - estimateSize: estimated row height px (default 36, based on BaseGrid <td className="px-4 py-3">). - overscan: buffer rows above/below the viewport (default 10, same as VirtualGrid.tsx:102). - onChange: virtualizer change callback (observes the visible range — the block-fetch trigger of SSRM). Passed through as-is to useVirtualizer. Generic passthrough (0 SSRM-specific logic).
virtualScrollHeight?numberScroll container height when virtualizing (px, default 400). Takes effect only when enableVirtualization=true.

GridRowSelectionOptions

Row selection options (object form).

Supports both the <Grid rowSelection="multi" /> shorthand and the <Grid rowSelection={{ mode, onSelectionChange }} /> object notation.

PropertyTypeDescription
mode?RowSelectionModeSelection mode (default 'none').
onSelectionChange?(…) => …Selection change callback. Argument: the row.original array of currently selected rows (based on page/filter).
onStateChange?OnChangeFn<RowSelectionState>Controlled state change handler (required in controlled mode).
selectAllPages?boolean: the 'multi' header select-all checkbox selects/deselects rows across all pages (default false = current page only). When true, the header checkbox uses TanStack getToggleAllRowsSelectedHandler (all pages) + getIsAllRowsSelected/getIsSomeRowsSelected. Corresponds to XX Grid's "select all across all pages".
state?RowSelectionStateControlled — used to control RowSelectionState directly from outside. Uses internal state when unspecified (uncontrolled).

GridState

The return type of useGridState<TData> — 8 TanStack states + 8 setters.

A unified return type that absorbs the useState<StateType> pattern that was declared redundantly across the 8 grid variants (BaseGrid/VirtualGrid/...) into one.

TData is currently unused ( to be leveraged when controlled mode is extended).

PropertyTypeDescription
columnFiltersColumnFiltersStateColumn filter state (TanStack ColumnFiltersState). Default [].
columnOrderColumnOrderStateColumn order state (TanStack ColumnOrderState). Default [].
columnPinningColumnPinningStateColumn pinning state (TanStack ColumnPinningState). Default {}.
columnSizingColumnSizingStateColumn width state (TanStack ColumnSizingState). Default {}.
columnVisibilityVisibilityStateColumn visibility state (TanStack VisibilityState). Default {}.
paginationPaginationStatePagination state (TanStack PaginationState). Default { pageIndex: 0, pageSize: 10 }.
resetSection(…) => …Restore a specific state key(s) to initialState.
resetState(…) => …Restore all states to initialState. - uncontrolled mode: to the provided key value when initialState is provided, otherwise to each key's default (sorting: [], columnFilters: [], rowSelection: {}, pagination: { pageIndex: 0, pageSize: 10 }, columnPinning: {}, columnOrder: [], columnSizing: {}, columnVisibility: {}) - controlled-mode keys: the setter only calls onChange → the external handler is responsible for updating the controlled state (useControllableState — the isControlled branch does not call the internal setInternalValue) initialState is captured once on mount (useRef) — later prop changes are ignored.
rowSelectionRowSelectionStateRow selection state (TanStack RowSelectionState). Default {}.
setColumnFiltersOnChangeFn<ColumnFiltersState>Column filter setter.
setColumnOrderOnChangeFn<ColumnOrderState>Column order setter.
setColumnPinningOnChangeFn<ColumnPinningState>Column pinning setter.
setColumnSizingOnChangeFn<ColumnSizingState>Column width setter.
setColumnVisibilityOnChangeFn<VisibilityState>Column visibility setter.
setPaginationOnChangeFn<PaginationState>Pagination setter.
setRowSelectionOnChangeFn<RowSelectionState>Row selection setter.
setSortingOnChangeFn<SortingState>Sort setter — TanStack OnChangeFn<SortingState> (T or an updater function).
sortingSortingStateSort state (TanStack SortingState). Default [].

GridStateValues

The 8 standard grid state values.

PropertyTypeDescription
columnFiltersColumnFiltersState
columnOrderColumnOrderState
columnPinningColumnPinningState
columnSizingColumnSizingState
columnVisibilityVisibilityState
paginationPaginationState
rowSelectionRowSelectionState
sortingSortingState

GridTheme

Themeable grid chrome colors. All optional via Partial<GridTheme> on the theme prop.

Only STATIC surfaces are themeable this way — a surface whose color lives in a :hover or :focus-visible pseudo-state (selection bg, focus outline) can't be set by an inline style and is intentionally absent (it would need shipped CSS). Those are handled by the selection sub-step.

PropertyTypeDescription
bodyBgstringBody background. Default #ffffff (white).
borderstringContainer border. Default #e5e7eb (gray-200).
cellTextstringBody cell text. Default #374151 (gray-700).
headerBgstringHeader (thead / group-header) background. Default #f9fafb (gray-50).
headerTextstringHeader label text. Default #6b7280 (gray-500).

GroupedHeaderGridProps

GroupedHeaderGridProps<TData> — AS-IS shape preserved (GroupedHeaderGrid.tsx L13-24).

columns are passed through as the TanStack standard group structure ({ header, columns: [...leaf] }) as-is — buildTableOptions passes group ColumnDefs through unmodified (TanStack internal placeholder mechanism).

PropertyTypeDescription
className?string
columnsColumnDef<TData>[]
dataTData[]
emptyText?string
loading?boolean
onRowClick?(…) => …
pagination?GridPaginationOptions
rowSelection?GridRowSelectionOptions<TData>

PageSizeSelectProps

PageSizeSelect props.

PropertyTypeDescription
label?string"Rows per page:" label (i18n — ). Korean default when unspecified.
onPageSizeChange(…) => …pageSize change callback.
pageSizenumberCurrent pageSize.
pageSizeOptionsnumber[]List of selectable pageSize options.

RowPinButtonProps

@topgrid/grid-core — RowPinButton (per-row pin control) —.

Place in a column cell (cell: ({ row }) => <RowPinButton row={row} />) to let users pin a data row to the top/bottom (sticky) or unpin it. Requires <Grid enableRowPinning />. Inline styles (Tailwind is inert in the headless storybook — P27-1). ★ Every click stopPropagations so pinning does not also trigger row-click selection / onRowClick.

PropertyTypeDescription
rowRow<TData>

RowTransaction

A delta over a row array: remove by id, update by id (matched rows replaced), add (appended).

PropertyTypeDescription
add?readonly TData[]
remove?readonly RowId[]
update?readonly TData[]

SortBadgeProps

SortBadge component props ( canonical — single source in grid-core).

PropertyTypeDescription
className?stringTailwind className override.
sortIndexnumberThe value returned by TanStack column.getSortIndex. -1 = unsorted → badge not shown. 0-based integer → displayed number = sortIndex + 1.

SortClearButtonProps

SortClearButton component props.

PropertyTypeDescription
className?stringTailwind className override.
label?stringButton label (default: '정렬 초기화').
onClear(…) => …Called on click — wire table.setSorting([]).

TopgridColumnGroup

Group-header column definition.

PropertyTypeDescription
columnsColumnDef<TData>[]Array of leaf columns or nested group columns within the group
headerstringGroup header label

TotalCountProps

TotalCount props.

PropertyTypeDescription
format?(…) => …Total-count text formatter (i18n — ). Korean default when unspecified ("total N items", with N emphasized).
totalnumberTotal row count.

TransactionBatcher

A batcher that coalesces many transactions into a single deferred apply.

PropertyTypeDescription
enqueue(…) => …Queue a transaction; the first queued since the last flush arms one schedule(flush).
flush(…) => …Apply all queued transactions to the current data in order, committing once.
pending(…) => …Queued (not-yet-flushed) transaction count — for tests/introspection.

TransactionBatcherDeps

Dependencies a createTransactionBatcher needs (all injected → node-deterministic).

PropertyTypeDescription
getData(…) => …Read the current row array (consumer-owned state).
getRowIdGetRowId<TData>
schedule(…) => …Schedule flush to run later ( host-capability injection). Production passes queueMicrotask/requestAnimationFrame; node tests pass a manual collector for determinism.
setData(…) => …Commit the new row array (consumer-owned setState). Called ONCE per flush.

TreeGridProps

TreeGridProps<TData> — AS-IS shape preserved (TreeGrid.tsx L12-22).

PropertyTypeDescription
className?string
columnsColumnDef<TData>[]
dataTData[]
emptyText?string
expandAll?booleanWhen true, expand the entire tree on mount ( maps to defaultExpanded={true}).
getSubRows?(…) => …Child-row extraction function (signature-compatible with TanStack getSubRows).
loading?boolean
onRowClick?(…) => …

TreeNode

Tree node. data=null = a synthetic group that exists only as a path prefix.

PropertyTypeDescription
childrenTreeNode<TData>[]Child nodes (in first-seen order).
datanull | TDataExplicit row data, or null if a synthetic parent.
keystringStable key (NUL-join, collision-safe).
pathstring[]The path segments up to this node.

UseColumnDragProps

useColumnDrag hook props.

PropertyTypeDescription
columnOrderStorageKey?stringlocalStorage key. Required when persistColumnOrder=true (empty string → save skipped).
enabledbooleanWhether drag reorder is active (passed from the enableColumnReorder prop).
onColumnOrderChange?(…) => …Callback invoked after column order change completes.
persistColumnOrder?booleanWhether localStorage persistence is active.
tableTable<TData>TanStack Table v8 instance (the return value of useReactTable).

UseColumnDragReturn

The return value of the useColumnDrag hook.

PropertyTypeDescription
dragOverIdnull | stringThe column ID to currently show the drop indicator on. null = drag disabled or not currently dragging.
getDragProps(…) => …Returns the drag event props to spread onto the header <th>.
getKeyDownHandler(…) => …Returns the handler function to wire to the header <th> onKeyDown. Alt+← / Alt+→ key events move the column left/right.

UseColumnOrderPersistProps

PropertyTypeDescription
enabledbooleanWhether localStorage persistence is active (persistColumnOrder prop)
storageKeystringlocalStorage key (columnOrderStorageKey prop)
tableTable<TData>TanStack Table v8 instance

UseFullRowEditOptions

PropertyTypeDescription
getRowId(…) => …Stable row identifier.
onRowEdit(…) => …Row commit callback — a single delta (the merged new row). The consumer applies it to the data.
validateRow?(…) => …Optional: validation before commit. Returning false blocks the commit (editing retained). E.g. derived from the edit-plus buildValidator.

UseGridStateOptions

The parameter type of useGridState<TData>(options?).

PropertyTypeDescription
clearSelectionKey?string | numberOption to auto-reset rowSelection via an external trigger. Absorbs the XxgridTable clearSelectionKey pattern (R-A: XxgridTable.tsx L88-92). Auto-resets to rowSelection: {} whenever this value changes. An undefined initial value does not trigger on mount ( isFirstClearRender ref flag).
debounceMs?numberonStateChange debounce wait time (ms). - unset or 0: synchronous call (identical behavior, no breaking). - > 0: fires once after debounceMs ms have elapsed since the last change. N consecutive changes within 300ms → only the last snapshot delivered. - negative: treated the same as 0 (synchronous).
initialState?Partial<GridStateValues<TData>>Uncontrolled-mode initial value. When provided, used as the useState initial value of that key. When used together with controlled mode (state provided), initialState is ignored (controlled takes precedence).
onStateChange?(…) => …State-change notification callback. Called in both controlled and uncontrolled modes. Debounced call when debounceMs > 0 (only the last change fires). Synchronous call when debounceMs is unset or 0 ( behavior preserved).
state?Partial<GridStateValues<TData>>Controlled-mode external state. Partial<GridStateValues> allows per-key control. If state.sorting is present, sorting is controlled, the rest uncontrolled.

UseStoragePersistOptions

useStoragePersist hook options.

GridStateValues ↔ localStorage / sessionStorage sync options.

  • storageKey required, the rest all optional.
  • The onHydrate callback may be non-stable ( option 2 — preserved via useRef).
PropertyTypeDescription
debounceMs?numberSave debounce delay ms (default: 300). 0 or less = immediate save (no debounce).
onHydrate?(…) => …Callback for storage → state hydration on mount. Called only on parse success + version match. May be non-stable (the latest value is preserved internally via useRef — option 2).
storage?"local" | "session"The Storage type to use (default: 'local'). - 'local'localStorage - 'session'sessionStorage
storageKeystringRequired: the localStorage / sessionStorage save key. A value unique within the app is recommended (e.g. 'my-grid-v1').
version?numberStorage format version (default: 1). On mismatch, existing stored data is ignored + removeItem. Raise the value when the storage schema changes (e.g. column structure change).

UseUrlSyncOptions

useUrlSync<TData> options.

All properties optional — each default applies when unspecified.

PropertyTypeDescription
debounceMs?numberURL update debounce ms (default 0 = immediate). When greater than 0, wrapped with useDebouncedCallback ( reuse).
keys?GridStateKey[]List of GridStateKeys to sync (all 8 when unspecified).
onHydrate?(…) => …Callback for reverse hydration from URL search params → state on mount. The hook returns void — the caller is responsible for updating state via setters. Non-stable callback safe: the latest value is preserved internally via useRef ( option 2).
prefix?stringURL param namespace prefix (default '' = no prefix). Prevents collisions when multiple grids coexist. When a prefix is specified, params are generated in the form ${prefix}_${key}.

UseViewStatePersistenceOptions

Options for useViewStatePersistence.

PropertyTypeDescription
initialTInitial value used when no (valid) stored value is found.
storageKeystringWeb Storage key (unique per persisted view).
storageType?StorageTypeWeb Storage type.
version?numberSchema version — a mismatch discards stored state.

VirtualGridProps

VirtualGridProps<TData> — AS-IS shape preserved (VirtualGrid.tsx L17-20).

PropertyTypeDescription
className?string
columnsColumnDef<TData, unknown>[]
containerHeight?numberscroll container height px (default 500 — differs from Grid virtualScrollHeight=400, AS-IS preserved).
dataTData[]
emptyText?string
loading?boolean
onRowClick?(…) => …
onRowDoubleClick?(…) => …
pagination?GridPaginationOptions
rowHeight?numberEstimated row height px (default 40 — differs from Grid estimateSize=36, AS-IS preserved).
rowSelection?GridRowSelectionOptions<TData>

CellClassNameCallback

Grid-level cell className callback.

Receives a clean GridCellContext (rowId/columnId/value/row — no TanStack types) and returns a Tailwind className string (or undefined for no addition) appended to the <td>. grid-core 1.0 : Cell<TData,unknown>GridCellContext<TData>.

Canonical home: @topgrid/grid-core (since / 2026-05-18 — ADR-). @topgrid/grid-renderers re-exports as type-only (ADR-MOD-GRID-REFACTOR-2026-05-17-009 conforming to the reverse-dependency removal policy).

type CellClassNameCallback = () =>

GetRowId

Extract a stable id from a row ( getRowId concept).

type GetRowId = () =>

GridColumnResizeMode

Column resize mode.

  • 'onChange': real-time width update during drag (default — best UX).
  • 'onEnd': single update at drag end (best performance, recommended for large-row environments).
type GridColumnResizeMode = "onChange" | "onEnd"

GridScrollToOptions

The options type for <Grid> ref.current.scrollTo(index, options).

Same signature as @tanstack/react-virtual ScrollToOptions. The same semantics apply to the fallback DOM scroll when enableVirtualization=false (alignblock, behavior as-is).

type GridScrollToOptions = VirtualScrollToOptions

GridStateKey

The union of the 8 state keys.

type GridStateKey = "sorting" | "columnFilters" | "rowSelection" | "pagination" | "columnPinning" | "columnOrder" | "columnSizing" | "columnVisibility"

PaginationMode

Pagination behavior mode.

  • 'client': client slicing after loading all data. manualPagination: false.
  • 'server': page-by-page load from the server. manualPagination: true. totalCount or pageCount required.
  • 'none': pagination disabled (default — enablePagination: false).
type PaginationMode = "client" | "server" | "none"

PersistTarget

The state target that useColumnPersistence will persist.

  • 'visibility': VisibilityState (column show/hide).
  • 'order': ColumnOrderState (column order).
type PersistTarget = "visibility" | "order"

RendererFn

Cell renderer function type.

Takes a TanStack CellContext<TData, unknown> and returns a ReactNode. No any — uses TValue=unknown.

type RendererFn = () =>

RendererRegistry

The type → RendererFn mapping type.

Based on Map<TopgridColumnType, RendererFn<TData>>. No any. References the XX Grid components registry pattern (L2: R-A).

type RendererRegistry = Map<TopgridColumnType, RendererFn<TData>>

RowClassNameCallback

Grid-level row className callback.

Receives a TanStack Row<TData> and returns a Tailwind className string (or undefined for no addition) to be appended to the rendered <tr>.

type RowClassNameCallback = () =>

RowId

A row id (TanStack row.id shape).

type RowId = string | number

RowSelectionMode

Row selection mode.

  • 'single': single row selection — the header checkbox is not rendered.
  • 'multi': multiple selection — header checkbox (select all) + per-row checkboxes.
  • 'none': selection disabled — no checkbox column synthesized.

Compatible with the BaseGrid GridRowSelectionOptions.mode (legacy alias support).

type RowSelectionMode = "single" | "multi" | "none"

TopgridColumnDef

Standard column definition. The input type for producing a TanStack ColumnDef<TData>.

Automatic renderer branching via the type field. Consumed by createColumns<TData>(defs).

type TopgridColumnDef = BaseColumnDef & {} | BaseColumnDef & {}

TopgridColumnType

The union of 11 automatic renderer-branching types.

createColumns looks up the rendererRegistry by this type to select the appropriate cell renderer.

  • 'checkbox': DisplayColumnDef-specific handling (no accessorKey, enableSorting forced false)
  • 'number': number formatter applied ( to be injected, placeholder)
  • 'boolean': Y/N display
  • 'dateTime': date+time formatter ( to be injected, placeholder)
  • 'date': date formatter ( pending → placeholder)
  • 'text': plain text (default)
  • 'badge': Badge component ( pending → placeholder)
  • 'link': Link component ( pending → placeholder)
  • 'icon': Icon component ( pending → placeholder)
  • 'tag': TagCell (+018 wired — readonly string[]).
  • 'progress': ProgressCell (+018 wired — number|null|undefined).
type TopgridColumnType = "checkbox" | "number" | "boolean" | "dateTime" | "date" | "text" | "badge" | "link" | "icon" | "tag" | "progress"

Constants

darkTheme

Dark preset — spread into the theme prop (theme={darkTheme} or {...darkTheme, headerBg }). Covers only the static surfaces; selection/focus/hover stay at their (blue) defaults, which read acceptably on dark. Row dividers (divide-gray-100) are not themed (Tailwind divide utility).

const darkTheme: GridTheme

defaultGridIcons

const defaultGridIcons: GridIcons

defaultGridLocale

const defaultGridLocale: GridLocale

defaultRendererRegistry

The default rendererRegistry (Map).

  • After +018 is applied: at the moment import '@topgrid/grid-renderers' runs, the 8 placeholders text/number/ date/dateTime/badge/link/tag/progress are replaced with real component adapters. boolean (Y/N) / icon (placeholder) / checkbox (registry-bypassed) are unchanged.
  • When grid-renderers is not imported: the 11 placeholders act as fallbacks (graceful degradation).
  • checkbox branches to DisplayColumnDef — low registry priority.
  • : when a type is not registered, createColumns applies the fallback.
const defaultRendererRegistry: RendererRegistry