@toolbox-web/grid 0.4.1 → 0.4.2

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 (157) hide show
  1. package/README.md +10 -13
  2. package/all.js +1101 -1048
  3. package/all.js.map +1 -1
  4. package/index.js +245 -137
  5. package/index.js.map +1 -1
  6. package/lib/core/grid.d.ts +10 -0
  7. package/lib/core/grid.d.ts.map +1 -1
  8. package/lib/core/internal/config-manager.d.ts +1 -0
  9. package/lib/core/internal/config-manager.d.ts.map +1 -1
  10. package/lib/core/internal/keyboard.d.ts.map +1 -1
  11. package/lib/core/internal/utils.d.ts +1 -0
  12. package/lib/core/internal/utils.d.ts.map +1 -1
  13. package/lib/core/plugin/base-plugin.d.ts +57 -1
  14. package/lib/core/plugin/base-plugin.d.ts.map +1 -1
  15. package/lib/core/plugin/expander-column.d.ts +51 -0
  16. package/lib/core/plugin/expander-column.d.ts.map +1 -0
  17. package/lib/core/plugin/types.d.ts +117 -1
  18. package/lib/core/plugin/types.d.ts.map +1 -1
  19. package/lib/core/types.d.ts +4 -2
  20. package/lib/core/types.d.ts.map +1 -1
  21. package/lib/plugins/clipboard/ClipboardPlugin.d.ts +5 -4
  22. package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
  23. package/lib/plugins/clipboard/index.d.ts +1 -1
  24. package/lib/plugins/clipboard/index.d.ts.map +1 -1
  25. package/lib/plugins/clipboard/index.js +282 -188
  26. package/lib/plugins/clipboard/index.js.map +1 -1
  27. package/lib/plugins/clipboard/types.d.ts +72 -2
  28. package/lib/plugins/clipboard/types.d.ts.map +1 -1
  29. package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts +0 -1
  30. package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
  31. package/lib/plugins/column-virtualization/index.js +102 -26
  32. package/lib/plugins/column-virtualization/index.js.map +1 -1
  33. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +0 -1
  34. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  35. package/lib/plugins/context-menu/index.js +154 -78
  36. package/lib/plugins/context-menu/index.js.map +1 -1
  37. package/lib/plugins/editing/EditingPlugin.d.ts +1 -7
  38. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  39. package/lib/plugins/editing/index.js +200 -136
  40. package/lib/plugins/editing/index.js.map +1 -1
  41. package/lib/plugins/export/ExportPlugin.d.ts +0 -1
  42. package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
  43. package/lib/plugins/export/index.js +175 -99
  44. package/lib/plugins/export/index.js.map +1 -1
  45. package/lib/plugins/filtering/FilteringPlugin.d.ts +5 -2
  46. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  47. package/lib/plugins/filtering/index.js +129 -43
  48. package/lib/plugins/filtering/index.js.map +1 -1
  49. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +1 -2
  50. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
  51. package/lib/plugins/grouping-columns/grouping-columns.d.ts +1 -1
  52. package/lib/plugins/grouping-columns/grouping-columns.d.ts.map +1 -1
  53. package/lib/plugins/grouping-columns/index.js +144 -66
  54. package/lib/plugins/grouping-columns/index.js.map +1 -1
  55. package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +14 -2
  56. package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
  57. package/lib/plugins/grouping-rows/index.js +230 -138
  58. package/lib/plugins/grouping-rows/index.js.map +1 -1
  59. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +13 -11
  60. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
  61. package/lib/plugins/master-detail/index.js +265 -196
  62. package/lib/plugins/master-detail/index.js.map +1 -1
  63. package/lib/plugins/master-detail/types.d.ts +0 -10
  64. package/lib/plugins/master-detail/types.d.ts.map +1 -1
  65. package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +1 -2
  66. package/lib/plugins/multi-sort/MultiSortPlugin.d.ts.map +1 -1
  67. package/lib/plugins/multi-sort/index.js +105 -31
  68. package/lib/plugins/multi-sort/index.js.map +1 -1
  69. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +0 -1
  70. package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
  71. package/lib/plugins/pinned-columns/index.js +128 -52
  72. package/lib/plugins/pinned-columns/index.js.map +1 -1
  73. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +1 -2
  74. package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
  75. package/lib/plugins/pinned-rows/index.js +162 -88
  76. package/lib/plugins/pinned-rows/index.js.map +1 -1
  77. package/lib/plugins/pivot/PivotPlugin.d.ts +26 -4
  78. package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -1
  79. package/lib/plugins/pivot/index.js +398 -310
  80. package/lib/plugins/pivot/index.js.map +1 -1
  81. package/lib/plugins/pivot/pivot-rows.d.ts +2 -1
  82. package/lib/plugins/pivot/pivot-rows.d.ts.map +1 -1
  83. package/lib/plugins/reorder/ReorderPlugin.d.ts +13 -10
  84. package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
  85. package/lib/plugins/reorder/index.js +288 -226
  86. package/lib/plugins/reorder/index.js.map +1 -1
  87. package/lib/plugins/selection/SelectionPlugin.d.ts +21 -3
  88. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  89. package/lib/plugins/selection/index.d.ts +2 -2
  90. package/lib/plugins/selection/index.d.ts.map +1 -1
  91. package/lib/plugins/selection/index.js +276 -145
  92. package/lib/plugins/selection/index.js.map +1 -1
  93. package/lib/plugins/selection/types.d.ts +24 -0
  94. package/lib/plugins/selection/types.d.ts.map +1 -1
  95. package/lib/plugins/server-side/ServerSidePlugin.d.ts +0 -1
  96. package/lib/plugins/server-side/ServerSidePlugin.d.ts.map +1 -1
  97. package/lib/plugins/server-side/index.js +83 -7
  98. package/lib/plugins/server-side/index.js.map +1 -1
  99. package/lib/plugins/tree/TreePlugin.d.ts +5 -1
  100. package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
  101. package/lib/plugins/tree/index.js +197 -112
  102. package/lib/plugins/tree/index.js.map +1 -1
  103. package/lib/plugins/tree/types.d.ts +0 -10
  104. package/lib/plugins/tree/types.d.ts.map +1 -1
  105. package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +0 -1
  106. package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
  107. package/lib/plugins/undo-redo/index.js +93 -17
  108. package/lib/plugins/undo-redo/index.js.map +1 -1
  109. package/lib/plugins/visibility/VisibilityPlugin.d.ts +7 -4
  110. package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
  111. package/lib/plugins/visibility/index.js +144 -65
  112. package/lib/plugins/visibility/index.js.map +1 -1
  113. package/package.json +1 -1
  114. package/umd/grid.all.umd.js +17 -19
  115. package/umd/grid.all.umd.js.map +1 -1
  116. package/umd/grid.umd.js +7 -7
  117. package/umd/grid.umd.js.map +1 -1
  118. package/umd/plugins/clipboard.umd.js +5 -7
  119. package/umd/plugins/clipboard.umd.js.map +1 -1
  120. package/umd/plugins/column-virtualization.umd.js +1 -1
  121. package/umd/plugins/column-virtualization.umd.js.map +1 -1
  122. package/umd/plugins/context-menu.umd.js +1 -1
  123. package/umd/plugins/context-menu.umd.js.map +1 -1
  124. package/umd/plugins/editing.umd.js +1 -1
  125. package/umd/plugins/editing.umd.js.map +1 -1
  126. package/umd/plugins/export.umd.js +1 -1
  127. package/umd/plugins/export.umd.js.map +1 -1
  128. package/umd/plugins/filtering.umd.js +1 -1
  129. package/umd/plugins/filtering.umd.js.map +1 -1
  130. package/umd/plugins/grouping-columns.umd.js +1 -1
  131. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  132. package/umd/plugins/grouping-rows.umd.js +1 -1
  133. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  134. package/umd/plugins/master-detail.umd.js +1 -1
  135. package/umd/plugins/master-detail.umd.js.map +1 -1
  136. package/umd/plugins/multi-sort.umd.js +1 -1
  137. package/umd/plugins/multi-sort.umd.js.map +1 -1
  138. package/umd/plugins/pinned-columns.umd.js +1 -1
  139. package/umd/plugins/pinned-columns.umd.js.map +1 -1
  140. package/umd/plugins/pinned-rows.umd.js +1 -1
  141. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  142. package/umd/plugins/pivot.umd.js +1 -1
  143. package/umd/plugins/pivot.umd.js.map +1 -1
  144. package/umd/plugins/reorder.umd.js +1 -1
  145. package/umd/plugins/reorder.umd.js.map +1 -1
  146. package/umd/plugins/selection.umd.js +1 -1
  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
  156. package/lib/core/internal/editing.d.ts +0 -76
  157. package/lib/core/internal/editing.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- const S = {
1
+ const _ = {
2
2
  expand: "▶",
3
3
  collapse: "▼",
4
4
  sortAsc: "▲",
@@ -8,7 +8,7 @@ const S = {
8
8
  dragHandle: "⋮⋮",
9
9
  toolPanel: "☰"
10
10
  };
11
- class R {
11
+ class S {
12
12
  /**
13
13
  * Plugin dependencies - declare other plugins this one requires.
14
14
  *
@@ -25,8 +25,11 @@ class R {
25
25
  * ```
26
26
  */
27
27
  static dependencies;
28
- /** Plugin version - override in subclass if needed */
29
- version = "1.0.0";
28
+ /**
29
+ * Plugin version - defaults to grid version for built-in plugins.
30
+ * Third-party plugins can override with their own semver.
31
+ */
32
+ version = typeof __GRID_VERSION__ < "u" ? __GRID_VERSION__ : "dev";
30
33
  /** CSS styles to inject into the grid's shadow DOM */
31
34
  styles;
32
35
  /** Custom cell renderers keyed by type name */
@@ -113,12 +116,28 @@ class R {
113
116
  emit(e, t) {
114
117
  this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
115
118
  }
119
+ /**
120
+ * Emit a cancelable custom event from the grid.
121
+ * @returns `true` if the event was cancelled (preventDefault called), `false` otherwise
122
+ */
123
+ emitCancelable(e, t) {
124
+ const n = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
125
+ return this.grid?.dispatchEvent?.(n), n.defaultPrevented;
126
+ }
116
127
  /**
117
128
  * Request a re-render of the grid.
118
129
  */
119
130
  requestRender() {
120
131
  this.grid?.requestRender?.();
121
132
  }
133
+ /**
134
+ * Request a re-render and restore focus styling afterward.
135
+ * Use this when a plugin action (like expand/collapse) triggers a render
136
+ * but needs to maintain keyboard navigation focus.
137
+ */
138
+ requestRenderWithFocus() {
139
+ this.grid?.requestRenderWithFocus?.();
140
+ }
122
141
  /**
123
142
  * Request a lightweight style update without rebuilding DOM.
124
143
  * Use this instead of requestRender() when only CSS classes need updating.
@@ -152,6 +171,19 @@ class R {
152
171
  get visibleColumns() {
153
172
  return this.grid?._visibleColumns ?? [];
154
173
  }
174
+ /**
175
+ * Get the grid as an HTMLElement for direct DOM operations.
176
+ * Use sparingly - prefer the typed GridElementRef API when possible.
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * const width = this.gridElement.clientWidth;
181
+ * this.gridElement.classList.add('my-plugin-active');
182
+ * ```
183
+ */
184
+ get gridElement() {
185
+ return this.grid;
186
+ }
155
187
  /**
156
188
  * Get the shadow root of the grid.
157
189
  */
@@ -184,8 +216,53 @@ class R {
184
216
  */
185
217
  get gridIcons() {
186
218
  const e = this.grid?.gridConfig?.icons ?? {};
187
- return { ...S, ...e };
219
+ return { ..._, ...e };
188
220
  }
221
+ // #region Animation Helpers
222
+ /**
223
+ * Check if animations are enabled at the grid level.
224
+ * Respects gridConfig.animation.mode and the CSS variable set by the grid.
225
+ *
226
+ * Plugins should use this to skip animations when:
227
+ * - Animation mode is 'off' or `false`
228
+ * - User prefers reduced motion and mode is 'reduced-motion' (default)
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * private get animationStyle(): 'slide' | 'fade' | false {
233
+ * if (!this.isAnimationEnabled) return false;
234
+ * return this.config.animation ?? 'slide';
235
+ * }
236
+ * ```
237
+ */
238
+ get isAnimationEnabled() {
239
+ const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
240
+ if (e === !1 || e === "off") return !1;
241
+ if (e === !0 || e === "on") return !0;
242
+ const t = this.shadowRoot?.host;
243
+ return t ? getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
244
+ }
245
+ /**
246
+ * Get the animation duration in milliseconds from CSS variable.
247
+ * Falls back to 200ms if not set.
248
+ *
249
+ * Plugins can use this for their animation timing to stay consistent
250
+ * with the grid-level animation.duration setting.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * element.animate(keyframes, { duration: this.animationDuration });
255
+ * ```
256
+ */
257
+ get animationDuration() {
258
+ const e = this.shadowRoot?.host;
259
+ if (e) {
260
+ const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
261
+ if (!isNaN(n)) return n;
262
+ }
263
+ return 200;
264
+ }
265
+ // #endregion
189
266
  /**
190
267
  * Resolve an icon value to string or HTMLElement.
191
268
  * Checks plugin config first, then grid-level icons, then defaults.
@@ -215,54 +292,54 @@ class R {
215
292
  }
216
293
  // #endregion
217
294
  }
218
- function x(i, e, t) {
219
- return i.id !== void 0 ? String(i.id) : t ? `${t}-${e}` : String(e);
295
+ function b(s, e, t) {
296
+ return s.id !== void 0 ? String(s.id) : t ? `${t}-${e}` : String(e);
220
297
  }
221
- function m(i, e) {
222
- const t = new Set(i);
298
+ function y(s, e) {
299
+ const t = new Set(s);
223
300
  return t.has(e) ? t.delete(e) : t.add(e), t;
224
301
  }
225
- function p(i, e, t = null, n = 0) {
226
- const s = e.childrenField ?? "children", o = /* @__PURE__ */ new Set();
227
- for (let r = 0; r < i.length; r++) {
228
- const d = i[r], a = x(d, r, t), l = d[s];
229
- if (Array.isArray(l) && l.length > 0) {
302
+ function w(s, e, t = null, n = 0) {
303
+ const i = e.childrenField ?? "children", o = /* @__PURE__ */ new Set();
304
+ for (let r = 0; r < s.length; r++) {
305
+ const l = s[r], a = b(l, r, t), d = l[i];
306
+ if (Array.isArray(d) && d.length > 0) {
230
307
  o.add(a);
231
- const h = p(l, e, a, n + 1);
232
- for (const f of h) o.add(f);
308
+ const h = w(d, e, a, n + 1);
309
+ for (const u of h) o.add(u);
233
310
  }
234
311
  }
235
312
  return o;
236
313
  }
237
- function C() {
314
+ function v() {
238
315
  return /* @__PURE__ */ new Set();
239
316
  }
240
- function A(i, e, t, n = null, s = 0) {
317
+ function x(s, e, t, n = null, i = 0) {
241
318
  const o = t.childrenField ?? "children";
242
- for (let r = 0; r < i.length; r++) {
243
- const d = i[r], a = x(d, r, n);
319
+ for (let r = 0; r < s.length; r++) {
320
+ const l = s[r], a = b(l, r, n);
244
321
  if (a === e)
245
322
  return [a];
246
- const l = d[o];
247
- if (Array.isArray(l) && l.length > 0) {
248
- const h = A(l, e, t, a, s + 1);
323
+ const d = l[o];
324
+ if (Array.isArray(d) && d.length > 0) {
325
+ const h = x(d, e, t, a, i + 1);
249
326
  if (h)
250
327
  return [a, ...h];
251
328
  }
252
329
  }
253
330
  return null;
254
331
  }
255
- function v(i, e, t, n) {
256
- const s = A(i, e, t);
257
- if (!s) return n;
332
+ function C(s, e, t, n) {
333
+ const i = x(s, e, t);
334
+ if (!i) return n;
258
335
  const o = new Set(n);
259
- for (let r = 0; r < s.length - 1; r++)
260
- o.add(s[r]);
336
+ for (let r = 0; r < i.length - 1; r++)
337
+ o.add(i[r]);
261
338
  return o;
262
339
  }
263
- function b(i, e = "children") {
264
- if (!Array.isArray(i) || i.length === 0) return !1;
265
- for (const t of i) {
340
+ function m(s, e = "children") {
341
+ if (!Array.isArray(s) || s.length === 0) return !1;
342
+ for (const t of s) {
266
343
  if (!t) continue;
267
344
  const n = t[e];
268
345
  if (Array.isArray(n) && n.length > 0)
@@ -270,47 +347,46 @@ function b(i, e = "children") {
270
347
  }
271
348
  return !1;
272
349
  }
273
- function _(i) {
274
- if (!Array.isArray(i) || i.length === 0) return null;
350
+ function E(s) {
351
+ if (!Array.isArray(s) || s.length === 0) return null;
275
352
  const e = ["children", "items", "nodes", "subRows", "nested"];
276
- for (const t of i)
353
+ for (const t of s)
277
354
  if (!(!t || typeof t != "object"))
278
355
  for (const n of e) {
279
- const s = t[n];
280
- if (Array.isArray(s) && s.length > 0)
356
+ const i = t[n];
357
+ if (Array.isArray(i) && i.length > 0)
281
358
  return n;
282
359
  }
283
360
  return null;
284
361
  }
285
- function E(i, e = "children", t = 0) {
286
- if (!Array.isArray(i) || i.length === 0) return t;
362
+ function k(s, e = "children", t = 0) {
363
+ if (!Array.isArray(s) || s.length === 0) return t;
287
364
  let n = t;
288
- for (const s of i) {
289
- if (!s) continue;
290
- const o = s[e];
365
+ for (const i of s) {
366
+ if (!i) continue;
367
+ const o = i[e];
291
368
  if (Array.isArray(o) && o.length > 0) {
292
- const r = E(o, e, t + 1);
369
+ const r = k(o, e, t + 1);
293
370
  r > n && (n = r);
294
371
  }
295
372
  }
296
373
  return n;
297
374
  }
298
- function k(i, e = "children") {
299
- if (!Array.isArray(i)) return 0;
375
+ function T(s, e = "children") {
376
+ if (!Array.isArray(s)) return 0;
300
377
  let t = 0;
301
- for (const n of i) {
378
+ for (const n of s) {
302
379
  if (!n) continue;
303
380
  t++;
304
- const s = n[e];
305
- Array.isArray(s) && (t += k(s, e));
381
+ const i = n[e];
382
+ Array.isArray(i) && (t += T(i, e));
306
383
  }
307
384
  return t;
308
385
  }
309
- const T = ".tree-cell{display:flex;align-items:center;padding-left:calc(var(--tree-depth, 0) * var(--tbw-tree-indent, 20px))}.tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center;margin-right:4px}.tree-toggle:hover{color:var(--tbw-tree-accent, var(--tbw-color-accent))}.tree-spacer{width:14px;display:inline-block}.data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}";
310
- class F extends R {
386
+ const I = ".cell[data-field=__tbw_expander]{border-right:none!important;padding:0;display:flex;align-items:center;justify-content:flex-start}.header-row .cell[data-field=__tbw_expander]{visibility:hidden;border:none!important;padding:0;overflow:hidden}.header-row .cell[data-field=__tbw_expander]+.cell{margin-left:-32px;padding-left:calc(var(--tbw-cell-padding, 8px) + 32px)}.tree-expander{display:flex;align-items:center;justify-content:flex-start;width:100%;height:100%;box-sizing:border-box}.tree-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center}.tree-toggle:hover{color:var(--tbw-tree-accent, var(--tbw-color-accent))}.tree-spacer{width:14px;display:inline-block}.data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}";
387
+ class F extends S {
311
388
  name = "tree";
312
- version = "1.0.0";
313
- styles = T;
389
+ styles = I;
314
390
  get defaultConfig() {
315
391
  return {
316
392
  childrenField: "children",
@@ -334,31 +410,28 @@ class F extends R {
334
410
  }
335
411
  // #endregion
336
412
  // #region Animation
413
+ /**
414
+ * Get expand/collapse animation style from plugin config.
415
+ * Uses base class isAnimationEnabled to respect grid-level settings.
416
+ */
337
417
  get animationStyle() {
338
- const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
339
- if (t === !1 || t === "off") return !1;
340
- if (t !== !0 && t !== "on") {
341
- const n = this.shadowRoot?.host;
342
- if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
343
- return !1;
344
- }
345
- return this.config.animation ?? "slide";
418
+ return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
346
419
  }
347
420
  // #endregion
348
421
  // #region Auto-Detection
349
422
  detect(e) {
350
423
  if (!this.config.autoDetect) return !1;
351
- const t = e, n = this.config.childrenField ?? _(t) ?? "children";
352
- return b(t, n);
424
+ const t = e, n = this.config.childrenField ?? E(t) ?? "children";
425
+ return m(t, n);
353
426
  }
354
427
  // #endregion
355
428
  // #region Data Processing
356
429
  processRows(e) {
357
430
  const t = this.config.childrenField ?? "children", n = e;
358
- if (!b(n, t))
431
+ if (!m(n, t))
359
432
  return this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), [...e];
360
- let s = this.withStableKeys(n);
361
- this.sortState && (s = this.sortTree(s, this.sortState.field, this.sortState.direction)), this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = p(s, this.config), this.initialExpansionDone = !0), this.flattenedRows = this.flattenTree(s, this.expandedKeys), this.rowKeyMap.clear(), this.keysToAnimate.clear();
433
+ let i = this.withStableKeys(n);
434
+ this.sortState && (i = this.sortTree(i, this.sortState.field, this.sortState.direction)), this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = w(i, this.config), this.initialExpansionDone = !0), this.flattenedRows = this.flattenTree(i, this.expandedKeys), this.rowKeyMap.clear(), this.keysToAnimate.clear();
362
435
  const o = /* @__PURE__ */ new Set();
363
436
  for (const r of this.flattenedRows)
364
437
  this.rowKeyMap.set(r.key, r), o.add(r.key), !this.previousVisibleKeys.has(r.key) && r.depth > 0 && this.keysToAnimate.add(r.key);
@@ -373,80 +446,92 @@ class F extends R {
373
446
  /** Assign stable keys to rows (preserves key across sort operations) */
374
447
  withStableKeys(e, t = null) {
375
448
  const n = this.config.childrenField ?? "children";
376
- return e.map((s, o) => {
377
- const r = s.__stableKey, d = s.id !== void 0 ? String(s.id) : r ?? (t ? `${t}-${o}` : String(o)), a = s[n], l = Array.isArray(a) && a.length > 0;
449
+ return e.map((i, o) => {
450
+ const r = i.__stableKey, l = i.id !== void 0 ? String(i.id) : r ?? (t ? `${t}-${o}` : String(o)), a = i[n], d = Array.isArray(a) && a.length > 0;
378
451
  return {
379
- ...s,
380
- __stableKey: d,
381
- ...l ? { [n]: this.withStableKeys(a, d) } : {}
452
+ ...i,
453
+ __stableKey: l,
454
+ ...d ? { [n]: this.withStableKeys(a, l) } : {}
382
455
  };
383
456
  });
384
457
  }
385
458
  /** Flatten tree using stable keys */
386
459
  flattenTree(e, t, n = 0) {
387
- const s = this.config.childrenField ?? "children", o = [];
460
+ const i = this.config.childrenField ?? "children", o = [];
388
461
  for (const r of e) {
389
- const a = r.__stableKey ?? String(r.id ?? "?"), l = r[s], h = Array.isArray(l) && l.length > 0, f = t.has(a);
462
+ const a = r.__stableKey ?? String(r.id ?? "?"), d = r[i], h = Array.isArray(d) && d.length > 0, u = t.has(a);
390
463
  o.push({
391
464
  key: a,
392
465
  data: r,
393
466
  depth: n,
394
467
  hasChildren: h,
395
- isExpanded: f,
468
+ isExpanded: u,
396
469
  parentKey: n > 0 && a.substring(0, a.lastIndexOf("-")) || null
397
- }), h && f && o.push(...this.flattenTree(l, t, n + 1));
470
+ }), h && u && o.push(...this.flattenTree(d, t, n + 1));
398
471
  }
399
472
  return o;
400
473
  }
401
474
  /** Sort tree recursively, keeping children with parents */
402
475
  sortTree(e, t, n) {
403
- const s = this.config.childrenField ?? "children";
404
- return [...e].sort((r, d) => {
405
- const a = r[t], l = d[t];
406
- return a == null && l == null ? 0 : a == null ? -1 : l == null ? 1 : a > l ? n : a < l ? -n : 0;
476
+ const i = this.config.childrenField ?? "children";
477
+ return [...e].sort((r, l) => {
478
+ const a = r[t], d = l[t];
479
+ return a == null && d == null ? 0 : a == null ? -1 : d == null ? 1 : a > d ? n : a < d ? -n : 0;
407
480
  }).map((r) => {
408
- const d = r[s];
409
- return Array.isArray(d) && d.length > 0 ? { ...r, [s]: this.sortTree(d, t, n) } : r;
481
+ const l = r[i];
482
+ return Array.isArray(l) && l.length > 0 ? { ...r, [i]: this.sortTree(l, t, n) } : r;
410
483
  });
411
484
  }
412
485
  processColumns(e) {
413
486
  if (this.flattenedRows.length === 0) return [...e];
414
487
  const t = [...e];
415
488
  if (t.length === 0) return t;
416
- const n = { ...t[0] }, s = n.viewRenderer;
417
- if (s?.__treeWrapped) return t;
418
- const o = () => this.config, r = this.setIcon.bind(this), d = this.resolveIcon.bind(this), a = (l) => {
419
- const { value: h, row: f } = l, { indentWidth: K = 20, showExpandIcons: w = !0 } = o(), g = f, u = document.createElement("span");
420
- if (u.className = "tree-cell", u.style.setProperty("--tree-depth", String(g.__treeDepth ?? 0)), u.style.setProperty("--tbw-tree-indent", `${K}px`), g.__treeHasChildren && w) {
421
- const c = document.createElement("span");
422
- c.className = `tree-toggle${g.__treeExpanded ? " expanded" : ""}`, r(c, d(g.__treeExpanded ? "collapse" : "expand")), c.setAttribute("data-tree-key", String(g.__treeKey ?? "")), u.appendChild(c);
423
- } else if (w) {
424
- const c = document.createElement("span");
425
- c.className = "tree-spacer", u.appendChild(c);
426
- }
427
- const y = document.createElement("span");
428
- if (s) {
429
- const c = s(l);
430
- c instanceof Node ? y.appendChild(c) : y.textContent = String(c ?? h ?? "");
489
+ const n = t[0], i = n.viewRenderer, o = () => this.config, r = this.setIcon.bind(this), l = this.resolveIcon.bind(this), a = (d) => {
490
+ const { row: h, value: u } = d, { indentWidth: R = 20, showExpandIcons: A = !0 } = o(), p = h, K = p.__treeDepth ?? 0, f = document.createElement("span");
491
+ if (f.className = "tree-cell-wrapper", f.style.paddingLeft = `${Number(K) * R}px`, A)
492
+ if (p.__treeHasChildren) {
493
+ const c = document.createElement("span");
494
+ c.className = `tree-toggle${p.__treeExpanded ? " expanded" : ""}`, r(c, l(p.__treeExpanded ? "collapse" : "expand")), c.setAttribute("data-tree-key", String(p.__treeKey ?? "")), f.appendChild(c);
495
+ } else {
496
+ const c = document.createElement("span");
497
+ c.className = "tree-spacer", f.appendChild(c);
498
+ }
499
+ const g = document.createElement("span");
500
+ if (g.className = "tree-content", i) {
501
+ const c = i(d);
502
+ c instanceof Node ? g.appendChild(c) : typeof c == "string" && (g.innerHTML = c);
431
503
  } else
432
- y.textContent = String(h ?? "");
433
- return u.appendChild(y), u;
504
+ g.textContent = u != null ? String(u) : "";
505
+ return f.appendChild(g), f;
434
506
  };
435
- return a.__treeWrapped = !0, n.viewRenderer = a, t[0] = n, t;
507
+ return t[0] = { ...n, viewRenderer: a }, t;
436
508
  }
437
509
  // #endregion
438
510
  // #region Event Handlers
439
511
  onCellClick(e) {
440
512
  const t = e.originalEvent?.target;
441
513
  if (!t?.classList.contains("tree-toggle")) return !1;
442
- const n = t.getAttribute("data-tree-key"), s = n ? this.rowKeyMap.get(n) : null;
443
- return s ? (this.expandedKeys = m(this.expandedKeys, n), this.emit("tree-expand", {
514
+ const n = t.getAttribute("data-tree-key");
515
+ if (!n) return !1;
516
+ const i = this.rowKeyMap.get(n);
517
+ return i ? (this.expandedKeys = y(this.expandedKeys, n), this.emit("tree-expand", {
444
518
  key: n,
445
- row: s.data,
519
+ row: i.data,
446
520
  expanded: this.expandedKeys.has(n),
447
- depth: s.depth
521
+ depth: i.depth
448
522
  }), this.requestRender(), !0) : !1;
449
523
  }
524
+ onKeyDown(e) {
525
+ if (e.key !== " ") return;
526
+ const t = this.grid._focusRow, n = this.flattenedRows[t];
527
+ if (n?.hasChildren)
528
+ return e.preventDefault(), this.expandedKeys = y(this.expandedKeys, n.key), this.emit("tree-expand", {
529
+ key: n.key,
530
+ row: n.data,
531
+ expanded: this.expandedKeys.has(n.key),
532
+ depth: n.depth
533
+ }), this.requestRenderWithFocus(), !0;
534
+ }
450
535
  onHeaderClick(e) {
451
536
  if (this.flattenedRows.length === 0 || !e.column.sortable) return !1;
452
537
  const { field: t } = e.column;
@@ -460,9 +545,9 @@ class F extends R {
460
545
  const t = this.shadowRoot?.querySelector(".rows");
461
546
  if (!t) return;
462
547
  const n = e === "fade" ? "tbw-tree-fade-in" : "tbw-tree-slide-in";
463
- for (const s of t.querySelectorAll(".data-grid-row")) {
464
- const o = s.querySelector(".cell[data-row]"), r = o ? parseInt(o.getAttribute("data-row") ?? "-1", 10) : -1, d = this.flattenedRows[r]?.key;
465
- d && this.keysToAnimate.has(d) && (s.classList.add(n), s.addEventListener("animationend", () => s.classList.remove(n), { once: !0 }));
548
+ for (const i of t.querySelectorAll(".data-grid-row")) {
549
+ const o = i.querySelector(".cell[data-row]"), r = o ? parseInt(o.getAttribute("data-row") ?? "-1", 10) : -1, l = this.flattenedRows[r]?.key;
550
+ l && this.keysToAnimate.has(l) && (i.classList.add(n), i.addEventListener("animationend", () => i.classList.remove(n), { once: !0 }));
466
551
  }
467
552
  this.keysToAnimate.clear();
468
553
  }
@@ -475,13 +560,13 @@ class F extends R {
475
560
  this.expandedKeys.delete(e), this.requestRender();
476
561
  }
477
562
  toggle(e) {
478
- this.expandedKeys = m(this.expandedKeys, e), this.requestRender();
563
+ this.expandedKeys = y(this.expandedKeys, e), this.requestRender();
479
564
  }
480
565
  expandAll() {
481
- this.expandedKeys = p(this.rows, this.config), this.requestRender();
566
+ this.expandedKeys = w(this.rows, this.config), this.requestRender();
482
567
  }
483
568
  collapseAll() {
484
- this.expandedKeys = C(), this.requestRender();
569
+ this.expandedKeys = v(), this.requestRender();
485
570
  }
486
571
  isExpanded(e) {
487
572
  return this.expandedKeys.has(e);
@@ -496,15 +581,15 @@ class F extends R {
496
581
  return this.rowKeyMap.get(e)?.data;
497
582
  }
498
583
  expandToKey(e) {
499
- this.expandedKeys = v(this.rows, e, this.config, this.expandedKeys), this.requestRender();
584
+ this.expandedKeys = C(this.rows, e, this.config, this.expandedKeys), this.requestRender();
500
585
  }
501
586
  // #endregion
502
587
  }
503
588
  export {
504
589
  F as TreePlugin,
505
- k as countNodes,
506
- b as detectTreeStructure,
507
- E as getMaxDepth,
508
- _ as inferChildrenField
590
+ T as countNodes,
591
+ m as detectTreeStructure,
592
+ k as getMaxDepth,
593
+ E as inferChildrenField
509
594
  };
510
595
  //# sourceMappingURL=index.js.map