@toolbox-web/grid 0.2.5 → 0.2.7

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 (71) hide show
  1. package/all.d.ts +486 -80
  2. package/all.js +1364 -1029
  3. package/all.js.map +1 -1
  4. package/index-DG2CZ_Zo.js +3229 -0
  5. package/index-DG2CZ_Zo.js.map +1 -0
  6. package/index.d.ts +222 -11
  7. package/index.js +25 -3143
  8. package/index.js.map +1 -1
  9. package/lib/plugins/clipboard/index.js +1 -1
  10. package/lib/plugins/clipboard/index.js.map +1 -1
  11. package/lib/plugins/column-virtualization/index.js +1 -1
  12. package/lib/plugins/column-virtualization/index.js.map +1 -1
  13. package/lib/plugins/context-menu/index.js +1 -1
  14. package/lib/plugins/context-menu/index.js.map +1 -1
  15. package/lib/plugins/export/index.js +1 -1
  16. package/lib/plugins/export/index.js.map +1 -1
  17. package/lib/plugins/filtering/index.js +184 -149
  18. package/lib/plugins/filtering/index.js.map +1 -1
  19. package/lib/plugins/grouping-columns/index.js +46 -45
  20. package/lib/plugins/grouping-columns/index.js.map +1 -1
  21. package/lib/plugins/grouping-rows/index.js +117 -83
  22. package/lib/plugins/grouping-rows/index.js.map +1 -1
  23. package/lib/plugins/master-detail/index.js +140 -82
  24. package/lib/plugins/master-detail/index.js.map +1 -1
  25. package/lib/plugins/multi-sort/index.js +18 -18
  26. package/lib/plugins/multi-sort/index.js.map +1 -1
  27. package/lib/plugins/pinned-columns/index.js +1 -1
  28. package/lib/plugins/pinned-columns/index.js.map +1 -1
  29. package/lib/plugins/pinned-rows/index.js +55 -47
  30. package/lib/plugins/pinned-rows/index.js.map +1 -1
  31. package/lib/plugins/pivot/index.js +385 -351
  32. package/lib/plugins/pivot/index.js.map +1 -1
  33. package/lib/plugins/reorder/index.js +278 -85
  34. package/lib/plugins/reorder/index.js.map +1 -1
  35. package/lib/plugins/selection/index.js +28 -27
  36. package/lib/plugins/selection/index.js.map +1 -1
  37. package/lib/plugins/server-side/index.js +2 -2
  38. package/lib/plugins/server-side/index.js.map +1 -1
  39. package/lib/plugins/tree/index.js +181 -170
  40. package/lib/plugins/tree/index.js.map +1 -1
  41. package/lib/plugins/undo-redo/index.js +1 -1
  42. package/lib/plugins/undo-redo/index.js.map +1 -1
  43. package/lib/plugins/visibility/index.js +1 -1
  44. package/lib/plugins/visibility/index.js.map +1 -1
  45. package/package.json +1 -1
  46. package/umd/grid.all.umd.js +22 -22
  47. package/umd/grid.all.umd.js.map +1 -1
  48. package/umd/grid.umd.js +12 -12
  49. package/umd/grid.umd.js.map +1 -1
  50. package/umd/plugins/filtering.umd.js +1 -1
  51. package/umd/plugins/filtering.umd.js.map +1 -1
  52. package/umd/plugins/grouping-columns.umd.js +1 -1
  53. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  54. package/umd/plugins/grouping-rows.umd.js +1 -1
  55. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  56. package/umd/plugins/master-detail.umd.js +1 -1
  57. package/umd/plugins/master-detail.umd.js.map +1 -1
  58. package/umd/plugins/multi-sort.umd.js +1 -1
  59. package/umd/plugins/multi-sort.umd.js.map +1 -1
  60. package/umd/plugins/pinned-rows.umd.js +1 -1
  61. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  62. package/umd/plugins/pivot.umd.js +1 -1
  63. package/umd/plugins/pivot.umd.js.map +1 -1
  64. package/umd/plugins/reorder.umd.js +1 -1
  65. package/umd/plugins/reorder.umd.js.map +1 -1
  66. package/umd/plugins/selection.umd.js +1 -1
  67. package/umd/plugins/selection.umd.js.map +1 -1
  68. package/umd/plugins/server-side.umd.js +1 -1
  69. package/umd/plugins/server-side.umd.js.map +1 -1
  70. package/umd/plugins/tree.umd.js +1 -1
  71. package/umd/plugins/tree.umd.js.map +1 -1
package/all.d.ts CHANGED
@@ -27,10 +27,29 @@ declare interface AggregationRowConfig {
27
27
  label?: string;
28
28
  /** Static or computed cell values keyed by field */
29
29
  cells?: Record<string, unknown | string | ((rows: unknown[], field: string, column?: ColumnConfig_2) => unknown)>;
30
- /** Per-field aggregator override; string maps to registered aggregator key */
31
- aggregators?: Record<string, AggregatorRef_3>;
30
+ /**
31
+ * Per-field aggregator configuration.
32
+ * Can be a simple string ('sum', 'avg', etc.), a function, or an object with aggFunc and formatter.
33
+ * @example
34
+ * aggregators: {
35
+ * quantity: 'sum', // simple built-in
36
+ * price: { aggFunc: 'sum', formatter: (v) => `$${v.toFixed(2)}` } // with formatter
37
+ * }
38
+ */
39
+ aggregators?: Record<string, AggregatorDefinition>;
32
40
  }
33
41
 
42
+ /** Full aggregator config with optional formatter */
43
+ declare interface AggregatorConfig {
44
+ /** The aggregator function or built-in key ('sum', 'avg', 'min', 'max', 'count', 'first', 'last') */
45
+ aggFunc: AggregatorRef_3;
46
+ /** Optional formatter to format the computed value for display */
47
+ formatter?: AggregatorFormatter;
48
+ }
49
+
50
+ /** Aggregator definition - simple string/function or full config object */
51
+ declare type AggregatorDefinition = AggregatorRef_3 | AggregatorConfig;
52
+
34
53
  /**
35
54
  * Aggregators Core Registry
36
55
  *
@@ -59,6 +78,12 @@ export declare type AggregatorFn = (rows: any[], field: string, column?: any) =>
59
78
  */
60
79
  declare type AggregatorFn_2 = (rows: any[], field: string, column?: any) => any;
61
80
 
81
+ /** Aggregator function signature */
82
+ declare type AggregatorFn_3 = (rows: unknown[], field: string, column?: ColumnConfig_2) => unknown;
83
+
84
+ /** Aggregator formatter function - formats the computed value for display */
85
+ declare type AggregatorFormatter = (value: unknown, field: string, column?: ColumnConfig_2) => string;
86
+
62
87
  /** Map of field names to aggregator references */
63
88
  declare type AggregatorMap = Record<string, AggregatorRef_2>;
64
89
 
@@ -71,8 +96,8 @@ declare type AggregatorRef_2 = string | AggregatorFn_2;
71
96
 
72
97
  declare type AggregatorRef_2_2 = string | AggregatorFn;
73
98
 
74
- /** Aggregator reference - string key for built-in or custom function */
75
- declare type AggregatorRef_3 = string | ((rows: unknown[], field: string, column?: ColumnConfig_2) => unknown);
99
+ /** Simple aggregator reference - string key for built-in or custom function */
100
+ declare type AggregatorRef_3 = string | AggregatorFn_3;
76
101
 
77
102
  /**
78
103
  * The aggregator registry singleton.
@@ -105,6 +130,48 @@ export declare const aggregatorRegistry: {
105
130
  list(): string[];
106
131
  };
107
132
 
133
+ /**
134
+ * Grid-wide animation configuration.
135
+ * Controls global animation behavior - individual plugins define their own animation styles.
136
+ * Duration and easing values set corresponding CSS variables on the grid element.
137
+ */
138
+ export declare interface AnimationConfig {
139
+ /**
140
+ * Global animation mode.
141
+ * @default 'reduced-motion'
142
+ */
143
+ mode?: AnimationMode;
144
+ /**
145
+ * Default animation duration in milliseconds.
146
+ * Sets `--tbw-animation-duration` CSS variable.
147
+ * @default 200
148
+ */
149
+ duration?: number;
150
+ /**
151
+ * Default easing function.
152
+ * Sets `--tbw-animation-easing` CSS variable.
153
+ * @default 'ease-out'
154
+ */
155
+ easing?: string;
156
+ }
157
+
158
+ /**
159
+ * Animation behavior mode.
160
+ * - `true` or `'on'`: Animations always enabled
161
+ * - `false` or `'off'`: Animations always disabled
162
+ * - `'reduced-motion'`: Respects `prefers-reduced-motion` media query (default)
163
+ */
164
+ export declare type AnimationMode = boolean | 'on' | 'off' | 'reduced-motion';
165
+
166
+ /**
167
+ * Animation style for visual transitions.
168
+ * - `'slide'`: Slide/transform animation (e.g., expand down, slide left/right)
169
+ * - `'fade'`: Opacity fade animation
170
+ * - `'flip'`: FLIP technique for position changes (First, Last, Invert, Play)
171
+ * - `false`: No animation for this specific feature
172
+ */
173
+ export declare type AnimationStyle = 'slide' | 'fade' | 'flip' | false;
174
+
108
175
  /**
109
176
  * Base contract for a column. Public; kept intentionally lean so host apps can extend via intersection types.
110
177
  * Prefer adding optional properties here only when broadly useful to most grids.
@@ -169,7 +236,7 @@ export declare abstract class BaseGridPlugin<TConfig = unknown> implements GridP
169
236
  /** Plugin configuration - merged with defaults in attach() */
170
237
  protected config: TConfig;
171
238
  /** User-provided configuration from constructor */
172
- private readonly userConfig;
239
+ protected readonly userConfig: Partial<TConfig>;
173
240
  /**
174
241
  * Default configuration - subclasses should override this getter.
175
242
  * Note: This must be a getter (not property initializer) for proper inheritance
@@ -764,7 +831,7 @@ declare abstract class BaseGridPlugin_2<TConfig = unknown> implements GridPlugin
764
831
  /** Plugin configuration - merged with defaults in attach() */
765
832
  protected config: TConfig;
766
833
  /** User-provided configuration from constructor */
767
- private readonly userConfig;
834
+ protected readonly userConfig: Partial<TConfig>;
768
835
  /**
769
836
  * Default configuration - subclasses should override this getter.
770
837
  * Note: This must be a getter (not property initializer) for proper inheritance
@@ -1336,6 +1403,12 @@ declare abstract class BaseGridPlugin_2<TConfig = unknown> implements GridPlugin
1336
1403
  getHeaderContent?(): HeaderContentDefinition_2 | undefined;
1337
1404
  }
1338
1405
 
1406
+ /**
1407
+ * Built-in sort implementation using column comparator or default.
1408
+ * This is the default sortHandler when none is configured.
1409
+ */
1410
+ export declare function builtInSort<T>(rows: T[], sortState: SortState, columns: ColumnConfig<T>[]): T[];
1411
+
1339
1412
  /**
1340
1413
  * Cell click event
1341
1414
  */
@@ -2095,6 +2168,11 @@ export declare class DataGridElement<T = any> extends HTMLElement implements Int
2095
2168
  * Returns true if any plugin handled the event.
2096
2169
  */
2097
2170
  _dispatchCellClick(event: MouseEvent, rowIndex: number, colIndex: number, cellEl: HTMLElement): boolean;
2171
+ /**
2172
+ * Dispatch a row click event to the plugin system.
2173
+ * Returns true if any plugin handled the event.
2174
+ */
2175
+ _dispatchRowClick(event: MouseEvent, rowIndex: number, row: any, rowEl: HTMLElement): boolean;
2098
2176
  /**
2099
2177
  * Dispatch a header click event to the plugin system.
2100
2178
  * Returns true if any plugin handled the event.
@@ -2261,12 +2339,21 @@ declare interface DataRowModelItem {
2261
2339
  rowIndex: number;
2262
2340
  }
2263
2341
 
2342
+ /** Default animation configuration */
2343
+ export declare const DEFAULT_ANIMATION_CONFIG: Required<Omit<AnimationConfig, 'sort'>>;
2344
+
2264
2345
  /** Default icons used when not overridden */
2265
2346
  export declare const DEFAULT_GRID_ICONS: Required<GridIcons>;
2266
2347
 
2267
2348
  /** Default icons used when not overridden */
2268
2349
  declare const DEFAULT_GRID_ICONS_2: Required<GridIcons_2>;
2269
2350
 
2351
+ /**
2352
+ * Default comparator for sorting values.
2353
+ * Handles nulls (pushed to end), numbers, and string fallback.
2354
+ */
2355
+ export declare function defaultComparator(a: unknown, b: unknown): number;
2356
+
2270
2357
  export declare type DGEventName = (typeof DGEvents)[keyof typeof DGEvents];
2271
2358
 
2272
2359
  export declare const DGEvents: {
@@ -2322,6 +2409,42 @@ declare interface EditorExecContext<T = any> extends CellContext<T> {
2322
2409
  cancel: () => void;
2323
2410
  }
2324
2411
 
2412
+ /** Animation style for expand/collapse */
2413
+ declare type ExpandCollapseAnimation = false | 'slide' | 'fade';
2414
+
2415
+ /**
2416
+ * Master/Detail Plugin Types
2417
+ *
2418
+ * Type definitions for expandable detail rows showing additional content.
2419
+ */
2420
+ /** Animation style for expand/collapse */
2421
+ declare type ExpandCollapseAnimation_2 = false | 'slide' | 'fade';
2422
+
2423
+ /** Animation style for expand/collapse */
2424
+ declare type ExpandCollapseAnimation_2_2 = false | 'slide' | 'fade';
2425
+
2426
+ /** Animation style for expand/collapse */
2427
+ declare type ExpandCollapseAnimation_3 = false | 'slide' | 'fade';
2428
+
2429
+ /** Animation style for expand/collapse */
2430
+ declare type ExpandCollapseAnimation_3_2 = false | 'slide' | 'fade';
2431
+
2432
+ /**
2433
+ * Tree Data Plugin Types
2434
+ *
2435
+ * Type definitions for hierarchical tree data with expand/collapse functionality.
2436
+ */
2437
+ /** Animation style for expand/collapse */
2438
+ declare type ExpandCollapseAnimation_4 = false | 'slide' | 'fade';
2439
+
2440
+ /**
2441
+ * Tree Data Plugin Types
2442
+ *
2443
+ * Type definitions for hierarchical tree data with expand/collapse functionality.
2444
+ */
2445
+ /** Animation style for expand/collapse */
2446
+ declare type ExpandCollapseAnimation_5 = false | 'slide' | 'fade';
2447
+
2325
2448
  /** Configuration options for the export plugin */
2326
2449
  declare interface ExportConfig {
2327
2450
  /** Default file name for exports (default: 'export') */
@@ -2462,7 +2585,7 @@ export declare interface ExternalMountViewDetail<TRow = unknown> {
2462
2585
  }
2463
2586
 
2464
2587
  /** Configuration options for the filtering plugin */
2465
- export declare interface FilterConfig {
2588
+ export declare interface FilterConfig<TRow = unknown> {
2466
2589
  /** Debounce delay in ms for filter input (default: 300) */
2467
2590
  debounceMs?: number;
2468
2591
  /** Whether text filtering is case sensitive (default: false) */
@@ -2473,10 +2596,25 @@ export declare interface FilterConfig {
2473
2596
  useWorker?: boolean;
2474
2597
  /** Custom filter panel renderer (replaces default panel content) */
2475
2598
  filterPanelRenderer?: FilterPanelRenderer_2;
2599
+ /**
2600
+ * Async handler for fetching unique values from a server.
2601
+ * When provided, this is called instead of extracting values from local rows.
2602
+ * Useful for server-side datasets where not all data is loaded.
2603
+ */
2604
+ valuesHandler?: FilterValuesHandler;
2605
+ /**
2606
+ * Async handler for applying filters on a server.
2607
+ * When provided, filtering is delegated to the server instead of local filtering.
2608
+ * Should return the filtered rows from the server.
2609
+ *
2610
+ * Note: When using filterHandler, processRows() becomes a passthrough
2611
+ * and the returned rows replace the grid's data.
2612
+ */
2613
+ filterHandler?: FilterHandler<TRow>;
2476
2614
  }
2477
2615
 
2478
2616
  /** Configuration options for the filtering plugin */
2479
- declare interface FilterConfig_2 {
2617
+ declare interface FilterConfig_2<TRow = unknown> {
2480
2618
  /** Debounce delay in ms for filter input (default: 300) */
2481
2619
  debounceMs?: number;
2482
2620
  /** Whether text filtering is case sensitive (default: false) */
@@ -2487,8 +2625,69 @@ declare interface FilterConfig_2 {
2487
2625
  useWorker?: boolean;
2488
2626
  /** Custom filter panel renderer (replaces default panel content) */
2489
2627
  filterPanelRenderer?: FilterPanelRenderer;
2628
+ /**
2629
+ * Async handler for fetching unique values from a server.
2630
+ * When provided, this is called instead of extracting values from local rows.
2631
+ * Useful for server-side datasets where not all data is loaded.
2632
+ */
2633
+ valuesHandler?: FilterValuesHandler_2;
2634
+ /**
2635
+ * Async handler for applying filters on a server.
2636
+ * When provided, filtering is delegated to the server instead of local filtering.
2637
+ * Should return the filtered rows from the server.
2638
+ *
2639
+ * Note: When using filterHandler, processRows() becomes a passthrough
2640
+ * and the returned rows replace the grid's data.
2641
+ */
2642
+ filterHandler?: FilterHandler_2<TRow>;
2490
2643
  }
2491
2644
 
2645
+ /**
2646
+ * Async handler for applying filters on a server.
2647
+ *
2648
+ * For server-side filtering, this handler is called when filters change.
2649
+ * It should fetch filtered data from the server and return the new rows.
2650
+ * The plugin will replace the grid's rows with the returned data.
2651
+ *
2652
+ * @param filters - Current active filter models
2653
+ * @param currentRows - Current row array (for reference/optimistic updates)
2654
+ * @returns Promise resolving to filtered rows
2655
+ *
2656
+ * @example
2657
+ * ```ts
2658
+ * filterHandler: async (filters) => {
2659
+ * const params = new URLSearchParams();
2660
+ * filters.forEach(f => params.append(f.field, `${f.operator}:${f.value}`));
2661
+ * const response = await fetch(`/api/data?${params}`);
2662
+ * return response.json();
2663
+ * }
2664
+ * ```
2665
+ */
2666
+ export declare type FilterHandler<TRow = unknown> = (filters: FilterModel[], currentRows: TRow[]) => TRow[] | Promise<TRow[]>;
2667
+
2668
+ /**
2669
+ * Async handler for applying filters on a server.
2670
+ *
2671
+ * For server-side filtering, this handler is called when filters change.
2672
+ * It should fetch filtered data from the server and return the new rows.
2673
+ * The plugin will replace the grid's rows with the returned data.
2674
+ *
2675
+ * @param filters - Current active filter models
2676
+ * @param currentRows - Current row array (for reference/optimistic updates)
2677
+ * @returns Promise resolving to filtered rows
2678
+ *
2679
+ * @example
2680
+ * ```ts
2681
+ * filterHandler: async (filters) => {
2682
+ * const params = new URLSearchParams();
2683
+ * filters.forEach(f => params.append(f.field, `${f.operator}:${f.value}`));
2684
+ * const response = await fetch(`/api/data?${params}`);
2685
+ * return response.json();
2686
+ * }
2687
+ * ```
2688
+ */
2689
+ declare type FilterHandler_2<TRow = unknown> = (filters: FilterModel_2[], currentRows: TRow[]) => TRow[] | Promise<TRow[]>;
2690
+
2492
2691
  /**
2493
2692
  * Filtering Plugin for tbw-grid
2494
2693
  *
@@ -2571,6 +2770,14 @@ export declare class FilteringPlugin extends BaseGridPlugin_2<FilterConfig_2> {
2571
2770
  * Toggle the filter panel for a field
2572
2771
  */
2573
2772
  private toggleFilterPanel;
2773
+ /**
2774
+ * Render filter panel content with given values
2775
+ */
2776
+ private renderPanelContent;
2777
+ /**
2778
+ * Setup click-outside handler to close the panel
2779
+ */
2780
+ private setupPanelCloseHandler;
2574
2781
  /**
2575
2782
  * Close the filter panel
2576
2783
  */
@@ -2591,6 +2798,10 @@ export declare class FilteringPlugin extends BaseGridPlugin_2<FilterConfig_2> {
2591
2798
  * Apply a text filter
2592
2799
  */
2593
2800
  private applyTextFilter;
2801
+ /**
2802
+ * Internal method to apply filters (sync or async based on config)
2803
+ */
2804
+ private applyFiltersInternal;
2594
2805
  /**
2595
2806
  * Return filter state for a column if it has an active filter.
2596
2807
  */
@@ -2692,6 +2903,48 @@ export declare type FilterType = 'text' | 'number' | 'date' | 'set' | 'boolean';
2692
2903
  /** Supported filter types */
2693
2904
  declare type FilterType_2 = 'text' | 'number' | 'date' | 'set' | 'boolean';
2694
2905
 
2906
+ /**
2907
+ * Async handler for fetching unique filter values from a server.
2908
+ *
2909
+ * For server-side datasets where not all values are available locally,
2910
+ * this handler is called when the filter panel opens to fetch all
2911
+ * possible values for the column.
2912
+ *
2913
+ * @param field - The field/column name
2914
+ * @param column - The column configuration
2915
+ * @returns Promise resolving to array of unique values
2916
+ *
2917
+ * @example
2918
+ * ```ts
2919
+ * valuesHandler: async (field, column) => {
2920
+ * const response = await fetch(`/api/distinct/${field}`);
2921
+ * return response.json(); // ['Engineering', 'Marketing', 'Sales', ...]
2922
+ * }
2923
+ * ```
2924
+ */
2925
+ export declare type FilterValuesHandler = (field: string, column: ColumnConfig) => Promise<unknown[]>;
2926
+
2927
+ /**
2928
+ * Async handler for fetching unique filter values from a server.
2929
+ *
2930
+ * For server-side datasets where not all values are available locally,
2931
+ * this handler is called when the filter panel opens to fetch all
2932
+ * possible values for the column.
2933
+ *
2934
+ * @param field - The field/column name
2935
+ * @param column - The column configuration
2936
+ * @returns Promise resolving to array of unique values
2937
+ *
2938
+ * @example
2939
+ * ```ts
2940
+ * valuesHandler: async (field, column) => {
2941
+ * const response = await fetch(`/api/distinct/${field}`);
2942
+ * return response.json(); // ['Engineering', 'Marketing', 'Sales', ...]
2943
+ * }
2944
+ * ```
2945
+ */
2946
+ declare type FilterValuesHandler_2 = (field: string, column: ColumnConfig_2) => Promise<unknown[]>;
2947
+
2695
2948
  export declare type FitMode = (typeof FitModeEnum)[keyof typeof FitModeEnum];
2696
2949
 
2697
2950
  export declare const FitModeEnum: {
@@ -2901,6 +3154,41 @@ export declare interface GridConfig<TRow = any> {
2901
3154
  * Plugins will use these by default but can override with their own config.
2902
3155
  */
2903
3156
  icons?: GridIcons;
3157
+ /**
3158
+ * Grid-wide animation configuration.
3159
+ * Controls animations for expand/collapse, reordering, and other visual transitions.
3160
+ * Individual plugins can override these defaults in their own config.
3161
+ */
3162
+ animation?: AnimationConfig;
3163
+ /**
3164
+ * Custom sort handler for full control over sorting behavior.
3165
+ *
3166
+ * When provided, this handler is called instead of the built-in sorting logic.
3167
+ * Enables custom sorting algorithms, server-side sorting, or plugin-specific sorting.
3168
+ *
3169
+ * The handler receives:
3170
+ * - `rows`: Current row array to sort
3171
+ * - `sortState`: Sort field and direction (1 = asc, -1 = desc)
3172
+ * - `columns`: Column configurations (for accessing sortComparator)
3173
+ *
3174
+ * Return the sorted array (sync) or a Promise that resolves to the sorted array (async).
3175
+ * For server-side sorting, return a Promise that resolves when data is fetched.
3176
+ *
3177
+ * @example
3178
+ * ```ts
3179
+ * // Custom stable sort
3180
+ * sortHandler: (rows, state, cols) => {
3181
+ * return stableSort(rows, (a, b) => compare(a[state.field], b[state.field]) * state.direction);
3182
+ * }
3183
+ *
3184
+ * // Server-side sorting
3185
+ * sortHandler: async (rows, state) => {
3186
+ * const response = await fetch(`/api/data?sort=${state.field}&dir=${state.direction}`);
3187
+ * return response.json();
3188
+ * }
3189
+ * ```
3190
+ */
3191
+ sortHandler?: SortHandler<TRow>;
2904
3192
  }
2905
3193
 
2906
3194
  export declare type GridCSSVar = (typeof GridCSSVars)[keyof typeof GridCSSVars];
@@ -2949,10 +3237,8 @@ export declare interface GridElement {
2949
3237
  rows: any[];
2950
3238
  columns: ColumnConfig[];
2951
3239
  gridConfig: any;
2952
- /** Current focused row index */
2953
- focusRow: number;
2954
- /** Current focused column index */
2955
- focusCol: number;
3240
+ /* Excluded from this release type: _focusRow */
3241
+ /* Excluded from this release type: _focusCol */
2956
3242
  /** AbortSignal that is aborted when the grid disconnects from the DOM */
2957
3243
  disconnectSignal: AbortSignal;
2958
3244
  requestRender(): void;
@@ -2968,10 +3254,8 @@ declare interface GridElement_2 {
2968
3254
  rows: any[];
2969
3255
  columns: ColumnConfig_2[];
2970
3256
  gridConfig: any;
2971
- /** Current focused row index */
2972
- focusRow: number;
2973
- /** Current focused column index */
2974
- focusCol: number;
3257
+ /* Excluded from this release type: _focusRow */
3258
+ /* Excluded from this release type: _focusCol */
2975
3259
  /** AbortSignal that is aborted when the grid disconnects from the DOM */
2976
3260
  disconnectSignal: AbortSignal;
2977
3261
  requestRender(): void;
@@ -3167,6 +3451,14 @@ export declare interface GroupingRowsConfig {
3167
3451
  formatLabel?: (value: any, depth: number, key: string) => string;
3168
3452
  /** Whether to render group row as full-width spanning cell (default: true) */
3169
3453
  fullWidth?: boolean;
3454
+ /**
3455
+ * Animation style for expanding/collapsing groups.
3456
+ * - `false`: No animation
3457
+ * - `'slide'`: Slide animation (default)
3458
+ * - `'fade'`: Fade animation
3459
+ * @default 'slide'
3460
+ */
3461
+ animation?: ExpandCollapseAnimation_3_2;
3170
3462
  }
3171
3463
 
3172
3464
  /** Configuration options for the row grouping plugin */
@@ -3190,6 +3482,14 @@ declare interface GroupingRowsConfig_2 {
3190
3482
  formatLabel?: (value: any, depth: number, key: string) => string;
3191
3483
  /** Whether to render group row as full-width spanning cell (default: true) */
3192
3484
  fullWidth?: boolean;
3485
+ /**
3486
+ * Animation style for expanding/collapsing groups.
3487
+ * - `false`: No animation
3488
+ * - `'slide'`: Slide animation (default)
3489
+ * - `'fade'`: Fade animation
3490
+ * @default 'slide'
3491
+ */
3492
+ animation?: ExpandCollapseAnimation;
3193
3493
  }
3194
3494
 
3195
3495
  /**
@@ -3212,6 +3512,9 @@ export declare class GroupingRowsPlugin extends BaseGridPlugin_2<GroupingRowsCon
3212
3512
  private expandedKeys;
3213
3513
  private flattenedRows;
3214
3514
  private isActive;
3515
+ private previousVisibleKeys;
3516
+ private keysToAnimate;
3517
+ private get animationStyle();
3215
3518
  detach(): void;
3216
3519
  /**
3217
3520
  * Auto-detect grouping configuration from grid config.
@@ -3462,6 +3765,8 @@ declare interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
3462
3765
  commitActiveRowEdit?: () => void;
3463
3766
  /** Dispatch cell click to plugin system, returns true if handled */
3464
3767
  _dispatchCellClick?: (event: MouseEvent, rowIndex: number, colIndex: number, cellEl: HTMLElement) => boolean;
3768
+ /** Dispatch row click to plugin system, returns true if handled */
3769
+ _dispatchRowClick?: (event: MouseEvent, rowIndex: number, row: any, rowEl: HTMLElement) => boolean;
3465
3770
  /** Dispatch header click to plugin system, returns true if handled */
3466
3771
  _dispatchHeaderClick?: (event: MouseEvent, colIndex: number, headerEl: HTMLElement) => boolean;
3467
3772
  /** Dispatch keydown to plugin system, returns true if handled */
@@ -3490,11 +3795,6 @@ export declare interface KeyboardModifiers {
3490
3795
 
3491
3796
  export declare const listAggregators: () => string[];
3492
3797
 
3493
- /**
3494
- * Master/Detail Plugin Types
3495
- *
3496
- * Type definitions for expandable detail rows showing additional content.
3497
- */
3498
3798
  /** Configuration options for the master-detail plugin */
3499
3799
  declare interface MasterDetailConfig {
3500
3800
  /** Renderer function that returns detail content for a row */
@@ -3507,6 +3807,14 @@ declare interface MasterDetailConfig {
3507
3807
  collapseOnClickOutside?: boolean;
3508
3808
  /** Show expand/collapse column (default: true) */
3509
3809
  showExpandColumn?: boolean;
3810
+ /**
3811
+ * Animation style for expanding/collapsing detail rows.
3812
+ * - `false`: No animation
3813
+ * - `'slide'`: Slide down/up animation (default)
3814
+ * - `'fade'`: Fade in/out animation
3815
+ * @default 'slide'
3816
+ */
3817
+ animation?: ExpandCollapseAnimation_2;
3510
3818
  }
3511
3819
 
3512
3820
  /**
@@ -3526,6 +3834,27 @@ export declare class MasterDetailPlugin extends BaseGridPlugin_2<MasterDetailCon
3526
3834
  readonly name = "masterDetail";
3527
3835
  readonly version = "1.0.0";
3528
3836
  protected get defaultConfig(): Partial<MasterDetailConfig>;
3837
+ /**
3838
+ * Check if animations are enabled at the grid level.
3839
+ * Respects gridConfig.animation.mode and CSS variable.
3840
+ */
3841
+ private get isAnimationEnabled();
3842
+ /**
3843
+ * Get expand/collapse animation style from plugin config.
3844
+ */
3845
+ private get animationStyle();
3846
+ /**
3847
+ * Get animation duration from CSS variable (set by grid).
3848
+ */
3849
+ private get animationDuration();
3850
+ /**
3851
+ * Apply expand animation to a detail element.
3852
+ */
3853
+ private animateExpand;
3854
+ /**
3855
+ * Apply collapse animation to a detail element and remove after animation.
3856
+ */
3857
+ private animateCollapse;
3529
3858
  private expandedRows;
3530
3859
  private detailElements;
3531
3860
  detach(): void;
@@ -3876,6 +4205,16 @@ export declare interface PivotConfig {
3876
4205
  defaultExpanded?: boolean;
3877
4206
  /** Indent width per depth level in pixels (default: 20) */
3878
4207
  indentWidth?: number;
4208
+ /** Whether to show the pivot configuration tool panel (default: true) */
4209
+ showToolPanel?: boolean;
4210
+ /**
4211
+ * Animation style for expanding/collapsing groups.
4212
+ * - `false`: No animation
4213
+ * - `'slide'`: Slide animation (default)
4214
+ * - `'fade'`: Fade animation
4215
+ * @default 'slide'
4216
+ */
4217
+ animation?: ExpandCollapseAnimation_2_2;
3879
4218
  }
3880
4219
 
3881
4220
  declare interface PivotConfig_2 {
@@ -3890,6 +4229,16 @@ declare interface PivotConfig_2 {
3890
4229
  defaultExpanded?: boolean;
3891
4230
  /** Indent width per depth level in pixels (default: 20) */
3892
4231
  indentWidth?: number;
4232
+ /** Whether to show the pivot configuration tool panel (default: true) */
4233
+ showToolPanel?: boolean;
4234
+ /**
4235
+ * Animation style for expanding/collapsing groups.
4236
+ * - `false`: No animation
4237
+ * - `'slide'`: Slide animation (default)
4238
+ * - `'fade'`: Fade animation
4239
+ * @default 'slide'
4240
+ */
4241
+ animation?: ExpandCollapseAnimation_3;
3893
4242
  }
3894
4243
 
3895
4244
  declare type PivotDataRow = Record<string, unknown>;
@@ -3921,10 +4270,16 @@ export declare class PivotPlugin extends BaseGridPlugin_2<PivotConfig_2> {
3921
4270
  private originalColumns;
3922
4271
  private panelContainer;
3923
4272
  private grandTotalFooter;
4273
+ private previousVisibleKeys;
4274
+ private keysToAnimate;
3924
4275
  /**
3925
4276
  * Check if the plugin has valid pivot configuration (at least value fields).
3926
4277
  */
3927
4278
  private hasValidPivotConfig;
4279
+ /**
4280
+ * Get animation style respecting grid-level animation mode.
4281
+ */
4282
+ private get animationStyle();
3928
4283
  detach(): void;
3929
4284
  getToolPanel(): ToolPanelDefinition_2 | undefined;
3930
4285
  processRows(rows: readonly unknown[]): PivotDataRow[];
@@ -4401,12 +4756,30 @@ declare type RenderRow = GroupRowModelItem | DataRowModelItem;
4401
4756
  *
4402
4757
  * Type definitions for the column reordering feature.
4403
4758
  */
4759
+ /** Animation type for column reordering */
4760
+ declare type ReorderAnimation = false | 'flip' | 'fade';
4761
+
4404
4762
  /** Configuration options for the reorder plugin */
4405
4763
  declare interface ReorderConfig {
4406
- /** Whether to animate column movement (default: true) */
4407
- animation?: boolean;
4408
- /** Animation duration in milliseconds (default: 200) */
4764
+ /**
4765
+ * Animation type for column movement.
4766
+ * - `false`: No animation, instant reorder
4767
+ * - `'flip'`: FLIP animation (slides columns smoothly)
4768
+ * - `'fade'`: View Transitions API (cross-fade effect)
4769
+ * @default 'flip'
4770
+ */
4771
+ animation?: ReorderAnimation;
4772
+ /**
4773
+ * Animation duration in milliseconds.
4774
+ * Applies to FLIP animation. View Transitions use browser defaults.
4775
+ * @default 200
4776
+ */
4409
4777
  animationDuration?: number;
4778
+ /**
4779
+ * @deprecated Use `animation` instead. Will be removed in next major version.
4780
+ * Use View Transitions API for smooth column movement.
4781
+ */
4782
+ viewTransition?: boolean;
4410
4783
  }
4411
4784
 
4412
4785
  /**
@@ -4414,17 +4787,27 @@ declare interface ReorderConfig {
4414
4787
  *
4415
4788
  * @example
4416
4789
  * ```ts
4417
- * new ReorderPlugin({
4418
- * enabled: true,
4419
- * animation: true,
4420
- * animationDuration: 200,
4421
- * })
4790
+ * new ReorderPlugin()
4422
4791
  * ```
4423
4792
  */
4424
4793
  export declare class ReorderPlugin extends BaseGridPlugin_2<ReorderConfig> {
4425
4794
  readonly name = "reorder";
4426
4795
  readonly version = "1.0.0";
4427
4796
  protected get defaultConfig(): Partial<ReorderConfig>;
4797
+ /**
4798
+ * Resolve animation type from plugin config.
4799
+ * Respects grid-level animation.mode (disabled = no animation).
4800
+ */
4801
+ private get animationType();
4802
+ /**
4803
+ * Check if animations are enabled at the grid level.
4804
+ * Respects gridConfig.animation.mode and CSS variable.
4805
+ */
4806
+ private get isAnimationEnabled();
4807
+ /**
4808
+ * Get animation duration from CSS variable (set by grid config).
4809
+ */
4810
+ private get animationDuration();
4428
4811
  private isDragging;
4429
4812
  private draggedField;
4430
4813
  private draggedIndex;
@@ -4432,6 +4815,10 @@ export declare class ReorderPlugin extends BaseGridPlugin_2<ReorderConfig> {
4432
4815
  attach(grid: GridElement_2): void;
4433
4816
  detach(): void;
4434
4817
  afterRender(): void;
4818
+ /**
4819
+ * Handle Alt+Arrow keyboard shortcuts for column reordering.
4820
+ */
4821
+ onKeyDown(event: KeyboardEvent): boolean | void;
4435
4822
  /**
4436
4823
  * Get the current column order from the grid.
4437
4824
  * @returns Array of field names in display order
@@ -4452,6 +4839,25 @@ export declare class ReorderPlugin extends BaseGridPlugin_2<ReorderConfig> {
4452
4839
  * Reset column order to the original configuration order.
4453
4840
  */
4454
4841
  resetColumnOrder(): void;
4842
+ /**
4843
+ * Capture header cell positions before reorder.
4844
+ */
4845
+ private captureHeaderPositions;
4846
+ /**
4847
+ * Apply FLIP animation for column reorder.
4848
+ * Uses CSS transitions - JS sets initial transform and toggles class.
4849
+ * @param oldPositions - Header positions captured before DOM change
4850
+ */
4851
+ private animateFLIP;
4852
+ /**
4853
+ * Apply crossfade animation for moved columns.
4854
+ * Uses CSS keyframes - JS just toggles classes.
4855
+ */
4856
+ private animateFade;
4857
+ /**
4858
+ * Update column order with configured animation.
4859
+ */
4860
+ private updateColumnOrder;
4455
4861
  readonly styles: string;
4456
4862
  }
4457
4863
 
@@ -4623,6 +5029,8 @@ export declare class SelectionPlugin extends BaseGridPlugin_2<SelectionConfig_2>
4623
5029
  private activeRange;
4624
5030
  private cellAnchor;
4625
5031
  private isDragging;
5032
+ /** Pending keyboard navigation update (processed in afterRender) */
5033
+ private pendingKeyboardUpdate;
4626
5034
  /** Cell selection state (cell mode) */
4627
5035
  private selectedCell;
4628
5036
  detach(): void;
@@ -4770,6 +5178,16 @@ export declare interface SortChangeDetail {
4770
5178
  direction: 1 | -1 | 0;
4771
5179
  }
4772
5180
 
5181
+ /**
5182
+ * Custom sort handler function signature.
5183
+ *
5184
+ * @param rows - Current row array to sort
5185
+ * @param sortState - Sort field and direction
5186
+ * @param columns - Column configurations (for accessing sortComparator)
5187
+ * @returns Sorted array (sync) or Promise resolving to sorted array (async)
5188
+ */
5189
+ export declare type SortHandler<TRow = any> = (rows: TRow[], sortState: SortState, columns: ColumnConfig<TRow>[]) => TRow[] | Promise<TRow[]>;
5190
+
4773
5191
  /**
4774
5192
  * Multi-Sort Plugin Types
4775
5193
  *
@@ -4796,6 +5214,16 @@ declare interface SortModel_2 {
4796
5214
  direction: 'asc' | 'desc';
4797
5215
  }
4798
5216
 
5217
+ /**
5218
+ * Sort state passed to custom sort handlers.
5219
+ */
5220
+ export declare interface SortState {
5221
+ /** Field to sort by */
5222
+ field: string;
5223
+ /** Sort direction: 1 = ascending, -1 = descending */
5224
+ direction: 1 | -1;
5225
+ }
5226
+
4799
5227
  /**
4800
5228
  * Toolbar button defined via config (programmatic approach).
4801
5229
  * Supports three modes:
@@ -4896,11 +5324,6 @@ declare interface ToolPanelDefinition_2 {
4896
5324
  order?: number;
4897
5325
  }
4898
5326
 
4899
- /**
4900
- * Tree Data Plugin Types
4901
- *
4902
- * Type definitions for hierarchical tree data with expand/collapse functionality.
4903
- */
4904
5327
  /** Configuration options for the tree plugin */
4905
5328
  export declare interface TreeConfig {
4906
5329
  /** Field name containing child rows (default: 'children') */
@@ -4913,13 +5336,16 @@ export declare interface TreeConfig {
4913
5336
  indentWidth?: number;
4914
5337
  /** Show expand/collapse icons (default: true) */
4915
5338
  showExpandIcons?: boolean;
5339
+ /**
5340
+ * Animation style for expanding/collapsing tree nodes.
5341
+ * - `false`: No animation
5342
+ * - `'slide'`: Slide animation (default)
5343
+ * - `'fade'`: Fade animation
5344
+ * @default 'slide'
5345
+ */
5346
+ animation?: ExpandCollapseAnimation_5;
4916
5347
  }
4917
5348
 
4918
- /**
4919
- * Tree Data Plugin Types
4920
- *
4921
- * Type definitions for hierarchical tree data with expand/collapse functionality.
4922
- */
4923
5349
  /** Configuration options for the tree plugin */
4924
5350
  declare interface TreeConfig_2 {
4925
5351
  /** Field name containing child rows (default: 'children') */
@@ -4932,6 +5358,14 @@ declare interface TreeConfig_2 {
4932
5358
  indentWidth?: number;
4933
5359
  /** Show expand/collapse icons (default: true) */
4934
5360
  showExpandIcons?: boolean;
5361
+ /**
5362
+ * Animation style for expanding/collapsing tree nodes.
5363
+ * - `false`: No animation
5364
+ * - `'slide'`: Slide animation (default)
5365
+ * - `'fade'`: Fade animation
5366
+ * @default 'slide'
5367
+ */
5368
+ animation?: ExpandCollapseAnimation_4;
4935
5369
  }
4936
5370
 
4937
5371
  /** Event detail emitted when a tree node is expanded or collapsed */
@@ -4949,8 +5383,6 @@ export declare interface TreeExpandDetail {
4949
5383
  /**
4950
5384
  * Tree Data Plugin for tbw-grid
4951
5385
  *
4952
- * Provides hierarchical tree data display with expand/collapse functionality.
4953
- *
4954
5386
  * @example
4955
5387
  * ```ts
4956
5388
  * new TreePlugin({ defaultExpanded: true, indentWidth: 24 })
@@ -4959,65 +5391,39 @@ export declare interface TreeExpandDetail {
4959
5391
  export declare class TreePlugin extends BaseGridPlugin_2<TreeConfig_2> {
4960
5392
  readonly name = "tree";
4961
5393
  readonly version = "1.0.0";
5394
+ readonly styles: string;
4962
5395
  protected get defaultConfig(): Partial<TreeConfig_2>;
4963
- /** Set of expanded row keys */
4964
5396
  private expandedKeys;
4965
- /** Whether initial expansion (based on defaultExpanded config) has been applied */
4966
5397
  private initialExpansionDone;
4967
- /** Flattened tree rows for rendering */
4968
5398
  private flattenedRows;
4969
- /** Map from key to flattened row for quick lookup */
4970
5399
  private rowKeyMap;
5400
+ private previousVisibleKeys;
5401
+ private keysToAnimate;
5402
+ private sortState;
4971
5403
  detach(): void;
4972
- /**
4973
- * Detects if tree functionality should be enabled based on data structure.
4974
- * Called by the grid during plugin initialization.
4975
- */
5404
+ private get animationStyle();
4976
5405
  detect(rows: readonly unknown[]): boolean;
4977
5406
  processRows(rows: readonly unknown[]): any[];
5407
+ /** Assign stable keys to rows (preserves key across sort operations) */
5408
+ private withStableKeys;
5409
+ /** Flatten tree using stable keys */
5410
+ private flattenTree;
5411
+ /** Sort tree recursively, keeping children with parents */
5412
+ private sortTree;
4978
5413
  processColumns(columns: readonly ColumnConfig_2[]): ColumnConfig_2[];
4979
5414
  onCellClick(event: CellClickEvent_2): boolean;
4980
- /**
4981
- * Expand a specific node by key.
4982
- */
5415
+ onHeaderClick(event: HeaderClickEvent_2): boolean;
5416
+ afterRender(): void;
4983
5417
  expand(key: string): void;
4984
- /**
4985
- * Collapse a specific node by key.
4986
- */
4987
5418
  collapse(key: string): void;
4988
- /**
4989
- * Toggle the expansion state of a node.
4990
- */
4991
5419
  toggle(key: string): void;
4992
- /**
4993
- * Expand all nodes in the tree.
4994
- */
4995
5420
  expandAll(): void;
4996
- /**
4997
- * Collapse all nodes in the tree.
4998
- */
4999
5421
  collapseAll(): void;
5000
- /**
5001
- * Check if a node is currently expanded.
5002
- */
5003
5422
  isExpanded(key: string): boolean;
5004
- /**
5005
- * Get all currently expanded keys.
5006
- */
5007
5423
  getExpandedKeys(): string[];
5008
- /**
5009
- * Get the flattened tree rows with metadata.
5010
- */
5011
5424
  getFlattenedRows(): FlattenedTreeRow[];
5012
- /**
5013
- * Get a row's original data by its key.
5014
- */
5015
5425
  getRowByKey(key: string): any | undefined;
5016
- /**
5017
- * Expand all ancestors of a node to make it visible.
5018
- */
5019
5426
  expandToKey(key: string): void;
5020
- readonly styles: string;
5021
5427
  }
5022
5428
 
5023
5429
  /**