GridConfig<T>

The GridConfig<T> interface controls every aspect of grid behaviour. Pass an instance to the [config] input of <gridcraft>. All properties are optional — the grid works with an empty object {}.

import { GridConfig } from '@gridcraft/angular';

// T is your row data type — inferred from your columns or data source
const config: GridConfig<MyRow> = {
  // All properties are optional; the grid has safe defaults for everything
};

Scrolling & pagination

PropertyTypeDefaultDescription
scrollModeScrollMode'infinite' Controls how rows are loaded. 'infinite' appends rows as the user scrolls. 'paging' replaces the current page on navigation (shows a pagination bar at the bottom).
scrollbarsGcScrollbarMode'grid' Who draws the scrollbars. 'grid' keeps them inside the body area, between the header and the footer, and styles them from the --gc-scrollbar-* theme variables. 'native' hands them back to the browser, which draws them alongside the header and footer as well. Scrolling itself is the browser's either way — wheel, trackpad, touch and keyboard are untouched. Touch devices always get the platform's own scrollbars.
pageSizenumber50Number of rows fetched per request. Also the page size in paging modes.
pageSizeOptionsnumber[][] Options shown in the pagination bar's page-size dropdown (e.g. [10, 25, 50, 100]). Only relevant in 'paging' mode. When empty or omitted, the dropdown is hidden.
scrollThresholdnumber150Distance in px from the bottom of the scroll container that triggers the next infinite-scroll fetch.

Layout

PropertyTypeDefaultDescription
rowHeightnumber48Fixed row height in px. Used by the virtual scroll engine for offset calculations.
headerHeightnumber48Header row height in px.
heightnumber | string'100%' CSS height of the grid container. Use a px number, any CSS string (e.g. '600px', '50vh'), or 'auto' to expand the grid to fit its content. The sticky group header overlay and inner-scroll grouping only work in fixed-height mode.
autoRowHeightbooleanfalse Let each data row grow taller than rowHeight to fit its own content — wrapped text, multi-line chips, tall cell templates. rowHeight then acts as the minimum, and as the estimate for rows still off screen. This is not the same as height: 'auto', which grows the whole grid so every row fits with no inner scrolling; autoRowHeight varies individual row heights inside the normal virtual-scrolling viewport. Group and tree filler rows stay at rowHeight. Not supported with scrollMode: 'virtual-paging', whose page maths assumes uniform rows.
fullWidthRows(row, index) => boolean— Return true for rows that should render one projected component (#gcFullWidthRow) spanning the whole grid width instead of the usual column cells — info banners, embedded content, a callout between data rows.
cellSpanningbooleanauto The explicit off-switch for merged cells. Spanning turns itself on as soon as any column declares colSpan, rowSpan or autoMerge; set this to false to force it off without removing those column callbacks. Not supported with scrollMode: 'virtual-paging' or the Kanban view.

Column features

PropertyTypeDefaultDescription
columnReorderbooleanfalseEnable HTML5 drag-drop column reorder globally. Individual columns also need draggable: true.
columnResizebooleanfalseEnable drag resize handles globally. Individual columns also need resizable: true.
autoSizeStrategySizeColumnsToFitGridStrategy | SizeColumnsToFitProvidedWidthStrategy | SizeColumnsToFitCellContentsStrategy— Automatic column sizing on startup and container resize. Three strategies:
  • { type: 'fitGridWidth' } — fills the grid container exactly with no horizontal scroll. Re-runs automatically on container resize and column show/hide. Columns with suppressSizeToFit: true are excluded. Manually dragged columns lock their width and opt out of future auto-fits.
  • { type: 'fitProvidedWidth', width: N } — fills a specific pixel width. Does not auto-trigger; call grid.sizeColumnsToFit(strategy) imperatively.
  • { type: 'fitCellContents' } — sizes each column to its cell contents (header + data). Triggers once after the first data load. Call grid.autoSizeColumns() to trigger imperatively. Set scaleUpToFitGridWidth: true to also fill remaining space after content sizing.
All three strategies support defaultMinWidth and per-column columnLimits overrides.
persistColumnsColumnPersistConfig— Persist column state (order, width, visibility, pin) across page loads. Modes: 'none', 'local-storage', 'session-storage', 'server'.
alignGroupstring— Links this grid's column layout to every other grid carrying the same name. Width, order, pin and hidden state stay identical across the group and the grids scroll horizontally together, so stacked grids read as one table. Rows, sorting, filtering and selection stay independent. Grids with different columns align on the shared ones only. See Aligned Grids.
inferDataTypesbooleantrue Work out each column's data type from the data when the column declares none. Inference reads at most 20 non-blank values per column, once — when the grid first has rows, and again only if the column definitions change. It never re-runs on a data change, so a column's behaviour cannot shift under the reader; a column whose sampled values disagree stays 'text' rather than being guessed at. Set false to turn the sampling off grid-wide. An explicit column.dataType is not inference and still applies — use dataType: false to opt out one column.
autoGenerateColumnsboolean | AutoGenerateColumns— Derive the column definitions from the data's shape — one column per scalar key, typed through the same engine inferDataTypes uses. Omitted, generation happens only when no columns are bound at all; true generates alongside supplied columns, filling in the keys they do not cover; false never generates, even with no columns bound. A supplied definition merges field by field over the generated one, so a column stating only a width keeps the generated header and type. Generated columns are sortable and resizable and never editable; keys holding objects, arrays or functions are skipped rather than printed as [object Object]. Generation runs once, when the grid first has rows, and then holds still — call GridcraftComponent.regenerateColumns() to re-derive. Pass an object for sampleSize (default 20), exclude and headerFrom. See Columns from Data.
tooltipboolean | GridTooltipConfigtrue The master switch for cell and header tooltips. Omitted or true gives the styled floating tooltip — themed, keyboard-accessible, and never clipped by the grid's own scrolling. false turns tooltips off entirely. An object customises the delay, placement and width, or opts into the browser's native title. Per-column tooltip, headerTooltip and tooltipTemplate still decide the content.
keyboardNavbooleantrue Keyboard cell navigation and the focused-cell model. On by default: Arrow, Tab, Home, End, Ctrl+Home/End and PgUp/PgDn move a focused cell, Enter opens the inline editor, Space toggles row selection. false disables it completely — no tabindex bindings and no key handling.

Theming

PropertyTypeDefaultDescription
themeGridTheme'default' Active theme name. Built-in values: 'default', 'material', 'dark'. Pass any other string to activate a custom theme class (.gc-theme-{name}).
iconsPartial<GridIconSet>—Replaces the grid's state icons — empty, error and retry — with your own SVG strings. Any key you omit keeps the shipped icon. See Custom Icons.
messagesPartial<GridMessages>— Override default UI text — around sixty keys covering the overlays, the pager, the editors and the screen-reader announcements. The ones a grid meets first are empty, error, retry, noColumns and allLoaded. Twelve languages ship with the library as GRID_MESSAGES — see Localisation.

Row behaviour

PropertyTypeDefaultDescription
trackBykeyof T | (index, row) => any— Row identity used by virtual scroll and row selection. A string key (e.g. 'id') reads row[key]; a function is called directly. Defaults to object reference identity when omitted.
rowClassstring | (row, index) => string | Record<string, boolean>—Apply extra CSS classes to data rows. The function form receives the row and its index.
initialSortsSortConfig[][]Default sort applied on the very first fetch. Array of { key: string; dir: 'asc' | 'desc' }.
sortMode'server' | 'client''server''server' (default) — forwards active sorts to fetchRows() so your backend handles ordering. 'client' — sorts loaded rows in memory without triggering a refetch. Use 'client' for in-memory datasets (static data, editable grids). In client mode, params.sorts is always [], so fetchRows() does not need to implement sorting.
rowSelectionRowSelectionConfig—Enable row selection. See RowSelectionConfig below. Omit entirely to disable selection.
dir'ltr' | 'rtl''ltr' Layout direction for this grid. 'rtl' flips columns right-to-left, moves the scrollbar to the left, and right-aligns cell text automatically. Overrides GridDirectionService for this specific instance.
multiSortMode'modifier' | 'click''modifier' How a header click builds the sort. 'modifier' is the conventional behaviour: a plain click sorts by that column alone, clearing the others, and you hold Shift / Ctrl / Cmd (or press Shift+Enter on a focused header) to add a column to a multi-column sort. 'click' makes every plain click accumulate instead, appending to the existing sort — opt into it only to preserve the older behaviour.
animateRowsbooleantrue A brief enter transition on content revealed by an expand/collapse toggle — rows under a group header or tree node, and the panel opened by rowExpand. Collapse is always instant. Respects prefers-reduced-motion.
rowStyleCellStyle | (row, index) => CellStyle— Inline style for every data row, either static or computed per row. Symmetric with rowClass.
rowClickCursorbooleanfalse Show a pointer cursor on data rows. Set it when you bind (rowClick), so the rows look as clickable as they are.

Filtering

PropertyTypeDefaultDescription
filterModeFilterMode—'row' renders an inline filter row below the header. 'popup' shows per-column filter popups opened via a filter icon. Omit to disable filtering entirely.
filterLabelsGridFilterLabels—Override display labels for filter operators and placeholder text.
quickFilterboolean | QuickFilterConfigoff One search box in the toolbar that filters rows across all columns at once. It searches the formatted on-screen value, so columns with a valueFormatter match what the reader can actually see, with no extra config. Multiple words are an AND of case-insensitive substrings. true takes the defaults; pass an object to customise. Client-side sources apply it in memory; server-side sources receive it as FetchParams.quickFilter. Tree data is not supported yet.
filterApplyMode'client' | 'server''server' Where filtering happens — the mirror of sortMode, and it covers all three kinds at once (quick, column and advanced). 'server' sends the filter values on FetchParams and your source returns filtered rows. 'client' filters the loaded rows in memory, so fetchRows gets empty filter params and should return the full set. Choose 'client' when you want live updates and inline edits re-filtered as they happen: a row edited out of the query disappears, one edited into it appears. 'client' needs scrollMode: 'infinite' — paging and virtual-paging fall back to server filtering with a one-time console warning.

Row expansion

PropertyTypeDefaultDescription
rowExpandRowExpandConfig<T>— Enable expandable rows. Provide a #gcExpandRow ng-template inside the grid element.

Export

PropertyTypeDefaultDescription
exportExportConfig— Show export buttons in the toolbar. Set formats to any combination of 'csv', 'excel', 'word'. Optionally provide filename (without extension) for the downloaded file.
printboolean | GridPrintConfigoff Print-friendly layout. true takes the defaults; an object customises them (see GridPrintConfig). Enables the native Ctrl+P response — every loaded row renders in the page flow instead of the scroll viewport, and the grid restores itself afterwards — and exposes GridcraftComponent.print(). Omitted or false leaves printing to the browser's default, which prints only what is on screen.

Sub-type: ColumnPersistConfig

A discriminated union — choose exactly one mode:

import { ColumnPersistConfig } from '@gridcraft/angular';

// Option 1 — localStorage (survives browser restart)
const persist: ColumnPersistConfig = {
  mode: 'local-storage',
  key: 'my-grid-columns',   // unique key per grid
};

// Option 2 — sessionStorage (cleared on tab close)
const persist: ColumnPersistConfig = {
  mode: 'session-storage',
  key: 'my-grid-columns',
};

// Option 3 — server-side (you provide load/save functions)
const persist: ColumnPersistConfig = {
  mode: 'server',
  save: (states) => this.http.put('/api/column-prefs', states).pipe(map(() => undefined)),
  load: ()       => this.http.get<ColumnState[]>('/api/column-prefs'),
};

// Option 4 — disable persistence explicitly
const persist: ColumnPersistConfig = { mode: 'none' };

Sub-type: RowSelectionConfig

PropertyTypeDefaultDescription
mode'single' | 'multi''multi''single' allows only one selected row at a time. 'multi' allows shift-click range selection and select-all.
checkboxColumnbooleantrueShow a dedicated checkbox column. Set to false to select by clicking the row only.
checkboxPosition'left' | 'right''left'Side on which the checkbox column appears.

Sub-type: RowExpandConfig<T>

PropertyTypeDefaultDescription
expandMode'single' | 'multi''multi''single' automatically collapses the previously open row when a new one expands.
estimatedHeightnumber200Estimated expand panel height in px before the content is measured by ResizeObserver. Used for virtual scroll offsets.
canExpand(row: T) => boolean—Return false to hide the expand toggle for specific rows.

Row drag-reorder

PropertyTypeDefaultDescription
rowDragRowDragConfig<T>— Add a drag-handle column so users can reorder rows by dragging. Emits (rowDragEnd) on drop. When rowDrag.managed: true the grid automatically reorders state.rows() after each drop — no need to handle the event. Set managed: false (default) to apply reorders yourself (e.g. persist to a server).

RowDragConfig properties

PropertyTypeDefaultDescription
managedbooleanfalseWhen true, reorders state.rows() automatically on drop. Best for in-memory datasets.
position'left' | 'right''left'Side on which the drag-handle column is placed.
handleWidthnumber32Width of the drag-handle column in px.
canDrag(row: T) => boolean—Return false to make a specific row non-draggable (no handle rendered).

Inline cell editing

PropertyTypeDefaultDescription
editTrigger'click' | 'dblclick''dblclick' Interaction that starts inline cell editing for columns with column.editable: true. 'dblclick' is the default — a single click still selects the row. 'click' immediately opens the editor on the first click.
editMode'cell' | 'fullRow''cell' What one edit gesture opens. 'cell' opens a single cell. 'fullRow' opens every editable cell of that row at once and commits them as one change: Enter from any of them writes the row, Escape discards all of it, and Tab moves between the row's own cells and wraps at the end rather than leaving a half-edited row. One row is one entry in the undo history, so a single Ctrl+Z takes it all back. Validation is atomic in the default editValidation: 'block' — one failing cell means nothing is written and the session stays open with the message. Needs trackBy. editTrigger still chooses click vs double-click, and single-cell editing stays available via startEditing(rowId, colKey). See Row Editing.
editValidation'block' | 'allow''block' What happens when a commit fails a column's validate rules. 'block' keeps the value out of your data — the editor stays open showing the message. 'allow' commits it and leaves the cell visibly marked invalid until a valid commit replaces it. Column rules work without setting this.
batchEditbooleanon with row selection Ctrl/Cmd+Enter while editing fills the value you just typed into every selected row, through the same validated commit path, as one undoable batch. Set false to turn off the in-editor shortcut; grid.applyToSelectedRows(colKey, value) still works either way.
undoRedoboolean | UndoRedoConfigfalse Widens undo/redo (Ctrl+Z / Ctrl+Y · Cmd+Z / Cmd+Shift+Z) beyond cell edits to sorting, filtering, column changes, grouping and row moves, on one ordered history — so Ctrl+Z walks back the user's actual sequence of actions. Cell-edit undo is not affected by this flag and works with or without it; this only widens what else the history records. Pass an object to cap the depth or restrict which operations are recorded.

Committed edits emit (cellEditCommit) with a CellEditEvent<T>. The grid maintains a per-session undo/redo history — Ctrl+Z / Ctrl+Y (or Cmd+Z / Cmd+Shift+Z) work automatically. See GridColumn.editable and GridColumn.editor in the GridColumn reference.

Full configuration example

import { GridConfig } from '@gridcraft/angular';

const config: GridConfig<Employee> = {
  // ── Scrolling ─────────────────────────────────────────────
  scrollMode:      'infinite',
  pageSize:        50,
  scrollThreshold: 150,

  // ── Layout ────────────────────────────────────────────────
  rowHeight:    48,
  headerHeight: 48,
  height:       600,          // px — fixed height enables grouping overlay

  // ── Columns ───────────────────────────────────────────────
  columnReorder:    true,
  columnResize:     true,
  columnVisibility: true,
  persistColumns: { mode: 'local-storage', key: 'emp-grid-v1' },

  // ── Theming ───────────────────────────────────────────────
  messages: {
    loading:   'Fetching employees…',
    empty:     'No employees found',
    allLoaded: 'All employees loaded',
  },

  // ── Row behaviour ─────────────────────────────────────────
  trackBy:      'id',
  rowClass:     (row) => row.isActive ? '' : 'row--inactive',
  initialSorts: [{ key: 'lastName', dir: 'asc' }],

  // ── Selection ─────────────────────────────────────────────
  rowSelection: {
    mode:             'multi',
    checkboxColumn:   true,
    checkboxPosition: 'left',
  },

  // ── Filtering ─────────────────────────────────────────────
  filterMode: 'row',

  // ── Grouping ──────────────────────────────────────────────
  grouping: {
    groupBy:        'department',
    label:          (v) => `Dept: ${v}`,
    showCount:      true,
    startCollapsed: true,
  },

  // ── Row expansion ─────────────────────────────────────────
  rowExpand: {
    expandMode:      'multi',
    estimatedHeight: 240,
    canExpand:       (row) => row.hasDetails,
  },

  // ── Export ────────────────────────────────────────────────
  export: {
    formats:  ['csv', 'excel', 'word'],
    filename: 'employees',
  },
};