/** * The visible commit state of a single cell. * * - 'idle' — no in-flight or errored commit; cell renders saved value * - 'pending' — commit in flight; cell renders pending value with subtle * indicator * - 'error' — commit failed; cell renders pending value with error * decoration + retry * - 'conflict' — saved value changed underneath us between dispatch and * settle; consumer must resolve */ type CellStatus = 'idle' | 'pending' | 'error' | 'conflict'; /** * One pending change handed to the consumer's `onCommit` handler. * * `previousValue` is captured at dispatch time (NOT edit-start time) so it * always reflects the most recent saved value — useful for sending * `If-Match: ` style optimistic-concurrency headers. */ interface CellPatch { rowId: string; columnId: string; /** The value the user typed. */ value: TValue; /** The most recent saved value at the moment we dispatched. */ previousValue: TValue; /** The full row snapshot at dispatch time. */ row: TData; /** * Aborts when the user starts a new commit on the same cell. Consumers * with cancellable APIs (`fetch(url, { signal })`) can wire this through. */ signal: AbortSignal; } /** * What `onCommit` may return. `void` (or no return) means "the values you * received are now the saved values". Returning `resolved` lets the server * normalise/transform values before they replace the pending state. */ type CommitResult = void | { /** rowId → colId → resolved value */ resolved?: Record>; }; /** * The signature of the table-level `onCommit` option and per-column `commit` * override. */ type OnCommitFn = (patches: CellPatch[]) => Promise | CommitResult; /** * One in-flight, errored, or conflicted cell. Missing entry = idle status — * we never write `{ status: 'idle' }` records. */ interface CommitRecord { status: 'pending' | 'error' | 'conflict'; pendingValue: unknown; /** Captured at dispatch time. Used for conflict detection and `If-Match`. */ previousValue: unknown; /** Monotonic per-table. Stale settlements are dropped. */ opId: number; /** Only set when status === 'error'. */ errorMessage?: string; /** Only set when status === 'conflict'. The new saved value we collided with. */ conflictWith?: unknown; /** AbortController for cancellable consumer handlers. */ abortController: AbortController; } interface CommitsSlice { /** rowId → colId → record. Missing entry = idle. */ cells: Record>; /** Monotonic counter; allocated by the coordinator. */ nextOpId: number; } type RowData = Record; type Updater = T | ((prev: T) => T); type OnChangeFn = (updater: Updater) => void; type DeepKeys = unknown extends T ? string : T extends Record ? { [K in keyof T & string]: T[K] extends Record ? `${K}` | `${K}.${DeepKeys}` : `${K}`; }[keyof T & string] : never; type DeepValue = K extends `${infer A}.${infer B}` ? A extends keyof T ? DeepValue : never : K extends keyof T ? T[K] : never; interface TableFeature { getDefaultOptions?: (table: Table) => Partial>; getInitialState?: (state: TableState) => TableState; getDefaultColumnDef?: () => Partial>; createTable?: (table: Table) => void; createColumn?: (column: Column, table: Table) => void; createRow?: (row: Row, table: Table) => void; createCell?: (cell: Cell, column: Column, row: Row, table: Table) => void; } type ColumnDefBase = { id?: string; header?: string | ((ctx: HeaderContext) => unknown); footer?: string | ((ctx: HeaderContext) => unknown); cell?: string | ((ctx: CellContext) => unknown); meta?: ColumnMeta; }; type AccessorKeyColumnDef = ColumnDefBase & { accessorKey: DeepKeys & string; accessorFn?: never; } & ColumnDefExtensions; type AccessorFnColumnDef = ColumnDefBase & { accessorKey?: never; accessorFn: (row: TData, index: number) => TValue; id: string; } & ColumnDefExtensions; type DisplayColumnDef = ColumnDefBase & { accessorKey?: never; accessorFn?: never; id: string; } & ColumnDefExtensions; type GroupColumnDef = ColumnDefBase & { columns: ColumnDef[]; } & Partial>; type ColumnDef = AccessorKeyColumnDef | AccessorFnColumnDef | DisplayColumnDef | GroupColumnDef; interface ColumnDefExtensions { size?: number; minSize?: number; maxSize?: number; /** * Upper bound for USER drag-resize (defaults to `maxSize`). `maxSize` still * caps auto-sizing/stretch; set this (e.g. `Number.POSITIVE_INFINITY`, or via * `defaultColumnDef` for app-wide) to let a human drag a column past its * auto-size cap. */ resizeMaxSize?: number; flex?: number; /** * Opt out of the React `autoColumnWidth` feature for this column. When `false` * (or when an explicit `size` is set) the column keeps its width and is * excluded from content measurement and squishing. Passive flag — no core * logic reads it; the React adapter honors it. */ enableAutoSize?: boolean; /** * React `autoColumnWidth` measurement override: the string to MEASURE for this * column's content width (measured with the body font, plus cell padding and * the sort-indicator allowance, exactly like a normal value). Use this when the * displayed cell differs from the raw accessor value (a formatter or custom * `cell` renderer) so auto-sizing measures what the user actually sees instead * of the underlying value. Passive flag — only the React adapter reads it. */ autoSizeText?: (row: Row) => string; /** * React `autoColumnWidth` measurement override: an EXACT natural pixel width for * this row's cell. When present it bypasses text measurement entirely and is * used verbatim (no padding or sort-indicator is added). The column's natural * width is the max of this over sampled rows and the header's measured width. * Takes precedence over {@link autoSizeText}. Passive flag — only the React * adapter reads it. */ autoSizeWidth?: (row: Row) => number; enableSorting?: boolean; sortingFn?: SortingFnOption; sortDescFirst?: boolean; sortUndefined?: false | -1 | 1 | 'first' | 'last'; invertSorting?: boolean; enableColumnFilter?: boolean; enableGlobalFilter?: boolean; filterFn?: FilterFnOption; enableHiding?: boolean; /** * When true, this column's visibility cannot be toggled to hidden. * `toggleVisibility(false)` becomes a no-op; `toggleVisibility(true)` still works. * Useful for columns that should always remain visible (e.g. checkbox, actions). */ lockVisible?: boolean; enablePinning?: boolean; enableResizing?: boolean; enableReorder?: boolean; enableMultiRowSelection?: boolean; /** * Controls spreadsheet-style cell range selection for this column. * Table-level `enableCellSelection` must also be enabled. */ enableCellSelection?: boolean; enableGrouping?: boolean; getGroupingValue?: (row: TData) => unknown; aggregationFn?: AggregationFnOption; aggregatedCell?: string | ((ctx: CellContext) => unknown); editable?: boolean | ((row: Row) => boolean); editConfig?: CellEditConfig; /** * Per-column commit handler (Task #10). Takes precedence over * `table.options.onCommit` for cells in this column. Use for bespoke * endpoints, file uploads, etc. */ commit?: (patch: CellPatch) => Promise | CommitResult; rowSpan?: (row: Row, rows: Row[], rowIndex: number) => number | undefined; /** * Horizontal alignment for this column's header AND body cells. Emits * `data-align` on both, so one declaration centralizes what would otherwise be * a per-cell style. Right-aligned body cells also get tabular figures, which * is what numeric columns want. */ align?: 'left' | 'center' | 'right'; cellClassName?: string | ((ctx: CellContext) => string | undefined); cellStyle?: React.CSSProperties | ((ctx: CellContext) => React.CSSProperties | undefined); /** * Name of a reusable cell config supplied by framework adapters. * React resolves this through `YableProvider` / `useTable` config profiles. */ cellConfig?: string | string[]; headerClassName?: string | ((ctx: HeaderContext) => string | undefined); footerClassName?: string; tooltip?: boolean | string | ((ctx: CellContext) => string); headerTooltip?: string; tooltipDelay?: number; cellType?: 'badge' | 'currency' | 'status' | 'numeric' | 'rating' | 'boolean' | 'progress' | 'date' | 'link'; cellTypeProps?: Record; measureRecipe?: { /** CSS font string, e.g. "500 13px Inter" */ font: string; /** Line height in px */ lineHeight: number; /** Cell vertical padding (top + bottom) in px */ padding: number; /** * If true, this column does not wrap text — Pretext skips text measurement * and contributes a constant `lineHeight + padding` per row. */ fixedHeight?: boolean; }; enableCellFlash?: boolean; flashDuration?: number; flashUpColor?: string; flashDownColor?: string; } interface ColumnMeta { alwaysEditable?: boolean; [key: string]: unknown; } type CellEditType = 'text' | 'number' | 'select' | 'toggle' | 'date' | 'checkbox' | 'custom'; interface CellEditConfig { type: CellEditType; options?: { label: string; value: unknown; }[]; getOptions?: (row: Row) => { label: string; value: unknown; }[]; validate?: (value: TValue, row: Row) => string | null; parse?: (inputValue: string) => TValue; format?: (value: TValue) => string; placeholder?: string; render?: (props: CellEditRenderProps) => unknown; /** * Per-column commit handler. Fires once for every committed value in this * column — on single-cell commit, full-row commit, and `commitAllPending()` — * with the (pre-commit) row and the newly committed value. * * Lets the column-id → data-field mapping live on the column def instead of a * `switch (columnId)` inside a table-level `onEditCommit`/`onCommit` handler. * This is the recommended shape for nested/derived accessors * (`columnHelper.accessor((r) => r.a.b, { id })`), whose committed value is * keyed by column **id**, not by a `Partial` data path. Fires * regardless of whether `onEditCommit`/`onCommit` is also set; if both are * defined they both run, so pick one owner per column. */ commit?: (row: Row, value: TValue) => void; } interface CellEditRenderProps { value: TValue; onChange: (value: TValue) => void; onCommit: () => void; onCancel: () => void; row: Row; column: Column; isValid: boolean; validationError: string | null; } interface TableOptions { data: TData[]; columns: ColumnDef[]; /** * Default column definition values applied to every column. * Column-specific values take precedence over these defaults. */ defaultColumnDef?: Partial> & Partial>; state?: Partial; onStateChange?: OnChangeFn; initialState?: Partial; getRowId?: (row: TData, index: number, parent?: Row) => string; debugAll?: boolean; locale?: Record; getCoreRowModel?: (table: Table) => () => RowModel; getFilteredRowModel?: (table: Table) => () => RowModel; getSortedRowModel?: (table: Table) => () => RowModel; getPaginationRowModel?: (table: Table) => () => RowModel; getGroupedRowModel?: (table: Table) => () => RowModel; getExpandedRowModel?: (table: Table) => () => RowModel; getFacetedRowModel?: (table: Table, columnId: string) => () => RowModel; getFacetedUniqueValues?: (table: Table, columnId: string) => () => Map; getFacetedMinMaxValues?: (table: Table, columnId: string) => () => [number, number] | undefined; enableSorting?: boolean; enableMultiSort?: boolean; enableSortingRemoval?: boolean; maxMultiSortColCount?: number; manualSorting?: boolean; sortingFns?: Record>; onSortingChange?: OnChangeFn; isMultiSortEvent?: (e: unknown) => boolean; /** * Native post-sort hook (AG-parity `postSortRows`). Runs after the sorted row * model is built, receiving the sorted rows array. Return a reordered array, * or mutate the provided array in place, to control final render order — e.g. * keeping child rows grouped under their parents. Runs whenever provided, * including when no sorting is active. Skipped under `manualSorting`. */ postSortRows?: (rows: Row[]) => Row[] | void; enableFilters?: boolean; enableColumnFilters?: boolean; enableGlobalFilter?: boolean; manualFiltering?: boolean; filterFns?: Record>; onColumnFiltersChange?: OnChangeFn; onGlobalFilterChange?: OnChangeFn; globalFilterFn?: FilterFnOption; getColumnCanGlobalFilter?: (column: Column) => boolean; manualPagination?: boolean; pageCount?: number; rowCount?: number; autoResetPageIndex?: boolean; onPaginationChange?: OnChangeFn; enableRowSelection?: boolean | ((row: Row) => boolean); enableMultiRowSelection?: boolean | ((row: Row) => boolean); enableSubRowSelection?: boolean | ((row: Row) => boolean); /** Toggle row selection when the user clicks a non-interactive part of the row. */ enableRowClickSelection?: boolean; /** Enable spreadsheet-style cell range selection. Can be disabled globally or per column. */ enableCellSelection?: boolean; onRowSelectionChange?: OnChangeFn; enableHiding?: boolean; onColumnVisibilityChange?: OnChangeFn; /** * When true (default), columns cannot be hidden while a column drag is in * progress. Prevents accidental column hiding caused by `dragleave` events * during reorder operations. Set to `false` to allow hiding during drag. */ suppressDragHidesColumns?: boolean; enableColumnReorder?: boolean; onColumnOrderChange?: OnChangeFn; enableColumnPinning?: boolean; onColumnPinningChange?: OnChangeFn; enableColumnResizing?: boolean; columnResizeMode?: 'onChange' | 'onEnd'; columnResizeDirection?: 'ltr' | 'rtl'; onColumnSizingChange?: OnChangeFn; onColumnSizingInfoChange?: OnChangeFn; enableExpanding?: boolean; getSubRows?: (row: TData, index: number) => TData[] | undefined; getRowCanExpand?: (row: Row) => boolean; manualExpanding?: boolean; paginateExpandedRows?: boolean; onExpandedChange?: OnChangeFn; renderDetailPanel?: (row: Row) => unknown; enableRowPinning?: boolean | ((row: Row) => boolean); keepPinnedRows?: boolean; onRowPinningChange?: OnChangeFn; enableGrouping?: boolean; manualGrouping?: boolean; onGroupingChange?: OnChangeFn; enableCellEditing?: boolean; onEditingChange?: OnChangeFn; onEditCommit?: (changes: Record>) => void; /** * Async commit handler. Receives a batch of patches; resolve to mark * success, throw to mark failure. Throw a `CommitError` for per-cell * precision. See features/commits/types.ts for `CellPatch` shape. */ onCommit?: OnCommitFn; /** * Default true. Set to false to make the grid accumulate pending edits * and only fire `onCommit` when `table.commit()` is called. */ autoCommit?: boolean; /** * What happens when a row commit partially fails. * - 'failed' (default) — failed cells stay errored, succeeded cells clear * - 'batch' — entire row stays errored until the whole row is retried */ rowCommitRetryMode?: 'failed' | 'batch'; enableKeyboardNavigation?: boolean; onKeyboardNavigationChange?: OnChangeFn; enableVirtualization?: boolean; rowHeight?: number | ((index: number) => number); overscan?: number; estimateRowHeight?: number; /** Pre-computed row heights from Pretext measurement (Float64Array indexed by row) */ pretextHeights?: Float64Array | null; /** Pre-computed prefix sums for O(log n) scroll lookups */ pretextPrefixSums?: Float64Array | null; /** * Height in px of the virtualized scroll viewport. Without it the viewport * falls back to built-in heuristics (~20 rows, capped at 800px), which can * overflow a shorter styled container and leave a clipped-but-scrollable * region below it. */ virtualViewportHeight?: number; enableExport?: boolean; enableUndoRedo?: boolean; undoStackSize?: number; enableClipboard?: boolean; clipboardOptions?: ClipboardOptions; enableFillHandle?: boolean; enableFormulas?: boolean; enableRowDragging?: boolean; onRowReorder?: (event: { fromIndex: number; toIndex: number; rowId: string; }) => void; getDataPath?: (row: TData) => string[]; treeData?: boolean; enablePivot?: boolean; pivotConfig?: PivotConfig; rowClassName?: string | ((row: Row) => string | undefined); rowStyle?: React.CSSProperties | ((row: Row) => React.CSSProperties); onCellClick?: (event: CellClickEvent) => void; onCellDoubleClick?: (event: CellClickEvent) => void; onCellContextMenu?: (event: CellClickEvent) => void; onRowClick?: (event: RowClickEvent) => void; onRowDoubleClick?: (event: RowClickEvent) => void; onRowContextMenu?: (event: RowClickEvent) => void; onHeaderClick?: (event: HeaderClickEvent) => void; onHeaderContextMenu?: (event: HeaderClickEvent) => void; } type TableOptionsResolved = Required, 'data' | 'columns' | 'state' | 'onStateChange'>> & Omit, 'data' | 'columns' | 'state' | 'onStateChange'>; interface TableState { sorting: SortingState; columnFilters: ColumnFiltersState; globalFilter: string; pagination: PaginationState; rowSelection: RowSelectionState; cellSelection?: CellRangeSelectionState; columnVisibility: VisibilityState; columnOrder: ColumnOrderState; columnPinning: ColumnPinningState; columnSizing: ColumnSizingState; columnSizingInfo: ColumnSizingInfoState; expanded: ExpandedState; rowPinning: RowPinningState; grouping: GroupingState; editing: EditingState; /** Optimistic-commit slice — see features/commits/types.ts (Task #10). */ commits: CommitsSlice; keyboardNavigation: KeyboardNavigationState; undoRedo: UndoRedoState; fillHandle: FillHandleState; formulas: FormulaState; rowDrag: RowDragState; pivot: PivotState; } type SortDirection = 'asc' | 'desc'; interface ColumnSort { id: string; desc: boolean; } type SortingState = ColumnSort[]; type SortingFn = (rowA: Row, rowB: Row, columnId: string) => number; type SortingFnOption = 'auto' | SortingFn | keyof BuiltInSortingFns | (string & {}); interface BuiltInSortingFns { alphanumeric: SortingFn; alphanumericCaseSensitive: SortingFn; text: SortingFn; textCaseSensitive: SortingFn; datetime: SortingFn; basic: SortingFn; } interface ColumnFilter { id: string; value: unknown; } type ColumnFiltersState = ColumnFilter[]; type FilterFn = (row: Row, columnId: string, filterValue: unknown, addMeta: (meta: FilterMeta) => void) => boolean; type FilterFnOption = FilterFn | keyof BuiltInFilterFns | (string & {}); interface BuiltInFilterFns { includesString: FilterFn; includesStringSensitive: FilterFn; equalsString: FilterFn; equalsStringSensitive: FilterFn; arrIncludes: FilterFn; arrIncludesAll: FilterFn; arrIncludesSome: FilterFn; equals: FilterFn; weakEquals: FilterFn; inNumberRange: FilterFn; } interface FilterMeta { itemRank?: unknown; [key: string]: unknown; } interface PaginationState { pageIndex: number; pageSize: number; } type RowSelectionState = Record; interface CellRange { start: KeyboardNavigationCell; end: KeyboardNavigationCell; } interface CellRangeSelectionState { range: CellRange | null; anchor: KeyboardNavigationCell | null; isDragging: boolean; } type VisibilityState = Record; type ColumnOrderState = string[]; interface ColumnPinningState { left?: string[]; right?: string[]; } type ColumnSizingState = Record; interface ColumnSizingInfoState { startOffset: number | null; startSize: number | null; deltaOffset: number | null; deltaPercentage: number | null; isResizingColumn: string | false; columnSizingStart: [string, number][]; } type ExpandedState = Record | true; interface RowPinningState { top?: string[]; bottom?: string[]; } type GroupingState = string[]; interface EditingState { activeCell?: { rowId: string; columnId: string; }; pendingValues: Record>; /** Set of row IDs currently being edited in full-row mode */ editingRows?: string[]; } interface KeyboardNavigationCell { rowIndex: number; columnIndex: number; } interface KeyboardNavigationState { focusedCell: KeyboardNavigationCell | null; } type KeyboardNavigationDirection = 'up' | 'down' | 'left' | 'right'; type KeyboardNavigationAction = { type: 'arrow'; direction: KeyboardNavigationDirection; ctrlKey?: boolean; } | { type: 'tab'; shiftKey?: boolean; } | { type: 'home'; ctrlKey?: boolean; } | { type: 'end'; ctrlKey?: boolean; } | { type: 'page'; direction: 'up' | 'down'; pageSize: number; }; interface UndoRedoState { undoStack: UndoAction[]; redoStack: UndoAction[]; maxSize: number; } interface UndoAction { type: 'cell-edit'; rowId: string; columnId: string; oldValue: unknown; newValue: unknown; timestamp: number; } interface RowDragState { /** The row id currently being dragged, or null */ draggingRowId: string | null; /** The row id that is the current drop target */ overRowId: string | null; /** Position of the drop indicator relative to the target row */ dropPosition: 'before' | 'after' | null; } interface PivotConfig { /** Fields to use as row groups */ rowFields: { field: string; label?: string; }[]; /** Fields to use as column groups (generate dynamic columns) */ columnFields: { field: string; label?: string; }[]; /** Fields to aggregate as values */ valueFields: { field: string; aggregation: string | AggregationFn; label?: string; }[]; /** Whether to show row subtotals */ showRowSubtotals?: boolean; /** Whether to show column subtotals */ showColumnSubtotals?: boolean; /** Whether to show grand total row */ showGrandTotal?: boolean; } interface PivotState { /** Whether pivot mode is active */ enabled: boolean; /** Pivot configuration */ config: PivotConfig; /** Expanded row groups (by path key) */ expandedRowGroups: Record; /** Expanded column groups (by path key) */ expandedColumnGroups: Record; } interface ClipboardOptions { /** Column delimiter for copy/paste. Default: '\t' (tab, for Excel compatibility) */ delimiter?: string; /** Row delimiter for copy/paste. Default: '\n' */ rowDelimiter?: string; /** Include column headers when copying. Default: false */ includeHeaders?: boolean; } interface FillHandleState { /** Whether a fill drag is in progress */ isDragging: boolean; /** Source cell position (row index, column index) */ sourceCell?: { rowIndex: number; columnIndex: number; }; /** Current drag target cell position */ targetCell?: { rowIndex: number; columnIndex: number; }; /** Fill direction */ direction?: 'down' | 'right' | 'up' | 'left'; } interface FormulaState { /** Whether formulas are enabled */ enabled: boolean; /** Map of cell ID -> raw formula string (e.g. '=SUM(A1:A10)') */ formulas: Record; /** Map of cell ID -> computed value */ computedValues: Record; /** Map of cell ID -> error message (if evaluation failed) */ errors: Record; } type AggregationFn = (columnId: string, leafRows: Row[], childRows: Row[]) => unknown; type AggregationFnOption = 'sum' | 'min' | 'max' | 'extent' | 'mean' | 'median' | 'unique' | 'uniqueCount' | 'count' | AggregationFn | (string & {}); interface Table { _features: TableFeature[]; options: TableOptionsResolved; initialState: TableState; getState: () => TableState; setState: (updater: Updater) => void; setOptions: (newOptions: Updater>) => void; reset: () => void; getAllColumns: () => Column[]; getAllFlatColumns: () => Column[]; getAllLeafColumns: () => Column[]; getColumn: (columnId: string) => Column | undefined; getVisibleFlatColumns: () => Column[]; getVisibleLeafColumns: () => Column[]; getLeftVisibleLeafColumns: () => Column[]; getRightVisibleLeafColumns: () => Column[]; getCenterVisibleLeafColumns: () => Column[]; getHeaderGroups: () => HeaderGroup[]; getLeftHeaderGroups: () => HeaderGroup[]; getRightHeaderGroups: () => HeaderGroup[]; getCenterHeaderGroups: () => HeaderGroup[]; getFooterGroups: () => HeaderGroup[]; getLeftFooterGroups: () => HeaderGroup[]; getRightFooterGroups: () => HeaderGroup[]; getCenterFooterGroups: () => HeaderGroup[]; getCoreRowModel: () => RowModel; getRowModel: () => RowModel; getRow: (id: string, searchAll?: boolean) => Row; getFilteredRowModel: () => RowModel; getPreFilteredRowModel: () => RowModel; getSortedRowModel: () => RowModel; getPreSortedRowModel: () => RowModel; getPaginationRowModel: () => RowModel; getPrePaginationRowModel: () => RowModel; getGroupedRowModel: () => RowModel; getPreGroupedRowModel: () => RowModel; getExpandedRowModel: () => RowModel; getPreExpandedRowModel: () => RowModel; getPageCount: () => number; getRowCount: () => number; getCanPreviousPage: () => boolean; getCanNextPage: () => boolean; previousPage: () => void; nextPage: () => void; firstPage: () => void; lastPage: () => void; setPagination: (updater: Updater) => void; setPageIndex: (updater: Updater) => void; setPageSize: (size: number) => void; resetPageIndex: (defaultState?: boolean) => void; resetPageSize: (defaultState?: boolean) => void; resetPagination: (defaultState?: boolean) => void; setSorting: (updater: Updater) => void; resetSorting: (defaultState?: boolean) => void; setColumnFilters: (updater: Updater) => void; resetColumnFilters: (defaultState?: boolean) => void; setGlobalFilter: (updater: Updater) => void; resetGlobalFilter: (defaultState?: boolean) => void; getSelectedRowModel: () => RowModel; getFilteredSelectedRowModel: () => RowModel; getGroupedSelectedRowModel: () => RowModel; getIsAllRowsSelected: () => boolean; getIsSomeRowsSelected: () => boolean; getIsAllPageRowsSelected: () => boolean; getIsSomePageRowsSelected: () => boolean; toggleAllRowsSelected: (value?: boolean) => void; toggleAllPageRowsSelected: (value?: boolean) => void; getToggleAllRowsSelectedHandler: () => (event: unknown) => void; getToggleAllPageRowsSelectedHandler: () => (event: unknown) => void; setRowSelection: (updater: Updater) => void; resetRowSelection: (defaultState?: boolean) => void; getCellSelectionRange: () => CellRange | null; clearCellSelection: () => void; selectCell: (cell: KeyboardNavigationCell, options?: { extend?: boolean; keepAnchor?: boolean; }) => void; startCellRangeSelection: (cell: KeyboardNavigationCell, options?: { extend?: boolean; }) => void; updateCellRangeSelection: (cell: KeyboardNavigationCell) => void; endCellRangeSelection: () => void; getIsCellSelected: (rowIndex: number, columnIndex: number) => boolean; getCellSelectionEdges: (rowIndex: number, columnIndex: number) => { top: boolean; right: boolean; bottom: boolean; left: boolean; } | null; setColumnVisibility: (updater: Updater) => void; resetColumnVisibility: (defaultState?: boolean) => void; toggleAllColumnsVisible: (value?: boolean) => void; getIsAllColumnsVisible: () => boolean; getIsSomeColumnsVisible: () => boolean; setColumnOrder: (updater: Updater) => void; resetColumnOrder: (defaultState?: boolean) => void; setColumnPinning: (updater: Updater) => void; resetColumnPinning: (defaultState?: boolean) => void; getIsSomeColumnsPinned: (position?: 'left' | 'right') => boolean; setColumnSizing: (updater: Updater) => void; setColumnSizingInfo: (updater: Updater) => void; resetColumnSizing: (defaultState?: boolean) => void; sizeColumnsToFit: (width: number) => void; getTotalSize: () => number; getLeftTotalSize: () => number; getRightTotalSize: () => number; getCenterTotalSize: () => number; setExpanded: (updater: Updater) => void; toggleAllRowsExpanded: (expanded?: boolean) => void; resetExpanded: (defaultState?: boolean) => void; getCanSomeRowsExpand: () => boolean; getIsAllRowsExpanded: () => boolean; getIsSomeRowsExpanded: () => boolean; getExpandedDepth: () => number; setRowPinning: (updater: Updater) => void; resetRowPinning: (defaultState?: boolean) => void; getTopRows: () => Row[]; getBottomRows: () => Row[]; getCenterRows: () => Row[]; setGrouping: (updater: Updater) => void; resetGrouping: (defaultState?: boolean) => void; startEditing: (rowId: string, columnId: string) => void; commitEdit: () => void; cancelEdit: () => void; setPendingValue: (rowId: string, columnId: string, value: unknown) => void; getPendingValue: (rowId: string, columnId: string) => unknown | undefined; getPendingRow: (rowId: string) => Partial | undefined; getAllPendingChanges: () => Record>; hasPendingChanges: () => boolean; commitAllPending: () => void; discardAllPending: () => void; getValidationErrors: () => Record>; isValid: () => boolean; setEditing: (updater: Updater) => void; resetEditing: (defaultState?: boolean) => void; /** Read the merged render value (pending shadows saved). */ getCellRenderValue: (rowId: string, columnId: string) => unknown; /** Read the cell's commit status. */ getCellStatus: (rowId: string, columnId: string) => 'idle' | 'pending' | 'error' | 'conflict'; /** Error message if status === 'error'. */ getCellErrorMessage: (rowId: string, columnId: string) => string | undefined; /** Conflicting saved value if status === 'conflict'. */ getCellConflictWith: (rowId: string, columnId: string) => unknown; /** Manually fire all pending commits (used when autoCommit=false). */ commit: () => Promise; /** Retry a single failed/conflicted cell. */ retryCommit: (rowId: string, columnId: string) => Promise; /** Drop a single pending/error/conflict entry without retrying. */ dismissCommit: (rowId: string, columnId: string) => void; /** Drop all pending/error/conflict entries. */ dismissAllCommits: () => void; getFocusedCell: () => KeyboardNavigationCell | null; setFocusedCell: (cell: KeyboardNavigationCell | null) => void; clearFocusedCell: () => void; moveFocus: (action: KeyboardNavigationAction) => KeyboardNavigationCell | null; setKeyboardNavigation: (updater: Updater) => void; resetKeyboardNavigation: (defaultState?: boolean) => void; exportData: (options?: ExportOptions) => string; undo: () => void; redo: () => void; canUndo: () => boolean; canRedo: () => boolean; clearUndoHistory: () => void; copyToClipboard: (options?: ClipboardOptions) => string; pasteFromClipboard: (text: string, targetRowId: string, targetColumnId: string, options?: ClipboardOptions) => void; cutCells: (options?: ClipboardOptions) => string; fillRange: (sourceRange: { startRow: number; startCol: number; endRow: number; endCol: number; }, targetRange: { startRow: number; startCol: number; endRow: number; endCol: number; }) => void; setFormula: (rowId: string, columnId: string, formula: string) => void; getFormula: (rowId: string, columnId: string) => string | undefined; evaluateFormulas: () => void; moveRow: (fromIndex: number, toIndex: number) => void; startRowEditing: (rowId: string) => void; commitRowEdit: (rowId: string) => void; cancelRowEdit: (rowId: string) => void; isRowEditing: (rowId: string) => boolean; getEditingRows: () => string[]; getEditableColumnIds: (rowId: string) => string[]; getPivotRowModel: () => RowModel; /** Signal that a column header drag has started. */ setColumnDragActive: (active: boolean) => void; /** Returns true while a column header drag is in progress. */ getIsColumnDragActive: () => boolean; /** * Ask any active `autoColumnWidth` sizing to re-measure column content now. * Emits `'columns:remeasure'`. Call this after an async value merge (cell * values arriving from a separate query) so smart width re-sizes on the real * content instead of the placeholder it first saw. No-op when smart width is * off. Respects the provenance rule: only auto-owned widths update; user-set * or persisted widths are never overwritten. */ remeasureColumns: (reason?: string) => void; events: EventEmitter>; getLocaleString: (key: string) => string; } interface RowModel { rows: Row[]; flatRows: Row[]; rowsById: Record>; } interface Column { id: string; depth: number; columnDef: ColumnDef; columns: Column[]; parent?: Column; accessorFn?: (row: TData, index: number) => TValue; getFlatColumns: () => Column[]; getLeafColumns: () => Column[]; getSize: () => number; getStart: (position?: ColumnPinningPosition) => number; getAfter: (position?: ColumnPinningPosition) => number; getCanResize: () => boolean; getIsResizing: () => boolean; resetSize: () => void; getCanReorder: () => boolean; getCanSort: () => boolean; getCanMultiSort: () => boolean; getAutoSortingFn: () => SortingFn; getAutoSortDir: () => SortDirection; getSortingFn: () => SortingFn; getNextSortingOrder: () => SortDirection | false; getIsSorted: () => false | SortDirection; getSortIndex: () => number; clearSorting: () => void; toggleSorting: (desc?: boolean, isMulti?: boolean) => void; getToggleSortingHandler: () => ((event: unknown) => void) | undefined; getCanFilter: () => boolean; getCanGlobalFilter: () => boolean; getIsFiltered: () => boolean; getFilterValue: () => unknown; getFilterIndex: () => number; setFilterValue: (value: unknown) => void; getAutoFilterFn: () => FilterFn | undefined; getFilterFn: () => FilterFn | undefined; getCanHide: () => boolean; getIsVisible: () => boolean; toggleVisibility: (value?: boolean) => void; getToggleVisibilityHandler: () => (event: unknown) => void; getCanPin: () => boolean; getIsPinned: () => ColumnPinningPosition | false; pin: (position: ColumnPinningPosition) => void; getPinnedIndex: () => number; getFacetedRowModel: () => RowModel; getFacetedUniqueValues: () => Map; getFacetedMinMaxValues: () => [number, number] | undefined; getCanGroup: () => boolean; getIsGrouped: () => boolean; getGroupedIndex: () => number; toggleGrouping: () => void; getAutoAggregationFn: () => AggregationFn | undefined; getAggregationFn: () => AggregationFn | undefined; } type ColumnPinningPosition = 'left' | 'right' | false; interface Header { id: string; index: number; depth: number; column: Column; headerGroup: HeaderGroup; subHeaders: Header[]; colSpan: number; rowSpan: number; isPlaceholder: boolean; placeholderId?: string; getLeafHeaders: () => Header[]; getSize: () => number; getStart: (position?: ColumnPinningPosition) => number; getContext: () => HeaderContext; getResizeHandler: () => ((event: unknown) => void) | undefined; } interface HeaderGroup { id: string; depth: number; headers: Header[]; } interface HeaderContext { table: Table; header: Header; column: Column; } interface Row { id: string; index: number; original: TData; depth: number; parentId?: string; subRows: Row[]; getValue: (columnId: string) => TValue; renderValue: (columnId: string) => TValue; getAllCells: () => Cell[]; getVisibleCells: () => Cell[]; getLeftVisibleCells: () => Cell[]; getRightVisibleCells: () => Cell[]; getCenterVisibleCells: () => Cell[]; getIsSelected: () => boolean; getIsSomeSelected: () => boolean; getIsAllSubRowsSelected: () => boolean; getCanSelect: () => boolean; getCanMultiSelect: () => boolean; getCanSelectSubRows: () => boolean; toggleSelected: (value?: boolean, opts?: { selectChildren?: boolean; }) => void; getToggleSelectedHandler: () => (event: unknown) => void; getIsExpanded: () => boolean; getCanExpand: () => boolean; getIsGrouped: () => boolean; toggleExpanded: (expanded?: boolean) => void; getToggleExpandedHandler: () => (event: unknown) => void; getIsPinned: () => RowPinningPosition | false; getCanPin: () => boolean; pin: (position: RowPinningPosition, includeLeafRows?: boolean, includeParentRows?: boolean) => void; groupingColumnId?: string; groupingValue?: unknown; getGroupingValue: (columnId: string) => unknown; getLeafRows: () => Row[]; getParentRow: () => Row | undefined; getTreeDepth: () => number; isLeaf: () => boolean; } type RowPinningPosition = 'top' | 'bottom' | false; interface Cell { id: string; row: Row; column: Column; getValue: () => TValue; renderValue: () => TValue; getContext: () => CellContext; getIsEditing: () => boolean; getIsAlwaysEditable: () => boolean; getRowSpan: () => number | undefined; } interface CellContext { table: Table; column: Column; row: Row; cell: Cell; getValue: () => TValue; renderValue: () => TValue; } interface EventEmitter> { on: (event: K, handler: (payload: TEventMap[K]) => void) => () => void; off: (event: K, handler: (payload: TEventMap[K]) => void) => void; emit: (event: K, payload: TEventMap[K]) => void; removeAllListeners: (event?: keyof TEventMap) => void; } interface YableEventMap { 'cell:click': CellClickEvent; 'cell:dblclick': CellClickEvent; 'cell:contextmenu': CellClickEvent; 'row:click': RowClickEvent; 'row:dblclick': RowClickEvent; 'row:contextmenu': RowClickEvent; 'header:click': HeaderClickEvent; 'header:contextmenu': HeaderClickEvent; 'cell:edit:start': CellEditEvent; 'cell:edit:commit': CellEditEvent; 'cell:edit:cancel': CellEditEvent; 'selection:change': SelectionChangeEvent; 'sort:change': SortChangeEvent; 'filter:change': FilterChangeEvent; 'page:change': PageChangeEvent; 'state:change': StateChangeEvent; undo: UndoRedoEvent; redo: UndoRedoEvent; 'clipboard:copy': ClipboardEvent_; 'clipboard:paste': ClipboardEvent_; 'clipboard:cut': ClipboardEvent_; fill: FillEvent; 'cell:flash': CellFlashEvent; 'row:drag:start': RowDragEvent; 'row:drag:end': RowDragEndEvent; 'row:reorder': RowReorderEvent; 'row:edit:start': RowEditEvent; 'row:edit:commit': RowEditCommitEvent; 'row:edit:cancel': RowEditEvent; 'columns:remeasure': ColumnsRemeasureEvent; } interface ColumnsRemeasureEvent { /** Optional caller-supplied hint for why a re-measure was requested. */ reason?: string; } interface CellClickEvent { cell: Cell; row: Row; column: Column; originalEvent?: unknown; } interface RowClickEvent { row: Row; cells: Cell[]; originalEvent?: unknown; } interface HeaderClickEvent { column: Column; header: Header; originalEvent?: unknown; } interface CellEditEvent { cell: Cell; row: Row; column: Column; value: unknown; previousValue?: unknown; } interface SelectionChangeEvent { selection: RowSelectionState; selectedRows: Row[]; } interface SortChangeEvent { sorting: SortingState; } interface FilterChangeEvent { columnFilters: ColumnFiltersState; globalFilter: string; } interface PageChangeEvent { pagination: PaginationState; } interface StateChangeEvent { state: TableState; previousState: TableState; } interface UndoRedoEvent { action: UndoAction; state: UndoRedoState; } interface ClipboardEvent_ { text: string; cells: { rowId: string; columnId: string; value: unknown; }[]; } interface FillEvent { sourceRange: { startRow: number; startCol: number; endRow: number; endCol: number; }; targetRange: { startRow: number; startCol: number; endRow: number; endCol: number; }; filledValues: { rowId: string; columnId: string; value: unknown; }[]; } interface CellFlashEvent { columnId: string; rowId: string; direction: 'up' | 'down' | 'change'; previousValue: unknown; newValue: unknown; timestamp: number; } interface ExportOptions { format?: 'csv' | 'json'; allRows?: boolean; columns?: string[]; includeHeaders?: boolean; delimiter?: string; fileName?: string; } interface RowDragEvent { rowId: string; rowIndex: number; row: Row; } interface RowDragEndEvent { rowId: string; row: Row; cancelled: boolean; } interface RowReorderEvent { fromIndex: number; toIndex: number; rowId: string; } interface RowEditEvent { rowId: string; row: Row; } interface RowEditCommitEvent { rowId: string; row: Row; values: Record; } interface ColumnHelper { accessor: | ((row: TData) => unknown), TValue extends TAccessor extends (...args: any) => infer R ? R : TAccessor extends DeepKeys ? DeepValue : never>(accessor: TAccessor, column: TAccessor extends (...args: any) => any ? Omit, 'accessorFn'> : Omit, 'accessorKey'>) => ColumnDef; display: (column: DisplayColumnDef) => ColumnDef; group: (column: GroupColumnDef) => ColumnDef; /** * Normalize a heterogeneous column list into `ColumnDef[]`. * * `helper.accessor(...)` returns a `ColumnDef` with a concrete, * per-column `TValue`. Because `TValue` is invariant, an inline array of mixed * accessor columns (string, number, boolean, derived) infers as a union of * element types that does **not** assign to `ColumnDef[]`, * forcing an `as ColumnDef` cast on nearly every column. Wrap * the array in `helper.columns([...])` to erase the per-column `TValue` in one * place and get an array the table options accept directly. */ columns: (columns: ReadonlyArray>) => ColumnDef[]; } declare module 'react' { interface CSSProperties { [key: string]: string | number | undefined; } } export type { ExportOptions as $, AccessorFnColumnDef as A, ColumnDefExtensions as B, CommitsSlice as C, DeepKeys as D, ColumnFilter as E, FilterFn as F, ColumnFiltersState as G, HeaderGroup as H, ColumnMeta as I, ColumnOrderState as J, KeyboardNavigationCell as K, ColumnPinningPosition as L, ColumnPinningState as M, ColumnSizingInfoState as N, OnCommitFn as O, ColumnSizingState as P, ColumnSort as Q, RowData as R, SortingFn as S, TableOptions as T, Updater as U, ColumnsRemeasureEvent as V, CommitResult as W, DisplayColumnDef as X, EditingState as Y, EventEmitter as Z, ExpandedState as _, CellPatch as a, FillHandleState as a0, FilterChangeEvent as a1, FilterFnOption as a2, FilterMeta as a3, FormulaState as a4, GroupColumnDef as a5, GroupingState as a6, HeaderClickEvent as a7, HeaderContext as a8, KeyboardNavigationDirection as a9, UndoAction as aA, UndoRedoState as aB, VisibilityState as aC, YableEventMap as aD, KeyboardNavigationState as aa, OnChangeFn as ab, PageChangeEvent as ac, PaginationState as ad, PivotConfig as ae, PivotState as af, RowClickEvent as ag, RowDragEndEvent as ah, RowDragEvent as ai, RowDragState as aj, RowEditCommitEvent as ak, RowEditEvent as al, RowModel as am, RowPinningPosition as an, RowPinningState as ao, RowReorderEvent as ap, RowSelectionState as aq, SelectionChangeEvent as ar, SortChangeEvent as as, SortDirection as at, SortingFnOption as au, SortingState as av, StateChangeEvent as aw, TableFeature as ax, TableOptionsResolved as ay, TableState as az, CommitRecord as b, Table as c, ColumnDef as d, Column as e, Row as f, Cell as g, Header as h, DeepValue as i, ColumnHelper as j, KeyboardNavigationAction as k, AccessorKeyColumnDef as l, AggregationFn as m, AggregationFnOption as n, CellClickEvent as o, CellContext as p, CellEditConfig as q, CellEditEvent as r, CellEditRenderProps as s, CellEditType as t, CellFlashEvent as u, CellRange as v, CellRangeSelectionState as w, CellStatus as x, ClipboardOptions as y, ColumnDefBase as z };