@toolbox-web/grid 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +46 -0
  2. package/all.d.ts +327 -178
  3. package/all.js +328 -287
  4. package/all.js.map +1 -1
  5. package/index.d.ts +219 -113
  6. package/index.js +1182 -1108
  7. package/index.js.map +1 -1
  8. package/lib/plugins/clipboard/index.js.map +1 -1
  9. package/lib/plugins/column-virtualization/index.js.map +1 -1
  10. package/lib/plugins/context-menu/index.js.map +1 -1
  11. package/lib/plugins/export/index.js.map +1 -1
  12. package/lib/plugins/filtering/index.js.map +1 -1
  13. package/lib/plugins/grouping-columns/index.js.map +1 -1
  14. package/lib/plugins/grouping-rows/index.js.map +1 -1
  15. package/lib/plugins/master-detail/index.js.map +1 -1
  16. package/lib/plugins/multi-sort/index.js.map +1 -1
  17. package/lib/plugins/pinned-columns/index.js +91 -48
  18. package/lib/plugins/pinned-columns/index.js.map +1 -1
  19. package/lib/plugins/pinned-rows/index.js.map +1 -1
  20. package/lib/plugins/pivot/index.js.map +1 -1
  21. package/lib/plugins/reorder/index.js +38 -35
  22. package/lib/plugins/reorder/index.js.map +1 -1
  23. package/lib/plugins/selection/index.js.map +1 -1
  24. package/lib/plugins/server-side/index.js.map +1 -1
  25. package/lib/plugins/tree/index.js.map +1 -1
  26. package/lib/plugins/undo-redo/index.js.map +1 -1
  27. package/lib/plugins/visibility/index.js.map +1 -1
  28. package/package.json +1 -1
  29. package/umd/grid.all.umd.js +19 -19
  30. package/umd/grid.all.umd.js.map +1 -1
  31. package/umd/grid.umd.js +16 -16
  32. package/umd/grid.umd.js.map +1 -1
  33. package/umd/plugins/pinned-columns.umd.js +1 -1
  34. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  35. package/umd/plugins/reorder.umd.js +1 -1
  36. package/umd/plugins/reorder.umd.js.map +1 -1
package/index.d.ts CHANGED
@@ -26,7 +26,7 @@ export declare type AggregatorFn = (rows: any[], field: string, column?: any) =>
26
26
  /** Map of field names to aggregator references */
27
27
  declare type AggregatorMap = Record<string, AggregatorRef_2>;
28
28
 
29
- export declare type AggregatorRef = string | ((rows: any[], field: string, column?: any) => any);
29
+ export declare type AggregatorRef = string | ((rows: unknown[], field: string, column?: unknown) => unknown);
30
30
 
31
31
  declare type AggregatorRef_2 = string | AggregatorFn;
32
32
 
@@ -89,17 +89,17 @@ export declare interface BaseColumnConfig<TRow = any, TValue = any> {
89
89
  /** For select/typeahead types - available options */
90
90
  options?: Array<{
91
91
  label: string;
92
- value: any;
92
+ value: unknown;
93
93
  }> | (() => Array<{
94
94
  label: string;
95
- value: any;
95
+ value: unknown;
96
96
  }>);
97
97
  /** For select/typeahead - allow multi select */
98
98
  multi?: boolean;
99
99
  /** Optional formatter */
100
100
  format?: (value: TValue, row: TRow) => string;
101
101
  /** Arbitrary extra metadata */
102
- meta?: Record<string, any>;
102
+ meta?: Record<string, unknown>;
103
103
  }
104
104
 
105
105
  /**
@@ -107,7 +107,7 @@ export declare interface BaseColumnConfig<TRow = any, TValue = any> {
107
107
  *
108
108
  * @template TConfig - Configuration type for the plugin
109
109
  */
110
- export declare abstract class BaseGridPlugin<TConfig = unknown> {
110
+ export declare abstract class BaseGridPlugin<TConfig = unknown> implements GridPlugin {
111
111
  /** Unique plugin identifier (derived from class name by default) */
112
112
  abstract readonly name: string;
113
113
  /** Plugin version - override in subclass if needed */
@@ -403,6 +403,33 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
403
403
  * ```
404
404
  */
405
405
  renderRow?(row: any, rowEl: HTMLElement, rowIndex: number): boolean | void;
406
+ /**
407
+ * Handle queries from other plugins.
408
+ * This is the generic mechanism for inter-plugin communication.
409
+ * Plugins can respond to well-known query types or define their own.
410
+ *
411
+ * @param query - The query object with type and context
412
+ * @returns Query-specific response, or undefined if not handling this query
413
+ *
414
+ * @example
415
+ * ```ts
416
+ * onPluginQuery(query: PluginQuery): unknown {
417
+ * switch (query.type) {
418
+ * case PLUGIN_QUERIES.CAN_MOVE_COLUMN:
419
+ * // Prevent moving pinned columns
420
+ * const column = query.context as ColumnConfig;
421
+ * if (column.sticky === 'left' || column.sticky === 'right') {
422
+ * return false;
423
+ * }
424
+ * break;
425
+ * case PLUGIN_QUERIES.GET_CONTEXT_MENU_ITEMS:
426
+ * const params = query.context as ContextMenuParams;
427
+ * return [{ id: 'my-action', label: 'My Action', action: () => {} }];
428
+ * }
429
+ * }
430
+ * ```
431
+ */
432
+ onPluginQuery?(query: PluginQuery): unknown;
406
433
  /**
407
434
  * Handle keyboard events on the grid.
408
435
  * Called when a key is pressed while the grid or a cell has focus.
@@ -546,29 +573,6 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
546
573
  * ```
547
574
  */
548
575
  onCellMouseUp?(event: CellMouseEvent): boolean | void;
549
- /**
550
- * Provide context menu items when right-clicking on the grid.
551
- * Multiple plugins can contribute items; they are merged into a single menu.
552
- *
553
- * @param params - Context about where the menu was triggered (row, column, etc.)
554
- * @returns Array of menu items to display
555
- *
556
- * @example
557
- * ```ts
558
- * getContextMenuItems(params: ContextMenuParams): ContextMenuItem[] {
559
- * if (params.isHeader) {
560
- * return [
561
- * { id: 'sort-asc', label: 'Sort Ascending', action: () => this.sortAsc(params.field) },
562
- * { id: 'sort-desc', label: 'Sort Descending', action: () => this.sortDesc(params.field) },
563
- * ];
564
- * }
565
- * return [
566
- * { id: 'copy', label: 'Copy Cell', action: () => this.copyCell(params) },
567
- * ];
568
- * }
569
- * ```
570
- */
571
- getContextMenuItems?(params: ContextMenuParams): ContextMenuItem[];
572
576
  /**
573
577
  * Contribute plugin-specific state for a column.
574
578
  * Called by the grid when collecting column state for serialization.
@@ -611,6 +615,34 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
611
615
  * ```
612
616
  */
613
617
  applyColumnState?(field: string, state: ColumnState): void;
618
+ /**
619
+ * Report horizontal scroll boundary offsets for this plugin.
620
+ * Plugins that obscure part of the scroll area (e.g., pinned/sticky columns)
621
+ * should return how much space they occupy on each side.
622
+ * The keyboard navigation uses this to ensure focused cells are fully visible.
623
+ *
624
+ * @param rowEl - The row element (optional, for calculating widths from rendered cells)
625
+ * @param focusedCell - The currently focused cell element (optional, to determine if scrolling should be skipped)
626
+ * @returns Object with left/right pixel offsets and optional skipScroll flag, or undefined if plugin has no offsets
627
+ *
628
+ * @example
629
+ * ```ts
630
+ * getHorizontalScrollOffsets(rowEl?: HTMLElement, focusedCell?: HTMLElement): { left: number; right: number; skipScroll?: boolean } | undefined {
631
+ * // Calculate total width of left-pinned columns
632
+ * const leftCells = rowEl?.querySelectorAll('.sticky-left') ?? [];
633
+ * let left = 0;
634
+ * leftCells.forEach(el => { left += (el as HTMLElement).offsetWidth; });
635
+ * // Skip scroll if focused cell is pinned (always visible)
636
+ * const skipScroll = focusedCell?.classList.contains('sticky-left');
637
+ * return { left, right: 0, skipScroll };
638
+ * }
639
+ * ```
640
+ */
641
+ getHorizontalScrollOffsets?(rowEl?: HTMLElement, focusedCell?: HTMLElement): {
642
+ left: number;
643
+ right: number;
644
+ skipScroll?: boolean;
645
+ } | undefined;
614
646
  /**
615
647
  * Register a tool panel for this plugin.
616
648
  * Return undefined if plugin has no tool panel.
@@ -678,13 +710,13 @@ export declare interface CellClickEvent {
678
710
  originalEvent: MouseEvent;
679
711
  }
680
712
 
681
- export declare interface CellCommitDetail<TRow = any> {
713
+ export declare interface CellCommitDetail<TRow = unknown> {
682
714
  /** The mutated row after commit. */
683
715
  row: TRow;
684
716
  /** Field name whose value changed. */
685
717
  field: string;
686
718
  /** New value stored. */
687
- value: any;
719
+ value: unknown;
688
720
  /** Index of the row in current data set. */
689
721
  rowIndex: number;
690
722
  /** All rows that have at least one committed change (snapshot list). */
@@ -700,7 +732,7 @@ export declare interface CellCommitDetail<TRow = any> {
700
732
  */
701
733
  declare interface CellContext<T = any> {
702
734
  row: T;
703
- value: any;
735
+ value: unknown;
704
736
  field: string;
705
737
  column: ColumnInternal<T>;
706
738
  }
@@ -786,7 +818,7 @@ export declare interface CellRenderContext<TRow = any, TValue = any> {
786
818
  export declare type CellRenderer = (ctx: PluginCellRenderContext) => string | HTMLElement;
787
819
 
788
820
  /** Emitted when the changed rows tracking set is cleared programmatically. */
789
- export declare interface ChangedRowsResetDetail<TRow = any> {
821
+ export declare interface ChangedRowsResetDetail<TRow = unknown> {
790
822
  /** New (empty) changed rows array after reset. */
791
823
  rows: TRow[];
792
824
  /** Parallel indices (likely empty). */
@@ -801,12 +833,12 @@ export declare interface ColumnConfig<TRow = any> extends BaseColumnConfig<TRow,
801
833
  viewRenderer?: ColumnViewRenderer<TRow, any>;
802
834
  /** External view spec (lets host app mount any framework component) */
803
835
  externalView?: {
804
- component: any;
805
- props?: Record<string, any>;
836
+ component: unknown;
837
+ props?: Record<string, unknown>;
806
838
  mount?: (options: {
807
839
  placeholder: HTMLElement;
808
- context: CellRenderContext<TRow, any>;
809
- spec: any;
840
+ context: CellRenderContext<TRow, unknown>;
841
+ spec: unknown;
810
842
  }) => void | {
811
843
  dispose?: () => void;
812
844
  };
@@ -838,16 +870,16 @@ export declare interface ColumnEditorContext<TRow = any, TValue = any> {
838
870
  }
839
871
 
840
872
  /** External editor spec: tag name, factory function, or external mount spec */
841
- export declare type ColumnEditorSpec<TRow = any, TValue = any> = string | ((context: ColumnEditorContext<TRow, TValue>) => HTMLElement | string) | {
873
+ export declare type ColumnEditorSpec<TRow = unknown, TValue = unknown> = string | ((context: ColumnEditorContext<TRow, TValue>) => HTMLElement | string) | {
842
874
  /** Arbitrary component reference (class, function, token) */
843
- component: any;
875
+ component: unknown;
844
876
  /** Optional static props passed to mount */
845
- props?: Record<string, any>;
877
+ props?: Record<string, unknown>;
846
878
  /** Optional custom mount function; if provided we call it directly instead of emitting an event */
847
879
  mount?: (options: {
848
880
  placeholder: HTMLElement;
849
881
  context: ColumnEditorContext<TRow, TValue>;
850
- spec: any;
882
+ spec: unknown;
851
883
  }) => void | {
852
884
  dispose?: () => void;
853
885
  };
@@ -909,10 +941,10 @@ export declare interface ColumnState {
909
941
  sort?: ColumnSortState;
910
942
  }
911
943
 
912
- export declare type ColumnViewRenderer<TRow = any, TValue = any> = (ctx: CellRenderContext<TRow, TValue>) => Node | string | void;
944
+ export declare type ColumnViewRenderer<TRow = unknown, TValue = unknown> = (ctx: CellRenderContext<TRow, TValue>) => Node | string | void;
913
945
 
914
946
  /**
915
- * Context menu item
947
+ * Context menu item (used by context-menu plugin query)
916
948
  */
917
949
  export declare interface ContextMenuItem {
918
950
  id: string;
@@ -939,7 +971,7 @@ export declare interface ContextMenuParams {
939
971
  isHeader?: boolean;
940
972
  }
941
973
 
942
- export declare type DataGridCustomEvent<K extends keyof DataGridEventMap<any>, TRow = any> = CustomEvent<DataGridEventMap<TRow>[K]>;
974
+ export declare type DataGridCustomEvent<K extends keyof DataGridEventMap<unknown>, TRow = unknown> = CustomEvent<DataGridEventMap<TRow>[K]>;
943
975
 
944
976
  export declare class DataGridElement<T = any> extends HTMLElement implements InternalGrid<T> {
945
977
  #private;
@@ -1023,7 +1055,6 @@ export declare class DataGridElement<T = any> extends HTMLElement implements Int
1023
1055
  emitSortChange(detail: SortChangeDetail): void;
1024
1056
  emitColumnResize(detail: ColumnResizeDetail): void;
1025
1057
  emitActivateCell(detail: ActivateCellDetail): void;
1026
- updateTemplate(): void;
1027
1058
  findHeaderRow(): HTMLElement;
1028
1059
  findRenderedRowElement(rowIndex: number): HTMLElement | null;
1029
1060
  /**
@@ -1041,6 +1072,26 @@ export declare class DataGridElement<T = any> extends HTMLElement implements Int
1041
1072
  * Returns true if any plugin handled the event.
1042
1073
  */
1043
1074
  dispatchKeyDown(event: KeyboardEvent): boolean;
1075
+ /**
1076
+ * Get horizontal scroll boundary offsets from plugins.
1077
+ * Used by keyboard navigation to ensure focused cells are fully visible
1078
+ * when plugins like pinned columns obscure part of the scroll area.
1079
+ */
1080
+ getHorizontalScrollOffsets(rowEl?: HTMLElement, focusedCell?: HTMLElement): {
1081
+ left: number;
1082
+ right: number;
1083
+ skipScroll?: boolean;
1084
+ };
1085
+ /**
1086
+ * Query all plugins with a generic query and collect responses.
1087
+ * This enables inter-plugin communication without the core knowing plugin-specific concepts.
1088
+ *
1089
+ * @example
1090
+ * // Check if any plugin vetoes moving a column
1091
+ * const responses = grid.queryPlugins<boolean>({ type: PLUGIN_QUERIES.CAN_MOVE_COLUMN, context: column });
1092
+ * const canMove = !responses.includes(false);
1093
+ */
1094
+ queryPlugins<T>(query: PluginQuery): T[];
1044
1095
  get changedRows(): T[];
1045
1096
  get changedRowIndices(): number[];
1046
1097
  resetChangedRows(silent?: boolean): Promise<void>;
@@ -1122,76 +1173,42 @@ export declare class DataGridElement<T = any> extends HTMLElement implements Int
1122
1173
  * Clears all user modifications (order, width, visibility, sort).
1123
1174
  */
1124
1175
  resetColumnState(): void;
1125
- /**
1126
- * Check if the tool panel is currently open.
1127
- */
1176
+ /** Check if the tool panel is currently open. */
1128
1177
  get isToolPanelOpen(): boolean;
1129
1178
  /**
1130
1179
  * Get the currently active tool panel ID, or null if none is open.
1131
1180
  * @deprecated Use isToolPanelOpen and expandedToolPanelSections instead.
1132
1181
  */
1133
1182
  get activeToolPanel(): string | null;
1134
- /**
1135
- * Get the IDs of expanded accordion sections.
1136
- */
1183
+ /** Get the IDs of expanded accordion sections. */
1137
1184
  get expandedToolPanelSections(): string[];
1138
- /**
1139
- * Open the tool panel (accordion view with all registered panels).
1140
- */
1185
+ /** Open the tool panel (accordion view with all registered panels). */
1141
1186
  openToolPanel(): void;
1142
- /**
1143
- * Close the tool panel.
1144
- */
1187
+ /** Close the tool panel. */
1145
1188
  closeToolPanel(): void;
1146
- /**
1147
- * Toggle the tool panel open/closed.
1148
- */
1189
+ /** Toggle the tool panel open/closed. */
1149
1190
  toggleToolPanel(): void;
1150
- /**
1151
- * Toggle an accordion section expanded/collapsed.
1152
- * Only one section can be expanded at a time (exclusive accordion).
1153
- * When there's only one panel, toggling is disabled (always expanded).
1154
- */
1191
+ /** Toggle an accordion section expanded/collapsed. */
1155
1192
  toggleToolPanelSection(sectionId: string): void;
1156
- /**
1157
- * Get registered tool panel definitions.
1158
- */
1193
+ /** Get registered tool panel definitions. */
1159
1194
  getToolPanels(): ToolPanelDefinition[];
1160
- /**
1161
- * Register a custom tool panel (without creating a plugin).
1162
- */
1195
+ /** Register a custom tool panel (without creating a plugin). */
1163
1196
  registerToolPanel(panel: ToolPanelDefinition): void;
1164
- /**
1165
- * Unregister a custom tool panel.
1166
- */
1197
+ /** Unregister a custom tool panel. */
1167
1198
  unregisterToolPanel(panelId: string): void;
1168
- /**
1169
- * Get registered header content definitions.
1170
- */
1199
+ /** Get registered header content definitions. */
1171
1200
  getHeaderContents(): HeaderContentDefinition[];
1172
- /**
1173
- * Register custom header content (without creating a plugin).
1174
- */
1201
+ /** Register custom header content (without creating a plugin). */
1175
1202
  registerHeaderContent(content: HeaderContentDefinition): void;
1176
- /**
1177
- * Unregister custom header content.
1178
- */
1203
+ /** Unregister custom header content. */
1179
1204
  unregisterHeaderContent(contentId: string): void;
1180
- /**
1181
- * Get all registered toolbar buttons.
1182
- */
1205
+ /** Get all registered toolbar buttons. */
1183
1206
  getToolbarButtons(): ToolbarButtonInfo[];
1184
- /**
1185
- * Register a custom toolbar button programmatically.
1186
- */
1207
+ /** Register a custom toolbar button programmatically. */
1187
1208
  registerToolbarButton(button: ToolbarButtonConfig): void;
1188
- /**
1189
- * Unregister a custom toolbar button.
1190
- */
1209
+ /** Unregister a custom toolbar button. */
1191
1210
  unregisterToolbarButton(buttonId: string): void;
1192
- /**
1193
- * Enable/disable a toolbar button by ID.
1194
- */
1211
+ /** Enable/disable a toolbar button by ID. */
1195
1212
  setToolbarButtonDisabled(buttonId: string, disabled: boolean): void;
1196
1213
  /**
1197
1214
  * Re-parse light DOM shell elements and refresh shell header.
@@ -1211,7 +1228,7 @@ export declare class DataGridElement<T = any> extends HTMLElement implements Int
1211
1228
  export declare interface DataGridElementInterface extends PublicGrid, HTMLElement {
1212
1229
  }
1213
1230
 
1214
- export declare interface DataGridEventMap<TRow = any> {
1231
+ export declare interface DataGridEventMap<TRow = unknown> {
1215
1232
  'cell-commit': CellCommitDetail<TRow>;
1216
1233
  'row-commit': RowCommitDetail<TRow>;
1217
1234
  'changed-rows-reset': ChangedRowsResetDetail<TRow>;
@@ -1261,7 +1278,7 @@ export declare interface EditAction {
1261
1278
  * Internal editor execution context extending the generic cell context with commit helpers.
1262
1279
  */
1263
1280
  declare interface EditorExecContext<T = any> extends CellContext<T> {
1264
- commit: (newValue: any) => void;
1281
+ commit: (newValue: unknown) => void;
1265
1282
  cancel: () => void;
1266
1283
  }
1267
1284
 
@@ -1291,27 +1308,27 @@ export declare interface ExportParams {
1291
1308
  processHeader?: (header: string, field: string) => string;
1292
1309
  }
1293
1310
 
1294
- export declare interface ExternalMountEditorDetail<TRow = any> {
1311
+ export declare interface ExternalMountEditorDetail<TRow = unknown> {
1295
1312
  placeholder: HTMLElement;
1296
- spec: any;
1313
+ spec: unknown;
1297
1314
  context: {
1298
1315
  row: TRow;
1299
- value: any;
1316
+ value: unknown;
1300
1317
  field: string;
1301
- column: any;
1302
- commit: (v: any) => void;
1318
+ column: unknown;
1319
+ commit: (v: unknown) => void;
1303
1320
  cancel: () => void;
1304
1321
  };
1305
1322
  }
1306
1323
 
1307
- export declare interface ExternalMountViewDetail<TRow = any> {
1324
+ export declare interface ExternalMountViewDetail<TRow = unknown> {
1308
1325
  placeholder: HTMLElement;
1309
- spec: any;
1326
+ spec: unknown;
1310
1327
  context: {
1311
1328
  row: TRow;
1312
- value: any;
1329
+ value: unknown;
1313
1330
  field: string;
1314
- column: any;
1331
+ column: unknown;
1315
1332
  };
1316
1333
  }
1317
1334
 
@@ -1411,6 +1428,10 @@ export declare function getValueAggregator(aggFunc: string): ValueAggregatorFn;
1411
1428
  /**
1412
1429
  * CSS class names used in the grid's shadow DOM.
1413
1430
  * Use these when adding/removing classes or querying elements.
1431
+ *
1432
+ * Classes are organized by:
1433
+ * - Core: Used by the grid core for structure and basic functionality
1434
+ * - Shared: Used by multiple features/plugins, styled by core CSS
1414
1435
  */
1415
1436
  export declare const GridClasses: {
1416
1437
  readonly ROOT: "tbw-grid-root";
@@ -1496,6 +1517,27 @@ export declare interface GridConfig<TRow = any> {
1496
1517
  fitMode?: FitMode;
1497
1518
  /** Edit activation mode ('click' | 'dblclick'). Can also be set via `editOn` prop. */
1498
1519
  editOn?: string;
1520
+ /**
1521
+ * Row height in pixels for virtualization calculations.
1522
+ * The virtualization system assumes uniform row heights for performance.
1523
+ *
1524
+ * If not specified, the grid measures the first rendered row's height,
1525
+ * which respects the CSS variable `--tbw-row-height` set by themes.
1526
+ *
1527
+ * Set this explicitly when:
1528
+ * - Row content may wrap to multiple lines (also set `--tbw-cell-white-space: normal`)
1529
+ * - Using custom row templates with variable content
1530
+ * - You want to override theme-defined row height
1531
+ *
1532
+ * @default Auto-measured from first row (respects --tbw-row-height CSS variable)
1533
+ *
1534
+ * @example
1535
+ * ```ts
1536
+ * // Fixed height for rows that may wrap to 2 lines
1537
+ * gridConfig = { rowHeight: 56 };
1538
+ * ```
1539
+ */
1540
+ rowHeight?: number;
1499
1541
  /**
1500
1542
  * Array of plugin instances.
1501
1543
  * Each plugin is instantiated with its configuration and attached to this grid.
@@ -1509,7 +1551,7 @@ export declare interface GridConfig<TRow = any> {
1509
1551
  * ]
1510
1552
  * ```
1511
1553
  */
1512
- plugins?: any[];
1554
+ plugins?: GridPlugin[];
1513
1555
  /**
1514
1556
  * Saved column state to restore on initialization.
1515
1557
  * Includes order, width, visibility, sort, and plugin-contributed state.
@@ -1611,6 +1653,20 @@ export declare interface GridIcons {
1611
1653
  toolPanel?: IconValue;
1612
1654
  }
1613
1655
 
1656
+ /**
1657
+ * Minimal plugin interface for type-checking.
1658
+ * This interface is defined here to avoid circular imports with BaseGridPlugin.
1659
+ * All plugins must satisfy this shape (BaseGridPlugin implements it).
1660
+ */
1661
+ export declare interface GridPlugin {
1662
+ /** Unique plugin identifier */
1663
+ readonly name: string;
1664
+ /** Plugin version */
1665
+ readonly version: string;
1666
+ /** CSS styles to inject into grid's shadow DOM */
1667
+ readonly styles?: string;
1668
+ }
1669
+
1614
1670
  /**
1615
1671
  * Common CSS selectors for querying grid elements.
1616
1672
  * Built from the class constants for consistency.
@@ -1705,7 +1761,7 @@ export declare type HeaderRenderer = (ctx: PluginHeaderRenderContext) => string
1705
1761
  export declare type IconValue = string | HTMLElement;
1706
1762
 
1707
1763
  /** Result of automatic column inference from sample rows. */
1708
- export declare interface InferredColumnResult<TRow = any> {
1764
+ export declare interface InferredColumnResult<TRow = unknown> {
1709
1765
  columns: ColumnConfigMap<TRow>;
1710
1766
  typeMap: Record<string, PrimitiveColumnType>;
1711
1767
  }
@@ -1737,7 +1793,7 @@ declare interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
1737
1793
  focusRow: number;
1738
1794
  focusCol: number;
1739
1795
  activeEditRows: number;
1740
- rowEditSnapshots: Map<number, any>;
1796
+ rowEditSnapshots: Map<number, T>;
1741
1797
  _changedRowIndices: Set<number>;
1742
1798
  changedRows?: T[];
1743
1799
  changedRowIndices?: number[];
@@ -1754,6 +1810,14 @@ declare interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
1754
1810
  dispatchHeaderClick?: (event: MouseEvent, colIndex: number, headerEl: HTMLElement) => boolean;
1755
1811
  /** Dispatch keydown to plugin system, returns true if handled */
1756
1812
  dispatchKeyDown?: (event: KeyboardEvent) => boolean;
1813
+ /** Get horizontal scroll boundary offsets from plugins (e.g., pinned columns) */
1814
+ getHorizontalScrollOffsets?: (rowEl?: HTMLElement, focusedCell?: HTMLElement) => {
1815
+ left: number;
1816
+ right: number;
1817
+ skipScroll?: boolean;
1818
+ };
1819
+ /** Query all plugins with a generic query and collect responses */
1820
+ queryPlugins?: <T>(query: PluginQuery) => T[];
1757
1821
  /** Request emission of column-state-change event (debounced) */
1758
1822
  requestStateChange?: () => void;
1759
1823
  }
@@ -1850,6 +1914,17 @@ export declare interface PivotValueField {
1850
1914
  header?: string;
1851
1915
  }
1852
1916
 
1917
+ /**
1918
+ * Well-known plugin query types.
1919
+ * Plugins can define additional query types beyond these.
1920
+ */
1921
+ export declare const PLUGIN_QUERIES: {
1922
+ /** Ask if a column can be moved. Context: ColumnConfig. Response: boolean | undefined */
1923
+ readonly CAN_MOVE_COLUMN: "canMoveColumn";
1924
+ /** Get context menu items. Context: ContextMenuParams. Response: ContextMenuItem[] */
1925
+ readonly GET_CONTEXT_MENU_ITEMS: "getContextMenuItems";
1926
+ };
1927
+
1853
1928
  /**
1854
1929
  * Cell render context for plugin cell renderers.
1855
1930
  * Provides full context including position and editing state.
@@ -2008,6 +2083,16 @@ export declare class PluginManager {
2008
2083
  * Returns true if any plugin handled the row.
2009
2084
  */
2010
2085
  renderRow(row: any, rowEl: HTMLElement, rowIndex: number): boolean;
2086
+ /**
2087
+ * Query all plugins with a generic query and collect responses.
2088
+ * This enables inter-plugin communication without the core knowing plugin-specific concepts.
2089
+ *
2090
+ * Common query types are defined in PLUGIN_QUERIES, but plugins can define their own.
2091
+ *
2092
+ * @param query - The query object containing type and context
2093
+ * @returns Array of non-undefined responses from plugins
2094
+ */
2095
+ queryPlugins<T>(query: PluginQuery): T[];
2011
2096
  /**
2012
2097
  * Execute onKeyDown hook on all plugins.
2013
2098
  * Returns true if any plugin handled the event.
@@ -2048,9 +2133,18 @@ export declare class PluginManager {
2048
2133
  */
2049
2134
  onCellMouseUp(event: CellMouseEvent): boolean;
2050
2135
  /**
2051
- * Collect context menu items from all plugins.
2052
- */
2053
- getContextMenuItems(params: ContextMenuParams): ContextMenuItem[];
2136
+ * Collect horizontal scroll boundary offsets from all plugins.
2137
+ * Combines offsets from all plugins that report them.
2138
+ *
2139
+ * @param rowEl - The row element (optional, for calculating widths from rendered cells)
2140
+ * @param focusedCell - The currently focused cell element (optional, to determine if scrolling should be skipped)
2141
+ * @returns Combined left and right pixel offsets, plus skipScroll if any plugin requests it
2142
+ */
2143
+ getHorizontalScrollOffsets(rowEl?: HTMLElement, focusedCell?: HTMLElement): {
2144
+ left: number;
2145
+ right: number;
2146
+ skipScroll?: boolean;
2147
+ };
2054
2148
  /**
2055
2149
  * Collect tool panels from all plugins.
2056
2150
  * Returns panels sorted by order (ascending).
@@ -2069,6 +2163,18 @@ export declare class PluginManager {
2069
2163
  }[];
2070
2164
  }
2071
2165
 
2166
+ /**
2167
+ * Generic plugin query for inter-plugin communication.
2168
+ * Plugins can define their own query types as string constants
2169
+ * and respond to queries from other plugins.
2170
+ */
2171
+ export declare interface PluginQuery<T = unknown> {
2172
+ /** Query type identifier (e.g., 'canMoveColumn', 'getContextMenuItems') */
2173
+ type: string;
2174
+ /** Query-specific context/parameters */
2175
+ context: T;
2176
+ }
2177
+
2072
2178
  export declare type PrimitiveColumnType = 'number' | 'string' | 'date' | 'boolean' | 'select' | 'typeahead';
2073
2179
 
2074
2180
  /**
@@ -2131,7 +2237,7 @@ export declare interface RowClickEvent {
2131
2237
  }
2132
2238
 
2133
2239
  /** Detail payload for a committed row edit (may or may not include changes). */
2134
- export declare interface RowCommitDetail<TRow = any> {
2240
+ export declare interface RowCommitDetail<TRow = unknown> {
2135
2241
  /** Row index that lost edit focus. */
2136
2242
  rowIndex: number;
2137
2243
  /** Row object reference. */
@@ -2152,7 +2258,7 @@ export declare interface RowGroupRenderConfig {
2152
2258
  /** If true, group rows span all columns (single full-width cell). Default false. */
2153
2259
  fullWidth?: boolean;
2154
2260
  /** Optional label formatter override. Receives raw group value + depth. */
2155
- formatLabel?: (value: any, depth: number, key: string) => string;
2261
+ formatLabel?: (value: unknown, depth: number, key: string) => string;
2156
2262
  /** Optional aggregate overrides per field for group summary cells (only when not fullWidth). */
2157
2263
  aggregators?: Record<string, AggregatorRef>;
2158
2264
  /** Additional CSS class applied to each group row root element. */