Grid Configurator
GridConfiguratorPlugin is exported from @revolist/revogrid-pro. Search columns, show or hide columns, reorder them, and configure row groups, summaries, and filters from one panel. Pro and Pivot use shared @revolist/ui controls; regular grids do not require the Pivot package or execute Pivot reports. Source records remain owned by the grid.
For the Pivot configurator, use Configurator and its external mounting recipe. The plugin on this page is the optional configurator for regular grids.
Set grid.gridConfigurator.miniMode to true to start with a compact rail. Select a rail button to expand the configurator and use Collapse to return to the rail. Set resizable: true in the same options to enable width resizing. Dragging below 200 px collapses the panel to its rail.
For supported signatures, see Grid Configurator API. Its ordinary-grid summary callbacks are separate from Pivot report input policies; installing this configurator does not select a Pivot aggregation or execution pin.
Try it
Section titled “Try it”Use Columns to show or hide Product, or open the Sales cog under Values and change sum to avg. Portugal starts with a sum of 30 and Spain with 80. Remove Country from Row Groups to see the original records without summaries.
Source code
import { defineCustomElements } from '@revolist/revogrid/loader';import { createConfiguratorAssistant } from '../ai-assistant/configurator';import { AiAssistantPlugin, GridConfiguratorPlugin } from '@revolist/revogrid-pro';
/** Mount an ordinary grid and its Pro configurator; return framework cleanup. */export function mountGridConfiguratorExample(host: HTMLElement) { defineCustomElements(); const grid = document.createElement('revo-grid'); grid.setAttribute('aria-label', 'Configurable sales grid'); grid.className = 'skip-style'; grid.style.cssText = 'display:block;width:100%;height:320px;min-width:0'; grid.hideAttribution = true; grid.theme = 'material'; grid.filter = true; grid.columns = [ { prop: 'country', name: 'Country', size: 140, filter: 'string' }, { prop: 'product', name: 'Product', size: 140, filter: 'string' }, { prop: 'sales', name: 'Sales', size: 100, filter: 'number' }, ]; grid.source = [ { country: 'Portugal', product: 'Notebook', sales: 10 }, { country: 'Portugal', product: 'Desk lamp', sales: 20 }, { country: 'Spain', product: 'Notebook', sales: 30 }, { country: 'Spain', product: 'Desk lamp', sales: 50 }, ]; grid.grouping = { props: ['country'], expandedAll: true }; grid.gridConfigurator = { width: '100%', height: 440, fields: [{ prop: 'sales', dataType: 'number' }], values: [{ prop: 'sales', aggregator: 'sum' }], }; grid.plugins = [GridConfiguratorPlugin, AiAssistantPlugin]; host.append(grid); let disposed = false; void (async () => { await customElements.whenDefined('revo-grid'); await grid.componentOnReady(); if (disposed) return; const section = await createConfiguratorAssistant(grid, [ { prompt: 'Read the sales rows', result: { kind: 'action', name: 'grid.read', input: { start: 0, limit: 10, fields: ['country', 'product', 'sales'] } } }, ], { gridActions: { readRows: true } }); if (!disposed) grid.gridConfigurator = { ...grid.gridConfigurator, sections: [section] }; })().catch(error => { if (!disposed) host.setAttribute('data-assistant-error', String(error)); }); return () => { disposed = true; grid.remove(); };}Attach to a grid
Section titled “Attach to a grid”import { GridConfiguratorPlugin } from '@revolist/revogrid-pro';import '@revolist/revogrid-pro/styles.css';
const grid = document.createElement('revo-grid');grid.columns = [ { prop: 'country', name: 'Country', filter: 'string' }, { prop: 'sales', name: 'Sales', filter: 'number' },];grid.source = [ { country: 'Portugal', sales: 10 }, { country: 'Portugal', sales: 20 },];grid.filter = true;grid.grouping = { props: [], expandedAll: true };grid.gridConfigurator = { fields: [{ prop: 'sales', dataType: 'number' }], values: [{ prop: 'sales', aggregator: 'sum' }],};grid.plugins = [GridConfiguratorPlugin];document.querySelector('#grid-host')!.append(grid);The default mount inserts a panel immediately before the grid. The application
owns the surrounding layout; for a sidebar, place the grid in a flex or grid
container. The plugin installs or reuses ColumnHidePlugin and
AdvanceFilterPlugin.
The Columns tree controls source-column visibility and order. Existing nested header groups can be expanded, searched, hidden, and reordered using the same parent and pin-section restrictions as the column dialog. It does not create or edit header groups. There is no Pivot column-axis destination.
Drag a column’s grip to reorder it with RowOrderPlugin’s preview and insertion
indicator. Drag its name to assign it to Row Groups, Values, or Filters.
Row Groups, Values, and Filters are independent roles. Adding a field to one role does not hide its source column or remove another role. Checkboxes only control visibility. Hidden fields retain their configuration.
Mount externally
Section titled “Mount externally”Wait until the connected grid has initialized, then pass a connected host in the same document:
import { defineGridConfigurator } from '@revolist/revogrid-pro';
grid.gridConfigurator = { mountTo: false };await grid.componentOnReady();const panel = await defineGridConfigurator( document.querySelector<HTMLElement>('#sidebar')!, grid, { fields: [{ prop: 'sales', dataType: 'number' }] },);
// Unmount this surface. The adapter and grid configuration remain installed.panel.destroy();defineGridConfigurator reuses the installed GridConfiguratorPlugin, or
installs one with no attached panel. Mounting again moves its single surface;
older cleanup handles cannot remove a newer mount. The external host itself is
never removed.
To release subscriptions and restore the owned group-cell rendering hook, remove the plugin through the grid’s plugin lifecycle. Destroying the adapter preserves visibility, grouping, filters, and any rendering callback installed afterward.
Aggregations and filters
Section titled “Aggregations and filters”Each source column has at most one selected aggregation. Explicit numeric
metadata defaults to sum; other or unknown fields default to count. Supply
fields[].aggregators to restrict a field’s available functions,
fields[].defaultAggregator to override its default, or configure shared
aggregators and defaultAggregator options. Functions receive the field values
of matching leaf records, using the existing Pro aggregator semantics.
Values appear beneath their source columns in synthetic group rows. With no row groups, the selections remain configured but no summary or grand total appears. Filtered-out records do not contribute. Collapsed descendants still contribute, and scrolling does not change the results. Calculations are cached outside cell rendering and refreshed after relevant data, edit, filter, or grouping changes.
Filters open the normal column filter editor. Panel and header filters share the
same canonical state. Removing a filter clears that column’s conditions while
preserving unrelated predicates and quick filtering. Columns explicitly marked
filter: false cannot be added as filters.
This integration summarizes locally loaded records. It does not coordinate server-side grouping, remote aggregates, or complete-dataset totals for partial data.
Options and updates
Section titled “Options and updates”GridConfiguratorConfig exposes fields, values, filters, aggregators,
defaultAggregator, areas, mountTo, theme, and width. areas defaults to
['rows', 'values', 'filters']; hiding a destination does not clear its settings.
theme can override the panel’s automatic grid-theme synchronization.
Existing grid columns, hidden-column state, grouping, and filters are
authoritative. Listen to gridconfiguratorchange for snapshots containing
columns, rows, values, filters, and activeFilters.
Use the installed plugin’s getState() to inspect accepted settings and
updateConfig(config) to replace configurator options. Other public methods
include mount, setVisible, reorderColumn, addField, removeField,
reorderField, setAggregator, and openFilter. Keep runtime aggregator
functions separate when persisting application settings.
Display settings, undo/redo, saved views, and runtime switching between ordinary Grid and Pivot execution are outside this integration.
Continue learning
Section titled “Continue learning”Explore the interface · Configurator options · Custom controls.
Custom sections and AI
Section titled “Custom sections and AI”Add named tabs with sections. Each section has a stable id, a label, optional hidden/disabled flags, and either render() for Preact content or mount(host) for other frameworks. A mount callback can return cleanup. Built-in IDs are reserved; duplicate IDs are ignored. initialSection chooses the initial enabled tab and onSectionChange observes user navigation.
import type { ConfiguratorSection } from '@revolist/revogrid-pro';
const help: ConfiguratorSection = { id: 'help', label: 'Help', mount(host) { const text = document.createElement('p'); text.textContent = 'Choose fields in Layout, or ask the assistant in AI.'; host.append(text); return () => text.remove(); },};
grid.gridConfigurator = { ...grid.gridConfigurator, sections: [help], initialSection: 'layout',};Custom sections mount on their first visit and stay mounted while another tab is active, preserving drafts and chat transcripts. Hiding or removing a section, disposing the configurator, or replacing its mount callback releases that content. Callbacks are runtime UI configuration, not persisted report content.
The AI tab in the live example uses the existing assistant plugin and chat UI with a local scripted interpreter. Try Read the sales rows; no model backend is contacted.
For an application, register AiAssistantPlugin alongside your grid plugins and configure its interpreter and allowed actions as described in the AI Assistant guide. Set mountTo: false to use only the configurator surface, then create its section from the initialized plugin:
import { AiAssistantPlugin, createAiConfiguratorSection,} from '@revolist/revogrid-pro';
// Keep your existing interpreter, actions and other assistant settings.// Set grid.aiAssistant.mountTo to false before getting the plugin.const assistant = (await grid.getPlugins()).find( (plugin): plugin is AiAssistantPlugin => plugin instanceof AiAssistantPlugin,)!;const ai = createAiConfiguratorSection(assistant, { label: 'AI' });
grid.gridConfigurator = { ...grid.gridConfigurator, sections: [ai, help] };The same section contract works in Pivot and Pivot Charts:
| Configurator | Custom section configuration |
|---|---|
| Pro Grid | grid.gridConfigurator = { ...grid.gridConfigurator, sections: [ai] } |
| Pivot | pivot.updatePivotConfig({ ...config, configurator: { sections: [ai] } }) |
| Standalone Pivot component | PivotConfigurator / definePivotConfigurator accept sections in their component props / actions |
| Pivot Charts | grid.pivotChartsUi = { ...grid.pivotChartsUi, sections: [ai] } |
createAiConfiguratorSection defaults to id: 'ai', label AI, full-height chat mode, and hidden history controls. Set ui.showHistoryControls: true to opt into Restore/Reset, Clear chat and data history controls. It accepts section visibility/disabled settings and assistant ui options. Multiple surfaces share one assistant controller and its action permissions. Removing a section releases only its UI; destroying the plugin releases its mounted surfaces.