Skip to main content

Grid options

These are the primary options shared by the core, React props, and Angular inputs. Optional fields use documented defaults when omitted.

Data and identity

OptionTypePurpose
columnDefsColDef[]Column and column-group definitions
rowIdKeystringField containing a stable row ID
getRowId(row) => stringDerive a stable row ID
rowDataModeauto | reset | diffWhether a replacement rowData array is diffed into the grid (keeping history and page) or re-ingested. Default auto
asyncTransactionWaitMsnumberBatch window for applyTransactionAsync; defaults to 16 ms. 0 flushes on the next macrotask
rowModelTypeclientSide | serverSideSelect the row model
serverSideDataSourceIServerSideDataSourceLazy data-source contract
serverSideBlockSizenumberRequested block size

React and Angular expose rowData through their bindings; core integrations use api.setRowData().

Layout and columns

OptionTypeDefault
rowHeightnumberTheme/default row height
headerHeightnumberTheme/default header height
overscanRowCountnumberViewport-derived default
rowNumbersbooleanfalse
defaultColDefDefaultColDef{}
minResizeWidthnumber75
maxColumnWidthnumber420
columnPanelboolean | ColumnPanelOptionsfalse

Interaction

OptionTypeDefault
cellSelectionboolean | "text"true (false/"text" also disable the body keyboard cursor — navigation, clipboard, and editing keys)
rangeSelectionbooleantrue
columnSelectionbooleantrue
headerKeyboardNavigationbooleantrue (false makes header sort/menu/selection mouse-only)
rowSelectionboolean | RowSelectionOptionsfalse (object form configures mode and the checkbox column)
selectAllScope"filtered" | "page""filtered" (select-all and areAllRowsSelected span the whole filtered set)
selectionPersistence"clear" | "keep""clear" (row selection on filter/sort/quick-filter changes)
selectAllRowsOnHeaderClickbooleanfalse
clearSelectionOnBodyClickbooleantrue
highlightActiveCellbooleanfalse
bodyContextMenuboolean | gettertrue
rowInsertionMenuRowInsertionMenuOptionsNot set; opt-in Insert submenu on client-side row numbers

RowSelectionOptions accepts mode: "single" | "multiple" (default "multiple"), checkboxes, and headerCheckbox. Single mode always hides the header checkbox. Checkbox-column placement uses two independent options: checkboxColumnPinned: "left" | "right" | null chooses its initial position (default "left"), while checkboxColumnPinnable controls whether users can change that position later (default true). These nested row-selection options reconcile live in both React and Angular; changing them does not remount the grid or replace its API instance.

Editing

OptionTypeDefault
editTriggerdoubleClick | singleClick | nonedoubleClick
suppressKeyboardEditbooleanfalse
suppressTypeToEditbooleanfalse
moveAfterEditbooleantrue
commitOnBlurbooleantrue
reevaluateOnEditbooleantrue
undoLimitnumber100

Sort, filter, and pagination

OptionTypePurpose
initialSort{ colId, dir }[]Ordered initial client-side sort
showSortPrioritymulti | always | neverPriority badge behavior
quickFilterboolean | QuickFilterOptionsGlobal client-side search
filterDebounceMsnumberDefault column-filter debounce
paginationbooleanEnable footer pagination
paginationControlsPaginationControlsOptionsPage-picker style plus visible pagination controls and their order
pageSizenumberInitial page size
pageSizesnumber[]User-selectable page sizes
resetPageOn("filter" | "sort" | "quickFilter")[]Model changes that jump back to page 1 (default [])

pageSizes is normalized at init (sorted ascending, non-positive entries dropped). If pageSize is not in the list it is added automatically so the page-size selector can display it — with a console warning when pageSizes was set explicitly.

The page picker remains a <select> by default. Use numbered buttons and configure the footer controls by supplying their visual (and keyboard) order:

paginationControls: {
pageSelection: "buttons",
showPageLabel: false,
controls: ["previousPage", "pageSelector", "nextPage", "pageSize"],
maxPageButtons: 7,
}

Available controls are "pageSize", "firstPage", "previousPage", "pageSelector", "nextPage", and "lastPage". Omitted controls are hidden. Set showPageLabel: false to remove the visible Page label while preserving accessible names on the select or numbered-button group. Numbered pagination keeps the first and last known pages visible, centers a bounded window around the current page, and inserts ellipses when pages are skipped.

The footer adapts to its own width, on the same ladder the toolbar uses — see Narrow bars. Its rungs, cheapest first: the text beside each control ("Rows per page", "Aggregate", "Page") is hidden; the first and last page buttons go, since the page picker beside them already reaches any page; rows-per-page moves into the footer's overflow menu; then the aggregate scope; then the sheet strip's +. Page navigation itself never gives way — a footer that cannot page is not a footer — so a footer still short of room scrolls instead. Trimming controls is how an application spends that width on something else — a wide sheet-tab strip, for instance.

paginationControls: { responsive: "collapse" } // "collapse" (default) | "scroll" | false
Behavior change

Filter and quick-filter changes used to reset pagination to page 1 (and sort changes never did). The default is now resetPageOn: []no model change resets the page. The grid keeps the user's current page; when the change shrinks the row count past it, it clamps to the last page instead of showing an empty view. Add "filter", "quickFilter", and/or "sort" to restore the jump-to-page-1 behavior for that trigger — the policy is now symmetric and per-trigger. (On the server-side row model the page snaps back once the total row count is known; the quick filter is client-side only.)

Grouping and hierarchy

OptionTypePurpose
groupDisplayTypesingleColumn | multipleColumns | groupRowsLabel layout
groupDefaultExpandednumberInitial expanded depth; -1 means all
groupSortModelocal | hierarchy | globalClient-side group ordering
groupRowsSelectablebooleanInclude generated groups in selection
groupRowsStickybooleanDock the active ancestor chain
treeDataTreeDataOptionsEnable path, parent, or children hierarchy
pivotModebooleanStart in pivot mode (client-side; exclusive with tree data). Live in both wrappers — a prop/input change toggles the mode
pivotColumnsstring[]Columns to pivot on, by colId, in level order. Live in both wrappers
pivotResultColumnDefPartial<ColDef>Overlay for every generated pivot value column
maxPivotColumnsnumberCap on generated pivot columns (default 200; truncates + fires pivotColumnLimitReached). A target, not an exact ceiling — truncation is per pivot value, so the count can land under or over it
pivotColumnMoveMode"measures" | "free"What dragging a generated pivot column does: reorder the measures everywhere (default) or arrange leaves freely, splitting groups (updatable at runtime)

Presentation and integration

OptionTypePurpose
themeGridThemePer-instance visual theme
iconsGridIconMapNamed icon overrides
tooltipboolean | TooltipOptionsGlobal tooltip behavior
getRowPresentation(params) => RowPresentationRow/cell styling defaults, tooltip defaults, editability, ARIA description/busy state, and metadata
toolbarGridToolbarOptionsOpt-in toolbar sections, plus responsive (see Narrow bars)
savedViewsSavedViewsOptionsApplication-owned view persistence
sheetsSheetsOptionsSpreadsheet-style footer tabs (Data + pivot sheets over one row model); application-owned list
suppressStyleInjectionbooleanUse imported CSS instead
styleNoncestringCSP nonce for injected styles
loadingMessagestringLoading overlay copy
noRowsMessagestringEmpty-data copy
pivotNoValuesMessagestringCopy of the header hint shown while pivot mode has no aggregates

Narrow bars

Both bars — the toolbar above the header and the footer below the body — cope with a width their controls do not fit by the same rule: nothing is ever clipped, overlapped, or compressed. Every control is laid out at its natural size in one of its presentation stages, or it moves into that bar's overflow menu (); a bar that runs out of stages scrolls, so nothing becomes unreachable.

The toolbar's rungs, cheapest first:

  1. every button caption at once — the tooltip on each button carries the label it lost;
  2. the quick-filter input narrows — a field you can still read and type in costs less than the name of a column you grouped by;
  3. Grouped by / Sort by chips fold from the end into a +N chip, one at a time;
  4. each chip section becomes a summary button (Grouped by 3) that opens the same drag-reorder editor as a popover — and stays a drop target for a column dragged out of the header;
  5. Export, Pivot, Views, then the two chip sections move into the ;
  6. the quick filter becomes a search icon that expands the box back over the bar in place;
  7. Columns last, because the column panel is the escape hatch to everything else.

Two rules keep that honest. A control that holds focus, or that carries state the user is relying on (a quick filter with a query), is not displaced — the next rung goes instead — so nothing collapses out from under someone mid-use. And when something is displaced, its state does not vanish quietly: the wears a dot while anything inside it is active, and focus follows a displaced control to the button that now holds it.

A settled bar has no hole in it. The last rung applied usually frees more room than was needed, and rather than leaving that as blank space in the middle of the bar, one control takes it: the search field, which stretches into it (up to a limit), or — with no quick filter configured — the last chip section, which widens its drop zone instead.

The order is fixed. An application that wants a different one configures fewer controls rather than re-ordering the ladder; every ordering is a degradation path that has to hold up at every width. What is configurable is whether the ladder runs at all:

toolbar: { grouping: true, sorting: true, quickFilter: true, responsive: "collapse" }

"collapse" (the default) walks the ladder above. "scroll" leaves every control at full size and scrolls the bar as soon as they do not fit — simplest to reason about, at the cost of controls sitting off-screen. false lays the bar out and lets it clip, for an application that guarantees its own width. paginationControls.responsive says the same for the footer.

The package's TypeScript declarations remain the source of truth for less common callbacks and detailed nested option types.

Row presentation

Use getRowPresentation when a status belongs to the whole row rather than a particular field:

getRowPresentation: ({ rowId }) => {
const error = errors.get(rowId);
if (!error) return undefined;
return {
rowClass: "row-error",
cellClass: "cell-in-error-row",
cellStyle: { backgroundColor: "var(--error-row-bg)" },
editable: false,
tooltip: {
content: error.message,
component: ErrorTooltip,
componentParams: { showCode: true },
options: { mode: "follow", escapeRootClip: true },
},
accessibility: {
description: `Row contains an error: ${error.message}`,
busy: false,
},
metadata: { status: "error", error },
};
}

rowClass/rowStyle style every row-container fragment and compose with the older getRowClass/getRowStyle hooks. cellClass is combined with each column's cellClass; cellStyle is the default object and the column wins only conflicting properties. The resolved presentation is also available to cell renderers, cell-style callbacks, and tooltip components as rowPresentation.

editable: false prevents user editing throughout the row. It is a veto: the row cannot make a column editable unless that column is already editable, and a column with editable: false remains non-editable. For a deliberate exception, set inheritRowPresentation.editable: false on that column. Programmatic writes through setCellValue and setCellValues are not blocked by UI editability.

Tooltip layers resolve by specificity:

  • Content: explicit column getter/field → row content → defaultColDef → clipped-cell text.
  • Component: explicit column component → row component → defaultColDef → built-in text.
  • Options, field by field: grid → defaultColDef → row → explicit column.

This lets a column replace its message or placement while retaining the row's component and other behavior. interactive: true always forces anchored mode; placement is relevant only while anchored. A column can opt out selectively:

{
key: "actions",
label: "Actions",
inheritRowPresentation: {
tooltip: false,
cellClass: false,
cellStyle: false,
editable: false,
},
}

When the callback reads external state (a pending-ID set, for example), call api.refreshRowPresentation() after changing it. Row transactions already repaint affected rendered rows. React and Angular row tooltip components use the framework-aware ReactGetRowPresentation and NgGetRowPresentation types.