Documentation

@kanunilabs/datagrid


@kanunilabs/datagrid / DataGridController

Interface: DataGridController<TRow>

Type Parameters

TRow

TRow = GridRowData

Properties

events

readonly events: PivotEventEmitter<GridEventMap<TRow>>


gridId

readonly gridId: string


text

readonly text: GridDictionary

The grid's language, for engine-produced text (undo labels, validation).

Methods

addCalculatedColumn()

addCalculatedColumn(spec): string

Add a calculated column (Enterprise — the end user's "Add calculated column" dialog; a formula in the column definitions is Community). Returns its id. Placed after after, or last. A formula that does not compile is still added, showing #NAME? — check previewFormula first to refuse it instead.

Parameters

spec
after?

string

dataType?

GridDataType

formula

string

headerName

string

id?

string

Returns

string


applyAiState()

applyAiState(answer, options?): AiApplyResult

Apply a model's answer: an object or the JSON text of one. What is valid is applied in ONE step (one recompute, one undo-able change of view); what is not is left out and listed in dropped. Never throws on a bad answer — a half-right answer is the common case, and the half that is right is worth having.

Pass the same options the schema was built with: a part or column the model was not offered is ignored even if it sent one.

Parameters

answer

unknown

options?

AiStateOptions

Returns

AiApplyResult


applyColumnStates()

applyColumnStates(states): void

Parameters

states

ColumnState[]

Returns

void


applyTransaction()

applyTransaction(transaction): void

Parameters

transaction

RowTransaction<TRow>

Returns

void


applyTransactionAsync()

applyTransactionAsync(transaction, callback?): void

Queue a transaction. Applied with the others in the batch after asyncTransactionWait milliseconds, or immediately on flushAsyncTransactions().

The callback fires when the batch it joined has been applied — not when this call returns, which is the whole point.

Parameters

transaction

RowTransaction<TRow>

callback?

() => void

Returns

void


applyViewState()

applyViewState(view): void

Restore a snapshot produced by getViewState (unknown columns ignored).

Parameters

view

GridViewState

Returns

void


buildExportModel()

buildExportModel(options?): ExportModel

Build the export model from the CURRENT view — sorted, filtered, grouped, visible columns only, formatted values. Pagination is deliberately ignored: users expect "export" to mean the whole result, not the page on screen.

Parameters

options?

ExportOptions

Returns

ExportModel


cancel()

cancel(): void

Ask the current pipeline pass to stop.

Best-effort and honest about it: the off-thread pass checks between chunks, so a cancel lands at the next boundary rather than instantly, and a pass that has already produced its answer completes. What it reliably kills is work that is queued but not started — the common case when a user keeps typing.

computeToken is bumped so any result still on its way is discarded, which means calling this is always safe even when nothing is running.

Returns

void


canExportAll()

canExportAll(): boolean

Whether an export can cover the whole result — false for a Community grid on a server source, where that means paging through every row the server has. Writing only the rows already loaded instead would be a file that looks complete and is not.

Returns

boolean


canGroup()

canGroup(): boolean

Whether grouping is offered — false for a Community grid on a server source, and for a viewport source, which sends flat rows in its own order.

Returns

boolean


canListDistinctValues()

canListDistinctValues(): boolean

Whether the header filter checklist can be offered at all.

Client data: always — the rows are right here. Remote data: only when the DataSource implements loadDistinctValues, because a list built from the few blocks the grid happens to have cached would be a PARTIAL set the user would filter against believing it was complete.

Returns

boolean


canPinRow()

canPinRow(key): boolean

Whether the menu may offer pinning for this row (rowPinning on, and isRowPinnable).

Parameters

key

RowKey

Returns

boolean


canRedo()

canRedo(): boolean

Returns

boolean


canUndo()

canUndo(): boolean

Whether undo() would do anything — for enabling a toolbar button.

Returns

boolean


chartBasis()

chartBasis(source?, ordered?): string

Fingerprint of everything that can move a chart's numbers, for the given source. An adapter recomputes when this string changes and NOT otherwise — which is precisely how a sort (new contentReady, same rows) costs nothing: aggregation is order-independent, so the basis deliberately excludes it. Selection is also excluded: 'selection' charts listen to selectionChanged directly rather than fingerprinting a potentially huge key set.

Parameters

source?

ChartSource

ordered?

boolean

Returns

string


clearColumnFilters()

clearColumnFilters(): void

Returns

void


clearFind()

clearFind(): void

Stop finding: no text, no marks.

Returns

void


clearFocus()

clearFocus(): void

Returns

void


clearGrouping()

clearGrouping(): void

Returns

void


clearMeasuredRowHeights()

clearMeasuredRowHeights(): boolean

Forget every measurement — a column resize invalidates all of them.

Returns

boolean


clearPinnedRows()

clearPinnedRows(): void

Unpin every row.

Returns

void


clearSelection()

clearSelection(): void

Returns

void


clearSort()

clearSort(): void

Returns

void


clipboardCellText()

clipboardCellText(node, columnId, value, text): string

The text one cell copies — text (what it shows) through processCellForClipboard. For the renderers' range copy and cut; the row copy (getClipboardText) asks the same callback itself.

Parameters

node

DataRowNode<TRow>

columnId

string

value

unknown

text

string

Returns

string


collapseAllDetails()

collapseAllDetails(): void

Returns

void


collapseAllGroups()

collapseAllGroups(): void

Returns

void


collapseAllTreeRows()

collapseAllTreeRows(): void

Returns

void


collapseTreeRow()

collapseTreeRow(key): void

Parameters

key

RowKey

Returns

void


computeChartBoxData()

computeChartBoxData(spec): Promise<ChartBoxModel>

Each category's spread of one number column, for a box plot (computeChartBoxModel). Main thread, like the X-Y data: a median needs the values themselves, not an accumulator a worker could fold. Rows by source, as for every chart.

Parameters

spec

ChartBoxSpec

Returns

Promise<ChartBoxModel>


computeChartData()

computeChartData(spec, options?): Promise<ChartModel>

Aggregate the current data into a chart model.

Which rows, by source: 'view' — filtered + searched rows, BEFORE paging (default); 'selection' — the selected rows, falling back to 'view' when nothing is selected (a silently empty chart reads as a bug); 'all' — the source rows, ignoring the filter.

Runs off-thread through the worker's aggregate message whenever the grid itself is worker-backed and the spec has no custom reducer — measured at 33 ms vs 105 ms for a million rows, none of it on the main thread. Falls back to the row-walking path otherwise, so the answer is always available.

Pending edits: with a pending-value reader installed the worker table holds STALE stored values, so the row path is forced — the chart must agree with the footer, which reads pending values too.

Parameters

spec

ChartSpec<TRow>

options?
source?

ChartSource

Returns

Promise<ChartModel>


computeChartXYData()

computeChartXYData(spec): Promise<ChartXYModel>

Parameters

spec

ChartXYSpec

Returns

Promise<ChartXYModel>


dispose()

dispose(): void

Returns

void


ensureVisible()

ensureVisible(rowIndex, centerColumnIndex?): { scrollLeft?: number; scrollTop?: number; } | null

Scroll offsets needed to bring a row/column into view; null if already visible.

With sticky group headers, the headers of the row's own groups will cover the top of the viewport once it is there — scrolling up to the row stops short by their height, or keyboard navigation upward would walk the focus in under them.

Parameters

rowIndex

number

centerColumnIndex?

number

Returns

{ scrollLeft?: number; scrollTop?: number; } | null


executeCommand()

executeCommand(command): boolean

Execute a resolved keyboard command. Returning the handled flag lets the adapter decide about preventDefault without duplicating the matrix.

Parameters

command

GridCommand

Returns

boolean


expandAllDetails()

expandAllDetails(): void

Open every visible master row's panel — the mirror of collapseAllDetails (the stored set means OPEN unless expandedByDefault turned it around). Rows a filter hides stay as they were: "all" is what the reader sees.

Returns

void


expandAllGroups()

expandAllGroups(): void

Returns

void


expandAllTreeRows()

expandAllTreeRows(): void

Returns

void


expandTreeRow()

expandTreeRow(key): void

Parameters

key

RowKey

Returns

void


exportToCsv()

exportToCsv(options?): Promise<ExportResult>

The file writers report as busy but WITHOUT a percentage, because they have no honest one to report.

A percentage over the row loop was measured to cover 7 % of a large Excel export's wall time; the other 93 % is one writeBuffer() call that cannot report anything. A bar that races to full and then sits there for a minute and a half says the work is over when it has barely started, so the build gets the spinner and the honest news that it can no longer be interrupted. CSV is the exception — it is chunked end to end, so cancelling it works.

Parameters

options?

CsvExportOptions

Returns

Promise<ExportResult>


exportToExcel()

exportToExcel(options?): Promise<ExportResult>

Parameters

options?

ExcelExportOptions

Returns

Promise<ExportResult>


exportToPdf()

exportToPdf(options?): Promise<ExportResult>

Render the current view as a PDF (gap G3).

Fed by the SAME export model as CSV and Excel, so a parity rule that lands in the model reaches all three at once. jspdf and jspdf-autotable are optional peers, loaded on first use.

Parameters

options?

PdfExportOptions

Returns

Promise<ExportResult>


findNext()

findNext(): void

Make the next match current, wrapping at the end.

Returns

void


findPrevious()

findPrevious(): void

Make the previous match current, wrapping at the start.

Returns

void


flashCells()

flashCells(target?): void

Pulse these cells — the "this number just changed" highlight a trading or monitoring grid needs.

Core has no DOM, so this publishes the INTENT and the adapter paints it; the same split scrollRequested uses. Omitting columnIds flashes the whole row; omitting rowKeys flashes those columns in every visible row.

Nothing is validated against the current view on purpose: a key that has scrolled out simply matches no cell, and refusing the call would make the caller track the viewport the grid already tracks.

Parameters

target?
columnIds?

readonly string[]

duration?

number

rowKeys?

readonly RowKey[]

Returns

void


flushAsyncTransactions()

flushAsyncTransactions(): void

Apply everything queued right now.

The escape hatch for the moments a window is wrong: the user pressed something and the answer has to reflect every tick received so far.

Returns

void


focusCell()

focusCell(rowKey, columnId): void

Parameters

rowKey

RowKey

columnId

string

Returns

void


focusFindMatch()

focusFindMatch(): void

Move keyboard focus to the current match — what closing a find box does.

Returns

void


focusRow()

focusRow(key): void

Focus a row by key, keeping the column where it is (or taking the first one when nothing was focused yet). Scrolls it into view — focusing a row the user cannot see is not focus.

Parameters

key

RowKey

Returns

void


forEachDisplayedNode()

forEachDisplayedNode(callback): void

What the user can actually scroll to: group headers interleaved, tree rows at their depth, collapsed subtrees absent, and — when paging is on — only the current page.

The index is the row's position in the VIEW, which is what cellClicked/rowClicked report and what scrollToRow moves to.

Parameters

callback

(node, index) => void

Returns

void


forEachNode()

forEachNode(callback): void

Every row the grid was given, in SOURCE order — including rows the current filter hides. The iterator for "walk all my data as the grid sees it".

On a REMOTE grid the source is the server's; only loaded rows can be walked, so this iterates what the block cache currently holds and says so rather than pretending to reach rows nobody fetched.

Parameters

callback

(node, index) => void

Returns

void


forEachNodeAfterFilterAndSort()

forEachNodeAfterFilterAndSort(callback): void

The rows that survived the filter, in sort order — data rows only, no group headers. This is what a footer total, an export or a "select all matching" is computed over.

Parameters

callback

(node, index) => void

Returns

void


formatCellForEdit()

formatCellForEdit(columnId, value): unknown

A stored cell value as the EDITOR shows it: a formula's references as A1.

Parameters

columnId

string

value

unknown

Returns

unknown


getAiSchema()

getAiSchema(options?): Record<string, unknown>

The JSON Schema of this grid's state — filter, sort, grouping, column visibility / width / pinning and search — narrowed to what its columns allow. Send it to your own model as the structured-output format, with the user's request and getAiState(), and pass the answer to applyAiState.

No model ships with the grid and nothing is sent anywhere: the schema is plain data for the application to use with whichever model it chooses.

Parameters

options?

AiStateOptions

Returns

Record<string, unknown>


getAiState()

getAiState(options?): GridAiState

The current state in the schema's shape — what the model should start from, so "also sort by date" keeps the filter that is already there.

The filter is the whole one: the filter panel's tree and every column's own filter, ANDed.

Parameters

options?

AiStateOptions

Returns

GridAiState


getAnimateRows()

getAnimateRows(): boolean

Whether rows animate to a new order (G-CORE-04) — read by the renderers.

Returns

boolean


getBusy()

getBusy(): BusyChangedEvent

What the grid is doing right now. busy is false when it is idle.

Returns

BusyChangedEvent


getCalculatedColumns()

getCalculatedColumns(): CalculatedColumnSpec[]

The calculated columns added at runtime (not the ones in the configuration).

Returns

CalculatedColumnSpec[]


getCellFormula()

getCellFormula(rowKey, columnId): string | null

The formula text of a cell, or null when it holds a plain value.

Parameters

rowKey

RowKey

columnId

string

Returns

string | null


getCellSpans()

getCellSpans(columnId): readonly CellSpan[]

Merged blocks for one column, over the current view.

Computed on FIRST ASK and cached against the result identity, for two reasons. The pipeline does not know or care about spans, so making it compute them would charge every grid for a feature almost none use; and the renderer asks for the same column many times per frame — once per rendered row — so it has to be a lookup by the second call.

The cache is dropped whole when the result changes, because that is exactly when a sort, a filter or an edit can have moved a block's boundaries.

Parameters

columnId

string

Returns

readonly CellSpan[]


getClipboardText()

getClipboardText(options?): string

TSV for the current selection, or for the focused row when nothing is selected. Returns '' when there is nothing to copy.

Parameters

options?

ClipboardOptions

Returns

string


getColumnFilter()

getColumnFilter(columnId, part?): FilterNode | null

A column's effective filter, or just the part a given surface owns.

Parameters

columnId

string

part?

string

Returns

FilterNode | null


getColumnIdAt()

getColumnIdAt(index): string | null

One visual column position → its id, without building the whole list.

Parameters

index

number

Returns

string | null


getColumnLayout()

getColumnLayout(): ColumnLayout<TRow>

Returns

ColumnLayout<TRow>


getColumnModel()

getColumnModel(): ColumnModel<TRow>

Returns

ColumnModel<TRow>


getColumnStates()

getColumnStates(): ColumnState[]

Returns

ColumnState[]


getColumnSummary()

getColumnSummary(columnId): SummaryDef<TRow> | null

The aggregation a column's footer cell shows, or null when it has none.

Parameters

columnId

string

Returns

SummaryDef<TRow> | null


getComputeTimings()

getComputeTimings(): Record<string, number>

Where the last pipeline pass spent its time, in milliseconds.

Telemetry, not API: shapes and keys may grow. modelMs covers the row model (encode + worker + node projection, itemized when the model reports them); summaryMs the footer reduction; projectViewMs handing the result to the window engine and listeners.

Returns

Record<string, number>


getDataRowCount()

getDataRowCount(): number

Data rows only — group headers excluded (what a "row count" should mean).

Returns

number


getDataRowNode()

getDataRowNode(key): DataRowNode<TRow> | undefined

The DATA node for a key, in O(1) — the accessor an editing or drag layer needs per row.

Without this the only way to go from a key to a row was to scan getDataRows(), which is how a grid with a custom footer aggregate ended up doing rows × rows work on every recompute.

Parameters

key

RowKey

Returns

DataRowNode<TRow> | undefined


getDataRows()

getDataRows(): DataRowNode<TRow>[]

Data rows only. Remote grouping puts server-produced headers into the same result, and remote paging leaves holes, so both are filtered out here rather than at every call site.

The array is a SHARED SNAPSHOT, rebuilt when the result changes — treat it as read-only. Handing out a fresh copy per call is what made resolving one row by key cost a walk of the whole result; use getRowByKey() for that.

Returns

DataRowNode<TRow>[]


getDetailHeight()

getDetailHeight(): number

Height of one detail panel in px.

Returns

number


getDistinctValues()

getDistinctValues(columnId, limit?): object[]

Distinct display values for a column, collator-sorted — the data behind the header filter popup. Computed over the FULL dataset (not the filtered view) so unchecking a value never makes it disappear from the list.

Parameters

columnId

string

limit?

number

Returns

object[]


getDistinctValuesAsync()

getDistinctValuesAsync(columnId, limit?): Promise<object[]>

Distinct values for the header filter popup, whichever data path this grid is on.

The async twin of getDistinctValues, which stays synchronous (and empty for remote) because it is public API. Adapters should prefer this one: it is the only version that works for a server-side grid.

Parameters

columnId

string

limit?

number

Returns

Promise<object[]>


getDistinctValueSet()

getDistinctValueSet(columnId, limit?): object

The same list, plus whether the scan STOPPED EARLY.

truncated is the part that was missing. A million-row id column yields limit values and a list that looks complete, so the popup showed 1000 of 1.000.000 with nothing to say otherwise — the user reasonably concluded that was all the data there was. Whoever renders the list has to be able to say "and more", and searchDistinctValues is how the rest is reached.

Parameters

columnId

string

limit?

number

Returns

object

entries

entries: object[]

truncated

truncated: boolean


getDistinctValueSetAsync()

getDistinctValueSetAsync(columnId, onProgress?): Promise<{ entries: object[]; truncated: boolean; }>

The FULL distinct list — every value, collator-sorted, built in event-loop slices so the main thread never freezes (user requirement, 2026-08-14: the checklist must offer every value, with a loader while it is prepared).

Same collator, same tie order, same first-occurrence values as the synchronous scan — only the schedule differs. Cached until the source rows change, and concurrent calls for the same column share one build. The result reflects the rows as they were when the build STARTED; a build that outlives its data is simply not cached.

Parameters

columnId

string

onProgress?

(fraction) => void

Returns

Promise<{ entries: object[]; truncated: boolean; }>


getEditFormHeight()

getEditFormHeight(): number

Height of the open form in px — the adapter needs it to size the panel.

Returns

number


getEditFormRow()

getEditFormRow(): RowKey | null

The row whose form is open in the grid, or null.

Returns

RowKey | null


getEditingCells()

getEditingCells(): object[]

Cells currently open for editing. One entry for a cell session; every editable cell of the open row for a row/form/popup session; empty otherwise. Reported as cells either way, so a caller can highlight or validate without caring which mode produced them.

Returns

object[]


getEffectiveFilter()

getEffectiveFilter(): FilterNode | null

Programmatic + column filters combined.

This is the filter as WRITTEN, which is what the filter panel displays — it still reports the conditions while the filter is switched off, because a panel that went blank when you unticked it would give you nothing to tick back on. Use isFilterEnabled() to know whether the pipeline is running it.

Returns

FilterNode | null


getFilter()

getFilter(): FilterNode | null

Returns

FilterNode | null


getFindMatchKind()

getFindMatchKind(rowKey, columnId): "active" | "match" | null

How a cell takes part in the find: the current match, another match, or not at all. O(1).

Parameters

rowKey

RowKey

columnId

string

Returns

"active" | "match" | null


getFindNeedle()

getFindNeedle(): string

The folded search, for renderers marking the text inside a cell; '' when not finding.

Returns

string


getFindState()

getFindState(): object

Returns

object

active

active: FindMatch | null

activeIndex

activeIndex: number

count

count: number

text

text: string


getFocus()

getFocus(): FocusPosition | null

Returns

FocusPosition | null


getFocusedNode()

getFocusedNode(): RowNode<TRow> | undefined

The view node holding keyboard focus (may be a group header).

Resolved through the row axis (O(1) via the index cache), NOT with viewNodes.find. Two reasons, both learned the hard way: a linear scan per keystroke is the O(axis) navigation cost the remote surface was fixed for, and a REMOTE view is sparse — find visits holes as undefined and reading .key off one throws.

Returns

RowNode<TRow> | undefined


getFocusedRow()

getFocusedRow(): TRow | undefined

The focused row's DATA, or undefined for a group header / no focus.

Returns

TRow | undefined


getFocusedRowIndex()

getFocusedRowIndex(): number

Index of the focused row in the current view, or -1.

Returns

number


getFocusedRowKey()

getFocusedRowKey(): RowKey | null

Key of the focused row, or null.

Returns

RowKey | null


getFocusIndices()

getFocusIndices(): { columnIndex: number; rowIndex: number; } | null

Focused cell as view indices — adapters use this to scroll it into view.

Returns

{ columnIndex: number; rowIndex: number; } | null


getFormulaError()

getFormulaError(columnId): FormulaCompileError | null

Why a calculated column shows #NAME? — null when its formula compiled.

Parameters

columnId

string

Returns

FormulaCompileError | null


getGroupBy()

getGroupBy(): string | null

Outermost group column, or null — the single-level convenience accessor.

Returns

string | null


getGroupDisplay()

getGroupDisplay(): "fullWidth" | "aligned" | "column"

How group rows are drawn: one banner, cells aligned to the columns, or a group column.

Returns

"fullWidth" | "aligned" | "column"


getGroupEditAggregate()

getGroupEditAggregate(columnId): "sum" | "avg" | null

The subtotal a group row shows under this column, when the user may type a new one there: the column has groupEdit, the group row lays its subtotals out under their columns (display: 'aligned' | 'column') with group summaries on, and the column's first summary is a sum or an avg. Else null.

Parameters

columnId

string

Returns

"sum" | "avg" | null


getGroupLevels()

getGroupLevels(): string[]

Grouping levels, outermost first. Empty when not grouping.

Returns

string[]


getGroupRowKeys()

getGroupRowKeys(groupKey): RowKey[]

The data rows under a group header (any level), whether it is open or not.

Parameters

groupKey

string

Returns

RowKey[]


getGroupSelectionState()

getGroupSelectionState(groupKey): "none" | "all" | "some"

Whether a group's rows are all, some or none selected — the header checkbox's checked / indeterminate / empty. Cached per selection change, because every visible group header asks on every repaint.

Parameters

groupKey

string

Returns

"none" | "all" | "some"


getGroupSummaries()

getGroupSummaries(): boolean

Whether group headers currently carry aggregates.

Returns

boolean


getHistoryDepth()

getHistoryDepth(): object

History sizes, for a UI that shows "Undo (3)". Zeros without an editor.

Returns

object

redo

redo: number

undo

undo: number


getMeasuredRowHeights()

getMeasuredRowHeights(): ReadonlyMap<RowKey, number>

What the adapter last measured, so it can diff instead of re-reporting.

Returns

ReadonlyMap<RowKey, number>


getOverlay()

getOverlay(): "loading" | "noRows" | null

The overlay an adapter should render, or null for none.

Resolves the override against the grid's own state, so an adapter asks one question instead of reimplementing the precedence.

Returns

"loading" | "noRows" | null


getPage()

getPage(): number

Returns

number


getPageCount()

getPageCount(): number

Returns

number


getPageSize()

getPageSize(): number

Returns

number


getPendingAsyncTransactionCount()

getPendingAsyncTransactionCount(): number

How many transactions are waiting. Zero when the queue is idle.

Returns

number


getPinnedRowKeys()

getPinnedRowKeys(): PinnedRowKeys

The pinned keys of both bands, in pinned order.

Returns

PinnedRowKeys


getPinnedRows()

getPinnedRows(side): object[]

The rows of one band, with their current values: what the renderers draw. A key whose row is not loaded (a remote page scrolled away) shows the row as it was when pinned.

Parameters

side

PinnedRowSide

Returns

object[]


getRevealedCount()

getRevealedCount(): number

Rows revealed so far. Equals the full result once everything is shown.

Returns

number


getRowByKey()

getRowByKey(key): TRow | undefined

The row DATA for a key, in O(1). Undefined when no such row is loaded.

Parameters

key

RowKey

Returns

TRow | undefined


getRowHeight()

getRowHeight(): number

Returns

number


getRowHeightAt()

getRowHeightAt(index): number

Height of one view row, standard or not.

Parameters

index

number

Returns

number


getRowIndex()

getRowIndex(rowKey): number

The row's position in the current view, or -1 — the index cell ranges and getRows() use.

Parameters

rowKey

RowKey

Returns

number


getRowKey()

getRowKey(row): RowKey

Key of a row, using whatever resolver the grid was configured with.

Parameters

row

TRow

Returns

RowKey


getRowKeyField()

getRowKeyField(): string | null

The field a row's key is read from, or null when rowKey was given as a function. Used when a NEW row has to carry a key before the server assigns one; with a function resolver the app has to seed whatever it reads, which is what onInitNewRow is for.

Returns

string | null


getRowOffset()

getRowOffset(index): number

Distance from the top of the first view row to the top of this one.

Parameters

index

number

Returns

number


getRowPinSide()

getRowPinSide(key): PinnedRowSide | null

Which band a row is pinned to, or null.

Parameters

key

RowKey

Returns

PinnedRowSide | null


getRows()

getRows(): RowNode<TRow>[]

The rendered view: data rows, with group headers interleaved when grouping.

Returns

RowNode<TRow>[]


getSearchText()

getSearchText(): string

Returns

string


getSelectableCount()

getSelectableCount(): number

How many rows of the current result can be selected — the denominator of "everything is selected" for the header checkbox. The visible row count when there is no rule (or the source is remote, where only loaded rows could be asked).

Returns

number


getSelectedCount()

getSelectedCount(): number

Under "everything matching" this is the matching rows minus the exclusions AMONG them. An excluded row the current filter hides is not one of the rows the selection can mean, so it is not subtracted — the count once said 5 beside six listed rows (yapilacaklar 6d-5). O(exclusions).

A remote view holds only the blocks it fetched, so there an unloaded exclusion cannot be told apart from a filtered-out one; every exclusion still counts.

Returns

number


getSelectedKeys()

getSelectedKeys(): RowKey[]

The selected keys, MATERIALIZED.

Under deferred selection this walks the view to expand "everything matching" into a list — which is exactly the cost the deferred mode exists to avoid, so a caller that only needs to describe the selection (to send it to a server, say) should use getSelectionDescriptor() instead.

Returns

RowKey[]


getSelectedRows()

getSelectedRows(): TRow[]

Selected rows in current view order (unselected-but-filtered rows excluded).

Returns

TRow[]


getSelectionDescriptor()

getSelectionDescriptor(): SelectionDescriptor

The selection as a SHAPE rather than a list: { allMatching, keys }. O(exclusions) even when a million rows are selected.

Returns

SelectionDescriptor


getSelectionMode()

getSelectionMode(): SelectionMode

Returns

SelectionMode


getSort()

getSort(): SortDescriptor[]

Returns

SortDescriptor[]


getSortCycle()

getSortCycle(columnId): SortCycle

The directions a header click on this column steps through: its own sortCycle, else the grid's sorting.cycle, else ascending → descending → unsorted (G-SORT-01).

Parameters

columnId

string

Returns

SortCycle


getStickyGroupRows()

getStickyGroupRows(): StickyGroupRow[]

The group headers to draw pinned over the rows at the current scroll position, outermost first (grouping.stickyHeaders). Empty when the option is off, nothing is grouped, or the top row is in no group.

Changes with every scrolled pixel while a header is being pushed out, so renderers read it on bodyScroll as well as on view changes.

Returns

StickyGroupRow[]


getSummaries()

getSummaries(): Record<string, number | null>

Returns

Record<string, number | null>


getSummaryDefs()

getSummaryDefs(): readonly SummaryDef<TRow>[]

Current definitions, in the order they were added.

Returns

readonly SummaryDef<TRow>[]


getTotalCount()

getTotalCount(): number

Returns

number


getViewState()

getViewState(options?): GridViewState

Serializable snapshot of everything the user can change. Session state — selection, focused cell, scroll, Enterprise cell ranges — only when asked for with include (see ViewStateSession).

Parameters

options?

GetViewStateOptions

Returns

GridViewState


getVirtualWindow()

getVirtualWindow(): VirtualWindow

Returns

VirtualWindow


getVisibleCenterColumns()

getVisibleCenterColumns(): ColumnRuntime<TRow>[]

Center columns currently inside the window (pinned blocks render in full).

Returns

ColumnRuntime<TRow>[]


getVisibleCount()

getVisibleCount(): number

Returns

number


getVisualColumnCount()

getVisualColumnCount(): number

Number of columns a visual coordinate can address.

Returns

number


getVisualColumnIds()

getVisualColumnIds(): string[]

Column ids in VISUAL order — pinned-left, then centre, then pinned-right.

The order the user sees, which is what every rectangular operation is expressed in: a cell range, the fill handle, paste, the selection totals.

NOT getColumnModel().runtime(). That one buckets by pin already, so it looks equivalent — until a column is GROUPED, at which point it leaves the data area (layoutRuntime) while staying in the model, and every index from there rightwards names its neighbour. Nothing errors; the wrong column's values are simply read, or written.

Returns

string[]


groupBy()

groupBy(groupBy): void

Group by one column or a list of levels (multi-level is Enterprise — approved decision #4; the engine supports both and the edition gates it).

Parameters

groupBy

string | readonly string[] | null

Returns

void


handleRowClick()

handleRowClick(key, modifiers?): void

Standard click contract (plain / ctrl-toggle / shift-range).

Parameters

key

RowKey

modifiers?

SelectionClickModifiers

Returns

void


hasCellSpans()

hasCellSpans(): boolean

Whether ANY visible column merges — one check to skip the whole path.

Returns

boolean


hasMasterDetail()

hasMasterDetail(): boolean

Whether the grid was configured with master-detail at all.

Returns

boolean


hasMoreRows()

hasMoreRows(): boolean

True while there is more of the result left to reveal.

Returns

boolean


hasStickyGroupHeaders()

hasStickyGroupHeaders(): boolean

Whether grouping.stickyHeaders is on (renderers mount their layer on it).

Returns

boolean


hasTreePathRows()

hasTreePathRows(): boolean

Whether the view can hold made-up path rows (tree.getDataPath) — rows that are not records, so a renderer numbering records has to skip them.

Returns

boolean


hideOverlay()

hideOverlay(): void

Hand the decision back to the grid.

Returns

void


invalidate()

invalidate(options?): void

Ask the server again for everything cached (no-op for client data). The rows on screen stay until their new version arrives; a block the refresh cannot reload keeps its last data (2026-10-09 — it used to become Retry rows) and dataError reports the failure.

background: true refreshes without the loading overlay — for polling a server every few seconds, where the overlay would blink over a grid whose rows never left (2026-10-09). The busyChanged event still fires, with background: true.

Parameters

options?
background?

boolean

Returns

void


invalidateCellFormulas()

invalidateCellFormulas(): void

Forget every cell formula result. For a write that changes a row IN PLACE without a data change the controller hears about — the editing layer's write-through and its undo — after which a formula reading that cell would otherwise keep its old result until the next data change.

Returns

void


isAllMatchingSelected()

isAllMatchingSelected(): boolean

True while the selection is "everything matching the current filter".

Returns

boolean


isBandCollapsed()

isBandCollapsed(path): boolean

Parameters

path

string | readonly string[]

Returns

boolean


isBandCollapsible()

isBandCollapsible(path): boolean

True when some column under the band declares bandShow.

Parameters

path

string | readonly string[]

Returns

boolean


isCellFocused()

isCellFocused(rowKey, columnId): boolean

Parameters

rowKey

RowKey

columnId

string

Returns

boolean


isDebugMode()

isDebugMode(): boolean

Whether the app asked to be told when the grid declines to do something.

Read by the ADAPTER, which has refusals of its own to explain — a print layout skipped because the result is too large, say. Without this the adapter would either warn always (noise in production) or never (a feature that silently does nothing).

Returns

boolean


isDetailExpanded()

isDetailExpanded(rowKey): boolean

Parameters

rowKey

RowKey

Returns

boolean


isDisposed()

isDisposed(): boolean

Returns

boolean


isEditing()

isEditing(): boolean

Returns

boolean


isEnterpriseEdition()

isEnterpriseEdition(): boolean

Returns

boolean


isExternalFilterPresent()

isExternalFilterPresent(): boolean

True when a predicate is installed.

Returns

boolean


isFilterEnabled()

isFilterEnabled(): boolean

Whether the filter is currently being applied.

Returns

boolean


isGroupCollapsed()

isGroupCollapsed(groupKey): boolean

Parameters

groupKey

string

Returns

boolean


isInfiniteScroll()

isInfiniteScroll(): boolean

Returns

boolean


isPaginated()

isPaginated(): boolean

Returns

boolean


isRemote()

isRemote(): boolean

True when rows come from a DataSource rather than an array.

Returns

boolean


isRowLoadFailed()

isRowLoadFailed(index): boolean

Whether the row at this view index could not be loaded from the server. Such a row draws as failed — with a way to retry — instead of a loading skeleton that never resolves (P-SSRM-01). Always false for array data.

Parameters

index

number

Returns

boolean


isRowPinningEnabled()

isRowPinningEnabled(): boolean

Whether rowPinning is on — the renderers offer the menu entries only then.

Returns

boolean


isRowSelectable()

isRowSelectable(key): boolean

Whether the row may be selected under selection.isRowSelectable — what a renderer asks to disable a row's checkbox. True without a rule, and for a key the grid cannot resolve (a remote row not loaded yet): there is no row to judge, and a server-side selection is the server's to police.

Parameters

key

RowKey

Returns

boolean


isRowSelected()

isRowSelected(key): boolean

Parameters

key

RowKey

Returns

boolean


isTreeRowExpanded()

isTreeRowExpanded(key): boolean

Parameters

key

RowKey

Returns

boolean


isUsingWorker()

isUsingWorker(): boolean

Whether the pipeline is currently running off-thread. False below the worker threshold, without a Worker global (SSR), or after a worker failure dropped the grid back to the main thread. Exposed for diagnostics.

Returns

boolean


moveColumn()

moveColumn(id, beforeId?): void

Parameters

id

string

beforeId?

string

Returns

void


moveFocus()

moveFocus(command): boolean

Parameters

command

FocusCommand

Returns

boolean


moveRow()

moveRow(dragKey, targetKey, position?): boolean

Move a row next to another by hand (row drag & drop).

REFUSES while a sort is active, and says so under debugMode. A manual order that the sort immediately overrides is a drop that visibly does nothing — worse than no drag at all, because the user cannot tell whether it failed or the grid is broken. An app that wants both keeps its own order field, sorts by it, and updates it from onReorder.

Remote grids refuse too: the server owns the order, so the app persists the move from onReorder and the grid re-queries.

Returns whether the source array actually changed.

Parameters

dragKey

RowKey

targetKey

RowKey | null

position?

RowDropPosition

Returns

boolean


nextPage()

nextPage(): void

Returns

void


notifyCell()

notifyCell(name, node, rowIndex, columnId): void

Publish a cell interaction. Called by the adapter, not by applications.

Parameters

name

"cellClicked" | "cellDoubleClicked" | "cellContextMenu"

node

RowNode<TRow>

rowIndex

number

columnId

string

Returns

void


notifyCellValueChanged()

notifyCellValueChanged(change): void

Publish an edit. Called by the adapter (which owns the editing engine), not by applications.

row is resolved HERE rather than passed in, so the payload always carries the record as the grid currently holds it — the engine knows the pending value but not the row it belongs to.

Parameters

change
columnId

string

previousValue

unknown

rowKey

RowKey

source

CellChangeSource

value

unknown

Returns

void


notifyClipboardGesture()

notifyClipboardGesture(kind, cellCount, run): boolean

Publish a clipboard or fill gesture as a bracket (P1.9).

Called by whoever performs the gesture — the Community key handler for copy, the enterprise editing layer for cut/paste/fill — so the events fire once per gesture regardless of which door it came through, exactly like the undo/redo bracket. …Start always has a matching …End, even when the gesture turned out to do nothing: a listener that pauses its own cellValueChanged handling between them must never be left paused.

Parameters

kind

"cut" | "fill" | "paste" | "copy"

cellCount

number

run

() => boolean

Returns

boolean


notifyEditingStarted()

notifyEditingStarted(info): void

Publish an editor opening. Called by the adapter.

Parameters

info
columnId

string

rowKey

RowKey

value

unknown

Returns

void


notifyEditingStopped()

notifyEditingStopped(info): void

Publish an editor closing. Called by the adapter.

Parameters

info
cancelled

boolean

columnId

string

rowKey

RowKey

value

unknown

Returns

void


notifyHistoryEnded()

notifyHistoryEnded(kind, info): void

Publish the close of the bracket, after the replayed cell changes.

Parameters

kind

"undo" | "redo"

info
label

string | null

performed

boolean

Returns

void


notifyHistoryStarted()

notifyHistoryStarted(kind, label): void

Publish the opening of an undo/redo bracket. Called by the adapter.

Parameters

kind

"undo" | "redo"

label

string | null

Returns

void


notifyRow()

notifyRow(name, node, rowIndex): void

Publish a row interaction. Called by the adapter, not by applications.

Parameters

name

"rowClicked" | "rowDoubleClicked"

node

RowNode<TRow>

rowIndex

number

Returns

void


notifyRowDrag()

notifyRowDrag(kind, info): void

rowDragEnter / rowDragMove / rowDragLeave.

Parameters

kind

"enter" | "move" | "leave"

info
fromGridId?

string

overKey?

RowKey | null

position?

"before" | "after" | null

rowKey

RowKey

Returns

void


notifyRowDragEnd()

notifyRowDragEnd(info): void

rowDragEnd — fires for EVERY drag that ends, dropped or abandoned.

Parameters

info
dropped

boolean

fromGridId?

string

overKey?

RowKey | null

position?

"before" | "after" | null

rowKey

RowKey

Returns

void


notifyRowEditingStarted()

notifyRowEditingStarted(info): void

Publish a whole row opening (row / form / popup modes).

Parameters

info
isNew

boolean

rowKey

RowKey

Returns

void


notifyRowEditingStopped()

notifyRowEditingStopped(info): void

Publish the open row closing.

Parameters

info
cancelled

boolean

isNew

boolean

rowKey

RowKey

Returns

void


notifyViewStateChanged()

notifyViewStateChanged(): void

Something the saved view carries changed without going through the store (footer aggregations, folded bands, server group expansion, an Enterprise part). stateUpdated is the one event a persisting layer listens to, so it fires here too — before 2026-10-09 these changes reached storage only if something else happened to save after them.

Returns

void


parseCellFromEdit()

parseCellFromEdit(columnId, value): unknown

What an edit writes: a formula with its typed A1 references stored by row key, or — in a formula column of numbers — a typed number as a number.

Parameters

columnId

string

value

unknown

Returns

unknown


pastedCellValue()

pastedCellValue(rowKey, columnId, text, value): unknown

The value one pasted cell writes, through processCellFromClipboard.

Parameters

rowKey

RowKey

columnId

string

text

string

value

unknown

Returns

unknown


pinRow()

pinRow(key, side): boolean

Pin a row to the top or bottom band, or unpin it with null. Works with rowPinning off too (the option is the MENU); isRowPinnable still holds. A row pinned again moves to the end of its band. Returns whether anything changed.

Parameters

key

RowKey

side

PinnedRowSide | null

Returns

boolean


planGroupEdit()

planGroupEdit(groupKey, columnId, target, valueOf, writable): object[] | null

The new row values that make a group's subtotal under columnId equal target — the column's groupEdit method or function over the group's rows. valueOf reads a row's current value (a pending edit included) and writable says whether the user may change it; the caller writes the answer through its editing engine as one step. Null when the subtotal is not editable or no row can take the change.

Parameters

groupKey

string

columnId

string

target

number

valueOf

(rowKey) => unknown

writable

(rowKey) => boolean

Returns

object[] | null


planRowColSpans()

planRowColSpans(node, window): ColSpanPlan<TRow> | null

How a data row's cells span columns (G-CORE-03) — what both renderers draw. window is the rendered range of the scrolling block, or null for the whole row. Null when nothing in the row spans.

Parameters

node

DataRowNode<TRow>

window

{ end: number; start: number; } | null

Returns

ColSpanPlan<TRow> | null


previewFormula()

previewFormula(formula, rows?): { dataType: GridDataType; ok: true; values: FormulaValue[]; } | { error: FormulaCompileError; ok: false; }

Compile a formula against this grid's columns and run it on the first rows of the current view — the dialog's live preview. Community: it changes nothing.

Parameters

formula

string

rows?

number

Returns

{ dataType: GridDataType; ok: true; values: FormulaValue[]; } | { error: FormulaCompileError; ok: false; }


previousPage()

previousPage(): void

Returns

void


processPastedTable()

processPastedTable(table): string[][] | null

The pasted table through processDataFromClipboard; null = paste nothing.

Parameters

table

string[][]

Returns

string[][] | null


redo()

redo(): boolean

Redo the last undone action. Returns whether anything was redone.

Returns

boolean


refresh()

refresh(): Promise<void>

Force a pipeline pass (e.g. after mutating derived column definitions).

Returns

Promise<void>


refreshCells()

refreshCells(): void

Repaint what is on screen WITHOUT re-running the pipeline — for a valueGetter that reads something outside the row (a live price map, a permission that just changed) where the rows are the same but what they should show is not.

Deliberately NOT per-cell, unlike the refreshCells({rowNodes, columns}) shape some grids expose. That granularity exists when a grid keeps rendered cells around; this grid virtualizes, so only the window is mounted — "repaint everything visible" is about twenty rows. Targeting individual cells inside that would be ceremony with nothing to save, and an API whose cost story is a lie is worse than one method fewer.

Returns

void


refreshExternalFilter()

refreshExternalFilter(): void

Re-run the pipeline because what the predicate DEPENDS on moved, even though the predicate itself is the same function.

The common shape: the predicate reads a map's bounds, the user pans, and nothing about the grid has changed — so nothing would have recomputed.

Returns

void


refreshSummaries()

refreshSummaries(): void

Re-total without re-running the pipeline. Called after an edit, which changes values but neither the sort, the filter nor the row set.

Returns

void


registerViewStatePart()

registerViewStatePart(key, part): () => void

Keep a piece of state owned outside the core inside the saved view — the Enterprise chart panel keeps its chart this way, so getViewState, applyViewState and stateStoring carry it with no wiring of their own.

Order-independent on purpose. stateStoring restores while the grid is being created, BEFORE an Enterprise layer has mounted anything; a part restored before its owner registers is held and handed over on registration. Returns the unregister function.

Parameters

key

string

part

ViewStatePart

Returns

() => void


removeCalculatedColumn()

removeCalculatedColumn(id): void

Remove a runtime calculated column, and the sort, filter or grouping on it.

Parameters

id

string

Returns

void


resetColumnState()

resetColumnState(): void

Back to what the column definitions say: authored widths, pins, visibility and order. The counterpart of applyColumnStates for the "reset layout" button every state-persisting app ends up needing.

Returns

void


retryFailedLoads()

retryFailedLoads(): boolean

Ask the server again for every block that failed to load (the failed rows' Retry button calls this). Failed blocks are not re-requested on their own, so a server that is down is not hammered by every scroll; call this when it is back, from the button, a timer or an online listener. Returns false when nothing had failed.

Returns

boolean


revealMore()

revealMore(): boolean

Reveal the next chunk. Called automatically as the user nears the end; public so an app can drive it from its own "Load more" button.

Returns

boolean


revealRow()

revealRow(rowKey, maxPublications?): void

Bring a row into view once it EXISTS.

scrollToRow is a no-op for a key the view does not hold, which is right for a genuinely unknown row and wrong for one that is on its way. Adding a row goes: transaction → recompute → (worker round trip) → publish, so a caller that scrolled on the next macrotask was racing the pipeline. It won at 500 rows and lost at a million — the row was appended far below the viewport, indexOf returned -1, the scroll was dropped, and the user saw the button do nothing.

So: scroll now if it is there, otherwise wait for the publication that brings it. Bounded, because a key that never arrives (a filter excludes it) must not leave a listener attached for the life of the grid.

Parameters

rowKey

RowKey

maxPublications?

number

Returns

void


scrollToCell()

scrollToCell(rowKey, columnId): void

Bring a CELL into view — both axes. Tabbing along a row walks off the right edge of the window, and an editor opened on a column that is not rendered has nothing to attach to.

Parameters

rowKey

RowKey

columnId

string

Returns

void


scrollToRow()

scrollToRow(rowKey): void

Parameters

rowKey

RowKey

Returns

void


searchDistinctValues()

searchDistinctValues(columnId, needle, limit?): object

Distinct values whose label CONTAINS needle, scanned over the whole source rather than over the truncated list.

Without this, searching a truncated list can only ever find what was already loaded: on a million-row id column, typing "999999" matched nothing, because the value exists in the data but not in the first 1000 distinct values. Deliberately uncached — the needle changes on every keystroke, and caching per needle would grow without bound.

Parameters

columnId

string

needle

string

limit?

number

Returns

object

entries

entries: object[]

truncated

truncated: boolean


selectAll()

selectAll(): void

With selection.deferred on this records ONE boolean instead of building a key set — the difference between instant and a stall at a million rows.

Returns

void


selectRow()

selectRow(key): void

Parameters

key

RowKey

Returns

void


setAnimateRows()

setAnimateRows(on): void

Parameters

on

boolean

Returns

void


setBandCollapsed()

setBandCollapsed(path, collapsed): void

Fold or unfold a band. path is the band's caption path, outermost first.

Parameters

path

string | readonly string[]

collapsed

boolean

Returns

void


setChromeOffsets()

setChromeOffsets(header, footer): void

Heights of the sticky blocks inside the scroller — the header stack (bands

  • header + filter row) above the rows, and the totals row below them — so scrolling to a row can account for the space they cover.

Parameters

number

number

Returns

void


setClipboardHooks()

setClipboardHooks(hooks): void

The application's clipboard callbacks — what a copy writes, what a paste reads, where the text goes. Enterprise; set by the Enterprise grids' clipboard option. null removes them.

Parameters

hooks

GridClipboardHooks<TRow> | null

Returns

void


setColumnFilter()

setColumnFilter(columnId, node, part?): void

Set (or clear, with null) a single column's filter — the UI entry point.

part lets two surfaces filter ONE column at the same time (gap analysis P3.7): the filter row writes FILTER_PART_ROW, the header popup writes FILTER_PART_SET, and the two are ANDed. Omit it to replace whatever the column had, which is what a programmatic caller means.

Parameters

columnId

string

node

FilterNode | null

part?

string

Returns

void


setColumnHeaderName()

setColumnHeaderName(id, name): void

Rename a column in the grid (G-CORE-06). Enterprise. An empty name — or null — goes back to the name the definition gives. The new name is part of the column state, so a saved layout keeps it; formulas keep resolving [Name] against the authored names, so a rename breaks none of them.

Parameters

id

string

name

string | null

Returns

void


setColumnPinned()

setColumnPinned(id, pinned): void

Parameters

id

string

pinned

ColumnPin

Returns

void


setColumns()

setColumns(columns): void

Replace the column set (adapters call this when the columns prop changes).

Parameters

columns

GridColumnDef<TRow>[]

Returns

void


setColumnSummary()

setColumnSummary(columnId, type): void

Set (or clear, with null) the aggregation for ONE column — what the footer's right-click menu drives.

Replaces any existing definitions for that column: a footer cell shows one number, so two definitions on the same column would mean the second was computed and never displayed.

When group headers do NOT carry aggregates this takes the cheap path and re-reduces the rows already in hand instead of re-running sort + filter, which the user would feel as a stall on a large grid.

Parameters

columnId

string

type

SummaryType | null

Returns

void


setColumnVisible()

setColumnVisible(id, visible): void

Parameters

id

string

visible

boolean

Returns

void


setColumnWidth()

setColumnWidth(id, width, finished?): void

finished separates a drag in progress from its end: the header resize handle reports every pointer move as false and the release as true, so a layout-persisting listener saves once, not once per pixel. Programmatic calls are one-shot and default to true.

Parameters

id

string

width

number

finished?

boolean

Returns

void


setData()

setData(rows): void

Parameters

rows

TRow[]

Returns

void


setEditFormRow()

setEditFormRow(rowKey, options?): void

Open the edit form among the rows, or close it with null.

height is the form's measured (or configured) pixel height, used as given: the form is one tall row, not a run of row slots.

Parameters

rowKey

RowKey | null

options?
atTop?

boolean

height?

number

Returns

void


setEditingDelegate()

setEditingDelegate(delegate): void

Same arrangement as setHistoryDelegate: the editing engine lives in the enterprise adapter, which registers this while an editable grid is mounted. Without a delegate the methods answer honestly — nothing opened, nothing stopped, nothing being edited.

Parameters

delegate

{ getEditingCells: object[]; startEditingCell: boolean; stopEditing: Promise<boolean>; } | null

Returns

void


setEnterpriseEdition()

setEnterpriseEdition(on): void

Which edition is driving this controller. Set by the React adapter from the flag EnterpriseDataGrid passes; Community never turns it on.

The engine keeps the capability either way — the pipeline is one piece and an edition boundary that tried to cut through it would be a fork, not a gate. What the flag decides is what the controller AGREES to do.

Parameters

on

boolean

Returns

void


setExportDefaults()

Call Signature

setExportDefaults(defaults): void

Options merged UNDER every export call of one format — explicit arguments still win. Each call REPLACES that format's defaults.

controller.setExportDefaults('csv', { delimiter: ';' }); controller.setExportDefaults('pdf', { font: { family: 'Noto', normal: ttf } });

The toolbar and menu export buttons call the export methods with no arguments, so this is how their output is configured.

The one-argument form is the original, Excel-only signature, kept working unchanged.

Parameters
defaults

Partial<ExcelExportOptions>

Returns

void

Call Signature

setExportDefaults(format, defaults): void

Options merged UNDER every export call of one format — explicit arguments still win. Each call REPLACES that format's defaults.

controller.setExportDefaults('csv', { delimiter: ';' }); controller.setExportDefaults('pdf', { font: { family: 'Noto', normal: ttf } });

The toolbar and menu export buttons call the export methods with no arguments, so this is how their output is configured.

The one-argument form is the original, Excel-only signature, kept working unchanged.

Parameters
format

"csv"

defaults

Partial<CsvExportOptions>

Returns

void

Call Signature

setExportDefaults(format, defaults): void

Options merged UNDER every export call of one format — explicit arguments still win. Each call REPLACES that format's defaults.

controller.setExportDefaults('csv', { delimiter: ';' }); controller.setExportDefaults('pdf', { font: { family: 'Noto', normal: ttf } });

The toolbar and menu export buttons call the export methods with no arguments, so this is how their output is configured.

The one-argument form is the original, Excel-only signature, kept working unchanged.

Parameters
format

"excel"

defaults

Partial<ExcelExportOptions>

Returns

void

Call Signature

setExportDefaults(format, defaults): void

Options merged UNDER every export call of one format — explicit arguments still win. Each call REPLACES that format's defaults.

controller.setExportDefaults('csv', { delimiter: ';' }); controller.setExportDefaults('pdf', { font: { family: 'Noto', normal: ttf } });

The toolbar and menu export buttons call the export methods with no arguments, so this is how their output is configured.

The one-argument form is the original, Excel-only signature, kept working unchanged.

Parameters
format

"pdf"

defaults

Partial<PdfExportOptions>

Returns

void


setExternalFilter()

setExternalFilter(predicate): void

Set (or clear, with null) the application's own row test. ANDed with the column filters and the search — it narrows, it never widens.

Costs the worker: a function cannot cross postMessage, so a grid with one set filters and sorts on the main thread whatever the row count, exactly as a custom comparator does. Prefer setFilter for anything the filter AST can already say.

The predicate is called during the pass, so it must be PURE and fast — and when what it closes over changes, call this again (or refreshExternalFilter()); the grid cannot see a change it has no handle on.

Parameters

predicate

((row) => boolean) | null

Returns

void


setFilter()

setFilter(filter): void

Parameters

filter

FilterNode | null

Returns

void


setFilterEnabled()

setFilterEnabled(enabled): void

Apply or suspend the filter, keeping every condition.

The filter panel's checkbox. Separate from clearing on purpose: "show me everything for a moment" and "throw away what I built" are different intentions, and a user who has to rebuild three conditions to peek at the unfiltered data will simply not peek.

Parameters

enabled

boolean

Returns

void


setFindText()

setFindText(text): void

Search for text, or stop with an empty string. The first match at or after the focused cell becomes current and is scrolled into view; focus itself does not move, so typing in a find box keeps typing there.

Parameters

text

string

Returns

void


setGroupSelected()

setGroupSelected(groupKey, selected): void

Select (or, with false, deselect) every row under a group. Multiple selection only.

Parameters

groupKey

string

selected

boolean

Returns

void


setGroupSummaries()

setGroupSummaries(enabled): void

Turn per-group aggregates on or off at runtime (the header menu's "group footers"). They are attached during grouping, so the view has to be rebuilt — hence the recompute rather than a repaint.

Parameters

enabled

boolean

Returns

void


setHistoryDelegate()

setHistoryDelegate(delegate): void

Let an editing layer answer undo/redo for the controller.

Same arrangement as setPendingValueReader: the editing engine is built by the enterprise adapter and core never sees it, so the controller cannot reach the history directly. The adapter registers this while an editable grid is mounted and clears it on unmount. Without a delegate — Community build, editing off, unlicensed — the methods below answer honestly: nothing to undo, nothing done.

Parameters

delegate

{ canRedo: boolean; canUndo: boolean; depth: { redo: number; undo: number; }; redo: boolean; undo: boolean; } | null

Returns

void


setLeadWidth()

setLeadWidth(px): void

Width of the leading expander/checkbox columns — the INLINE counterpart to setChromeOffsets. They are the adapter's, so it has to report them.

Parameters

px

number

Returns

void


setMaxCanvasHeight()

setMaxCanvasHeight(px): boolean

Companion to setMaxScrollOffset: the tallest element this browser lays out.

Parameters

px

number

Returns

boolean


setMaxScrollOffset()

setMaxScrollOffset(px): boolean

Tell the engine the largest scroll offset this browser honours, once an adapter has measured it.

Only matters past a few hundred thousand rows, where the scroll position of the last row exceeds what the browser will accept and everything below it becomes unreachable. See DEFAULT_MAX_SCROLL_OFFSET.

Parameters

px

number

Returns

boolean


setMeasuredRowHeights()

setMeasuredRowHeights(heights): boolean

Heights the ADAPTER measured, by row key — autoHeight columns.

By key rather than index because a measurement outlives the sort that produced it; by the adapter rather than here because only it knows how the text wrapped at this column width in this font.

Parameters

heights

ReadonlyMap<RowKey, number>

Returns

boolean

whether the geometry moved, so the caller can skip a re-render.


setPage()

setPage(page): void

Parameters

page

number

Returns

void


setPageSize()

setPageSize(pageSize): void

Parameters

pageSize

number

Returns

void


setPaginationEnabled()

setPaginationEnabled(enabled): void

Switch between paged and continuous virtual scrolling at runtime.

Parameters

enabled

boolean

Returns

void


setPendingValueReader()

setPendingValueReader(readers): void

Let an editing layer supply pending cell values to the footer.

Without this the totals read the STORED rows, so in batch mode a user could change every number in a column and watch the sum sit still — a total that contradicts the cells above it is worse than no total. Registered by useGridEditing; null while nothing is editing, which is also the fast path (no per-cell indirection).

Parameters

readers

Pick<SummaryOptions<TRow>, "effectiveValue" | "effectiveRow"> & object | null

Pick<SummaryOptions<TRow>, "effectiveValue" | "effectiveRow"> & object


null

Returns

void


setPostSort()

setPostSort(hook): void

Replace (or remove, with null) the sorting.postSort hook and re-sort. Call it again, or refresh(), when what the hook reads has changed.

Parameters

hook

PostSortHook<TRow> | null

Returns

void


setRowHeight()

setRowHeight(rowHeight): void

Change the fixed row height at runtime (density presets). Goes through the window engine because every offset, the scroll height and the visible range are computed from it — setting a CSS variable alone would leave the virtualizer positioning rows on the old grid.

Parameters

rowHeight

number

Returns

void


setRowPinning()

setRowPinning(option): void

Turn the menu entries on or off, or change isRowPinnable. Rows already pinned stay pinned: the option governs what the MENU offers.

Parameters

option

boolean | RowPinningOptions<TRow> | undefined

Returns

void


setRowSelectable()

setRowSelectable(rule): void

Replace (or remove, with null) the selection.isRowSelectable rule — or pass the same one again to make the grid re-ask, when what it reads has changed without the data changing. Rows the rule now refuses are deselected, and the visible checkboxes repaint.

Parameters

rule

((row) => boolean) | null

Returns

void


setScroll()

setScroll(scrollTop, scrollLeft): boolean

Hot path — call on every scroll event. Returns true only when the QUANTIZED window moved, so adapters can skip state updates for sub-row scrolling.

Parameters

scrollTop

number

scrollLeft

number

Returns

boolean


setSearchText()

setSearchText(searchText): void

Parameters

searchText

string

Returns

void


setSelectedKeys()

setSelectedKeys(keys): void

Parameters

keys

readonly RowKey[]

Returns

void


setSelectionMode()

setSelectionMode(mode): void

Parameters

mode

SelectionMode

Returns

void


setSort()

setSort(sort): void

Parameters

sort

SortDescriptor[]

Returns

void


setSummaryDefs()

setSummaryDefs(defs): void

Parameters

defs

SummaryDef<TRow>[]

Returns

void


setViewportSize()

setViewportSize(width, height): boolean

Parameters

width

number

height

number

Returns

boolean


shiftCellFormula()

shiftCellFormula(columnId, value, rows, columns): unknown

A formula copied rows down and columns right on screen — the fill handle's step. Relative references move, $ parts stay.

Parameters

columnId

string

value

unknown

rows

number

columns

number

Returns

unknown


showLoadingOverlay()

showLoadingOverlay(): void

Show the busy overlay until hideOverlay(), whatever the grid is doing.

Returns

void


showNoRowsOverlay()

showNoRowsOverlay(): void

Show the empty-result message, whatever the row count says.

Returns

void


sizeColumnsToFit()

sizeColumnsToFit(options?): void

Spread the visible columns across the grid's width so they exactly fill it (gap analysis P2.5) — the answer to a grid that leaves a stripe of empty canvas on a wide screen, or overflows on a narrow one.

PROPORTIONAL to the widths already in place, not equal: a column configured at 300 was made wide for a reason, and dividing the space evenly would throw that away every time the window resized.

minWidth / maxWidth are honoured, which is what makes this iterative: a column that hits its limit stops absorbing space, and the remainder has to go to the columns that can still take it. The loop is bounded by the column count — each pass either freezes at least one column or finishes.

Publishes ONE columnStateChanged and no columnResized: this is a bulk operation, and replaying it as a resize gesture per column would tell a listener the user dragged twelve handles.

Parameters

options?
skip?

readonly string[]

width?

number

Returns

void


startEditingCell()

startEditingCell(rowKey, columnId): boolean

Open the editor on a cell, scrolled into view first — the same path a double-click takes, so an editor can never open somewhere the user cannot see. False when the cell refused (not editable, unknown, or a whole-row session is already open — row modes edit rows, not loose cells).

Parameters

rowKey

RowKey

columnId

string

Returns

boolean


stopEditing()

stopEditing(options?): Promise<boolean>

Close whatever is being edited: commits (or with cancel: true, discards) the open cell editor OR the open row session. A promise because a row commit persists through the app's async save; a cell commit resolves immediately. False when validation refused the commit or nothing was open.

Parameters

options?
cancel?

boolean

Returns

Promise<boolean>


toggleBand()

toggleBand(path): void

Parameters

path

string | readonly string[]

Returns

void


toggleDetail()

toggleDetail(rowKey): void

Parameters

rowKey

RowKey

Returns

void


toggleGroup()

toggleGroup(groupKey): void

Parameters

groupKey

string

Returns

void


toggleGroupSelection()

toggleGroupSelection(groupKey): void

The header checkbox: a fully selected group is cleared, anything else is filled.

Parameters

groupKey

string

Returns

void


toggleRow()

toggleRow(key): void

Parameters

key

RowKey

Returns

void


toggleSort()

toggleSort(columnId, additive?): void

Parameters

columnId

string

additive?

boolean

Returns

void


toggleTreeRow()

toggleTreeRow(key): void

Parameters

key

RowKey

Returns

void


undo()

undo(): boolean

Undo the last edit action (one action = one gesture: a whole paste, not one cell of it). Returns whether anything was undone. Publishes undoStarted / undoEnded around the replayed cellValueChanged events — the same bracket Ctrl+Z produces, because both routes run the same engine method.

Returns

boolean


updateCalculatedColumn()

updateCalculatedColumn(id, patch): void

Change a runtime calculated column's name, formula or type.

Parameters

id

string

patch

Partial<Omit<CalculatedColumnSpec, "id">>

Returns

void


writeClipboard()

writeClipboard(text, kind?): boolean

Write copied text: to sendToClipboard when the app took that over, else to the system clipboard. False when there is nothing to write or nowhere to write it. The platform's refusal (an unfocused page, a withheld permission) is swallowed — the gesture event already said what happened.

Parameters

text

string

kind?

"cut" | "copy"

Returns

boolean