@toolbox-web/grid 0.0.4 → 0.0.6

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 (64) hide show
  1. package/README.md +24 -0
  2. package/all.d.ts +1709 -135
  3. package/all.js +745 -645
  4. package/all.js.map +1 -1
  5. package/index.d.ts +161 -1
  6. package/index.js +1050 -913
  7. package/index.js.map +1 -1
  8. package/lib/plugins/clipboard/index.js +110 -52
  9. package/lib/plugins/clipboard/index.js.map +1 -1
  10. package/lib/plugins/column-virtualization/index.js +78 -20
  11. package/lib/plugins/column-virtualization/index.js.map +1 -1
  12. package/lib/plugins/context-menu/index.js +163 -95
  13. package/lib/plugins/context-menu/index.js.map +1 -1
  14. package/lib/plugins/export/index.js +93 -35
  15. package/lib/plugins/export/index.js.map +1 -1
  16. package/lib/plugins/filtering/index.js +188 -133
  17. package/lib/plugins/filtering/index.js.map +1 -1
  18. package/lib/plugins/grouping-columns/index.js +69 -11
  19. package/lib/plugins/grouping-columns/index.js.map +1 -1
  20. package/lib/plugins/grouping-rows/index.js +111 -55
  21. package/lib/plugins/grouping-rows/index.js.map +1 -1
  22. package/lib/plugins/master-detail/index.js +196 -51
  23. package/lib/plugins/master-detail/index.js.map +1 -1
  24. package/lib/plugins/multi-sort/index.js +104 -46
  25. package/lib/plugins/multi-sort/index.js.map +1 -1
  26. package/lib/plugins/pinned-columns/index.js +74 -16
  27. package/lib/plugins/pinned-columns/index.js.map +1 -1
  28. package/lib/plugins/pinned-rows/index.js +65 -7
  29. package/lib/plugins/pinned-rows/index.js.map +1 -1
  30. package/lib/plugins/pivot/index.js +117 -59
  31. package/lib/plugins/pivot/index.js.map +1 -1
  32. package/lib/plugins/reorder/index.js +103 -45
  33. package/lib/plugins/reorder/index.js.map +1 -1
  34. package/lib/plugins/selection/index.js +139 -81
  35. package/lib/plugins/selection/index.js.map +1 -1
  36. package/lib/plugins/server-side/index.js +96 -38
  37. package/lib/plugins/server-side/index.js.map +1 -1
  38. package/lib/plugins/tree/index.js +108 -47
  39. package/lib/plugins/tree/index.js.map +1 -1
  40. package/lib/plugins/undo-redo/index.js +70 -12
  41. package/lib/plugins/undo-redo/index.js.map +1 -1
  42. package/lib/plugins/visibility/index.js +82 -24
  43. package/lib/plugins/visibility/index.js.map +1 -1
  44. package/package.json +1 -1
  45. package/umd/grid.all.umd.js +31 -31
  46. package/umd/grid.all.umd.js.map +1 -1
  47. package/umd/grid.umd.js +15 -15
  48. package/umd/grid.umd.js.map +1 -1
  49. package/umd/plugins/context-menu.umd.js +2 -2
  50. package/umd/plugins/context-menu.umd.js.map +1 -1
  51. package/umd/plugins/filtering.umd.js +3 -3
  52. package/umd/plugins/filtering.umd.js.map +1 -1
  53. package/umd/plugins/grouping-rows.umd.js +2 -2
  54. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  55. package/umd/plugins/master-detail.umd.js +2 -2
  56. package/umd/plugins/master-detail.umd.js.map +1 -1
  57. package/umd/plugins/multi-sort.umd.js +1 -1
  58. package/umd/plugins/multi-sort.umd.js.map +1 -1
  59. package/umd/plugins/reorder.umd.js +1 -1
  60. package/umd/plugins/reorder.umd.js.map +1 -1
  61. package/umd/plugins/tree.umd.js +2 -2
  62. package/umd/plugins/tree.umd.js.map +1 -1
  63. package/umd/plugins/visibility.umd.js +1 -1
  64. package/umd/plugins/visibility.umd.js.map +1 -1
package/all.d.ts CHANGED
@@ -20,7 +20,7 @@ declare interface AggregationRowConfig {
20
20
  /** Label when in fullWidth mode */
21
21
  label?: string;
22
22
  /** Static or computed cell values keyed by field */
23
- cells?: Record<string, unknown | string | ((rows: unknown[], field: string, column?: ColumnConfig) => unknown)>;
23
+ cells?: Record<string, unknown | string | ((rows: unknown[], field: string, column?: ColumnConfig_2) => unknown)>;
24
24
  /** Per-field aggregator override; string maps to registered aggregator key */
25
25
  aggregators?: Record<string, AggregatorRef_3>;
26
26
  }
@@ -37,17 +37,67 @@ declare interface AggregationRowConfig {
37
37
  * - By UMD/CDN: TbwGrid.aggregatorRegistry
38
38
  * - By plugins via context: ctx.aggregatorRegistry
39
39
  */
40
- declare type AggregatorFn = (rows: any[], field: string, column?: any) => any;
40
+ export declare type AggregatorFn = (rows: any[], field: string, column?: any) => any;
41
+
42
+ /**
43
+ * Aggregators Core Registry
44
+ *
45
+ * Provides a central registry for aggregator functions.
46
+ * Built-in aggregators are provided by default.
47
+ * Plugins can register additional aggregators.
48
+ *
49
+ * The registry is exposed as a singleton object that can be accessed:
50
+ * - By ES module imports: import { aggregatorRegistry } from '@toolbox-web/grid'
51
+ * - By UMD/CDN: TbwGrid.aggregatorRegistry
52
+ * - By plugins via context: ctx.aggregatorRegistry
53
+ */
54
+ declare type AggregatorFn_2 = (rows: any[], field: string, column?: any) => any;
41
55
 
42
56
  /** Map of field names to aggregator references */
43
57
  declare type AggregatorMap = Record<string, AggregatorRef_2>;
44
58
 
59
+ /** Map of field names to aggregator references */
60
+ declare type AggregatorMap_2 = Record<string, AggregatorRef_2_2>;
61
+
45
62
  export declare type AggregatorRef = string | ((rows: any[], field: string, column?: any) => any);
46
63
 
47
- declare type AggregatorRef_2 = string | AggregatorFn;
64
+ declare type AggregatorRef_2 = string | AggregatorFn_2;
65
+
66
+ declare type AggregatorRef_2_2 = string | AggregatorFn;
48
67
 
49
68
  /** Aggregator reference - string key for built-in or custom function */
50
- declare type AggregatorRef_3 = string | ((rows: unknown[], field: string, column?: ColumnConfig) => unknown);
69
+ declare type AggregatorRef_3 = string | ((rows: unknown[], field: string, column?: ColumnConfig_2) => unknown);
70
+
71
+ /**
72
+ * The aggregator registry singleton.
73
+ * Plugins should access this through context or the global namespace.
74
+ */
75
+ export declare const aggregatorRegistry: {
76
+ /**
77
+ * Register a custom aggregator function.
78
+ */
79
+ register(name: string, fn: AggregatorFn): void;
80
+ /**
81
+ * Unregister a custom aggregator function.
82
+ */
83
+ unregister(name: string): void;
84
+ /**
85
+ * Get an aggregator function by reference.
86
+ */
87
+ get(ref: AggregatorRef_2_2 | undefined): AggregatorFn | undefined;
88
+ /**
89
+ * Run an aggregator on a set of rows.
90
+ */
91
+ run(ref: AggregatorRef_2_2 | undefined, rows: any[], field: string, column?: any): any;
92
+ /**
93
+ * Check if an aggregator exists.
94
+ */
95
+ has(name: string): boolean;
96
+ /**
97
+ * List all available aggregator names.
98
+ */
99
+ list(): string[];
100
+ };
51
101
 
52
102
  /**
53
103
  * Base contract for a column. Public; kept intentionally lean so host apps can extend via intersection types.
@@ -95,7 +145,570 @@ export declare interface BaseColumnConfig<TRow = any, TValue = any> {
95
145
  *
96
146
  * @template TConfig - Configuration type for the plugin
97
147
  */
98
- export declare abstract class BaseGridPlugin<TConfig = unknown> {
148
+ export declare abstract class BaseGridPlugin<TConfig = unknown> {
149
+ /** Unique plugin identifier (derived from class name by default) */
150
+ abstract readonly name: string;
151
+ /** Plugin version - override in subclass if needed */
152
+ readonly version: string;
153
+ /** CSS styles to inject into the grid's shadow DOM */
154
+ readonly styles?: string;
155
+ /** Custom cell renderers keyed by type name */
156
+ readonly cellRenderers?: Record<string, CellRenderer>;
157
+ /** Custom header renderers keyed by type name */
158
+ readonly headerRenderers?: Record<string, HeaderRenderer>;
159
+ /** Custom cell editors keyed by type name */
160
+ readonly cellEditors?: Record<string, CellEditor>;
161
+ /** The grid instance this plugin is attached to */
162
+ protected grid: GridElement;
163
+ /** Plugin configuration - merged with defaults in attach() */
164
+ protected config: TConfig;
165
+ /** User-provided configuration from constructor */
166
+ private readonly userConfig;
167
+ /**
168
+ * Default configuration - subclasses should override this getter.
169
+ * Note: This must be a getter (not property initializer) for proper inheritance
170
+ * since property initializers run after parent constructor.
171
+ */
172
+ protected get defaultConfig(): Partial<TConfig>;
173
+ constructor(config?: Partial<TConfig>);
174
+ /**
175
+ * Called when the plugin is attached to a grid.
176
+ * Override to set up event listeners, initialize state, etc.
177
+ */
178
+ attach(grid: GridElement): void;
179
+ /**
180
+ * Called when the plugin is detached from a grid.
181
+ * Override to clean up event listeners, timers, etc.
182
+ */
183
+ detach(): void;
184
+ /**
185
+ * Get another plugin instance from the same grid.
186
+ * Use for inter-plugin communication.
187
+ */
188
+ protected getPlugin<T extends BaseGridPlugin>(PluginClass: new (...args: any[]) => T): T | undefined;
189
+ /**
190
+ * Emit a custom event from the grid.
191
+ */
192
+ protected emit<T>(eventName: string, detail: T): void;
193
+ /**
194
+ * Request a re-render of the grid.
195
+ */
196
+ protected requestRender(): void;
197
+ /**
198
+ * Request a lightweight style update without rebuilding DOM.
199
+ * Use this instead of requestRender() when only CSS classes need updating.
200
+ */
201
+ protected requestAfterRender(): void;
202
+ /**
203
+ * Get the current rows from the grid.
204
+ */
205
+ protected get rows(): any[];
206
+ /**
207
+ * Get the original unfiltered/unprocessed rows from the grid.
208
+ * Use this when you need all source data regardless of active filters.
209
+ */
210
+ protected get sourceRows(): any[];
211
+ /**
212
+ * Get the current columns from the grid.
213
+ */
214
+ protected get columns(): ColumnConfig[];
215
+ /**
216
+ * Get only visible columns from the grid (excludes hidden).
217
+ * Use this for rendering that needs to match the grid template.
218
+ */
219
+ protected get visibleColumns(): ColumnConfig[];
220
+ /**
221
+ * Get the shadow root of the grid.
222
+ */
223
+ protected get shadowRoot(): ShadowRoot | null;
224
+ /**
225
+ * Get the disconnect signal for event listener cleanup.
226
+ * This signal is aborted when the grid disconnects from the DOM.
227
+ * Use this when adding event listeners that should be cleaned up automatically.
228
+ *
229
+ * Best for:
230
+ * - Document/window-level listeners added in attach()
231
+ * - Listeners on the grid element itself
232
+ * - Any listener that should persist across renders
233
+ *
234
+ * Not needed for:
235
+ * - Listeners on elements created in afterRender() (removed with element)
236
+ *
237
+ * @example
238
+ * element.addEventListener('click', handler, { signal: this.disconnectSignal });
239
+ * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
240
+ */
241
+ protected get disconnectSignal(): AbortSignal;
242
+ /**
243
+ * Get the grid-level icons configuration.
244
+ * Returns merged icons (user config + defaults).
245
+ */
246
+ protected get gridIcons(): typeof DEFAULT_GRID_ICONS;
247
+ /**
248
+ * Resolve an icon value to string or HTMLElement.
249
+ * Checks plugin config first, then grid-level icons, then defaults.
250
+ *
251
+ * @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
252
+ * @param pluginOverride - Optional plugin-level override
253
+ * @returns The resolved icon value
254
+ */
255
+ protected resolveIcon(iconKey: keyof typeof DEFAULT_GRID_ICONS, pluginOverride?: IconValue): IconValue;
256
+ /**
257
+ * Set an icon value on an element.
258
+ * Handles both string (text/HTML) and HTMLElement values.
259
+ *
260
+ * @param element - The element to set the icon on
261
+ * @param icon - The icon value (string or HTMLElement)
262
+ */
263
+ protected setIcon(element: HTMLElement, icon: IconValue): void;
264
+ /**
265
+ * Log a warning message.
266
+ */
267
+ protected warn(message: string): void;
268
+ /**
269
+ * Transform rows before rendering.
270
+ * Called during each render cycle before rows are rendered to the DOM.
271
+ * Use this to filter, sort, or add computed properties to rows.
272
+ *
273
+ * @param rows - The current rows array (readonly to encourage returning a new array)
274
+ * @returns The modified rows array to render
275
+ *
276
+ * @example
277
+ * ```ts
278
+ * processRows(rows: readonly any[]): any[] {
279
+ * // Filter out hidden rows
280
+ * return rows.filter(row => !row._hidden);
281
+ * }
282
+ * ```
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * processRows(rows: readonly any[]): any[] {
287
+ * // Add computed properties
288
+ * return rows.map(row => ({
289
+ * ...row,
290
+ * _fullName: `${row.firstName} ${row.lastName}`
291
+ * }));
292
+ * }
293
+ * ```
294
+ */
295
+ processRows?(rows: readonly any[]): any[];
296
+ /**
297
+ * Transform columns before rendering.
298
+ * Called during each render cycle before column headers and cells are rendered.
299
+ * Use this to add, remove, or modify column definitions.
300
+ *
301
+ * @param columns - The current columns array (readonly to encourage returning a new array)
302
+ * @returns The modified columns array to render
303
+ *
304
+ * @example
305
+ * ```ts
306
+ * processColumns(columns: readonly ColumnConfig[]): ColumnConfig[] {
307
+ * // Add a selection checkbox column
308
+ * return [
309
+ * { field: '_select', header: '', width: 40 },
310
+ * ...columns
311
+ * ];
312
+ * }
313
+ * ```
314
+ */
315
+ processColumns?(columns: readonly ColumnConfig[]): ColumnConfig[];
316
+ /**
317
+ * Called before each render cycle begins.
318
+ * Use this to prepare state or cache values needed during rendering.
319
+ *
320
+ * @example
321
+ * ```ts
322
+ * beforeRender(): void {
323
+ * this.visibleRowCount = this.calculateVisibleRows();
324
+ * }
325
+ * ```
326
+ */
327
+ beforeRender?(): void;
328
+ /**
329
+ * Called after each render cycle completes.
330
+ * Use this for DOM manipulation, adding event listeners to rendered elements,
331
+ * or applying visual effects like selection highlights.
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * afterRender(): void {
336
+ * // Apply selection styling to rendered rows
337
+ * const rows = this.shadowRoot?.querySelectorAll('.data-row');
338
+ * rows?.forEach((row, i) => {
339
+ * row.classList.toggle('selected', this.selectedRows.has(i));
340
+ * });
341
+ * }
342
+ * ```
343
+ */
344
+ afterRender?(): void;
345
+ /**
346
+ * Called after scroll-triggered row rendering completes.
347
+ * This is a lightweight hook for applying visual state to recycled DOM elements.
348
+ * Use this instead of afterRender when you need to reapply styling during scroll.
349
+ *
350
+ * Performance note: This is called frequently during scroll. Keep implementation fast.
351
+ *
352
+ * @example
353
+ * ```ts
354
+ * onScrollRender(): void {
355
+ * // Reapply selection state to visible cells
356
+ * this.applySelectionToVisibleCells();
357
+ * }
358
+ * ```
359
+ */
360
+ onScrollRender?(): void;
361
+ /**
362
+ * Return extra height contributed by this plugin (e.g., expanded detail rows).
363
+ * Used to adjust scrollbar height calculations for virtualization.
364
+ *
365
+ * @returns Total extra height in pixels
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * getExtraHeight(): number {
370
+ * return this.expandedRows.size * this.detailHeight;
371
+ * }
372
+ * ```
373
+ */
374
+ getExtraHeight?(): number;
375
+ /**
376
+ * Return extra height that appears before a given row index.
377
+ * Used by virtualization to correctly calculate scroll positions when
378
+ * there's variable height content (like expanded detail rows) above the viewport.
379
+ *
380
+ * @param beforeRowIndex - The row index to calculate extra height before
381
+ * @returns Extra height in pixels that appears before this row
382
+ *
383
+ * @example
384
+ * ```ts
385
+ * getExtraHeightBefore(beforeRowIndex: number): number {
386
+ * let height = 0;
387
+ * for (const expandedRowIndex of this.expandedRowIndices) {
388
+ * if (expandedRowIndex < beforeRowIndex) {
389
+ * height += this.getDetailHeight(expandedRowIndex);
390
+ * }
391
+ * }
392
+ * return height;
393
+ * }
394
+ * ```
395
+ */
396
+ getExtraHeightBefore?(beforeRowIndex: number): number;
397
+ /**
398
+ * Adjust the virtualization start index to render additional rows before the visible range.
399
+ * Use this when expanded content (like detail rows) needs its parent row to remain rendered
400
+ * even when the parent row itself has scrolled above the viewport.
401
+ *
402
+ * @param start - The calculated start row index
403
+ * @param scrollTop - The current scroll position
404
+ * @param rowHeight - The height of a single row
405
+ * @returns The adjusted start index (lower than or equal to original start)
406
+ *
407
+ * @example
408
+ * ```ts
409
+ * adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): number {
410
+ * // If row 5 is expanded and scrolled partially, keep it rendered
411
+ * for (const expandedRowIndex of this.expandedRowIndices) {
412
+ * const expandedRowTop = expandedRowIndex * rowHeight;
413
+ * const expandedRowBottom = expandedRowTop + rowHeight + this.detailHeight;
414
+ * if (expandedRowBottom > scrollTop && expandedRowIndex < start) {
415
+ * return expandedRowIndex;
416
+ * }
417
+ * }
418
+ * return start;
419
+ * }
420
+ * ```
421
+ */
422
+ adjustVirtualStart?(start: number, scrollTop: number, rowHeight: number): number;
423
+ /**
424
+ * Render a custom row, bypassing the default row rendering.
425
+ * Use this for special row types like group headers, detail rows, or footers.
426
+ *
427
+ * @param row - The row data object
428
+ * @param rowEl - The row DOM element to render into
429
+ * @param rowIndex - The index of the row in the data array
430
+ * @returns `true` if the plugin handled rendering (prevents default), `false`/`void` for default rendering
431
+ *
432
+ * @example
433
+ * ```ts
434
+ * renderRow(row: any, rowEl: HTMLElement, rowIndex: number): boolean | void {
435
+ * if (row._isGroupHeader) {
436
+ * rowEl.innerHTML = `<div class="group-header">${row._groupLabel}</div>`;
437
+ * return true; // Handled - skip default rendering
438
+ * }
439
+ * // Return void to let default rendering proceed
440
+ * }
441
+ * ```
442
+ */
443
+ renderRow?(row: any, rowEl: HTMLElement, rowIndex: number): boolean | void;
444
+ /**
445
+ * Handle keyboard events on the grid.
446
+ * Called when a key is pressed while the grid or a cell has focus.
447
+ *
448
+ * @param event - The native KeyboardEvent
449
+ * @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
450
+ *
451
+ * @example
452
+ * ```ts
453
+ * onKeyDown(event: KeyboardEvent): boolean | void {
454
+ * // Handle Ctrl+A for select all
455
+ * if (event.ctrlKey && event.key === 'a') {
456
+ * this.selectAllRows();
457
+ * return true; // Prevent default browser select-all
458
+ * }
459
+ * }
460
+ * ```
461
+ */
462
+ onKeyDown?(event: KeyboardEvent): boolean | void;
463
+ /**
464
+ * Handle cell click events.
465
+ * Called when a data cell is clicked (not headers).
466
+ *
467
+ * @param event - Cell click event with row/column context
468
+ * @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
469
+ *
470
+ * @example
471
+ * ```ts
472
+ * onCellClick(event: CellClickEvent): boolean | void {
473
+ * if (event.field === '_select') {
474
+ * this.toggleRowSelection(event.rowIndex);
475
+ * return true; // Handled
476
+ * }
477
+ * }
478
+ * ```
479
+ */
480
+ onCellClick?(event: CellClickEvent): boolean | void;
481
+ /**
482
+ * Handle row click events.
483
+ * Called when any part of a data row is clicked.
484
+ * Note: This is called in addition to onCellClick, not instead of.
485
+ *
486
+ * @param event - Row click event with row context
487
+ * @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
488
+ *
489
+ * @example
490
+ * ```ts
491
+ * onRowClick(event: RowClickEvent): boolean | void {
492
+ * if (this.config.mode === 'row') {
493
+ * this.selectRow(event.rowIndex, event.originalEvent);
494
+ * return true;
495
+ * }
496
+ * }
497
+ * ```
498
+ */
499
+ onRowClick?(event: RowClickEvent): boolean | void;
500
+ /**
501
+ * Handle header click events.
502
+ * Called when a column header is clicked. Commonly used for sorting.
503
+ *
504
+ * @param event - Header click event with column context
505
+ * @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
506
+ *
507
+ * @example
508
+ * ```ts
509
+ * onHeaderClick(event: HeaderClickEvent): boolean | void {
510
+ * if (event.column.sortable !== false) {
511
+ * this.toggleSort(event.field);
512
+ * return true;
513
+ * }
514
+ * }
515
+ * ```
516
+ */
517
+ onHeaderClick?(event: HeaderClickEvent): boolean | void;
518
+ /**
519
+ * Handle scroll events on the grid viewport.
520
+ * Called during scrolling. Note: This may be called frequently; debounce if needed.
521
+ *
522
+ * @param event - Scroll event with scroll position and viewport dimensions
523
+ *
524
+ * @example
525
+ * ```ts
526
+ * onScroll(event: ScrollEvent): void {
527
+ * // Update sticky column positions
528
+ * this.updateStickyPositions(event.scrollLeft);
529
+ * }
530
+ * ```
531
+ */
532
+ onScroll?(event: ScrollEvent): void;
533
+ /**
534
+ * Handle cell mousedown events.
535
+ * Used for initiating drag operations like range selection or column resize.
536
+ *
537
+ * @param event - Mouse event with cell context
538
+ * @returns `true` to indicate drag started (prevents text selection), `false`/`void` otherwise
539
+ *
540
+ * @example
541
+ * ```ts
542
+ * onCellMouseDown(event: CellMouseEvent): boolean | void {
543
+ * if (event.rowIndex !== undefined && this.config.mode === 'range') {
544
+ * this.startDragSelection(event.rowIndex, event.colIndex);
545
+ * return true; // Prevent text selection
546
+ * }
547
+ * }
548
+ * ```
549
+ */
550
+ onCellMouseDown?(event: CellMouseEvent): boolean | void;
551
+ /**
552
+ * Handle cell mousemove events during drag operations.
553
+ * Only called when a drag is in progress (after mousedown returned true).
554
+ *
555
+ * @param event - Mouse event with current cell context
556
+ * @returns `true` to continue handling the drag, `false`/`void` otherwise
557
+ *
558
+ * @example
559
+ * ```ts
560
+ * onCellMouseMove(event: CellMouseEvent): boolean | void {
561
+ * if (this.isDragging && event.rowIndex !== undefined) {
562
+ * this.extendSelection(event.rowIndex, event.colIndex);
563
+ * return true;
564
+ * }
565
+ * }
566
+ * ```
567
+ */
568
+ onCellMouseMove?(event: CellMouseEvent): boolean | void;
569
+ /**
570
+ * Handle cell mouseup events to end drag operations.
571
+ *
572
+ * @param event - Mouse event with final cell context
573
+ * @returns `true` if drag was finalized, `false`/`void` otherwise
574
+ *
575
+ * @example
576
+ * ```ts
577
+ * onCellMouseUp(event: CellMouseEvent): boolean | void {
578
+ * if (this.isDragging) {
579
+ * this.finalizeDragSelection();
580
+ * this.isDragging = false;
581
+ * return true;
582
+ * }
583
+ * }
584
+ * ```
585
+ */
586
+ onCellMouseUp?(event: CellMouseEvent): boolean | void;
587
+ /**
588
+ * Provide context menu items when right-clicking on the grid.
589
+ * Multiple plugins can contribute items; they are merged into a single menu.
590
+ *
591
+ * @param params - Context about where the menu was triggered (row, column, etc.)
592
+ * @returns Array of menu items to display
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * getContextMenuItems(params: ContextMenuParams): ContextMenuItem[] {
597
+ * if (params.isHeader) {
598
+ * return [
599
+ * { id: 'sort-asc', label: 'Sort Ascending', action: () => this.sortAsc(params.field) },
600
+ * { id: 'sort-desc', label: 'Sort Descending', action: () => this.sortDesc(params.field) },
601
+ * ];
602
+ * }
603
+ * return [
604
+ * { id: 'copy', label: 'Copy Cell', action: () => this.copyCell(params) },
605
+ * ];
606
+ * }
607
+ * ```
608
+ */
609
+ getContextMenuItems?(params: ContextMenuParams): ContextMenuItem[];
610
+ /**
611
+ * Contribute plugin-specific state for a column.
612
+ * Called by the grid when collecting column state for serialization.
613
+ * Plugins can add their own properties to the column state.
614
+ *
615
+ * @param field - The field name of the column
616
+ * @returns Partial column state with plugin-specific properties, or undefined if no state to contribute
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * getColumnState(field: string): Partial<ColumnState> | undefined {
621
+ * const filterModel = this.filterModels.get(field);
622
+ * if (filterModel) {
623
+ * // Uses module augmentation to add filter property to ColumnState
624
+ * return { filter: filterModel } as Partial<ColumnState>;
625
+ * }
626
+ * return undefined;
627
+ * }
628
+ * ```
629
+ */
630
+ getColumnState?(field: string): Partial<ColumnState> | undefined;
631
+ /**
632
+ * Apply plugin-specific state to a column.
633
+ * Called by the grid when restoring column state from serialized data.
634
+ * Plugins should restore their internal state based on the provided state.
635
+ *
636
+ * @param field - The field name of the column
637
+ * @param state - The column state to apply (may contain plugin-specific properties)
638
+ *
639
+ * @example
640
+ * ```ts
641
+ * applyColumnState(field: string, state: ColumnState): void {
642
+ * // Check for filter property added via module augmentation
643
+ * const filter = (state as any).filter;
644
+ * if (filter) {
645
+ * this.filterModels.set(field, filter);
646
+ * this.applyFilter();
647
+ * }
648
+ * }
649
+ * ```
650
+ */
651
+ applyColumnState?(field: string, state: ColumnState): void;
652
+ /**
653
+ * Register a tool panel for this plugin.
654
+ * Return undefined if plugin has no tool panel.
655
+ * The shell will create a toolbar toggle button and render the panel content
656
+ * when the user opens the panel.
657
+ *
658
+ * @returns Tool panel definition, or undefined if plugin has no panel
659
+ *
660
+ * @example
661
+ * ```ts
662
+ * getToolPanel(): ToolPanelDefinition | undefined {
663
+ * return {
664
+ * id: 'columns',
665
+ * title: 'Columns',
666
+ * icon: '☰',
667
+ * tooltip: 'Show/hide columns',
668
+ * order: 10,
669
+ * render: (container) => {
670
+ * this.renderColumnList(container);
671
+ * return () => this.cleanup();
672
+ * },
673
+ * };
674
+ * }
675
+ * ```
676
+ */
677
+ getToolPanel?(): ToolPanelDefinition | undefined;
678
+ /**
679
+ * Register content for the shell header center section.
680
+ * Return undefined if plugin has no header content.
681
+ * Examples: search input, selection summary, status indicators.
682
+ *
683
+ * @returns Header content definition, or undefined if plugin has no header content
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * getHeaderContent(): HeaderContentDefinition | undefined {
688
+ * return {
689
+ * id: 'quick-filter',
690
+ * order: 10,
691
+ * render: (container) => {
692
+ * const input = document.createElement('input');
693
+ * input.type = 'text';
694
+ * input.placeholder = 'Search...';
695
+ * input.addEventListener('input', this.handleInput);
696
+ * container.appendChild(input);
697
+ * return () => input.removeEventListener('input', this.handleInput);
698
+ * },
699
+ * };
700
+ * }
701
+ * ```
702
+ */
703
+ getHeaderContent?(): HeaderContentDefinition | undefined;
704
+ }
705
+
706
+ /**
707
+ * Abstract base class for all grid plugins.
708
+ *
709
+ * @template TConfig - Configuration type for the plugin
710
+ */
711
+ declare abstract class BaseGridPlugin_2<TConfig = unknown> {
99
712
  /** Unique plugin identifier (derived from class name by default) */
100
713
  abstract readonly name: string;
101
714
  /** Plugin version - override in subclass if needed */
@@ -103,11 +716,11 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
103
716
  /** CSS styles to inject into the grid's shadow DOM */
104
717
  readonly styles?: string;
105
718
  /** Custom cell renderers keyed by type name */
106
- readonly cellRenderers?: Record<string, CellRenderer>;
719
+ readonly cellRenderers?: Record<string, CellRenderer_2>;
107
720
  /** Custom header renderers keyed by type name */
108
- readonly headerRenderers?: Record<string, HeaderRenderer>;
721
+ readonly headerRenderers?: Record<string, HeaderRenderer_2>;
109
722
  /** Custom cell editors keyed by type name */
110
- readonly cellEditors?: Record<string, CellEditor>;
723
+ readonly cellEditors?: Record<string, CellEditor_2>;
111
724
  /** The grid instance this plugin is attached to */
112
725
  protected grid: GridElement_2;
113
726
  /** Plugin configuration - merged with defaults in attach() */
@@ -135,7 +748,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
135
748
  * Get another plugin instance from the same grid.
136
749
  * Use for inter-plugin communication.
137
750
  */
138
- protected getPlugin<T extends BaseGridPlugin>(PluginClass: new (...args: any[]) => T): T | undefined;
751
+ protected getPlugin<T extends BaseGridPlugin_2>(PluginClass: new (...args: any[]) => T): T | undefined;
139
752
  /**
140
753
  * Emit a custom event from the grid.
141
754
  */
@@ -161,16 +774,56 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
161
774
  /**
162
775
  * Get the current columns from the grid.
163
776
  */
164
- protected get columns(): ColumnConfig[];
777
+ protected get columns(): ColumnConfig_2[];
165
778
  /**
166
779
  * Get only visible columns from the grid (excludes hidden).
167
780
  * Use this for rendering that needs to match the grid template.
168
781
  */
169
- protected get visibleColumns(): ColumnConfig[];
782
+ protected get visibleColumns(): ColumnConfig_2[];
170
783
  /**
171
784
  * Get the shadow root of the grid.
172
785
  */
173
786
  protected get shadowRoot(): ShadowRoot | null;
787
+ /**
788
+ * Get the disconnect signal for event listener cleanup.
789
+ * This signal is aborted when the grid disconnects from the DOM.
790
+ * Use this when adding event listeners that should be cleaned up automatically.
791
+ *
792
+ * Best for:
793
+ * - Document/window-level listeners added in attach()
794
+ * - Listeners on the grid element itself
795
+ * - Any listener that should persist across renders
796
+ *
797
+ * Not needed for:
798
+ * - Listeners on elements created in afterRender() (removed with element)
799
+ *
800
+ * @example
801
+ * element.addEventListener('click', handler, { signal: this.disconnectSignal });
802
+ * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
803
+ */
804
+ protected get disconnectSignal(): AbortSignal;
805
+ /**
806
+ * Get the grid-level icons configuration.
807
+ * Returns merged icons (user config + defaults).
808
+ */
809
+ protected get gridIcons(): typeof DEFAULT_GRID_ICONS_2;
810
+ /**
811
+ * Resolve an icon value to string or HTMLElement.
812
+ * Checks plugin config first, then grid-level icons, then defaults.
813
+ *
814
+ * @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
815
+ * @param pluginOverride - Optional plugin-level override
816
+ * @returns The resolved icon value
817
+ */
818
+ protected resolveIcon(iconKey: keyof typeof DEFAULT_GRID_ICONS_2, pluginOverride?: IconValue_2): IconValue_2;
819
+ /**
820
+ * Set an icon value on an element.
821
+ * Handles both string (text/HTML) and HTMLElement values.
822
+ *
823
+ * @param element - The element to set the icon on
824
+ * @param icon - The icon value (string or HTMLElement)
825
+ */
826
+ protected setIcon(element: HTMLElement, icon: IconValue_2): void;
174
827
  /**
175
828
  * Log a warning message.
176
829
  */
@@ -222,7 +875,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
222
875
  * }
223
876
  * ```
224
877
  */
225
- processColumns?(columns: readonly ColumnConfig[]): ColumnConfig[];
878
+ processColumns?(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
226
879
  /**
227
880
  * Called before each render cycle begins.
228
881
  * Use this to prepare state or cache values needed during rendering.
@@ -268,6 +921,68 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
268
921
  * ```
269
922
  */
270
923
  onScrollRender?(): void;
924
+ /**
925
+ * Return extra height contributed by this plugin (e.g., expanded detail rows).
926
+ * Used to adjust scrollbar height calculations for virtualization.
927
+ *
928
+ * @returns Total extra height in pixels
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * getExtraHeight(): number {
933
+ * return this.expandedRows.size * this.detailHeight;
934
+ * }
935
+ * ```
936
+ */
937
+ getExtraHeight?(): number;
938
+ /**
939
+ * Return extra height that appears before a given row index.
940
+ * Used by virtualization to correctly calculate scroll positions when
941
+ * there's variable height content (like expanded detail rows) above the viewport.
942
+ *
943
+ * @param beforeRowIndex - The row index to calculate extra height before
944
+ * @returns Extra height in pixels that appears before this row
945
+ *
946
+ * @example
947
+ * ```ts
948
+ * getExtraHeightBefore(beforeRowIndex: number): number {
949
+ * let height = 0;
950
+ * for (const expandedRowIndex of this.expandedRowIndices) {
951
+ * if (expandedRowIndex < beforeRowIndex) {
952
+ * height += this.getDetailHeight(expandedRowIndex);
953
+ * }
954
+ * }
955
+ * return height;
956
+ * }
957
+ * ```
958
+ */
959
+ getExtraHeightBefore?(beforeRowIndex: number): number;
960
+ /**
961
+ * Adjust the virtualization start index to render additional rows before the visible range.
962
+ * Use this when expanded content (like detail rows) needs its parent row to remain rendered
963
+ * even when the parent row itself has scrolled above the viewport.
964
+ *
965
+ * @param start - The calculated start row index
966
+ * @param scrollTop - The current scroll position
967
+ * @param rowHeight - The height of a single row
968
+ * @returns The adjusted start index (lower than or equal to original start)
969
+ *
970
+ * @example
971
+ * ```ts
972
+ * adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): number {
973
+ * // If row 5 is expanded and scrolled partially, keep it rendered
974
+ * for (const expandedRowIndex of this.expandedRowIndices) {
975
+ * const expandedRowTop = expandedRowIndex * rowHeight;
976
+ * const expandedRowBottom = expandedRowTop + rowHeight + this.detailHeight;
977
+ * if (expandedRowBottom > scrollTop && expandedRowIndex < start) {
978
+ * return expandedRowIndex;
979
+ * }
980
+ * }
981
+ * return start;
982
+ * }
983
+ * ```
984
+ */
985
+ adjustVirtualStart?(start: number, scrollTop: number, rowHeight: number): number;
271
986
  /**
272
987
  * Render a custom row, bypassing the default row rendering.
273
988
  * Use this for special row types like group headers, detail rows, or footers.
@@ -325,7 +1040,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
325
1040
  * }
326
1041
  * ```
327
1042
  */
328
- onCellClick?(event: CellClickEvent): boolean | void;
1043
+ onCellClick?(event: CellClickEvent_2): boolean | void;
329
1044
  /**
330
1045
  * Handle row click events.
331
1046
  * Called when any part of a data row is clicked.
@@ -344,7 +1059,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
344
1059
  * }
345
1060
  * ```
346
1061
  */
347
- onRowClick?(event: RowClickEvent): boolean | void;
1062
+ onRowClick?(event: RowClickEvent_2): boolean | void;
348
1063
  /**
349
1064
  * Handle header click events.
350
1065
  * Called when a column header is clicked. Commonly used for sorting.
@@ -362,7 +1077,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
362
1077
  * }
363
1078
  * ```
364
1079
  */
365
- onHeaderClick?(event: HeaderClickEvent): boolean | void;
1080
+ onHeaderClick?(event: HeaderClickEvent_2): boolean | void;
366
1081
  /**
367
1082
  * Handle scroll events on the grid viewport.
368
1083
  * Called during scrolling. Note: This may be called frequently; debounce if needed.
@@ -377,7 +1092,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
377
1092
  * }
378
1093
  * ```
379
1094
  */
380
- onScroll?(event: ScrollEvent): void;
1095
+ onScroll?(event: ScrollEvent_2): void;
381
1096
  /**
382
1097
  * Handle cell mousedown events.
383
1098
  * Used for initiating drag operations like range selection or column resize.
@@ -395,7 +1110,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
395
1110
  * }
396
1111
  * ```
397
1112
  */
398
- onCellMouseDown?(event: CellMouseEvent): boolean | void;
1113
+ onCellMouseDown?(event: CellMouseEvent_2): boolean | void;
399
1114
  /**
400
1115
  * Handle cell mousemove events during drag operations.
401
1116
  * Only called when a drag is in progress (after mousedown returned true).
@@ -413,7 +1128,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
413
1128
  * }
414
1129
  * ```
415
1130
  */
416
- onCellMouseMove?(event: CellMouseEvent): boolean | void;
1131
+ onCellMouseMove?(event: CellMouseEvent_2): boolean | void;
417
1132
  /**
418
1133
  * Handle cell mouseup events to end drag operations.
419
1134
  *
@@ -431,7 +1146,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
431
1146
  * }
432
1147
  * ```
433
1148
  */
434
- onCellMouseUp?(event: CellMouseEvent): boolean | void;
1149
+ onCellMouseUp?(event: CellMouseEvent_2): boolean | void;
435
1150
  /**
436
1151
  * Provide context menu items when right-clicking on the grid.
437
1152
  * Multiple plugins can contribute items; they are merged into a single menu.
@@ -454,7 +1169,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
454
1169
  * }
455
1170
  * ```
456
1171
  */
457
- getContextMenuItems?(params: ContextMenuParams): ContextMenuItem[];
1172
+ getContextMenuItems?(params: ContextMenuParams_2): ContextMenuItem_2[];
458
1173
  /**
459
1174
  * Contribute plugin-specific state for a column.
460
1175
  * Called by the grid when collecting column state for serialization.
@@ -475,7 +1190,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
475
1190
  * }
476
1191
  * ```
477
1192
  */
478
- getColumnState?(field: string): Partial<ColumnState> | undefined;
1193
+ getColumnState?(field: string): Partial<ColumnState_2> | undefined;
479
1194
  /**
480
1195
  * Apply plugin-specific state to a column.
481
1196
  * Called by the grid when restoring column state from serialized data.
@@ -496,7 +1211,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
496
1211
  * }
497
1212
  * ```
498
1213
  */
499
- applyColumnState?(field: string, state: ColumnState): void;
1214
+ applyColumnState?(field: string, state: ColumnState_2): void;
500
1215
  /**
501
1216
  * Register a tool panel for this plugin.
502
1217
  * Return undefined if plugin has no tool panel.
@@ -522,7 +1237,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
522
1237
  * }
523
1238
  * ```
524
1239
  */
525
- getToolPanel?(): ToolPanelDefinition | undefined;
1240
+ getToolPanel?(): ToolPanelDefinition_2 | undefined;
526
1241
  /**
527
1242
  * Register content for the shell header center section.
528
1243
  * Return undefined if plugin has no header content.
@@ -548,13 +1263,26 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> {
548
1263
  * }
549
1264
  * ```
550
1265
  */
551
- getHeaderContent?(): HeaderContentDefinition | undefined;
1266
+ getHeaderContent?(): HeaderContentDefinition_2 | undefined;
1267
+ }
1268
+
1269
+ /**
1270
+ * Cell click event
1271
+ */
1272
+ export declare interface CellClickEvent {
1273
+ rowIndex: number;
1274
+ colIndex: number;
1275
+ field: string;
1276
+ value: any;
1277
+ row: any;
1278
+ cellEl: HTMLElement;
1279
+ originalEvent: MouseEvent;
552
1280
  }
553
1281
 
554
1282
  /**
555
1283
  * Cell click event
556
1284
  */
557
- declare interface CellClickEvent {
1285
+ declare interface CellClickEvent_2 {
558
1286
  rowIndex: number;
559
1287
  colIndex: number;
560
1288
  field: string;
@@ -594,7 +1322,15 @@ declare interface CellContext<T = any> {
594
1322
  /**
595
1323
  * Cell coordinates
596
1324
  */
597
- declare interface CellCoords {
1325
+ export declare interface CellCoords {
1326
+ row: number;
1327
+ col: number;
1328
+ }
1329
+
1330
+ /**
1331
+ * Cell coordinates
1332
+ */
1333
+ declare interface CellCoords_2 {
598
1334
  row: number;
599
1335
  col: number;
600
1336
  }
@@ -602,16 +1338,25 @@ declare interface CellCoords {
602
1338
  /**
603
1339
  * Cell editor interface for plugins.
604
1340
  */
605
- declare interface CellEditor {
1341
+ export declare interface CellEditor {
606
1342
  create(ctx: PluginCellRenderContext, commitFn: (value: any) => void, cancelFn: () => void): HTMLElement;
607
1343
  getValue?(element: HTMLElement): any;
608
1344
  focus?(element: HTMLElement): void;
609
1345
  }
610
1346
 
1347
+ /**
1348
+ * Cell editor interface for plugins.
1349
+ */
1350
+ declare interface CellEditor_2 {
1351
+ create(ctx: PluginCellRenderContext_2, commitFn: (value: any) => void, cancelFn: () => void): HTMLElement;
1352
+ getValue?(element: HTMLElement): any;
1353
+ focus?(element: HTMLElement): void;
1354
+ }
1355
+
611
1356
  /**
612
1357
  * Cell mouse event (for drag operations, selection, etc.)
613
1358
  */
614
- declare interface CellMouseEvent {
1359
+ export declare interface CellMouseEvent {
615
1360
  /** Event type: mousedown, mousemove, or mouseup */
616
1361
  type: 'mousedown' | 'mousemove' | 'mouseup';
617
1362
  /** Row index, undefined if not over a data cell */
@@ -638,6 +1383,36 @@ declare interface CellMouseEvent {
638
1383
  originalEvent: MouseEvent;
639
1384
  }
640
1385
 
1386
+ /**
1387
+ * Cell mouse event (for drag operations, selection, etc.)
1388
+ */
1389
+ declare interface CellMouseEvent_2 {
1390
+ /** Event type: mousedown, mousemove, or mouseup */
1391
+ type: 'mousedown' | 'mousemove' | 'mouseup';
1392
+ /** Row index, undefined if not over a data cell */
1393
+ rowIndex?: number;
1394
+ /** Column index, undefined if not over a cell */
1395
+ colIndex?: number;
1396
+ /** Field name, undefined if not over a cell */
1397
+ field?: string;
1398
+ /** Cell value, undefined if not over a data cell */
1399
+ value?: unknown;
1400
+ /** Row data object, undefined if not over a data row */
1401
+ row?: unknown;
1402
+ /** Column configuration, undefined if not over a column */
1403
+ column?: ColumnConfig_2;
1404
+ /** The cell element, undefined if not over a cell */
1405
+ cellElement?: HTMLElement;
1406
+ /** The row element, undefined if not over a row */
1407
+ rowElement?: HTMLElement;
1408
+ /** Whether the event is over a header cell */
1409
+ isHeader: boolean;
1410
+ /** Cell coordinates if over a valid data cell */
1411
+ cell?: CellCoords_2;
1412
+ /** The original mouse event */
1413
+ originalEvent: MouseEvent;
1414
+ }
1415
+
641
1416
  /** Public representation of a cell range (for events) */
642
1417
  export declare interface CellRange {
643
1418
  /** Starting cell coordinates */
@@ -652,6 +1427,20 @@ export declare interface CellRange {
652
1427
  };
653
1428
  }
654
1429
 
1430
+ /** Public representation of a cell range (for events) */
1431
+ declare interface CellRange_2 {
1432
+ /** Starting cell coordinates */
1433
+ from: {
1434
+ row: number;
1435
+ col: number;
1436
+ };
1437
+ /** Ending cell coordinates */
1438
+ to: {
1439
+ row: number;
1440
+ col: number;
1441
+ };
1442
+ }
1443
+
655
1444
  /**
656
1445
  * Context passed to custom view renderers (pure display – no commit helpers).
657
1446
  */
@@ -666,10 +1455,29 @@ export declare interface CellRenderContext<TRow = any, TValue = any> {
666
1455
  column: ColumnConfig<TRow>;
667
1456
  }
668
1457
 
1458
+ /**
1459
+ * Context passed to custom view renderers (pure display – no commit helpers).
1460
+ */
1461
+ declare interface CellRenderContext_2<TRow = any, TValue = any> {
1462
+ /** Row object for the cell being rendered. */
1463
+ row: TRow;
1464
+ /** Value at field. */
1465
+ value: TValue;
1466
+ /** Field key. */
1467
+ field: keyof TRow & string;
1468
+ /** Column configuration reference. */
1469
+ column: ColumnConfig_2<TRow>;
1470
+ }
1471
+
669
1472
  /**
670
1473
  * Cell renderer function type for plugins.
671
1474
  */
672
- declare type CellRenderer = (ctx: PluginCellRenderContext) => string | HTMLElement;
1475
+ export declare type CellRenderer = (ctx: PluginCellRenderContext) => string | HTMLElement;
1476
+
1477
+ /**
1478
+ * Cell renderer function type for plugins.
1479
+ */
1480
+ declare type CellRenderer_2 = (ctx: PluginCellRenderContext_2) => string | HTMLElement;
673
1481
 
674
1482
  /** Emitted when the changed rows tracking set is cleared programmatically. */
675
1483
  export declare interface ChangedRowsResetDetail<TRow = any> {
@@ -708,7 +1516,7 @@ declare interface ClipboardConfig {
708
1516
  * new ClipboardPlugin({ includeHeaders: true })
709
1517
  * ```
710
1518
  */
711
- export declare class ClipboardPlugin extends BaseGridPlugin<ClipboardConfig> {
1519
+ export declare class ClipboardPlugin extends BaseGridPlugin_2<ClipboardConfig> {
712
1520
  #private;
713
1521
  readonly name = "clipboard";
714
1522
  readonly version = "1.0.0";
@@ -767,6 +1575,30 @@ export declare interface ColumnConfig<TRow = any> extends BaseColumnConfig<TRow,
767
1575
  lockVisible?: boolean;
768
1576
  }
769
1577
 
1578
+ /**
1579
+ * Full column configuration including optional custom view/renderer & grouping metadata.
1580
+ */
1581
+ declare interface ColumnConfig_2<TRow = any> extends BaseColumnConfig<TRow, any> {
1582
+ /** Optional custom view renderer used instead of default text rendering */
1583
+ viewRenderer?: ColumnViewRenderer_2<TRow, any>;
1584
+ /** External view spec (lets host app mount any framework component) */
1585
+ externalView?: {
1586
+ component: any;
1587
+ props?: Record<string, any>;
1588
+ mount?: (options: {
1589
+ placeholder: HTMLElement;
1590
+ context: CellRenderContext_2<TRow, any>;
1591
+ spec: any;
1592
+ }) => void | {
1593
+ dispose?: () => void;
1594
+ };
1595
+ };
1596
+ /** Whether the column is initially hidden */
1597
+ hidden?: boolean;
1598
+ /** Prevent this column from being hidden by the visibility plugin */
1599
+ lockVisible?: boolean;
1600
+ }
1601
+
770
1602
  export declare type ColumnConfigMap<TRow = any> = ColumnConfig<TRow>[];
771
1603
 
772
1604
  /**
@@ -810,7 +1642,7 @@ declare interface ColumnGroup<T = any> {
810
1642
  /** Display label for the group header */
811
1643
  label?: string;
812
1644
  /** Columns belonging to this group */
813
- columns: ColumnConfig<T>[];
1645
+ columns: ColumnConfig_2<T>[];
814
1646
  /** Index of first column in this group */
815
1647
  firstIndex: number;
816
1648
  }
@@ -844,6 +1676,16 @@ export declare interface ColumnSortState {
844
1676
  priority: number;
845
1677
  }
846
1678
 
1679
+ /**
1680
+ * Sort state for a column
1681
+ */
1682
+ declare interface ColumnSortState_2 {
1683
+ /** Sort direction */
1684
+ direction: 'asc' | 'desc';
1685
+ /** Priority for multi-sort (0 = primary, 1 = secondary, etc.) */
1686
+ priority: number;
1687
+ }
1688
+
847
1689
  /**
848
1690
  * State for a single column. Captures user-driven changes at runtime.
849
1691
  * Plugins can extend this interface via module augmentation to add their own state.
@@ -871,8 +1713,37 @@ export declare interface ColumnState {
871
1713
  sort?: ColumnSortState;
872
1714
  }
873
1715
 
1716
+ /**
1717
+ * State for a single column. Captures user-driven changes at runtime.
1718
+ * Plugins can extend this interface via module augmentation to add their own state.
1719
+ *
1720
+ * @example
1721
+ * ```ts
1722
+ * // In filtering plugin
1723
+ * declare module '@toolbox-web/grid' {
1724
+ * interface ColumnState {
1725
+ * filter?: FilterValue;
1726
+ * }
1727
+ * }
1728
+ * ```
1729
+ */
1730
+ declare interface ColumnState {
1731
+ /** Column field identifier */
1732
+ field: string;
1733
+ /** Position index after reordering (0-based) */
1734
+ order: number;
1735
+ /** Width in pixels (undefined = use default) */
1736
+ width?: number;
1737
+ /** Visibility state */
1738
+ visible: boolean;
1739
+ /** Sort state (undefined = not sorted) */
1740
+ sort?: ColumnSortState_2;
1741
+ }
1742
+
874
1743
  export declare type ColumnViewRenderer<TRow = any, TValue = any> = (ctx: CellRenderContext<TRow, TValue>) => Node | string | void;
875
1744
 
1745
+ declare type ColumnViewRenderer_2<TRow = any, TValue = any> = (ctx: CellRenderContext_2<TRow, TValue>) => Node | string | void;
1746
+
876
1747
  /**
877
1748
  * Column Virtualization Plugin Types
878
1749
  *
@@ -898,7 +1769,7 @@ declare interface ColumnVirtualizationConfig {
898
1769
  * new ColumnVirtualizationPlugin({ threshold: 30, overscan: 3 })
899
1770
  * ```
900
1771
  */
901
- export declare class ColumnVirtualizationPlugin extends BaseGridPlugin<ColumnVirtualizationConfig> {
1772
+ export declare class ColumnVirtualizationPlugin extends BaseGridPlugin_2<ColumnVirtualizationConfig> {
902
1773
  readonly name = "columnVirtualization";
903
1774
  readonly version = "1.0.0";
904
1775
  protected get defaultConfig(): Partial<ColumnVirtualizationConfig>;
@@ -911,9 +1782,9 @@ export declare class ColumnVirtualizationPlugin extends BaseGridPlugin<ColumnVir
911
1782
  private columnOffsets;
912
1783
  attach(grid: GridElement_2): void;
913
1784
  detach(): void;
914
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
1785
+ processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
915
1786
  afterRender(): void;
916
- onScroll(event: ScrollEvent): void;
1787
+ onScroll(event: ScrollEvent_2): void;
917
1788
  /**
918
1789
  * Check if column virtualization is currently active.
919
1790
  */
@@ -948,20 +1819,33 @@ declare interface ContextMenuConfig {
948
1819
  /** Whether the context menu is enabled (default: true) */
949
1820
  enabled?: boolean;
950
1821
  /** Menu items - static array or function returning items */
951
- items?: ContextMenuItem_2[] | ((params: ContextMenuParams_2) => ContextMenuItem_2[]);
1822
+ items?: ContextMenuItem_3[] | ((params: ContextMenuParams_3) => ContextMenuItem_3[]);
1823
+ }
1824
+
1825
+ /**
1826
+ * Context menu item
1827
+ */
1828
+ export declare interface ContextMenuItem {
1829
+ id: string;
1830
+ label: string;
1831
+ icon?: string;
1832
+ disabled?: boolean;
1833
+ separator?: boolean;
1834
+ children?: ContextMenuItem[];
1835
+ action?: (params: ContextMenuParams) => void;
952
1836
  }
953
1837
 
954
1838
  /**
955
1839
  * Context menu item
956
1840
  */
957
- declare interface ContextMenuItem {
1841
+ declare interface ContextMenuItem_2 {
958
1842
  id: string;
959
1843
  label: string;
960
1844
  icon?: string;
961
1845
  disabled?: boolean;
962
1846
  separator?: boolean;
963
- children?: ContextMenuItem[];
964
- action?: (params: ContextMenuParams) => void;
1847
+ children?: ContextMenuItem_2[];
1848
+ action?: (params: ContextMenuParams_2) => void;
965
1849
  }
966
1850
 
967
1851
  /**
@@ -973,7 +1857,7 @@ declare interface ContextMenuItem {
973
1857
  * Context menu item definition.
974
1858
  * Supports icons, shortcuts, submenus, separators, and dynamic disabled/hidden states.
975
1859
  */
976
- declare interface ContextMenuItem_2 {
1860
+ declare interface ContextMenuItem_3 {
977
1861
  /** Unique identifier for the menu item */
978
1862
  id: string;
979
1863
  /** Display label for the menu item */
@@ -983,13 +1867,13 @@ declare interface ContextMenuItem_2 {
983
1867
  /** Optional keyboard shortcut hint (display only) */
984
1868
  shortcut?: string;
985
1869
  /** Whether the item is disabled (static or dynamic) */
986
- disabled?: boolean | ((params: ContextMenuParams_2) => boolean);
1870
+ disabled?: boolean | ((params: ContextMenuParams_3) => boolean);
987
1871
  /** Whether the item is hidden (static or dynamic) */
988
- hidden?: boolean | ((params: ContextMenuParams_2) => boolean);
1872
+ hidden?: boolean | ((params: ContextMenuParams_3) => boolean);
989
1873
  /** Action handler when the item is clicked */
990
- action?: (params: ContextMenuParams_2) => void;
1874
+ action?: (params: ContextMenuParams_3) => void;
991
1875
  /** Nested submenu items */
992
- subMenu?: ContextMenuItem_2[];
1876
+ subMenu?: ContextMenuItem_3[];
993
1877
  /** Whether this is a separator (id and name required but ignored) */
994
1878
  separator?: boolean;
995
1879
  /** Optional CSS class to add to the menu item */
@@ -999,7 +1883,7 @@ declare interface ContextMenuItem_2 {
999
1883
  /**
1000
1884
  * Context menu parameters
1001
1885
  */
1002
- declare interface ContextMenuParams {
1886
+ export declare interface ContextMenuParams {
1003
1887
  x: number;
1004
1888
  y: number;
1005
1889
  rowIndex?: number;
@@ -1011,11 +1895,26 @@ declare interface ContextMenuParams {
1011
1895
  isHeader?: boolean;
1012
1896
  }
1013
1897
 
1898
+ /**
1899
+ * Context menu parameters
1900
+ */
1901
+ declare interface ContextMenuParams_2 {
1902
+ x: number;
1903
+ y: number;
1904
+ rowIndex?: number;
1905
+ colIndex?: number;
1906
+ field?: string;
1907
+ value?: any;
1908
+ row?: any;
1909
+ column?: ColumnConfig_2;
1910
+ isHeader?: boolean;
1911
+ }
1912
+
1014
1913
  /**
1015
1914
  * Parameters passed to context menu callbacks.
1016
1915
  * Provides context about what element triggered the menu.
1017
1916
  */
1018
- declare interface ContextMenuParams_2 {
1917
+ declare interface ContextMenuParams_3 {
1019
1918
  /** The row data object (null for header clicks) */
1020
1919
  row: unknown;
1021
1920
  /** The row index (-1 for header clicks) */
@@ -1049,7 +1948,7 @@ declare interface ContextMenuParams_2 {
1049
1948
  * })
1050
1949
  * ```
1051
1950
  */
1052
- export declare class ContextMenuPlugin extends BaseGridPlugin<ContextMenuConfig> {
1951
+ export declare class ContextMenuPlugin extends BaseGridPlugin_2<ContextMenuConfig> {
1053
1952
  readonly name = "contextMenu";
1054
1953
  readonly version = "1.0.0";
1055
1954
  protected get defaultConfig(): Partial<ContextMenuConfig>;
@@ -1067,7 +1966,7 @@ export declare class ContextMenuPlugin extends BaseGridPlugin<ContextMenuConfig>
1067
1966
  * @param y - Y coordinate
1068
1967
  * @param params - Partial context menu parameters
1069
1968
  */
1070
- showMenu(x: number, y: number, params: Partial<ContextMenuParams_2>): void;
1969
+ showMenu(x: number, y: number, params: Partial<ContextMenuParams_3>): void;
1071
1970
  /**
1072
1971
  * Hide the context menu.
1073
1972
  */
@@ -1128,7 +2027,7 @@ export declare type DataGridCustomEvent<K extends keyof DataGridEventMap<any>, T
1128
2027
  * @cssprop --tbw-color-bg - Background color
1129
2028
  * @cssprop --tbw-color-fg - Foreground/text color
1130
2029
  */
1131
- declare class DataGridElement<T = any> extends HTMLElement implements InternalGrid<T> {
2030
+ export declare class DataGridElement<T = any> extends HTMLElement implements InternalGrid<T> {
1132
2031
  #private;
1133
2032
  static readonly tagName = "tbw-grid";
1134
2033
  _rows: T[];
@@ -1171,6 +2070,14 @@ declare class DataGridElement<T = any> extends HTMLElement implements InternalGr
1171
2070
  get editOn(): string | undefined;
1172
2071
  set editOn(value: string | undefined);
1173
2072
  get effectiveConfig(): GridConfig<T>;
2073
+ /**
2074
+ * Get the disconnect signal for event listener cleanup.
2075
+ * This signal is aborted when the grid disconnects from the DOM.
2076
+ * Plugins and internal code can use this for automatic listener cleanup.
2077
+ * @example
2078
+ * element.addEventListener('click', handler, { signal: this.grid.disconnectSignal });
2079
+ */
2080
+ get disconnectSignal(): AbortSignal;
1174
2081
  constructor();
1175
2082
  /**
1176
2083
  * Get a plugin instance by its class.
@@ -1368,8 +2275,6 @@ declare class DataGridElement<T = any> extends HTMLElement implements InternalGr
1368
2275
  */
1369
2276
  refreshVirtualWindow(force?: boolean): void;
1370
2277
  }
1371
- export { DataGridElement }
1372
- export { DataGridElement as GridElement }
1373
2278
 
1374
2279
  /**
1375
2280
  * The compiled webcomponent interface for DataGrid
@@ -1396,6 +2301,12 @@ declare interface DataRowModelItem {
1396
2301
  rowIndex: number;
1397
2302
  }
1398
2303
 
2304
+ /** Default icons used when not overridden */
2305
+ export declare const DEFAULT_GRID_ICONS: Required<GridIcons>;
2306
+
2307
+ /** Default icons used when not overridden */
2308
+ declare const DEFAULT_GRID_ICONS_2: Required<GridIcons_2>;
2309
+
1399
2310
  export declare type DGEventName = (typeof DGEvents)[keyof typeof DGEvents];
1400
2311
 
1401
2312
  export declare const DGEvents: {
@@ -1427,6 +2338,22 @@ export declare interface EditAction {
1427
2338
  timestamp: number;
1428
2339
  }
1429
2340
 
2341
+ /** Represents a single edit action that can be undone/redone */
2342
+ declare interface EditAction_2 {
2343
+ /** Type of action - currently only 'cell-edit' is supported */
2344
+ type: 'cell-edit';
2345
+ /** The row index where the edit occurred */
2346
+ rowIndex: number;
2347
+ /** The field (column key) that was edited */
2348
+ field: string;
2349
+ /** The value before the edit */
2350
+ oldValue: unknown;
2351
+ /** The value after the edit */
2352
+ newValue: unknown;
2353
+ /** Unix timestamp when the edit occurred */
2354
+ timestamp: number;
2355
+ }
2356
+
1430
2357
  /**
1431
2358
  * Internal editor execution context extending the generic cell context with commit helpers.
1432
2359
  */
@@ -1457,6 +2384,14 @@ declare interface ExportConfig {
1457
2384
  /** Supported export formats */
1458
2385
  export declare type ExportFormat = 'csv' | 'excel' | 'json';
1459
2386
 
2387
+ /**
2388
+ * Export Plugin Types
2389
+ *
2390
+ * Type definitions for the data export feature.
2391
+ */
2392
+ /** Supported export formats */
2393
+ declare type ExportFormat_2 = 'csv' | 'excel' | 'json';
2394
+
1460
2395
  /** Parameters for a specific export operation */
1461
2396
  export declare interface ExportParams {
1462
2397
  /** Export format */
@@ -1475,6 +2410,24 @@ export declare interface ExportParams {
1475
2410
  processHeader?: (header: string, field: string) => string;
1476
2411
  }
1477
2412
 
2413
+ /** Parameters for a specific export operation */
2414
+ declare interface ExportParams_2 {
2415
+ /** Export format */
2416
+ format: ExportFormat_2;
2417
+ /** File name for the export (without extension) */
2418
+ fileName?: string;
2419
+ /** Specific column fields to export */
2420
+ columns?: string[];
2421
+ /** Specific row indices to export */
2422
+ rowIndices?: number[];
2423
+ /** Include column headers in export */
2424
+ includeHeaders?: boolean;
2425
+ /** Custom cell value processor */
2426
+ processCell?: (value: any, field: string, row: any) => any;
2427
+ /** Custom header processor */
2428
+ processHeader?: (header: string, field: string) => string;
2429
+ }
2430
+
1478
2431
  /**
1479
2432
  * Export Plugin for tbw-grid
1480
2433
  *
@@ -1488,7 +2441,7 @@ export declare interface ExportParams {
1488
2441
  * })
1489
2442
  * ```
1490
2443
  */
1491
- export declare class ExportPlugin extends BaseGridPlugin<ExportConfig> {
2444
+ export declare class ExportPlugin extends BaseGridPlugin_2<ExportConfig> {
1492
2445
  readonly name = "export";
1493
2446
  readonly version = "1.0.0";
1494
2447
  protected get defaultConfig(): Partial<ExportConfig>;
@@ -1500,17 +2453,17 @@ export declare class ExportPlugin extends BaseGridPlugin<ExportConfig> {
1500
2453
  * Export data to CSV format.
1501
2454
  * @param params - Optional export parameters
1502
2455
  */
1503
- exportCsv(params?: Partial<ExportParams>): void;
2456
+ exportCsv(params?: Partial<ExportParams_2>): void;
1504
2457
  /**
1505
2458
  * Export data to Excel format (XML Spreadsheet).
1506
2459
  * @param params - Optional export parameters
1507
2460
  */
1508
- exportExcel(params?: Partial<ExportParams>): void;
2461
+ exportExcel(params?: Partial<ExportParams_2>): void;
1509
2462
  /**
1510
2463
  * Export data to JSON format.
1511
2464
  * @param params - Optional export parameters
1512
2465
  */
1513
- exportJson(params?: Partial<ExportParams>): void;
2466
+ exportJson(params?: Partial<ExportParams_2>): void;
1514
2467
  /**
1515
2468
  * Check if an export is currently in progress.
1516
2469
  * @returns Whether export is in progress
@@ -1521,7 +2474,7 @@ export declare class ExportPlugin extends BaseGridPlugin<ExportConfig> {
1521
2474
  * @returns Export info or null if no export has occurred
1522
2475
  */
1523
2476
  getLastExport(): {
1524
- format: ExportFormat;
2477
+ format: ExportFormat_2;
1525
2478
  timestamp: Date;
1526
2479
  } | null;
1527
2480
  }
@@ -1552,6 +2505,22 @@ export declare interface ExternalMountViewDetail<TRow = any> {
1552
2505
 
1553
2506
  /** Configuration options for the filtering plugin */
1554
2507
  export declare interface FilterConfig {
2508
+ /** Whether filtering is enabled (default: true) */
2509
+ enabled?: boolean;
2510
+ /** Debounce delay in ms for filter input (default: 300) */
2511
+ debounceMs?: number;
2512
+ /** Whether text filtering is case sensitive (default: false) */
2513
+ caseSensitive?: boolean;
2514
+ /** Whether to trim whitespace from filter input (default: true) */
2515
+ trimInput?: boolean;
2516
+ /** Use Web Worker for filtering large datasets >1000 rows (default: true) */
2517
+ useWorker?: boolean;
2518
+ /** Custom filter panel renderer (replaces default panel content) */
2519
+ filterPanelRenderer?: FilterPanelRenderer_2;
2520
+ }
2521
+
2522
+ /** Configuration options for the filtering plugin */
2523
+ declare interface FilterConfig_2 {
1555
2524
  /** Whether filtering is enabled (default: true) */
1556
2525
  enabled?: boolean;
1557
2526
  /** Debounce delay in ms for filter input (default: 300) */
@@ -1574,10 +2543,10 @@ export declare interface FilterConfig {
1574
2543
  * new FilteringPlugin({ enabled: true, debounceMs: 300 })
1575
2544
  * ```
1576
2545
  */
1577
- export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
2546
+ export declare class FilteringPlugin extends BaseGridPlugin_2<FilterConfig_2> {
1578
2547
  readonly name = "filtering";
1579
2548
  readonly version = "1.0.0";
1580
- protected get defaultConfig(): Partial<FilterConfig>;
2549
+ protected get defaultConfig(): Partial<FilterConfig_2>;
1581
2550
  private filters;
1582
2551
  private cachedResult;
1583
2552
  private cacheKey;
@@ -1585,7 +2554,7 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
1585
2554
  private panelElement;
1586
2555
  private searchText;
1587
2556
  private excludedValues;
1588
- private documentClickHandler;
2557
+ private panelAbortController;
1589
2558
  private globalStylesInjected;
1590
2559
  private static readonly LIST_ITEM_HEIGHT;
1591
2560
  private static readonly LIST_OVERSCAN;
@@ -1598,23 +2567,23 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
1598
2567
  * Set a filter on a specific field.
1599
2568
  * Pass null to remove the filter.
1600
2569
  */
1601
- setFilter(field: string, filter: Omit<FilterModel, 'field'> | null): void;
2570
+ setFilter(field: string, filter: Omit<FilterModel_2, 'field'> | null): void;
1602
2571
  /**
1603
2572
  * Get the current filter for a field.
1604
2573
  */
1605
- getFilter(field: string): FilterModel | undefined;
2574
+ getFilter(field: string): FilterModel_2 | undefined;
1606
2575
  /**
1607
2576
  * Get all active filters.
1608
2577
  */
1609
- getFilters(): FilterModel[];
2578
+ getFilters(): FilterModel_2[];
1610
2579
  /**
1611
2580
  * Alias for getFilters() to match functional API naming.
1612
2581
  */
1613
- getFilterModel(): FilterModel[];
2582
+ getFilterModel(): FilterModel_2[];
1614
2583
  /**
1615
2584
  * Set filters from an array (replaces all existing filters).
1616
2585
  */
1617
- setFilterModel(filters: FilterModel[]): void;
2586
+ setFilterModel(filters: FilterModel_2[]): void;
1618
2587
  /**
1619
2588
  * Clear all filters.
1620
2589
  */
@@ -1634,7 +2603,7 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
1634
2603
  /**
1635
2604
  * Get all active filters (alias for getFilters).
1636
2605
  */
1637
- getActiveFilters(): FilterModel[];
2606
+ getActiveFilters(): FilterModel_2[];
1638
2607
  /**
1639
2608
  * Get unique values for a field (for set filter dropdowns).
1640
2609
  * Uses sourceRows to include all values regardless of current filter.
@@ -1652,10 +2621,6 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
1652
2621
  * Close the filter panel
1653
2622
  */
1654
2623
  private closeFilterPanel;
1655
- /**
1656
- * Remove the document click handler
1657
- */
1658
- private removeDocumentClickHandler;
1659
2624
  /**
1660
2625
  * Position the panel below the button
1661
2626
  */
@@ -1675,11 +2640,11 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
1675
2640
  /**
1676
2641
  * Return filter state for a column if it has an active filter.
1677
2642
  */
1678
- getColumnState(field: string): Partial<ColumnState> | undefined;
2643
+ getColumnState(field: string): Partial<ColumnState_2> | undefined;
1679
2644
  /**
1680
2645
  * Apply filter state from column state.
1681
2646
  */
1682
- applyColumnState(field: string, state: ColumnState): void;
2647
+ applyColumnState(field: string, state: ColumnState_2): void;
1683
2648
  readonly styles = "\n .header-cell.filtered::before {\n content: '';\n position: absolute;\n top: 4px;\n right: 4px;\n width: 6px;\n height: 6px;\n background: var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));\n border-radius: 50%;\n }\n .tbw-filter-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 2px;\n margin-left: 4px;\n opacity: 0.4;\n transition: opacity 0.15s;\n color: inherit;\n vertical-align: middle;\n }\n .tbw-filter-btn:hover,\n .tbw-filter-btn.active {\n opacity: 1;\n }\n .tbw-filter-btn.active {\n color: var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));\n }\n ";
1684
2649
  }
1685
2650
 
@@ -1697,11 +2662,50 @@ export declare interface FilterModel {
1697
2662
  valueTo?: unknown;
1698
2663
  }
1699
2664
 
2665
+ /** Filter model representing a single filter condition */
2666
+ declare interface FilterModel_2 {
2667
+ /** The field/column to filter on */
2668
+ field: string;
2669
+ /** The type of filter */
2670
+ type: FilterType_2;
2671
+ /** The filter operator */
2672
+ operator: FilterOperator_2;
2673
+ /** The filter value (type depends on operator) */
2674
+ value: unknown;
2675
+ /** Secondary value for 'between' operator */
2676
+ valueTo?: unknown;
2677
+ }
2678
+
1700
2679
  /** Filter operators for different filter types */
1701
2680
  export declare type FilterOperator = 'contains' | 'notContains' | 'equals' | 'notEquals' | 'startsWith' | 'endsWith' | 'blank' | 'notBlank' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'between' | 'in' | 'notIn';
1702
2681
 
2682
+ /** Filter operators for different filter types */
2683
+ declare type FilterOperator_2 = 'contains' | 'notContains' | 'equals' | 'notEquals' | 'startsWith' | 'endsWith' | 'blank' | 'notBlank' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'between' | 'in' | 'notIn';
2684
+
1703
2685
  /** Parameters passed to custom filter panel renderer */
1704
2686
  declare interface FilterPanelParams {
2687
+ /** The field being filtered */
2688
+ field: string;
2689
+ /** The column configuration */
2690
+ column: ColumnConfig_2;
2691
+ /** All unique values for this field */
2692
+ uniqueValues: unknown[];
2693
+ /** Currently excluded values (for set filter) */
2694
+ excludedValues: Set<unknown>;
2695
+ /** Current search text */
2696
+ searchText: string;
2697
+ /** Apply a set filter (exclude these values) */
2698
+ applySetFilter: (excludedValues: unknown[]) => void;
2699
+ /** Apply a text filter */
2700
+ applyTextFilter: (operator: FilterOperator_2, value: string, valueTo?: string) => void;
2701
+ /** Clear the filter for this field */
2702
+ clearFilter: () => void;
2703
+ /** Close the filter panel */
2704
+ closePanel: () => void;
2705
+ }
2706
+
2707
+ /** Parameters passed to custom filter panel renderer */
2708
+ declare interface FilterPanelParams_2 {
1705
2709
  /** The field being filtered */
1706
2710
  field: string;
1707
2711
  /** The column configuration */
@@ -1725,9 +2729,15 @@ declare interface FilterPanelParams {
1725
2729
  /** Custom filter panel renderer function. Return undefined to use default panel for this column. */
1726
2730
  declare type FilterPanelRenderer = (container: HTMLElement, params: FilterPanelParams) => void | undefined;
1727
2731
 
2732
+ /** Custom filter panel renderer function. Return undefined to use default panel for this column. */
2733
+ declare type FilterPanelRenderer_2 = (container: HTMLElement, params: FilterPanelParams_2) => void | undefined;
2734
+
1728
2735
  /** Supported filter types */
1729
2736
  export declare type FilterType = 'text' | 'number' | 'date' | 'set' | 'boolean';
1730
2737
 
2738
+ /** Supported filter types */
2739
+ declare type FilterType_2 = 'text' | 'number' | 'date' | 'set' | 'boolean';
2740
+
1731
2741
  export declare type FitMode = (typeof FitModeEnum)[keyof typeof FitModeEnum];
1732
2742
 
1733
2743
  export declare const FitModeEnum: {
@@ -1751,6 +2761,8 @@ declare interface FlattenedTreeRow {
1751
2761
  parentKey: string | null;
1752
2762
  }
1753
2763
 
2764
+ export declare const getAggregator: (ref: AggregatorRef_2_2 | undefined) => AggregatorFn | undefined;
2765
+
1754
2766
  export declare interface GetRowsParams {
1755
2767
  startRow: number;
1756
2768
  endRow: number;
@@ -1761,12 +2773,28 @@ export declare interface GetRowsParams {
1761
2773
  filterModel?: Record<string, any>;
1762
2774
  }
1763
2775
 
2776
+ declare interface GetRowsParams_2 {
2777
+ startRow: number;
2778
+ endRow: number;
2779
+ sortModel?: Array<{
2780
+ field: string;
2781
+ direction: 'asc' | 'desc';
2782
+ }>;
2783
+ filterModel?: Record<string, any>;
2784
+ }
2785
+
1764
2786
  export declare interface GetRowsResult {
1765
2787
  rows: any[];
1766
2788
  totalRowCount: number;
1767
2789
  lastRow?: number;
1768
2790
  }
1769
2791
 
2792
+ declare interface GetRowsResult_2 {
2793
+ rows: any[];
2794
+ totalRowCount: number;
2795
+ lastRow?: number;
2796
+ }
2797
+
1770
2798
  /**
1771
2799
  * CSS class names used in the grid's shadow DOM.
1772
2800
  * Use these when adding/removing classes or querying elements.
@@ -1879,6 +2907,12 @@ export declare interface GridConfig<TRow = any> {
1879
2907
  * When configured, adds an optional wrapper with title, toolbar, and collapsible side panels.
1880
2908
  */
1881
2909
  shell?: ShellConfig;
2910
+ /**
2911
+ * Grid-wide icon configuration.
2912
+ * Provides consistent icons across all plugins (tree, grouping, sorting, etc.).
2913
+ * Plugins will use these by default but can override with their own config.
2914
+ */
2915
+ icons?: GridIcons;
1882
2916
  }
1883
2917
 
1884
2918
  export declare type GridCSSVar = (typeof GridCSSVars)[keyof typeof GridCSSVars];
@@ -1922,11 +2956,13 @@ export declare const GridDataAttrs: {
1922
2956
  readonly STICKY: "data-sticky";
1923
2957
  };
1924
2958
 
1925
- declare interface GridElement_2 {
2959
+ export declare interface GridElement {
1926
2960
  shadowRoot: ShadowRoot | null;
1927
2961
  rows: any[];
1928
2962
  columns: ColumnConfig[];
1929
2963
  gridConfig: any;
2964
+ /** AbortSignal that is aborted when the grid disconnects from the DOM */
2965
+ disconnectSignal: AbortSignal;
1930
2966
  requestRender(): void;
1931
2967
  requestAfterRender(): void;
1932
2968
  forceLayout(): Promise<void>;
@@ -1935,6 +2971,63 @@ declare interface GridElement_2 {
1935
2971
  dispatchEvent(event: Event): boolean;
1936
2972
  }
1937
2973
 
2974
+ declare interface GridElement_2 {
2975
+ shadowRoot: ShadowRoot | null;
2976
+ rows: any[];
2977
+ columns: ColumnConfig_2[];
2978
+ gridConfig: any;
2979
+ /** AbortSignal that is aborted when the grid disconnects from the DOM */
2980
+ disconnectSignal: AbortSignal;
2981
+ requestRender(): void;
2982
+ requestAfterRender(): void;
2983
+ forceLayout(): Promise<void>;
2984
+ getPlugin<T extends BaseGridPlugin_2>(PluginClass: new (...args: any[]) => T): T | undefined;
2985
+ getPluginByName(name: string): BaseGridPlugin_2 | undefined;
2986
+ dispatchEvent(event: Event): boolean;
2987
+ }
2988
+
2989
+ /**
2990
+ * Grid-wide icon configuration.
2991
+ * All icons are optional - sensible defaults are used when not specified.
2992
+ */
2993
+ export declare interface GridIcons {
2994
+ /** Expand icon for collapsed items (trees, groups, details). Default: '▶' */
2995
+ expand?: IconValue;
2996
+ /** Collapse icon for expanded items (trees, groups, details). Default: '▼' */
2997
+ collapse?: IconValue;
2998
+ /** Sort ascending indicator. Default: '▲' */
2999
+ sortAsc?: IconValue;
3000
+ /** Sort descending indicator. Default: '▼' */
3001
+ sortDesc?: IconValue;
3002
+ /** Sort neutral/unsorted indicator. Default: '⇅' */
3003
+ sortNone?: IconValue;
3004
+ /** Submenu arrow for context menus. Default: '▶' */
3005
+ submenuArrow?: IconValue;
3006
+ /** Drag handle icon for reordering. Default: '⋮⋮' */
3007
+ dragHandle?: IconValue;
3008
+ }
3009
+
3010
+ /**
3011
+ * Grid-wide icon configuration.
3012
+ * All icons are optional - sensible defaults are used when not specified.
3013
+ */
3014
+ declare interface GridIcons_2 {
3015
+ /** Expand icon for collapsed items (trees, groups, details). Default: '▶' */
3016
+ expand?: IconValue_2;
3017
+ /** Collapse icon for expanded items (trees, groups, details). Default: '▼' */
3018
+ collapse?: IconValue_2;
3019
+ /** Sort ascending indicator. Default: '▲' */
3020
+ sortAsc?: IconValue_2;
3021
+ /** Sort descending indicator. Default: '▼' */
3022
+ sortDesc?: IconValue_2;
3023
+ /** Sort neutral/unsorted indicator. Default: '⇅' */
3024
+ sortNone?: IconValue_2;
3025
+ /** Submenu arrow for context menus. Default: '▶' */
3026
+ submenuArrow?: IconValue_2;
3027
+ /** Drag handle icon for reordering. Default: '⋮⋮' */
3028
+ dragHandle?: IconValue_2;
3029
+ }
3030
+
1938
3031
  /**
1939
3032
  * Common CSS selectors for querying grid elements.
1940
3033
  * Built from the class constants for consistency.
@@ -1963,7 +3056,7 @@ declare interface GroupHeaderRenderParams {
1963
3056
  /** The group label (or id if no label) */
1964
3057
  label: string;
1965
3058
  /** Columns in this group */
1966
- columns: ColumnConfig[];
3059
+ columns: ColumnConfig_2[];
1967
3060
  /** Starting column index */
1968
3061
  firstIndex: number;
1969
3062
  /** Whether this is an implicit (unnamed) group */
@@ -1991,7 +3084,7 @@ declare interface GroupingColumnsConfig {
1991
3084
  * })
1992
3085
  * ```
1993
3086
  */
1994
- export declare class GroupingColumnsPlugin extends BaseGridPlugin<GroupingColumnsConfig> {
3087
+ export declare class GroupingColumnsPlugin extends BaseGridPlugin_2<GroupingColumnsConfig> {
1995
3088
  readonly name = "groupingColumns";
1996
3089
  readonly version = "1.0.0";
1997
3090
  protected get defaultConfig(): Partial<GroupingColumnsConfig>;
@@ -2002,7 +3095,7 @@ export declare class GroupingColumnsPlugin extends BaseGridPlugin<GroupingColumn
2002
3095
  * Auto-detect column groups from column configuration.
2003
3096
  */
2004
3097
  static detect(rows: readonly any[], config: any): boolean;
2005
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
3098
+ processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
2006
3099
  afterRender(): void;
2007
3100
  /**
2008
3101
  * Check if column groups are active.
@@ -2019,7 +3112,7 @@ export declare class GroupingColumnsPlugin extends BaseGridPlugin<GroupingColumn
2019
3112
  * @param groupId - The group ID to find
2020
3113
  * @returns Array of columns in the group
2021
3114
  */
2022
- getGroupColumns(groupId: string): ColumnConfig[];
3115
+ getGroupColumns(groupId: string): ColumnConfig_2[];
2023
3116
  /**
2024
3117
  * Refresh column groups (recompute from current columns).
2025
3118
  */
@@ -2038,7 +3131,32 @@ export declare interface GroupingRowsConfig {
2038
3131
  groupOn?: (row: any) => any[] | any | null | false;
2039
3132
  /** Whether groups are expanded by default (default: false) */
2040
3133
  defaultExpanded?: boolean;
2041
- /** Custom group row renderer */
3134
+ /** Custom group row renderer - takes full control of group row rendering */
3135
+ groupRowRenderer?: (params: GroupRowRenderParams_2) => HTMLElement | string | void;
3136
+ /** Show row count in group headers (default: true) */
3137
+ showRowCount?: boolean;
3138
+ /** Indent width per depth level in pixels (default: 20) */
3139
+ indentWidth?: number;
3140
+ /** Aggregators for group row cells by field name */
3141
+ aggregators?: AggregatorMap_2;
3142
+ /** Custom format function for group label */
3143
+ formatLabel?: (value: any, depth: number, key: string) => string;
3144
+ /** Whether to render group row as full-width spanning cell (default: true) */
3145
+ fullWidth?: boolean;
3146
+ }
3147
+
3148
+ /** Configuration options for the row grouping plugin */
3149
+ declare interface GroupingRowsConfig_2 {
3150
+ /** Whether the plugin is enabled (default: true) */
3151
+ enabled?: boolean;
3152
+ /**
3153
+ * Callback to determine group path for a row.
3154
+ * Return an array of group keys, a single key, null/false to skip grouping.
3155
+ */
3156
+ groupOn?: (row: any) => any[] | any | null | false;
3157
+ /** Whether groups are expanded by default (default: false) */
3158
+ defaultExpanded?: boolean;
3159
+ /** Custom group row renderer - takes full control of group row rendering */
2042
3160
  groupRowRenderer?: (params: GroupRowRenderParams) => HTMLElement | string | void;
2043
3161
  /** Show row count in group headers (default: true) */
2044
3162
  showRowCount?: boolean;
@@ -2065,10 +3183,10 @@ export declare interface GroupingRowsConfig {
2065
3183
  * })
2066
3184
  * ```
2067
3185
  */
2068
- export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfig> {
3186
+ export declare class GroupingRowsPlugin extends BaseGridPlugin_2<GroupingRowsConfig_2> {
2069
3187
  readonly name = "groupingRows";
2070
3188
  readonly version = "1.0.0";
2071
- protected get defaultConfig(): Partial<GroupingRowsConfig>;
3189
+ protected get defaultConfig(): Partial<GroupingRowsConfig_2>;
2072
3190
  private expandedKeys;
2073
3191
  private flattenedRows;
2074
3192
  private isActive;
@@ -2079,7 +3197,7 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfi
2079
3197
  */
2080
3198
  static detect(rows: readonly any[], config: any): boolean;
2081
3199
  processRows(rows: readonly any[]): any[];
2082
- onCellClick(event: CellClickEvent): boolean | void;
3200
+ onCellClick(event: CellClickEvent_2): boolean | void;
2083
3201
  /**
2084
3202
  * Render a row. Returns true if we handled the row (group row), false otherwise.
2085
3203
  */
@@ -2180,6 +3298,22 @@ declare interface GroupRowRenderParams {
2180
3298
  toggleExpand: () => void;
2181
3299
  }
2182
3300
 
3301
+ /** Parameters passed to custom group row renderer */
3302
+ declare interface GroupRowRenderParams_2 {
3303
+ /** The group key */
3304
+ key: string;
3305
+ /** The group value (last segment of path) */
3306
+ value: any;
3307
+ /** Depth level (0-based) */
3308
+ depth: number;
3309
+ /** All data rows in this group (including nested) */
3310
+ rows: any[];
3311
+ /** Whether the group is expanded */
3312
+ expanded: boolean;
3313
+ /** Toggle expand/collapse */
3314
+ toggleExpand: () => void;
3315
+ }
3316
+
2183
3317
  /**
2184
3318
  * Group state information returned by getGroupState()
2185
3319
  */
@@ -2197,7 +3331,7 @@ declare interface GroupState {
2197
3331
  /**
2198
3332
  * Header click event
2199
3333
  */
2200
- declare interface HeaderClickEvent {
3334
+ export declare interface HeaderClickEvent {
2201
3335
  colIndex: number;
2202
3336
  field: string;
2203
3337
  column: ColumnConfig;
@@ -2205,6 +3339,17 @@ declare interface HeaderClickEvent {
2205
3339
  originalEvent: MouseEvent;
2206
3340
  }
2207
3341
 
3342
+ /**
3343
+ * Header click event
3344
+ */
3345
+ declare interface HeaderClickEvent_2 {
3346
+ colIndex: number;
3347
+ field: string;
3348
+ column: ColumnConfig_2;
3349
+ headerEl: HTMLElement;
3350
+ originalEvent: MouseEvent;
3351
+ }
3352
+
2208
3353
  /**
2209
3354
  * Header content definition for plugins contributing to shell header center section.
2210
3355
  */
@@ -2219,10 +3364,35 @@ export declare interface HeaderContentDefinition {
2219
3364
  order?: number;
2220
3365
  }
2221
3366
 
3367
+ /**
3368
+ * Header content definition for plugins contributing to shell header center section.
3369
+ */
3370
+ declare interface HeaderContentDefinition_2 {
3371
+ /** Unique content ID */
3372
+ id: string;
3373
+ /** Content factory - called once when shell header renders */
3374
+ render: (container: HTMLElement) => void | (() => void);
3375
+ /** Called when content is removed (for cleanup) */
3376
+ onDestroy?: () => void;
3377
+ /** Order priority (lower = first, default: 100) */
3378
+ order?: number;
3379
+ }
3380
+
3381
+ /**
3382
+ * Header renderer function type for plugins.
3383
+ */
3384
+ export declare type HeaderRenderer = (ctx: PluginHeaderRenderContext) => string | HTMLElement;
3385
+
2222
3386
  /**
2223
3387
  * Header renderer function type for plugins.
2224
3388
  */
2225
- declare type HeaderRenderer = (ctx: PluginHeaderRenderContext) => string | HTMLElement;
3389
+ declare type HeaderRenderer_2 = (ctx: PluginHeaderRenderContext_2) => string | HTMLElement;
3390
+
3391
+ /** Icon value - can be a string (text/HTML) or HTMLElement */
3392
+ export declare type IconValue = string | HTMLElement;
3393
+
3394
+ /** Icon value - can be a string (text/HTML) or HTMLElement */
3395
+ declare type IconValue_2 = string | HTMLElement;
2226
3396
 
2227
3397
  /** Result of automatic column inference from sample rows. */
2228
3398
  export declare interface InferredColumnResult<TRow = any> {
@@ -2278,6 +3448,18 @@ declare interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
2278
3448
  requestStateChange?: () => void;
2279
3449
  }
2280
3450
 
3451
+ /**
3452
+ * Keyboard modifier flags
3453
+ */
3454
+ export declare interface KeyboardModifiers {
3455
+ ctrl?: boolean;
3456
+ shift?: boolean;
3457
+ alt?: boolean;
3458
+ meta?: boolean;
3459
+ }
3460
+
3461
+ export declare const listAggregators: () => string[];
3462
+
2281
3463
  /**
2282
3464
  * Master/Detail Plugin Types
2283
3465
  *
@@ -2311,16 +3493,38 @@ declare interface MasterDetailConfig {
2311
3493
  * })
2312
3494
  * ```
2313
3495
  */
2314
- export declare class MasterDetailPlugin extends BaseGridPlugin<MasterDetailConfig> {
3496
+ export declare class MasterDetailPlugin extends BaseGridPlugin_2<MasterDetailConfig> {
3497
+ #private;
2315
3498
  readonly name = "masterDetail";
2316
3499
  readonly version = "1.0.0";
2317
3500
  protected get defaultConfig(): Partial<MasterDetailConfig>;
2318
3501
  private expandedRows;
2319
3502
  private detailElements;
2320
3503
  detach(): void;
2321
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
2322
- onRowClick(event: RowClickEvent): boolean | void;
3504
+ processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
3505
+ onRowClick(event: RowClickEvent_2): boolean | void;
3506
+ onCellClick(): boolean | void;
2323
3507
  afterRender(): void;
3508
+ /**
3509
+ * Called on scroll to sync detail elements with visible rows.
3510
+ * Removes details for rows that scrolled out of view and reattaches for visible rows.
3511
+ */
3512
+ onScrollRender(): void;
3513
+ /**
3514
+ * Return total extra height from all expanded detail rows.
3515
+ * Used by grid virtualization to adjust scrollbar height.
3516
+ */
3517
+ getExtraHeight(): number;
3518
+ /**
3519
+ * Return extra height that appears before a given row index.
3520
+ * This is the sum of heights of all expanded details whose parent row is before the given index.
3521
+ */
3522
+ getExtraHeightBefore(beforeRowIndex: number): number;
3523
+ /**
3524
+ * Adjust the virtualization start index to keep expanded row visible while its detail is visible.
3525
+ * This ensures the detail scrolls smoothly out of view instead of disappearing abruptly.
3526
+ */
3527
+ adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): number;
2324
3528
  /**
2325
3529
  * Expand the detail row at the given index.
2326
3530
  * @param rowIndex - Index of the row to expand
@@ -2374,6 +3578,16 @@ export declare interface MultiSortConfig {
2374
3578
  showSortIndex?: boolean;
2375
3579
  }
2376
3580
 
3581
+ /** Configuration options for the multi-sort plugin */
3582
+ declare interface MultiSortConfig_2 {
3583
+ /** Whether multi-sort is enabled (default: true) */
3584
+ enabled?: boolean;
3585
+ /** Maximum number of columns to sort by (default: 3) */
3586
+ maxSortColumns?: number;
3587
+ /** Whether to show sort order badges (1, 2, 3) on headers (default: true) */
3588
+ showSortIndex?: boolean;
3589
+ }
3590
+
2377
3591
  /**
2378
3592
  * Multi-Sort Plugin for tbw-grid
2379
3593
  *
@@ -2382,25 +3596,25 @@ export declare interface MultiSortConfig {
2382
3596
  * new MultiSortPlugin({ maxSortColumns: 3, showSortIndex: true })
2383
3597
  * ```
2384
3598
  */
2385
- export declare class MultiSortPlugin extends BaseGridPlugin<MultiSortConfig> {
3599
+ export declare class MultiSortPlugin extends BaseGridPlugin_2<MultiSortConfig_2> {
2386
3600
  readonly name = "multiSort";
2387
3601
  readonly version = "1.0.0";
2388
- protected get defaultConfig(): Partial<MultiSortConfig>;
3602
+ protected get defaultConfig(): Partial<MultiSortConfig_2>;
2389
3603
  private sortModel;
2390
3604
  detach(): void;
2391
3605
  processRows(rows: readonly unknown[]): unknown[];
2392
- onHeaderClick(event: HeaderClickEvent): boolean;
3606
+ onHeaderClick(event: HeaderClickEvent_2): boolean;
2393
3607
  afterRender(): void;
2394
3608
  /**
2395
3609
  * Get the current sort model.
2396
3610
  * @returns Copy of the current sort model
2397
3611
  */
2398
- getSortModel(): SortModel[];
3612
+ getSortModel(): SortModel_2[];
2399
3613
  /**
2400
3614
  * Set the sort model programmatically.
2401
3615
  * @param model - New sort model to apply
2402
3616
  */
2403
- setSortModel(model: SortModel[]): void;
3617
+ setSortModel(model: SortModel_2[]): void;
2404
3618
  /**
2405
3619
  * Clear all sorting.
2406
3620
  */
@@ -2420,12 +3634,12 @@ export declare class MultiSortPlugin extends BaseGridPlugin<MultiSortConfig> {
2420
3634
  /**
2421
3635
  * Return sort state for a column if it's in the sort model.
2422
3636
  */
2423
- getColumnState(field: string): Partial<ColumnState> | undefined;
3637
+ getColumnState(field: string): Partial<ColumnState_2> | undefined;
2424
3638
  /**
2425
3639
  * Apply sort state from column state.
2426
3640
  * Rebuilds the sort model from all column states.
2427
3641
  */
2428
- applyColumnState(field: string, state: ColumnState): void;
3642
+ applyColumnState(field: string, state: ColumnState_2): void;
2429
3643
  readonly styles = "\n .header-cell[data-sort=\"asc\"]::after {\n content: '\u2191';\n margin-left: 4px;\n opacity: 0.8;\n }\n .header-cell[data-sort=\"desc\"]::after {\n content: '\u2193';\n margin-left: 4px;\n opacity: 0.8;\n }\n .sort-index {\n font-size: 10px;\n background: var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));\n color: var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));\n border-radius: 50%;\n width: 14px;\n height: 14px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-left: 2px;\n font-weight: 600;\n }\n ";
2430
3644
  }
2431
3645
 
@@ -2448,7 +3662,7 @@ declare interface PinnedColumnsConfig {
2448
3662
  * new PinnedColumnsPlugin({ enabled: true })
2449
3663
  * ```
2450
3664
  */
2451
- export declare class PinnedColumnsPlugin extends BaseGridPlugin<PinnedColumnsConfig> {
3665
+ export declare class PinnedColumnsPlugin extends BaseGridPlugin_2<PinnedColumnsConfig> {
2452
3666
  readonly name = "pinnedColumns";
2453
3667
  readonly version = "1.0.0";
2454
3668
  protected get defaultConfig(): Partial<PinnedColumnsConfig>;
@@ -2460,9 +3674,9 @@ export declare class PinnedColumnsPlugin extends BaseGridPlugin<PinnedColumnsCon
2460
3674
  * Auto-detect sticky columns from column configuration.
2461
3675
  */
2462
3676
  static detect(rows: readonly unknown[], config: {
2463
- columns?: ColumnConfig[];
3677
+ columns?: ColumnConfig_2[];
2464
3678
  }): boolean;
2465
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
3679
+ processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
2466
3680
  afterRender(): void;
2467
3681
  /**
2468
3682
  * Re-apply sticky offsets (e.g., after column resize).
@@ -2471,11 +3685,11 @@ export declare class PinnedColumnsPlugin extends BaseGridPlugin<PinnedColumnsCon
2471
3685
  /**
2472
3686
  * Get columns pinned to the left.
2473
3687
  */
2474
- getLeftPinnedColumns(): ColumnConfig[];
3688
+ getLeftPinnedColumns(): ColumnConfig_2[];
2475
3689
  /**
2476
3690
  * Get columns pinned to the right.
2477
3691
  */
2478
- getRightPinnedColumns(): ColumnConfig[];
3692
+ getRightPinnedColumns(): ColumnConfig_2[];
2479
3693
  /**
2480
3694
  * Clear all sticky positioning.
2481
3695
  */
@@ -2495,13 +3709,29 @@ declare interface PinnedRowsConfig {
2495
3709
  /** Show filtered row count when filter is active (default: true) */
2496
3710
  showFilteredCount?: boolean;
2497
3711
  /** Custom panels to display in the info bar */
2498
- customPanels?: PinnedRowsPanel[];
3712
+ customPanels?: PinnedRowsPanel_2[];
2499
3713
  /** Aggregation rows (footer/header rows with computed values) */
2500
3714
  aggregationRows?: AggregationRowConfig[];
2501
3715
  }
2502
3716
 
2503
3717
  /** Context provided to panel renderers */
2504
- export declare interface PinnedRowsContext {
3718
+ export declare interface PinnedRowsContext {
3719
+ /** Total number of rows in the grid */
3720
+ totalRows: number;
3721
+ /** Number of rows after filtering */
3722
+ filteredRows: number;
3723
+ /** Number of selected rows */
3724
+ selectedRows: number;
3725
+ /** Current column configuration */
3726
+ columns: ColumnConfig[];
3727
+ /** Current row data */
3728
+ rows: unknown[];
3729
+ /** Reference to the grid element */
3730
+ grid: HTMLElement;
3731
+ }
3732
+
3733
+ /** Context provided to panel renderers */
3734
+ declare interface PinnedRowsContext_2 {
2505
3735
  /** Total number of rows in the grid */
2506
3736
  totalRows: number;
2507
3737
  /** Number of rows after filtering */
@@ -2509,7 +3739,7 @@ export declare interface PinnedRowsContext {
2509
3739
  /** Number of selected rows */
2510
3740
  selectedRows: number;
2511
3741
  /** Current column configuration */
2512
- columns: ColumnConfig[];
3742
+ columns: ColumnConfig_2[];
2513
3743
  /** Current row data */
2514
3744
  rows: unknown[];
2515
3745
  /** Reference to the grid element */
@@ -2526,6 +3756,16 @@ export declare interface PinnedRowsPanel {
2526
3756
  render: (context: PinnedRowsContext) => HTMLElement | string;
2527
3757
  }
2528
3758
 
3759
+ /** Custom panel definition for the status bar */
3760
+ declare interface PinnedRowsPanel_2 {
3761
+ /** Unique identifier for the panel */
3762
+ id: string;
3763
+ /** Position within the status bar */
3764
+ position: 'left' | 'center' | 'right';
3765
+ /** Render function for the panel content */
3766
+ render: (context: PinnedRowsContext_2) => HTMLElement | string;
3767
+ }
3768
+
2529
3769
  /**
2530
3770
  * Pinned Rows Plugin for tbw-grid
2531
3771
  *
@@ -2542,7 +3782,7 @@ export declare interface PinnedRowsPanel {
2542
3782
  * })
2543
3783
  * ```
2544
3784
  */
2545
- export declare class PinnedRowsPlugin extends BaseGridPlugin<PinnedRowsConfig> {
3785
+ export declare class PinnedRowsPlugin extends BaseGridPlugin_2<PinnedRowsConfig> {
2546
3786
  readonly name = "pinnedRows";
2547
3787
  readonly version = "1.0.0";
2548
3788
  protected get defaultConfig(): Partial<PinnedRowsConfig>;
@@ -2564,12 +3804,12 @@ export declare class PinnedRowsPlugin extends BaseGridPlugin<PinnedRowsConfig> {
2564
3804
  * Get the current status bar context.
2565
3805
  * @returns The context with row counts and other info
2566
3806
  */
2567
- getContext(): PinnedRowsContext;
3807
+ getContext(): PinnedRowsContext_2;
2568
3808
  /**
2569
3809
  * Add a custom panel to the info bar.
2570
3810
  * @param panel - The panel configuration to add
2571
3811
  */
2572
- addPanel(panel: PinnedRowsPanel): void;
3812
+ addPanel(panel: PinnedRowsPanel_2): void;
2573
3813
  /**
2574
3814
  * Remove a custom panel by ID.
2575
3815
  * @param id - The panel ID to remove
@@ -2600,6 +3840,15 @@ export declare interface PivotConfig {
2600
3840
  showGrandTotal?: boolean;
2601
3841
  }
2602
3842
 
3843
+ declare interface PivotConfig_2 {
3844
+ enabled?: boolean;
3845
+ rowGroupFields?: string[];
3846
+ columnGroupFields?: string[];
3847
+ valueFields?: PivotValueField_2[];
3848
+ showTotals?: boolean;
3849
+ showGrandTotal?: boolean;
3850
+ }
3851
+
2603
3852
  declare type PivotDataRow = Record<string, unknown>;
2604
3853
 
2605
3854
  /**
@@ -2614,17 +3863,17 @@ declare type PivotDataRow = Record<string, unknown>;
2614
3863
  * })
2615
3864
  * ```
2616
3865
  */
2617
- export declare class PivotPlugin extends BaseGridPlugin<PivotConfig> {
3866
+ export declare class PivotPlugin extends BaseGridPlugin_2<PivotConfig_2> {
2618
3867
  readonly name = "pivot";
2619
3868
  readonly version = "1.0.0";
2620
- protected get defaultConfig(): Partial<PivotConfig>;
3869
+ protected get defaultConfig(): Partial<PivotConfig_2>;
2621
3870
  private isActive;
2622
3871
  private pivotResult;
2623
3872
  private columnHeaders;
2624
3873
  private rowHeaders;
2625
3874
  detach(): void;
2626
3875
  processRows(rows: readonly unknown[]): PivotDataRow[];
2627
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
3876
+ processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
2628
3877
  /**
2629
3878
  * Enable pivot mode.
2630
3879
  */
@@ -2640,7 +3889,7 @@ export declare class PivotPlugin extends BaseGridPlugin<PivotConfig> {
2640
3889
  /**
2641
3890
  * Get the current pivot result.
2642
3891
  */
2643
- getPivotResult(): PivotResult | null;
3892
+ getPivotResult(): PivotResult_2 | null;
2644
3893
  /**
2645
3894
  * Set the row group fields for pivoting.
2646
3895
  * @param fields - Array of field names to group rows by
@@ -2655,7 +3904,7 @@ export declare class PivotPlugin extends BaseGridPlugin<PivotConfig> {
2655
3904
  * Set the value fields with aggregation functions.
2656
3905
  * @param fields - Array of value field configurations
2657
3906
  */
2658
- setValueFields(fields: PivotValueField[]): void;
3907
+ setValueFields(fields: PivotValueField_2[]): void;
2659
3908
  /**
2660
3909
  * Refresh the pivot by clearing cached results.
2661
3910
  */
@@ -2664,6 +3913,13 @@ export declare class PivotPlugin extends BaseGridPlugin<PivotConfig> {
2664
3913
  }
2665
3914
 
2666
3915
  export declare interface PivotResult {
3916
+ rows: PivotRow_2[];
3917
+ columnKeys: string[];
3918
+ totals: Record<string, number>;
3919
+ grandTotal: number;
3920
+ }
3921
+
3922
+ declare interface PivotResult_2 {
2667
3923
  rows: PivotRow[];
2668
3924
  columnKeys: string[];
2669
3925
  totals: Record<string, number>;
@@ -2680,12 +3936,28 @@ declare interface PivotRow {
2680
3936
  children?: PivotRow[];
2681
3937
  }
2682
3938
 
3939
+ declare interface PivotRow_2 {
3940
+ rowKey: string;
3941
+ rowLabel: string;
3942
+ depth: number;
3943
+ values: Record<string, number | null>;
3944
+ total?: number;
3945
+ isGroup: boolean;
3946
+ children?: PivotRow_2[];
3947
+ }
3948
+
2683
3949
  export declare interface PivotValueField {
2684
3950
  field: string;
2685
3951
  aggFunc: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last';
2686
3952
  header?: string;
2687
3953
  }
2688
3954
 
3955
+ declare interface PivotValueField_2 {
3956
+ field: string;
3957
+ aggFunc: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last';
3958
+ header?: string;
3959
+ }
3960
+
2689
3961
  /**
2690
3962
  * Cell render context for plugin cell renderers.
2691
3963
  * Provides full context including position and editing state.
@@ -2694,7 +3966,7 @@ export declare interface PivotValueField {
2694
3966
  * simpler and used for column view renderers. This version provides additional
2695
3967
  * context needed by plugins that register custom cell renderers.
2696
3968
  */
2697
- declare interface PluginCellRenderContext {
3969
+ export declare interface PluginCellRenderContext {
2698
3970
  /** The cell value */
2699
3971
  value: any;
2700
3972
  /** The field/column key */
@@ -2711,6 +3983,31 @@ declare interface PluginCellRenderContext {
2711
3983
  isEditing: boolean;
2712
3984
  }
2713
3985
 
3986
+ /**
3987
+ * Cell render context for plugin cell renderers.
3988
+ * Provides full context including position and editing state.
3989
+ *
3990
+ * Note: This differs from the core `CellRenderContext` in types.ts which is
3991
+ * simpler and used for column view renderers. This version provides additional
3992
+ * context needed by plugins that register custom cell renderers.
3993
+ */
3994
+ declare interface PluginCellRenderContext_2 {
3995
+ /** The cell value */
3996
+ value: any;
3997
+ /** The field/column key */
3998
+ field: string;
3999
+ /** The row data object */
4000
+ row: any;
4001
+ /** Row index in the data array */
4002
+ rowIndex: number;
4003
+ /** Column index */
4004
+ colIndex: number;
4005
+ /** Column configuration */
4006
+ column: ColumnConfig_2;
4007
+ /** Whether the cell is currently in edit mode */
4008
+ isEditing: boolean;
4009
+ }
4010
+
2714
4011
  export declare type PluginEventName = (typeof PluginEvents)[keyof typeof PluginEvents];
2715
4012
 
2716
4013
  export declare const PluginEvents: {
@@ -2736,13 +4033,185 @@ export declare const PluginEvents: {
2736
4033
  /**
2737
4034
  * Header render context for plugin header renderers.
2738
4035
  */
2739
- declare interface PluginHeaderRenderContext {
4036
+ export declare interface PluginHeaderRenderContext {
2740
4037
  /** Column configuration */
2741
4038
  column: ColumnConfig;
2742
4039
  /** Column index */
2743
4040
  colIndex: number;
2744
4041
  }
2745
4042
 
4043
+ /**
4044
+ * Header render context for plugin header renderers.
4045
+ */
4046
+ declare interface PluginHeaderRenderContext_2 {
4047
+ /** Column configuration */
4048
+ column: ColumnConfig_2;
4049
+ /** Column index */
4050
+ colIndex: number;
4051
+ }
4052
+
4053
+ /**
4054
+ * Manages plugins for a single grid instance.
4055
+ */
4056
+ export declare class PluginManager {
4057
+ private grid;
4058
+ /** Plugin instances in order of attachment */
4059
+ private plugins;
4060
+ /** Map from plugin class to instance for fast lookup */
4061
+ private pluginMap;
4062
+ /** Cell renderers registered by plugins */
4063
+ private cellRenderers;
4064
+ /** Header renderers registered by plugins */
4065
+ private headerRenderers;
4066
+ /** Cell editors registered by plugins */
4067
+ private cellEditors;
4068
+ constructor(grid: any);
4069
+ /**
4070
+ * Attach all plugins from the config.
4071
+ */
4072
+ attachAll(plugins: BaseGridPlugin[]): void;
4073
+ /**
4074
+ * Attach a plugin to this grid.
4075
+ */
4076
+ attach(plugin: BaseGridPlugin): void;
4077
+ /**
4078
+ * Detach all plugins and clean up.
4079
+ */
4080
+ detachAll(): void;
4081
+ /**
4082
+ * Get a plugin instance by its class.
4083
+ */
4084
+ getPlugin<T extends BaseGridPlugin>(PluginClass: new (...args: any[]) => T): T | undefined;
4085
+ /**
4086
+ * Get a plugin instance by its name.
4087
+ */
4088
+ getPluginByName(name: string): BaseGridPlugin | undefined;
4089
+ /**
4090
+ * Check if a plugin is attached.
4091
+ */
4092
+ hasPlugin<T extends BaseGridPlugin>(PluginClass: new (...args: any[]) => T): boolean;
4093
+ /**
4094
+ * Get all attached plugins.
4095
+ */
4096
+ getAll(): readonly BaseGridPlugin[];
4097
+ /**
4098
+ * Get a cell renderer by type name.
4099
+ */
4100
+ getCellRenderer(type: string): CellRenderer | undefined;
4101
+ /**
4102
+ * Get a header renderer by type name.
4103
+ */
4104
+ getHeaderRenderer(type: string): HeaderRenderer | undefined;
4105
+ /**
4106
+ * Get a cell editor by type name.
4107
+ */
4108
+ getCellEditor(type: string): CellEditor | undefined;
4109
+ /**
4110
+ * Get all CSS styles from all plugins.
4111
+ */
4112
+ getAllStyles(): string;
4113
+ /**
4114
+ * Execute processRows hook on all plugins.
4115
+ */
4116
+ processRows(rows: readonly any[]): any[];
4117
+ /**
4118
+ * Execute processColumns hook on all plugins.
4119
+ */
4120
+ processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
4121
+ /**
4122
+ * Execute beforeRender hook on all plugins.
4123
+ */
4124
+ beforeRender(): void;
4125
+ /**
4126
+ * Execute afterRender hook on all plugins.
4127
+ */
4128
+ afterRender(): void;
4129
+ /**
4130
+ * Execute onScrollRender hook on all plugins.
4131
+ * Called after scroll-triggered row rendering for lightweight visual state updates.
4132
+ */
4133
+ onScrollRender(): void;
4134
+ /**
4135
+ * Get total extra height contributed by plugins (e.g., expanded detail rows).
4136
+ * Used to adjust scrollbar height calculations.
4137
+ */
4138
+ getExtraHeight(): number;
4139
+ /**
4140
+ * Get extra height from plugins that appears before a given row index.
4141
+ * Used by virtualization to correctly position the scroll window.
4142
+ */
4143
+ getExtraHeightBefore(beforeRowIndex: number): number;
4144
+ /**
4145
+ * Adjust the virtualization start index based on plugin needs.
4146
+ * Returns the minimum start index from all plugins.
4147
+ */
4148
+ adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): number;
4149
+ /**
4150
+ * Execute renderRow hook on all plugins.
4151
+ * Returns true if any plugin handled the row.
4152
+ */
4153
+ renderRow(row: any, rowEl: HTMLElement, rowIndex: number): boolean;
4154
+ /**
4155
+ * Execute onKeyDown hook on all plugins.
4156
+ * Returns true if any plugin handled the event.
4157
+ */
4158
+ onKeyDown(event: KeyboardEvent): boolean;
4159
+ /**
4160
+ * Execute onCellClick hook on all plugins.
4161
+ * Returns true if any plugin handled the event.
4162
+ */
4163
+ onCellClick(event: CellClickEvent): boolean;
4164
+ /**
4165
+ * Execute onRowClick hook on all plugins.
4166
+ * Returns true if any plugin handled the event.
4167
+ */
4168
+ onRowClick(event: RowClickEvent): boolean;
4169
+ /**
4170
+ * Execute onHeaderClick hook on all plugins.
4171
+ * Returns true if any plugin handled the event.
4172
+ */
4173
+ onHeaderClick(event: HeaderClickEvent): boolean;
4174
+ /**
4175
+ * Execute onScroll hook on all plugins.
4176
+ */
4177
+ onScroll(event: ScrollEvent): void;
4178
+ /**
4179
+ * Execute onCellMouseDown hook on all plugins.
4180
+ * Returns true if any plugin handled the event.
4181
+ */
4182
+ onCellMouseDown(event: CellMouseEvent): boolean;
4183
+ /**
4184
+ * Execute onCellMouseMove hook on all plugins.
4185
+ * Returns true if any plugin handled the event.
4186
+ */
4187
+ onCellMouseMove(event: CellMouseEvent): boolean;
4188
+ /**
4189
+ * Execute onCellMouseUp hook on all plugins.
4190
+ * Returns true if any plugin handled the event.
4191
+ */
4192
+ onCellMouseUp(event: CellMouseEvent): boolean;
4193
+ /**
4194
+ * Collect context menu items from all plugins.
4195
+ */
4196
+ getContextMenuItems(params: ContextMenuParams): ContextMenuItem[];
4197
+ /**
4198
+ * Collect tool panels from all plugins.
4199
+ * Returns panels sorted by order (ascending).
4200
+ */
4201
+ getToolPanels(): {
4202
+ plugin: BaseGridPlugin;
4203
+ panel: NonNullable<ReturnType<NonNullable<BaseGridPlugin['getToolPanel']>>>;
4204
+ }[];
4205
+ /**
4206
+ * Collect header contents from all plugins.
4207
+ * Returns contents sorted by order (ascending).
4208
+ */
4209
+ getHeaderContents(): {
4210
+ plugin: BaseGridPlugin;
4211
+ content: NonNullable<ReturnType<NonNullable<BaseGridPlugin['getHeaderContent']>>>;
4212
+ }[];
4213
+ }
4214
+
2746
4215
  export declare type PrimitiveColumnType = 'number' | 'string' | 'date' | 'boolean' | 'select' | 'typeahead';
2747
4216
 
2748
4217
  /**
@@ -2784,6 +4253,8 @@ export declare interface PublicGrid<T = any> {
2784
4253
  toggleGroup?: (key: string) => Promise<void>;
2785
4254
  }
2786
4255
 
4256
+ export declare const registerAggregator: (name: string, fn: AggregatorFn) => void;
4257
+
2787
4258
  /** Union type for render rows */
2788
4259
  declare type RenderRow = GroupRowModelItem | DataRowModelItem;
2789
4260
 
@@ -2814,7 +4285,7 @@ declare interface ReorderConfig {
2814
4285
  * })
2815
4286
  * ```
2816
4287
  */
2817
- export declare class ReorderPlugin extends BaseGridPlugin<ReorderConfig> {
4288
+ export declare class ReorderPlugin extends BaseGridPlugin_2<ReorderConfig> {
2818
4289
  readonly name = "reorder";
2819
4290
  readonly version = "1.0.0";
2820
4291
  protected get defaultConfig(): Partial<ReorderConfig>;
@@ -2822,7 +4293,6 @@ export declare class ReorderPlugin extends BaseGridPlugin<ReorderConfig> {
2822
4293
  private draggedField;
2823
4294
  private draggedIndex;
2824
4295
  private dropIndex;
2825
- private boundReorderRequestHandler;
2826
4296
  attach(grid: GridElement_2): void;
2827
4297
  detach(): void;
2828
4298
  afterRender(): void;
@@ -2860,7 +4330,17 @@ declare interface ResizeController {
2860
4330
  /**
2861
4331
  * Row click event
2862
4332
  */
2863
- declare interface RowClickEvent {
4333
+ export declare interface RowClickEvent {
4334
+ rowIndex: number;
4335
+ row: any;
4336
+ rowEl: HTMLElement;
4337
+ originalEvent: MouseEvent;
4338
+ }
4339
+
4340
+ /**
4341
+ * Row click event
4342
+ */
4343
+ declare interface RowClickEvent_2 {
2864
4344
  rowIndex: number;
2865
4345
  row: any;
2866
4346
  rowEl: HTMLElement;
@@ -2896,10 +4376,25 @@ export declare interface RowGroupRenderConfig {
2896
4376
  class?: string;
2897
4377
  }
2898
4378
 
4379
+ export declare const runAggregator: (ref: AggregatorRef_2_2 | undefined, rows: any[], field: string, column?: any) => any;
4380
+
4381
+ /**
4382
+ * Scroll event
4383
+ */
4384
+ export declare interface ScrollEvent {
4385
+ scrollTop: number;
4386
+ scrollLeft: number;
4387
+ scrollHeight: number;
4388
+ scrollWidth: number;
4389
+ clientHeight: number;
4390
+ clientWidth: number;
4391
+ originalEvent?: Event;
4392
+ }
4393
+
2899
4394
  /**
2900
4395
  * Scroll event
2901
4396
  */
2902
- declare interface ScrollEvent {
4397
+ declare interface ScrollEvent_2 {
2903
4398
  scrollTop: number;
2904
4399
  scrollLeft: number;
2905
4400
  scrollHeight: number;
@@ -2926,6 +4421,12 @@ export declare interface SelectionConfig {
2926
4421
  mode: SelectionMode_2;
2927
4422
  }
2928
4423
 
4424
+ /** Configuration options for the selection plugin */
4425
+ declare interface SelectionConfig_2 {
4426
+ /** Selection mode (default: 'cell') */
4427
+ mode: SelectionMode_3;
4428
+ }
4429
+
2929
4430
  /**
2930
4431
  * Selection Plugin Types
2931
4432
  *
@@ -2940,6 +4441,19 @@ export declare interface SelectionConfig {
2940
4441
  declare type SelectionMode_2 = 'cell' | 'row' | 'range';
2941
4442
  export { SelectionMode_2 as SelectionMode }
2942
4443
 
4444
+ /**
4445
+ * Selection Plugin Types
4446
+ *
4447
+ * Type definitions for the selection feature.
4448
+ */
4449
+ /**
4450
+ * Selection mode for the grid:
4451
+ * - 'cell': Single cell selection (default). No border, just focus highlight.
4452
+ * - 'row': Row selection. Clicking a cell selects the entire row. Uses focus outline color.
4453
+ * - 'range': Range selection. Shift+click or drag to select rectangular cell ranges. Uses success border color.
4454
+ */
4455
+ declare type SelectionMode_3 = 'cell' | 'row' | 'range';
4456
+
2943
4457
  /**
2944
4458
  * Selection Plugin for tbw-grid
2945
4459
  *
@@ -2948,11 +4462,11 @@ export { SelectionMode_2 as SelectionMode }
2948
4462
  * new SelectionPlugin({ mode: 'range' })
2949
4463
  * ```
2950
4464
  */
2951
- export declare class SelectionPlugin extends BaseGridPlugin<SelectionConfig> {
4465
+ export declare class SelectionPlugin extends BaseGridPlugin_2<SelectionConfig_2> {
2952
4466
  #private;
2953
4467
  readonly name = "selection";
2954
4468
  readonly version = "1.0.0";
2955
- protected get defaultConfig(): Partial<SelectionConfig>;
4469
+ protected get defaultConfig(): Partial<SelectionConfig_2>;
2956
4470
  /** Row selection state (row mode) */
2957
4471
  private selected;
2958
4472
  private lastSelected;
@@ -2965,11 +4479,11 @@ export declare class SelectionPlugin extends BaseGridPlugin<SelectionConfig> {
2965
4479
  /** Cell selection state (cell mode) */
2966
4480
  private selectedCell;
2967
4481
  detach(): void;
2968
- onCellClick(event: CellClickEvent): boolean;
4482
+ onCellClick(event: CellClickEvent_2): boolean;
2969
4483
  onKeyDown(event: KeyboardEvent): boolean;
2970
- onCellMouseDown(event: CellMouseEvent): boolean | void;
2971
- onCellMouseMove(event: CellMouseEvent): boolean | void;
2972
- onCellMouseUp(_event: CellMouseEvent): boolean | void;
4484
+ onCellMouseDown(event: CellMouseEvent_2): boolean | void;
4485
+ onCellMouseMove(event: CellMouseEvent_2): boolean | void;
4486
+ onCellMouseUp(_event: CellMouseEvent_2): boolean | void;
2973
4487
  afterRender(): void;
2974
4488
  /**
2975
4489
  * Called after scroll-triggered row rendering.
@@ -2990,7 +4504,7 @@ export declare class SelectionPlugin extends BaseGridPlugin<SelectionConfig> {
2990
4504
  /**
2991
4505
  * Get all selected cell ranges in public format.
2992
4506
  */
2993
- getRanges(): CellRange[];
4507
+ getRanges(): CellRange_2[];
2994
4508
  /**
2995
4509
  * Get all selected cells across all ranges.
2996
4510
  */
@@ -3009,7 +4523,7 @@ export declare class SelectionPlugin extends BaseGridPlugin<SelectionConfig> {
3009
4523
  /**
3010
4524
  * Set selected ranges programmatically.
3011
4525
  */
3012
- setRanges(ranges: CellRange[]): void;
4526
+ setRanges(ranges: CellRange_2[]): void;
3013
4527
  readonly styles = "\n /* Prevent text selection during range drag */\n :host .selecting .data-grid-row > .cell {\n user-select: none;\n }\n\n /* Row selection - use accent color for row focus */\n :host .data-grid-row.row-focus {\n background-color: var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%));\n }\n\n /* Disable cell-focus outline in row mode - row is the focus unit */\n :host([data-selection-mode=\"row\"]) .cell-focus {\n outline: none;\n }\n\n /* Selection cell styles - for range mode */\n :host .data-grid-row > .cell.selected {\n background-color: var(--tbw-range-selection-bg);\n }\n :host .data-grid-row > .cell.selected.top {\n border-top: 2px solid var(--tbw-range-border-color);\n }\n :host .data-grid-row > .cell.selected.bottom {\n border-bottom: 2px solid var(--tbw-range-border-color);\n }\n :host .data-grid-row > .cell.selected.first {\n border-left: 2px solid var(--tbw-range-border-color);\n }\n :host .data-grid-row > .cell.selected.last {\n border-right: 2px solid var(--tbw-range-border-color);\n }\n ";
3014
4528
  }
3015
4529
 
@@ -3024,6 +4538,10 @@ export declare interface ServerSideDataSource {
3024
4538
  getRows(params: GetRowsParams): Promise<GetRowsResult>;
3025
4539
  }
3026
4540
 
4541
+ declare interface ServerSideDataSource_2 {
4542
+ getRows(params: GetRowsParams_2): Promise<GetRowsResult_2>;
4543
+ }
4544
+
3027
4545
  /**
3028
4546
  * Server-Side Plugin for tbw-grid
3029
4547
  *
@@ -3033,7 +4551,7 @@ export declare interface ServerSideDataSource {
3033
4551
  * plugin.setDataSource(myDataSource);
3034
4552
  * ```
3035
4553
  */
3036
- export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
4554
+ export declare class ServerSidePlugin extends BaseGridPlugin_2<ServerSideConfig> {
3037
4555
  readonly name = "serverSide";
3038
4556
  readonly version = "1.0.0";
3039
4557
  protected get defaultConfig(): Partial<ServerSideConfig>;
@@ -3049,12 +4567,12 @@ export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
3049
4567
  */
3050
4568
  private loadRequiredBlocks;
3051
4569
  processRows(rows: readonly unknown[]): unknown[];
3052
- onScroll(event: ScrollEvent): void;
4570
+ onScroll(event: ScrollEvent_2): void;
3053
4571
  /**
3054
4572
  * Set the data source for server-side loading.
3055
4573
  * @param dataSource - Data source implementing the getRows method
3056
4574
  */
3057
- setDataSource(dataSource: ServerSideDataSource): void;
4575
+ setDataSource(dataSource: ServerSideDataSource_2): void;
3058
4576
  /**
3059
4577
  * Refresh all data from the server.
3060
4578
  */
@@ -3119,6 +4637,19 @@ export declare interface SortModel {
3119
4637
  direction: 'asc' | 'desc';
3120
4638
  }
3121
4639
 
4640
+ /**
4641
+ * Multi-Sort Plugin Types
4642
+ *
4643
+ * Type definitions for the multi-column sorting feature.
4644
+ */
4645
+ /** Represents a single column sort configuration */
4646
+ declare interface SortModel_2 {
4647
+ /** The field key to sort by */
4648
+ field: string;
4649
+ /** Sort direction */
4650
+ direction: 'asc' | 'desc';
4651
+ }
4652
+
3122
4653
  /**
3123
4654
  * Toolbar button defined via config (programmatic approach).
3124
4655
  * Supports three modes:
@@ -3199,6 +4730,26 @@ export declare interface ToolPanelDefinition {
3199
4730
  order?: number;
3200
4731
  }
3201
4732
 
4733
+ /**
4734
+ * Tool panel definition registered by plugins or consumers.
4735
+ */
4736
+ declare interface ToolPanelDefinition_2 {
4737
+ /** Unique panel ID */
4738
+ id: string;
4739
+ /** Panel title shown in header */
4740
+ title: string;
4741
+ /** Icon for toolbar button (SVG string or emoji) */
4742
+ icon: string;
4743
+ /** Toolbar button tooltip */
4744
+ tooltip?: string;
4745
+ /** Panel content factory - called when panel opens */
4746
+ render: (container: HTMLElement) => void | (() => void);
4747
+ /** Called when panel closes (for cleanup) */
4748
+ onClose?: () => void;
4749
+ /** Panel order priority (lower = first, default: 100) */
4750
+ order?: number;
4751
+ }
4752
+
3202
4753
  /**
3203
4754
  * Tree Data Plugin Types
3204
4755
  *
@@ -3220,6 +4771,27 @@ export declare interface TreeConfig {
3220
4771
  showExpandIcons?: boolean;
3221
4772
  }
3222
4773
 
4774
+ /**
4775
+ * Tree Data Plugin Types
4776
+ *
4777
+ * Type definitions for hierarchical tree data with expand/collapse functionality.
4778
+ */
4779
+ /** Configuration options for the tree plugin */
4780
+ declare interface TreeConfig_2 {
4781
+ /** Whether tree functionality is enabled (default: true) */
4782
+ enabled?: boolean;
4783
+ /** Field name containing child rows (default: 'children') */
4784
+ childrenField?: string;
4785
+ /** Auto-detect tree structure from data (default: true) */
4786
+ autoDetect?: boolean;
4787
+ /** Whether nodes are expanded by default (default: false) */
4788
+ defaultExpanded?: boolean;
4789
+ /** Indentation width per level in pixels (default: 20) */
4790
+ indentWidth?: number;
4791
+ /** Show expand/collapse icons (default: true) */
4792
+ showExpandIcons?: boolean;
4793
+ }
4794
+
3223
4795
  /** Event detail emitted when a tree node is expanded or collapsed */
3224
4796
  export declare interface TreeExpandDetail {
3225
4797
  /** The row key that was toggled */
@@ -3242,10 +4814,10 @@ export declare interface TreeExpandDetail {
3242
4814
  * new TreePlugin({ defaultExpanded: true, indentWidth: 24 })
3243
4815
  * ```
3244
4816
  */
3245
- export declare class TreePlugin extends BaseGridPlugin<TreeConfig> {
4817
+ export declare class TreePlugin extends BaseGridPlugin_2<TreeConfig_2> {
3246
4818
  readonly name = "tree";
3247
4819
  readonly version = "1.0.0";
3248
- protected get defaultConfig(): Partial<TreeConfig>;
4820
+ protected get defaultConfig(): Partial<TreeConfig_2>;
3249
4821
  /** Set of expanded row keys */
3250
4822
  private expandedKeys;
3251
4823
  /** Whether initial expansion (based on defaultExpanded config) has been applied */
@@ -3261,8 +4833,8 @@ export declare class TreePlugin extends BaseGridPlugin<TreeConfig> {
3261
4833
  */
3262
4834
  detect(rows: readonly unknown[]): boolean;
3263
4835
  processRows(rows: readonly unknown[]): any[];
3264
- processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
3265
- onCellClick(event: CellClickEvent): boolean;
4836
+ processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
4837
+ onCellClick(event: CellClickEvent_2): boolean;
3266
4838
  /**
3267
4839
  * Expand a specific node by key.
3268
4840
  */
@@ -3326,7 +4898,7 @@ declare interface UndoRedoConfig {
3326
4898
  * Tracks cell edits and provides undo/redo functionality via keyboard shortcuts
3327
4899
  * or programmatic API.
3328
4900
  */
3329
- export declare class UndoRedoPlugin extends BaseGridPlugin<UndoRedoConfig> {
4901
+ export declare class UndoRedoPlugin extends BaseGridPlugin_2<UndoRedoConfig> {
3330
4902
  readonly name = "undoRedo";
3331
4903
  readonly version = "1.0.0";
3332
4904
  protected get defaultConfig(): Partial<UndoRedoConfig>;
@@ -3357,13 +4929,13 @@ export declare class UndoRedoPlugin extends BaseGridPlugin<UndoRedoConfig> {
3357
4929
  *
3358
4930
  * @returns The undone action, or null if nothing to undo
3359
4931
  */
3360
- undo(): EditAction | null;
4932
+ undo(): EditAction_2 | null;
3361
4933
  /**
3362
4934
  * Programmatically redo the last undone action.
3363
4935
  *
3364
4936
  * @returns The redone action, or null if nothing to redo
3365
4937
  */
3366
- redo(): EditAction | null;
4938
+ redo(): EditAction_2 | null;
3367
4939
  /**
3368
4940
  * Check if there are any actions that can be undone.
3369
4941
  */
@@ -3379,13 +4951,15 @@ export declare class UndoRedoPlugin extends BaseGridPlugin<UndoRedoConfig> {
3379
4951
  /**
3380
4952
  * Get a copy of the current undo stack.
3381
4953
  */
3382
- getUndoStack(): EditAction[];
4954
+ getUndoStack(): EditAction_2[];
3383
4955
  /**
3384
4956
  * Get a copy of the current redo stack.
3385
4957
  */
3386
- getRedoStack(): EditAction[];
4958
+ getRedoStack(): EditAction_2[];
3387
4959
  }
3388
4960
 
4961
+ export declare const unregisterAggregator: (name: string) => void;
4962
+
3389
4963
  /** Virtual window bookkeeping; modified in-place as scroll position changes. */
3390
4964
  declare interface VirtualState {
3391
4965
  enabled: boolean;
@@ -3423,7 +4997,7 @@ declare interface VisibilityConfig {
3423
4997
  * new VisibilityPlugin({ enabled: true, allowHideAll: false })
3424
4998
  * ```
3425
4999
  */
3426
- export declare class VisibilityPlugin extends BaseGridPlugin<VisibilityConfig> {
5000
+ export declare class VisibilityPlugin extends BaseGridPlugin_2<VisibilityConfig> {
3427
5001
  readonly name = "visibility";
3428
5002
  readonly version = "1.0.0";
3429
5003
  /** Tool panel ID for shell integration */
@@ -3438,7 +5012,7 @@ export declare class VisibilityPlugin extends BaseGridPlugin<VisibilityConfig> {
3438
5012
  /**
3439
5013
  * Register the column visibility tool panel with the shell.
3440
5014
  */
3441
- getToolPanel(): ToolPanelDefinition | undefined;
5015
+ getToolPanel(): ToolPanelDefinition_2 | undefined;
3442
5016
  /**
3443
5017
  * Show the visibility sidebar panel.
3444
5018
  */