BaseGridPlugin
Abstract base class for all grid plugins.
Constructors
Section titled “Constructors”constructor
Section titled “constructor”new BaseGridPlugin(config: Partial<TConfig>)Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
dependencies? | PluginDependency[] | Plugin dependencies - declare other plugins this one requires. |
manifest? | PluginManifest<any> | Plugin manifest - declares owned properties, config rules, and hook priorities. |
name | string | Unique plugin identifier (derived from class name by default) |
aliases? | unknown | Alternative names for backward compatibility. getPluginByName() matches against both name and aliases. |
version | string | Plugin version - defaults to grid version for built-in plugins. Third-party plugins can override with their own semver. |
styles? | string | CSS styles to inject into the grid’s shadow DOM |
cellRenderers? | Record<string, CellRenderer> | Custom cell renderers keyed by type name |
headerRenderers? | Record<string, HeaderRenderer> | Custom header renderers keyed by type name |
cellEditors? | Record<string, CellEditor> | Custom cell editors keyed by type name |
grid | GridElement | The grid instance this plugin is attached to |
config | TConfig | Plugin configuration - merged with defaults in attach() |
userConfig | Partial<TConfig> | User-provided configuration from constructor |
Property Details
Section titled “Property Details”dependencies
Section titled “dependencies”Plugin dependencies - declare other plugins this one requires.
Dependencies are validated when the plugin is attached. Required dependencies throw an error if missing. Optional dependencies log an info message if missing.
static readonly dependencies: PluginDependency[] = [ { name: 'editing', required: true, reason: 'Tracks cell edits for undo/redo' }, { name: 'selection', required: false, reason: 'Enables selection-based undo' },];manifest
Section titled “manifest”Plugin manifest - declares owned properties, config rules, and hook priorities.
This is read by the configuration validator to:
- Validate that required plugins are loaded when their properties are used
- Execute configRules to detect invalid/conflicting settings
- Order hook execution based on priority
static override readonly manifest: PluginManifest<MyConfig> = { ownedProperties: [ { property: 'myProp', level: 'column', description: 'the "myProp" column property' }, ], configRules: [ { id: 'myPlugin/conflict', severity: 'warn', message: '...', check: (c) => c.a && c.b }, ],};Accessors
Section titled “Accessors”defaultConfig
Section titled “defaultConfig”Default configuration - subclasses should override this getter. Note: This must be a getter (not property initializer) for proper inheritance since property initializers run after parent constructor.
readonly defaultConfig: Partial<TConfig>Get the current rows from the grid.
readonly rows: any[]sourceRows
Section titled “sourceRows”Get the original unfiltered/unprocessed rows from the grid. Use this when you need all source data regardless of active filters.
readonly sourceRows: any[]columns
Section titled “columns”Get the current columns from the grid.
readonly columns: ColumnConfig<any>[]visibleColumns
Section titled “visibleColumns”Get only visible columns from the grid (excludes hidden). Use this for rendering that needs to match the grid template.
readonly visibleColumns: ColumnConfig<any>[]gridElement
Section titled “gridElement”Get the grid as an HTMLElement for direct DOM operations. Use sparingly - prefer the typed GridElementRef API when possible.
readonly gridElement: HTMLElementExample
Section titled “Example”const width = this.gridElement.clientWidth;this.gridElement.classList.add('my-plugin-active');disconnectSignal
Section titled “disconnectSignal”Get the disconnect signal for event listener cleanup. This signal is aborted when the grid disconnects from the DOM. Use this when adding event listeners that should be cleaned up automatically.
Best for:
- Document/window-level listeners added in attach()
- Listeners on the grid element itself
- Any listener that should persist across renders
Not needed for:
- Listeners on elements created in afterRender() (removed with element)
readonly disconnectSignal: AbortSignalExample
Section titled “Example”element.addEventListener('click', handler, { signal: this.disconnectSignal });document.addEventListener('keydown', handler, { signal: this.disconnectSignal });gridIcons
Section titled “gridIcons”Get the grid-level icons configuration. Returns merged icons (user config + defaults).
readonly gridIcons: Required<GridIcons>isAnimationEnabled
Section titled “isAnimationEnabled”Check if animations are enabled at the grid level. Respects gridConfig.animation.mode and the CSS variable set by the grid.
Plugins should use this to skip animations when:
- Animation mode is ‘off’ or
false - User prefers reduced motion and mode is ‘reduced-motion’ (default)
readonly isAnimationEnabled: booleanExample
Section titled “Example”private get animationStyle(): 'slide' | 'fade' | false { if (!this.isAnimationEnabled) return false; return this.config.animation ?? 'slide';}animationDuration
Section titled “animationDuration”Get the animation duration in milliseconds from CSS variable. Falls back to 200ms if not set.
Plugins can use this for their animation timing to stay consistent with the grid-level animation.duration setting.
readonly animationDuration: numberExample
Section titled “Example”element.animate(keyframes, { duration: this.animationDuration });Methods
Section titled “Methods”attach()
Section titled “attach()”Called when the plugin is attached to a grid. Override to set up event listeners, initialize state, etc.
attach(grid: GridElement): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
grid | GridElement |
Example
Section titled “Example”attach(grid: GridElement): void { super.attach(grid); // Set up document-level listeners with auto-cleanup document.addEventListener('keydown', this.handleEscape, { signal: this.disconnectSignal });}detach()
Section titled “detach()”Called when the plugin is detached from a grid. Override to clean up event listeners, timers, etc.
detach(): voidExample
Section titled “Example”detach(): void { // Clean up any state not handled by disconnectSignal this.selectedRows.clear(); this.cache = null;}onPluginAttached()
Section titled “onPluginAttached()”Called when another plugin is attached to the same grid. Use for inter-plugin coordination, e.g., to integrate with new plugins.
onPluginAttached(name: string, plugin: BaseGridPlugin): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
name | string | The name of the plugin that was attached |
plugin | BaseGridPlugin | The plugin instance (for direct access if needed) |
Example
Section titled “Example”onPluginAttached(name: string, plugin: BaseGridPlugin): void { if (name === 'selection') { // Integrate with selection plugin this.selectionPlugin = plugin as SelectionPlugin; }}onPluginDetached()
Section titled “onPluginDetached()”Called when another plugin is detached from the same grid. Use to clean up inter-plugin references.
onPluginDetached(name: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
name | string | The name of the plugin that was detached |
Example
Section titled “Example”onPluginDetached(name: string): void { if (name === 'selection') { this.selectionPlugin = undefined; }}getPlugin()
Section titled “getPlugin()”Get another plugin instance from the same grid. Use for inter-plugin communication.
Prefer grid.getPluginByName() when you don’t need the class import.
getPlugin(PluginClass: (args: any[]) => T): T | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
PluginClass | (args: any[]) => T |
Example
Section titled “Example”// Preferred: by nameconst selection = this.grid?.getPluginByName('selection');
// Alternative: by classconst selection = this.getPlugin(SelectionPlugin);if (selection) { const selectedRows = selection.getSelectedRows();}emit()
Section titled “emit()”Emit a custom event from the grid.
emit(eventName: string, detail: T): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
eventName | string | |
detail | T |
emitCancelable()
Section titled “emitCancelable()”Emit a cancelable custom event from the grid.
emitCancelable(eventName: string, detail: T): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
eventName | string | |
detail | T |
Returns
Section titled “Returns”boolean - true if the event was cancelled (preventDefault called), false otherwise
Subscribe to an event from another plugin. The subscription is automatically cleaned up when this plugin is detached.
on(eventType: string, callback: (detail: T) => void): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
eventType | string | The event type to listen for (e.g., ‘filter-change’) |
callback | (detail: T) => void | The callback to invoke when the event is emitted |
Example
Section titled “Example”// In attach() or other initializationthis.on('filter-change', (detail) => { console.log('Filter changed:', detail);});Unsubscribe from a plugin event.
off(eventType: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
eventType | string | The event type to stop listening for |
Example
Section titled “Example”this.off('filter-change');emitPluginEvent()
Section titled “emitPluginEvent()”Emit an event to other plugins via the Event Bus.
This is for inter-plugin communication only; it does NOT dispatch DOM events.
Use emit() to dispatch DOM events that external consumers can listen to.
emitPluginEvent(eventType: string, detail: T): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
eventType | string | The event type to emit (should be declared in manifest.events) |
detail | T | The event payload |
Example
Section titled “Example”// Emit to other plugins (not DOM)this.emitPluginEvent('filter-change', { field: 'name', value: 'Alice' });
// For DOM events that consumers can addEventListener to:this.emit('filter-change', { field: 'name', value: 'Alice' });requestRender()
Section titled “requestRender()”Request a re-render of the grid. Uses ROWS phase - does NOT trigger processColumns hooks.
requestRender(): voidrequestColumnsRender()
Section titled “requestColumnsRender()”Request a columns re-render of the grid. Uses COLUMNS phase - triggers processColumns hooks. Use this when your plugin needs to reprocess column configuration.
requestColumnsRender(): voidrequestRenderWithFocus()
Section titled “requestRenderWithFocus()”Request a re-render and restore focus styling afterward. Use this when a plugin action (like expand/collapse) triggers a render but needs to maintain keyboard navigation focus.
requestRenderWithFocus(): voidrequestAfterRender()
Section titled “requestAfterRender()”Request a lightweight style update without rebuilding DOM. Use this instead of requestRender() when only CSS classes need updating.
requestAfterRender(): voidrequestVirtualRefresh()
Section titled “requestVirtualRefresh()”Re-render visible rows without rebuilding the row model or recalculating geometry. Use this when row data has been updated in-place (e.g., server-side block loads) and only the visible viewport needs to re-render.
requestVirtualRefresh(): voidresolveIcon()
Section titled “resolveIcon()”Resolve an icon value to string or HTMLElement. Checks plugin config first, then grid-level icons, then defaults.
resolveIcon(iconKey: unknown, pluginOverride: IconValue): IconValueParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
iconKey | unknown | The icon key in GridIcons (e.g., ‘expand’, ‘collapse’) |
pluginOverride | IconValue | Optional plugin-level override |
Returns
Section titled “Returns”IconValue - The resolved icon value
setIcon()
Section titled “setIcon()”Set an icon value on an element. Handles both string (text/HTML) and HTMLElement values.
setIcon(element: HTMLElement, icon: IconValue): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
element | HTMLElement | The element to set the icon on |
icon | IconValue | The icon value (string or HTMLElement) |
warn()
Section titled “warn()”Log a warning with an optional diagnostic code.
When a diagnostic code is provided, the message is formatted with the code and a link to the troubleshooting docs.
warn(message: string): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
message | string |
Example
Section titled “Example”this.warn('Something went wrong'); // plainthis.warn(MISSING_BREAKPOINT, 'Set a breakpoint'); // with code + docs linkthrowDiagnostic()
Section titled “throwDiagnostic()”Throw an error with a diagnostic code and docs link. Use for configuration errors and API misuse that should halt execution.
throwDiagnostic(code: DiagnosticCode, message: string): neverParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
code | DiagnosticCode | |
message | string |
processRows()
Section titled “processRows()”Transform rows before rendering. Called during each render cycle before rows are rendered to the DOM. Use this to filter, sort, or add computed properties to rows.
processRows(rows: unknown): any[]Parameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rows | unknown | The current rows array (readonly to encourage returning a new array) |
Returns
Section titled “Returns”any[] - The modified rows array to render
Example
Section titled “Example”processRows(rows: readonly any[]): any[] { // Filter out hidden rows return rows.filter(row => !row._hidden);}processColumns()
Section titled “processColumns()”Transform columns before rendering. Called during each render cycle before column headers and cells are rendered. Use this to add, remove, or modify column definitions.
processColumns(columns: unknown): ColumnConfig<any>[]Parameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
columns | unknown | The current columns array (readonly to encourage returning a new array) |
Returns
Section titled “Returns”ColumnConfig<any>[] - The modified columns array to render
Example
Section titled “Example”processColumns(columns: readonly ColumnConfig[]): ColumnConfig[] { // Add a selection checkbox column return [ { field: '_select', header: '', width: 40 }, ...columns ];}beforeRender()
Section titled “beforeRender()”Called before each render cycle begins. Use this to prepare state or cache values needed during rendering.
Note: This hook is currently a placeholder for future implementation. It is defined in the interface but not yet invoked by the grid’s render pipeline. If you need this functionality, please open an issue or contribute an implementation.
beforeRender(): voidExample
Section titled “Example”beforeRender(): void { this.visibleRowCount = this.calculateVisibleRows();}afterRender()
Section titled “afterRender()”Called after each render cycle completes. Use this for DOM manipulation, adding event listeners to rendered elements, or applying visual effects like selection highlights.
afterRender(): voidExample
Section titled “Example”afterRender(): void { // Apply selection styling to rendered rows const rows = this.gridElement?.querySelectorAll('.data-row'); rows?.forEach((row, i) => { row.classList.toggle('selected', this.selectedRows.has(i)); });}afterCellRender()
Section titled “afterCellRender()”Called after each cell is rendered.
This hook is more efficient than afterRender() for cell-level modifications
because you receive the cell context directly - no DOM queries needed.
Use cases:
- Adding selection/highlight classes to specific cells
- Injecting badges or decorations
- Applying conditional styling based on cell value
Performance note: Called for every visible cell during render. Keep implementation fast. This hook is also called during scroll when cells are recycled.
afterCellRender(context: AfterCellRenderContext): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
context | AfterCellRenderContext | The cell render context with row, column, value, and elements |
Example
Section titled “Example”afterCellRender(context: AfterCellRenderContext): void { // Add selection class without DOM queries if (this.isSelected(context.rowIndex, context.colIndex)) { context.cellElement.classList.add('selected'); }
// Add validation error styling if (this.hasError(context.row, context.column.field)) { context.cellElement.classList.add('has-error'); }}afterRowRender()
Section titled “afterRowRender()”Called after a row is fully rendered (all cells complete). Use this for row-level decorations, styling, or ARIA attributes.
Common use cases:
- Adding selection classes to entire rows (row-focus, selected)
- Setting row-level ARIA attributes
- Applying row validation highlighting
- Tree indentation styling
Performance note: Called for every visible row during render. Keep implementation fast. This hook is also called during scroll when rows are recycled.
afterRowRender(context: AfterRowRenderContext): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
context | AfterRowRenderContext | The row render context with row data and element |
Example
Section titled “Example”afterRowRender(context: AfterRowRenderContext): void { // Add row selection class without DOM queries if (this.isRowSelected(context.rowIndex)) { context.rowElement.classList.add('selected', 'row-focus'); }
// Add validation error styling if (this.rowHasErrors(context.row)) { context.rowElement.classList.add('has-errors'); }}onScrollRender()
Section titled “onScrollRender()”Called after scroll-triggered row rendering completes. This is a lightweight hook for applying visual state to recycled DOM elements. Use this instead of afterRender when you need to reapply styling during scroll.
Performance note: This is called frequently during scroll. Keep implementation fast.
onScrollRender(): voidExample
Section titled “Example”onScrollRender(): void { // Reapply selection state to visible cells this.applySelectionToVisibleCells();}getExtraHeight()
Section titled “getExtraHeight()”⚠️ Deprecated: Use getRowHeight instead. This hook will be removed in v2.0. The new
getRowHeight(row, index)hook provides per-row height information which enables better position caching and variable row height support.
Return extra height contributed by this plugin (e.g., expanded detail rows). Used to adjust scrollbar height calculations for virtualization.
getExtraHeight(): numberReturns
Section titled “Returns”number - Total extra height in pixels
Example
Section titled “Example”// OLD (deprecated):getExtraHeight(): number { return this.expandedRows.size * this.detailHeight;}
// NEW (preferred):getRowHeight(row: unknown, index: number): number | undefined { if (this.isExpanded(row)) { return this.baseRowHeight + this.getDetailHeight(row); } return undefined;}getExtraHeightBefore()
Section titled “getExtraHeightBefore()”⚠️ Deprecated: Use getRowHeight instead. This hook will be removed in v2.0. The new
getRowHeight(row, index)hook provides per-row height information which enables better position caching and variable row height support.
Return extra height that appears before a given row index. Used by virtualization to correctly calculate scroll positions when there’s variable height content (like expanded detail rows) above the viewport.
getExtraHeightBefore(beforeRowIndex: number): numberParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
beforeRowIndex | number | The row index to calculate extra height before |
Returns
Section titled “Returns”number - Extra height in pixels that appears before this row
Example
Section titled “Example”// OLD (deprecated):getExtraHeightBefore(beforeRowIndex: number): number { let height = 0; for (const expandedRowIndex of this.expandedRowIndices) { if (expandedRowIndex < beforeRowIndex) { height += this.getDetailHeight(expandedRowIndex); } } return height;}
// NEW (preferred):getRowHeight(row: unknown, index: number): number | undefined { if (this.isExpanded(row)) { return this.baseRowHeight + this.getDetailHeight(row); } return undefined;}getRowHeight()
Section titled “getRowHeight()”Get the height of a specific row. Used for synthetic rows (group headers, detail panels, etc.) that have fixed heights. Return undefined if this plugin does not manage the height for this row.
This hook is called during position cache rebuilds for variable row height virtualization. Plugins that create synthetic rows should implement this to provide accurate heights.
getRowHeight(row: unknown, index: number): number | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
row | unknown | The row data |
index | number | The row index in the processed rows array |
Returns
Section titled “Returns”number | undefined - The row height in pixels, or undefined if not managed by this plugin
Example
Section titled “Example”getRowHeight(row: unknown, index: number): number | undefined { // Group headers have a fixed height if (this.isGroupHeader(row)) { return 32; } return undefined; // Let grid use default/measured height}adjustVirtualStart()
Section titled “adjustVirtualStart()”Adjust the virtualization start index to render additional rows before the visible range. Use this when expanded content (like detail rows) needs its parent row to remain rendered even when the parent row itself has scrolled above the viewport.
adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): numberParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
start | number | The calculated start row index |
scrollTop | number | The current scroll position |
rowHeight | number | The height of a single row |
Returns
Section titled “Returns”number - The adjusted start index (lower than or equal to original start)
Example
Section titled “Example”adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): number { // If row 5 is expanded and scrolled partially, keep it rendered for (const expandedRowIndex of this.expandedRowIndices) { const expandedRowTop = expandedRowIndex * rowHeight; const expandedRowBottom = expandedRowTop + rowHeight + this.detailHeight; if (expandedRowBottom > scrollTop && expandedRowIndex < start) { return expandedRowIndex; } } return start;}renderRow()
Section titled “renderRow()”Render a custom row, bypassing the default row rendering. Use this for special row types like group headers, detail rows, or footers.
renderRow(row: any, rowEl: HTMLElement, rowIndex: number): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
row | any | The row data object |
rowEl | HTMLElement | The row DOM element to render into |
rowIndex | number | The index of the row in the data array |
Returns
Section titled “Returns”boolean | void - true if the plugin handled rendering (prevents default), false/void for default rendering
Example
Section titled “Example”renderRow(row: any, rowEl: HTMLElement, rowIndex: number): boolean | void { if (row._isGroupHeader) { rowEl.innerHTML = `<div class="group-header">${row._groupLabel}</div>`; return true; // Handled - skip default rendering } // Return void to let default rendering proceed}onPluginQuery()
Section titled “onPluginQuery()”⚠️ Deprecated: Use
handleQueryinstead for new plugins. Will be removed in v2.
Handle queries from other plugins. This is the generic mechanism for inter-plugin communication. Plugins can respond to well-known query types or define their own.
Prefer handleQuery for new plugins - it has the same signature but
a clearer name. onPluginQuery is kept for backwards compatibility.
onPluginQuery(query: PluginQuery): unknownParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
query | PluginQuery | The query object with type and context |
Returns
Section titled “Returns”unknown - Query-specific response, or undefined if not handling this query
Example
Section titled “Example”onPluginQuery(query: PluginQuery): unknown { switch (query.type) { case PLUGIN_QUERIES.CAN_MOVE_COLUMN: // Prevent moving pinned columns const column = query.context as ColumnConfig; if (column.sticky === 'left' || column.sticky === 'right') { return false; } break; case PLUGIN_QUERIES.GET_CONTEXT_MENU_ITEMS: const params = query.context as ContextMenuParams; return [{ id: 'my-action', label: 'My Action', action: () => {} }]; }}handleQuery()
Section titled “handleQuery()”Handle queries from other plugins or the grid.
Queries are declared in manifest.queries and dispatched via grid.query().
This enables type-safe, discoverable inter-plugin communication.
handleQuery(query: PluginQuery): unknownParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
query | PluginQuery | The query object with type and context |
Returns
Section titled “Returns”unknown - Query-specific response, or undefined if not handling this query
Example
Section titled “Example”// In manifeststatic override readonly manifest: PluginManifest = { queries: [ { type: 'canMoveColumn', description: 'Check if a column can be moved' }, ],};
// In plugin classhandleQuery(query: PluginQuery): unknown { if (query.type === 'canMoveColumn') { const column = query.context as ColumnConfig; return !column.sticky; // Can't move sticky columns }}onKeyDown()
Section titled “onKeyDown()”Handle keyboard events on the grid. Called when a key is pressed while the grid or a cell has focus.
onKeyDown(event: KeyboardEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | KeyboardEvent | The native KeyboardEvent |
Returns
Section titled “Returns”boolean | void - true to prevent default behavior and stop propagation, false/void to allow default
Example
Section titled “Example”onKeyDown(event: KeyboardEvent): boolean | void { // Handle Ctrl+A for select all if (event.ctrlKey && event.key === 'a') { this.selectAllRows(); return true; // Prevent default browser select-all }}onCellClick()
Section titled “onCellClick()”Handle cell click events. Called when a data cell is clicked (not headers).
onCellClick(event: CellClickEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | CellClickEvent | Cell click event with row/column context |
Returns
Section titled “Returns”boolean | void - true to prevent default behavior and stop propagation, false/void to allow default
Example
Section titled “Example”onCellClick(event: CellClickEvent): boolean | void { if (event.field === '_select') { this.toggleRowSelection(event.rowIndex); return true; // Handled }}onRowClick()
Section titled “onRowClick()”Handle row click events. Called when any part of a data row is clicked. Note: This is called in addition to onCellClick, not instead of.
onRowClick(event: RowClickEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | RowClickEvent | Row click event with row context |
Returns
Section titled “Returns”boolean | void - true to prevent default behavior and stop propagation, false/void to allow default
Example
Section titled “Example”onRowClick(event: RowClickEvent): boolean | void { if (this.config.mode === 'row') { this.selectRow(event.rowIndex, event.originalEvent); return true; }}onHeaderClick()
Section titled “onHeaderClick()”Handle header click events. Called when a column header is clicked. Commonly used for sorting.
onHeaderClick(event: HeaderClickEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | HeaderClickEvent | Header click event with column context |
Returns
Section titled “Returns”boolean | void - true to prevent default behavior and stop propagation, false/void to allow default
Example
Section titled “Example”onHeaderClick(event: HeaderClickEvent): boolean | void { if (event.column.sortable !== false) { this.toggleSort(event.field); return true; }}onScroll()
Section titled “onScroll()”Handle scroll events on the grid viewport. Called during scrolling. Note: This may be called frequently; debounce if needed.
onScroll(event: ScrollEvent): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | ScrollEvent | Scroll event with scroll position and viewport dimensions |
Example
Section titled “Example”onScroll(event: ScrollEvent): void { // Update sticky column positions this.updateStickyPositions(event.scrollLeft);}onCellMouseDown()
Section titled “onCellMouseDown()”Handle cell mousedown events. Used for initiating drag operations like range selection or column resize.
onCellMouseDown(event: CellMouseEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | CellMouseEvent | Mouse event with cell context |
Returns
Section titled “Returns”boolean | void - true to indicate drag started (prevents text selection), false/void otherwise
Example
Section titled “Example”onCellMouseDown(event: CellMouseEvent): boolean | void { if (event.rowIndex !== undefined && this.config.mode === 'range') { this.startDragSelection(event.rowIndex, event.colIndex); return true; // Prevent text selection }}onCellMouseMove()
Section titled “onCellMouseMove()”Handle cell mousemove events during drag operations. Only called when a drag is in progress (after mousedown returned true).
onCellMouseMove(event: CellMouseEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | CellMouseEvent | Mouse event with current cell context |
Returns
Section titled “Returns”boolean | void - true to continue handling the drag, false/void otherwise
Example
Section titled “Example”onCellMouseMove(event: CellMouseEvent): boolean | void { if (this.isDragging && event.rowIndex !== undefined) { this.extendSelection(event.rowIndex, event.colIndex); return true; }}onCellMouseUp()
Section titled “onCellMouseUp()”Handle cell mouseup events to end drag operations.
onCellMouseUp(event: CellMouseEvent): boolean | voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
event | CellMouseEvent | Mouse event with final cell context |
Returns
Section titled “Returns”boolean | void - true if drag was finalized, false/void otherwise
Example
Section titled “Example”onCellMouseUp(event: CellMouseEvent): boolean | void { if (this.isDragging) { this.finalizeDragSelection(); this.isDragging = false; return true; }}getColumnState()
Section titled “getColumnState()”Contribute plugin-specific state for a column. Called by the grid when collecting column state for serialization. Plugins can add their own properties to the column state.
getColumnState(field: string): Partial<ColumnState> | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
field | string | The field name of the column |
Returns
Section titled “Returns”Partial<ColumnState> | undefined - Partial column state with plugin-specific properties, or undefined if no state to contribute
Example
Section titled “Example”getColumnState(field: string): Partial<ColumnState> | undefined { const filterModel = this.filterModels.get(field); if (filterModel) { // Uses module augmentation to add filter property to ColumnState return { filter: filterModel } as Partial<ColumnState>; } return undefined;}applyColumnState()
Section titled “applyColumnState()”Apply plugin-specific state to a column. Called by the grid when restoring column state from serialized data. Plugins should restore their internal state based on the provided state.
applyColumnState(field: string, state: ColumnState): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
field | string | The field name of the column |
state | ColumnState | The column state to apply (may contain plugin-specific properties) |
Example
Section titled “Example”applyColumnState(field: string, state: ColumnState): void { // Check for filter property added via module augmentation const filter = (state as any).filter; if (filter) { this.filterModels.set(field, filter); this.applyFilter(); }}getHorizontalScrollOffsets()
Section titled “getHorizontalScrollOffsets()”Report horizontal scroll boundary offsets for this plugin. Plugins that obscure part of the scroll area (e.g., pinned/sticky columns) should return how much space they occupy on each side. The keyboard navigation uses this to ensure focused cells are fully visible.
getHorizontalScrollOffsets(rowEl: HTMLElement, focusedCell: HTMLElement): object | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowEl | HTMLElement | The row element (optional, for calculating widths from rendered cells) |
focusedCell | HTMLElement | The currently focused cell element (optional, to determine if scrolling should be skipped) |
Returns
Section titled “Returns”object | undefined - Object with left/right pixel offsets and optional skipScroll flag, or undefined if plugin has no offsets
Example
Section titled “Example”getHorizontalScrollOffsets(rowEl?: HTMLElement, focusedCell?: HTMLElement): { left: number; right: number; skipScroll?: boolean } | undefined { // Calculate total width of left-pinned columns const leftCells = rowEl?.querySelectorAll('.sticky-left') ?? []; let left = 0; leftCells.forEach(el => { left += (el as HTMLElement).offsetWidth; }); // Skip scroll if focused cell is pinned (always visible) const skipScroll = focusedCell?.classList.contains('sticky-left'); return { left, right: 0, skipScroll };}getToolPanel()
Section titled “getToolPanel()”Register a tool panel for this plugin. Return undefined if plugin has no tool panel. The shell will create a toolbar toggle button and render the panel content when the user opens the panel.
getToolPanel(): ToolPanelDefinition | undefinedReturns
Section titled “Returns”ToolPanelDefinition | undefined - Tool panel definition, or undefined if plugin has no panel
Example
Section titled “Example”getToolPanel(): ToolPanelDefinition | undefined { return { id: 'columns', title: 'Columns', icon: '☰', tooltip: 'Show/hide columns', order: 10, render: (container) => { this.renderColumnList(container); return () => this.cleanup(); }, };}getHeaderContent()
Section titled “getHeaderContent()”Register content for the shell header center section. Return undefined if plugin has no header content. Examples: search input, selection summary, status indicators.
getHeaderContent(): HeaderContentDefinition | undefinedReturns
Section titled “Returns”HeaderContentDefinition | undefined - Header content definition, or undefined if plugin has no header content
Example
Section titled “Example”getHeaderContent(): HeaderContentDefinition | undefined { return { id: 'quick-filter', order: 10, render: (container) => { const input = document.createElement('input'); input.type = 'text'; input.placeholder = 'Search...'; input.addEventListener('input', this.handleInput); container.appendChild(input); return () => input.removeEventListener('input', this.handleInput); }, };}