DataGridProps
Props for the DataGrid component.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
rows | TRow[] | Row data to display |
gridConfig? | GridConfig<TRow> | Grid configuration. Supports React renderers/editors via reactRenderer and reactEditor properties. |
columns? | ColumnShorthand<TRow>[] | Column definitions. Supports shorthand syntax for quick definitions. |
columnDefaults? | Partial<ColumnConfig<TRow>> | Default column properties applied to all columns. Individual column definitions override these defaults. |
fitMode? | stretch | fit-columns | auto-fit | Fit mode for column sizing |
sortable? | boolean | Grid-wide sorting toggle. When false, disables sorting for all columns regardless of their individual sortable setting. When true (default), columns with sortable: true can be sorted. |
filterable? | boolean | Grid-wide filtering toggle. When false, disables filtering for all columns regardless of their individual filterable setting. When true (default), columns with filterable: true can be filtered. |
selectable? | boolean | Grid-wide selection toggle. When false, disables selection for all rows/cells. When true (default), selection is enabled based on plugin mode. |
loading? | boolean | Show a loading overlay on the grid. Use this during initial data fetch or refresh operations. |
customStyles? | string | Custom CSS styles to inject into the grid via document.adoptedStyleSheets |
className? | string | Class name for the grid element |
style? | CSSProperties | Inline styles for the grid element |
children? | ReactNode | Children (GridColumn components for custom renderers/editors) |
plugins? | BaseGridPlugin<unknown>[] | Escape hatch: manually provide plugin instances. When provided, feature props for those plugins are ignored. Useful for advanced configurations not covered by feature props. |
onRowsChange? | (rows: TRow[]) => void | Fired when rows change (sorting, editing, etc.) |
onCellClick? | EventHandler<CellClickDetail<TRow>> | Fired when a cell is clicked. |
onRowClick? | EventHandler<RowClickDetail<TRow>> | Fired when a row is clicked. |
onCellActivate? | EventHandler<CellActivateDetail<TRow>> | Fired when a cell is activated (Enter key or double-click). |
onCellChange? | EventHandler<CellChangeDetail<TRow>> | Fired when a cell value changes (before commit). |
onCellCommit? | EventHandler<CellCommitDetail<TRow>> | Fired when a cell edit is committed. Cancelable - call event.preventDefault() to reject the edit. |
onRowCommit? | EventHandler<RowCommitDetail<TRow>> | Fired when all pending row edits are committed. |
onChangedRowsReset? | EventHandler<ChangedRowsResetDetail<TRow>> | Fired when changed rows cache is reset via resetChangedRows(). |
onEditOpen? | EventHandler<EditOpenDetail<TRow>> | Fired when an editor opens for a cell. |
onBeforeEditClose? | EventHandler<BeforeEditCloseDetail<TRow>> | Fired before an editor closes (commit or cancel). Cancelable. |
onEditClose? | EventHandler<EditCloseDetail<TRow>> | Fired after an editor closes (commit or cancel). |
onCellCancel? | EventHandler<CellCancelDetail> | Fired when a cell edit is canceled (e.g. Escape key). |
onDirtyChange? | EventHandler<DirtyChangeDetail<TRow>> | Fired when the dirty/changed-rows state transitions. |
onDataChange? | EventHandler<DataChangeDetail> | Fired when the row data is replaced (e.g. via the data property setter). |
onSortChange? | EventHandler<SortChangeDetail> | Fired when sort state changes. |
onFilterChange? | EventHandler<FilterChangeDetail> | Fired when filter values change. |
onColumnResize? | EventHandler<ColumnResizeDetail> | Fired when a column is resized. |
onColumnMove? | EventHandler<ColumnMoveDetail> | Fired when a column is moved via drag-and-drop. Cancelable - call event.preventDefault() to cancel the move. |
onColumnResizeReset? | EventHandler<ColumnResizeResetDetail> | Fired when a column resize is reset (e.g. via double-click on the resize handle). |
onColumnVisibility? | EventHandler<ColumnVisibilityDetail> | Fired when a column is shown or hidden — either via the visibility sidebar, grid.toggleColumnVisibility(field), grid.setColumnVisible(field, visible), or grid.showAllColumns(). |
onColumnStateChange? | EventHandler<GridColumnState> | Fired when column state changes (resize, reorder, visibility). Useful for persisting column state. |
onSelectionChange? | EventHandler<SelectionChangeDetail> | Fired when selection changes. |
onRowMove? | EventHandler<RowMoveDetail<TRow>> | Fired when a row is moved via drag-and-drop. Cancelable - call event.preventDefault() to cancel the move. |
onRowDragStart? | EventHandler<RowDragStartDetail<TRow>> | Fired when a row drag starts. Cancelable. |
onRowDragEnd? | EventHandler<RowDragEndDetail<TRow>> | Fired when a row drag ends (after drop or cancel). |
onRowDrop? | EventHandler<RowDropDetail<TRow>> | Fired on the target grid when rows are dropped from another grid. Cancelable. |
onRowTransfer? | EventHandler<RowTransferDetail<TRow>> | Fired on BOTH source and target grids after a successful cross-grid row transfer. |
onGroupToggle? | EventHandler<GroupToggleDetail> | Fired when a group is expanded or collapsed. |
onGroupExpand? | EventHandler<GroupExpandDetail> | Fired when a group is expanded. |
onGroupCollapse? | EventHandler<GroupCollapseDetail> | Fired when a group is collapsed. |
onContextMenuOpen? | EventHandler<ContextMenuOpenDetail> | Fired when the context menu opens. |
onTreeExpand? | EventHandler<TreeExpandDetail<TRow>> | Fired when a tree node is expanded. |
onDetailExpand? | EventHandler<DetailExpandDetail> | Fired when a detail panel is expanded or collapsed. |
onResponsiveChange? | EventHandler<ResponsiveChangeDetail> | Fired when responsive mode changes (table ↔ card). |
onCopy? | EventHandler<CopyDetail> | Fired when cells are copied to clipboard. |
onPaste? | EventHandler<PasteDetail> | Fired when cells are pasted from clipboard. |
onUndo? | EventHandler<UndoRedoDetail> | Fired when an undo action is performed. |
onRedo? | EventHandler<UndoRedoDetail> | Fired when a redo action is performed. |
onExportComplete? | EventHandler<ExportCompleteDetail> | Fired when export completes. |
onPrintStart? | EventHandler<PrintStartDetail> | Fired when print starts. |
onPrintComplete? | EventHandler<PrintCompleteDetail> | Fired when print completes. |
onTbwScroll? | EventHandler<TbwScrollDetail> | Fired (rAF-batched) when the grid’s viewport scrolls vertically. |
onRender? | EventHandler<RenderDetail> | Fired once at the end of every render-scheduler flush, after all plugin afterRender hooks have run and ready() has resolved. |
selection? | cell | row | range | SelectionConfig<TRow> | Enable cell/row/range selection. |
editing? | boolean | click | dblclick | manual | EditingConfig | Enable inline cell editing. |
clipboard? | boolean | ClipboardConfig | Enable clipboard copy/paste. Requires selection to be enabled (will be auto-added). |
contextMenu? | boolean | ContextMenuConfig | Enable right-click context menu. |
multiSort? | boolean | multi | MultiSortConfig | single | Enable multi-column sorting. |
filtering? | boolean | FilterConfig<TRow> | Enable column filtering. |
reorderColumns? | boolean | ReorderConfig | Enable column drag-to-reorder. |
visibility? | boolean | VisibilityConfig | Enable column visibility toggle panel. |
pinnedColumns? | boolean | Enable pinned/sticky columns. Columns are pinned via the sticky column property. |
groupingColumns? | boolean | GroupingColumnsConfig | Enable multi-level column headers (column groups). |
columnVirtualization? | boolean | ColumnVirtualizationConfig | Enable horizontal column virtualization for wide grids. |
reorderRows? | boolean | RowReorderConfig | ⚠️ Enable row drag-to-reorder. |
rowDragDrop? | boolean | RowDragDropConfig<TRow> | Enable row drag-and-drop, both within a single grid (reorder) and across grids that share a dropZone. |
groupingRows? | GroupingRowsConfig | Enable row grouping by field values. |
pinnedRows? | boolean | PinnedRowsConfig | Enable pinned rows (aggregation/status bar). |
stickyRows? | StickyRowsConfig | Pin selected data rows below the header as the user scrolls past them. |
tree? | boolean | TreeConfig | Enable hierarchical tree view. |
masterDetail? | MasterDetailConfig | Enable master-detail expandable rows. |
responsive? | boolean | ResponsivePluginConfig<TRow> | Enable responsive card layout for narrow viewports. |
undoRedo? | boolean | UndoRedoConfig | Enable undo/redo for cell edits. Requires editing to be enabled (will be auto-added). |
export? | boolean | ExportConfig | Enable CSV/JSON export functionality. |
print? | boolean | PrintConfig | Enable print functionality. |
pivot? | PivotConfig | Enable pivot table functionality. |
serverSide? | ServerSideConfig | Enable server-side data operations. |
tooltip? | boolean | TooltipConfig | Enable styled popover tooltips on overflowing cells and headers. |
shell? | boolean | ShellConfig | Enable the grid shell (header bar + collapsible tool panels). |
ssr? | boolean | ⚠️ Enable SSR mode - skips React-side plugin instantiation. |
Property Details
Section titled “Property Details”gridConfig
Section titled “gridConfig”gridConfig={{ columns: [ { field: 'status', reactRenderer: (ctx) => <StatusBadge value={ctx.value} />, reactEditor: (ctx) => <StatusEditor value={ctx.value} onCommit={ctx.commit} />, }, ],}}columns
Section titled “columns”// Shorthand strings (auto-generate headers from field names)columns={['id:number', 'name', 'email', 'salary:currency']}
// Mixed: shorthand + full configcolumns={['id:number', 'name', { field: 'status', editable: true }]}
// Full config objects (standard usage)columns={[{ field: 'id', type: 'number' }, { field: 'name' }]}columnDefaults
Section titled “columnDefaults”<DataGrid columnDefaults={{ sortable: true, resizable: true }} columns={[ { field: 'id', sortable: false }, // Override: not sortable { field: 'name' }, // Inherits: sortable, resizable ]}/>sortable
Section titled “sortable”Grid-wide sorting toggle.
When false, disables sorting for all columns regardless of their individual sortable setting.
When true (default), columns with sortable: true can be sorted.
For multi-column sorting, also add the multiSort prop.
Default: true
// Disable all sorting<DataGrid sortable={false} />
// Enable sorting with multi-sort<DataGrid sortable multiSort />filterable
Section titled “filterable”Grid-wide filtering toggle.
When false, disables filtering for all columns regardless of their individual filterable setting.
When true (default), columns with filterable: true can be filtered.
Requires the FilteringPlugin to be loaded (via filtering prop or feature import).
Default: true
// Disable all filtering<DataGrid filterable={false} filtering />
// Enable filtering (default)<DataGrid filterable filtering />selectable
Section titled “selectable”Grid-wide selection toggle. When false, disables selection for all rows/cells. When true (default), selection is enabled based on plugin mode.
Requires the SelectionPlugin to be loaded (via selection prop or feature import).
Default: true
// Disable all selection<DataGrid selectable={false} selection="range" />
// Enable selection (default)<DataGrid selectable selection="range" />loading
Section titled “loading”Show a loading overlay on the grid. Use this during initial data fetch or refresh operations.
For row/cell loading states, use the ref to access methods:
ref.element.setRowLoading(rowId, true/false)ref.element.setCellLoading(rowId, field, true/false)
Default: false
const [loading, setLoading] = useState(true);
useEffect(() => { fetchData().then(data => { setRows(data); setLoading(false); });}, []);
<DataGrid loading={loading} rows={rows} />plugins
Section titled “plugins”import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
<DataGrid plugins={[new SelectionPlugin({ mode: 'range', checkbox: true })]}/>onCellClick
Section titled “onCellClick”onCellClick={(detail) => console.log('Clicked:', detail.field, detail.value)}onRowClick
Section titled “onRowClick”onRowClick={(detail) => navigateTo(`/employees/${detail.row.id}`)}onCellActivate
Section titled “onCellActivate”onCellActivate={(detail) => openEditor(detail.field, detail.row)}onCellChange
Section titled “onCellChange”onCellChange={(detail) => validateChange(detail)}onCellCommit
Section titled “onCellCommit”onCellCommit={(detail, event) => { if (!isValid(detail.value)) { event?.preventDefault(); showError('Invalid value'); }}}onRowCommit
Section titled “onRowCommit”onRowCommit={(detail) => saveToServer(detail.row)}onChangedRowsReset
Section titled “onChangedRowsReset”onChangedRowsReset={(detail) => console.log('Reset:', detail.rows.length, 'rows cleared')}onSortChange
Section titled “onSortChange”onSortChange={(detail) => console.log('Sort:', detail.field, detail.direction)}onFilterChange
Section titled “onFilterChange”onFilterChange={(detail) => console.log('Filters:', detail.activeFilters)}onColumnResize
Section titled “onColumnResize”onColumnResize={(detail) => console.log('Resized:', detail.field, detail.width)}onColumnMove
Section titled “onColumnMove”onColumnMove={(detail, event) => { if (detail.column.field === 'id') { event?.preventDefault(); // Don't allow moving ID column }}}onColumnResizeReset
Section titled “onColumnResizeReset”onColumnResizeReset={(detail) => console.log('Reset width for:', detail.field)}onColumnVisibility
Section titled “onColumnVisibility”Fired when a column is shown or hidden — either via the visibility
sidebar, grid.toggleColumnVisibility(field), grid.setColumnVisible(field, visible),
or grid.showAllColumns().
field and visible are present for single-column toggles and
undefined for bulk operations (showAllColumns). visibleColumns
always lists the current set.
onColumnVisibility={(detail) => { console.log(detail.hidden ? 'Hidden:' : 'Shown:', detail.field); localStorage.setItem('visibleColumns', JSON.stringify(detail.visibleColumns));}}onColumnStateChange
Section titled “onColumnStateChange”onColumnStateChange={(state) => saveToLocalStorage('gridState', state)}onSelectionChange
Section titled “onSelectionChange”onSelectionChange={(detail) => { console.log('Selected ranges:', detail.ranges); console.log('Mode:', detail.mode);}}onRowMove
Section titled “onRowMove”onRowMove={(detail, event) => { if (!canMove(detail.row)) { event?.preventDefault(); }}}onGroupToggle
Section titled “onGroupToggle”onGroupToggle={(detail) => { console.log(detail.expanded ? 'Expanded' : 'Collapsed', detail.key);}}onTreeExpand
Section titled “onTreeExpand”onTreeExpand={(detail) => console.log('Expanded:', detail.row)}onDetailExpand
Section titled “onDetailExpand”onDetailExpand={(detail) => { if (detail.expanded) loadDetailData(detail.rowId);}}onResponsiveChange
Section titled “onResponsiveChange”onResponsiveChange={(detail) => { console.log('Mode:', detail.mode); // 'table' | 'card'}}onCopy
Section titled “onCopy”onCopy={(detail) => console.log('Copied:', detail.text)}onPaste
Section titled “onPaste”onPaste={(detail) => console.log('Pasted:', detail.affectedCells.length, 'cells')}onUndo
Section titled “onUndo”onUndo={(detail) => console.log('Undid:', detail.action.type, '- Can undo:', detail.canUndo)}onRedo
Section titled “onRedo”onRedo={(detail) => console.log('Redid:', detail.action.type, '- Can redo:', detail.canRedo)}onExportComplete
Section titled “onExportComplete”onExportComplete={(detail) => console.log('Exported:', detail.filename)}onPrintStart
Section titled “onPrintStart”onPrintStart={(detail) => console.log('Printing:', detail.rowCount, 'rows')}onPrintComplete
Section titled “onPrintComplete”onPrintComplete={() => console.log('Print complete')}onTbwScroll
Section titled “onTbwScroll”Fired (rAF-batched) when the grid’s viewport scrolls vertically.
For server-side pagination of large datasets prefer ServerSidePlugin
— this event is the lower-level primitive for custom load-more
triggers, deferring heavy cell content, dismissing overlays, etc.
onTbwScroll={(detail) => { if (detail.scrollTop + detail.clientHeight >= detail.scrollHeight - 200) { loadMore(); }}}onRender
Section titled “onRender”Fired once at the end of every render-scheduler flush, after all
plugin afterRender hooks have run and ready() has resolved.
Use this to act on the rendered DOM after a programmatic mutation
(e.g. focus the first input of a freshly added row in full-grid
edit mode) without setTimeout or double-requestAnimationFrame
hacks. Fires on every flush — including scroll-driven virtual-window
updates — so prefer subscribing once and unsubscribing (or gating on
detail.phase >= RenderPhase.ROWS) when you only care about a
specific mutation.
onRender={(detail) => { if (detail.initial) console.log('first render complete');}}selection
Section titled “selection”// Shorthand - just the mode<DataGrid selection="range" />
// Full config<DataGrid selection={{ mode: 'range', checkbox: true }} />editing
Section titled “editing”// Enable with default trigger (dblclick)<DataGrid editing />
// Specify trigger<DataGrid editing="click" /><DataGrid editing="dblclick" /><DataGrid editing="manual" />
// Full config with callbacks<DataGrid editing={{ editOn: 'dblclick', onBeforeEditClose: myCallback }} />clipboard
Section titled “clipboard”<DataGrid selection="range" clipboard />contextMenu
Section titled “contextMenu”<DataGrid contextMenu /><DataGrid contextMenu={{ items: customItems }} />multiSort
Section titled “multiSort”Enable multi-column sorting.
Multi-sort allows users to sort by multiple columns simultaneously.
For basic single-column sorting, columns with sortable: true work without this plugin.
Use the sortable prop to disable all sorting grid-wide.
// Enable multi-column sorting<DataGrid multiSort />
// Limit to single column (uses plugin but restricts to 1)<DataGrid multiSort="single" />
// Full config<DataGrid multiSort={{ maxSortColumns: 3 }} />filtering
Section titled “filtering”<DataGrid filtering /><DataGrid filtering={{ debounceMs: 200 }} />reorderColumns
Section titled “reorderColumns”<DataGrid reorderColumns />visibility
Section titled “visibility”<DataGrid visibility />pinnedColumns
Section titled “pinnedColumns”<DataGrid pinnedColumns columns={[ { field: 'id', pinned: 'left' }, { field: 'name' }, { field: 'actions', pinned: 'right' },]} />groupingColumns
Section titled “groupingColumns”<DataGrid groupingColumns={{ columnGroups: [ { header: 'Personal Info', children: ['firstName', 'lastName'] }, ],}} />columnVirtualization
Section titled “columnVirtualization”<DataGrid columnVirtualization />reorderRows
Section titled “reorderRows”<DataGrid reorderRows />rowDragDrop
Section titled “rowDragDrop”// Intra-grid reorder (parity with reorderRows)<DataGrid rowDragDrop />
// Cross-grid transfer<DataGrid rowDragDrop={{ dropZone: 'employees', operation: 'move' }} />groupingRows
Section titled “groupingRows”<DataGrid groupingRows={{ groupOn: (row) => [row.department, row.team], defaultExpanded: true,}} />To keep mouse-toggle behavior, either add the `group-toggle` class to aclickable element (the plugin delegates clicks via `closest('.group-toggle')`)or call `params.toggleExpand()` from your own handler.
```tsx<DataGrid groupingRows={{ groupOn: (row) => row.department, groupRowRenderer: (params) => ( <button type="button" className="group-toggle"> {params.expanded ? '▾' : '▸'} {params.value} ({params.rows.length}) </button> ),}} />---
#### pinnedRows
```tsx<DataGrid pinnedRows={{ bottom: [{ type: 'aggregation', aggregator: 'sum' }],}} /><DataGrid pinnedRows={{ slots: [ { id: 'add-row', position: 'bottom', render: () => <AddRowPanel /> }, ],}} />stickyRows
Section titled “stickyRows”// Field-name shorthand<DataGrid stickyRows={{ isSticky: 'isSection' }} />
// Predicate + stack mode<DataGrid stickyRows={{ isSticky: (row) => row.kind === 'section', mode: 'stack', maxStacked: 3,}} /><DataGrid tree={{ childrenField: 'children', defaultExpanded: true,}} />masterDetail
Section titled “masterDetail”<DataGrid masterDetail={{ renderer: (row) => <OrderDetails order={row} />,}} />responsive
Section titled “responsive”<DataGrid responsive={{ breakpoint: 768, cardRenderer: (row) => <EmployeeCard employee={row} />,}} />undoRedo
Section titled “undoRedo”<DataGrid editing="dblclick" undoRedo />export
Section titled “export”<DataGrid export /><DataGrid export={{ filename: 'data.csv' }} /><DataGrid print /><DataGrid pivot={{ rowFields: ['category'], columnFields: ['year'], valueField: 'sales',}} />serverSide
Section titled “serverSide”<DataGrid serverSide={{ dataSource: async (params) => fetchData(params),}} />tooltip
Section titled “tooltip”<DataGrid tooltip /><DataGrid tooltip={{ cell: false }} />Default: false