@toolbox-web/grid 1.21.1 → 1.22.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 (155) hide show
  1. package/README.md +6 -8
  2. package/all.js +2 -6850
  3. package/all.js.map +1 -1
  4. package/index.js +1 -4352
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts +75 -8
  7. package/lib/core/grid.d.ts.map +1 -1
  8. package/lib/core/internal/rows.d.ts.map +1 -1
  9. package/lib/core/plugin/base-plugin.d.ts +8 -2
  10. package/lib/core/plugin/base-plugin.d.ts.map +1 -1
  11. package/lib/core/styles/index.d.ts.map +1 -1
  12. package/lib/core/types.d.ts +84 -2
  13. package/lib/core/types.d.ts.map +1 -1
  14. package/lib/plugins/clipboard/index.js +1 -733
  15. package/lib/plugins/clipboard/index.js.map +1 -1
  16. package/lib/plugins/clipboard/types.d.ts +5 -0
  17. package/lib/plugins/clipboard/types.d.ts.map +1 -1
  18. package/lib/plugins/column-virtualization/index.js +1 -560
  19. package/lib/plugins/column-virtualization/index.js.map +1 -1
  20. package/lib/plugins/column-virtualization/types.d.ts +5 -0
  21. package/lib/plugins/column-virtualization/types.d.ts.map +1 -1
  22. package/lib/plugins/context-menu/index.js +1 -754
  23. package/lib/plugins/context-menu/index.js.map +1 -1
  24. package/lib/plugins/context-menu/types.d.ts +5 -0
  25. package/lib/plugins/context-menu/types.d.ts.map +1 -1
  26. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  27. package/lib/plugins/editing/index.d.ts +1 -1
  28. package/lib/plugins/editing/index.d.ts.map +1 -1
  29. package/lib/plugins/editing/index.js +1 -1539
  30. package/lib/plugins/editing/index.js.map +1 -1
  31. package/lib/plugins/editing/types.d.ts +49 -0
  32. package/lib/plugins/editing/types.d.ts.map +1 -1
  33. package/lib/plugins/export/index.js +1 -589
  34. package/lib/plugins/export/index.js.map +1 -1
  35. package/lib/plugins/export/types.d.ts +5 -0
  36. package/lib/plugins/export/types.d.ts.map +1 -1
  37. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  38. package/lib/plugins/filtering/filter-model.d.ts.map +1 -1
  39. package/lib/plugins/filtering/index.js +1 -1283
  40. package/lib/plugins/filtering/index.js.map +1 -1
  41. package/lib/plugins/filtering/types.d.ts +7 -2
  42. package/lib/plugins/filtering/types.d.ts.map +1 -1
  43. package/lib/plugins/grouping-columns/index.js +1 -726
  44. package/lib/plugins/grouping-columns/index.js.map +1 -1
  45. package/lib/plugins/grouping-columns/types.d.ts +3 -0
  46. package/lib/plugins/grouping-columns/types.d.ts.map +1 -1
  47. package/lib/plugins/grouping-rows/index.js +2 -905
  48. package/lib/plugins/grouping-rows/index.js.map +1 -1
  49. package/lib/plugins/grouping-rows/types.d.ts +5 -0
  50. package/lib/plugins/grouping-rows/types.d.ts.map +1 -1
  51. package/lib/plugins/master-detail/index.js +1 -950
  52. package/lib/plugins/master-detail/index.js.map +1 -1
  53. package/lib/plugins/master-detail/types.d.ts +5 -0
  54. package/lib/plugins/master-detail/types.d.ts.map +1 -1
  55. package/lib/plugins/multi-sort/index.js +1 -553
  56. package/lib/plugins/multi-sort/index.js.map +1 -1
  57. package/lib/plugins/multi-sort/types.d.ts +5 -0
  58. package/lib/plugins/multi-sort/types.d.ts.map +1 -1
  59. package/lib/plugins/pinned-columns/index.js +1 -688
  60. package/lib/plugins/pinned-columns/index.js.map +1 -1
  61. package/lib/plugins/pinned-columns/types.d.ts +3 -0
  62. package/lib/plugins/pinned-columns/types.d.ts.map +1 -1
  63. package/lib/plugins/pinned-rows/index.js +1 -704
  64. package/lib/plugins/pinned-rows/index.js.map +1 -1
  65. package/lib/plugins/pinned-rows/types.d.ts +5 -0
  66. package/lib/plugins/pinned-rows/types.d.ts.map +1 -1
  67. package/lib/plugins/pivot/index.js +1 -1191
  68. package/lib/plugins/pivot/index.js.map +1 -1
  69. package/lib/plugins/pivot/types.d.ts +5 -0
  70. package/lib/plugins/pivot/types.d.ts.map +1 -1
  71. package/lib/plugins/print/index.js +1 -691
  72. package/lib/plugins/print/index.js.map +1 -1
  73. package/lib/plugins/print/types.d.ts +3 -0
  74. package/lib/plugins/print/types.d.ts.map +1 -1
  75. package/lib/plugins/reorder/index.js +1 -703
  76. package/lib/plugins/reorder/index.js.map +1 -1
  77. package/lib/plugins/reorder/types.d.ts +5 -0
  78. package/lib/plugins/reorder/types.d.ts.map +1 -1
  79. package/lib/plugins/responsive/index.js +1 -971
  80. package/lib/plugins/responsive/index.js.map +1 -1
  81. package/lib/plugins/responsive/types.d.ts +5 -0
  82. package/lib/plugins/responsive/types.d.ts.map +1 -1
  83. package/lib/plugins/row-reorder/index.js +1 -728
  84. package/lib/plugins/row-reorder/index.js.map +1 -1
  85. package/lib/plugins/row-reorder/types.d.ts +5 -0
  86. package/lib/plugins/row-reorder/types.d.ts.map +1 -1
  87. package/lib/plugins/selection/index.js +1 -1071
  88. package/lib/plugins/selection/index.js.map +1 -1
  89. package/lib/plugins/selection/types.d.ts +3 -0
  90. package/lib/plugins/selection/types.d.ts.map +1 -1
  91. package/lib/plugins/server-side/index.js +1 -521
  92. package/lib/plugins/server-side/index.js.map +1 -1
  93. package/lib/plugins/server-side/types.d.ts +5 -0
  94. package/lib/plugins/server-side/types.d.ts.map +1 -1
  95. package/lib/plugins/tree/index.js +1 -686
  96. package/lib/plugins/tree/index.js.map +1 -1
  97. package/lib/plugins/tree/types.d.ts +5 -0
  98. package/lib/plugins/tree/types.d.ts.map +1 -1
  99. package/lib/plugins/undo-redo/index.js +1 -584
  100. package/lib/plugins/undo-redo/index.js.map +1 -1
  101. package/lib/plugins/undo-redo/types.d.ts +5 -0
  102. package/lib/plugins/undo-redo/types.d.ts.map +1 -1
  103. package/lib/plugins/visibility/index.js +1 -792
  104. package/lib/plugins/visibility/index.js.map +1 -1
  105. package/lib/plugins/visibility/types.d.ts +5 -0
  106. package/lib/plugins/visibility/types.d.ts.map +1 -1
  107. package/package.json +1 -1
  108. package/umd/grid.all.umd.js +1 -186
  109. package/umd/grid.all.umd.js.map +1 -1
  110. package/umd/grid.umd.js +1 -90
  111. package/umd/grid.umd.js.map +1 -1
  112. package/umd/plugins/clipboard.umd.js +1 -6
  113. package/umd/plugins/clipboard.umd.js.map +1 -1
  114. package/umd/plugins/column-virtualization.umd.js +1 -1
  115. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  116. package/umd/plugins/context-menu.umd.js +1 -1
  117. package/umd/plugins/context-menu.umd.js.map +1 -1
  118. package/umd/plugins/editing.umd.js +1 -1
  119. package/umd/plugins/editing.umd.js.map +1 -1
  120. package/umd/plugins/export.umd.js +1 -13
  121. package/umd/plugins/export.umd.js.map +1 -1
  122. package/umd/plugins/filtering.umd.js +1 -1
  123. package/umd/plugins/filtering.umd.js.map +1 -1
  124. package/umd/plugins/grouping-columns.umd.js +1 -1
  125. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  126. package/umd/plugins/grouping-rows.umd.js +1 -4
  127. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  128. package/umd/plugins/master-detail.umd.js +1 -1
  129. package/umd/plugins/master-detail.umd.js.map +1 -1
  130. package/umd/plugins/multi-sort.umd.js +1 -1
  131. package/umd/plugins/multi-sort.umd.js.map +1 -1
  132. package/umd/plugins/pinned-columns.umd.js +1 -1
  133. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  134. package/umd/plugins/pinned-rows.umd.js +1 -1
  135. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  136. package/umd/plugins/pivot.umd.js +1 -1
  137. package/umd/plugins/pivot.umd.js.map +1 -1
  138. package/umd/plugins/print.umd.js +1 -75
  139. package/umd/plugins/print.umd.js.map +1 -1
  140. package/umd/plugins/reorder.umd.js +1 -1
  141. package/umd/plugins/reorder.umd.js.map +1 -1
  142. package/umd/plugins/responsive.umd.js +1 -1
  143. package/umd/plugins/responsive.umd.js.map +1 -1
  144. package/umd/plugins/row-reorder.umd.js +1 -1
  145. package/umd/plugins/row-reorder.umd.js.map +1 -1
  146. package/umd/plugins/selection.umd.js +1 -3
  147. package/umd/plugins/selection.umd.js.map +1 -1
  148. package/umd/plugins/server-side.umd.js +1 -1
  149. package/umd/plugins/server-side.umd.js.map +1 -1
  150. package/umd/plugins/tree.umd.js +1 -1
  151. package/umd/plugins/tree.umd.js.map +1 -1
  152. package/umd/plugins/undo-redo.umd.js +1 -1
  153. package/umd/plugins/undo-redo.umd.js.map +1 -1
  154. package/umd/plugins/visibility.umd.js +1 -1
  155. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -1,704 +1,2 @@
1
- function v(l) {
2
- l && l.querySelectorAll(".cell-focus").forEach((e) => e.classList.remove("cell-focus"));
3
- }
4
- const C = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])', E = document.createElement("template");
5
- E.innerHTML = '<div class="cell" role="gridcell" part="cell"></div>';
6
- const w = document.createElement("template");
7
- w.innerHTML = '<div class="data-grid-row" role="row" part="row"></div>';
8
- function y(l, e) {
9
- if (l._virtualization?.enabled) {
10
- const { rowHeight: a, container: r, viewportEl: s } = l._virtualization, i = r, c = s?.clientHeight ?? i?.clientHeight ?? 0;
11
- if (i && c > 0) {
12
- const u = l._focusRow * a;
13
- u < i.scrollTop ? i.scrollTop = u : u + a > i.scrollTop + c && (i.scrollTop = u - c + a);
14
- }
15
- }
16
- const t = l._activeEditRows !== void 0 && l._activeEditRows !== -1;
17
- t || l.refreshVirtualWindow(!1), v(l._bodyEl), Array.from(l._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach((a) => {
18
- a.setAttribute("aria-selected", "false");
19
- });
20
- const n = l._focusRow, o = l._virtualization.start ?? 0, d = l._virtualization.end ?? l._rows.length;
21
- if (n >= o && n < d) {
22
- const a = l._bodyEl.querySelectorAll(".data-grid-row")[n - o];
23
- let r = a?.children[l._focusCol];
24
- if ((!r || !r.classList?.contains("cell")) && (r = a?.querySelector(`.cell[data-col="${l._focusCol}"]`) ?? a?.querySelector(".cell[data-col]")), r) {
25
- r.classList.add("cell-focus"), r.setAttribute("aria-selected", "true");
26
- const s = l.querySelector(".tbw-scroll-area");
27
- if (s && r && (!t || e?.forceHorizontalScroll)) {
28
- const i = l._getHorizontalScrollOffsets?.(a ?? void 0, r) ?? { left: 0, right: 0 };
29
- if (!i.skipScroll) {
30
- const c = r.getBoundingClientRect(), u = s.getBoundingClientRect(), f = c.left - u.left + s.scrollLeft, g = f + c.width, h = s.scrollLeft + i.left, m = s.scrollLeft + s.clientWidth - i.right;
31
- f < h ? s.scrollLeft = f - i.left : g > m && (s.scrollLeft = g - s.clientWidth + i.right);
32
- }
33
- }
34
- if (t && r.classList.contains("editing")) {
35
- const i = r.querySelector(C);
36
- if (i && document.activeElement !== i)
37
- try {
38
- i.focus({ preventScroll: !0 });
39
- } catch {
40
- }
41
- } else if (t && !r.contains(document.activeElement)) {
42
- r.hasAttribute("tabindex") || r.setAttribute("tabindex", "-1");
43
- try {
44
- r.focus({ preventScroll: !0 });
45
- } catch {
46
- }
47
- } else if (!t) {
48
- const i = l;
49
- document.activeElement !== i && i.focus({ preventScroll: !0 });
50
- }
51
- }
52
- }
53
- }
54
- const p = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', L = {
55
- expand: "▶",
56
- collapse: "▼",
57
- sortAsc: "▲",
58
- sortDesc: "▼",
59
- sortNone: "⇅",
60
- submenuArrow: "▶",
61
- dragHandle: "⋮⋮",
62
- toolPanel: "☰",
63
- filter: p,
64
- filterActive: p,
65
- print: "🖨️"
66
- };
67
- class A {
68
- /**
69
- * Plugin dependencies - declare other plugins this one requires.
70
- *
71
- * Dependencies are validated when the plugin is attached.
72
- * Required dependencies throw an error if missing.
73
- * Optional dependencies log an info message if missing.
74
- *
75
- * @example
76
- * ```typescript
77
- * static readonly dependencies: PluginDependency[] = [
78
- * { name: 'editing', required: true, reason: 'Tracks cell edits for undo/redo' },
79
- * { name: 'selection', required: false, reason: 'Enables selection-based undo' },
80
- * ];
81
- * ```
82
- */
83
- static dependencies;
84
- /**
85
- * Plugin manifest - declares owned properties, config rules, and hook priorities.
86
- *
87
- * This is read by the configuration validator to:
88
- * - Validate that required plugins are loaded when their properties are used
89
- * - Execute configRules to detect invalid/conflicting settings
90
- * - Order hook execution based on priority
91
- *
92
- * @example
93
- * ```typescript
94
- * static override readonly manifest: PluginManifest<MyConfig> = {
95
- * ownedProperties: [
96
- * { property: 'myProp', level: 'column', description: 'the "myProp" column property' },
97
- * ],
98
- * configRules: [
99
- * { id: 'myPlugin/conflict', severity: 'warn', message: '...', check: (c) => c.a && c.b },
100
- * ],
101
- * };
102
- * ```
103
- */
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- static manifest;
106
- /**
107
- * Plugin version - defaults to grid version for built-in plugins.
108
- * Third-party plugins can override with their own semver.
109
- */
110
- version = typeof __GRID_VERSION__ < "u" ? __GRID_VERSION__ : "dev";
111
- /** CSS styles to inject into the grid's shadow DOM */
112
- styles;
113
- /** Custom cell renderers keyed by type name */
114
- cellRenderers;
115
- /** Custom header renderers keyed by type name */
116
- headerRenderers;
117
- /** Custom cell editors keyed by type name */
118
- cellEditors;
119
- /** The grid instance this plugin is attached to */
120
- grid;
121
- /** Plugin configuration - merged with defaults in attach() */
122
- config;
123
- /** User-provided configuration from constructor */
124
- userConfig;
125
- /**
126
- * Plugin-level AbortController for event listener cleanup.
127
- * Created fresh in attach(), aborted in detach().
128
- * This ensures event listeners are properly cleaned up when plugins are re-attached.
129
- */
130
- #e;
131
- /**
132
- * Default configuration - subclasses should override this getter.
133
- * Note: This must be a getter (not property initializer) for proper inheritance
134
- * since property initializers run after parent constructor.
135
- */
136
- get defaultConfig() {
137
- return {};
138
- }
139
- constructor(e = {}) {
140
- this.userConfig = e;
141
- }
142
- /**
143
- * Called when the plugin is attached to a grid.
144
- * Override to set up event listeners, initialize state, etc.
145
- *
146
- * @example
147
- * ```ts
148
- * attach(grid: GridElement): void {
149
- * super.attach(grid);
150
- * // Set up document-level listeners with auto-cleanup
151
- * document.addEventListener('keydown', this.handleEscape, {
152
- * signal: this.disconnectSignal
153
- * });
154
- * }
155
- * ```
156
- */
157
- attach(e) {
158
- this.#e?.abort(), this.#e = new AbortController(), this.grid = e, this.config = { ...this.defaultConfig, ...this.userConfig };
159
- }
160
- /**
161
- * Called when the plugin is detached from a grid.
162
- * Override to clean up event listeners, timers, etc.
163
- *
164
- * @example
165
- * ```ts
166
- * detach(): void {
167
- * // Clean up any state not handled by disconnectSignal
168
- * this.selectedRows.clear();
169
- * this.cache = null;
170
- * }
171
- * ```
172
- */
173
- detach() {
174
- this.#e?.abort(), this.#e = void 0;
175
- }
176
- /**
177
- * Get another plugin instance from the same grid.
178
- * Use for inter-plugin communication.
179
- *
180
- * @example
181
- * ```ts
182
- * const selection = this.getPlugin(SelectionPlugin);
183
- * if (selection) {
184
- * const selectedRows = selection.getSelectedRows();
185
- * }
186
- * ```
187
- */
188
- getPlugin(e) {
189
- return this.grid?.getPlugin(e);
190
- }
191
- /**
192
- * Emit a custom event from the grid.
193
- */
194
- emit(e, t) {
195
- this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
196
- }
197
- /**
198
- * Emit a cancelable custom event from the grid.
199
- * @returns `true` if the event was cancelled (preventDefault called), `false` otherwise
200
- */
201
- emitCancelable(e, t) {
202
- const n = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
203
- return this.grid?.dispatchEvent?.(n), n.defaultPrevented;
204
- }
205
- // =========================================================================
206
- // Event Bus - Plugin-to-Plugin Communication
207
- // =========================================================================
208
- /**
209
- * Subscribe to an event from another plugin.
210
- * The subscription is automatically cleaned up when this plugin is detached.
211
- *
212
- * @category Plugin Development
213
- * @param eventType - The event type to listen for (e.g., 'filter-change')
214
- * @param callback - The callback to invoke when the event is emitted
215
- *
216
- * @example
217
- * ```typescript
218
- * // In attach() or other initialization
219
- * this.on('filter-change', (detail) => {
220
- * console.log('Filter changed:', detail);
221
- * });
222
- * ```
223
- */
224
- on(e, t) {
225
- this.grid?._pluginManager?.subscribe(this, e, t);
226
- }
227
- /**
228
- * Unsubscribe from a plugin event.
229
- *
230
- * @category Plugin Development
231
- * @param eventType - The event type to stop listening for
232
- *
233
- * @example
234
- * ```typescript
235
- * this.off('filter-change');
236
- * ```
237
- */
238
- off(e) {
239
- this.grid?._pluginManager?.unsubscribe(this, e);
240
- }
241
- /**
242
- * Emit an event to other plugins via the Event Bus.
243
- * This is for inter-plugin communication only; it does NOT dispatch DOM events.
244
- * Use `emit()` to dispatch DOM events that external consumers can listen to.
245
- *
246
- * @category Plugin Development
247
- * @param eventType - The event type to emit (should be declared in manifest.events)
248
- * @param detail - The event payload
249
- *
250
- * @example
251
- * ```typescript
252
- * // Emit to other plugins (not DOM)
253
- * this.emitPluginEvent('filter-change', { field: 'name', value: 'Alice' });
254
- *
255
- * // For DOM events that consumers can addEventListener to:
256
- * this.emit('filter-change', { field: 'name', value: 'Alice' });
257
- * ```
258
- */
259
- emitPluginEvent(e, t) {
260
- this.grid?._pluginManager?.emitPluginEvent(e, t);
261
- }
262
- /**
263
- * Request a re-render of the grid.
264
- * Uses ROWS phase - does NOT trigger processColumns hooks.
265
- */
266
- requestRender() {
267
- this.grid?.requestRender?.();
268
- }
269
- /**
270
- * Request a columns re-render of the grid.
271
- * Uses COLUMNS phase - triggers processColumns hooks.
272
- * Use this when your plugin needs to reprocess column configuration.
273
- */
274
- requestColumnsRender() {
275
- this.grid?.requestColumnsRender?.();
276
- }
277
- /**
278
- * Request a re-render and restore focus styling afterward.
279
- * Use this when a plugin action (like expand/collapse) triggers a render
280
- * but needs to maintain keyboard navigation focus.
281
- */
282
- requestRenderWithFocus() {
283
- this.grid?.requestRenderWithFocus?.();
284
- }
285
- /**
286
- * Request a lightweight style update without rebuilding DOM.
287
- * Use this instead of requestRender() when only CSS classes need updating.
288
- */
289
- requestAfterRender() {
290
- this.grid?.requestAfterRender?.();
291
- }
292
- /**
293
- * Get the current rows from the grid.
294
- */
295
- get rows() {
296
- return this.grid?.rows ?? [];
297
- }
298
- /**
299
- * Get the original unfiltered/unprocessed rows from the grid.
300
- * Use this when you need all source data regardless of active filters.
301
- */
302
- get sourceRows() {
303
- return this.grid?.sourceRows ?? [];
304
- }
305
- /**
306
- * Get the current columns from the grid.
307
- */
308
- get columns() {
309
- return this.grid?.columns ?? [];
310
- }
311
- /**
312
- * Get only visible columns from the grid (excludes hidden).
313
- * Use this for rendering that needs to match the grid template.
314
- */
315
- get visibleColumns() {
316
- return this.grid?._visibleColumns ?? [];
317
- }
318
- /**
319
- * Get the grid as an HTMLElement for direct DOM operations.
320
- * Use sparingly - prefer the typed GridElementRef API when possible.
321
- *
322
- * @example
323
- * ```ts
324
- * const width = this.gridElement.clientWidth;
325
- * this.gridElement.classList.add('my-plugin-active');
326
- * ```
327
- */
328
- get gridElement() {
329
- return this.grid;
330
- }
331
- /**
332
- * Get the disconnect signal for event listener cleanup.
333
- * This signal is aborted when the grid disconnects from the DOM.
334
- * Use this when adding event listeners that should be cleaned up automatically.
335
- *
336
- * Best for:
337
- * - Document/window-level listeners added in attach()
338
- * - Listeners on the grid element itself
339
- * - Any listener that should persist across renders
340
- *
341
- * Not needed for:
342
- * - Listeners on elements created in afterRender() (removed with element)
343
- *
344
- * @example
345
- * element.addEventListener('click', handler, { signal: this.disconnectSignal });
346
- * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
347
- */
348
- get disconnectSignal() {
349
- return this.#e?.signal ?? this.grid?.disconnectSignal;
350
- }
351
- /**
352
- * Get the grid-level icons configuration.
353
- * Returns merged icons (user config + defaults).
354
- */
355
- get gridIcons() {
356
- const e = this.grid?.gridConfig?.icons ?? {};
357
- return { ...L, ...e };
358
- }
359
- // #region Animation Helpers
360
- /**
361
- * Check if animations are enabled at the grid level.
362
- * Respects gridConfig.animation.mode and the CSS variable set by the grid.
363
- *
364
- * Plugins should use this to skip animations when:
365
- * - Animation mode is 'off' or `false`
366
- * - User prefers reduced motion and mode is 'reduced-motion' (default)
367
- *
368
- * @example
369
- * ```ts
370
- * private get animationStyle(): 'slide' | 'fade' | false {
371
- * if (!this.isAnimationEnabled) return false;
372
- * return this.config.animation ?? 'slide';
373
- * }
374
- * ```
375
- */
376
- get isAnimationEnabled() {
377
- const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
378
- if (e === !1 || e === "off") return !1;
379
- if (e === !0 || e === "on") return !0;
380
- const t = this.gridElement;
381
- return t ? getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
382
- }
383
- /**
384
- * Get the animation duration in milliseconds from CSS variable.
385
- * Falls back to 200ms if not set.
386
- *
387
- * Plugins can use this for their animation timing to stay consistent
388
- * with the grid-level animation.duration setting.
389
- *
390
- * @example
391
- * ```ts
392
- * element.animate(keyframes, { duration: this.animationDuration });
393
- * ```
394
- */
395
- get animationDuration() {
396
- const e = this.gridElement;
397
- if (e) {
398
- const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
399
- if (!isNaN(n)) return n;
400
- }
401
- return 200;
402
- }
403
- // #endregion
404
- /**
405
- * Resolve an icon value to string or HTMLElement.
406
- * Checks plugin config first, then grid-level icons, then defaults.
407
- *
408
- * @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
409
- * @param pluginOverride - Optional plugin-level override
410
- * @returns The resolved icon value
411
- */
412
- resolveIcon(e, t) {
413
- return t !== void 0 ? t : this.gridIcons[e];
414
- }
415
- /**
416
- * Set an icon value on an element.
417
- * Handles both string (text/HTML) and HTMLElement values.
418
- *
419
- * @param element - The element to set the icon on
420
- * @param icon - The icon value (string or HTMLElement)
421
- */
422
- setIcon(e, t) {
423
- typeof t == "string" ? e.innerHTML = t : t instanceof HTMLElement && (e.innerHTML = "", e.appendChild(t.cloneNode(!0)));
424
- }
425
- /**
426
- * Log a warning message.
427
- */
428
- warn(e) {
429
- console.warn(`[tbw-grid:${this.name}] ${e}`);
430
- }
431
- // #endregion
432
- }
433
- function O(l) {
434
- const e = l.meta ?? {};
435
- return e.lockPosition !== !0 && e.suppressMovable !== !0;
436
- }
437
- function b(l, e, t) {
438
- if (e === t || e < 0 || e >= l.length || t < 0 || t > l.length) return l;
439
- const n = [...l], [o] = n.splice(e, 1);
440
- return n.splice(t, 0, o), n;
441
- }
442
- const _ = '@layer tbw-plugins{.header-row>.cell[draggable=true]{cursor:grab;position:relative}.header-row>.cell.dragging{opacity:.5;cursor:grabbing}.header-row>.cell.drop-before:before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.header-row>.cell.drop-after:after{content:"";position:absolute;right:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.cell.flip-animating{transition:transform var(--tbw-animation-duration, .2s) ease-out;will-change:transform;z-index:1}@keyframes reorder-fade-in{0%{opacity:0}to{opacity:1}}.cell.fade-animating{animation:reorder-fade-in var(--tbw-animation-duration, .2s) ease-out backwards}}';
443
- class R extends A {
444
- /** @internal */
445
- name = "reorder";
446
- /** @internal */
447
- styles = _;
448
- /** @internal */
449
- get defaultConfig() {
450
- return {
451
- animation: "flip"
452
- // Plugin's own default
453
- };
454
- }
455
- /**
456
- * Resolve animation type from plugin config.
457
- * Uses base class isAnimationEnabled to respect grid-level settings.
458
- */
459
- get animationType() {
460
- return this.isAnimationEnabled ? this.config.animation !== void 0 ? this.config.animation : "flip" : !1;
461
- }
462
- /**
463
- * Get animation duration, allowing plugin config override.
464
- * Uses base class animationDuration for default.
465
- */
466
- get animationDuration() {
467
- return this.config.animationDuration !== void 0 ? this.config.animationDuration : super.animationDuration;
468
- }
469
- // #region Internal State
470
- isDragging = !1;
471
- draggedField = null;
472
- draggedIndex = null;
473
- dropIndex = null;
474
- /**
475
- * Check if a column can be moved, considering both column config and plugin queries.
476
- */
477
- canMoveColumnWithPlugins(e) {
478
- return !e || !O(e) ? !1 : !this.grid.query("canMoveColumn", e).includes(!1);
479
- }
480
- /**
481
- * Clear all drag-related classes from header cells.
482
- */
483
- clearDragClasses() {
484
- this.gridElement?.querySelectorAll(".header-row > .cell").forEach((e) => {
485
- e.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
486
- });
487
- }
488
- // #endregion
489
- // #region Lifecycle
490
- /** @internal */
491
- attach(e) {
492
- super.attach(e), e.addEventListener(
493
- "column-reorder-request",
494
- (t) => {
495
- const n = t.detail;
496
- n?.field && typeof n.toIndex == "number" && this.moveColumn(n.field, n.toIndex);
497
- },
498
- { signal: this.disconnectSignal }
499
- );
500
- }
501
- /** @internal */
502
- detach() {
503
- this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null;
504
- }
505
- // #endregion
506
- // #region Hooks
507
- /** @internal */
508
- afterRender() {
509
- const e = this.gridElement;
510
- if (!e) return;
511
- e.querySelectorAll(".header-row > .cell").forEach((n) => {
512
- const o = n, d = o.getAttribute("data-field");
513
- if (!d) return;
514
- const a = this.columns.find((r) => r.field === d);
515
- if (!this.canMoveColumnWithPlugins(a)) {
516
- o.draggable = !1;
517
- return;
518
- }
519
- o.draggable = !0, !o.getAttribute("data-dragstart-bound") && (o.setAttribute("data-dragstart-bound", "true"), o.addEventListener("dragstart", (r) => {
520
- const i = this.getColumnOrder().indexOf(d);
521
- this.isDragging = !0, this.draggedField = d, this.draggedIndex = i, r.dataTransfer && (r.dataTransfer.effectAllowed = "move", r.dataTransfer.setData("text/plain", d)), o.classList.add("dragging");
522
- }), o.addEventListener("dragend", () => {
523
- this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses();
524
- }), o.addEventListener("dragover", (r) => {
525
- if (r.preventDefault(), !this.isDragging || this.draggedField === d) return;
526
- const s = o.getBoundingClientRect(), i = s.left + s.width / 2, u = this.getColumnOrder().indexOf(d);
527
- this.dropIndex = r.clientX < i ? u : u + 1, o.classList.add("drop-target"), o.classList.toggle("drop-before", r.clientX < i), o.classList.toggle("drop-after", r.clientX >= i);
528
- }), o.addEventListener("dragleave", () => {
529
- o.classList.remove("drop-target", "drop-before", "drop-after");
530
- }), o.addEventListener("drop", (r) => {
531
- r.preventDefault();
532
- const s = this.draggedField, i = this.draggedIndex, c = this.dropIndex;
533
- if (!this.isDragging || s === null || i === null || c === null)
534
- return;
535
- const u = c > i ? c - 1 : c, f = this.getColumnOrder(), g = b(f, i, u), h = {
536
- field: s,
537
- fromIndex: i,
538
- toIndex: u,
539
- columnOrder: g
540
- };
541
- this.emitCancelable("column-move", h) || this.updateColumnOrder(g);
542
- }));
543
- });
544
- }
545
- /**
546
- * Handle Alt+Arrow keyboard shortcuts for column reordering.
547
- * @internal
548
- */
549
- onKeyDown(e) {
550
- if (!e.altKey || e.key !== "ArrowLeft" && e.key !== "ArrowRight")
551
- return;
552
- const t = this.grid, n = t._focusCol, o = t._visibleColumns;
553
- if (n < 0 || n >= o.length) return;
554
- const d = o[n];
555
- if (!this.canMoveColumnWithPlugins(d)) return;
556
- const a = this.getColumnOrder(), r = a.indexOf(d.field);
557
- if (r === -1) return;
558
- const s = e.key === "ArrowLeft" ? r - 1 : r + 1;
559
- if (s < 0 || s >= a.length) return;
560
- const i = o.find((c) => c.field === a[s]);
561
- if (this.canMoveColumnWithPlugins(i))
562
- return this.moveColumn(d.field, s), t._focusCol = s, y(this.grid), e.preventDefault(), e.stopPropagation(), !0;
563
- }
564
- // #endregion
565
- // #region Public API
566
- /**
567
- * Get the current column order from the grid.
568
- * @returns Array of field names in display order
569
- */
570
- getColumnOrder() {
571
- return this.grid.getColumnOrder();
572
- }
573
- /**
574
- * Move a column to a new position.
575
- * @param field - The field name of the column to move
576
- * @param toIndex - The target index
577
- */
578
- moveColumn(e, t) {
579
- const n = this.getColumnOrder(), o = n.indexOf(e);
580
- if (o === -1) return;
581
- const d = b(n, o, t);
582
- this.emitCancelable("column-move", {
583
- field: e,
584
- fromIndex: o,
585
- toIndex: t,
586
- columnOrder: d
587
- }) || this.updateColumnOrder(d);
588
- }
589
- /**
590
- * Set a specific column order.
591
- * @param order - Array of field names in desired order
592
- */
593
- setColumnOrder(e) {
594
- this.updateColumnOrder(e);
595
- }
596
- /**
597
- * Reset column order to the original configuration order.
598
- */
599
- resetColumnOrder() {
600
- const e = this.columns.map((t) => t.field);
601
- this.updateColumnOrder(e);
602
- }
603
- // #endregion
604
- // #region View Transition
605
- /**
606
- * Capture header cell positions before reorder.
607
- */
608
- captureHeaderPositions() {
609
- const e = /* @__PURE__ */ new Map();
610
- return this.gridElement?.querySelectorAll(".header-row > .cell[data-field]").forEach((t) => {
611
- const n = t.getAttribute("data-field");
612
- n && e.set(n, t.getBoundingClientRect().left);
613
- }), e;
614
- }
615
- /**
616
- * Apply FLIP animation for column reorder.
617
- * Uses CSS transitions - JS sets initial transform and toggles class.
618
- * @param oldPositions - Header positions captured before DOM change
619
- */
620
- animateFLIP(e) {
621
- const t = this.gridElement;
622
- if (!t || e.size === 0) return;
623
- const n = /* @__PURE__ */ new Map();
624
- if (t.querySelectorAll(".header-row > .cell[data-field]").forEach((a) => {
625
- const r = a.getAttribute("data-field");
626
- if (!r) return;
627
- const s = e.get(r);
628
- if (s === void 0) return;
629
- const i = s - a.getBoundingClientRect().left;
630
- Math.abs(i) > 1 && n.set(r, i);
631
- }), n.size === 0) return;
632
- const o = [];
633
- if (t.querySelectorAll(".cell[data-field]").forEach((a) => {
634
- const r = n.get(a.getAttribute("data-field") ?? "");
635
- if (r !== void 0) {
636
- const s = a;
637
- s.style.transform = `translateX(${r}px)`, o.push(s);
638
- }
639
- }), o.length === 0) return;
640
- this.gridElement.offsetHeight;
641
- const d = this.animationDuration;
642
- requestAnimationFrame(() => {
643
- o.forEach((a) => {
644
- a.classList.add("flip-animating"), a.style.transform = "";
645
- }), setTimeout(() => {
646
- o.forEach((a) => {
647
- a.style.transform = "", a.classList.remove("flip-animating");
648
- });
649
- }, d + 50);
650
- });
651
- }
652
- /**
653
- * Apply crossfade animation for moved columns.
654
- * Uses CSS keyframes - JS just toggles classes.
655
- */
656
- animateFade(e) {
657
- const t = this.gridElement;
658
- if (!t) {
659
- e();
660
- return;
661
- }
662
- const n = this.captureHeaderPositions();
663
- e();
664
- const o = /* @__PURE__ */ new Set();
665
- if (t.querySelectorAll(".header-row > .cell[data-field]").forEach((r) => {
666
- const s = r.getAttribute("data-field");
667
- if (!s) return;
668
- const i = n.get(s);
669
- if (i === void 0) return;
670
- const c = r.getBoundingClientRect().left;
671
- Math.abs(i - c) > 1 && o.add(s);
672
- }), o.size === 0) return;
673
- const d = [];
674
- if (t.querySelectorAll(".cell[data-field]").forEach((r) => {
675
- const s = r.getAttribute("data-field");
676
- if (s && o.has(s)) {
677
- const i = r;
678
- i.classList.add("fade-animating"), d.push(i);
679
- }
680
- }), d.length === 0) return;
681
- const a = this.animationDuration;
682
- setTimeout(() => {
683
- d.forEach((r) => r.classList.remove("fade-animating"));
684
- }, a + 50);
685
- }
686
- /**
687
- * Update column order with configured animation.
688
- */
689
- updateColumnOrder(e) {
690
- const t = this.animationType;
691
- if (t === "flip" && this.gridElement) {
692
- const n = this.captureHeaderPositions();
693
- this.grid.setColumnOrder(e), requestAnimationFrame(() => {
694
- this.gridElement.offsetHeight, this.animateFLIP(n);
695
- });
696
- } else t === "fade" ? this.animateFade(() => this.grid.setColumnOrder(e)) : this.grid.setColumnOrder(e);
697
- this.grid.requestStateChange?.();
698
- }
699
- // #endregion
700
- }
701
- export {
702
- R as ReorderPlugin
703
- };
1
+ document.createElement("template").innerHTML='<div class="cell" role="gridcell" part="cell"></div>';document.createElement("template").innerHTML='<div class="data-grid-row" role="row" part="row"></div>';const e='<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>',t={expand:"▶",collapse:"▼",sortAsc:"▲",sortDesc:"▼",sortNone:"⇅",submenuArrow:"▶",dragHandle:"⋮⋮",toolPanel:"☰",filter:e,filterActive:e,print:"🖨️"};class r{static dependencies;static manifest;version="undefined"!=typeof __GRID_VERSION__?__GRID_VERSION__:"dev";styles;cellRenderers;headerRenderers;cellEditors;grid;config;userConfig;#e;get defaultConfig(){return{}}constructor(e={}){this.userConfig=e}attach(e){this.#e?.abort(),this.#e=new AbortController,this.grid=e,this.config={...this.defaultConfig,...this.userConfig}}detach(){this.#e?.abort(),this.#e=void 0}getPlugin(e){return this.grid?.getPlugin(e)}emit(e,t){this.grid?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0}))}emitCancelable(e,t){const r=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});return this.grid?.dispatchEvent?.(r),r.defaultPrevented}on(e,t){this.grid?._pluginManager?.subscribe(this,e,t)}off(e){this.grid?._pluginManager?.unsubscribe(this,e)}emitPluginEvent(e,t){this.grid?._pluginManager?.emitPluginEvent(e,t)}requestRender(){this.grid?.requestRender?.()}requestColumnsRender(){this.grid?.requestColumnsRender?.()}requestRenderWithFocus(){this.grid?.requestRenderWithFocus?.()}requestAfterRender(){this.grid?.requestAfterRender?.()}get rows(){return this.grid?.rows??[]}get sourceRows(){return this.grid?.sourceRows??[]}get columns(){return this.grid?.columns??[]}get visibleColumns(){return this.grid?._visibleColumns??[]}get gridElement(){return this.grid}get disconnectSignal(){return this.#e?.signal??this.grid?.disconnectSignal}get gridIcons(){const e=this.grid?.gridConfig?.icons??{};return{...t,...e}}get isAnimationEnabled(){const e=this.grid?.effectiveConfig?.animation?.mode??"reduced-motion";if(!1===e||"off"===e)return!1;if(!0===e||"on"===e)return!0;const t=this.gridElement;if(t){return"0"!==getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim()}return!0}get animationDuration(){const e=this.gridElement;if(e){const t=getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(),r=parseInt(t,10);if(!isNaN(r))return r}return 200}resolveIcon(e,t){return void 0!==t?t:this.gridIcons[e]}setIcon(e,t){"string"==typeof t?e.innerHTML=t:t instanceof HTMLElement&&(e.innerHTML="",e.appendChild(t.cloneNode(!0)))}warn(e){console.warn(`[tbw-grid:${this.name}] ${e}`)}}function i(e,t,r){if(t===r)return e;if(t<0||t>=e.length)return e;if(r<0||r>e.length)return e;const i=[...e],[n]=i.splice(t,1);return i.splice(r,0,n),i}class n extends r{name="reorder";styles='@layer tbw-plugins{.header-row>.cell[draggable=true]{cursor:grab;position:relative}.header-row>.cell.dragging{opacity:.5;cursor:grabbing}.header-row>.cell.drop-before:before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.header-row>.cell.drop-after:after{content:"";position:absolute;right:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.cell.flip-animating{transition:transform var(--tbw-animation-duration, .2s) ease-out;will-change:transform;z-index:1}@keyframes reorder-fade-in{0%{opacity:0}to{opacity:1}}.cell.fade-animating{animation:reorder-fade-in var(--tbw-animation-duration, .2s) ease-out backwards}}';get defaultConfig(){return{animation:"flip"}}get animationType(){return!!this.isAnimationEnabled&&(void 0!==this.config.animation?this.config.animation:"flip")}get animationDuration(){return void 0!==this.config.animationDuration?this.config.animationDuration:super.animationDuration}isDragging=!1;draggedField=null;draggedIndex=null;dropIndex=null;canMoveColumnWithPlugins(e){if(!e||!function(e){const t=e.meta??{};return!0!==t.lockPosition&&!0!==t.suppressMovable}(e))return!1;return!this.grid.query("canMoveColumn",e).includes(!1)}clearDragClasses(){this.gridElement?.querySelectorAll(".header-row > .cell").forEach(e=>{e.classList.remove("dragging","drop-target","drop-before","drop-after")})}attach(e){super.attach(e),e.addEventListener("column-reorder-request",e=>{const t=e.detail;t?.field&&"number"==typeof t.toIndex&&this.moveColumn(t.field,t.toIndex)},{signal:this.disconnectSignal})}detach(){this.isDragging=!1,this.draggedField=null,this.draggedIndex=null,this.dropIndex=null}afterRender(){const e=this.gridElement;if(!e)return;e.querySelectorAll(".header-row > .cell").forEach(e=>{const t=e,r=t.getAttribute("data-field");if(!r)return;const n=this.columns.find(e=>e.field===r);this.canMoveColumnWithPlugins(n)?(t.draggable=!0,t.getAttribute("data-dragstart-bound")||(t.setAttribute("data-dragstart-bound","true"),t.addEventListener("dragstart",e=>{const i=this.getColumnOrder().indexOf(r);this.isDragging=!0,this.draggedField=r,this.draggedIndex=i,e.dataTransfer&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",r)),t.classList.add("dragging")}),t.addEventListener("dragend",()=>{this.isDragging=!1,this.draggedField=null,this.draggedIndex=null,this.dropIndex=null,this.clearDragClasses()}),t.addEventListener("dragover",e=>{if(e.preventDefault(),!this.isDragging||this.draggedField===r)return;const i=t.getBoundingClientRect(),n=i.left+i.width/2,o=this.getColumnOrder().indexOf(r);this.dropIndex=e.clientX<n?o:o+1,t.classList.add("drop-target"),t.classList.toggle("drop-before",e.clientX<n),t.classList.toggle("drop-after",e.clientX>=n)}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target","drop-before","drop-after")}),t.addEventListener("drop",e=>{e.preventDefault();const t=this.draggedField,r=this.draggedIndex,n=this.dropIndex;if(!this.isDragging||null===t||null===r||null===n)return;const o=n>r?n-1:n,s=i(this.getColumnOrder(),r,o),a={field:t,fromIndex:r,toIndex:o,columnOrder:s};this.emitCancelable("column-move",a)||this.updateColumnOrder(s)}))):t.draggable=!1})}onKeyDown(e){if(!e.altKey||"ArrowLeft"!==e.key&&"ArrowRight"!==e.key)return;const t=this.grid,r=t._focusCol,i=t._visibleColumns;if(r<0||r>=i.length)return;const n=i[r];if(!this.canMoveColumnWithPlugins(n))return;const o=this.getColumnOrder(),s=o.indexOf(n.field);if(-1===s)return;const a="ArrowLeft"===e.key?s-1:s+1;if(a<0||a>=o.length)return;const l=i.find(e=>e.field===o[a]);return this.canMoveColumnWithPlugins(l)?(this.moveColumn(n.field,a),t._focusCol=a,function(e,t){if(e._virtualization?.enabled){const{rowHeight:t,container:r,viewportEl:i}=e._virtualization,n=r,o=i?.clientHeight??n?.clientHeight??0;if(n&&o>0){const r=e._focusRow*t;r<n.scrollTop?n.scrollTop=r:r+t>n.scrollTop+o&&(n.scrollTop=r-o+t)}}const r=void 0!==e._activeEditRows&&-1!==e._activeEditRows;var i;r||e.refreshVirtualWindow(!1),(i=e._bodyEl)&&i.querySelectorAll(".cell-focus").forEach(e=>e.classList.remove("cell-focus")),Array.from(e._bodyEl.querySelectorAll('[aria-selected="true"]')).forEach(e=>{e.setAttribute("aria-selected","false")});const n=e._focusRow,o=e._virtualization.start??0,s=e._virtualization.end??e._rows.length;if(n>=o&&n<s){const i=e._bodyEl.querySelectorAll(".data-grid-row")[n-o];let s=i?.children[e._focusCol];if(s&&s.classList?.contains("cell")||(s=i?.querySelector(`.cell[data-col="${e._focusCol}"]`)??i?.querySelector(".cell[data-col]")),s){s.classList.add("cell-focus"),s.setAttribute("aria-selected","true");const n=e.querySelector(".tbw-scroll-area");if(n&&s&&(!r||t?.forceHorizontalScroll)){const t=e._getHorizontalScrollOffsets?.(i??void 0,s)??{left:0,right:0};if(!t.skipScroll){const e=s.getBoundingClientRect(),r=n.getBoundingClientRect(),i=e.left-r.left+n.scrollLeft,o=i+e.width,a=n.scrollLeft+t.left,l=n.scrollLeft+n.clientWidth-t.right;i<a?n.scrollLeft=i-t.left:o>l&&(n.scrollLeft=o-n.clientWidth+t.right)}}if(r&&s.classList.contains("editing")){const e=s.querySelector('input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])');if(e&&document.activeElement!==e)try{e.focus({preventScroll:!0})}catch{}}else if(r&&!s.contains(document.activeElement)){s.hasAttribute("tabindex")||s.setAttribute("tabindex","-1");try{s.focus({preventScroll:!0})}catch{}}else if(!r){const t=e;document.activeElement!==t&&t.focus({preventScroll:!0})}}}}(this.grid),e.preventDefault(),e.stopPropagation(),!0):void 0}getColumnOrder(){return this.grid.getColumnOrder()}moveColumn(e,t){const r=this.getColumnOrder(),n=r.indexOf(e);if(-1===n)return;const o=i(r,n,t);this.emitCancelable("column-move",{field:e,fromIndex:n,toIndex:t,columnOrder:o})||this.updateColumnOrder(o)}setColumnOrder(e){this.updateColumnOrder(e)}resetColumnOrder(){const e=this.columns.map(e=>e.field);this.updateColumnOrder(e)}captureHeaderPositions(){const e=/* @__PURE__ */new Map;return this.gridElement?.querySelectorAll(".header-row > .cell[data-field]").forEach(t=>{const r=t.getAttribute("data-field");r&&e.set(r,t.getBoundingClientRect().left)}),e}animateFLIP(e){const t=this.gridElement;if(!t||0===e.size)return;const r=/* @__PURE__ */new Map;if(t.querySelectorAll(".header-row > .cell[data-field]").forEach(t=>{const i=t.getAttribute("data-field");if(!i)return;const n=e.get(i);if(void 0===n)return;const o=n-t.getBoundingClientRect().left;Math.abs(o)>1&&r.set(i,o)}),0===r.size)return;const i=[];if(t.querySelectorAll(".cell[data-field]").forEach(e=>{const t=r.get(e.getAttribute("data-field")??"");if(void 0!==t){const r=e;r.style.transform=`translateX(${t}px)`,i.push(r)}}),0===i.length)return;this.gridElement.offsetHeight;const n=this.animationDuration;requestAnimationFrame(()=>{i.forEach(e=>{e.classList.add("flip-animating"),e.style.transform=""}),setTimeout(()=>{i.forEach(e=>{e.style.transform="",e.classList.remove("flip-animating")})},n+50)})}animateFade(e){const t=this.gridElement;if(!t)return void e();const r=this.captureHeaderPositions();e();const i=/* @__PURE__ */new Set;if(t.querySelectorAll(".header-row > .cell[data-field]").forEach(e=>{const t=e.getAttribute("data-field");if(!t)return;const n=r.get(t);if(void 0===n)return;const o=e.getBoundingClientRect().left;Math.abs(n-o)>1&&i.add(t)}),0===i.size)return;const n=[];if(t.querySelectorAll(".cell[data-field]").forEach(e=>{const t=e.getAttribute("data-field");if(t&&i.has(t)){const t=e;t.classList.add("fade-animating"),n.push(t)}}),0===n.length)return;const o=this.animationDuration;setTimeout(()=>{n.forEach(e=>e.classList.remove("fade-animating"))},o+50)}updateColumnOrder(e){const t=this.animationType;if("flip"===t&&this.gridElement){const t=this.captureHeaderPositions();this.grid.setColumnOrder(e),requestAnimationFrame(()=>{this.gridElement.offsetHeight,this.animateFLIP(t)})}else"fade"===t?this.animateFade(()=>this.grid.setColumnOrder(e)):this.grid.setColumnOrder(e);this.grid.requestStateChange?.()}}export{n as ReorderPlugin};
704
2
  //# sourceMappingURL=index.js.map