@toolbox-web/grid 1.14.1 → 1.15.0

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 (70) hide show
  1. package/README.md +5 -1
  2. package/all.js +1985 -1558
  3. package/all.js.map +1 -1
  4. package/index.js +46 -20
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts.map +1 -1
  7. package/lib/core/internal/validate-config.d.ts.map +1 -1
  8. package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
  9. package/lib/plugins/column-virtualization/index.js +1 -1
  10. package/lib/plugins/column-virtualization/index.js.map +1 -1
  11. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +20 -1
  12. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  13. package/lib/plugins/context-menu/index.d.ts +1 -1
  14. package/lib/plugins/context-menu/index.d.ts.map +1 -1
  15. package/lib/plugins/context-menu/index.js +153 -70
  16. package/lib/plugins/context-menu/index.js.map +1 -1
  17. package/lib/plugins/context-menu/menu.d.ts +7 -0
  18. package/lib/plugins/context-menu/menu.d.ts.map +1 -1
  19. package/lib/plugins/context-menu/types.d.ts +46 -0
  20. package/lib/plugins/context-menu/types.d.ts.map +1 -1
  21. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  22. package/lib/plugins/editing/index.js +214 -197
  23. package/lib/plugins/editing/index.js.map +1 -1
  24. package/lib/plugins/filtering/FilteringPlugin.d.ts +7 -1
  25. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  26. package/lib/plugins/filtering/index.js +169 -133
  27. package/lib/plugins/filtering/index.js.map +1 -1
  28. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +5 -1
  29. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
  30. package/lib/plugins/grouping-columns/index.js +242 -109
  31. package/lib/plugins/grouping-columns/index.js.map +1 -1
  32. package/lib/plugins/grouping-columns/types.d.ts +7 -0
  33. package/lib/plugins/grouping-columns/types.d.ts.map +1 -1
  34. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +11 -1
  35. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
  36. package/lib/plugins/pinned-columns/index.d.ts +1 -1
  37. package/lib/plugins/pinned-columns/index.d.ts.map +1 -1
  38. package/lib/plugins/pinned-columns/index.js +174 -79
  39. package/lib/plugins/pinned-columns/index.js.map +1 -1
  40. package/lib/plugins/pinned-columns/pinned-columns.d.ts +23 -4
  41. package/lib/plugins/pinned-columns/pinned-columns.d.ts.map +1 -1
  42. package/lib/plugins/pinned-columns/types.d.ts +21 -9
  43. package/lib/plugins/pinned-columns/types.d.ts.map +1 -1
  44. package/lib/plugins/visibility/VisibilityPlugin.d.ts +42 -2
  45. package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
  46. package/lib/plugins/visibility/index.d.ts +1 -1
  47. package/lib/plugins/visibility/index.d.ts.map +1 -1
  48. package/lib/plugins/visibility/index.js +219 -59
  49. package/lib/plugins/visibility/index.js.map +1 -1
  50. package/lib/plugins/visibility/types.d.ts +25 -0
  51. package/lib/plugins/visibility/types.d.ts.map +1 -1
  52. package/package.json +1 -1
  53. package/umd/grid.all.umd.js +25 -25
  54. package/umd/grid.all.umd.js.map +1 -1
  55. package/umd/grid.umd.js +2 -2
  56. package/umd/grid.umd.js.map +1 -1
  57. package/umd/plugins/column-virtualization.umd.js +1 -1
  58. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  59. package/umd/plugins/context-menu.umd.js +1 -1
  60. package/umd/plugins/context-menu.umd.js.map +1 -1
  61. package/umd/plugins/editing.umd.js +1 -1
  62. package/umd/plugins/editing.umd.js.map +1 -1
  63. package/umd/plugins/filtering.umd.js +1 -1
  64. package/umd/plugins/filtering.umd.js.map +1 -1
  65. package/umd/plugins/grouping-columns.umd.js +1 -1
  66. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  67. package/umd/plugins/pinned-columns.umd.js +1 -1
  68. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  69. package/umd/plugins/visibility.umd.js +1 -1
  70. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -1,15 +1,24 @@
1
1
  import { TextDirection } from '../../core/internal/utils';
2
- import { ResolvedStickyPosition, StickyPosition } from './types';
2
+ import { PinnedPosition, ResolvedPinnedPosition } from './types';
3
+ type StickyPosition = PinnedPosition;
4
+ type ResolvedStickyPosition = ResolvedPinnedPosition;
3
5
  /**
4
- * Resolve a sticky position to a physical position based on text direction.
6
+ * Get the effective pinned position from a column, checking `pinned` first then `sticky` (deprecated).
7
+ *
8
+ * @param col - Column configuration object
9
+ * @returns The pinned position, or undefined if not pinned
10
+ */
11
+ export declare function getColumnPinned(col: any): PinnedPosition | undefined;
12
+ /**
13
+ * Resolve a pinned position to a physical position based on text direction.
5
14
  *
6
15
  * - `'left'` / `'right'` → unchanged (physical values)
7
16
  * - `'start'` → `'left'` in LTR, `'right'` in RTL
8
17
  * - `'end'` → `'right'` in LTR, `'left'` in RTL
9
18
  *
10
- * @param position - The sticky position (logical or physical)
19
+ * @param position - The pinned position (logical or physical)
11
20
  * @param direction - Text direction ('ltr' or 'rtl')
12
- * @returns Physical sticky position ('left' or 'right')
21
+ * @returns Physical pinned position ('left' or 'right')
13
22
  */
14
23
  export declare function resolveStickyPosition(position: StickyPosition, direction: TextDirection): ResolvedStickyPosition;
15
24
  /**
@@ -70,10 +79,20 @@ export declare function calculateRightStickyOffsets(columns: any[], getColumnWid
70
79
  * @param columns - Array of column configurations
71
80
  */
72
81
  export declare function applyStickyOffsets(host: HTMLElement, columns: any[]): void;
82
+ /**
83
+ * Reorder columns so that pinned-left columns come first and pinned-right columns come last.
84
+ * Maintains the relative order within each group (left-pinned, unpinned, right-pinned).
85
+ *
86
+ * @param columns - Array of column configurations (in their current order)
87
+ * @param direction - Text direction ('ltr' or 'rtl'), used to resolve logical positions
88
+ * @returns New array with pinned columns moved to the edges
89
+ */
90
+ export declare function reorderColumnsForPinning(columns: readonly any[], direction?: TextDirection): any[];
73
91
  /**
74
92
  * Clear sticky positioning from all cells.
75
93
  *
76
94
  * @param host - The grid host element (render root for DOM queries)
77
95
  */
78
96
  export declare function clearStickyOffsets(host: HTMLElement): void;
97
+ export {};
79
98
  //# sourceMappingURL=pinned-columns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pinned-columns.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/pinned-columns/pinned-columns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACpG,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,GAAG,sBAAsB,CAEhH;AAoBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,GAAE,aAAqB,GAAG,GAAG,EAAE,CAE5F;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,GAAE,aAAqB,GAAG,GAAG,EAAE,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAIxD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc,GAAG,IAAI,CAM1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,GAAG,EAAE,EACd,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACzC,SAAS,GAAE,aAAqB,GAC/B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,GAAG,EAAE,EACd,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACzC,SAAS,GAAE,aAAqB,GAC/B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAcrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CA2D1E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAS1D"}
1
+ {"version":3,"file":"pinned-columns.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/pinned-columns/pinned-columns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACpG,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGtE,KAAK,cAAc,GAAG,cAAc,CAAC;AACrC,KAAK,sBAAsB,GAAG,sBAAsB,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,GAAG,sBAAsB,CAEhH;AAoBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,GAAE,aAAqB,GAAG,GAAG,EAAE,CAE5F;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,GAAE,aAAqB,GAAG,GAAG,EAAE,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc,GAAG,IAAI,CAE1E;AAGD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,GAAG,EAAE,EACd,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACzC,SAAS,GAAE,aAAqB,GAC/B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,GAAG,EAAE,EACd,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACzC,SAAS,GAAE,aAAqB,GAC/B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAcrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAgD1E;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,GAAG,EAAE,EAAE,SAAS,GAAE,aAAqB,GAAG,GAAG,EAAE,CAiBzG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAS1D"}
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Sticky Columns Plugin Types
2
+ * Pinned Columns Plugin Types
3
3
  *
4
4
  * Type definitions for column pinning (sticky left/right columns).
5
5
  */
6
6
  /**
7
- * Sticky column position.
7
+ * Column pin position.
8
8
  *
9
9
  * **Physical values** (always pin to specified side):
10
10
  * - `'left'` - Pin to left edge
@@ -20,20 +20,28 @@
20
20
  * @example
21
21
  * ```typescript
22
22
  * // Physical - always pins to left side regardless of direction
23
- * { field: 'id', sticky: 'left' }
23
+ * { field: 'id', pinned: 'left' }
24
24
  *
25
25
  * // Logical - pins to visual start (left in LTR, right in RTL)
26
- * { field: 'id', sticky: 'start' }
26
+ * { field: 'id', pinned: 'start' }
27
27
  * ```
28
28
  */
29
- export type StickyPosition = 'left' | 'right' | 'start' | 'end';
29
+ export type PinnedPosition = 'left' | 'right' | 'start' | 'end';
30
30
  /**
31
- * Physical sticky position after resolving logical values.
31
+ * @deprecated Use {@link PinnedPosition} instead. Will be removed in a future major version.
32
+ */
33
+ export type StickyPosition = PinnedPosition;
34
+ /**
35
+ * Physical pin position after resolving logical values.
32
36
  * Used internally after applying RTL resolution.
33
37
  */
34
- export type ResolvedStickyPosition = 'left' | 'right';
38
+ export type ResolvedPinnedPosition = 'left' | 'right';
39
+ /**
40
+ * @deprecated Use {@link ResolvedPinnedPosition} instead. Will be removed in a future major version.
41
+ */
42
+ export type ResolvedStickyPosition = ResolvedPinnedPosition;
35
43
  /**
36
- * When PinnedColumnsPlugin is imported, the `sticky` property becomes available on column config.
44
+ * When PinnedColumnsPlugin is imported, the `pinned` property becomes available on column config.
37
45
  * This augments the core BaseColumnConfig interface.
38
46
  */
39
47
  declare module '../../core/types' {
@@ -51,7 +59,11 @@ declare module '../../core/types' {
51
59
  *
52
60
  * Requires PinnedColumnsPlugin.
53
61
  */
54
- sticky?: StickyPosition;
62
+ pinned?: PinnedPosition;
63
+ /**
64
+ * @deprecated Use `pinned` instead. Will be removed in a future major version.
65
+ */
66
+ sticky?: PinnedPosition;
55
67
  }
56
68
  }
57
69
  /** Configuration options for the pinned columns plugin */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/pinned-columns/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAEhE;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,OAAO,CAAC;AAMtD;;;GAGG;AACH,OAAO,QAAQ,kBAAkB,CAAC;IAChC,UAAU,gBAAgB,CAAC,IAAI,EAAE,MAAM;QACrC;;;;;;;;;;;;WAYG;QACH,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB;CACF;AAED,0DAA0D;AAE1D,MAAM,WAAW,mBAAmB;CAEnC;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oCAAoC;IACpC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/pinned-columns/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,sBAAsB,CAAC;AAM5D;;;GAGG;AACH,OAAO,QAAQ,kBAAkB,CAAC;IAChC,UAAU,gBAAgB,CAAC,IAAI,EAAE,MAAM;QACrC;;;;;;;;;;;;WAYG;QACH,MAAM,CAAC,EAAE,cAAc,CAAC;QAExB;;WAEG;QACH,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB;CACF;AAED,0DAA0D;AAE1D,MAAM,WAAW,mBAAmB;CAEnC;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oCAAoC;IACpC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC"}
@@ -1,4 +1,4 @@
1
- import { BaseGridPlugin, PluginDependency } from '../../core/plugin/base-plugin';
1
+ import { BaseGridPlugin, PluginDependency, PluginManifest, PluginQuery } from '../../core/plugin/base-plugin';
2
2
  import { ToolPanelDefinition } from '../../core/types';
3
3
  import { VisibilityConfig } from './types';
4
4
  /**
@@ -106,6 +106,11 @@ export declare class VisibilityPlugin extends BaseGridPlugin<VisibilityConfig> {
106
106
  * @internal
107
107
  */
108
108
  static readonly dependencies: PluginDependency[];
109
+ /**
110
+ * Plugin manifest - declares handled queries.
111
+ * @internal
112
+ */
113
+ static readonly manifest: PluginManifest;
109
114
  /** @internal */
110
115
  readonly name = "visibility";
111
116
  /** Tool panel ID for shell integration */
@@ -119,10 +124,22 @@ export declare class VisibilityPlugin extends BaseGridPlugin<VisibilityConfig> {
119
124
  private draggedField;
120
125
  private draggedIndex;
121
126
  private dropIndex;
122
- /** Clear drag-related classes from all rows in a list. */
127
+ /** When dragging a group, holds the group ID; null for individual column drags. */
128
+ private draggedGroupId;
129
+ /** Fields belonging to the group currently being dragged. */
130
+ private draggedGroupFields;
131
+ /** Clear drag-related classes from all rows and group headers in a list. */
123
132
  private clearDragClasses;
124
133
  /** @internal */
134
+ attach(grid: import('../../core/plugin/base-plugin').GridElement): void;
135
+ /** @internal */
125
136
  detach(): void;
137
+ /**
138
+ * Handle inter-plugin queries.
139
+ * Contributes a "Hide column" item to the header context menu.
140
+ * @internal
141
+ */
142
+ handleQuery(query: PluginQuery): unknown;
126
143
  /**
127
144
  * Register the column visibility tool panel with the shell.
128
145
  * @internal
@@ -216,9 +233,32 @@ export declare class VisibilityPlugin extends BaseGridPlugin<VisibilityConfig> {
216
233
  private hasReorderPlugin;
217
234
  /**
218
235
  * Build the column toggle checkboxes.
236
+ * When GroupingColumnsPlugin is present, renders columns under collapsible group headers.
219
237
  * When a reorder plugin is present, adds drag handles for reordering.
220
238
  */
221
239
  private rebuildToggles;
240
+ /**
241
+ * Render a group section with header checkbox and indented column rows.
242
+ */
243
+ private renderGroupSection;
244
+ /**
245
+ * Render a flat (ungrouped) list of column rows.
246
+ */
247
+ private renderFlatColumnList;
248
+ /**
249
+ * Create a single column visibility row element.
250
+ */
251
+ private createColumnRow;
252
+ /**
253
+ * Set up drag-and-drop listeners for a group header row.
254
+ * Dragging a group moves all its member columns as a block.
255
+ */
256
+ private setupGroupDragListeners;
257
+ /**
258
+ * Execute a group drop — move the dragged group's fields as a block
259
+ * to the position relative to the target group or column.
260
+ */
261
+ private executeGroupDrop;
222
262
  /**
223
263
  * Set up drag-and-drop event listeners for a row.
224
264
  * On drop, emits a 'column-reorder-request' event for other plugins to handle.
@@ -1 +1 @@
1
- {"version":3,"file":"VisibilityPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/visibility/VisibilityPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtF,OAAO,KAAK,EAAgB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGhD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;CACjB;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,qBAAa,gBAAiB,SAAQ,cAAc,CAAC,gBAAgB,CAAC;IACpE;;;;;OAKG;IACH,gBAAyB,YAAY,EAAE,gBAAgB,EAAE,CAEvD;IAEF,gBAAgB;IAChB,QAAQ,CAAC,IAAI,gBAAgB;IAE7B,0CAA0C;IAC1C,MAAM,CAAC,QAAQ,CAAC,QAAQ,aAAa;IACrC,gBAAgB;IAChB,SAAkB,MAAM,SAAU;IAElC,gBAAgB;IAChB,cAAuB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAIhE;IAGD,OAAO,CAAC,iBAAiB,CAA4B;IAGrD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,SAAS,CAAuB;IAExC,0DAA0D;IAC1D,OAAO,CAAC,gBAAgB;IASxB,gBAAgB;IACP,MAAM,IAAI,IAAI;IAWvB;;;OAGG;IACM,YAAY,IAAI,mBAAmB,GAAG,SAAS;IAcxD;;;OAGG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,MAAM,IAAI,IAAI;IAQd;;;;;OAKG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;;OAKG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIvD;;;OAGG;IACH,iBAAiB,IAAI,MAAM,EAAE;IAO7B;;;OAGG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAO5B;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIjC;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;OAIG;IACH,aAAa,IAAI,KAAK,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAIF;;;OAGG;IACH,cAAc,IAAI,OAAO;IAOzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAoC1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA4DtB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAqF3B"}
1
+ {"version":3,"file":"VisibilityPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/visibility/VisibilityPlugin.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * @module Plugins/Visibility
6
6
  */
7
- export type { ColumnVisibilityDetail, VisibilityConfig } from './types';
7
+ export type { ColumnGroupInfo, ColumnVisibilityDetail, VisibilityConfig } from './types';
8
8
  export { VisibilityPlugin } from './VisibilityPlugin';
9
9
  export type { ColumnReorderRequestDetail } from './VisibilityPlugin';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/visibility/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/visibility/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
@@ -146,8 +146,8 @@ class C {
146
146
  * @returns `true` if the event was cancelled (preventDefault called), `false` otherwise
147
147
  */
148
148
  emitCancelable(e, t) {
149
- const r = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
150
- return this.grid?.dispatchEvent?.(r), r.defaultPrevented;
149
+ const i = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
150
+ return this.grid?.dispatchEvent?.(i), i.defaultPrevented;
151
151
  }
152
152
  // =========================================================================
153
153
  // Event Bus - Plugin-to-Plugin Communication
@@ -342,8 +342,8 @@ class C {
342
342
  get animationDuration() {
343
343
  const e = this.gridElement;
344
344
  if (e) {
345
- const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), r = parseInt(t, 10);
346
- if (!isNaN(r)) return r;
345
+ const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), i = parseInt(t, 10);
346
+ if (!isNaN(i)) return i;
347
347
  }
348
348
  return 200;
349
349
  }
@@ -377,12 +377,12 @@ class C {
377
377
  }
378
378
  // #endregion
379
379
  }
380
- const y = '@layer tbw-plugins{.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem))}.tbw-visibility-row{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding:var(--tbw-menu-item-padding, .375rem .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem);border-radius:var(--tbw-border-radius, .25rem);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted);font-size:var(--tbw-font-size-2xs, .625rem);letter-spacing:-2px;-webkit-user-select:none;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg)}.tbw-visibility-label{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));flex:1;cursor:pointer}.tbw-visibility-row.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-row.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-show-all{margin:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem));padding:var(--tbw-button-padding, .5rem .75rem);border:1px solid var(--tbw-visibility-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius, .25rem);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg));color:var(--tbw-color-fg);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem)}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}}';
381
- function p(b) {
382
- const e = b.meta ?? {};
380
+ const y = '@layer tbw-plugins{.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem))}.tbw-visibility-row{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding:var(--tbw-menu-item-padding, .375rem .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem);border-radius:var(--tbw-border-radius, .25rem);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted);font-size:var(--tbw-font-size-2xs, .625rem);letter-spacing:-2px;-webkit-user-select:none;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg)}.tbw-visibility-label{display:flex;align-items:center;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));flex:1;cursor:pointer}.tbw-visibility-row.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-row.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-show-all{margin:var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem));padding:var(--tbw-button-padding, .5rem .75rem);border:1px solid var(--tbw-visibility-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius, .25rem);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg));color:var(--tbw-color-fg);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem)}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}.tbw-visibility-group-header{display:flex;align-items:center;padding:var(--tbw-menu-item-padding, .375rem .25rem);font-size:var(--tbw-font-size-sm, .8125rem);font-weight:600;color:var(--tbw-color-fg);border-bottom:1px solid var(--tbw-color-border);margin-top:var(--tbw-spacing-sm, .25rem);position:relative}.tbw-visibility-group-header:first-child{margin-top:0}.tbw-visibility-group-header .tbw-visibility-label{gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem))}.tbw-visibility-group-header.reorderable{cursor:grab}.tbw-visibility-group-header.reorderable:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover))}.tbw-visibility-group-header .tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted);font-size:var(--tbw-font-size-2xs, .625rem);letter-spacing:-2px;-webkit-user-select:none;user-select:none;flex-shrink:0}.tbw-visibility-group-header.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg)}.tbw-visibility-group-header.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-group-header.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-group-header.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-visibility-indicator, var(--tbw-color-accent))}.tbw-visibility-row--grouped{padding-left:calc(var(--tbw-panel-padding, var(--tbw-spacing-md, .5rem)) + .75rem)}}';
381
+ function v(f) {
382
+ const e = f.meta ?? {};
383
383
  return e.lockPosition !== !0 && e.suppressMovable !== !0;
384
384
  }
385
- class g extends C {
385
+ class b extends C {
386
386
  /**
387
387
  * Plugin dependencies - VisibilityPlugin optionally uses ReorderPlugin for drag-drop reordering.
388
388
  *
@@ -392,6 +392,18 @@ class g extends C {
392
392
  static dependencies = [
393
393
  { name: "reorder", required: !1, reason: "Enables drag-to-reorder columns in visibility panel" }
394
394
  ];
395
+ /**
396
+ * Plugin manifest - declares handled queries.
397
+ * @internal
398
+ */
399
+ static manifest = {
400
+ queries: [
401
+ {
402
+ type: "getContextMenuItems",
403
+ description: 'Contributes "Hide column" item to the header context menu'
404
+ }
405
+ ]
406
+ };
395
407
  /** @internal */
396
408
  name = "visibility";
397
409
  /** Tool panel ID for shell integration */
@@ -411,19 +423,58 @@ class g extends C {
411
423
  draggedField = null;
412
424
  draggedIndex = null;
413
425
  dropIndex = null;
414
- /** Clear drag-related classes from all rows in a list. */
426
+ /** When dragging a group, holds the group ID; null for individual column drags. */
427
+ draggedGroupId = null;
428
+ /** Fields belonging to the group currently being dragged. */
429
+ draggedGroupFields = [];
430
+ /** Clear drag-related classes from all rows and group headers in a list. */
415
431
  clearDragClasses(e) {
416
- e.querySelectorAll(".tbw-visibility-row").forEach((t) => {
432
+ e.querySelectorAll(".tbw-visibility-row, .tbw-visibility-group-header").forEach((t) => {
417
433
  t.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
418
434
  });
419
435
  }
420
436
  // #endregion
421
437
  // #region Lifecycle
422
438
  /** @internal */
439
+ attach(e) {
440
+ super.attach(e), e.addEventListener(
441
+ "column-move",
442
+ () => {
443
+ this.columnListElement && requestAnimationFrame(() => {
444
+ this.columnListElement && this.rebuildToggles(this.columnListElement);
445
+ });
446
+ },
447
+ { signal: this.disconnectSignal }
448
+ );
449
+ }
450
+ /** @internal */
423
451
  detach() {
424
452
  this.columnListElement = null, this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null;
425
453
  }
426
454
  // #endregion
455
+ // #region Query Handlers
456
+ /**
457
+ * Handle inter-plugin queries.
458
+ * Contributes a "Hide column" item to the header context menu.
459
+ * @internal
460
+ */
461
+ handleQuery(e) {
462
+ if (e.type === "getContextMenuItems") {
463
+ const t = e.context;
464
+ if (!t.isHeader) return;
465
+ const i = t.column;
466
+ return !i?.field || i.meta?.lockVisibility ? void 0 : [
467
+ {
468
+ id: "visibility/hide-column",
469
+ label: "Hide Column",
470
+ icon: "👁",
471
+ order: 30,
472
+ action: () => this.hideColumn(i.field)
473
+ }
474
+ ];
475
+ }
476
+ }
477
+ // #endregion
427
478
  // #region Shell Integration
428
479
  /**
429
480
  * Register the column visibility tool panel with the shell.
@@ -431,7 +482,7 @@ class g extends C {
431
482
  */
432
483
  getToolPanel() {
433
484
  return {
434
- id: g.PANEL_ID,
485
+ id: b.PANEL_ID,
435
486
  title: "Columns",
436
487
  icon: "☰",
437
488
  tooltip: "Column visibility",
@@ -447,7 +498,7 @@ class g extends C {
447
498
  * Opens the tool panel and ensures this section is expanded.
448
499
  */
449
500
  show() {
450
- this.grid.openToolPanel(), this.grid.expandedToolPanelSections.includes(g.PANEL_ID) || this.grid.toggleToolPanelSection(g.PANEL_ID);
501
+ this.grid.openToolPanel(), this.grid.expandedToolPanelSections.includes(b.PANEL_ID) || this.grid.toggleToolPanelSection(b.PANEL_ID);
451
502
  }
452
503
  /**
453
504
  * Hide the visibility sidebar panel.
@@ -459,7 +510,7 @@ class g extends C {
459
510
  * Toggle the visibility sidebar panel section.
460
511
  */
461
512
  toggle() {
462
- this.grid.isToolPanelOpen || this.grid.openToolPanel(), this.grid.toggleToolPanelSection(g.PANEL_ID);
513
+ this.grid.isToolPanelOpen || this.grid.openToolPanel(), this.grid.toggleToolPanelSection(b.PANEL_ID);
463
514
  }
464
515
  /**
465
516
  * Check if a specific column is visible.
@@ -537,7 +588,7 @@ class g extends C {
537
588
  * @returns True if the panel section is expanded
538
589
  */
539
590
  isPanelVisible() {
540
- return this.grid.isToolPanelOpen && this.grid.expandedToolPanelSections.includes(g.PANEL_ID);
591
+ return this.grid.isToolPanelOpen && this.grid.expandedToolPanelSections.includes(b.PANEL_ID);
541
592
  }
542
593
  // #endregion
543
594
  // #region Private Methods
@@ -548,12 +599,12 @@ class g extends C {
548
599
  renderPanelContent(e) {
549
600
  const t = document.createElement("div");
550
601
  t.className = "tbw-visibility-content";
551
- const r = document.createElement("div");
552
- r.className = "tbw-visibility-list", t.appendChild(r);
553
- const s = document.createElement("button");
554
- return s.className = "tbw-visibility-show-all", s.textContent = "Show All", s.addEventListener("click", () => {
555
- this.grid.showAllColumns(), this.rebuildToggles(r);
556
- }), t.appendChild(s), this.columnListElement = r, this.rebuildToggles(r), e.appendChild(t), () => {
602
+ const i = document.createElement("div");
603
+ i.className = "tbw-visibility-list", t.appendChild(i);
604
+ const l = document.createElement("button");
605
+ return l.className = "tbw-visibility-show-all", l.textContent = "Show All", l.addEventListener("click", () => {
606
+ this.grid.showAllColumns(), this.rebuildToggles(i);
607
+ }), t.appendChild(l), this.columnListElement = i, this.rebuildToggles(i), e.appendChild(t), () => {
557
608
  this.columnListElement = null, t.remove();
558
609
  };
559
610
  }
@@ -566,68 +617,177 @@ class g extends C {
566
617
  }
567
618
  /**
568
619
  * Build the column toggle checkboxes.
620
+ * When GroupingColumnsPlugin is present, renders columns under collapsible group headers.
569
621
  * When a reorder plugin is present, adds drag handles for reordering.
570
622
  */
571
623
  rebuildToggles(e) {
572
624
  const t = this.hasReorderPlugin();
573
625
  e.innerHTML = "";
574
- const r = this.grid.getAllColumns().filter((s) => !s.utility);
575
- for (let s = 0; s < r.length; s++) {
576
- const i = r[s], a = i.header || i.field, n = document.createElement("div");
577
- n.className = i.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", n.setAttribute("data-field", i.field), n.setAttribute("data-index", String(s)), t && p(i) && (n.draggable = !0, n.classList.add("reorderable"), this.setupDragListeners(n, i.field, s, e));
578
- const l = document.createElement("label");
579
- l.className = "tbw-visibility-label";
580
- const o = document.createElement("input");
581
- o.type = "checkbox", o.checked = i.visible, o.disabled = i.lockVisible ?? !1, o.addEventListener("change", () => {
582
- this.grid.toggleColumnVisibility(i.field), setTimeout(() => this.rebuildToggles(e), 0);
583
- });
584
- const d = document.createElement("span");
585
- if (d.textContent = a, l.appendChild(o), l.appendChild(d), t && p(i)) {
586
- const c = document.createElement("span");
587
- c.className = "tbw-visibility-handle", this.setIcon(c, this.resolveIcon("dragHandle")), c.title = "Drag to reorder", n.appendChild(c);
626
+ const i = this.grid.getAllColumns().filter((o) => !o.utility), r = this.grid.query("getColumnGrouping")?.flat().filter((o) => o && o.fields.length > 0) ?? [];
627
+ if (r.length === 0) {
628
+ this.renderFlatColumnList(i, t, e);
629
+ return;
630
+ }
631
+ const n = /* @__PURE__ */ new Map();
632
+ for (const o of r)
633
+ for (const a of o.fields) n.set(a, o);
634
+ const s = /* @__PURE__ */ new Set();
635
+ for (const o of i) {
636
+ const a = n.get(o.field);
637
+ if (a) {
638
+ if (!s.has(a.id)) {
639
+ s.add(a.id);
640
+ const g = new Set(a.fields), u = i.filter((d) => g.has(d.field));
641
+ u.length > 0 && this.renderGroupSection(a, u, t, e);
642
+ }
643
+ } else {
644
+ const g = i.indexOf(o);
645
+ e.appendChild(this.createColumnRow(o, g, t, e));
588
646
  }
589
- n.appendChild(l), e.appendChild(n);
590
647
  }
591
648
  }
649
+ /**
650
+ * Render a group section with header checkbox and indented column rows.
651
+ */
652
+ renderGroupSection(e, t, i, l) {
653
+ const r = document.createElement("div");
654
+ r.className = "tbw-visibility-group-header", r.setAttribute("data-group-id", e.id), i && (r.draggable = !0, r.classList.add("reorderable"), this.setupGroupDragListeners(r, e, l));
655
+ const n = document.createElement("label");
656
+ n.className = "tbw-visibility-label";
657
+ const s = document.createElement("input");
658
+ s.type = "checkbox";
659
+ const o = t.filter((d) => d.visible).length, a = t.every((d) => d.lockVisible);
660
+ o === t.length ? (s.checked = !0, s.indeterminate = !1) : o === 0 ? (s.checked = !1, s.indeterminate = !1) : (s.checked = !1, s.indeterminate = !0), s.disabled = a, s.addEventListener("change", () => {
661
+ const d = s.checked;
662
+ for (const c of t)
663
+ c.lockVisible || this.grid.setColumnVisible(c.field, d);
664
+ setTimeout(() => this.rebuildToggles(l), 0);
665
+ });
666
+ const g = document.createElement("span");
667
+ if (g.textContent = e.label, n.appendChild(s), n.appendChild(g), r.appendChild(n), i) {
668
+ const d = document.createElement("span");
669
+ d.className = "tbw-visibility-handle", this.setIcon(d, this.resolveIcon("dragHandle")), d.title = "Drag to reorder group", r.insertBefore(d, n);
670
+ }
671
+ l.appendChild(r);
672
+ const u = this.grid.getAllColumns().filter((d) => !d.utility);
673
+ for (const d of t) {
674
+ const c = u.findIndex((h) => h.field === d.field), p = this.createColumnRow(d, c, i, l);
675
+ p.classList.add("tbw-visibility-row--grouped"), l.appendChild(p);
676
+ }
677
+ }
678
+ /**
679
+ * Render a flat (ungrouped) list of column rows.
680
+ */
681
+ renderFlatColumnList(e, t, i) {
682
+ const l = this.grid.getAllColumns().filter((r) => !r.utility);
683
+ for (const r of e) {
684
+ const n = l.findIndex((s) => s.field === r.field);
685
+ i.appendChild(this.createColumnRow(r, n, t, i));
686
+ }
687
+ }
688
+ /**
689
+ * Create a single column visibility row element.
690
+ */
691
+ createColumnRow(e, t, i, l) {
692
+ const r = e.header || e.field, n = document.createElement("div");
693
+ n.className = e.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", n.setAttribute("data-field", e.field), n.setAttribute("data-index", String(t)), i && v(e) && (n.draggable = !0, n.classList.add("reorderable"), this.setupDragListeners(n, e.field, t, l));
694
+ const s = document.createElement("label");
695
+ s.className = "tbw-visibility-label";
696
+ const o = document.createElement("input");
697
+ o.type = "checkbox", o.checked = e.visible, o.disabled = e.lockVisible ?? !1, o.addEventListener("change", () => {
698
+ this.grid.toggleColumnVisibility(e.field), setTimeout(() => this.rebuildToggles(l), 0);
699
+ });
700
+ const a = document.createElement("span");
701
+ if (a.textContent = r, s.appendChild(o), s.appendChild(a), i && v(e)) {
702
+ const g = document.createElement("span");
703
+ g.className = "tbw-visibility-handle", this.setIcon(g, this.resolveIcon("dragHandle")), g.title = "Drag to reorder", n.appendChild(g);
704
+ }
705
+ return n.appendChild(s), n;
706
+ }
707
+ /**
708
+ * Set up drag-and-drop listeners for a group header row.
709
+ * Dragging a group moves all its member columns as a block.
710
+ */
711
+ setupGroupDragListeners(e, t, i) {
712
+ e.addEventListener("dragstart", (l) => {
713
+ this.isDragging = !0, this.draggedGroupId = t.id, this.draggedGroupFields = [...t.fields], this.draggedField = null, this.draggedIndex = null, l.dataTransfer && (l.dataTransfer.effectAllowed = "move", l.dataTransfer.setData("text/plain", `group:${t.id}`)), e.classList.add("dragging"), i.querySelectorAll(".tbw-visibility-row--grouped").forEach((r) => {
714
+ const n = r.getAttribute("data-field");
715
+ n && this.draggedGroupFields.includes(n) && r.classList.add("dragging");
716
+ });
717
+ }), e.addEventListener("dragend", () => {
718
+ this.isDragging = !1, this.draggedGroupId = null, this.draggedGroupFields = [], this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses(i);
719
+ }), e.addEventListener("dragover", (l) => {
720
+ if (l.preventDefault(), !this.isDragging || this.draggedGroupId === t.id || !this.draggedGroupId) return;
721
+ const r = e.getBoundingClientRect(), n = r.top + r.height / 2, s = l.clientY < n;
722
+ this.clearDragClasses(i), e.classList.add("drop-target"), e.classList.toggle("drop-before", s), e.classList.toggle("drop-after", !s);
723
+ }), e.addEventListener("dragleave", () => {
724
+ e.classList.remove("drop-target", "drop-before", "drop-after");
725
+ }), e.addEventListener("drop", (l) => {
726
+ if (l.preventDefault(), !this.isDragging || !this.draggedGroupId || this.draggedGroupId === t.id) return;
727
+ const r = e.getBoundingClientRect(), n = l.clientY < r.top + r.height / 2;
728
+ this.executeGroupDrop(this.draggedGroupFields, t.fields, n, i);
729
+ });
730
+ }
731
+ /**
732
+ * Execute a group drop — move the dragged group's fields as a block
733
+ * to the position relative to the target group or column.
734
+ */
735
+ executeGroupDrop(e, t, i, l) {
736
+ const n = this.grid.getAllColumns().map((d) => d.field), s = n.filter((d) => !e.includes(d)), o = i ? t[0] : t[t.length - 1], a = s.indexOf(o);
737
+ if (a === -1) return;
738
+ const g = i ? a : a + 1, u = n.filter((d) => e.includes(d));
739
+ s.splice(g, 0, ...u), this.grid.setColumnOrder(s), requestAnimationFrame(() => {
740
+ this.columnListElement && this.rebuildToggles(this.columnListElement);
741
+ });
742
+ }
592
743
  /**
593
744
  * Set up drag-and-drop event listeners for a row.
594
745
  * On drop, emits a 'column-reorder-request' event for other plugins to handle.
595
746
  */
596
- setupDragListeners(e, t, r, s) {
597
- e.addEventListener("dragstart", (i) => {
598
- this.isDragging = !0, this.draggedField = t, this.draggedIndex = r, i.dataTransfer && (i.dataTransfer.effectAllowed = "move", i.dataTransfer.setData("text/plain", t)), e.classList.add("dragging");
747
+ setupDragListeners(e, t, i, l) {
748
+ e.addEventListener("dragstart", (r) => {
749
+ this.isDragging = !0, this.draggedField = t, this.draggedIndex = i, this.draggedGroupId = null, this.draggedGroupFields = [], r.dataTransfer && (r.dataTransfer.effectAllowed = "move", r.dataTransfer.setData("text/plain", t)), e.classList.add("dragging");
599
750
  }), e.addEventListener("dragend", () => {
600
- this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses(s);
601
- }), e.addEventListener("dragover", (i) => {
602
- if (i.preventDefault(), !this.isDragging || this.draggedField === t) return;
603
- const a = e.getBoundingClientRect(), n = a.top + a.height / 2;
604
- this.dropIndex = i.clientY < n ? r : r + 1, s.querySelectorAll(".tbw-visibility-row").forEach((l) => {
605
- l !== e && l.classList.remove("drop-target", "drop-before", "drop-after");
606
- }), e.classList.add("drop-target"), e.classList.toggle("drop-before", i.clientY < n), e.classList.toggle("drop-after", i.clientY >= n);
751
+ this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses(l);
752
+ }), e.addEventListener("dragover", (r) => {
753
+ if (r.preventDefault(), !this.isDragging) return;
754
+ if (this.draggedGroupId) {
755
+ if (e.classList.contains("tbw-visibility-row--grouped")) return;
756
+ } else if (this.draggedField === t)
757
+ return;
758
+ const n = e.getBoundingClientRect(), s = n.top + n.height / 2;
759
+ this.dropIndex = r.clientY < s ? i : i + 1, this.clearDragClasses(l), this.draggedGroupId ? (l.querySelector(`.tbw-visibility-group-header[data-group-id="${this.draggedGroupId}"]`)?.classList.add("dragging"), l.querySelectorAll(".tbw-visibility-row--grouped").forEach((o) => {
760
+ const a = o.getAttribute("data-field");
761
+ a && this.draggedGroupFields.includes(a) && o.classList.add("dragging");
762
+ })) : this.draggedField && l.querySelector(`.tbw-visibility-row[data-field="${this.draggedField}"]`)?.classList.add("dragging"), e.classList.add("drop-target"), e.classList.toggle("drop-before", r.clientY < s), e.classList.toggle("drop-after", r.clientY >= s);
607
763
  }), e.addEventListener("dragleave", () => {
608
764
  e.classList.remove("drop-target", "drop-before", "drop-after");
609
- }), e.addEventListener("drop", (i) => {
610
- i.preventDefault();
611
- const a = this.draggedField, n = this.draggedIndex, l = this.dropIndex;
612
- if (!this.isDragging || a === null || n === null || l === null)
765
+ }), e.addEventListener("drop", (r) => {
766
+ if (r.preventDefault(), !this.isDragging) return;
767
+ if (this.draggedGroupId && this.draggedGroupFields.length > 0) {
768
+ if (e.classList.contains("tbw-visibility-row--grouped")) return;
769
+ const g = e.getBoundingClientRect(), u = r.clientY < g.top + g.height / 2;
770
+ this.executeGroupDrop(this.draggedGroupFields, [t], u, l);
771
+ return;
772
+ }
773
+ const n = this.draggedField, s = this.draggedIndex, o = this.dropIndex;
774
+ if (n === null || s === null || o === null)
613
775
  return;
614
- const o = l > n ? l - 1 : l;
615
- if (o !== n) {
616
- const d = this.grid.getAllColumns(), h = d.filter((u) => !u.utility)[o]?.field, v = h ? d.findIndex((u) => u.field === h) : d.length, f = {
617
- field: a,
618
- fromIndex: n,
776
+ const a = o > s ? o - 1 : o;
777
+ if (a !== s) {
778
+ const g = this.grid.getAllColumns(), d = g.filter((h) => !h.utility)[a]?.field, c = d ? g.findIndex((h) => h.field === d) : g.length, p = {
779
+ field: n,
780
+ fromIndex: s,
619
781
  // Not used by ReorderPlugin, just for info
620
- toIndex: v
782
+ toIndex: c
621
783
  };
622
- this.emit("column-reorder-request", f), setTimeout(() => {
623
- this.rebuildToggles(s);
624
- }, 0);
784
+ this.emit("column-reorder-request", p);
625
785
  }
626
786
  });
627
787
  }
628
788
  // #endregion
629
789
  }
630
790
  export {
631
- g as VisibilityPlugin
791
+ b as VisibilityPlugin
632
792
  };
633
793
  //# sourceMappingURL=index.js.map