@toolbox-web/grid 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/all.d.ts +486 -80
  2. package/all.js +1364 -1029
  3. package/all.js.map +1 -1
  4. package/index-DG2CZ_Zo.js +3229 -0
  5. package/index-DG2CZ_Zo.js.map +1 -0
  6. package/index.d.ts +222 -11
  7. package/index.js +25 -3143
  8. package/index.js.map +1 -1
  9. package/lib/plugins/clipboard/index.js +1 -1
  10. package/lib/plugins/clipboard/index.js.map +1 -1
  11. package/lib/plugins/column-virtualization/index.js +1 -1
  12. package/lib/plugins/column-virtualization/index.js.map +1 -1
  13. package/lib/plugins/context-menu/index.js +1 -1
  14. package/lib/plugins/context-menu/index.js.map +1 -1
  15. package/lib/plugins/export/index.js +1 -1
  16. package/lib/plugins/export/index.js.map +1 -1
  17. package/lib/plugins/filtering/index.js +184 -149
  18. package/lib/plugins/filtering/index.js.map +1 -1
  19. package/lib/plugins/grouping-columns/index.js +46 -45
  20. package/lib/plugins/grouping-columns/index.js.map +1 -1
  21. package/lib/plugins/grouping-rows/index.js +117 -83
  22. package/lib/plugins/grouping-rows/index.js.map +1 -1
  23. package/lib/plugins/master-detail/index.js +140 -82
  24. package/lib/plugins/master-detail/index.js.map +1 -1
  25. package/lib/plugins/multi-sort/index.js +18 -18
  26. package/lib/plugins/multi-sort/index.js.map +1 -1
  27. package/lib/plugins/pinned-columns/index.js +1 -1
  28. package/lib/plugins/pinned-columns/index.js.map +1 -1
  29. package/lib/plugins/pinned-rows/index.js +55 -47
  30. package/lib/plugins/pinned-rows/index.js.map +1 -1
  31. package/lib/plugins/pivot/index.js +385 -351
  32. package/lib/plugins/pivot/index.js.map +1 -1
  33. package/lib/plugins/reorder/index.js +278 -85
  34. package/lib/plugins/reorder/index.js.map +1 -1
  35. package/lib/plugins/selection/index.js +28 -27
  36. package/lib/plugins/selection/index.js.map +1 -1
  37. package/lib/plugins/server-side/index.js +2 -2
  38. package/lib/plugins/server-side/index.js.map +1 -1
  39. package/lib/plugins/tree/index.js +181 -170
  40. package/lib/plugins/tree/index.js.map +1 -1
  41. package/lib/plugins/undo-redo/index.js +1 -1
  42. package/lib/plugins/undo-redo/index.js.map +1 -1
  43. package/lib/plugins/visibility/index.js +1 -1
  44. package/lib/plugins/visibility/index.js.map +1 -1
  45. package/package.json +1 -1
  46. package/umd/grid.all.umd.js +22 -22
  47. package/umd/grid.all.umd.js.map +1 -1
  48. package/umd/grid.umd.js +12 -12
  49. package/umd/grid.umd.js.map +1 -1
  50. package/umd/plugins/filtering.umd.js +1 -1
  51. package/umd/plugins/filtering.umd.js.map +1 -1
  52. package/umd/plugins/grouping-columns.umd.js +1 -1
  53. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  54. package/umd/plugins/grouping-rows.umd.js +1 -1
  55. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  56. package/umd/plugins/master-detail.umd.js +1 -1
  57. package/umd/plugins/master-detail.umd.js.map +1 -1
  58. package/umd/plugins/multi-sort.umd.js +1 -1
  59. package/umd/plugins/multi-sort.umd.js.map +1 -1
  60. package/umd/plugins/pinned-rows.umd.js +1 -1
  61. package/umd/plugins/pinned-rows.umd.js.map +1 -1
  62. package/umd/plugins/pivot.umd.js +1 -1
  63. package/umd/plugins/pivot.umd.js.map +1 -1
  64. package/umd/plugins/reorder.umd.js +1 -1
  65. package/umd/plugins/reorder.umd.js.map +1 -1
  66. package/umd/plugins/selection.umd.js +1 -1
  67. package/umd/plugins/selection.umd.js.map +1 -1
  68. package/umd/plugins/server-side.umd.js +1 -1
  69. package/umd/plugins/server-side.umd.js.map +1 -1
  70. package/umd/plugins/tree.umd.js +1 -1
  71. package/umd/plugins/tree.umd.js.map +1 -1
package/all.js CHANGED
@@ -1,22 +1,22 @@
1
- import { BaseGridPlugin as x, DEFAULT_GRID_ICONS as He, runAggregator as se, PLUGIN_QUERIES as Pe, getAggregator as Ge, getValueAggregator as Oe } from "./index.js";
2
- import { DGEvents as Nn, DataGridElement as Pn, FitModeEnum as qn, GridCSSVars as Dn, GridClasses as Kn, GridDataAttrs as Hn, DataGridElement as Gn, GridSelectors as On, PluginEvents as Bn, PluginManager as Vn, aggregatorRegistry as zn, listAggregators as Wn, registerAggregator as $n, runValueAggregator as jn, unregisterAggregator as Un } from "./index.js";
3
- function Be(r, e, t, n) {
1
+ import { B as v, D as Ve, r as se, P as N, g as le, a as Oe, e as Ge } from "./index-DG2CZ_Zo.js";
2
+ import { k as Kn, i as Nn, b as qn, F as Dn, o as Hn, G as Vn, p as On, b as Gn, q as Bn, j as zn, c as Wn, d as $n, m as jn, n as Un, l as Yn, f as Zn, h as Xn, u as Jn } from "./index-DG2CZ_Zo.js";
3
+ function Be(s, e, t, n) {
4
4
  if (n.processCell)
5
- return n.processCell(r, e, t);
6
- if (r == null) return "";
7
- if (r instanceof Date) return r.toISOString();
8
- if (typeof r == "object") return JSON.stringify(r);
9
- const o = String(r), i = n.delimiter ?? " ", s = n.newline ?? `
5
+ return n.processCell(s, e, t);
6
+ if (s == null) return "";
7
+ if (s instanceof Date) return s.toISOString();
8
+ if (typeof s == "object") return JSON.stringify(s);
9
+ const o = String(s), i = n.delimiter ?? " ", r = n.newline ?? `
10
10
  `;
11
- return n.quoteStrings || o.includes(i) || o.includes(s) || o.includes('"') ? `"${o.replace(/"/g, '""')}"` : o;
11
+ return n.quoteStrings || o.includes(i) || o.includes(r) || o.includes('"') ? `"${o.replace(/"/g, '""')}"` : o;
12
12
  }
13
- function H(r) {
14
- const { rows: e, columns: t, selectedIndices: n, config: o } = r, i = o.delimiter ?? " ", s = o.newline ?? `
13
+ function V(s) {
14
+ const { rows: e, columns: t, selectedIndices: n, config: o } = s, i = o.delimiter ?? " ", r = o.newline ?? `
15
15
  `, l = t.filter((u) => !u.hidden && !u.field.startsWith("__")), a = [];
16
16
  if (o.includeHeaders) {
17
17
  const u = l.map((h) => {
18
18
  const g = h.header || h.field;
19
- return g.includes(i) || g.includes(s) || g.includes('"') ? `"${g.replace(/"/g, '""')}"` : g;
19
+ return g.includes(i) || g.includes(r) || g.includes('"') ? `"${g.replace(/"/g, '""')}"` : g;
20
20
  });
21
21
  a.push(u.join(i));
22
22
  }
@@ -25,42 +25,42 @@ function H(r) {
25
25
  const h = e[u];
26
26
  if (!h) continue;
27
27
  const g = l.map(
28
- (p) => Be(h[p.field], p.field, h, o)
28
+ (f) => Be(h[f.field], f.field, h, o)
29
29
  );
30
30
  a.push(g.join(i));
31
31
  }
32
- return a.join(s);
32
+ return a.join(r);
33
33
  }
34
- async function G(r) {
34
+ async function O(s) {
35
35
  try {
36
- return await navigator.clipboard.writeText(r), !0;
36
+ return await navigator.clipboard.writeText(s), !0;
37
37
  } catch {
38
38
  const e = document.createElement("textarea");
39
- e.value = r, e.style.position = "fixed", e.style.opacity = "0", e.style.pointerEvents = "none", document.body.appendChild(e), e.select();
39
+ e.value = s, e.style.position = "fixed", e.style.opacity = "0", e.style.pointerEvents = "none", document.body.appendChild(e), e.select();
40
40
  const t = document.execCommand("copy");
41
41
  return document.body.removeChild(e), t;
42
42
  }
43
43
  }
44
- function le(r, e) {
44
+ function ae(s, e) {
45
45
  const t = e.delimiter ?? " ", n = e.newline ?? `
46
- `, o = r.replace(/\r\n/g, `
46
+ `, o = s.replace(/\r\n/g, `
47
47
  `).replace(/\r/g, `
48
48
  `), i = [];
49
- let s = [], l = "", a = !1;
49
+ let r = [], l = "", a = !1;
50
50
  for (let d = 0; d < o.length; d++) {
51
51
  const c = o[d];
52
- c === '"' && !a ? a = !0 : c === '"' && a ? o[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (s.push(l), l = "") : c === n && !a ? (s.push(l), l = "", (s.length > 1 || s.some((u) => u.trim() !== "")) && i.push(s), s = []) : l += c;
52
+ c === '"' && !a ? a = !0 : c === '"' && a ? o[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (r.push(l), l = "") : c === n && !a ? (r.push(l), l = "", (r.length > 1 || r.some((u) => u.trim() !== "")) && i.push(r), r = []) : l += c;
53
53
  }
54
- return s.push(l), (s.length > 1 || s.some((d) => d.trim() !== "")) && i.push(s), i;
54
+ return r.push(l), (r.length > 1 || r.some((d) => d.trim() !== "")) && i.push(r), i;
55
55
  }
56
- async function ae() {
56
+ async function de() {
57
57
  try {
58
58
  return await navigator.clipboard.readText();
59
59
  } catch {
60
60
  return "";
61
61
  }
62
62
  }
63
- class wn extends x {
63
+ class bn extends v {
64
64
  name = "clipboard";
65
65
  version = "1.0.0";
66
66
  get defaultConfig() {
@@ -92,16 +92,16 @@ class wn extends x {
92
92
  * Handle copy operation
93
93
  */
94
94
  #t(e) {
95
- const t = this.#n(), n = t?.getSelectedRows() ?? [], o = n.length > 0, i = t?.getRanges() ?? [], s = i.length > 0, l = t?.getSelectedCell() != null;
95
+ const t = this.#n(), n = t?.getSelectedRows() ?? [], o = n.length > 0, i = t?.getRanges() ?? [], r = i.length > 0, l = t?.getSelectedCell() != null;
96
96
  let a, d, c;
97
97
  if (o && t)
98
- a = H({
98
+ a = V({
99
99
  rows: this.rows,
100
100
  columns: [...this.columns],
101
101
  selectedIndices: n,
102
102
  config: this.config
103
103
  }), d = n.length, c = this.columns.filter((u) => !u.hidden && !u.field.startsWith("__")).length;
104
- else if (s && t) {
104
+ else if (r && t) {
105
105
  const u = i[i.length - 1], h = this.#i({
106
106
  startRow: u.from.row,
107
107
  startCol: u.from.col,
@@ -118,7 +118,7 @@ class wn extends x {
118
118
  if (!u) return;
119
119
  a = u.text, d = 1, c = 1;
120
120
  }
121
- G(a).then(() => {
121
+ O(a).then(() => {
122
122
  this.lastCopied = { text: a, timestamp: Date.now() }, this.emit("copy", { text: a, rowCount: d, columnCount: c });
123
123
  });
124
124
  }
@@ -126,9 +126,9 @@ class wn extends x {
126
126
  * Handle paste operation
127
127
  */
128
128
  #e() {
129
- ae().then((e) => {
129
+ de().then((e) => {
130
130
  if (!e) return;
131
- const t = le(e, this.config);
131
+ const t = ae(e, this.config);
132
132
  this.emit("paste", { rows: t, text: e });
133
133
  });
134
134
  }
@@ -154,11 +154,11 @@ class wn extends x {
154
154
  if (!n) return null;
155
155
  const o = this.columns[t];
156
156
  if (!o) return null;
157
- const i = n[o.field], s = o.header || o.field;
157
+ const i = n[o.field], r = o.header || o.field;
158
158
  let l;
159
159
  if (this.config.includeHeaders) {
160
160
  const a = i == null ? "" : String(i);
161
- l = `${s}: ${a}`;
161
+ l = `${r}: ${a}`;
162
162
  } else
163
163
  l = i == null ? "" : String(i);
164
164
  return { text: l };
@@ -167,24 +167,24 @@ class wn extends x {
167
167
  * Build text for a rectangular range of cells.
168
168
  */
169
169
  #i(e) {
170
- const { startRow: t, startCol: n, endRow: o, endCol: i } = e, s = Math.min(t, o), l = Math.max(t, o), a = Math.min(n, i), d = Math.max(n, i), c = this.config.delimiter ?? " ", u = this.config.newline ?? `
170
+ const { startRow: t, startCol: n, endRow: o, endCol: i } = e, r = Math.min(t, o), l = Math.max(t, o), a = Math.min(n, i), d = Math.max(n, i), c = this.config.delimiter ?? " ", u = this.config.newline ?? `
171
171
  `, h = [], g = this.columns.slice(a, d + 1);
172
172
  if (this.config.includeHeaders) {
173
- const p = g.map((f) => f.header || f.field);
174
- h.push(p.join(c));
173
+ const f = g.map((m) => m.header || m.field);
174
+ h.push(f.join(c));
175
175
  }
176
- for (let p = s; p <= l; p++) {
177
- const f = this.rows[p];
178
- if (!f) continue;
179
- const m = g.map((w) => {
180
- const k = f[w.field];
181
- return k == null ? "" : k instanceof Date ? k.toISOString() : String(k);
176
+ for (let f = r; f <= l; f++) {
177
+ const m = this.rows[f];
178
+ if (!m) continue;
179
+ const p = g.map((R) => {
180
+ const E = m[R.field];
181
+ return E == null ? "" : E instanceof Date ? E.toISOString() : String(E);
182
182
  });
183
- h.push(m.join(c));
183
+ h.push(p.join(c));
184
184
  }
185
185
  return {
186
186
  text: h.join(u),
187
- rowCount: l - s + 1,
187
+ rowCount: l - r + 1,
188
188
  columnCount: d - a + 1
189
189
  };
190
190
  }
@@ -201,9 +201,9 @@ class wn extends x {
201
201
  if (!o) return null;
202
202
  const i = parseInt(o, 10);
203
203
  if (isNaN(i)) return null;
204
- const s = this.rows[i];
205
- if (!s) return null;
206
- const l = s[n], d = this.columns.find((u) => u.field === n)?.header || n;
204
+ const r = this.rows[i];
205
+ if (!r) return null;
206
+ const l = r[n], d = this.columns.find((u) => u.field === n)?.header || n;
207
207
  let c;
208
208
  if (this.config.includeHeaders) {
209
209
  const u = l == null ? "" : String(l);
@@ -219,13 +219,13 @@ class wn extends x {
219
219
  * @returns The copied text
220
220
  */
221
221
  async copy() {
222
- const t = this.#n()?.getSelectedRows() ?? [], n = H({
222
+ const t = this.#n()?.getSelectedRows() ?? [], n = V({
223
223
  rows: this.rows,
224
224
  columns: [...this.columns],
225
225
  selectedIndices: t,
226
226
  config: this.config
227
227
  });
228
- return await G(n), this.lastCopied = { text: n, timestamp: Date.now() }, n;
228
+ return await O(n), this.lastCopied = { text: n, timestamp: Date.now() }, n;
229
229
  }
230
230
  /**
231
231
  * Copy specific rows by index to clipboard.
@@ -233,21 +233,21 @@ class wn extends x {
233
233
  * @returns The copied text
234
234
  */
235
235
  async copyRows(e) {
236
- const t = H({
236
+ const t = V({
237
237
  rows: this.rows,
238
238
  columns: [...this.columns],
239
239
  selectedIndices: e,
240
240
  config: this.config
241
241
  });
242
- return await G(t), this.lastCopied = { text: t, timestamp: Date.now() }, t;
242
+ return await O(t), this.lastCopied = { text: t, timestamp: Date.now() }, t;
243
243
  }
244
244
  /**
245
245
  * Read and parse clipboard content.
246
246
  * @returns Parsed 2D array of cell values, or null if clipboard is empty
247
247
  */
248
248
  async paste() {
249
- const e = await ae();
250
- return e ? le(e, this.config) : null;
249
+ const e = await de();
250
+ return e ? ae(e, this.config) : null;
251
251
  }
252
252
  /**
253
253
  * Get the last copied text and timestamp.
@@ -258,37 +258,37 @@ class wn extends x {
258
258
  }
259
259
  // #endregion
260
260
  }
261
- const de = 100;
262
- function Q(r) {
263
- if (r == null)
264
- return de;
265
- if (typeof r == "number")
266
- return r;
267
- const e = parseFloat(r);
268
- return isNaN(e) ? de : e;
261
+ const ce = 100;
262
+ function ee(s) {
263
+ if (s == null)
264
+ return ce;
265
+ if (typeof s == "number")
266
+ return s;
267
+ const e = parseFloat(s);
268
+ return isNaN(e) ? ce : e;
269
269
  }
270
- function ce(r) {
271
- return r.map((e) => Q(e.width));
270
+ function ue(s) {
271
+ return s.map((e) => ee(e.width));
272
272
  }
273
- function ue(r) {
273
+ function he(s) {
274
274
  const e = [];
275
275
  let t = 0;
276
- for (const n of r)
277
- e.push(t), t += Q(n.width);
276
+ for (const n of s)
277
+ e.push(t), t += ee(n.width);
278
278
  return e;
279
279
  }
280
- function he(r) {
281
- return r.reduce((e, t) => e + Q(t.width), 0);
280
+ function ge(s) {
281
+ return s.reduce((e, t) => e + ee(t.width), 0);
282
282
  }
283
- function Ve(r, e, t, n, o) {
283
+ function ze(s, e, t, n, o) {
284
284
  const i = t.length;
285
285
  if (i === 0)
286
286
  return { startCol: 0, endCol: 0, visibleColumns: [] };
287
- let s = ze(r, t, n);
288
- s = Math.max(0, s - o);
289
- const l = r + e;
290
- let a = s;
291
- for (let c = s; c < i; c++) {
287
+ let r = We(s, t, n);
288
+ r = Math.max(0, r - o);
289
+ const l = s + e;
290
+ let a = r;
291
+ for (let c = r; c < i; c++) {
292
292
  if (t[c] >= l) {
293
293
  a = c - 1;
294
294
  break;
@@ -297,22 +297,22 @@ function Ve(r, e, t, n, o) {
297
297
  }
298
298
  a = Math.min(i - 1, a + o);
299
299
  const d = [];
300
- for (let c = s; c <= a; c++)
300
+ for (let c = r; c <= a; c++)
301
301
  d.push(c);
302
- return { startCol: s, endCol: a, visibleColumns: d };
302
+ return { startCol: r, endCol: a, visibleColumns: d };
303
303
  }
304
- function ze(r, e, t) {
304
+ function We(s, e, t) {
305
305
  let n = 0, o = e.length - 1;
306
306
  for (; n < o; ) {
307
307
  const i = Math.floor((n + o) / 2);
308
- e[i] + t[i] <= r ? n = i + 1 : o = i;
308
+ e[i] + t[i] <= s ? n = i + 1 : o = i;
309
309
  }
310
310
  return n;
311
311
  }
312
- function We(r, e, t) {
313
- return t ? r > e : !1;
312
+ function $e(s, e, t) {
313
+ return t ? s > e : !1;
314
314
  }
315
- class bn extends x {
315
+ class vn extends v {
316
316
  name = "columnVirtualization";
317
317
  version = "1.0.0";
318
318
  get defaultConfig() {
@@ -335,7 +335,7 @@ class bn extends x {
335
335
  attach(e) {
336
336
  super.attach(e);
337
337
  const t = this.columns;
338
- this.columnWidths = ce(t), this.columnOffsets = ue(t), this.totalWidth = he(t), this.endCol = t.length - 1;
338
+ this.columnWidths = ue(t), this.columnOffsets = he(t), this.totalWidth = ge(t), this.endCol = t.length - 1;
339
339
  }
340
340
  detach() {
341
341
  this.columnWidths = [], this.columnOffsets = [], this.isVirtualized = !1, this.startCol = 0, this.endCol = 0, this.scrollLeft = 0, this.totalWidth = 0;
@@ -343,10 +343,10 @@ class bn extends x {
343
343
  // #endregion
344
344
  // #region Hooks
345
345
  processColumns(e) {
346
- const t = We(e.length, this.config.threshold ?? 30, this.config.autoEnable ?? !0);
347
- if (this.isVirtualized = t ?? !1, this.columnWidths = ce(e), this.columnOffsets = ue(e), this.totalWidth = he(e), !t)
346
+ const t = $e(e.length, this.config.threshold ?? 30, this.config.autoEnable ?? !0);
347
+ if (this.isVirtualized = t ?? !1, this.columnWidths = ue(e), this.columnOffsets = he(e), this.totalWidth = ge(e), !t)
348
348
  return this.startCol = 0, this.endCol = e.length - 1, [...e];
349
- const n = this.grid.clientWidth || 800, o = Ve(
349
+ const n = this.grid.clientWidth || 800, o = ze(
350
350
  this.scrollLeft,
351
351
  n,
352
352
  this.columnOffsets,
@@ -360,8 +360,8 @@ class bn extends x {
360
360
  const e = this.shadowRoot;
361
361
  if (!e) return;
362
362
  const t = this.columnOffsets[this.startCol] ?? 0, n = e.querySelector(".header-row"), o = e.querySelectorAll(".data-grid-row");
363
- n && (n.style.paddingLeft = `${t}px`), o.forEach((s) => {
364
- s.style.paddingLeft = `${t}px`;
363
+ n && (n.style.paddingLeft = `${t}px`), o.forEach((r) => {
364
+ r.style.paddingLeft = `${t}px`;
365
365
  });
366
366
  const i = e.querySelector(".rows-viewport .rows");
367
367
  i && (i.style.width = `${this.totalWidth}px`);
@@ -406,77 +406,77 @@ class bn extends x {
406
406
  }
407
407
  // #endregion
408
408
  }
409
- const $e = ".tbw-context-menu{position:fixed;background:light-dark(#f5f5f5,#2a2a2a);color:light-dark(#222,#eee);border:1px solid light-dark(#d0d0d4,#454545);border-radius:4px;box-shadow:0 2px 10px #00000026;min-width:160px;padding:4px 0;z-index:10000;font-size:13px;font-family:system-ui,sans-serif}.tbw-context-menu-item{display:flex;align-items:center;padding:6px 12px;cursor:pointer;gap:8px}.tbw-context-menu-item:hover:not(.disabled){background:light-dark(#e8e8e8,#3a3a3a)}.tbw-context-menu-item.disabled{opacity:.5;cursor:default}.tbw-context-menu-item.danger{color:light-dark(#c00,#f66)}.tbw-context-menu-icon{width:16px;text-align:center}.tbw-context-menu-label{flex:1}.tbw-context-menu-shortcut{color:light-dark(#888,#888);font-size:11px}.tbw-context-menu-arrow{font-size:10px;color:light-dark(#888,#888)}.tbw-context-menu-separator{height:1px;background:light-dark(#d0d0d4,#454545);margin:4px 0}";
410
- function Y(r, e) {
411
- return (typeof r == "function" ? r(e) : r).filter((n) => !(n.hidden === !0 || typeof n.hidden == "function" && n.hidden(e)));
409
+ const je = ".tbw-context-menu{position:fixed;background:light-dark(#f5f5f5,#2a2a2a);color:light-dark(#222,#eee);border:1px solid light-dark(#d0d0d4,#454545);border-radius:4px;box-shadow:0 2px 10px #00000026;min-width:160px;padding:4px 0;z-index:10000;font-size:13px;font-family:system-ui,sans-serif}.tbw-context-menu-item{display:flex;align-items:center;padding:6px 12px;cursor:pointer;gap:8px}.tbw-context-menu-item:hover:not(.disabled){background:light-dark(#e8e8e8,#3a3a3a)}.tbw-context-menu-item.disabled{opacity:.5;cursor:default}.tbw-context-menu-item.danger{color:light-dark(#c00,#f66)}.tbw-context-menu-icon{width:16px;text-align:center}.tbw-context-menu-label{flex:1}.tbw-context-menu-shortcut{color:light-dark(#888,#888);font-size:11px}.tbw-context-menu-arrow{font-size:10px;color:light-dark(#888,#888)}.tbw-context-menu-separator{height:1px;background:light-dark(#d0d0d4,#454545);margin:4px 0}";
410
+ function Z(s, e) {
411
+ return (typeof s == "function" ? s(e) : s).filter((n) => !(n.hidden === !0 || typeof n.hidden == "function" && n.hidden(e)));
412
412
  }
413
- function je(r, e) {
414
- return r.disabled === !0 ? !0 : typeof r.disabled == "function" ? r.disabled(e) : !1;
413
+ function Ue(s, e) {
414
+ return s.disabled === !0 ? !0 : typeof s.disabled == "function" ? s.disabled(e) : !1;
415
415
  }
416
- function Z(r, e, t, n = He.submenuArrow) {
416
+ function X(s, e, t, n = Ve.submenuArrow) {
417
417
  const o = document.createElement("div");
418
418
  o.className = "tbw-context-menu", o.setAttribute("role", "menu");
419
- for (const i of r) {
419
+ for (const i of s) {
420
420
  if (i.separator) {
421
421
  const d = document.createElement("div");
422
422
  d.className = "tbw-context-menu-separator", d.setAttribute("role", "separator"), o.appendChild(d);
423
423
  continue;
424
424
  }
425
- const s = document.createElement("div");
426
- s.className = "tbw-context-menu-item", i.cssClass && s.classList.add(i.cssClass), s.setAttribute("role", "menuitem"), s.setAttribute("data-id", i.id);
427
- const l = je(i, e);
428
- if (l && (s.classList.add("disabled"), s.setAttribute("aria-disabled", "true")), i.icon) {
425
+ const r = document.createElement("div");
426
+ r.className = "tbw-context-menu-item", i.cssClass && r.classList.add(i.cssClass), r.setAttribute("role", "menuitem"), r.setAttribute("data-id", i.id);
427
+ const l = Ue(i, e);
428
+ if (l && (r.classList.add("disabled"), r.setAttribute("aria-disabled", "true")), i.icon) {
429
429
  const d = document.createElement("span");
430
- d.className = "tbw-context-menu-icon", d.innerHTML = i.icon, s.appendChild(d);
430
+ d.className = "tbw-context-menu-icon", d.innerHTML = i.icon, r.appendChild(d);
431
431
  }
432
432
  const a = document.createElement("span");
433
- if (a.className = "tbw-context-menu-label", a.textContent = i.name, s.appendChild(a), i.shortcut) {
433
+ if (a.className = "tbw-context-menu-label", a.textContent = i.name, r.appendChild(a), i.shortcut) {
434
434
  const d = document.createElement("span");
435
- d.className = "tbw-context-menu-shortcut", d.textContent = i.shortcut, s.appendChild(d);
435
+ d.className = "tbw-context-menu-shortcut", d.textContent = i.shortcut, r.appendChild(d);
436
436
  }
437
437
  if (i.subMenu?.length) {
438
438
  const d = document.createElement("span");
439
- d.className = "tbw-context-menu-arrow", typeof n == "string" ? d.innerHTML = n : n instanceof HTMLElement && d.appendChild(n.cloneNode(!0)), s.appendChild(d), s.addEventListener("mouseenter", () => {
440
- if (s.querySelector(".tbw-context-menu") || !i.subMenu) return;
441
- const u = Y(i.subMenu, e), h = Z(u, e, t, n);
442
- h.classList.add("tbw-context-submenu"), h.style.position = "absolute", h.style.left = "100%", h.style.top = "0", s.style.position = "relative", s.appendChild(h);
443
- }), s.addEventListener("mouseleave", () => {
444
- const c = s.querySelector(".tbw-context-menu");
439
+ d.className = "tbw-context-menu-arrow", typeof n == "string" ? d.innerHTML = n : n instanceof HTMLElement && d.appendChild(n.cloneNode(!0)), r.appendChild(d), r.addEventListener("mouseenter", () => {
440
+ if (r.querySelector(".tbw-context-menu") || !i.subMenu) return;
441
+ const u = Z(i.subMenu, e), h = X(u, e, t, n);
442
+ h.classList.add("tbw-context-submenu"), h.style.position = "absolute", h.style.left = "100%", h.style.top = "0", r.style.position = "relative", r.appendChild(h);
443
+ }), r.addEventListener("mouseleave", () => {
444
+ const c = r.querySelector(".tbw-context-menu");
445
445
  c && c.remove();
446
446
  });
447
447
  }
448
- !l && i.action && !i.subMenu && s.addEventListener("click", (d) => {
448
+ !l && i.action && !i.subMenu && r.addEventListener("click", (d) => {
449
449
  d.stopPropagation(), t(i);
450
- }), o.appendChild(s);
450
+ }), o.appendChild(r);
451
451
  }
452
452
  return o;
453
453
  }
454
- function ge(r, e, t) {
455
- r.style.position = "fixed", r.style.left = `${e}px`, r.style.top = `${t}px`, r.style.visibility = "hidden", r.style.zIndex = "10000";
456
- const n = r.getBoundingClientRect(), o = window.innerWidth, i = window.innerHeight;
457
- let s = e, l = t;
458
- e + n.width > o && (s = e - n.width), t + n.height > i && (l = t - n.height), s = Math.max(0, s), l = Math.max(0, l), r.style.left = `${s}px`, r.style.top = `${l}px`, r.style.visibility = "visible";
454
+ function fe(s, e, t) {
455
+ s.style.position = "fixed", s.style.left = `${e}px`, s.style.top = `${t}px`, s.style.visibility = "hidden", s.style.zIndex = "10000";
456
+ const n = s.getBoundingClientRect(), o = window.innerWidth, i = window.innerHeight;
457
+ let r = e, l = t;
458
+ e + n.width > o && (r = e - n.width), t + n.height > i && (l = t - n.height), r = Math.max(0, r), l = Math.max(0, l), s.style.left = `${r}px`, s.style.top = `${l}px`, s.style.visibility = "visible";
459
459
  }
460
- let _ = null, I = null, E = null, O = 0;
460
+ let _ = null, I = null, k = null, G = 0;
461
461
  const B = [
462
462
  {
463
463
  id: "copy",
464
464
  name: "Copy",
465
465
  shortcut: "Ctrl+C",
466
- action: (r) => {
467
- r.grid?.plugins?.clipboard?.copy?.();
466
+ action: (s) => {
467
+ s.grid?.plugins?.clipboard?.copy?.();
468
468
  }
469
469
  },
470
470
  { separator: !0, id: "sep1", name: "" },
471
471
  {
472
472
  id: "export-csv",
473
473
  name: "Export CSV",
474
- action: (r) => {
475
- r.grid?.plugins?.export?.exportCsv?.();
474
+ action: (s) => {
475
+ s.grid?.plugins?.export?.exportCsv?.();
476
476
  }
477
477
  }
478
478
  ];
479
- class vn extends x {
479
+ class xn extends v {
480
480
  name = "contextMenu";
481
481
  version = "1.0.0";
482
482
  get defaultConfig() {
@@ -492,7 +492,7 @@ class vn extends x {
492
492
  // #endregion
493
493
  // #region Lifecycle
494
494
  attach(e) {
495
- super.attach(e), this.installGlobalHandlers(), O++;
495
+ super.attach(e), this.installGlobalHandlers(), G++;
496
496
  }
497
497
  detach() {
498
498
  this.menuElement && (this.menuElement.remove(), this.menuElement = null), this.isOpen = !1, this.params = null, this.uninstallGlobalHandlers();
@@ -500,7 +500,7 @@ class vn extends x {
500
500
  // #endregion
501
501
  // #region Private Methods
502
502
  installGlobalHandlers() {
503
- !E && typeof document < "u" && (E = document.createElement("style"), E.id = "tbw-context-menu-styles", E.textContent = $e, document.head.appendChild(E)), _ || (_ = () => {
503
+ !k && typeof document < "u" && (k = document.createElement("style"), k.id = "tbw-context-menu-styles", k.textContent = je, document.head.appendChild(k)), _ || (_ = () => {
504
504
  document.querySelectorAll(".tbw-context-menu").forEach((t) => t.remove());
505
505
  }, document.addEventListener("click", _)), I || (I = (e) => {
506
506
  e.key === "Escape" && document.querySelectorAll(".tbw-context-menu").forEach((n) => n.remove());
@@ -511,7 +511,7 @@ class vn extends x {
511
511
  * Uses reference counting to ensure handlers persist while any grid uses the plugin.
512
512
  */
513
513
  uninstallGlobalHandlers() {
514
- O--, !(O > 0) && (_ && (document.removeEventListener("click", _), _ = null), I && (document.removeEventListener("keydown", I), I = null), E && (E.remove(), E = null));
514
+ G--, !(G > 0) && (_ && (document.removeEventListener("click", _), _ = null), I && (document.removeEventListener("keydown", I), I = null), k && (k.remove(), k = null));
515
515
  }
516
516
  // #endregion
517
517
  // #region Hooks
@@ -522,10 +522,10 @@ class vn extends x {
522
522
  t && t.getAttribute("data-context-menu-bound") !== "true" && (t.setAttribute("data-context-menu-bound", "true"), t.addEventListener("contextmenu", (n) => {
523
523
  const o = n;
524
524
  o.preventDefault();
525
- const i = o.target, s = i.closest("[data-row][data-col]"), l = i.closest(".header-cell");
525
+ const i = o.target, r = i.closest("[data-row][data-col]"), l = i.closest(".header-cell");
526
526
  let a;
527
- if (s) {
528
- const c = parseInt(s.getAttribute("data-row") ?? "-1", 10), u = parseInt(s.getAttribute("data-col") ?? "-1", 10), h = this.columns[u], g = this.rows[c];
527
+ if (r) {
528
+ const c = parseInt(r.getAttribute("data-row") ?? "-1", 10), u = parseInt(r.getAttribute("data-col") ?? "-1", 10), h = this.columns[u], g = this.rows[c];
529
529
  a = {
530
530
  row: g,
531
531
  rowIndex: c,
@@ -551,15 +551,15 @@ class vn extends x {
551
551
  } else
552
552
  return;
553
553
  this.params = a, this.position = { x: o.clientX, y: o.clientY };
554
- const d = Y(this.config.items ?? B, a);
555
- d.length && (this.menuElement && this.menuElement.remove(), this.menuElement = Z(
554
+ const d = Z(this.config.items ?? B, a);
555
+ d.length && (this.menuElement && this.menuElement.remove(), this.menuElement = X(
556
556
  d,
557
557
  a,
558
558
  (c) => {
559
559
  c.action && c.action(a), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
560
560
  },
561
561
  this.gridIcons.submenuArrow
562
- ), document.body.appendChild(this.menuElement), ge(this.menuElement, o.clientX, o.clientY), this.isOpen = !0, this.emit("context-menu-open", { params: a, items: d }));
562
+ ), document.body.appendChild(this.menuElement), fe(this.menuElement, o.clientX, o.clientY), this.isOpen = !0, this.emit("context-menu-open", { params: a, items: d }));
563
563
  }));
564
564
  }
565
565
  // #endregion
@@ -580,15 +580,15 @@ class vn extends x {
580
580
  value: n.value ?? null,
581
581
  isHeader: n.isHeader ?? !1,
582
582
  event: n.event ?? new MouseEvent("contextmenu")
583
- }, i = Y(this.config.items ?? B, o);
584
- this.menuElement && this.menuElement.remove(), this.menuElement = Z(
583
+ }, i = Z(this.config.items ?? B, o);
584
+ this.menuElement && this.menuElement.remove(), this.menuElement = X(
585
585
  i,
586
586
  o,
587
- (s) => {
588
- s.action && s.action(o), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
587
+ (r) => {
588
+ r.action && r.action(o), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
589
589
  },
590
590
  this.gridIcons.submenuArrow
591
- ), document.body.appendChild(this.menuElement), ge(this.menuElement, e, t), this.isOpen = !0;
591
+ ), document.body.appendChild(this.menuElement), fe(this.menuElement, e, t), this.isOpen = !0;
592
592
  }
593
593
  /**
594
594
  * Hide the context menu.
@@ -606,45 +606,45 @@ class vn extends x {
606
606
  // #endregion
607
607
  // Styles are injected globally via installGlobalHandlers() since menu renders in document.body
608
608
  }
609
- function pe(r, e = !0) {
610
- if (r == null) return "";
611
- if (r instanceof Date) return r.toISOString();
612
- if (typeof r == "object") return JSON.stringify(r);
613
- const t = String(r);
609
+ function pe(s, e = !0) {
610
+ if (s == null) return "";
611
+ if (s instanceof Date) return s.toISOString();
612
+ if (typeof s == "object") return JSON.stringify(s);
613
+ const t = String(s);
614
614
  return e && (t.includes(",") || t.includes('"') || t.includes(`
615
615
  `) || t.includes("\r")) ? `"${t.replace(/"/g, '""')}"` : t;
616
616
  }
617
- function Ue(r, e, t, n = {}) {
617
+ function Ye(s, e, t, n = {}) {
618
618
  const o = n.delimiter ?? ",", i = n.newline ?? `
619
- `, s = [], l = n.bom ? "\uFEFF" : "";
619
+ `, r = [], l = n.bom ? "\uFEFF" : "";
620
620
  if (t.includeHeaders !== !1) {
621
621
  const a = e.map((d) => {
622
622
  const c = d.header || d.field, u = t.processHeader ? t.processHeader(c, d.field) : c;
623
623
  return pe(u);
624
624
  });
625
- s.push(a.join(o));
625
+ r.push(a.join(o));
626
626
  }
627
- for (const a of r) {
627
+ for (const a of s) {
628
628
  const d = e.map((c) => {
629
629
  let u = a[c.field];
630
630
  return t.processCell && (u = t.processCell(u, c.field, a)), pe(u);
631
631
  });
632
- s.push(d.join(o));
632
+ r.push(d.join(o));
633
633
  }
634
- return l + s.join(i);
634
+ return l + r.join(i);
635
635
  }
636
- function ee(r, e) {
637
- const t = URL.createObjectURL(r), n = document.createElement("a");
636
+ function te(s, e) {
637
+ const t = URL.createObjectURL(s), n = document.createElement("a");
638
638
  n.href = t, n.download = e, n.style.display = "none", document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(t);
639
639
  }
640
- function Ye(r, e) {
641
- const t = new Blob([r], { type: "text/csv;charset=utf-8;" });
642
- ee(t, e);
640
+ function Ze(s, e) {
641
+ const t = new Blob([s], { type: "text/csv;charset=utf-8;" });
642
+ te(t, e);
643
643
  }
644
- function fe(r) {
645
- return r.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
644
+ function me(s) {
645
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
646
646
  }
647
- function Ze(r, e, t) {
647
+ function Xe(s, e, t) {
648
648
  let n = `<?xml version="1.0" encoding="UTF-8"?>
649
649
  <?mso-application progid="Excel.Sheet"?>
650
650
  <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
@@ -655,19 +655,19 @@ function Ze(r, e, t) {
655
655
  n += `
656
656
  <Row>`;
657
657
  for (const o of e) {
658
- const i = o.header || o.field, s = t.processHeader ? t.processHeader(i, o.field) : i;
659
- n += `<Cell><Data ss:Type="String">${fe(s)}</Data></Cell>`;
658
+ const i = o.header || o.field, r = t.processHeader ? t.processHeader(i, o.field) : i;
659
+ n += `<Cell><Data ss:Type="String">${me(r)}</Data></Cell>`;
660
660
  }
661
661
  n += "</Row>";
662
662
  }
663
- for (const o of r) {
663
+ for (const o of s) {
664
664
  n += `
665
665
  <Row>`;
666
666
  for (const i of e) {
667
- let s = o[i.field];
668
- t.processCell && (s = t.processCell(s, i.field, o));
667
+ let r = o[i.field];
668
+ t.processCell && (r = t.processCell(r, i.field, o));
669
669
  let l = "String", a = "";
670
- s == null ? a = "" : typeof s == "number" && !isNaN(s) ? (l = "Number", a = String(s)) : s instanceof Date ? (l = "DateTime", a = s.toISOString()) : a = fe(String(s)), n += `<Cell><Data ss:Type="${l}">${a}</Data></Cell>`;
670
+ r == null ? a = "" : typeof r == "number" && !isNaN(r) ? (l = "Number", a = String(r)) : r instanceof Date ? (l = "DateTime", a = r.toISOString()) : a = me(String(r)), n += `<Cell><Data ss:Type="${l}">${a}</Data></Cell>`;
671
671
  }
672
672
  n += "</Row>";
673
673
  }
@@ -676,13 +676,13 @@ function Ze(r, e, t) {
676
676
  </Worksheet>
677
677
  </Workbook>`, n;
678
678
  }
679
- function Xe(r, e) {
680
- const t = e.endsWith(".xls") ? e : `${e}.xls`, n = new Blob([r], {
679
+ function Je(s, e) {
680
+ const t = e.endsWith(".xls") ? e : `${e}.xls`, n = new Blob([s], {
681
681
  type: "application/vnd.ms-excel;charset=utf-8;"
682
682
  });
683
- ee(n, t);
683
+ te(n, t);
684
684
  }
685
- class xn extends x {
685
+ class yn extends v {
686
686
  name = "export";
687
687
  version = "1.0.0";
688
688
  get defaultConfig() {
@@ -713,44 +713,44 @@ class xn extends x {
713
713
  const a = new Set(t.columns);
714
714
  i = i.filter((d) => a.has(d.field));
715
715
  }
716
- let s = [...this.rows];
716
+ let r = [...this.rows];
717
717
  if (n.onlySelected) {
718
718
  const a = this.getSelectionState();
719
- a?.selected?.size && (s = [...a.selected].sort((c, u) => c - u).map((c) => this.rows[c]).filter(Boolean));
719
+ a?.selected?.size && (r = [...a.selected].sort((c, u) => c - u).map((c) => this.rows[c]).filter(Boolean));
720
720
  }
721
- t?.rowIndices && (s = t.rowIndices.map((a) => this.rows[a]).filter(Boolean)), this.isExportingFlag = !0;
721
+ t?.rowIndices && (r = t.rowIndices.map((a) => this.rows[a]).filter(Boolean)), this.isExportingFlag = !0;
722
722
  let l = o.fileName;
723
723
  try {
724
724
  switch (e) {
725
725
  case "csv": {
726
- const a = Ue(s, i, o, { bom: !0 });
727
- l = l.endsWith(".csv") ? l : `${l}.csv`, Ye(a, l);
726
+ const a = Ye(r, i, o, { bom: !0 });
727
+ l = l.endsWith(".csv") ? l : `${l}.csv`, Ze(a, l);
728
728
  break;
729
729
  }
730
730
  case "excel": {
731
- const a = Ze(s, i, o);
732
- l = l.endsWith(".xls") ? l : `${l}.xls`, Xe(a, l);
731
+ const a = Xe(r, i, o);
732
+ l = l.endsWith(".xls") ? l : `${l}.xls`, Je(a, l);
733
733
  break;
734
734
  }
735
735
  case "json": {
736
- const a = s.map((u) => {
736
+ const a = r.map((u) => {
737
737
  const h = {};
738
738
  for (const g of i) {
739
- let p = u[g.field];
740
- o.processCell && (p = o.processCell(p, g.field, u)), h[g.field] = p;
739
+ let f = u[g.field];
740
+ o.processCell && (f = o.processCell(f, g.field, u)), h[g.field] = f;
741
741
  }
742
742
  return h;
743
743
  }), d = JSON.stringify(a, null, 2);
744
744
  l = l.endsWith(".json") ? l : `${l}.json`;
745
745
  const c = new Blob([d], { type: "application/json" });
746
- ee(c, l);
746
+ te(c, l);
747
747
  break;
748
748
  }
749
749
  }
750
750
  this.lastExportInfo = { format: e, timestamp: /* @__PURE__ */ new Date() }, this.emit("export-complete", {
751
751
  format: e,
752
752
  fileName: l,
753
- rowCount: s.length,
753
+ rowCount: r.length,
754
754
  columnCount: i.length
755
755
  });
756
756
  } finally {
@@ -803,43 +803,43 @@ class xn extends x {
803
803
  }
804
804
  // #endregion
805
805
  }
806
- function Je(r) {
807
- const { totalRows: e, viewportHeight: t, scrollTop: n, rowHeight: o, overscan: i } = r, s = Math.ceil(t / o);
806
+ function Qe(s) {
807
+ const { totalRows: e, viewportHeight: t, scrollTop: n, rowHeight: o, overscan: i } = s, r = Math.ceil(t / o);
808
808
  let l = Math.floor(n / o) - i;
809
809
  l < 0 && (l = 0);
810
- let a = l + s + i * 2;
811
- return a > e && (a = e), a === e && l > 0 && (l = Math.max(0, a - s - i * 2)), {
810
+ let a = l + r + i * 2;
811
+ return a > e && (a = e), a === e && l > 0 && (l = Math.max(0, a - r - i * 2)), {
812
812
  start: l,
813
813
  end: a,
814
814
  offsetY: l * o,
815
815
  totalHeight: e * o
816
816
  };
817
817
  }
818
- function Qe(r, e) {
819
- return r <= e;
818
+ function et(s, e) {
819
+ return s <= e;
820
820
  }
821
- function et(r, e, t = !1) {
822
- const n = r[e.field];
821
+ function tt(s, e, t = !1) {
822
+ const n = s[e.field];
823
823
  if (e.operator === "blank")
824
824
  return n == null || n === "";
825
825
  if (e.operator === "notBlank")
826
826
  return n != null && n !== "";
827
827
  if (n == null) return !1;
828
- const o = String(n), i = t ? o : o.toLowerCase(), s = t ? String(e.value) : String(e.value).toLowerCase();
828
+ const o = String(n), i = t ? o : o.toLowerCase(), r = t ? String(e.value) : String(e.value).toLowerCase();
829
829
  switch (e.operator) {
830
830
  // Text operators
831
831
  case "contains":
832
- return i.includes(s);
832
+ return i.includes(r);
833
833
  case "notContains":
834
- return !i.includes(s);
834
+ return !i.includes(r);
835
835
  case "equals":
836
- return i === s;
836
+ return i === r;
837
837
  case "notEquals":
838
- return i !== s;
838
+ return i !== r;
839
839
  case "startsWith":
840
- return i.startsWith(s);
840
+ return i.startsWith(r);
841
841
  case "endsWith":
842
- return i.endsWith(s);
842
+ return i.endsWith(r);
843
843
  // Number/Date operators (use raw numeric values)
844
844
  case "lessThan":
845
845
  return Number(n) < Number(e.value);
@@ -860,12 +860,12 @@ function et(r, e, t = !1) {
860
860
  return !0;
861
861
  }
862
862
  }
863
- function tt(r, e, t = !1) {
864
- return e.length ? r.filter((n) => e.every((o) => et(n, o, t))) : r;
863
+ function nt(s, e, t = !1) {
864
+ return e.length ? s.filter((n) => e.every((o) => tt(n, o, t))) : s;
865
865
  }
866
- function nt(r) {
866
+ function ot(s) {
867
867
  return JSON.stringify(
868
- r.map((e) => ({
868
+ s.map((e) => ({
869
869
  field: e.field,
870
870
  operator: e.operator,
871
871
  value: e.value,
@@ -873,16 +873,16 @@ function nt(r) {
873
873
  }))
874
874
  );
875
875
  }
876
- function me(r, e) {
876
+ function we(s, e) {
877
877
  const t = /* @__PURE__ */ new Set();
878
- for (const n of r) {
878
+ for (const n of s) {
879
879
  const o = n[e];
880
880
  o != null && t.add(o);
881
881
  }
882
882
  return [...t].sort((n, o) => typeof n == "number" && typeof o == "number" ? n - o : String(n).localeCompare(String(o)));
883
883
  }
884
- const ot = '.header-cell.filtered:before{content:"";position:absolute;top:4px;right:4px;width:6px;height:6px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));border-radius:50%}.tbw-filter-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:2px;margin-left:4px;opacity:.4;transition:opacity .15s;color:inherit;vertical-align:middle}.tbw-filter-btn:hover,.tbw-filter-btn.active{opacity:1}.tbw-filter-btn.active{color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}', it = ".tbw-filter-panel{position:fixed;background:var(--tbw-filter-panel-bg, var(--tbw-color-panel-bg, light-dark(#eeeeee, #222222)));color:var(--tbw-filter-panel-fg, var(--tbw-color-fg, light-dark(#222222, #eeeeee)));border:1px solid var(--tbw-filter-panel-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-panel-radius, var(--tbw-border-radius, 4px));box-shadow:0 4px 16px var(--tbw-filter-panel-shadow, var(--tbw-color-shadow, light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3))));padding:12px;z-index:10000;min-width:200px;max-width:280px;max-height:350px;display:flex;flex-direction:column;font-family:var(--tbw-font-family, system-ui, sans-serif);font-size:var(--tbw-font-size, 13px)}.tbw-filter-search{margin-bottom:8px}.tbw-filter-search-input{width:100%;padding:6px 10px;background:var(--tbw-filter-input-bg, var(--tbw-color-bg, transparent));color:inherit;border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-input-radius, 4px);font-size:inherit;box-sizing:border-box}.tbw-filter-search-input:focus{outline:none;border-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));box-shadow:0 0 0 2px rgba(from var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6)) r g b / 15%)}.tbw-filter-actions{display:flex;padding:4px 2px;margin-bottom:8px;border-bottom:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-action-btn{background:transparent;border:none;color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));cursor:pointer;font-size:12px;padding:2px 0}.tbw-filter-action-btn:hover{text-decoration:underline}.tbw-filter-values{flex:1;overflow-y:auto;margin-bottom:8px;max-height:180px;position:relative}.tbw-filter-values-spacer{width:1px}.tbw-filter-values-content{position:absolute;top:0;left:0;right:0}.tbw-filter-value-item{display:flex;align-items:center;gap:8px;padding:4px 2px;cursor:pointer;border-radius:3px}.tbw-filter-value-item:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}.tbw-filter-checkbox{margin:0;cursor:pointer;accent-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}.tbw-filter-no-match{color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));padding:8px 0;text-align:center;font-style:italic}.tbw-filter-buttons{display:flex;gap:8px;padding-top:8px;border-top:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-apply-btn{flex:1;padding:6px 12px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));color:var(--tbw-filter-accent-fg, var(--tbw-color-accent-fg, light-dark(#ffffff, #000000)));border:none;border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-apply-btn:hover{filter:brightness(.9)}.tbw-filter-clear-btn{flex:1;padding:6px 12px;background:transparent;color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-clear-btn:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}";
885
- class A extends x {
884
+ const it = '.header-cell.filtered:before{content:"";position:absolute;top:4px;right:4px;width:6px;height:6px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));border-radius:50%}.tbw-filter-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:2px;margin-left:4px;opacity:.4;transition:opacity .15s;color:inherit;vertical-align:middle}.tbw-filter-btn:hover,.tbw-filter-btn.active{opacity:1}.tbw-filter-btn.active{color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}', rt = ".tbw-filter-panel{position:fixed;background:var(--tbw-filter-panel-bg, var(--tbw-color-panel-bg, light-dark(#eeeeee, #222222)));color:var(--tbw-filter-panel-fg, var(--tbw-color-fg, light-dark(#222222, #eeeeee)));border:1px solid var(--tbw-filter-panel-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-panel-radius, var(--tbw-border-radius, 4px));box-shadow:0 4px 16px var(--tbw-filter-panel-shadow, var(--tbw-color-shadow, light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3))));padding:12px;z-index:10000;min-width:200px;max-width:280px;max-height:350px;display:flex;flex-direction:column;font-family:var(--tbw-font-family, system-ui, sans-serif);font-size:var(--tbw-font-size, 13px)}.tbw-filter-search{margin-bottom:8px}.tbw-filter-search-input{width:100%;padding:6px 10px;background:var(--tbw-filter-input-bg, var(--tbw-color-bg, transparent));color:inherit;border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-input-radius, 4px);font-size:inherit;box-sizing:border-box}.tbw-filter-search-input:focus{outline:none;border-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));box-shadow:0 0 0 2px rgba(from var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6)) r g b / 15%)}.tbw-filter-actions{display:flex;padding:4px 2px;margin-bottom:8px;border-bottom:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-action-btn{background:transparent;border:none;color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));cursor:pointer;font-size:12px;padding:2px 0}.tbw-filter-action-btn:hover{text-decoration:underline}.tbw-filter-values{flex:1;overflow-y:auto;margin-bottom:8px;max-height:180px;position:relative}.tbw-filter-values-spacer{width:1px}.tbw-filter-values-content{position:absolute;top:0;left:0;right:0}.tbw-filter-value-item{display:flex;align-items:center;gap:8px;padding:4px 2px;cursor:pointer;border-radius:3px}.tbw-filter-value-item:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}.tbw-filter-checkbox{margin:0;cursor:pointer;accent-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}.tbw-filter-no-match{color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));padding:8px 0;text-align:center;font-style:italic}.tbw-filter-buttons{display:flex;gap:8px;padding-top:8px;border-top:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-apply-btn{flex:1;padding:6px 12px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));color:var(--tbw-filter-accent-fg, var(--tbw-color-accent-fg, light-dark(#ffffff, #000000)));border:none;border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-apply-btn:hover{filter:brightness(.9)}.tbw-filter-clear-btn{flex:1;padding:6px 12px;background:transparent;color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-clear-btn:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}";
885
+ class A extends v {
886
886
  name = "filtering";
887
887
  version = "1.0.0";
888
888
  get defaultConfig() {
@@ -922,10 +922,12 @@ class A extends x {
922
922
  processRows(e) {
923
923
  const t = [...this.filters.values()];
924
924
  if (!t.length) return [...e];
925
- const n = nt(t);
925
+ if (this.config.filterHandler)
926
+ return this.cachedResult ? this.cachedResult : [...e];
927
+ const n = ot(t);
926
928
  if (this.cacheKey === n && this.cachedResult)
927
929
  return this.cachedResult;
928
- const o = tt([...e], t, this.config.caseSensitive);
930
+ const o = nt([...e], t, this.config.caseSensitive);
929
931
  return this.cachedResult = o, this.cacheKey = n, o;
930
932
  }
931
933
  afterRender() {
@@ -934,14 +936,19 @@ class A extends x {
934
936
  e.querySelectorAll('[part~="header-cell"]').forEach((n) => {
935
937
  const o = n.getAttribute("data-col");
936
938
  if (o === null) return;
937
- const i = this.columns[parseInt(o, 10)];
938
- if (!i || i.filterable === !1 || n.querySelector(".tbw-filter-btn")) return;
939
- const s = i.field;
940
- if (!s) return;
941
- const l = document.createElement("button");
942
- l.className = "tbw-filter-btn", l.setAttribute("aria-label", `Filter ${i.header ?? s}`), l.innerHTML = '<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>', this.filters.has(s) && (l.classList.add("active"), n.classList.add("filtered")), l.addEventListener("click", (a) => {
943
- a.stopPropagation(), this.toggleFilterPanel(s, i, l);
944
- }), n.appendChild(l);
939
+ const i = this.visibleColumns[parseInt(o, 10)];
940
+ if (!i || i.filterable === !1) return;
941
+ const r = i.field;
942
+ if (!r) return;
943
+ const l = this.filters.has(r);
944
+ let a = n.querySelector(".tbw-filter-btn");
945
+ if (a) {
946
+ a.classList.toggle("active", l), n.classList.toggle("filtered", l);
947
+ return;
948
+ }
949
+ a = document.createElement("button"), a.className = "tbw-filter-btn", a.setAttribute("aria-label", `Filter ${i.header ?? r}`), a.innerHTML = '<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 && (a.classList.add("active"), n.classList.add("filtered")), a.addEventListener("click", (d) => {
950
+ d.stopPropagation(), this.toggleFilterPanel(r, i, a);
951
+ }), n.appendChild(a);
945
952
  });
946
953
  }
947
954
  // #endregion
@@ -951,7 +958,7 @@ class A extends x {
951
958
  * Pass null to remove the filter.
952
959
  */
953
960
  setFilter(e, t) {
954
- t === null ? this.filters.delete(e) : this.filters.set(e, { ...t, field: e }), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
961
+ t === null ? (this.filters.delete(e), this.excludedValues.delete(e)) : (this.filters.set(e, { ...t, field: e }), t.type === "set" && t.operator === "notIn" && Array.isArray(t.value) ? this.excludedValues.set(e, new Set(t.value)) : t.type === "set" && this.excludedValues.delete(e)), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
955
962
  filters: [...this.filters.values()],
956
963
  filteredRowCount: 0
957
964
  // Will be accurate after processRows
@@ -979,9 +986,9 @@ class A extends x {
979
986
  * Set filters from an array (replaces all existing filters).
980
987
  */
981
988
  setFilterModel(e) {
982
- this.filters.clear();
989
+ this.filters.clear(), this.excludedValues.clear();
983
990
  for (const t of e)
984
- this.filters.set(t.field, t);
991
+ this.filters.set(t.field, t), t.type === "set" && t.operator === "notIn" && Array.isArray(t.value) && this.excludedValues.set(t.field, new Set(t.value));
985
992
  this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
986
993
  filters: [...this.filters.values()],
987
994
  filteredRowCount: 0
@@ -991,19 +998,13 @@ class A extends x {
991
998
  * Clear all filters.
992
999
  */
993
1000
  clearAllFilters() {
994
- this.filters.clear(), this.excludedValues.clear(), this.searchText.clear(), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
995
- filters: [],
996
- filteredRowCount: this.rows.length
997
- }), this.requestRender();
1001
+ this.filters.clear(), this.excludedValues.clear(), this.searchText.clear(), this.applyFiltersInternal();
998
1002
  }
999
1003
  /**
1000
1004
  * Clear filter for a specific field.
1001
1005
  */
1002
1006
  clearFieldFilter(e) {
1003
- this.filters.delete(e), this.excludedValues.delete(e), this.searchText.delete(e), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
1004
- filters: [...this.filters.values()],
1005
- filteredRowCount: 0
1006
- }), this.requestRender();
1007
+ this.filters.delete(e), this.excludedValues.delete(e), this.searchText.delete(e), this.applyFiltersInternal();
1007
1008
  }
1008
1009
  /**
1009
1010
  * Check if a field has an active filter.
@@ -1028,7 +1029,7 @@ class A extends x {
1028
1029
  * Uses sourceRows to include all values regardless of current filter.
1029
1030
  */
1030
1031
  getUniqueValues(e) {
1031
- return me(this.sourceRows, e);
1032
+ return we(this.sourceRows, e);
1032
1033
  }
1033
1034
  // #endregion
1034
1035
  // #region Private Methods
@@ -1042,7 +1043,7 @@ class A extends x {
1042
1043
  return;
1043
1044
  }
1044
1045
  const e = document.createElement("style");
1045
- e.id = "tbw-filter-panel-styles", e.textContent = it, document.head.appendChild(e), this.globalStylesInjected = !0;
1046
+ e.id = "tbw-filter-panel-styles", e.textContent = rt, document.head.appendChild(e), this.globalStylesInjected = !0;
1046
1047
  }
1047
1048
  /**
1048
1049
  * Toggle the filter panel for a field
@@ -1054,33 +1055,50 @@ class A extends x {
1054
1055
  }
1055
1056
  this.closeFilterPanel();
1056
1057
  const o = document.createElement("div");
1057
- o.className = "tbw-filter-panel", this.panelElement = o, this.openPanelField = e;
1058
- const i = me(this.sourceRows, e);
1059
- let s = this.excludedValues.get(e);
1060
- s || (s = /* @__PURE__ */ new Set(), this.excludedValues.set(e, s));
1061
- const l = this.searchText.get(e) ?? "", a = {
1058
+ if (o.className = "tbw-filter-panel", this.panelElement = o, this.openPanelField = e, this.config.valuesHandler) {
1059
+ o.innerHTML = '<div class="tbw-filter-loading">Loading...</div>', document.body.appendChild(o), this.positionPanel(o, n), this.setupPanelCloseHandler(o, n), this.config.valuesHandler(e, t).then((r) => {
1060
+ this.openPanelField !== e || !this.panelElement || (o.innerHTML = "", this.renderPanelContent(e, t, o, r));
1061
+ });
1062
+ return;
1063
+ }
1064
+ const i = we(this.sourceRows, e);
1065
+ this.renderPanelContent(e, t, o, i), document.body.appendChild(o), this.positionPanel(o, n), this.setupPanelCloseHandler(o, n);
1066
+ }
1067
+ /**
1068
+ * Render filter panel content with given values
1069
+ */
1070
+ renderPanelContent(e, t, n, o) {
1071
+ let i = this.excludedValues.get(e);
1072
+ i || (i = /* @__PURE__ */ new Set(), this.excludedValues.set(e, i));
1073
+ const r = this.searchText.get(e) ?? "", l = {
1062
1074
  field: e,
1063
1075
  column: t,
1064
- uniqueValues: i,
1065
- excludedValues: s,
1066
- searchText: l,
1067
- applySetFilter: (c) => {
1068
- this.applySetFilter(e, c), this.closeFilterPanel();
1076
+ uniqueValues: o,
1077
+ excludedValues: i,
1078
+ searchText: r,
1079
+ applySetFilter: (d) => {
1080
+ this.applySetFilter(e, d), this.closeFilterPanel();
1069
1081
  },
1070
- applyTextFilter: (c, u, h) => {
1071
- this.applyTextFilter(e, c, u, h), this.closeFilterPanel();
1082
+ applyTextFilter: (d, c, u) => {
1083
+ this.applyTextFilter(e, d, c, u), this.closeFilterPanel();
1072
1084
  },
1073
1085
  clearFilter: () => {
1074
1086
  this.clearFieldFilter(e), this.closeFilterPanel();
1075
1087
  },
1076
1088
  closePanel: () => this.closeFilterPanel()
1077
1089
  };
1078
- let d = !1;
1079
- this.config.filterPanelRenderer && (this.config.filterPanelRenderer(o, a), d = o.children.length > 0), d || this.renderDefaultFilterPanel(o, a, i, s), document.body.appendChild(o), this.positionPanel(o, n), this.panelAbortController = new AbortController(), setTimeout(() => {
1090
+ let a = !1;
1091
+ this.config.filterPanelRenderer && (this.config.filterPanelRenderer(n, l), a = n.children.length > 0), a || this.renderDefaultFilterPanel(n, l, o, i);
1092
+ }
1093
+ /**
1094
+ * Setup click-outside handler to close the panel
1095
+ */
1096
+ setupPanelCloseHandler(e, t) {
1097
+ this.panelAbortController = new AbortController(), setTimeout(() => {
1080
1098
  document.addEventListener(
1081
1099
  "click",
1082
- (c) => {
1083
- !o.contains(c.target) && c.target !== n && this.closeFilterPanel();
1100
+ (n) => {
1101
+ !e.contains(n.target) && n.target !== t && this.closeFilterPanel();
1084
1102
  },
1085
1103
  { signal: this.panelAbortController?.signal }
1086
1104
  );
@@ -1106,10 +1124,10 @@ class A extends x {
1106
1124
  * Render the default filter panel content
1107
1125
  */
1108
1126
  renderDefaultFilterPanel(e, t, n, o) {
1109
- const { field: i } = t, s = document.createElement("div");
1110
- s.className = "tbw-filter-search";
1127
+ const { field: i } = t, r = document.createElement("div");
1128
+ r.className = "tbw-filter-search";
1111
1129
  const l = document.createElement("input");
1112
- l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(i) ?? "", s.appendChild(l), e.appendChild(s);
1130
+ l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(i) ?? "", r.appendChild(l), e.appendChild(r);
1113
1131
  const a = document.createElement("div");
1114
1132
  a.className = "tbw-filter-actions";
1115
1133
  const d = document.createElement("label");
@@ -1119,71 +1137,71 @@ class A extends x {
1119
1137
  const u = document.createElement("span");
1120
1138
  u.textContent = "Select All", d.appendChild(c), d.appendChild(u), a.appendChild(d);
1121
1139
  const h = () => {
1122
- const b = [...m.values()], C = b.every((y) => y), R = b.every((y) => !y);
1123
- c.checked = C, c.indeterminate = !C && !R;
1140
+ const w = [...p.values()], y = w.every((x) => x), C = w.every((x) => !x);
1141
+ c.checked = y, c.indeterminate = !y && !C;
1124
1142
  };
1125
1143
  c.addEventListener("change", () => {
1126
- const b = c.checked;
1127
- for (const C of m.keys())
1128
- m.set(C, b);
1129
- h(), K();
1144
+ const w = c.checked;
1145
+ for (const y of p.keys())
1146
+ p.set(y, w);
1147
+ h(), H();
1130
1148
  }), e.appendChild(a);
1131
1149
  const g = document.createElement("div");
1132
1150
  g.className = "tbw-filter-values";
1133
- const p = document.createElement("div");
1134
- p.className = "tbw-filter-values-spacer", g.appendChild(p);
1135
1151
  const f = document.createElement("div");
1136
- f.className = "tbw-filter-values-content", g.appendChild(f);
1137
- const m = /* @__PURE__ */ new Map();
1138
- n.forEach((b) => {
1139
- const C = b == null ? "__null__" : String(b);
1140
- m.set(C, !o.has(b));
1152
+ f.className = "tbw-filter-values-spacer", g.appendChild(f);
1153
+ const m = document.createElement("div");
1154
+ m.className = "tbw-filter-values-content", g.appendChild(m);
1155
+ const p = /* @__PURE__ */ new Map();
1156
+ n.forEach((w) => {
1157
+ const y = w == null ? "__null__" : String(w);
1158
+ p.set(y, !o.has(w));
1141
1159
  }), h();
1142
- let w = [];
1143
- const k = (b, C) => {
1144
- const R = b == null ? "(Blank)" : String(b), y = b == null ? "__null__" : String(b), v = document.createElement("label");
1145
- v.className = "tbw-filter-value-item", v.style.position = "absolute", v.style.top = `${C * A.LIST_ITEM_HEIGHT}px`, v.style.left = "0", v.style.right = "0", v.style.height = `${A.LIST_ITEM_HEIGHT}px`, v.style.boxSizing = "border-box";
1160
+ let R = [];
1161
+ const E = (w, y) => {
1162
+ const C = w == null ? "(Blank)" : String(w), x = w == null ? "__null__" : String(w), b = document.createElement("label");
1163
+ b.className = "tbw-filter-value-item", b.style.position = "absolute", b.style.top = `${y * A.LIST_ITEM_HEIGHT}px`, b.style.left = "0", b.style.right = "0", b.style.height = `${A.LIST_ITEM_HEIGHT}px`, b.style.boxSizing = "border-box";
1146
1164
  const S = document.createElement("input");
1147
- S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked = m.get(y) ?? !0, S.dataset.value = y, S.addEventListener("change", () => {
1148
- m.set(y, S.checked), h();
1165
+ S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked = p.get(x) ?? !0, S.dataset.value = x, S.addEventListener("change", () => {
1166
+ p.set(x, S.checked), h();
1149
1167
  });
1150
1168
  const re = document.createElement("span");
1151
- return re.textContent = R, v.appendChild(S), v.appendChild(re), v;
1152
- }, K = () => {
1153
- const b = w.length, C = g.clientHeight, R = g.scrollTop;
1154
- if (p.style.height = `${b * A.LIST_ITEM_HEIGHT}px`, Qe(b, A.LIST_BYPASS_THRESHOLD / 3)) {
1155
- f.innerHTML = "", f.style.transform = "translateY(0px)", w.forEach((v, S) => {
1156
- f.appendChild(k(v, S));
1169
+ return re.textContent = C, b.appendChild(S), b.appendChild(re), b;
1170
+ }, H = () => {
1171
+ const w = R.length, y = g.clientHeight, C = g.scrollTop;
1172
+ if (f.style.height = `${w * A.LIST_ITEM_HEIGHT}px`, et(w, A.LIST_BYPASS_THRESHOLD / 3)) {
1173
+ m.innerHTML = "", m.style.transform = "translateY(0px)", R.forEach((b, S) => {
1174
+ m.appendChild(E(b, S));
1157
1175
  });
1158
1176
  return;
1159
1177
  }
1160
- const y = Je({
1161
- totalRows: b,
1162
- viewportHeight: C,
1163
- scrollTop: R,
1178
+ const x = Qe({
1179
+ totalRows: w,
1180
+ viewportHeight: y,
1181
+ scrollTop: C,
1164
1182
  rowHeight: A.LIST_ITEM_HEIGHT,
1165
1183
  overscan: A.LIST_OVERSCAN
1166
1184
  });
1167
- f.style.transform = `translateY(${y.offsetY}px)`, f.innerHTML = "";
1168
- for (let v = y.start; v < y.end; v++)
1169
- f.appendChild(k(w[v], v - y.start));
1170
- }, oe = (b) => {
1171
- const C = b.toLowerCase();
1172
- if (w = n.filter((R) => {
1173
- const y = R == null ? "(Blank)" : String(R);
1174
- return !b || y.toLowerCase().includes(C);
1175
- }), w.length === 0) {
1176
- p.style.height = "0px", f.innerHTML = "";
1177
- const R = document.createElement("div");
1178
- R.className = "tbw-filter-no-match", R.textContent = "No matching values", f.appendChild(R);
1185
+ m.style.transform = `translateY(${x.offsetY}px)`, m.innerHTML = "";
1186
+ for (let b = x.start; b < x.end; b++)
1187
+ m.appendChild(E(R[b], b - x.start));
1188
+ }, oe = (w) => {
1189
+ const y = w.toLowerCase();
1190
+ if (R = n.filter((C) => {
1191
+ const x = C == null ? "(Blank)" : String(C);
1192
+ return !w || x.toLowerCase().includes(y);
1193
+ }), R.length === 0) {
1194
+ f.style.height = "0px", m.innerHTML = "";
1195
+ const C = document.createElement("div");
1196
+ C.className = "tbw-filter-no-match", C.textContent = "No matching values", m.appendChild(C);
1179
1197
  return;
1180
1198
  }
1181
- K();
1199
+ H();
1182
1200
  };
1183
1201
  g.addEventListener(
1184
1202
  "scroll",
1185
1203
  () => {
1186
- w.length > 0 && K();
1204
+ R.length > 0 && H();
1187
1205
  },
1188
1206
  { passive: !0 }
1189
1207
  ), oe(l.value), e.appendChild(g);
@@ -1193,25 +1211,25 @@ class A extends x {
1193
1211
  this.searchText.set(i, l.value), oe(l.value);
1194
1212
  }, this.config.debounceMs ?? 150);
1195
1213
  });
1196
- const M = document.createElement("div");
1197
- M.className = "tbw-filter-buttons";
1198
- const N = document.createElement("button");
1199
- N.className = "tbw-filter-apply-btn", N.textContent = "Apply", N.addEventListener("click", () => {
1200
- const b = [];
1201
- for (const [C, R] of m)
1202
- if (!R)
1203
- if (C === "__null__")
1204
- b.push(null);
1214
+ const P = document.createElement("div");
1215
+ P.className = "tbw-filter-buttons";
1216
+ const M = document.createElement("button");
1217
+ M.className = "tbw-filter-apply-btn", M.textContent = "Apply", M.addEventListener("click", () => {
1218
+ const w = [];
1219
+ for (const [y, C] of p)
1220
+ if (!C)
1221
+ if (y === "__null__")
1222
+ w.push(null);
1205
1223
  else {
1206
- const y = n.find((v) => String(v) === C);
1207
- b.push(y !== void 0 ? y : C);
1224
+ const x = n.find((b) => String(b) === y);
1225
+ w.push(x !== void 0 ? x : y);
1208
1226
  }
1209
- t.applySetFilter(b);
1210
- }), M.appendChild(N);
1211
- const P = document.createElement("button");
1212
- P.className = "tbw-filter-clear-btn", P.textContent = "Clear Filter", P.addEventListener("click", () => {
1227
+ t.applySetFilter(w);
1228
+ }), P.appendChild(M);
1229
+ const K = document.createElement("button");
1230
+ K.className = "tbw-filter-clear-btn", K.textContent = "Clear Filter", K.addEventListener("click", () => {
1213
1231
  t.clearFilter();
1214
- }), M.appendChild(P), e.appendChild(M);
1232
+ }), P.appendChild(K), e.appendChild(P);
1215
1233
  }
1216
1234
  /**
1217
1235
  * Apply a set filter (exclude values)
@@ -1222,10 +1240,7 @@ class A extends x {
1222
1240
  type: "set",
1223
1241
  operator: "notIn",
1224
1242
  value: t
1225
- }), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
1226
- filters: [...this.filters.values()],
1227
- filteredRowCount: 0
1228
- }), this.requestRender();
1243
+ }), this.applyFiltersInternal();
1229
1244
  }
1230
1245
  /**
1231
1246
  * Apply a text filter
@@ -1237,8 +1252,28 @@ class A extends x {
1237
1252
  operator: t,
1238
1253
  value: n,
1239
1254
  valueTo: o
1240
- }), this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
1241
- filters: [...this.filters.values()],
1255
+ }), this.applyFiltersInternal();
1256
+ }
1257
+ /**
1258
+ * Internal method to apply filters (sync or async based on config)
1259
+ */
1260
+ applyFiltersInternal() {
1261
+ this.cachedResult = null, this.cacheKey = null;
1262
+ const e = [...this.filters.values()];
1263
+ if (this.config.filterHandler) {
1264
+ const t = this.grid;
1265
+ t.setAttribute("aria-busy", "true");
1266
+ const n = this.config.filterHandler(e, this.sourceRows), o = (i) => {
1267
+ t.removeAttribute("aria-busy"), this.cachedResult = i, this.grid.rows = i, this.emit("filter-change", {
1268
+ filters: e,
1269
+ filteredRowCount: i.length
1270
+ }), this.requestRender();
1271
+ };
1272
+ n && typeof n.then == "function" ? n.then(o) : o(n);
1273
+ return;
1274
+ }
1275
+ this.emit("filter-change", {
1276
+ filters: e,
1242
1277
  filteredRowCount: 0
1243
1278
  }), this.requestRender();
1244
1279
  }
@@ -1278,31 +1313,31 @@ class A extends x {
1278
1313
  }
1279
1314
  // #endregion
1280
1315
  // #region Styles
1281
- styles = ot;
1316
+ styles = it;
1282
1317
  // #endregion
1283
1318
  }
1284
- function rt(r) {
1285
- if (!r.length) return [];
1286
- const e = /* @__PURE__ */ new Map(), t = [], n = (s, l) => {
1319
+ function st(s) {
1320
+ if (!s.length) return [];
1321
+ const e = /* @__PURE__ */ new Map(), t = [], n = (r, l) => {
1287
1322
  if (!l.length) return;
1288
1323
  const a = t[t.length - 1];
1289
- if (a && a.implicit && a.firstIndex + a.columns.length === s) {
1324
+ if (a && a.implicit && a.firstIndex + a.columns.length === r) {
1290
1325
  a.columns.push(...l);
1291
1326
  return;
1292
1327
  }
1293
1328
  t.push({
1294
- id: "__implicit__" + s,
1329
+ id: "__implicit__" + r,
1295
1330
  label: void 0,
1296
1331
  columns: l,
1297
- firstIndex: s,
1332
+ firstIndex: r,
1298
1333
  implicit: !0
1299
1334
  });
1300
1335
  };
1301
1336
  let o = [], i = 0;
1302
- return r.forEach((s, l) => {
1303
- const a = s.group;
1337
+ return s.forEach((r, l) => {
1338
+ const a = r.group;
1304
1339
  if (!a) {
1305
- o.length === 0 && (i = l), o.push(s);
1340
+ o.length === 0 && (i = l), o.push(r);
1306
1341
  return;
1307
1342
  }
1308
1343
  o.length && (n(i, o.slice()), o = []);
@@ -1313,40 +1348,40 @@ function rt(r) {
1313
1348
  label: typeof a == "string" ? void 0 : a.label,
1314
1349
  columns: [],
1315
1350
  firstIndex: l
1316
- }, e.set(d, c), t.push(c)), c.columns.push(s);
1317
- }), o.length && n(i, o), t.length === 1 && t[0].implicit && t[0].columns.length === r.length ? [] : t;
1351
+ }, e.set(d, c), t.push(c)), c.columns.push(r);
1352
+ }), o.length && n(i, o), t.length === 1 && t[0].implicit && t[0].columns.length === s.length ? [] : t;
1318
1353
  }
1319
- function st(r, e, t) {
1320
- if (!e.length || !r) return;
1354
+ function lt(s, e, t) {
1355
+ if (!e.length || !s) return;
1321
1356
  const n = /* @__PURE__ */ new Map();
1322
1357
  for (const i of e)
1323
- for (const s of i.columns)
1324
- s?.field && n.set(s.field, i.id);
1325
- const o = Array.from(r.querySelectorAll(".cell[data-field]"));
1358
+ for (const r of i.columns)
1359
+ r?.field && n.set(r.field, i.id);
1360
+ const o = Array.from(s.querySelectorAll(".cell[data-field]"));
1326
1361
  o.forEach((i) => {
1327
- const s = i.getAttribute("data-field") || "", l = n.get(s);
1362
+ const r = i.getAttribute("data-field") || "", l = n.get(r);
1328
1363
  l && (i.classList.add("grouped"), i.getAttribute("data-group") || i.setAttribute("data-group", l));
1329
1364
  });
1330
1365
  for (const i of e) {
1331
- const s = i.columns[i.columns.length - 1], l = o.find((a) => a.getAttribute("data-field") === s.field);
1366
+ const r = i.columns[i.columns.length - 1], l = o.find((a) => a.getAttribute("data-field") === r.field);
1332
1367
  l && l.classList.add("group-end");
1333
1368
  }
1334
1369
  }
1335
- function lt(r, e) {
1336
- if (r.length === 0) return null;
1370
+ function at(s, e) {
1371
+ if (s.length === 0) return null;
1337
1372
  const t = document.createElement("div");
1338
1373
  t.className = "header-group-row", t.setAttribute("role", "row");
1339
- for (const n of r) {
1340
- const o = n.firstIndex != null ? n.firstIndex : e.findIndex((a) => n.columns.includes(a)), i = String(n.id).startsWith("__implicit__"), s = i ? "" : n.label || n.id, l = document.createElement("div");
1341
- l.className = "cell header-group-cell", i && l.classList.add("implicit-group"), l.setAttribute("data-group", String(n.id)), l.style.gridColumn = `${o + 1} / span ${n.columns.length}`, l.textContent = s, t.appendChild(l);
1374
+ for (const n of s) {
1375
+ const o = n.firstIndex != null ? n.firstIndex : e.findIndex((a) => n.columns.includes(a)), i = String(n.id).startsWith("__implicit__"), r = i ? "" : n.label || n.id, l = document.createElement("div");
1376
+ l.className = "cell header-group-cell", i && l.classList.add("implicit-group"), l.setAttribute("data-group", String(n.id)), l.style.gridColumn = `${o + 1} / span ${n.columns.length}`, l.textContent = r, t.appendChild(l);
1342
1377
  }
1343
1378
  return t;
1344
1379
  }
1345
- function at(r) {
1346
- return r.some((e) => e.group != null);
1380
+ function dt(s) {
1381
+ return s.some((e) => e.group != null);
1347
1382
  }
1348
- const dt = ".header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:4px 8px;font-weight:600;font-size:.9em;text-transform:uppercase;letter-spacing:.5px;border-right:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong))}";
1349
- class yn extends x {
1383
+ const ct = ".header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:4px 8px;font-weight:600;font-size:.9em;text-transform:uppercase;letter-spacing:.5px;border-right:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong))}.header-row .cell.group-end:last-child{border-right:none}.header-group-row.no-borders{border-bottom:none}.header-group-row.no-borders .header-group-cell{border-right:none}.header-row.no-group-borders .cell.group-end{border-right:1px solid var(--tbw-color-border)}";
1384
+ class Cn extends v {
1350
1385
  name = "groupingColumns";
1351
1386
  version = "1.0.0";
1352
1387
  get defaultConfig() {
@@ -1369,31 +1404,32 @@ class yn extends x {
1369
1404
  */
1370
1405
  static detect(e, t) {
1371
1406
  const n = t?.columns;
1372
- return Array.isArray(n) ? at(n) : !1;
1407
+ return Array.isArray(n) ? dt(n) : !1;
1373
1408
  }
1374
1409
  // #endregion
1375
1410
  // #region Hooks
1376
1411
  processColumns(e) {
1377
- const t = rt(e);
1412
+ const t = st(e);
1378
1413
  return t.length === 0 ? (this.isActive = !1, this.groups = [], [...e]) : (this.isActive = !0, this.groups = t, [...e]);
1379
1414
  }
1380
1415
  afterRender() {
1381
1416
  if (!this.isActive || this.groups.length === 0) {
1382
- const s = this.shadowRoot?.querySelector(".header")?.querySelector(".header-group-row");
1383
- s && s.remove();
1417
+ const r = this.shadowRoot?.querySelector(".header")?.querySelector(".header-group-row");
1418
+ r && r.remove();
1384
1419
  return;
1385
1420
  }
1386
1421
  const e = this.shadowRoot?.querySelector(".header");
1387
1422
  if (!e) return;
1388
1423
  const t = e.querySelector(".header-group-row");
1389
1424
  t && t.remove();
1390
- const n = lt(this.groups, this.columns);
1425
+ const n = at(this.groups, this.columns);
1391
1426
  if (n) {
1427
+ n.classList.toggle("no-borders", !this.config.showGroupBorders);
1392
1428
  const i = e.querySelector(".header-row");
1393
1429
  i ? e.insertBefore(n, i) : e.appendChild(n);
1394
1430
  }
1395
1431
  const o = e.querySelector(".header-row");
1396
- o && st(o, this.groups, this.columns);
1432
+ o && (o.classList.toggle("no-group-borders", !this.config.showGroupBorders), lt(o, this.groups, this.columns));
1397
1433
  }
1398
1434
  // #endregion
1399
1435
  // #region Public API
@@ -1428,28 +1464,28 @@ class yn extends x {
1428
1464
  }
1429
1465
  // #endregion
1430
1466
  // #region Styles
1431
- styles = dt;
1467
+ styles = ct;
1432
1468
  // #endregion
1433
1469
  }
1434
- function ct({ rows: r, config: e, expanded: t }) {
1470
+ function ut({ rows: s, config: e, expanded: t }) {
1435
1471
  const n = e.groupOn;
1436
1472
  if (typeof n != "function")
1437
1473
  return [];
1438
1474
  const o = { key: "__root__", value: null, depth: -1, rows: [], children: /* @__PURE__ */ new Map() };
1439
- if (r.forEach((l) => {
1475
+ if (s.forEach((l) => {
1440
1476
  let a = n(l);
1441
1477
  a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
1442
1478
  let d = o;
1443
1479
  a.forEach((c, u) => {
1444
1480
  const h = c == null ? "∅" : String(c), g = d.key === "__root__" ? h : d.key + "||" + h;
1445
- let p = d.children.get(h);
1446
- p || (p = { key: g, value: c, depth: u, rows: [], children: /* @__PURE__ */ new Map(), parent: d }, d.children.set(h, p)), d = p;
1481
+ let f = d.children.get(h);
1482
+ f || (f = { key: g, value: c, depth: u, rows: [], children: /* @__PURE__ */ new Map(), parent: d }, d.children.set(h, f)), d = f;
1447
1483
  }), d.rows.push(l);
1448
- }), o.children.size === 1 && o.children.has("__ungrouped__") && o.children.get("__ungrouped__").rows.length === r.length)
1484
+ }), o.children.size === 1 && o.children.has("__ungrouped__") && o.children.get("__ungrouped__").rows.length === s.length)
1449
1485
  return [];
1450
- const i = [], s = (l) => {
1486
+ const i = [], r = (l) => {
1451
1487
  if (l === o) {
1452
- l.children.forEach((d) => s(d));
1488
+ l.children.forEach((d) => r(d));
1453
1489
  return;
1454
1490
  }
1455
1491
  const a = t.has(l.key);
@@ -1460,28 +1496,28 @@ function ct({ rows: r, config: e, expanded: t }) {
1460
1496
  depth: l.depth,
1461
1497
  rows: l.rows,
1462
1498
  expanded: a
1463
- }), a && (l.children.size ? l.children.forEach((d) => s(d)) : l.rows.forEach((d) => i.push({ kind: "data", row: d, rowIndex: r.indexOf(d) })));
1499
+ }), a && (l.children.size ? l.children.forEach((d) => r(d)) : l.rows.forEach((d) => i.push({ kind: "data", row: d, rowIndex: s.indexOf(d) })));
1464
1500
  };
1465
- return s(o), i;
1501
+ return r(o), i;
1466
1502
  }
1467
- function ut(r, e) {
1468
- const t = new Set(r);
1503
+ function ht(s, e) {
1504
+ const t = new Set(s);
1469
1505
  return t.has(e) ? t.delete(e) : t.add(e), t;
1470
1506
  }
1471
- function ht(r) {
1507
+ function gt(s) {
1472
1508
  const e = /* @__PURE__ */ new Set();
1473
- for (const t of r)
1509
+ for (const t of s)
1474
1510
  t.kind === "group" && e.add(t.key);
1475
1511
  return e;
1476
1512
  }
1477
- function gt() {
1513
+ function ft() {
1478
1514
  return /* @__PURE__ */ new Set();
1479
1515
  }
1480
- function pt(r) {
1481
- return r.kind !== "group" ? 0 : r.rows.length;
1516
+ function pt(s) {
1517
+ return s.kind !== "group" ? 0 : s.rows.length;
1482
1518
  }
1483
- const ft = '.group-row{background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500}.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}.group-toggle{cursor:pointer;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px;font-size:10px}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:2px}.group-label{display:inline-flex;align-items:center;gap:8px}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:.85em;font-weight:400}[data-group-depth="0"] .group-label{padding-left:0}[data-group-depth="1"] .group-label{padding-left:20px}[data-group-depth="2"] .group-label{padding-left:40px}[data-group-depth="3"] .group-label{padding-left:60px}[data-group-depth="4"] .group-label{padding-left:80px}';
1484
- class Cn extends x {
1519
+ const mt = '.group-row{background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500}.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}.group-toggle{cursor:pointer;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:2px}.group-label{display:inline-flex;align-items:center;gap:8px}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:.85em;font-weight:400}[data-group-depth="0"] .group-label{padding-left:0}[data-group-depth="1"] .group-label{padding-left:20px}[data-group-depth="2"] .group-label{padding-left:40px}[data-group-depth="3"] .group-label{padding-left:60px}[data-group-depth="4"] .group-label{padding-left:80px}.data-grid-row.tbw-group-slide-in{animation:tbw-group-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-group-fade-in{animation:tbw-group-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-fade-in{0%{opacity:0}to{opacity:1}}';
1520
+ class Rn extends v {
1485
1521
  name = "groupingRows";
1486
1522
  version = "1.0.0";
1487
1523
  get defaultConfig() {
@@ -1489,17 +1525,32 @@ class Cn extends x {
1489
1525
  defaultExpanded: !1,
1490
1526
  showRowCount: !0,
1491
1527
  indentWidth: 20,
1492
- aggregators: {}
1528
+ aggregators: {},
1529
+ animation: "slide"
1493
1530
  };
1494
1531
  }
1495
1532
  // #region Internal State
1496
1533
  expandedKeys = /* @__PURE__ */ new Set();
1497
1534
  flattenedRows = [];
1498
1535
  isActive = !1;
1536
+ previousVisibleKeys = /* @__PURE__ */ new Set();
1537
+ keysToAnimate = /* @__PURE__ */ new Set();
1538
+ // #endregion
1539
+ // #region Animation
1540
+ get animationStyle() {
1541
+ const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
1542
+ if (t === !1 || t === "off") return !1;
1543
+ if (t !== !0 && t !== "on") {
1544
+ const n = this.shadowRoot?.host;
1545
+ if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
1546
+ return !1;
1547
+ }
1548
+ return this.config.animation ?? "slide";
1549
+ }
1499
1550
  // #endregion
1500
1551
  // #region Lifecycle
1501
1552
  detach() {
1502
- this.expandedKeys.clear(), this.flattenedRows = [], this.isActive = !1;
1553
+ this.expandedKeys.clear(), this.flattenedRows = [], this.isActive = !1, this.previousVisibleKeys.clear(), this.keysToAnimate.clear();
1503
1554
  }
1504
1555
  // #endregion
1505
1556
  // #region Hooks
@@ -1514,20 +1565,29 @@ class Cn extends x {
1514
1565
  const t = this.config;
1515
1566
  if (typeof t.groupOn != "function")
1516
1567
  return this.isActive = !1, this.flattenedRows = [], [...e];
1517
- const n = ct({
1568
+ const n = ut({
1518
1569
  rows: e,
1519
1570
  config: t,
1520
1571
  expanded: this.expandedKeys
1521
1572
  });
1522
- return n.length === 0 ? (this.isActive = !1, this.flattenedRows = [], [...e]) : (this.isActive = !0, this.flattenedRows = n, n.map((o) => o.kind === "group" ? {
1573
+ if (n.length === 0)
1574
+ return this.isActive = !1, this.flattenedRows = [], [...e];
1575
+ this.isActive = !0, this.flattenedRows = n, this.keysToAnimate.clear();
1576
+ const o = /* @__PURE__ */ new Set();
1577
+ return n.forEach((i, r) => {
1578
+ if (i.kind === "data") {
1579
+ const l = `data-${r}`;
1580
+ o.add(l), this.previousVisibleKeys.has(l) || this.keysToAnimate.add(l);
1581
+ }
1582
+ }), this.previousVisibleKeys = o, n.map((i) => i.kind === "group" ? {
1523
1583
  __isGroupRow: !0,
1524
- __groupKey: o.key,
1525
- __groupValue: o.value,
1526
- __groupDepth: o.depth,
1527
- __groupRows: o.rows,
1528
- __groupExpanded: o.expanded,
1529
- __groupRowCount: pt(o)
1530
- } : o.row));
1584
+ __groupKey: i.key,
1585
+ __groupValue: i.value,
1586
+ __groupDepth: i.depth,
1587
+ __groupRows: i.rows,
1588
+ __groupExpanded: i.expanded,
1589
+ __groupRowCount: pt(i)
1590
+ } : i.row);
1531
1591
  }
1532
1592
  onCellClick(e) {
1533
1593
  const t = e.row;
@@ -1561,16 +1621,26 @@ class Cn extends x {
1561
1621
  return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), t.setAttribute("role", "row"), t.setAttribute("aria-expanded", String(e.__groupExpanded)), t.style.paddingLeft = `${(e.__groupDepth || 0) * (o.indentWidth ?? 20)}px`, t.innerHTML = "", o.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, i) : this.renderPerColumnGroupRow(e, t, i), !0;
1562
1622
  }
1563
1623
  afterRender() {
1624
+ const e = this.animationStyle;
1625
+ if (e === !1 || this.keysToAnimate.size === 0) return;
1626
+ const t = this.shadowRoot?.querySelector(".rows");
1627
+ if (!t) return;
1628
+ const n = e === "fade" ? "tbw-group-fade-in" : "tbw-group-slide-in";
1629
+ for (const o of t.querySelectorAll(".data-grid-row:not(.group-row)")) {
1630
+ const i = o.querySelector(".cell[data-row]"), r = i ? parseInt(i.getAttribute("data-row") ?? "-1", 10) : -1, a = this.flattenedRows[r]?.kind === "data" ? `data-${r}` : void 0;
1631
+ a && this.keysToAnimate.has(a) && (o.classList.add(n), o.addEventListener("animationend", () => o.classList.remove(n), { once: !0 }));
1632
+ }
1633
+ this.keysToAnimate.clear();
1564
1634
  }
1565
1635
  // #endregion
1566
1636
  // #region Private Rendering Helpers
1567
1637
  renderFullWidthGroupRow(e, t, n) {
1568
1638
  const o = this.config, i = document.createElement("div");
1569
1639
  i.className = "cell group-full", i.style.gridColumn = "1 / -1", i.setAttribute("role", "gridcell");
1570
- const s = document.createElement("button");
1571
- s.type = "button", s.className = "group-toggle", s.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(s, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), s.addEventListener("click", (d) => {
1640
+ const r = document.createElement("button");
1641
+ r.type = "button", r.className = `group-toggle${e.__groupExpanded ? " expanded" : ""}`, r.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(r, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), r.addEventListener("click", (d) => {
1572
1642
  d.stopPropagation(), n();
1573
- }), i.appendChild(s);
1643
+ }), i.appendChild(r);
1574
1644
  const l = document.createElement("span");
1575
1645
  l.className = "group-label";
1576
1646
  const a = o.formatLabel ? o.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
@@ -1581,31 +1651,31 @@ class Cn extends x {
1581
1651
  t.appendChild(i);
1582
1652
  }
1583
1653
  renderPerColumnGroupRow(e, t, n) {
1584
- const o = this.config, i = o.aggregators ?? {}, s = this.columns, l = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
1585
- d && (t.style.display = "grid", t.style.gridTemplateColumns = d), s.forEach((c, u) => {
1654
+ const o = this.config, i = o.aggregators ?? {}, r = this.columns, l = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
1655
+ d && (t.style.display = "grid", t.style.gridTemplateColumns = d), r.forEach((c, u) => {
1586
1656
  const h = document.createElement("div");
1587
1657
  if (h.className = "cell group-cell", h.setAttribute("data-col", String(u)), h.setAttribute("role", "gridcell"), u === 0) {
1588
1658
  const g = document.createElement("button");
1589
- g.type = "button", g.className = "group-toggle", g.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(g, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), g.addEventListener("click", (m) => {
1590
- m.stopPropagation(), n();
1659
+ g.type = "button", g.className = `group-toggle${e.__groupExpanded ? " expanded" : ""}`, g.setAttribute("aria-label", e.__groupExpanded ? "Collapse group" : "Expand group"), this.setIcon(g, this.resolveIcon(e.__groupExpanded ? "collapse" : "expand")), g.addEventListener("click", (p) => {
1660
+ p.stopPropagation(), n();
1591
1661
  }), h.appendChild(g);
1592
- const p = document.createElement("span"), f = i[c.field];
1593
- if (f) {
1594
- const m = se(f, l, c.field, c);
1595
- p.textContent = m != null ? String(m) : String(e.__groupValue);
1662
+ const f = document.createElement("span"), m = i[c.field];
1663
+ if (m) {
1664
+ const p = se(m, l, c.field, c);
1665
+ f.textContent = p != null ? String(p) : String(e.__groupValue);
1596
1666
  } else {
1597
- const m = o.formatLabel ? o.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
1598
- p.textContent = m;
1667
+ const p = o.formatLabel ? o.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
1668
+ f.textContent = p;
1599
1669
  }
1600
- if (h.appendChild(p), o.showRowCount !== !1) {
1601
- const m = document.createElement("span");
1602
- m.className = "group-count", m.textContent = ` (${l.length})`, h.appendChild(m);
1670
+ if (h.appendChild(f), o.showRowCount !== !1) {
1671
+ const p = document.createElement("span");
1672
+ p.className = "group-count", p.textContent = ` (${l.length})`, h.appendChild(p);
1603
1673
  }
1604
1674
  } else {
1605
1675
  const g = i[c.field];
1606
1676
  if (g) {
1607
- const p = se(g, l, c.field, c);
1608
- h.textContent = p != null ? String(p) : "";
1677
+ const f = se(g, l, c.field, c);
1678
+ h.textContent = f != null ? String(f) : "";
1609
1679
  } else
1610
1680
  h.textContent = "";
1611
1681
  }
@@ -1618,20 +1688,20 @@ class Cn extends x {
1618
1688
  * Expand all groups.
1619
1689
  */
1620
1690
  expandAll() {
1621
- this.expandedKeys = ht(this.flattenedRows), this.requestRender();
1691
+ this.expandedKeys = gt(this.flattenedRows), this.requestRender();
1622
1692
  }
1623
1693
  /**
1624
1694
  * Collapse all groups.
1625
1695
  */
1626
1696
  collapseAll() {
1627
- this.expandedKeys = gt(), this.requestRender();
1697
+ this.expandedKeys = ft(), this.requestRender();
1628
1698
  }
1629
1699
  /**
1630
1700
  * Toggle expansion of a specific group.
1631
1701
  * @param key - The group key to toggle
1632
1702
  */
1633
1703
  toggle(e) {
1634
- this.expandedKeys = ut(this.expandedKeys, e);
1704
+ this.expandedKeys = ht(this.expandedKeys, e);
1635
1705
  const t = this.flattenedRows.find((n) => n.kind === "group" && n.key === e);
1636
1706
  this.emit("group-toggle", {
1637
1707
  key: e,
@@ -1722,34 +1792,34 @@ class Cn extends x {
1722
1792
  }
1723
1793
  // #endregion
1724
1794
  // #region Styles
1725
- styles = ft;
1795
+ styles = mt;
1726
1796
  // #endregion
1727
1797
  }
1728
- function V(r, e) {
1729
- const t = new Set(r);
1798
+ function z(s, e) {
1799
+ const t = new Set(s);
1730
1800
  return t.has(e) ? t.delete(e) : t.add(e), t;
1731
1801
  }
1732
- function mt(r, e) {
1733
- const t = new Set(r);
1802
+ function wt(s, e) {
1803
+ const t = new Set(s);
1734
1804
  return t.add(e), t;
1735
1805
  }
1736
- function wt(r, e) {
1737
- const t = new Set(r);
1806
+ function bt(s, e) {
1807
+ const t = new Set(s);
1738
1808
  return t.delete(e), t;
1739
1809
  }
1740
- function bt(r, e) {
1741
- return r.has(e);
1810
+ function vt(s, e) {
1811
+ return s.has(e);
1742
1812
  }
1743
- function vt(r, e, t, n) {
1813
+ function xt(s, e, t, n) {
1744
1814
  const o = document.createElement("div");
1745
1815
  o.className = "master-detail-row", o.setAttribute("data-detail-for", String(e)), o.setAttribute("role", "row");
1746
1816
  const i = document.createElement("div");
1747
1817
  i.className = "master-detail-cell", i.setAttribute("role", "cell"), i.style.gridColumn = `1 / ${n + 1}`;
1748
- const s = t(r, e);
1749
- return typeof s == "string" ? i.innerHTML = s : s instanceof HTMLElement && i.appendChild(s), o.appendChild(i), o;
1818
+ const r = t(s, e);
1819
+ return typeof r == "string" ? i.innerHTML = r : r instanceof HTMLElement && i.appendChild(r), o.appendChild(i), o;
1750
1820
  }
1751
- const xt = ".master-detail-cell-wrapper{display:flex;align-items:center;gap:4px}.master-detail-toggle{cursor:pointer;font-size:10px;opacity:.7;user-select:none}.master-detail-toggle:hover{opacity:1}.master-detail-row{grid-column:1 / -1;display:grid;background:var(--tbw-master-detail-bg, var(--tbw-color-row-alt));border-bottom:1px solid var(--tbw-master-detail-border, var(--tbw-color-border))}.master-detail-cell{padding:16px;overflow:auto}";
1752
- class Rn extends x {
1821
+ const yt = ".master-detail-cell-wrapper{display:flex;align-items:center;gap:4px}.master-detail-toggle{cursor:pointer;opacity:.7;user-select:none;display:inline-flex;align-items:center;justify-content:center}.master-detail-toggle:hover{opacity:1}.master-detail-row{grid-column:1 / -1;display:grid;background:var(--tbw-master-detail-bg, var(--tbw-color-row-alt));border-bottom:1px solid var(--tbw-master-detail-border, var(--tbw-color-border));overflow:hidden}.master-detail-cell{padding:16px;overflow:auto}.master-detail-row.tbw-expanding{animation:tbw-detail-expand var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}.master-detail-row.tbw-collapsing{animation:tbw-detail-collapse var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-detail-expand{0%{opacity:0;max-height:0;padding-top:0;padding-bottom:0}to{opacity:1;max-height:500px;padding-top:16px;padding-bottom:16px}}@keyframes tbw-detail-collapse{0%{opacity:1;max-height:500px}to{opacity:0;max-height:0}}";
1822
+ class Sn extends v {
1753
1823
  name = "masterDetail";
1754
1824
  version = "1.0.0";
1755
1825
  get defaultConfig() {
@@ -1757,9 +1827,67 @@ class Rn extends x {
1757
1827
  detailHeight: "auto",
1758
1828
  expandOnRowClick: !1,
1759
1829
  collapseOnClickOutside: !1,
1760
- showExpandColumn: !0
1830
+ showExpandColumn: !0,
1831
+ animation: "slide"
1832
+ // Plugin's own default
1761
1833
  };
1762
1834
  }
1835
+ // #region Animation Helpers
1836
+ /**
1837
+ * Check if animations are enabled at the grid level.
1838
+ * Respects gridConfig.animation.mode and CSS variable.
1839
+ */
1840
+ get isAnimationEnabled() {
1841
+ const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
1842
+ if (t === !1 || t === "off") return !1;
1843
+ if (t === !0 || t === "on") return !0;
1844
+ const n = this.shadowRoot?.host;
1845
+ return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
1846
+ }
1847
+ /**
1848
+ * Get expand/collapse animation style from plugin config.
1849
+ */
1850
+ get animationStyle() {
1851
+ return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
1852
+ }
1853
+ /**
1854
+ * Get animation duration from CSS variable (set by grid).
1855
+ */
1856
+ get animationDuration() {
1857
+ const e = this.shadowRoot?.host;
1858
+ if (e) {
1859
+ const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
1860
+ if (!isNaN(n)) return n;
1861
+ }
1862
+ return 200;
1863
+ }
1864
+ /**
1865
+ * Apply expand animation to a detail element.
1866
+ */
1867
+ animateExpand(e) {
1868
+ !this.isAnimationEnabled || this.animationStyle === !1 || (e.classList.add("tbw-expanding"), e.addEventListener(
1869
+ "animationend",
1870
+ () => {
1871
+ e.classList.remove("tbw-expanding");
1872
+ },
1873
+ { once: !0 }
1874
+ ));
1875
+ }
1876
+ /**
1877
+ * Apply collapse animation to a detail element and remove after animation.
1878
+ */
1879
+ animateCollapse(e, t) {
1880
+ if (!this.isAnimationEnabled || this.animationStyle === !1) {
1881
+ t();
1882
+ return;
1883
+ }
1884
+ e.classList.add("tbw-collapsing");
1885
+ const n = () => {
1886
+ e.classList.remove("tbw-collapsing"), t();
1887
+ };
1888
+ e.addEventListener("animationend", n, { once: !0 }), setTimeout(n, this.animationDuration + 50);
1889
+ }
1890
+ // #endregion
1763
1891
  // #region Internal State
1764
1892
  expandedRows = /* @__PURE__ */ new Set();
1765
1893
  detailElements = /* @__PURE__ */ new Map();
@@ -1778,22 +1906,22 @@ class Rn extends x {
1778
1906
  const n = { ...t[0] }, o = n.viewRenderer;
1779
1907
  if (o?.__masterDetailWrapped)
1780
1908
  return t;
1781
- const i = (s) => {
1782
- const { value: l, row: a } = s, d = this.expandedRows.has(a), c = document.createElement("span");
1909
+ const i = (r) => {
1910
+ const { value: l, row: a } = r, d = this.expandedRows.has(a), c = document.createElement("span");
1783
1911
  c.className = "master-detail-cell-wrapper";
1784
1912
  const u = document.createElement("span");
1785
- u.className = "master-detail-toggle", this.setIcon(u, this.resolveIcon(d ? "collapse" : "expand")), u.setAttribute("role", "button"), u.setAttribute("tabindex", "0"), u.setAttribute("aria-expanded", String(d)), u.setAttribute("aria-label", d ? "Collapse details" : "Expand details"), u.addEventListener("click", (g) => {
1913
+ u.className = `master-detail-toggle${d ? " expanded" : ""}`, this.setIcon(u, this.resolveIcon(d ? "collapse" : "expand")), u.setAttribute("role", "button"), u.setAttribute("tabindex", "0"), u.setAttribute("aria-expanded", String(d)), u.setAttribute("aria-label", d ? "Collapse details" : "Expand details"), u.addEventListener("click", (g) => {
1786
1914
  g.stopPropagation();
1787
- const p = this.rows.indexOf(a);
1788
- this.expandedRows = V(this.expandedRows, a), this.emit("detail-expand", {
1789
- rowIndex: p,
1915
+ const f = this.rows.indexOf(a);
1916
+ this.expandedRows = z(this.expandedRows, a), this.emit("detail-expand", {
1917
+ rowIndex: f,
1790
1918
  row: a,
1791
1919
  expanded: this.expandedRows.has(a)
1792
1920
  }), this.requestRender();
1793
1921
  }), c.appendChild(u);
1794
1922
  const h = document.createElement("span");
1795
1923
  if (o) {
1796
- const g = o(s);
1924
+ const g = o(r);
1797
1925
  g instanceof Node ? h.appendChild(g) : h.textContent = String(g ?? l ?? "");
1798
1926
  } else
1799
1927
  h.textContent = String(l ?? "");
@@ -1805,7 +1933,7 @@ class Rn extends x {
1805
1933
  }
1806
1934
  onRowClick(e) {
1807
1935
  if (!(!this.config.expandOnRowClick || !this.config.detailRenderer))
1808
- return this.expandedRows = V(this.expandedRows, e.row), this.emit("detail-expand", {
1936
+ return this.expandedRows = z(this.expandedRows, e.row), this.emit("detail-expand", {
1809
1937
  rowIndex: e.rowIndex,
1810
1938
  row: e.row,
1811
1939
  expanded: this.expandedRows.has(e.row)
@@ -1833,25 +1961,25 @@ class Rn extends x {
1833
1961
  const e = this.shadowRoot?.querySelector(".rows");
1834
1962
  if (!e) return;
1835
1963
  const t = /* @__PURE__ */ new Map(), n = e.querySelectorAll(".data-grid-row"), o = this.columns.length;
1836
- for (const s of n) {
1837
- const l = s.querySelector(".cell[data-row]"), a = l ? parseInt(l.getAttribute("data-row") ?? "-1", 10) : -1;
1838
- a >= 0 && t.set(a, s);
1964
+ for (const r of n) {
1965
+ const l = r.querySelector(".cell[data-row]"), a = l ? parseInt(l.getAttribute("data-row") ?? "-1", 10) : -1;
1966
+ a >= 0 && t.set(a, r);
1839
1967
  }
1840
1968
  const i = e.querySelectorAll(".master-detail-row");
1841
- for (const s of i) {
1842
- const l = parseInt(s.getAttribute("data-detail-for") ?? "-1", 10), a = l >= 0 ? this.rows[l] : void 0, d = a && this.expandedRows.has(a), c = t.has(l);
1843
- (!d || !c) && (s.remove(), a && this.detailElements.delete(a));
1969
+ for (const r of i) {
1970
+ const l = parseInt(r.getAttribute("data-detail-for") ?? "-1", 10), a = l >= 0 ? this.rows[l] : void 0, d = a && this.expandedRows.has(a), c = t.has(l);
1971
+ (!d || !c) && (r.remove(), a && this.detailElements.delete(a));
1844
1972
  }
1845
- for (const [s, l] of t) {
1846
- const a = this.rows[s];
1973
+ for (const [r, l] of t) {
1974
+ const a = this.rows[r];
1847
1975
  if (!a || !this.expandedRows.has(a)) continue;
1848
1976
  const d = this.detailElements.get(a);
1849
1977
  if (d) {
1850
1978
  d.previousElementSibling !== l && l.after(d);
1851
1979
  continue;
1852
1980
  }
1853
- const c = vt(a, s, this.config.detailRenderer, o);
1854
- typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c);
1981
+ const c = xt(a, r, this.config.detailRenderer, o);
1982
+ typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c), this.animateExpand(c);
1855
1983
  }
1856
1984
  }
1857
1985
  /**
@@ -1884,8 +2012,8 @@ class Rn extends x {
1884
2012
  if (i)
1885
2013
  t += i.offsetHeight;
1886
2014
  else {
1887
- const s = this.config?.detailHeight;
1888
- t += typeof s == "number" ? s : 150;
2015
+ const r = this.config?.detailHeight;
2016
+ t += typeof r == "number" ? r : 150;
1889
2017
  }
1890
2018
  }
1891
2019
  }
@@ -1903,10 +2031,10 @@ class Rn extends x {
1903
2031
  a >= 0 && o.push({ index: a, row: l });
1904
2032
  }
1905
2033
  o.sort((l, a) => l.index - a.index);
1906
- let i = e, s = 0;
2034
+ let i = e, r = 0;
1907
2035
  for (const { index: l, row: a } of o) {
1908
- const d = l * n + s, u = this.detailElements.get(a)?.offsetHeight ?? (typeof this.config?.detailHeight == "number" ? this.config.detailHeight : 150), h = d + n + u;
1909
- s += u, !(l >= e) && h > t && l < i && (i = l);
2036
+ const d = l * n + r, u = this.detailElements.get(a)?.offsetHeight ?? (typeof this.config?.detailHeight == "number" ? this.config.detailHeight : 150), h = d + n + u;
2037
+ r += u, !(l >= e) && h > t && l < i && (i = l);
1910
2038
  }
1911
2039
  return i;
1912
2040
  }
@@ -1918,7 +2046,7 @@ class Rn extends x {
1918
2046
  */
1919
2047
  expand(e) {
1920
2048
  const t = this.rows[e];
1921
- t && (this.expandedRows = mt(this.expandedRows, t), this.requestRender());
2049
+ t && (this.expandedRows = wt(this.expandedRows, t), this.requestRender());
1922
2050
  }
1923
2051
  /**
1924
2052
  * Collapse the detail row at the given index.
@@ -1926,7 +2054,7 @@ class Rn extends x {
1926
2054
  */
1927
2055
  collapse(e) {
1928
2056
  const t = this.rows[e];
1929
- t && (this.expandedRows = wt(this.expandedRows, t), this.requestRender());
2057
+ t && (this.expandedRows = bt(this.expandedRows, t), this.requestRender());
1930
2058
  }
1931
2059
  /**
1932
2060
  * Toggle the detail row at the given index.
@@ -1934,7 +2062,7 @@ class Rn extends x {
1934
2062
  */
1935
2063
  toggle(e) {
1936
2064
  const t = this.rows[e];
1937
- t && (this.expandedRows = V(this.expandedRows, t), this.requestRender());
2065
+ t && (this.expandedRows = z(this.expandedRows, t), this.requestRender());
1938
2066
  }
1939
2067
  /**
1940
2068
  * Check if the detail row at the given index is expanded.
@@ -1943,7 +2071,7 @@ class Rn extends x {
1943
2071
  */
1944
2072
  isExpanded(e) {
1945
2073
  const t = this.rows[e];
1946
- return t ? bt(this.expandedRows, t) : !1;
2074
+ return t ? vt(this.expandedRows, t) : !1;
1947
2075
  }
1948
2076
  /**
1949
2077
  * Expand all detail rows.
@@ -1982,35 +2110,35 @@ class Rn extends x {
1982
2110
  }
1983
2111
  // #endregion
1984
2112
  // #region Styles
1985
- styles = xt;
2113
+ styles = yt;
1986
2114
  // #endregion
1987
2115
  }
1988
- function yt(r, e, t) {
1989
- return e.length ? [...r].sort((n, o) => {
2116
+ function Ct(s, e, t) {
2117
+ return e.length ? [...s].sort((n, o) => {
1990
2118
  for (const i of e) {
1991
- const l = t.find((u) => u.field === i.field)?.sortComparator ?? Ct, a = n[i.field], d = o[i.field], c = l(a, d, n, o);
2119
+ const l = t.find((u) => u.field === i.field)?.sortComparator ?? Rt, a = n[i.field], d = o[i.field], c = l(a, d, n, o);
1992
2120
  if (c !== 0)
1993
2121
  return i.direction === "asc" ? c : -c;
1994
2122
  }
1995
2123
  return 0;
1996
- }) : [...r];
2124
+ }) : [...s];
1997
2125
  }
1998
- function Ct(r, e) {
1999
- return r == null && e == null ? 0 : r == null ? 1 : e == null ? -1 : typeof r == "number" && typeof e == "number" ? r - e : r instanceof Date && e instanceof Date ? r.getTime() - e.getTime() : typeof r == "boolean" && typeof e == "boolean" ? r === e ? 0 : r ? -1 : 1 : String(r).localeCompare(String(e));
2126
+ function Rt(s, e) {
2127
+ return s == null && e == null ? 0 : s == null ? 1 : e == null ? -1 : typeof s == "number" && typeof e == "number" ? s - e : s instanceof Date && e instanceof Date ? s.getTime() - e.getTime() : typeof s == "boolean" && typeof e == "boolean" ? s === e ? 0 : s ? -1 : 1 : String(s).localeCompare(String(e));
2000
2128
  }
2001
- function Rt(r, e, t, n) {
2002
- const o = r.find((i) => i.field === e);
2003
- return t ? o ? o.direction === "asc" ? r.map((i) => i.field === e ? { ...i, direction: "desc" } : i) : r.filter((i) => i.field !== e) : r.length < n ? [...r, { field: e, direction: "asc" }] : r : o?.direction === "asc" ? [{ field: e, direction: "desc" }] : o?.direction === "desc" ? [] : [{ field: e, direction: "asc" }];
2129
+ function St(s, e, t, n) {
2130
+ const o = s.find((i) => i.field === e);
2131
+ return t ? o ? o.direction === "asc" ? s.map((i) => i.field === e ? { ...i, direction: "desc" } : i) : s.filter((i) => i.field !== e) : s.length < n ? [...s, { field: e, direction: "asc" }] : s : o?.direction === "asc" ? [{ field: e, direction: "desc" }] : o?.direction === "desc" ? [] : [{ field: e, direction: "asc" }];
2004
2132
  }
2005
- function we(r, e) {
2006
- const t = r.findIndex((n) => n.field === e);
2133
+ function be(s, e) {
2134
+ const t = s.findIndex((n) => n.field === e);
2007
2135
  return t >= 0 ? t + 1 : void 0;
2008
2136
  }
2009
- function be(r, e) {
2010
- return r.find((t) => t.field === e)?.direction;
2137
+ function ve(s, e) {
2138
+ return s.find((t) => t.field === e)?.direction;
2011
2139
  }
2012
- const St = '.header-cell[data-sort=asc]:after{content:"↑";margin-left:4px;opacity:.8}.header-cell[data-sort=desc]:after{content:"↓";margin-left:4px;opacity:.8}.sort-index{font-size:10px;background:var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));color:var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;margin-left:2px;font-weight:600}';
2013
- class Sn extends x {
2140
+ const kt = '.header-cell[data-sort=asc]:after{content:"↑";margin-left:4px;opacity:.8}.header-cell[data-sort=desc]:after{content:"↓";margin-left:4px;opacity:.8}.sort-indicator{margin-left:4px;opacity:.8}.sort-index{font-size:10px;background:var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));color:var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;margin-left:2px;font-weight:600}';
2141
+ class kn extends v {
2014
2142
  name = "multiSort";
2015
2143
  version = "1.0.0";
2016
2144
  get defaultConfig() {
@@ -2029,12 +2157,12 @@ class Sn extends x {
2029
2157
  // #endregion
2030
2158
  // #region Hooks
2031
2159
  processRows(e) {
2032
- return this.sortModel.length === 0 ? [...e] : yt([...e], this.sortModel, [...this.columns]);
2160
+ return this.sortModel.length === 0 ? [...e] : Ct([...e], this.sortModel, [...this.columns]);
2033
2161
  }
2034
2162
  onHeaderClick(e) {
2035
2163
  if (!this.columns.find((i) => i.field === e.field)?.sortable) return !1;
2036
2164
  const n = e.originalEvent.shiftKey, o = this.config.maxSortColumns ?? 3;
2037
- return this.sortModel = Rt(this.sortModel, e.field, n, o), this.emit("sort-change", { sortModel: [...this.sortModel] }), this.requestRender(), !0;
2165
+ return this.sortModel = St(this.sortModel, e.field, n, o), this.emit("sort-change", { sortModel: [...this.sortModel] }), this.requestRender(), !0;
2038
2166
  }
2039
2167
  afterRender() {
2040
2168
  const e = this.shadowRoot;
@@ -2043,13 +2171,13 @@ class Sn extends x {
2043
2171
  e.querySelectorAll(".header-row .cell[data-field]").forEach((o) => {
2044
2172
  const i = o.getAttribute("data-field");
2045
2173
  if (!i) return;
2046
- const s = we(this.sortModel, i), l = be(this.sortModel, i);
2174
+ const r = be(this.sortModel, i), l = ve(this.sortModel, i);
2047
2175
  if (o.querySelector(".sort-index")?.remove(), l) {
2048
2176
  o.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove(), o.setAttribute("data-sort", l);
2049
2177
  const c = document.createElement("span");
2050
- if (c.className = "sort-indicator", c.style.marginLeft = "4px", c.style.opacity = "0.8", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc")), o.appendChild(c), t && this.sortModel.length > 1 && s !== void 0) {
2178
+ if (c.className = "sort-indicator", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc")), o.appendChild(c), t && this.sortModel.length > 1 && r !== void 0) {
2051
2179
  const u = document.createElement("span");
2052
- u.className = "sort-index", u.textContent = String(s), o.appendChild(u);
2180
+ u.className = "sort-index", u.textContent = String(r), o.appendChild(u);
2053
2181
  }
2054
2182
  } else
2055
2183
  o.removeAttribute("data-sort");
@@ -2083,7 +2211,7 @@ class Sn extends x {
2083
2211
  * @returns 1-based index or undefined if not sorted
2084
2212
  */
2085
2213
  getSortIndex(e) {
2086
- return we(this.sortModel, e);
2214
+ return be(this.sortModel, e);
2087
2215
  }
2088
2216
  /**
2089
2217
  * Get the sort direction for a specific field.
@@ -2091,7 +2219,7 @@ class Sn extends x {
2091
2219
  * @returns Sort direction or undefined if not sorted
2092
2220
  */
2093
2221
  getSortDirection(e) {
2094
- return be(this.sortModel, e);
2222
+ return ve(this.sortModel, e);
2095
2223
  }
2096
2224
  // #endregion
2097
2225
  // #region Column State Hooks
@@ -2124,20 +2252,20 @@ class Sn extends x {
2124
2252
  }
2125
2253
  // #endregion
2126
2254
  // #region Styles
2127
- styles = St;
2255
+ styles = kt;
2128
2256
  // #endregion
2129
2257
  }
2130
- function Et(r) {
2131
- return r.filter((e) => e.sticky === "left");
2258
+ function Et(s) {
2259
+ return s.filter((e) => e.sticky === "left");
2132
2260
  }
2133
- function kt(r) {
2134
- return r.filter((e) => e.sticky === "right");
2261
+ function At(s) {
2262
+ return s.filter((e) => e.sticky === "right");
2135
2263
  }
2136
- function z(r) {
2137
- return r.some((e) => e.sticky === "left" || e.sticky === "right");
2264
+ function W(s) {
2265
+ return s.some((e) => e.sticky === "left" || e.sticky === "right");
2138
2266
  }
2139
- function ve(r, e) {
2140
- const t = r.shadowRoot;
2267
+ function xe(s, e) {
2268
+ const t = s.shadowRoot;
2141
2269
  if (!t) return;
2142
2270
  const n = Array.from(t.querySelectorAll(".header-row .cell"));
2143
2271
  if (!n.length) return;
@@ -2153,23 +2281,23 @@ function ve(r, e) {
2153
2281
  c.classList.add("sticky-left"), c.style.position = "sticky", c.style.left = i + "px";
2154
2282
  }), i += d.offsetWidth);
2155
2283
  }
2156
- let s = 0;
2284
+ let r = 0;
2157
2285
  for (const l of [...e].reverse())
2158
2286
  if (l.sticky === "right") {
2159
2287
  const a = o.get(l.field), d = n.find((c) => c.getAttribute("data-field") === l.field);
2160
- d && (d.classList.add("sticky-right"), d.style.position = "sticky", d.style.right = s + "px", a !== void 0 && t.querySelectorAll(`.data-grid-row .cell[data-col="${a}"]`).forEach((c) => {
2161
- c.classList.add("sticky-right"), c.style.position = "sticky", c.style.right = s + "px";
2162
- }), s += d.offsetWidth);
2288
+ d && (d.classList.add("sticky-right"), d.style.position = "sticky", d.style.right = r + "px", a !== void 0 && t.querySelectorAll(`.data-grid-row .cell[data-col="${a}"]`).forEach((c) => {
2289
+ c.classList.add("sticky-right"), c.style.position = "sticky", c.style.right = r + "px";
2290
+ }), r += d.offsetWidth);
2163
2291
  }
2164
2292
  }
2165
- function xe(r) {
2166
- const e = r.shadowRoot;
2293
+ function ye(s) {
2294
+ const e = s.shadowRoot;
2167
2295
  if (!e) return;
2168
2296
  e.querySelectorAll(".sticky-left, .sticky-right").forEach((n) => {
2169
2297
  n.classList.remove("sticky-left", "sticky-right"), n.style.position = "", n.style.left = "", n.style.right = "";
2170
2298
  });
2171
2299
  }
2172
- class En extends x {
2300
+ class En extends v {
2173
2301
  name = "pinnedColumns";
2174
2302
  version = "1.0.0";
2175
2303
  get defaultConfig() {
@@ -2191,23 +2319,23 @@ class En extends x {
2191
2319
  */
2192
2320
  static detect(e, t) {
2193
2321
  const n = t?.columns;
2194
- return Array.isArray(n) ? z(n) : !1;
2322
+ return Array.isArray(n) ? W(n) : !1;
2195
2323
  }
2196
2324
  // #endregion
2197
2325
  // #region Hooks
2198
2326
  processColumns(e) {
2199
- return this.isApplied = z([...e]), [...e];
2327
+ return this.isApplied = W([...e]), [...e];
2200
2328
  }
2201
2329
  afterRender() {
2202
2330
  if (!this.isApplied)
2203
2331
  return;
2204
2332
  const e = this.grid, t = [...this.columns];
2205
- if (!z(t)) {
2206
- xe(e), this.isApplied = !1;
2333
+ if (!W(t)) {
2334
+ ye(e), this.isApplied = !1;
2207
2335
  return;
2208
2336
  }
2209
2337
  queueMicrotask(() => {
2210
- ve(e, t);
2338
+ xe(e, t);
2211
2339
  });
2212
2340
  }
2213
2341
  /**
@@ -2215,7 +2343,7 @@ class En extends x {
2215
2343
  */
2216
2344
  onPluginQuery(e) {
2217
2345
  switch (e.type) {
2218
- case Pe.CAN_MOVE_COLUMN: {
2346
+ case N.CAN_MOVE_COLUMN: {
2219
2347
  const t = e.context, n = t.sticky;
2220
2348
  if (n === "left" || n === "right")
2221
2349
  return !1;
@@ -2233,7 +2361,7 @@ class En extends x {
2233
2361
  */
2234
2362
  refreshStickyOffsets() {
2235
2363
  const e = [...this.columns];
2236
- ve(this.grid, e);
2364
+ xe(this.grid, e);
2237
2365
  }
2238
2366
  /**
2239
2367
  * Get columns pinned to the left.
@@ -2247,13 +2375,13 @@ class En extends x {
2247
2375
  */
2248
2376
  getRightPinnedColumns() {
2249
2377
  const e = [...this.columns];
2250
- return kt(e);
2378
+ return At(e);
2251
2379
  }
2252
2380
  /**
2253
2381
  * Clear all sticky positioning.
2254
2382
  */
2255
2383
  clearStickyPositions() {
2256
- xe(this.grid);
2384
+ ye(this.grid);
2257
2385
  }
2258
2386
  /**
2259
2387
  * Report horizontal scroll boundary offsets for pinned columns.
@@ -2264,8 +2392,8 @@ class En extends x {
2264
2392
  return;
2265
2393
  let n = 0, o = 0;
2266
2394
  if (e) {
2267
- const s = e.querySelectorAll(".sticky-left"), l = e.querySelectorAll(".sticky-right");
2268
- s.forEach((a) => {
2395
+ const r = e.querySelectorAll(".sticky-left"), l = e.querySelectorAll(".sticky-right");
2396
+ r.forEach((a) => {
2269
2397
  n += a.offsetWidth;
2270
2398
  }), l.forEach((a) => {
2271
2399
  o += a.offsetWidth;
@@ -2281,7 +2409,10 @@ class En extends x {
2281
2409
  }
2282
2410
  // #endregion
2283
2411
  }
2284
- function W(r, e) {
2412
+ function _t(s) {
2413
+ return typeof s == "object" && s !== null && "aggFunc" in s;
2414
+ }
2415
+ function $(s, e) {
2285
2416
  const t = document.createElement("div");
2286
2417
  t.className = "tbw-pinned-rows", t.setAttribute("role", "presentation"), t.setAttribute("aria-live", "polite");
2287
2418
  const n = document.createElement("div");
@@ -2289,22 +2420,22 @@ function W(r, e) {
2289
2420
  const o = document.createElement("div");
2290
2421
  o.className = "tbw-pinned-rows-center";
2291
2422
  const i = document.createElement("div");
2292
- if (i.className = "tbw-pinned-rows-right", r.showRowCount !== !1) {
2293
- const s = document.createElement("span");
2294
- s.className = "tbw-status-panel tbw-status-panel-row-count", s.textContent = `Total: ${e.totalRows} rows`, n.appendChild(s);
2295
- }
2296
- if (r.showFilteredCount && e.filteredRows !== e.totalRows) {
2297
- const s = document.createElement("span");
2298
- s.className = "tbw-status-panel tbw-status-panel-filtered-count", s.textContent = `Filtered: ${e.filteredRows}`, n.appendChild(s);
2299
- }
2300
- if (r.showSelectedCount && e.selectedRows > 0) {
2301
- const s = document.createElement("span");
2302
- s.className = "tbw-status-panel tbw-status-panel-selected-count", s.textContent = `Selected: ${e.selectedRows}`, i.appendChild(s);
2303
- }
2304
- if (r.customPanels)
2305
- for (const s of r.customPanels) {
2306
- const l = At(s, e);
2307
- switch (s.position) {
2423
+ if (i.className = "tbw-pinned-rows-right", s.showRowCount !== !1) {
2424
+ const r = document.createElement("span");
2425
+ r.className = "tbw-status-panel tbw-status-panel-row-count", r.textContent = `Total: ${e.totalRows} rows`, n.appendChild(r);
2426
+ }
2427
+ if (s.showFilteredCount && e.filteredRows !== e.totalRows) {
2428
+ const r = document.createElement("span");
2429
+ r.className = "tbw-status-panel tbw-status-panel-filtered-count", r.textContent = `Filtered: ${e.filteredRows}`, n.appendChild(r);
2430
+ }
2431
+ if (s.showSelectedCount && e.selectedRows > 0) {
2432
+ const r = document.createElement("span");
2433
+ r.className = "tbw-status-panel tbw-status-panel-selected-count", r.textContent = `Selected: ${e.selectedRows}`, i.appendChild(r);
2434
+ }
2435
+ if (s.customPanels)
2436
+ for (const r of s.customPanels) {
2437
+ const l = It(r, e);
2438
+ switch (r.position) {
2308
2439
  case "left":
2309
2440
  n.appendChild(l);
2310
2441
  break;
@@ -2318,53 +2449,58 @@ function W(r, e) {
2318
2449
  }
2319
2450
  return t.appendChild(n), t.appendChild(o), t.appendChild(i), t;
2320
2451
  }
2321
- function ye(r) {
2452
+ function Ce(s) {
2322
2453
  const e = document.createElement("div");
2323
- return e.className = `tbw-aggregation-rows tbw-aggregation-rows-${r}`, e.setAttribute("role", "presentation"), e;
2454
+ return e.className = `tbw-aggregation-rows tbw-aggregation-rows-${s}`, e.setAttribute("role", "presentation"), e;
2324
2455
  }
2325
- function Ce(r, e, t, n) {
2326
- r.innerHTML = "";
2456
+ function Re(s, e, t, n) {
2457
+ s.innerHTML = "";
2327
2458
  for (const o of e) {
2328
2459
  const i = document.createElement("div");
2329
2460
  if (i.className = "tbw-aggregation-row", i.setAttribute("role", "presentation"), o.id && i.setAttribute("data-aggregation-id", o.id), o.fullWidth) {
2330
- const s = document.createElement("div");
2331
- s.className = "tbw-aggregation-cell tbw-aggregation-cell-full", s.style.gridColumn = "1 / -1", s.textContent = o.label || "", i.appendChild(s);
2461
+ const r = document.createElement("div");
2462
+ r.className = "tbw-aggregation-cell tbw-aggregation-cell-full", r.style.gridColumn = "1 / -1", r.textContent = o.label || "", i.appendChild(r);
2332
2463
  } else
2333
- for (const s of t) {
2464
+ for (const r of t) {
2334
2465
  const l = document.createElement("div");
2335
- l.className = "tbw-aggregation-cell", l.setAttribute("data-field", s.field);
2336
- let a;
2337
- const d = o.aggregators?.[s.field];
2338
- if (d) {
2339
- const c = Ge(d);
2340
- c && (a = c(n, s.field, s));
2341
- } else if (o.cells && Object.prototype.hasOwnProperty.call(o.cells, s.field)) {
2342
- const c = o.cells[s.field];
2343
- typeof c == "function" ? a = c(n, s.field, s) : a = c;
2466
+ l.className = "tbw-aggregation-cell", l.setAttribute("data-field", r.field);
2467
+ let a, d;
2468
+ const c = o.aggregators?.[r.field];
2469
+ if (c)
2470
+ if (_t(c)) {
2471
+ const u = le(c.aggFunc);
2472
+ u && (a = u(n, r.field, r)), d = c.formatter;
2473
+ } else {
2474
+ const u = le(c);
2475
+ u && (a = u(n, r.field, r));
2476
+ }
2477
+ else if (o.cells && Object.prototype.hasOwnProperty.call(o.cells, r.field)) {
2478
+ const u = o.cells[r.field];
2479
+ typeof u == "function" ? a = u(n, r.field, r) : a = u;
2344
2480
  }
2345
- l.textContent = a != null ? String(a) : "", i.appendChild(l);
2481
+ a != null ? l.textContent = d ? d(a, r.field, r) : String(a) : l.textContent = "", i.appendChild(l);
2346
2482
  }
2347
- r.appendChild(i);
2483
+ s.appendChild(i);
2348
2484
  }
2349
2485
  }
2350
- function At(r, e) {
2486
+ function It(s, e) {
2351
2487
  const t = document.createElement("div");
2352
- t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${r.id}`;
2353
- const n = r.render(e);
2488
+ t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${s.id}`;
2489
+ const n = s.render(e);
2354
2490
  return typeof n == "string" ? t.innerHTML = n : t.appendChild(n), t;
2355
2491
  }
2356
- function Re(r, e, t, n, o) {
2492
+ function Se(s, e, t, n, o) {
2357
2493
  return {
2358
- totalRows: r.length,
2359
- filteredRows: o?.cachedResult?.length ?? r.length,
2494
+ totalRows: s.length,
2495
+ filteredRows: o?.cachedResult?.length ?? s.length,
2360
2496
  selectedRows: n?.selected?.size ?? 0,
2361
2497
  columns: e,
2362
- rows: r,
2498
+ rows: s,
2363
2499
  grid: t
2364
2500
  };
2365
2501
  }
2366
- const _t = ".tbw-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-color-panel-bg)}.tbw-pinned-rows{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--tbw-pinned-rows-bg, var(--tbw-color-panel-bg));border-top:1px solid var(--tbw-pinned-rows-border, var(--tbw-color-border));font-size:12px;color:var(--tbw-pinned-rows-color, var(--tbw-color-fg-muted));min-height:32px;box-sizing:border-box;min-width:fit-content}.tbw-pinned-rows-left,.tbw-pinned-rows-center,.tbw-pinned-rows-right{display:flex;align-items:center;gap:16px}.tbw-pinned-rows-left{justify-content:flex-start}.tbw-pinned-rows-center{justify-content:center;flex:1}.tbw-pinned-rows-right{justify-content:flex-end}.tbw-status-panel{white-space:nowrap}.tbw-aggregation-rows{min-width:fit-content;background:var(--tbw-aggregation-bg, var(--tbw-color-header-bg))}.tbw-aggregation-rows-top{border-bottom:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-rows-bottom{border-top:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:var(--tbw-aggregation-font-weight, 600)}.tbw-aggregation-cell{padding:var(--tbw-cell-padding, 2px 8px);min-height:var(--tbw-row-height, 28px);display:flex;align-items:center;border-right:1px solid var(--tbw-color-border-cell)}.tbw-aggregation-cell:last-child{border-right:0}.tbw-aggregation-cell-full{grid-column:1 / -1;border-right:0}";
2367
- class kn extends x {
2502
+ const Lt = ".tbw-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-color-panel-bg)}.tbw-pinned-rows{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--tbw-pinned-rows-bg, var(--tbw-color-panel-bg));border-top:1px solid var(--tbw-pinned-rows-border, var(--tbw-color-border));font-size:12px;color:var(--tbw-pinned-rows-color, var(--tbw-color-fg-muted));min-height:32px;box-sizing:border-box;min-width:fit-content}.tbw-pinned-rows-left,.tbw-pinned-rows-center,.tbw-pinned-rows-right{display:flex;align-items:center;gap:16px}.tbw-pinned-rows-left{justify-content:flex-start}.tbw-pinned-rows-center{justify-content:center;flex:1}.tbw-pinned-rows-right{justify-content:flex-end}.tbw-status-panel{white-space:nowrap}.tbw-aggregation-rows{min-width:fit-content;background:var(--tbw-aggregation-bg, var(--tbw-color-header-bg))}.tbw-aggregation-rows-top{border-bottom:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-rows-bottom{border-top:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-row{display:grid;grid-template-columns:var(--tbw-column-template);font-size:var(--tbw-aggregation-font-size, .8em);font-weight:var(--tbw-aggregation-font-weight, 600)}.tbw-aggregation-cell{padding:var(--tbw-cell-padding, 2px 8px);min-height:var(--tbw-row-height, 28px);display:flex;align-items:center;border-right:1px solid var(--tbw-color-border-cell)}.tbw-aggregation-cell:last-child{border-right:0}.tbw-aggregation-cell-full{grid-column:1 / -1;border-right:0}";
2503
+ class An extends v {
2368
2504
  name = "pinnedRows";
2369
2505
  version = "1.0.0";
2370
2506
  get defaultConfig() {
@@ -2392,20 +2528,20 @@ class kn extends x {
2392
2528
  if (!e) return;
2393
2529
  const t = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
2394
2530
  if (!t) return;
2395
- const n = this.getSelectionState(), o = this.getFilterState(), i = Re(
2531
+ const n = this.getSelectionState(), o = this.getFilterState(), i = Se(
2396
2532
  this.rows,
2397
2533
  this.columns,
2398
2534
  this.grid,
2399
2535
  n,
2400
2536
  o
2401
- ), s = this.config.aggregationRows || [], l = s.filter((h) => h.position === "top"), a = s.filter((h) => h.position !== "top");
2537
+ ), r = this.config.aggregationRows || [], l = r.filter((h) => h.position === "top"), a = r.filter((h) => h.position !== "top");
2402
2538
  if (l.length > 0) {
2403
2539
  if (!this.topAggregationContainer) {
2404
- this.topAggregationContainer = ye("top");
2540
+ this.topAggregationContainer = Ce("top");
2405
2541
  const h = e.querySelector(".header");
2406
2542
  h && h.nextSibling ? t.insertBefore(this.topAggregationContainer, h.nextSibling) : t.appendChild(this.topAggregationContainer);
2407
2543
  }
2408
- Ce(
2544
+ Re(
2409
2545
  this.topAggregationContainer,
2410
2546
  l,
2411
2547
  this.visibleColumns,
@@ -2415,18 +2551,18 @@ class kn extends x {
2415
2551
  const d = this.config.showRowCount !== !1 || this.config.showSelectedCount && i.selectedRows > 0 || this.config.showFilteredCount && i.filteredRows !== i.totalRows || this.config.customPanels && this.config.customPanels.length > 0, c = d && this.config.position !== "top", u = a.length > 0 || c;
2416
2552
  if (d && this.config.position === "top")
2417
2553
  if (!this.infoBarElement)
2418
- this.infoBarElement = W(this.config, i), t.insertBefore(this.infoBarElement, t.firstChild);
2554
+ this.infoBarElement = $(this.config, i), t.insertBefore(this.infoBarElement, t.firstChild);
2419
2555
  else {
2420
- const h = W(this.config, i);
2556
+ const h = $(this.config, i);
2421
2557
  this.infoBarElement.replaceWith(h), this.infoBarElement = h;
2422
2558
  }
2423
2559
  else this.config.position === "top" && this.infoBarElement && (this.infoBarElement.remove(), this.infoBarElement = null);
2424
- u ? (this.footerWrapper || (this.footerWrapper = document.createElement("div"), this.footerWrapper.className = "tbw-footer", t.appendChild(this.footerWrapper)), this.footerWrapper.innerHTML = "", a.length > 0 && (this.bottomAggregationContainer || (this.bottomAggregationContainer = ye("bottom")), this.footerWrapper.appendChild(this.bottomAggregationContainer), Ce(
2560
+ u ? (this.footerWrapper || (this.footerWrapper = document.createElement("div"), this.footerWrapper.className = "tbw-footer", t.appendChild(this.footerWrapper)), this.footerWrapper.innerHTML = "", a.length > 0 && (this.bottomAggregationContainer || (this.bottomAggregationContainer = Ce("bottom")), this.footerWrapper.appendChild(this.bottomAggregationContainer), Re(
2425
2561
  this.bottomAggregationContainer,
2426
2562
  a,
2427
2563
  this.visibleColumns,
2428
2564
  this.rows
2429
- )), c && (this.infoBarElement = W(this.config, i), this.footerWrapper.appendChild(this.infoBarElement))) : this.cleanupFooter();
2565
+ )), c && (this.infoBarElement = $(this.config, i), this.footerWrapper.appendChild(this.infoBarElement))) : this.cleanupFooter();
2430
2566
  }
2431
2567
  // #endregion
2432
2568
  // #region Private Methods
@@ -2464,7 +2600,7 @@ class kn extends x {
2464
2600
  */
2465
2601
  getContext() {
2466
2602
  const e = this.getSelectionState(), t = this.getFilterState();
2467
- return Re(
2603
+ return Se(
2468
2604
  this.rows,
2469
2605
  this.columns,
2470
2606
  this.grid,
@@ -2502,20 +2638,20 @@ class kn extends x {
2502
2638
  }
2503
2639
  // #endregion
2504
2640
  // #region Styles
2505
- styles = _t;
2641
+ styles = Lt;
2506
2642
  // #endregion
2507
2643
  }
2508
- const It = Oe;
2509
- function Lt(r) {
2644
+ const Tt = Oe;
2645
+ function Ft(s) {
2510
2646
  const e = [];
2511
- return !r.rowGroupFields?.length && !r.columnGroupFields?.length && e.push("At least one row or column group field is required"), r.valueFields?.length || e.push("At least one value field is required"), e;
2647
+ return !s.rowGroupFields?.length && !s.columnGroupFields?.length && e.push("At least one row or column group field is required"), s.valueFields?.length || e.push("At least one value field is required"), e;
2512
2648
  }
2513
- function te(r, e) {
2514
- return [...r, e].join("|");
2649
+ function ne(s, e) {
2650
+ return [...s, e].join("|");
2515
2651
  }
2516
- function Ft(r, e) {
2517
- const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], o = e.valueFields ?? [], i = Tt(r, n), s = qe(
2518
- r,
2652
+ function Pt(s, e) {
2653
+ const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], o = e.valueFields ?? [], i = Mt(s, n), r = qe(
2654
+ s,
2519
2655
  t,
2520
2656
  n,
2521
2657
  i,
@@ -2524,148 +2660,148 @@ function Ft(r, e) {
2524
2660
  // starting depth
2525
2661
  ""
2526
2662
  // parent key prefix
2527
- ), l = Nt(s, i, o), a = Object.values(l).reduce((d, c) => d + c, 0);
2663
+ ), l = Nt(r, i, o), a = Object.values(l).reduce((d, c) => d + c, 0);
2528
2664
  return {
2529
- rows: s,
2665
+ rows: r,
2530
2666
  columnKeys: i,
2531
2667
  totals: l,
2532
2668
  grandTotal: a
2533
2669
  };
2534
2670
  }
2535
- function Tt(r, e) {
2671
+ function Mt(s, e) {
2536
2672
  if (e.length === 0) return ["value"];
2537
2673
  const t = /* @__PURE__ */ new Set();
2538
- for (const n of r) {
2674
+ for (const n of s) {
2539
2675
  const o = e.map((i) => String(n[i] ?? "")).join("|");
2540
2676
  t.add(o);
2541
2677
  }
2542
2678
  return [...t].sort();
2543
2679
  }
2544
- function Mt(r, e) {
2680
+ function Kt(s, e) {
2545
2681
  const t = /* @__PURE__ */ new Map();
2546
- for (const n of r) {
2682
+ for (const n of s) {
2547
2683
  const o = String(n[e] ?? ""), i = t.get(o);
2548
2684
  i ? i.push(n) : t.set(o, [n]);
2549
2685
  }
2550
2686
  return t;
2551
2687
  }
2552
- function qe(r, e, t, n, o, i, s) {
2688
+ function qe(s, e, t, n, o, i, r) {
2553
2689
  const l = [];
2554
2690
  if (e.length === 0) {
2555
- const h = Se(r, t, n, o), g = Ee(h);
2691
+ const h = ke(s, t, n, o), g = Ee(h);
2556
2692
  return l.push({
2557
- rowKey: s || "all",
2558
- rowLabel: s || "All",
2693
+ rowKey: r || "all",
2694
+ rowLabel: r || "All",
2559
2695
  depth: i,
2560
2696
  values: h,
2561
2697
  total: g,
2562
2698
  isGroup: !1,
2563
- rowCount: r.length
2699
+ rowCount: s.length
2564
2700
  }), l;
2565
2701
  }
2566
- const a = e[0], d = e.slice(1), c = d.length > 0, u = Mt(r, a);
2702
+ const a = e[0], d = e.slice(1), c = d.length > 0, u = Kt(s, a);
2567
2703
  for (const [h, g] of u) {
2568
- const p = s ? `${s}|${h}` : h, f = Se(g, t, n, o), m = Ee(f);
2569
- let w;
2570
- c && (w = qe(
2704
+ const f = r ? `${r}|${h}` : h, m = ke(g, t, n, o), p = Ee(m);
2705
+ let R;
2706
+ c && (R = qe(
2571
2707
  g,
2572
2708
  d,
2573
2709
  t,
2574
2710
  n,
2575
2711
  o,
2576
2712
  i + 1,
2577
- p
2713
+ f
2578
2714
  )), l.push({
2579
- rowKey: p,
2715
+ rowKey: f,
2580
2716
  rowLabel: h || "(blank)",
2581
2717
  depth: i,
2582
- values: f,
2583
- total: m,
2718
+ values: m,
2719
+ total: p,
2584
2720
  isGroup: c,
2585
- children: w,
2721
+ children: R,
2586
2722
  rowCount: g.length
2587
2723
  });
2588
2724
  }
2589
2725
  return l;
2590
2726
  }
2591
- function Se(r, e, t, n) {
2727
+ function ke(s, e, t, n) {
2592
2728
  const o = {};
2593
2729
  for (const i of t)
2594
- for (const s of n) {
2595
- const a = (e.length > 0 ? r.filter((h) => e.map((g) => String(h[g] ?? "")).join("|") === i) : r).map((h) => Number(h[s.field]) || 0), d = It(s.aggFunc), c = a.length > 0 ? d(a) : null, u = te([i], s.field);
2730
+ for (const r of n) {
2731
+ const a = (e.length > 0 ? s.filter((h) => e.map((g) => String(h[g] ?? "")).join("|") === i) : s).map((h) => Number(h[r.field]) || 0), d = Tt(r.aggFunc), c = a.length > 0 ? d(a) : null, u = ne([i], r.field);
2596
2732
  o[u] = c;
2597
2733
  }
2598
2734
  return o;
2599
2735
  }
2600
- function Ee(r) {
2736
+ function Ee(s) {
2601
2737
  let e = 0;
2602
- for (const t of Object.values(r))
2738
+ for (const t of Object.values(s))
2603
2739
  e += t ?? 0;
2604
2740
  return e;
2605
2741
  }
2606
- function Nt(r, e, t) {
2742
+ function Nt(s, e, t) {
2607
2743
  const n = {};
2608
2744
  function o(i) {
2609
- for (const s of i)
2610
- if (!s.isGroup || !s.children?.length)
2745
+ for (const r of i)
2746
+ if (!r.isGroup || !r.children?.length)
2611
2747
  for (const l of e)
2612
2748
  for (const a of t) {
2613
- const d = te([l], a.field);
2614
- n[d] = (n[d] ?? 0) + (s.values[d] ?? 0);
2749
+ const d = ne([l], a.field);
2750
+ n[d] = (n[d] ?? 0) + (r.values[d] ?? 0);
2615
2751
  }
2616
- else s.children && o(s.children);
2752
+ else r.children && o(r.children);
2617
2753
  }
2618
- return o(r), n;
2754
+ return o(s), n;
2619
2755
  }
2620
- function Pt(r, e, t = !0) {
2756
+ function qt(s, e, t = !0) {
2621
2757
  const n = [];
2622
2758
  function o(i) {
2623
2759
  n.push(i);
2624
- const s = e ? e.has(i.rowKey) : t;
2625
- if (i.children && s)
2760
+ const r = e ? e.has(i.rowKey) : t;
2761
+ if (i.children && r)
2626
2762
  for (const l of i.children)
2627
2763
  o(l);
2628
2764
  }
2629
- for (const i of r)
2765
+ for (const i of s)
2630
2766
  o(i);
2631
2767
  return n;
2632
2768
  }
2633
- function $(r) {
2769
+ function j(s) {
2634
2770
  const e = [];
2635
2771
  function t(n) {
2636
2772
  if (n.isGroup && e.push(n.rowKey), n.children)
2637
2773
  for (const o of n.children)
2638
2774
  t(o);
2639
2775
  }
2640
- for (const n of r)
2776
+ for (const n of s)
2641
2777
  t(n);
2642
2778
  return e;
2643
2779
  }
2644
- const qt = ["sum", "avg", "count", "min", "max", "first", "last"];
2645
- function Dt(r, e, t, n) {
2646
- const o = new AbortController(), i = { config: e, callbacks: n, signal: o.signal }, s = document.createElement("div");
2647
- return s.className = "tbw-pivot-panel", s.appendChild(L("Options", () => Bt(t, i))), s.appendChild(L("Row Groups", () => ke("rowGroups", i))), s.appendChild(L("Column Groups", () => ke("columnGroups", i))), s.appendChild(L("Values", () => Ht(i))), s.appendChild(L("Available Fields", () => Ot(i))), r.appendChild(s), () => {
2648
- o.abort(), s.remove();
2780
+ const Dt = ["sum", "avg", "count", "min", "max", "first", "last"];
2781
+ function Ht(s, e, t, n) {
2782
+ const o = new AbortController(), i = { config: e, callbacks: n, signal: o.signal }, r = document.createElement("div");
2783
+ return r.className = "tbw-pivot-panel", r.appendChild(L("Options", () => zt(t, i))), r.appendChild(L("Row Groups", () => Ae("rowGroups", i))), r.appendChild(L("Column Groups", () => Ae("columnGroups", i))), r.appendChild(L("Values", () => Ot(i))), r.appendChild(L("Available Fields", () => Bt(i))), s.appendChild(r), () => {
2784
+ o.abort(), r.remove();
2649
2785
  };
2650
2786
  }
2651
- function L(r, e) {
2787
+ function L(s, e) {
2652
2788
  const t = document.createElement("div");
2653
2789
  t.className = "tbw-pivot-section";
2654
2790
  const n = document.createElement("div");
2655
- n.className = "tbw-pivot-section-header", n.textContent = r;
2791
+ n.className = "tbw-pivot-section-header", n.textContent = s;
2656
2792
  const o = document.createElement("div");
2657
2793
  return o.className = "tbw-pivot-section-content", o.appendChild(e()), t.appendChild(n), t.appendChild(o), t;
2658
2794
  }
2659
- function ke(r, e) {
2795
+ function Ae(s, e) {
2660
2796
  const { config: t, callbacks: n, signal: o } = e, i = document.createElement("div");
2661
- i.className = "tbw-pivot-drop-zone", i.setAttribute("data-zone", r);
2662
- const s = r === "rowGroups" ? t.rowGroupFields ?? [] : t.columnGroupFields ?? [];
2663
- if (s.length === 0) {
2797
+ i.className = "tbw-pivot-drop-zone", i.setAttribute("data-zone", s);
2798
+ const r = s === "rowGroups" ? t.rowGroupFields ?? [] : t.columnGroupFields ?? [];
2799
+ if (r.length === 0) {
2664
2800
  const l = document.createElement("div");
2665
2801
  l.className = "tbw-pivot-placeholder", l.textContent = "Drag fields here or click to add", i.appendChild(l);
2666
2802
  } else
2667
- for (const l of s)
2668
- i.appendChild(Kt(l, r, e));
2803
+ for (const l of r)
2804
+ i.appendChild(Vt(l, s, e));
2669
2805
  return i.addEventListener(
2670
2806
  "dragover",
2671
2807
  (l) => {
@@ -2683,27 +2819,27 @@ function ke(r, e) {
2683
2819
  (l) => {
2684
2820
  l.preventDefault(), i.classList.remove("drag-over");
2685
2821
  const a = l.dataTransfer?.getData("text/plain");
2686
- a && n.onAddFieldToZone(a, r);
2822
+ a && n.onAddFieldToZone(a, s);
2687
2823
  },
2688
2824
  { signal: o }
2689
2825
  ), i;
2690
2826
  }
2691
- function Kt(r, e, t) {
2827
+ function Vt(s, e, t) {
2692
2828
  const { callbacks: n, signal: o } = t, i = document.createElement("div");
2693
2829
  i.className = "tbw-pivot-field-chip", i.draggable = !0;
2694
- const s = n.getAvailableFields().find((d) => d.field === r), l = document.createElement("span");
2695
- l.className = "tbw-pivot-chip-label", l.textContent = s?.header ?? r;
2830
+ const r = n.getAvailableFields().find((d) => d.field === s), l = document.createElement("span");
2831
+ l.className = "tbw-pivot-chip-label", l.textContent = r?.header ?? s;
2696
2832
  const a = document.createElement("button");
2697
2833
  return a.className = "tbw-pivot-chip-remove", a.innerHTML = "×", a.title = "Remove field", a.addEventListener(
2698
2834
  "click",
2699
2835
  (d) => {
2700
- d.stopPropagation(), n.onRemoveFieldFromZone(r, e);
2836
+ d.stopPropagation(), n.onRemoveFieldFromZone(s, e);
2701
2837
  },
2702
2838
  { signal: o }
2703
2839
  ), i.appendChild(l), i.appendChild(a), i.addEventListener(
2704
2840
  "dragstart",
2705
2841
  (d) => {
2706
- d.dataTransfer?.setData("text/plain", r), d.dataTransfer?.setData("source-zone", e), i.classList.add("dragging");
2842
+ d.dataTransfer?.setData("text/plain", s), d.dataTransfer?.setData("source-zone", e), i.classList.add("dragging");
2707
2843
  },
2708
2844
  { signal: o }
2709
2845
  ), i.addEventListener(
@@ -2714,20 +2850,20 @@ function Kt(r, e, t) {
2714
2850
  { signal: o }
2715
2851
  ), i;
2716
2852
  }
2717
- function Ht(r) {
2718
- const { config: e, callbacks: t, signal: n } = r, o = document.createElement("div");
2853
+ function Ot(s) {
2854
+ const { config: e, callbacks: t, signal: n } = s, o = document.createElement("div");
2719
2855
  o.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", o.setAttribute("data-zone", "values");
2720
2856
  const i = e.valueFields ?? [];
2721
2857
  if (i.length === 0) {
2722
- const s = document.createElement("div");
2723
- s.className = "tbw-pivot-placeholder", s.textContent = "Drag numeric fields here for aggregation", o.appendChild(s);
2858
+ const r = document.createElement("div");
2859
+ r.className = "tbw-pivot-placeholder", r.textContent = "Drag numeric fields here for aggregation", o.appendChild(r);
2724
2860
  } else
2725
- for (const s of i)
2726
- o.appendChild(Gt(s, r));
2861
+ for (const r of i)
2862
+ o.appendChild(Gt(r, s));
2727
2863
  return o.addEventListener(
2728
2864
  "dragover",
2729
- (s) => {
2730
- s.preventDefault(), o.classList.add("drag-over");
2865
+ (r) => {
2866
+ r.preventDefault(), o.classList.add("drag-over");
2731
2867
  },
2732
2868
  { signal: n }
2733
2869
  ), o.addEventListener(
@@ -2738,31 +2874,31 @@ function Ht(r) {
2738
2874
  { signal: n }
2739
2875
  ), o.addEventListener(
2740
2876
  "drop",
2741
- (s) => {
2742
- s.preventDefault(), o.classList.remove("drag-over");
2743
- const l = s.dataTransfer?.getData("text/plain");
2877
+ (r) => {
2878
+ r.preventDefault(), o.classList.remove("drag-over");
2879
+ const l = r.dataTransfer?.getData("text/plain");
2744
2880
  l && t.onAddValueField(l, "sum");
2745
2881
  },
2746
2882
  { signal: n }
2747
2883
  ), o;
2748
2884
  }
2749
- function Gt(r, e) {
2885
+ function Gt(s, e) {
2750
2886
  const { callbacks: t, signal: n } = e, o = document.createElement("div");
2751
2887
  o.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
2752
- const i = t.getAvailableFields().find((c) => c.field === r.field), s = document.createElement("div");
2753
- s.className = "tbw-pivot-value-label-wrapper";
2888
+ const i = t.getAvailableFields().find((c) => c.field === s.field), r = document.createElement("div");
2889
+ r.className = "tbw-pivot-value-label-wrapper";
2754
2890
  const l = document.createElement("span");
2755
- l.className = "tbw-pivot-chip-label", l.textContent = i?.header ?? r.field;
2891
+ l.className = "tbw-pivot-chip-label", l.textContent = i?.header ?? s.field;
2756
2892
  const a = document.createElement("select");
2757
2893
  a.className = "tbw-pivot-agg-select", a.title = "Aggregation function";
2758
- for (const c of qt) {
2894
+ for (const c of Dt) {
2759
2895
  const u = document.createElement("option");
2760
- u.value = c, u.textContent = c.toUpperCase(), u.selected = c === r.aggFunc, a.appendChild(u);
2896
+ u.value = c, u.textContent = c.toUpperCase(), u.selected = c === s.aggFunc, a.appendChild(u);
2761
2897
  }
2762
2898
  a.addEventListener(
2763
2899
  "change",
2764
2900
  () => {
2765
- t.onUpdateValueAggFunc(r.field, a.value);
2901
+ t.onUpdateValueAggFunc(s.field, a.value);
2766
2902
  },
2767
2903
  { signal: n }
2768
2904
  );
@@ -2770,19 +2906,19 @@ function Gt(r, e) {
2770
2906
  return d.className = "tbw-pivot-chip-remove", d.innerHTML = "×", d.title = "Remove value field", d.addEventListener(
2771
2907
  "click",
2772
2908
  (c) => {
2773
- c.stopPropagation(), t.onRemoveValueField(r.field);
2909
+ c.stopPropagation(), t.onRemoveValueField(s.field);
2774
2910
  },
2775
2911
  { signal: n }
2776
- ), s.appendChild(l), s.appendChild(a), o.appendChild(s), o.appendChild(d), o;
2912
+ ), r.appendChild(l), r.appendChild(a), o.appendChild(r), o.appendChild(d), o;
2777
2913
  }
2778
- function Ot(r) {
2779
- const { config: e, callbacks: t, signal: n } = r, o = document.createElement("div");
2914
+ function Bt(s) {
2915
+ const { config: e, callbacks: t, signal: n } = s, o = document.createElement("div");
2780
2916
  o.className = "tbw-pivot-available-fields";
2781
- const i = t.getAvailableFields(), s = /* @__PURE__ */ new Set([
2917
+ const i = t.getAvailableFields(), r = /* @__PURE__ */ new Set([
2782
2918
  ...e.rowGroupFields ?? [],
2783
2919
  ...e.columnGroupFields ?? [],
2784
2920
  ...e.valueFields?.map((a) => a.field) ?? []
2785
- ]), l = i.filter((a) => !s.has(a.field));
2921
+ ]), l = i.filter((a) => !r.has(a.field));
2786
2922
  if (l.length === 0) {
2787
2923
  const a = document.createElement("div");
2788
2924
  a.className = "tbw-pivot-placeholder", a.textContent = "All fields are in use", o.appendChild(a);
@@ -2805,96 +2941,96 @@ function Ot(r) {
2805
2941
  }
2806
2942
  return o;
2807
2943
  }
2808
- function Bt(r, e) {
2944
+ function zt(s, e) {
2809
2945
  const { config: t, callbacks: n, signal: o } = e, i = document.createElement("div");
2810
2946
  return i.className = "tbw-pivot-options", i.appendChild(
2811
- j(
2947
+ U(
2812
2948
  "Enable Pivot View",
2813
- r,
2814
- (s) => {
2815
- n.onTogglePivot(s);
2949
+ s,
2950
+ (r) => {
2951
+ n.onTogglePivot(r);
2816
2952
  },
2817
2953
  o
2818
2954
  )
2819
2955
  ), i.appendChild(
2820
- j(
2956
+ U(
2821
2957
  "Show Row Totals",
2822
2958
  t.showTotals ?? !0,
2823
- (s) => {
2824
- n.onOptionChange("showTotals", s);
2959
+ (r) => {
2960
+ n.onOptionChange("showTotals", r);
2825
2961
  },
2826
2962
  o
2827
2963
  )
2828
2964
  ), i.appendChild(
2829
- j(
2965
+ U(
2830
2966
  "Show Grand Total",
2831
2967
  t.showGrandTotal ?? !0,
2832
- (s) => {
2833
- n.onOptionChange("showGrandTotal", s);
2968
+ (r) => {
2969
+ n.onOptionChange("showGrandTotal", r);
2834
2970
  },
2835
2971
  o
2836
2972
  )
2837
2973
  ), i;
2838
2974
  }
2839
- function j(r, e, t, n) {
2975
+ function U(s, e, t, n) {
2840
2976
  const o = document.createElement("label");
2841
2977
  o.className = "tbw-pivot-checkbox";
2842
2978
  const i = document.createElement("input");
2843
2979
  i.type = "checkbox", i.checked = e, i.addEventListener("change", () => t(i.checked), { signal: n });
2844
- const s = document.createElement("span");
2845
- return s.textContent = r, o.appendChild(i), o.appendChild(s), o;
2980
+ const r = document.createElement("span");
2981
+ return r.textContent = s, o.appendChild(i), o.appendChild(r), o;
2846
2982
  }
2847
- function Vt(r, e, t) {
2848
- return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(r.__pivotDepth ?? 0)), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((n, o) => {
2983
+ function Wt(s, e, t) {
2984
+ return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((n, o) => {
2849
2985
  const i = document.createElement("div");
2850
2986
  if (i.className = "cell", i.setAttribute("data-col", String(o)), i.setAttribute("role", "gridcell"), o === 0) {
2851
- const s = Number(r.__pivotIndent) || 0;
2852
- i.style.paddingLeft = `${s}px`;
2853
- const l = String(r.__pivotRowKey), a = document.createElement("button");
2854
- a.type = "button", a.className = "pivot-toggle", a.setAttribute("aria-label", r.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(a, t.resolveIcon(r.__pivotExpanded ? "collapse" : "expand")), a.addEventListener("click", (u) => {
2987
+ const r = Number(s.__pivotIndent) || 0;
2988
+ i.style.paddingLeft = `${r}px`;
2989
+ const l = String(s.__pivotRowKey), a = document.createElement("button");
2990
+ a.type = "button", a.className = "pivot-toggle", a.setAttribute("aria-label", s.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(a, t.resolveIcon(s.__pivotExpanded ? "collapse" : "expand")), a.addEventListener("click", (u) => {
2855
2991
  u.stopPropagation(), t.onToggle(l);
2856
2992
  }), i.appendChild(a);
2857
2993
  const d = document.createElement("span");
2858
- d.className = "pivot-label", d.textContent = String(r.__pivotLabel ?? ""), i.appendChild(d);
2994
+ d.className = "pivot-label", d.textContent = String(s.__pivotLabel ?? ""), i.appendChild(d);
2859
2995
  const c = document.createElement("span");
2860
- c.className = "pivot-count", c.textContent = ` (${Number(r.__pivotRowCount) || 0})`, i.appendChild(c);
2996
+ c.className = "pivot-count", c.textContent = ` (${Number(s.__pivotRowCount) || 0})`, i.appendChild(c);
2861
2997
  } else {
2862
- const s = r[n.field];
2863
- i.textContent = s != null ? String(s) : "";
2998
+ const r = s[n.field];
2999
+ i.textContent = r != null ? String(r) : "";
2864
3000
  }
2865
3001
  e.appendChild(i);
2866
3002
  }), !0;
2867
3003
  }
2868
- function zt(r, e, t) {
2869
- return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(r.__pivotDepth ?? 0)), e.innerHTML = "", t.forEach((n, o) => {
3004
+ function $t(s, e, t) {
3005
+ return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.innerHTML = "", t.forEach((n, o) => {
2870
3006
  const i = document.createElement("div");
2871
3007
  if (i.className = "cell", i.setAttribute("data-col", String(o)), i.setAttribute("role", "gridcell"), o === 0) {
2872
- const s = Number(r.__pivotIndent) || 0;
2873
- i.style.paddingLeft = `${s + 20}px`;
3008
+ const r = Number(s.__pivotIndent) || 0;
3009
+ i.style.paddingLeft = `${r + 20}px`;
2874
3010
  const l = document.createElement("span");
2875
- l.className = "pivot-label", l.textContent = String(r.__pivotLabel ?? ""), i.appendChild(l);
3011
+ l.className = "pivot-label", l.textContent = String(s.__pivotLabel ?? ""), i.appendChild(l);
2876
3012
  } else {
2877
- const s = r[n.field];
2878
- i.textContent = s != null ? String(s) : "";
3013
+ const r = s[n.field];
3014
+ i.textContent = r != null ? String(r) : "";
2879
3015
  }
2880
3016
  e.appendChild(i);
2881
3017
  }), !0;
2882
3018
  }
2883
- function Wt(r, e, t) {
3019
+ function jt(s, e, t) {
2884
3020
  return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", t.forEach((n, o) => {
2885
3021
  const i = document.createElement("div");
2886
3022
  if (i.className = "cell", i.setAttribute("data-col", String(o)), o === 0) {
2887
- const s = document.createElement("span");
2888
- s.className = "pivot-label", s.textContent = "Grand Total", i.appendChild(s);
3023
+ const r = document.createElement("span");
3024
+ r.className = "pivot-label", r.textContent = "Grand Total", i.appendChild(r);
2889
3025
  } else {
2890
- const s = r[n.field];
2891
- i.textContent = s != null ? String(s) : "";
3026
+ const r = s[n.field];
3027
+ i.textContent = r != null ? String(r) : "";
2892
3028
  }
2893
3029
  e.appendChild(i);
2894
3030
  }), !0;
2895
3031
  }
2896
- const $t = '.pivot-group-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:600;background:var(--tbw-pivot-group-bg, var(--tbw-color-row-alt));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-group-row:hover{background:var(--tbw-pivot-group-hover, var(--tbw-color-row-hover))}.pivot-leaf-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-pivot-leaf-bg, var(--tbw-color-bg));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-grand-total-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:700;background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-height:var(--tbw-row-height);border-top:2px solid var(--tbw-color-border-strong)}.pivot-grand-total-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-grand-total-row>.cell:last-child{border-right:0}.pivot-grand-total-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-width:fit-content}.pivot-group-row>.cell,.pivot-leaf-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-group-row>.cell:last-child,.pivot-leaf-row>.cell:last-child{border-right:0}.pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:6px;border:none;background:transparent;cursor:pointer;font-size:10px;color:var(--tbw-pivot-toggle-color, var(--tbw-color-fg-muted));border-radius:var(--tbw-border-radius);transition:background .15s,color .15s}.pivot-toggle:hover{background:var(--tbw-pivot-toggle-hover-bg, var(--tbw-color-row-hover));color:var(--tbw-pivot-toggle-hover-color, var(--tbw-color-fg))}.pivot-toggle:focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}.pivot-label{font-weight:inherit}.pivot-count{color:var(--tbw-pivot-count-color, var(--tbw-color-fg-muted));font-size:.9em;font-weight:400}.pivot-total-row{font-weight:700;border-top:2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong))}[data-pivot-depth="1"]{--tbw-pivot-depth: 1}[data-pivot-depth="2"]{--tbw-pivot-depth: 2}[data-pivot-depth="3"]{--tbw-pivot-depth: 3}[data-pivot-depth="4"]{--tbw-pivot-depth: 4}.tbw-pivot-panel{display:flex;flex-direction:column;gap:12px;padding:12px;height:100%;overflow-y:auto;font-size:13px}.tbw-pivot-section{border:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-section-bg, var(--tbw-color-bg))}.tbw-pivot-section-header{padding:8px 12px;font-weight:600;background:var(--tbw-pivot-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius) var(--tbw-border-radius) 0 0}.tbw-pivot-section-content{padding:8px}.tbw-pivot-toggle-wrapper{display:flex;align-items:center}.tbw-pivot-toggle-label{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-toggle-label input{width:16px;height:16px;cursor:pointer}.tbw-pivot-drop-zone{min-height:60px;padding:8px;border:2px dashed var(--tbw-pivot-drop-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-drop-bg, var(--tbw-color-row-alt));display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start;transition:all .15s ease}.tbw-pivot-drop-zone.drag-over{border-color:var(--tbw-color-accent);background:var(--tbw-pivot-drop-active, var(--tbw-focus-background))}.tbw-pivot-placeholder{color:var(--tbw-color-fg-muted);font-style:italic;padding:8px;text-align:center;width:100%}.tbw-pivot-field-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tbw-pivot-chip-bg, var(--tbw-color-header-bg));border:1px solid var(--tbw-pivot-chip-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);cursor:grab;font-size:12px;transition:all .15s ease}.tbw-pivot-field-chip:hover{background:var(--tbw-pivot-chip-hover, var(--tbw-color-row-hover));border-color:var(--tbw-color-accent)}.tbw-pivot-field-chip.available{background:var(--tbw-color-bg)}.tbw-pivot-field-chip.dragging{opacity:.5;cursor:grabbing}.tbw-pivot-chip-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.tbw-pivot-chip-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--tbw-color-fg-muted);font-size:14px;font-weight:700;cursor:pointer;border-radius:50%;transition:all .15s ease}.tbw-pivot-chip-remove:hover{background:var(--tbw-pivot-chip-remove-hover-bg, var(--tbw-color-accent));color:var(--tbw-pivot-chip-remove-hover-fg, var(--tbw-color-accent-fg))}.tbw-pivot-value-chip{padding:4px 8px}.tbw-pivot-value-label-wrapper{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.tbw-pivot-agg-select{padding:2px 4px;font-size:11px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);cursor:pointer}.tbw-pivot-available-fields{display:flex;flex-wrap:wrap;gap:6px;min-height:40px}.tbw-pivot-options{display:flex;flex-direction:column;gap:8px}.tbw-pivot-checkbox{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-checkbox input{width:14px;height:14px;cursor:pointer}';
2897
- class F extends x {
3032
+ const Ut = '.pivot-group-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:600;background:var(--tbw-pivot-group-bg, var(--tbw-color-row-alt));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-group-row:hover{background:var(--tbw-pivot-group-hover, var(--tbw-color-row-hover))}.pivot-leaf-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-pivot-leaf-bg, var(--tbw-color-bg));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-grand-total-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:700;background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-height:var(--tbw-row-height);border-top:2px solid var(--tbw-color-border-strong)}.pivot-grand-total-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-grand-total-row>.cell:last-child{border-right:0}.pivot-grand-total-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-width:fit-content}.pivot-group-row>.cell,.pivot-leaf-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-group-row>.cell:last-child,.pivot-leaf-row>.cell:last-child{border-right:0}.pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:6px;border:none;background:transparent;cursor:pointer;color:var(--tbw-pivot-toggle-color, var(--tbw-color-fg-muted));border-radius:var(--tbw-border-radius);transition:background .15s,color .15s}.pivot-toggle:hover{background:var(--tbw-pivot-toggle-hover-bg, var(--tbw-color-row-hover));color:var(--tbw-pivot-toggle-hover-color, var(--tbw-color-fg))}.pivot-toggle:focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}.pivot-label{font-weight:inherit}.pivot-count{color:var(--tbw-pivot-count-color, var(--tbw-color-fg-muted));font-size:.9em;font-weight:400}.pivot-total-row{font-weight:700;border-top:2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong))}[data-pivot-depth="1"]{--tbw-pivot-depth: 1}[data-pivot-depth="2"]{--tbw-pivot-depth: 2}[data-pivot-depth="3"]{--tbw-pivot-depth: 3}[data-pivot-depth="4"]{--tbw-pivot-depth: 4}.tbw-pivot-panel{display:flex;flex-direction:column;gap:12px;padding:12px;height:100%;overflow-y:auto;font-size:13px}.tbw-pivot-section{border:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-section-bg, var(--tbw-color-bg))}.tbw-pivot-section-header{padding:8px 12px;font-weight:600;background:var(--tbw-pivot-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius) var(--tbw-border-radius) 0 0}.tbw-pivot-section-content{padding:8px}.tbw-pivot-toggle-wrapper{display:flex;align-items:center}.tbw-pivot-toggle-label{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-toggle-label input{width:16px;height:16px;cursor:pointer}.tbw-pivot-drop-zone{min-height:60px;padding:8px;border:2px dashed var(--tbw-pivot-drop-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-drop-bg, var(--tbw-color-row-alt));display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start;transition:all .15s ease}.tbw-pivot-drop-zone.drag-over{border-color:var(--tbw-color-accent);background:var(--tbw-pivot-drop-active, var(--tbw-focus-background))}.tbw-pivot-placeholder{color:var(--tbw-color-fg-muted);font-style:italic;padding:8px;text-align:center;width:100%}.tbw-pivot-field-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tbw-pivot-chip-bg, var(--tbw-color-header-bg));border:1px solid var(--tbw-pivot-chip-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);cursor:grab;font-size:12px;transition:all .15s ease}.tbw-pivot-field-chip:hover{background:var(--tbw-pivot-chip-hover, var(--tbw-color-row-hover));border-color:var(--tbw-color-accent)}.tbw-pivot-field-chip.available{background:var(--tbw-color-bg)}.tbw-pivot-field-chip.dragging{opacity:.5;cursor:grabbing}.tbw-pivot-chip-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.tbw-pivot-chip-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--tbw-color-fg-muted);font-size:14px;font-weight:700;cursor:pointer;border-radius:50%;transition:all .15s ease}.tbw-pivot-chip-remove:hover{background:var(--tbw-pivot-chip-remove-hover-bg, var(--tbw-color-accent));color:var(--tbw-pivot-chip-remove-hover-fg, var(--tbw-color-accent-fg))}.tbw-pivot-value-chip{padding:4px 8px}.tbw-pivot-value-label-wrapper{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.tbw-pivot-agg-select{padding:2px 4px;font-size:11px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);cursor:pointer}.tbw-pivot-available-fields{display:flex;flex-wrap:wrap;gap:6px;min-height:40px}.tbw-pivot-options{display:flex;flex-direction:column;gap:8px}.tbw-pivot-checkbox{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-checkbox input{width:14px;height:14px;cursor:pointer}.pivot-group-row.tbw-pivot-slide-in,.pivot-leaf-row.tbw-pivot-slide-in{animation:tbw-pivot-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.pivot-group-row.tbw-pivot-fade-in,.pivot-leaf-row.tbw-pivot-fade-in{animation:tbw-pivot-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-fade-in{0%{opacity:0}to{opacity:1}}';
3033
+ class T extends v {
2898
3034
  name = "pivot";
2899
3035
  version = "1.0.0";
2900
3036
  /** Tool panel ID for shell integration */
@@ -2903,7 +3039,9 @@ class F extends x {
2903
3039
  return {
2904
3040
  active: !0,
2905
3041
  showTotals: !0,
2906
- showGrandTotal: !0
3042
+ showGrandTotal: !0,
3043
+ showToolPanel: !0,
3044
+ animation: "slide"
2907
3045
  };
2908
3046
  }
2909
3047
  // #region Internal State
@@ -2916,64 +3054,86 @@ class F extends x {
2916
3054
  originalColumns = [];
2917
3055
  panelContainer = null;
2918
3056
  grandTotalFooter = null;
3057
+ previousVisibleKeys = /* @__PURE__ */ new Set();
3058
+ keysToAnimate = /* @__PURE__ */ new Set();
2919
3059
  /**
2920
3060
  * Check if the plugin has valid pivot configuration (at least value fields).
2921
3061
  */
2922
3062
  hasValidPivotConfig() {
2923
3063
  return (this.config.valueFields?.length ?? 0) > 0;
2924
3064
  }
3065
+ /**
3066
+ * Get animation style respecting grid-level animation mode.
3067
+ */
3068
+ get animationStyle() {
3069
+ const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
3070
+ if (t === !1 || t === "off") return !1;
3071
+ if (t !== !0 && t !== "on") {
3072
+ const n = this.shadowRoot?.host;
3073
+ if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
3074
+ return !1;
3075
+ }
3076
+ return this.config.animation ?? "slide";
3077
+ }
2925
3078
  // #endregion
2926
3079
  // #region Lifecycle
2927
3080
  detach() {
2928
- this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter();
3081
+ this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter(), this.previousVisibleKeys.clear(), this.keysToAnimate.clear();
2929
3082
  }
2930
3083
  // #endregion
2931
3084
  // #region Shell Integration
2932
3085
  getToolPanel() {
2933
- return {
2934
- id: F.PANEL_ID,
2935
- title: "Pivot",
2936
- icon: "",
2937
- tooltip: "Configure pivot table",
2938
- order: 90,
2939
- render: (e) => this.renderPanel(e)
2940
- };
3086
+ if ((this.config?.showToolPanel ?? this.userConfig?.showToolPanel ?? !0) !== !1)
3087
+ return {
3088
+ id: T.PANEL_ID,
3089
+ title: "Pivot",
3090
+ icon: "",
3091
+ tooltip: "Configure pivot table",
3092
+ order: 90,
3093
+ render: (t) => this.renderPanel(t)
3094
+ };
2941
3095
  }
2942
3096
  // #endregion
2943
3097
  // #region Hooks
2944
3098
  processRows(e) {
2945
3099
  if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
2946
3100
  return [...e];
2947
- const t = Lt(this.config);
3101
+ const t = Ft(this.config);
2948
3102
  if (t.length > 0)
2949
3103
  return this.warn(`Config errors: ${t.join(", ")}`), [...e];
2950
3104
  if (this.buildFieldHeaderMap(), this.defaultExpanded = this.config.defaultExpanded ?? !0, this.expandedKeys.size === 0 && this.defaultExpanded && this.pivotResult) {
2951
- const i = $(this.pivotResult.rows);
2952
- for (const s of i)
2953
- this.expandedKeys.add(s);
3105
+ const r = j(this.pivotResult.rows);
3106
+ for (const l of r)
3107
+ this.expandedKeys.add(l);
2954
3108
  }
2955
- if (this.pivotResult = Ft(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
2956
- const i = $(this.pivotResult.rows);
2957
- for (const s of i)
2958
- this.expandedKeys.add(s);
3109
+ if (this.pivotResult = Pt(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
3110
+ const r = j(this.pivotResult.rows);
3111
+ for (const l of r)
3112
+ this.expandedKeys.add(l);
2959
3113
  }
2960
- const n = this.config.indentWidth ?? 20;
2961
- return Pt(
3114
+ const n = this.config.indentWidth ?? 20, o = qt(
2962
3115
  this.pivotResult.rows,
2963
3116
  this.expandedKeys,
2964
3117
  this.defaultExpanded
2965
- ).map((i) => ({
2966
- __pivotRowKey: i.rowKey,
2967
- __pivotLabel: i.rowLabel,
2968
- __pivotDepth: i.depth,
2969
- __pivotIsGroup: i.isGroup,
2970
- __pivotHasChildren: !!i.children?.length,
2971
- __pivotExpanded: this.expandedKeys.has(i.rowKey),
2972
- __pivotRowCount: i.rowCount ?? 0,
2973
- __pivotIndent: i.depth * n,
2974
- __pivotTotal: i.total,
2975
- ...i.values
3118
+ ).map((r) => ({
3119
+ __pivotRowKey: r.rowKey,
3120
+ __pivotLabel: r.rowLabel,
3121
+ __pivotDepth: r.depth,
3122
+ __pivotIsGroup: r.isGroup,
3123
+ __pivotHasChildren: !!r.children?.length,
3124
+ __pivotExpanded: this.expandedKeys.has(r.rowKey),
3125
+ __pivotRowCount: r.rowCount ?? 0,
3126
+ __pivotIndent: r.depth * n,
3127
+ __pivotTotal: r.total,
3128
+ ...r.values
2976
3129
  }));
3130
+ this.keysToAnimate.clear();
3131
+ const i = /* @__PURE__ */ new Set();
3132
+ for (const r of o) {
3133
+ const l = r.__pivotRowKey;
3134
+ i.add(l), !this.previousVisibleKeys.has(l) && r.__pivotDepth > 0 && this.keysToAnimate.add(l);
3135
+ }
3136
+ return this.previousVisibleKeys = i, o;
2977
3137
  }
2978
3138
  processColumns(e) {
2979
3139
  if (!this.isActive || !this.pivotResult)
@@ -2986,9 +3146,9 @@ class F extends x {
2986
3146
  });
2987
3147
  for (const o of this.pivotResult.columnKeys)
2988
3148
  for (const i of this.config.valueFields ?? []) {
2989
- const s = te([o], i.field), l = i.header || this.fieldHeaderMap.get(i.field) || i.field;
3149
+ const r = ne([o], i.field), l = i.header || this.fieldHeaderMap.get(i.field) || i.field;
2990
3150
  t.push({
2991
- field: s,
3151
+ field: r,
2992
3152
  header: `${o} - ${l} (${i.aggFunc})`,
2993
3153
  width: 120,
2994
3154
  type: "number"
@@ -3003,12 +3163,12 @@ class F extends x {
3003
3163
  }
3004
3164
  renderRow(e, t) {
3005
3165
  const n = e;
3006
- return n.__pivotRowKey && n.__pivotHasChildren ? Vt(n, t, {
3166
+ return n.__pivotRowKey && n.__pivotHasChildren ? Wt(n, t, {
3007
3167
  columns: this.gridColumns,
3008
3168
  onToggle: (o) => this.toggle(o),
3009
3169
  resolveIcon: (o) => this.resolveIcon(o),
3010
3170
  setIcon: (o, i) => this.setIcon(o, i)
3011
- }) : n.__pivotRowKey !== void 0 && this.isActive ? zt(n, t, this.gridColumns) : (this.cleanupPivotStyling(t), !1);
3171
+ }) : n.__pivotRowKey !== void 0 && this.isActive ? $t(n, t, this.gridColumns) : (this.cleanupPivotStyling(t), !1);
3012
3172
  }
3013
3173
  /**
3014
3174
  * Remove pivot-specific classes, attributes, and inline styles from a row element.
@@ -3020,6 +3180,16 @@ class F extends x {
3020
3180
  }
3021
3181
  afterRender() {
3022
3182
  this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
3183
+ const e = this.animationStyle;
3184
+ if (e === !1 || this.keysToAnimate.size === 0) return;
3185
+ const t = this.shadowRoot?.querySelector(".rows");
3186
+ if (!t) return;
3187
+ const n = e === "fade" ? "tbw-pivot-fade-in" : "tbw-pivot-slide-in";
3188
+ for (const o of t.querySelectorAll(".pivot-group-row, .pivot-leaf-row")) {
3189
+ const i = o.dataset.pivotKey;
3190
+ i && this.keysToAnimate.has(i) && (o.classList.add(n), o.addEventListener("animationend", () => o.classList.remove(n), { once: !0 }));
3191
+ }
3192
+ this.keysToAnimate.clear();
3023
3193
  }
3024
3194
  /**
3025
3195
  * Render the grand total row as a sticky footer pinned to the bottom.
@@ -3038,7 +3208,7 @@ class F extends x {
3038
3208
  __pivotTotal: this.pivotResult.grandTotal,
3039
3209
  ...this.pivotResult.totals
3040
3210
  };
3041
- Wt(n, this.grandTotalFooter, this.gridColumns);
3211
+ jt(n, this.grandTotalFooter, this.gridColumns);
3042
3212
  }
3043
3213
  /**
3044
3214
  * Remove the grand total footer element.
@@ -3059,7 +3229,7 @@ class F extends x {
3059
3229
  }
3060
3230
  expandAll() {
3061
3231
  if (this.pivotResult) {
3062
- const e = $(this.pivotResult.rows);
3232
+ const e = j(this.pivotResult.rows);
3063
3233
  for (const t of e)
3064
3234
  this.expandedKeys.add(t);
3065
3235
  this.requestRender();
@@ -3100,16 +3270,16 @@ class F extends x {
3100
3270
  // #endregion
3101
3271
  // #region Tool Panel API
3102
3272
  showPanel() {
3103
- this.grid.openToolPanel(F.PANEL_ID);
3273
+ this.grid.openToolPanel(T.PANEL_ID);
3104
3274
  }
3105
3275
  hidePanel() {
3106
3276
  this.grid.closeToolPanel();
3107
3277
  }
3108
3278
  togglePanel() {
3109
- this.grid.toggleToolPanel(F.PANEL_ID);
3279
+ this.grid.toggleToolPanel(T.PANEL_ID);
3110
3280
  }
3111
3281
  isPanelVisible() {
3112
- return this.grid.activeToolPanel === F.PANEL_ID;
3282
+ return this.grid.activeToolPanel === T.PANEL_ID;
3113
3283
  }
3114
3284
  // #endregion
3115
3285
  // #region Private Helpers
@@ -3153,7 +3323,7 @@ class F extends x {
3153
3323
  },
3154
3324
  getAvailableFields: () => this.getAvailableFields()
3155
3325
  };
3156
- return Dt(e, this.config, this.isActive, t);
3326
+ return Ht(e, this.config, this.isActive, t);
3157
3327
  }
3158
3328
  refreshPanel() {
3159
3329
  this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
@@ -3187,28 +3357,59 @@ class F extends x {
3187
3357
  }
3188
3358
  // #endregion
3189
3359
  // #region Styles
3190
- styles = $t;
3360
+ styles = Ut;
3191
3361
  // #endregion
3192
3362
  }
3193
- function jt(r) {
3194
- const e = r.meta ?? {};
3363
+ function _e(s) {
3364
+ const e = s.meta ?? {};
3195
3365
  return e.lockPosition !== !0 && e.suppressMovable !== !0;
3196
3366
  }
3197
- function Ae(r, e, t) {
3198
- if (e === t || e < 0 || e >= r.length || t < 0 || t > r.length) return r;
3199
- const n = [...r], [o] = n.splice(e, 1);
3367
+ function Ie(s, e, t) {
3368
+ if (e === t || e < 0 || e >= s.length || t < 0 || t > s.length) return s;
3369
+ const n = [...s], [o] = n.splice(e, 1);
3200
3370
  return n.splice(t, 0, o), n;
3201
3371
  }
3202
- const Ut = '.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}';
3203
- class An extends x {
3372
+ const Yt = '.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}';
3373
+ class _n extends v {
3204
3374
  name = "reorder";
3205
3375
  version = "1.0.0";
3206
3376
  get defaultConfig() {
3207
3377
  return {
3208
- animation: !0,
3209
- animationDuration: 200
3378
+ animation: "flip"
3379
+ // Plugin's own default
3210
3380
  };
3211
3381
  }
3382
+ /**
3383
+ * Resolve animation type from plugin config.
3384
+ * Respects grid-level animation.mode (disabled = no animation).
3385
+ */
3386
+ get animationType() {
3387
+ return this.isAnimationEnabled ? this.config.animation !== void 0 ? this.config.animation : this.config.viewTransition === !1 ? !1 : (this.config.viewTransition === !0, "flip") : !1;
3388
+ }
3389
+ /**
3390
+ * Check if animations are enabled at the grid level.
3391
+ * Respects gridConfig.animation.mode and CSS variable.
3392
+ */
3393
+ get isAnimationEnabled() {
3394
+ const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
3395
+ if (t === !1 || t === "off") return !1;
3396
+ if (t === !0 || t === "on") return !0;
3397
+ const n = this.shadowRoot?.host;
3398
+ return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
3399
+ }
3400
+ /**
3401
+ * Get animation duration from CSS variable (set by grid config).
3402
+ */
3403
+ get animationDuration() {
3404
+ if (this.config.animationDuration !== void 0)
3405
+ return this.config.animationDuration;
3406
+ const e = this.shadowRoot?.host;
3407
+ if (e) {
3408
+ const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
3409
+ if (!isNaN(n)) return n;
3410
+ }
3411
+ return 200;
3412
+ }
3212
3413
  // #region Internal State
3213
3414
  isDragging = !1;
3214
3415
  draggedField = null;
@@ -3231,18 +3432,17 @@ class An extends x {
3231
3432
  }
3232
3433
  // #endregion
3233
3434
  // #region Hooks
3234
- // Note: No processColumns hook needed - we directly update the grid's column order
3235
3435
  afterRender() {
3236
3436
  const e = this.shadowRoot;
3237
3437
  if (!e) return;
3238
3438
  e.querySelectorAll(".header-row > .cell").forEach((n) => {
3239
3439
  const o = n, i = o.getAttribute("data-field");
3240
3440
  if (!i) return;
3241
- const s = this.columns.find((c) => c.field === i), d = !this.grid.queryPlugins({
3242
- type: Pe.CAN_MOVE_COLUMN,
3243
- context: s
3441
+ const r = this.columns.find((c) => c.field === i), d = !this.grid.queryPlugins({
3442
+ type: N.CAN_MOVE_COLUMN,
3443
+ context: r
3244
3444
  }).includes(!1);
3245
- if (!s || !jt(s) || !d) {
3445
+ if (!r || !_e(r) || !d) {
3246
3446
  o.draggable = !1;
3247
3447
  return;
3248
3448
  }
@@ -3255,8 +3455,8 @@ class An extends x {
3255
3455
  });
3256
3456
  }), o.addEventListener("dragover", (c) => {
3257
3457
  if (c.preventDefault(), !this.isDragging || this.draggedField === i) return;
3258
- const u = o.getBoundingClientRect(), h = u.left + u.width / 2, p = this.getColumnOrder().indexOf(i);
3259
- this.dropIndex = c.clientX < h ? p : p + 1, o.classList.add("drop-target"), o.classList.toggle("drop-before", c.clientX < h), o.classList.toggle("drop-after", c.clientX >= h);
3458
+ const u = o.getBoundingClientRect(), h = u.left + u.width / 2, f = this.getColumnOrder().indexOf(i);
3459
+ this.dropIndex = c.clientX < h ? f : f + 1, o.classList.add("drop-target"), o.classList.toggle("drop-before", c.clientX < h), o.classList.toggle("drop-after", c.clientX >= h);
3260
3460
  }), o.addEventListener("dragleave", () => {
3261
3461
  o.classList.remove("drop-target", "drop-before", "drop-after");
3262
3462
  }), o.addEventListener("drop", (c) => {
@@ -3264,16 +3464,42 @@ class An extends x {
3264
3464
  const u = this.draggedField, h = this.draggedIndex, g = this.dropIndex;
3265
3465
  if (!this.isDragging || u === null || h === null || g === null)
3266
3466
  return;
3267
- const p = g > h ? g - 1 : g, f = this.getColumnOrder(), m = Ae(f, h, p), w = {
3467
+ const f = g > h ? g - 1 : g, m = this.getColumnOrder(), p = Ie(m, h, f), R = {
3268
3468
  field: u,
3269
3469
  fromIndex: h,
3270
- toIndex: p,
3271
- columnOrder: m
3470
+ toIndex: f,
3471
+ columnOrder: p
3272
3472
  };
3273
- this.grid.setColumnOrder(m), this.emit("column-move", w), this.grid.requestStateChange?.();
3473
+ this.updateColumnOrder(p), this.emit("column-move", R);
3274
3474
  }));
3275
3475
  });
3276
3476
  }
3477
+ /**
3478
+ * Handle Alt+Arrow keyboard shortcuts for column reordering.
3479
+ */
3480
+ onKeyDown(e) {
3481
+ if (!e.altKey || e.key !== "ArrowLeft" && e.key !== "ArrowRight")
3482
+ return;
3483
+ const t = this.grid, n = t._focusCol, o = t._visibleColumns;
3484
+ if (n < 0 || n >= o.length) return;
3485
+ const i = o[n];
3486
+ if (!i || !_e(i)) return;
3487
+ const r = this.grid;
3488
+ if (r.queryPlugins({
3489
+ type: N.CAN_MOVE_COLUMN,
3490
+ context: i
3491
+ }).includes(!1)) return;
3492
+ const a = this.getColumnOrder(), d = a.indexOf(i.field);
3493
+ if (d === -1) return;
3494
+ const c = e.key === "ArrowLeft" ? d - 1 : d + 1;
3495
+ if (c < 0 || c >= a.length) return;
3496
+ const u = o.find((h) => h.field === a[c]);
3497
+ if (!(u && r.queryPlugins({
3498
+ type: N.CAN_MOVE_COLUMN,
3499
+ context: u
3500
+ }).includes(!1)))
3501
+ return this.moveColumn(i.field, c), t._focusCol = c, Ge(this.grid), e.preventDefault(), e.stopPropagation(), !0;
3502
+ }
3277
3503
  // #endregion
3278
3504
  // #region Public API
3279
3505
  /**
@@ -3291,85 +3517,179 @@ class An extends x {
3291
3517
  moveColumn(e, t) {
3292
3518
  const n = this.getColumnOrder(), o = n.indexOf(e);
3293
3519
  if (o === -1) return;
3294
- const i = Ae(n, o, t);
3295
- this.grid.setColumnOrder(i), this.emit("column-move", {
3520
+ const i = Ie(n, o, t);
3521
+ this.updateColumnOrder(i), this.emit("column-move", {
3296
3522
  field: e,
3297
3523
  fromIndex: o,
3298
3524
  toIndex: t,
3299
3525
  columnOrder: i
3300
- }), this.grid.requestStateChange?.();
3526
+ });
3301
3527
  }
3302
3528
  /**
3303
3529
  * Set a specific column order.
3304
3530
  * @param order - Array of field names in desired order
3305
3531
  */
3306
3532
  setColumnOrder(e) {
3307
- this.grid.setColumnOrder(e), this.grid.requestStateChange?.();
3533
+ this.updateColumnOrder(e);
3308
3534
  }
3309
3535
  /**
3310
3536
  * Reset column order to the original configuration order.
3311
3537
  */
3312
3538
  resetColumnOrder() {
3313
3539
  const e = this.columns.map((t) => t.field);
3314
- this.grid.setColumnOrder(e), this.grid.requestStateChange?.();
3540
+ this.updateColumnOrder(e);
3541
+ }
3542
+ // #endregion
3543
+ // #region View Transition
3544
+ /**
3545
+ * Capture header cell positions before reorder.
3546
+ */
3547
+ captureHeaderPositions() {
3548
+ const e = /* @__PURE__ */ new Map();
3549
+ return this.shadowRoot?.querySelectorAll(".header-row > .cell[data-field]").forEach((t) => {
3550
+ const n = t.getAttribute("data-field");
3551
+ n && e.set(n, t.getBoundingClientRect().left);
3552
+ }), e;
3553
+ }
3554
+ /**
3555
+ * Apply FLIP animation for column reorder.
3556
+ * Uses CSS transitions - JS sets initial transform and toggles class.
3557
+ * @param oldPositions - Header positions captured before DOM change
3558
+ */
3559
+ animateFLIP(e) {
3560
+ const t = this.shadowRoot;
3561
+ if (!t || e.size === 0) return;
3562
+ const n = /* @__PURE__ */ new Map();
3563
+ if (t.querySelectorAll(".header-row > .cell[data-field]").forEach((r) => {
3564
+ const l = r.getAttribute("data-field");
3565
+ if (!l) return;
3566
+ const a = e.get(l);
3567
+ if (a === void 0) return;
3568
+ const d = a - r.getBoundingClientRect().left;
3569
+ Math.abs(d) > 1 && n.set(l, d);
3570
+ }), n.size === 0) return;
3571
+ const o = [];
3572
+ if (t.querySelectorAll(".cell[data-field]").forEach((r) => {
3573
+ const l = n.get(r.getAttribute("data-field") ?? "");
3574
+ if (l !== void 0) {
3575
+ const a = r;
3576
+ a.style.transform = `translateX(${l}px)`, o.push(a);
3577
+ }
3578
+ }), o.length === 0) return;
3579
+ t.host.offsetHeight;
3580
+ const i = this.animationDuration;
3581
+ requestAnimationFrame(() => {
3582
+ o.forEach((r) => {
3583
+ r.classList.add("flip-animating"), r.style.transform = "";
3584
+ }), setTimeout(() => {
3585
+ o.forEach((r) => {
3586
+ r.style.transform = "", r.classList.remove("flip-animating");
3587
+ });
3588
+ }, i + 50);
3589
+ });
3590
+ }
3591
+ /**
3592
+ * Apply crossfade animation for moved columns.
3593
+ * Uses CSS keyframes - JS just toggles classes.
3594
+ */
3595
+ animateFade(e) {
3596
+ const t = this.shadowRoot;
3597
+ if (!t) {
3598
+ e();
3599
+ return;
3600
+ }
3601
+ const n = this.captureHeaderPositions();
3602
+ e();
3603
+ const o = /* @__PURE__ */ new Set();
3604
+ if (t.querySelectorAll(".header-row > .cell[data-field]").forEach((l) => {
3605
+ const a = l.getAttribute("data-field");
3606
+ if (!a) return;
3607
+ const d = n.get(a);
3608
+ if (d === void 0) return;
3609
+ const c = l.getBoundingClientRect().left;
3610
+ Math.abs(d - c) > 1 && o.add(a);
3611
+ }), o.size === 0) return;
3612
+ const i = [];
3613
+ if (t.querySelectorAll(".cell[data-field]").forEach((l) => {
3614
+ const a = l.getAttribute("data-field");
3615
+ if (a && o.has(a)) {
3616
+ const d = l;
3617
+ d.classList.add("fade-animating"), i.push(d);
3618
+ }
3619
+ }), i.length === 0) return;
3620
+ const r = this.animationDuration;
3621
+ setTimeout(() => {
3622
+ i.forEach((l) => l.classList.remove("fade-animating"));
3623
+ }, r + 50);
3624
+ }
3625
+ /**
3626
+ * Update column order with configured animation.
3627
+ */
3628
+ updateColumnOrder(e) {
3629
+ const t = this.grid, n = this.animationType;
3630
+ if (n === "flip" && this.shadowRoot) {
3631
+ const o = this.captureHeaderPositions();
3632
+ t.setColumnOrder(e), this.shadowRoot.host.offsetHeight, this.animateFLIP(o);
3633
+ } else n === "fade" ? this.animateFade(() => t.setColumnOrder(e)) : t.setColumnOrder(e);
3634
+ t.requestStateChange?.();
3315
3635
  }
3316
3636
  // #endregion
3317
3637
  // #region Styles
3318
- styles = Ut;
3638
+ styles = Yt;
3319
3639
  // #endregion
3320
3640
  }
3321
- function D(r) {
3641
+ function D(s) {
3322
3642
  return {
3323
- startRow: Math.min(r.startRow, r.endRow),
3324
- startCol: Math.min(r.startCol, r.endCol),
3325
- endRow: Math.max(r.startRow, r.endRow),
3326
- endCol: Math.max(r.startCol, r.endCol)
3643
+ startRow: Math.min(s.startRow, s.endRow),
3644
+ startCol: Math.min(s.startCol, s.endCol),
3645
+ endRow: Math.max(s.startRow, s.endRow),
3646
+ endCol: Math.max(s.startCol, s.endCol)
3327
3647
  };
3328
3648
  }
3329
- function Yt(r) {
3330
- const e = D(r);
3649
+ function Zt(s) {
3650
+ const e = D(s);
3331
3651
  return {
3332
3652
  from: { row: e.startRow, col: e.startCol },
3333
3653
  to: { row: e.endRow, col: e.endCol }
3334
3654
  };
3335
3655
  }
3336
- function X(r) {
3337
- return r.map(Yt);
3656
+ function J(s) {
3657
+ return s.map(Zt);
3338
3658
  }
3339
- function Zt(r, e, t) {
3659
+ function Xt(s, e, t) {
3340
3660
  const n = D(t);
3341
- return r >= n.startRow && r <= n.endRow && e >= n.startCol && e <= n.endCol;
3661
+ return s >= n.startRow && s <= n.endRow && e >= n.startCol && e <= n.endCol;
3342
3662
  }
3343
- function _e(r, e, t) {
3344
- return t.some((n) => Zt(r, e, n));
3663
+ function Le(s, e, t) {
3664
+ return t.some((n) => Xt(s, e, n));
3345
3665
  }
3346
- function Xt(r) {
3347
- const e = [], t = D(r);
3666
+ function Jt(s) {
3667
+ const e = [], t = D(s);
3348
3668
  for (let n = t.startRow; n <= t.endRow; n++)
3349
3669
  for (let o = t.startCol; o <= t.endCol; o++)
3350
3670
  e.push({ row: n, col: o });
3351
3671
  return e;
3352
3672
  }
3353
- function Jt(r) {
3673
+ function Qt(s) {
3354
3674
  const e = /* @__PURE__ */ new Map();
3355
- for (const t of r)
3356
- for (const n of Xt(t))
3675
+ for (const t of s)
3676
+ for (const n of Jt(t))
3357
3677
  e.set(`${n.row},${n.col}`, n);
3358
3678
  return [...e.values()];
3359
3679
  }
3360
- function U(r, e) {
3680
+ function Y(s, e) {
3361
3681
  return {
3362
- startRow: r.row,
3363
- startCol: r.col,
3682
+ startRow: s.row,
3683
+ startCol: s.col,
3364
3684
  endRow: e.row,
3365
3685
  endCol: e.col
3366
3686
  };
3367
3687
  }
3368
- const Qt = ':host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}:host([data-selection-mode="row"]) .cell-focus{outline:none}:host .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}:host .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}';
3369
- function en(r, e, t) {
3370
- if (r === "cell" && e.selectedCell)
3688
+ const en = ':host .selecting .data-grid-row>.cell{user-select:none}:host .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}:host([data-selection-mode="row"]) .cell-focus{outline:none}:host .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}:host .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}';
3689
+ function tn(s, e, t) {
3690
+ if (s === "cell" && e.selectedCell)
3371
3691
  return {
3372
- mode: r,
3692
+ mode: s,
3373
3693
  ranges: [
3374
3694
  {
3375
3695
  from: { row: e.selectedCell.row, col: e.selectedCell.col },
@@ -3377,16 +3697,16 @@ function en(r, e, t) {
3377
3697
  }
3378
3698
  ]
3379
3699
  };
3380
- if (r === "row" && e.selected.size > 0) {
3700
+ if (s === "row" && e.selected.size > 0) {
3381
3701
  const n = [...e.selected].map((o) => ({
3382
3702
  from: { row: o, col: 0 },
3383
3703
  to: { row: o, col: t - 1 }
3384
3704
  }));
3385
- return { mode: r, ranges: n };
3705
+ return { mode: s, ranges: n };
3386
3706
  }
3387
- return r === "range" && e.ranges.length > 0 ? { mode: r, ranges: X(e.ranges) } : { mode: r, ranges: [] };
3707
+ return s === "range" && e.ranges.length > 0 ? { mode: s, ranges: J(e.ranges) } : { mode: s, ranges: [] };
3388
3708
  }
3389
- class _n extends x {
3709
+ class In extends v {
3390
3710
  name = "selection";
3391
3711
  version = "1.0.0";
3392
3712
  get defaultConfig() {
@@ -3404,12 +3724,14 @@ class _n extends x {
3404
3724
  activeRange = null;
3405
3725
  cellAnchor = null;
3406
3726
  isDragging = !1;
3727
+ /** Pending keyboard navigation update (processed in afterRender) */
3728
+ pendingKeyboardUpdate = null;
3407
3729
  /** Cell selection state (cell mode) */
3408
3730
  selectedCell = null;
3409
3731
  // #endregion
3410
3732
  // #region Lifecycle
3411
3733
  detach() {
3412
- this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null;
3734
+ this.selected.clear(), this.ranges = [], this.activeRange = null, this.cellAnchor = null, this.isDragging = !1, this.selectedCell = null, this.pendingKeyboardUpdate = null;
3413
3735
  }
3414
3736
  // #endregion
3415
3737
  // #region Event Handlers
@@ -3420,9 +3742,9 @@ class _n extends x {
3420
3742
  if (i === "row")
3421
3743
  return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !1;
3422
3744
  if (i === "range") {
3423
- const s = o.shiftKey, l = o.ctrlKey || o.metaKey;
3424
- if (s && this.cellAnchor) {
3425
- const a = U(this.cellAnchor, { row: t, col: n });
3745
+ const r = o.shiftKey, l = o.ctrlKey || o.metaKey;
3746
+ if (r && this.cellAnchor) {
3747
+ const a = Y(this.cellAnchor, { row: t, col: n });
3426
3748
  l ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = a : this.ranges.push(a) : this.ranges = [a], this.activeRange = a;
3427
3749
  } else if (l) {
3428
3750
  const a = {
@@ -3451,33 +3773,22 @@ class _n extends x {
3451
3773
  return t === "cell" ? this.selectedCell = null : t === "row" ? (this.selected.clear(), this.anchor = null) : t === "range" && (this.ranges = [], this.activeRange = null, this.cellAnchor = null), this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
3452
3774
  if (t === "cell" && o)
3453
3775
  return queueMicrotask(() => {
3454
- this.selectedCell = { row: this.grid.focusRow, col: this.grid.focusCol }, this.emit("selection-change", this.#e()), this.requestAfterRender();
3776
+ this.selectedCell = { row: this.grid._focusRow, col: this.grid._focusCol }, this.emit("selection-change", this.#e()), this.requestAfterRender();
3455
3777
  }), !1;
3456
3778
  if (t === "row" && (e.key === "ArrowUp" || e.key === "ArrowDown"))
3457
3779
  return queueMicrotask(() => {
3458
- this.selected.clear(), this.selected.add(this.grid.focusRow), this.lastSelected = this.grid.focusRow, this.emit("selection-change", this.#e()), this.requestAfterRender();
3780
+ this.selected.clear(), this.selected.add(this.grid._focusRow), this.lastSelected = this.grid._focusRow, this.emit("selection-change", this.#e()), this.requestAfterRender();
3459
3781
  }), !1;
3460
- if (t === "range" && o) {
3461
- const i = e.shiftKey;
3462
- return queueMicrotask(() => {
3463
- const s = this.grid.focusRow, l = this.grid.focusCol;
3464
- if (i) {
3465
- this.cellAnchor || (this.cellAnchor = { row: s, col: l });
3466
- const a = U(this.cellAnchor, { row: s, col: l });
3467
- this.ranges = [a], this.activeRange = a;
3468
- } else
3469
- this.ranges = [], this.activeRange = null, this.cellAnchor = { row: s, col: l };
3470
- this.emit("selection-change", this.#e()), this.requestAfterRender();
3471
- }), !1;
3472
- }
3782
+ if (t === "range" && o)
3783
+ return e.shiftKey && !this.cellAnchor && (this.cellAnchor = { row: this.grid._focusRow, col: this.grid._focusCol }), this.pendingKeyboardUpdate = { shiftKey: e.shiftKey }, queueMicrotask(() => this.requestAfterRender()), !1;
3473
3784
  if (t === "range" && e.key === "a" && (e.ctrlKey || e.metaKey)) {
3474
- const i = this.rows.length, s = this.columns.length;
3475
- if (i > 0 && s > 0) {
3785
+ const i = this.rows.length, r = this.columns.length;
3786
+ if (i > 0 && r > 0) {
3476
3787
  const l = {
3477
3788
  startRow: 0,
3478
3789
  startCol: 0,
3479
3790
  endRow: i - 1,
3480
- endCol: s - 1
3791
+ endCol: r - 1
3481
3792
  };
3482
3793
  return this.ranges = [l], this.activeRange = l, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
3483
3794
  }
@@ -3500,7 +3811,7 @@ class _n extends x {
3500
3811
  }
3501
3812
  onCellMouseMove(e) {
3502
3813
  if (this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
3503
- const t = U(this.cellAnchor, { row: e.rowIndex, col: e.colIndex });
3814
+ const t = Y(this.cellAnchor, { row: e.rowIndex, col: e.colIndex });
3504
3815
  return this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = t : this.ranges.push(t), this.activeRange = t, this.emit("selection-change", this.#e()), this.requestAfterRender(), !0;
3505
3816
  }
3506
3817
  onCellMouseUp(e) {
@@ -3522,13 +3833,13 @@ class _n extends x {
3522
3833
  if (o.forEach((i) => {
3523
3834
  i.classList.remove("selected", "row-focus");
3524
3835
  }), t === "row" && (e.querySelectorAll(".cell-focus").forEach((i) => i.classList.remove("cell-focus")), o.forEach((i) => {
3525
- const s = i.querySelector(".cell[data-row]"), l = parseInt(s?.getAttribute("data-row") ?? "-1", 10);
3836
+ const r = i.querySelector(".cell[data-row]"), l = parseInt(r?.getAttribute("data-row") ?? "-1", 10);
3526
3837
  l >= 0 && this.selected.has(l) && i.classList.add("selected", "row-focus");
3527
3838
  })), t === "range" && this.ranges.length > 0) {
3528
3839
  const i = this.activeRange ? D(this.activeRange) : null;
3529
3840
  e.querySelectorAll(".cell[data-row][data-col]").forEach((l) => {
3530
3841
  const a = parseInt(l.getAttribute("data-row") ?? "-1", 10), d = parseInt(l.getAttribute("data-col") ?? "-1", 10);
3531
- a >= 0 && d >= 0 && _e(a, d, this.ranges) && (l.classList.add("selected"), l.classList.remove("cell-focus"), i && (a === i.startRow && l.classList.add("top"), a === i.endRow && l.classList.add("bottom"), d === i.startCol && l.classList.add("first"), d === i.endCol && l.classList.add("last")));
3842
+ a >= 0 && d >= 0 && Le(a, d, this.ranges) && (l.classList.add("selected"), l.classList.remove("cell-focus"), i && (a === i.startRow && l.classList.add("top"), a === i.endRow && l.classList.add("bottom"), d === i.startCol && l.classList.add("first"), d === i.endCol && l.classList.add("last")));
3532
3843
  });
3533
3844
  }
3534
3845
  t === "cell" && this.selectedCell && e.querySelectorAll(".cell-focus").forEach((i) => i.classList.remove("cell-focus"));
@@ -3537,6 +3848,16 @@ class _n extends x {
3537
3848
  const e = this.shadowRoot;
3538
3849
  if (!e) return;
3539
3850
  const t = e.children[0], { mode: n } = this.config;
3851
+ if (this.pendingKeyboardUpdate && n === "range") {
3852
+ const { shiftKey: o } = this.pendingKeyboardUpdate;
3853
+ this.pendingKeyboardUpdate = null;
3854
+ const i = this.grid._focusRow, r = this.grid._focusCol;
3855
+ if (o && this.cellAnchor) {
3856
+ const l = Y(this.cellAnchor, { row: i, col: r });
3857
+ this.ranges = [l], this.activeRange = l;
3858
+ } else o || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: i, col: r });
3859
+ this.emit("selection-change", this.#e());
3860
+ }
3540
3861
  this.grid.setAttribute("data-selection-mode", n), t && t.classList.toggle("selecting", this.isDragging), this.#t();
3541
3862
  }
3542
3863
  /**
@@ -3564,19 +3885,19 @@ class _n extends x {
3564
3885
  * Get all selected cell ranges in public format.
3565
3886
  */
3566
3887
  getRanges() {
3567
- return X(this.ranges);
3888
+ return J(this.ranges);
3568
3889
  }
3569
3890
  /**
3570
3891
  * Get all selected cells across all ranges.
3571
3892
  */
3572
3893
  getSelectedCells() {
3573
- return Jt(this.ranges);
3894
+ return Qt(this.ranges);
3574
3895
  }
3575
3896
  /**
3576
3897
  * Check if a specific cell is in range selection.
3577
3898
  */
3578
3899
  isCellSelected(e, t) {
3579
- return _e(e, t, this.ranges);
3900
+ return Le(e, t, this.ranges);
3580
3901
  }
3581
3902
  /**
3582
3903
  * Clear all selection.
@@ -3595,13 +3916,13 @@ class _n extends x {
3595
3916
  endCol: t.to.col
3596
3917
  })), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
3597
3918
  mode: this.config.mode,
3598
- ranges: X(this.ranges)
3919
+ ranges: J(this.ranges)
3599
3920
  }), this.requestAfterRender();
3600
3921
  }
3601
3922
  // #endregion
3602
3923
  // #region Private Helpers
3603
3924
  #e() {
3604
- return en(
3925
+ return tn(
3605
3926
  this.config.mode,
3606
3927
  {
3607
3928
  selectedCell: this.selectedCell,
@@ -3613,41 +3934,41 @@ class _n extends x {
3613
3934
  }
3614
3935
  // #endregion
3615
3936
  // #region Styles
3616
- styles = Qt;
3937
+ styles = en;
3617
3938
  // #endregion
3618
3939
  }
3619
- function q(r, e) {
3620
- return Math.floor(r / e);
3940
+ function q(s, e) {
3941
+ return Math.floor(s / e);
3621
3942
  }
3622
- function tn(r, e) {
3943
+ function nn(s, e) {
3623
3944
  return {
3624
- start: r * e,
3625
- end: (r + 1) * e
3945
+ start: s * e,
3946
+ end: (s + 1) * e
3626
3947
  };
3627
3948
  }
3628
- function nn(r, e, t) {
3629
- const n = q(r, t), o = q(e - 1, t), i = [];
3630
- for (let s = n; s <= o; s++)
3631
- i.push(s);
3949
+ function on(s, e, t) {
3950
+ const n = q(s, t), o = q(e - 1, t), i = [];
3951
+ for (let r = n; r <= o; r++)
3952
+ i.push(r);
3632
3953
  return i;
3633
3954
  }
3634
- async function Ie(r, e, t, n) {
3635
- const o = tn(e, t);
3636
- return r.getRows({
3955
+ async function Te(s, e, t, n) {
3956
+ const o = nn(e, t);
3957
+ return s.getRows({
3637
3958
  startRow: o.start,
3638
3959
  endRow: o.end,
3639
3960
  sortModel: n.sortModel,
3640
3961
  filterModel: n.filterModel
3641
3962
  });
3642
3963
  }
3643
- function on(r, e, t) {
3644
- const n = q(r, e), o = t.get(n);
3964
+ function rn(s, e, t) {
3965
+ const n = q(s, e), o = t.get(n);
3645
3966
  if (!o) return;
3646
- const i = r % e;
3967
+ const i = s % e;
3647
3968
  return o[i];
3648
3969
  }
3649
- const rn = 100;
3650
- class In extends x {
3970
+ const sn = 100;
3971
+ class Ln extends v {
3651
3972
  name = "serverSide";
3652
3973
  version = "1.0.0";
3653
3974
  get defaultConfig() {
@@ -3676,13 +3997,13 @@ class In extends x {
3676
3997
  */
3677
3998
  loadRequiredBlocks() {
3678
3999
  if (!this.dataSource) return;
3679
- const e = this.grid, t = this.config.cacheBlockSize ?? 100, n = { startRow: e.virtualization.start, endRow: e.virtualization.end }, o = nn(n.startRow, n.endRow, t);
4000
+ const e = this.grid, t = this.config.cacheBlockSize ?? 100, n = { startRow: e._virtualization.start, endRow: e._virtualization.end }, o = on(n.startRow, n.endRow, t);
3680
4001
  for (const i of o)
3681
4002
  if (!(this.loadedBlocks.has(i) || this.loadingBlocks.has(i))) {
3682
4003
  if (this.loadingBlocks.size >= (this.config.maxConcurrentRequests ?? 2))
3683
4004
  break;
3684
- this.loadingBlocks.add(i), Ie(this.dataSource, i, t, {}).then((s) => {
3685
- this.loadedBlocks.set(i, s.rows), this.totalRowCount = s.totalRowCount, this.loadingBlocks.delete(i), this.requestRender(), this.loadRequiredBlocks();
4005
+ this.loadingBlocks.add(i), Te(this.dataSource, i, t, {}).then((r) => {
4006
+ this.loadedBlocks.set(i, r.rows), this.totalRowCount = r.totalRowCount, this.loadingBlocks.delete(i), this.requestRender(), this.loadRequiredBlocks();
3686
4007
  }).catch(() => {
3687
4008
  this.loadingBlocks.delete(i);
3688
4009
  });
@@ -3694,7 +4015,7 @@ class In extends x {
3694
4015
  if (!this.dataSource) return [...e];
3695
4016
  const t = [];
3696
4017
  for (let n = 0; n < this.totalRowCount; n++) {
3697
- const o = on(n, this.config.cacheBlockSize ?? 100, this.loadedBlocks);
4018
+ const o = rn(n, this.config.cacheBlockSize ?? 100, this.loadedBlocks);
3698
4019
  t.push(o ?? { __loading: !0, __index: n });
3699
4020
  }
3700
4021
  return t;
@@ -3702,7 +4023,7 @@ class In extends x {
3702
4023
  onScroll(e) {
3703
4024
  this.dataSource && (this.loadRequiredBlocks(), this.scrollDebounceTimer && clearTimeout(this.scrollDebounceTimer), this.scrollDebounceTimer = setTimeout(() => {
3704
4025
  this.loadRequiredBlocks();
3705
- }, rn));
4026
+ }, sn));
3706
4027
  }
3707
4028
  // #endregion
3708
4029
  // #region Public API
@@ -3713,7 +4034,7 @@ class In extends x {
3713
4034
  setDataSource(e) {
3714
4035
  this.dataSource = e, this.loadedBlocks.clear(), this.loadingBlocks.clear();
3715
4036
  const t = this.config.cacheBlockSize ?? 100;
3716
- Ie(e, 0, t, {}).then((n) => {
4037
+ Te(e, 0, t, {}).then((n) => {
3717
4038
  this.loadedBlocks.set(0, n.rows), this.totalRowCount = n.totalRowCount, this.requestRender();
3718
4039
  });
3719
4040
  }
@@ -3751,80 +4072,62 @@ class In extends x {
3751
4072
  }
3752
4073
  // #endregion
3753
4074
  }
3754
- function ne(r, e, t) {
3755
- return r.id !== void 0 ? String(r.id) : t ? `${t}-${e}` : String(e);
3756
- }
3757
- function De(r, e, t, n = null, o = 0) {
3758
- const i = e.childrenField ?? "children", s = [];
3759
- for (let l = 0; l < r.length; l++) {
3760
- const a = r[l], d = ne(a, l, n), c = a[i], u = Array.isArray(c) && c.length > 0, h = t.has(d);
3761
- if (s.push({
3762
- key: d,
3763
- data: a,
3764
- depth: o,
3765
- hasChildren: u,
3766
- isExpanded: h,
3767
- parentKey: n
3768
- }), u && h) {
3769
- const g = De(c, e, t, d, o + 1);
3770
- s.push(...g);
3771
- }
3772
- }
3773
- return s;
4075
+ function De(s, e, t) {
4076
+ return s.id !== void 0 ? String(s.id) : t ? `${t}-${e}` : String(e);
3774
4077
  }
3775
- function Le(r, e) {
3776
- const t = new Set(r);
4078
+ function Fe(s, e) {
4079
+ const t = new Set(s);
3777
4080
  return t.has(e) ? t.delete(e) : t.add(e), t;
3778
4081
  }
3779
- function J(r, e, t = null, n = 0) {
4082
+ function Q(s, e, t = null, n = 0) {
3780
4083
  const o = e.childrenField ?? "children", i = /* @__PURE__ */ new Set();
3781
- for (let s = 0; s < r.length; s++) {
3782
- const l = r[s], a = ne(l, s, t), d = l[o];
4084
+ for (let r = 0; r < s.length; r++) {
4085
+ const l = s[r], a = De(l, r, t), d = l[o];
3783
4086
  if (Array.isArray(d) && d.length > 0) {
3784
4087
  i.add(a);
3785
- const c = J(d, e, a, n + 1);
4088
+ const c = Q(d, e, a, n + 1);
3786
4089
  for (const u of c) i.add(u);
3787
4090
  }
3788
4091
  }
3789
4092
  return i;
3790
4093
  }
3791
- function sn() {
4094
+ function ln() {
3792
4095
  return /* @__PURE__ */ new Set();
3793
4096
  }
3794
- function Ke(r, e, t, n = null, o = 0) {
4097
+ function He(s, e, t, n = null, o = 0) {
3795
4098
  const i = t.childrenField ?? "children";
3796
- for (let s = 0; s < r.length; s++) {
3797
- const l = r[s], a = ne(l, s, n);
4099
+ for (let r = 0; r < s.length; r++) {
4100
+ const l = s[r], a = De(l, r, n);
3798
4101
  if (a === e)
3799
4102
  return [a];
3800
4103
  const d = l[i];
3801
4104
  if (Array.isArray(d) && d.length > 0) {
3802
- const c = Ke(d, e, t, a, o + 1);
4105
+ const c = He(d, e, t, a, o + 1);
3803
4106
  if (c)
3804
4107
  return [a, ...c];
3805
4108
  }
3806
4109
  }
3807
4110
  return null;
3808
4111
  }
3809
- function ln(r, e, t, n) {
3810
- const o = Ke(r, e, t);
4112
+ function an(s, e, t, n) {
4113
+ const o = He(s, e, t);
3811
4114
  if (!o) return n;
3812
4115
  const i = new Set(n);
3813
- for (let s = 0; s < o.length - 1; s++)
3814
- i.add(o[s]);
4116
+ for (let r = 0; r < o.length - 1; r++)
4117
+ i.add(o[r]);
3815
4118
  return i;
3816
4119
  }
3817
- function Fe(r, e = "children") {
3818
- if (!Array.isArray(r) || r.length === 0) return !1;
3819
- for (const t of r)
4120
+ function Pe(s, e = "children") {
4121
+ if (!Array.isArray(s) || s.length === 0) return !1;
4122
+ for (const t of s)
3820
4123
  if (t && Array.isArray(t[e]) && t[e].length > 0)
3821
4124
  return !0;
3822
4125
  return !1;
3823
4126
  }
3824
- function an(r) {
3825
- if (!Array.isArray(r) || r.length === 0) return null;
4127
+ function dn(s) {
4128
+ if (!Array.isArray(s) || s.length === 0) return null;
3826
4129
  const e = ["children", "items", "nodes", "subRows", "nested"];
3827
- for (const t of r)
4130
+ for (const t of s)
3828
4131
  if (!(!t || typeof t != "object")) {
3829
4132
  for (const n of e)
3830
4133
  if (Array.isArray(t[n]) && t[n].length > 0)
@@ -3832,173 +4135,202 @@ function an(r) {
3832
4135
  }
3833
4136
  return null;
3834
4137
  }
3835
- const dn = ".tree-toggle{cursor:pointer;user-select:none;transition:transform .2s}.tree-toggle:hover{color:var(--tbw-tree-accent, var(--tbw-color-accent))}";
3836
- class Ln extends x {
4138
+ const cn = ".tree-cell{display:flex;align-items:center;padding-left:calc(var(--tree-depth, 0) * var(--tbw-tree-indent, 20px))}.tree-toggle{cursor:pointer;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}}";
4139
+ class Tn extends v {
3837
4140
  name = "tree";
3838
4141
  version = "1.0.0";
4142
+ styles = cn;
3839
4143
  get defaultConfig() {
3840
4144
  return {
3841
4145
  childrenField: "children",
3842
4146
  autoDetect: !0,
3843
4147
  defaultExpanded: !1,
3844
4148
  indentWidth: 20,
3845
- showExpandIcons: !0
4149
+ showExpandIcons: !0,
4150
+ animation: "slide"
3846
4151
  };
3847
4152
  }
3848
- // #region Internal State
3849
- /** Set of expanded row keys */
4153
+ // #region State
3850
4154
  expandedKeys = /* @__PURE__ */ new Set();
3851
- /** Whether initial expansion (based on defaultExpanded config) has been applied */
3852
4155
  initialExpansionDone = !1;
3853
- /** Flattened tree rows for rendering */
3854
4156
  flattenedRows = [];
3855
- /** Map from key to flattened row for quick lookup */
3856
4157
  rowKeyMap = /* @__PURE__ */ new Map();
3857
- // #endregion
3858
- // #region Lifecycle
4158
+ previousVisibleKeys = /* @__PURE__ */ new Set();
4159
+ keysToAnimate = /* @__PURE__ */ new Set();
4160
+ sortState = null;
3859
4161
  detach() {
3860
- this.expandedKeys.clear(), this.initialExpansionDone = !1, this.flattenedRows = [], this.rowKeyMap.clear();
4162
+ this.expandedKeys.clear(), this.initialExpansionDone = !1, this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), this.keysToAnimate.clear(), this.sortState = null;
4163
+ }
4164
+ // #endregion
4165
+ // #region Animation
4166
+ get animationStyle() {
4167
+ const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
4168
+ if (t === !1 || t === "off") return !1;
4169
+ if (t !== !0 && t !== "on") {
4170
+ const n = this.shadowRoot?.host;
4171
+ if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
4172
+ return !1;
4173
+ }
4174
+ return this.config.animation ?? "slide";
3861
4175
  }
3862
4176
  // #endregion
3863
4177
  // #region Auto-Detection
3864
- /**
3865
- * Detects if tree functionality should be enabled based on data structure.
3866
- * Called by the grid during plugin initialization.
3867
- */
3868
4178
  detect(e) {
3869
4179
  if (!this.config.autoDetect) return !1;
3870
- const t = this.config.childrenField ?? an(e) ?? "children";
3871
- return Fe(e, t);
4180
+ const t = this.config.childrenField ?? dn(e) ?? "children";
4181
+ return Pe(e, t);
3872
4182
  }
3873
4183
  // #endregion
3874
4184
  // #region Data Processing
3875
4185
  processRows(e) {
3876
4186
  const t = this.config.childrenField ?? "children";
3877
- if (!Fe(e, t))
3878
- return this.flattenedRows = [], this.rowKeyMap.clear(), [...e];
3879
- this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = J(e, this.config), this.initialExpansionDone = !0), this.flattenedRows = De(e, this.config, this.expandedKeys), this.rowKeyMap.clear();
3880
- for (const n of this.flattenedRows)
3881
- this.rowKeyMap.set(n.key, n);
3882
- return this.flattenedRows.map((n) => ({
3883
- ...n.data,
3884
- __treeKey: n.key,
3885
- __treeDepth: n.depth,
3886
- __treeHasChildren: n.hasChildren,
3887
- __treeExpanded: n.isExpanded
4187
+ if (!Pe(e, t))
4188
+ return this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), [...e];
4189
+ let n = this.withStableKeys(e);
4190
+ this.sortState && (n = this.sortTree(n, this.sortState.field, this.sortState.direction)), this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = Q(n, this.config), this.initialExpansionDone = !0), this.flattenedRows = this.flattenTree(n, this.expandedKeys), this.rowKeyMap.clear(), this.keysToAnimate.clear();
4191
+ const o = /* @__PURE__ */ new Set();
4192
+ for (const i of this.flattenedRows)
4193
+ this.rowKeyMap.set(i.key, i), o.add(i.key), !this.previousVisibleKeys.has(i.key) && i.depth > 0 && this.keysToAnimate.add(i.key);
4194
+ return this.previousVisibleKeys = o, this.flattenedRows.map((i) => ({
4195
+ ...i.data,
4196
+ __treeKey: i.key,
4197
+ __treeDepth: i.depth,
4198
+ __treeHasChildren: i.hasChildren,
4199
+ __treeExpanded: i.isExpanded
3888
4200
  }));
3889
4201
  }
3890
- processColumns(e) {
3891
- if (this.flattenedRows.length === 0) return [...e];
3892
- const t = this.config.indentWidth ?? 20, n = this.config.showExpandIcons ?? !0, o = [...e];
3893
- if (o.length > 0) {
3894
- const i = { ...o[0] }, s = i.viewRenderer;
3895
- if (s?.__treeWrapped)
3896
- return o;
3897
- const l = (a) => {
3898
- const { value: d, row: c, column: u } = a, h = c.__treeDepth ?? 0, g = c.__treeHasChildren ?? !1, p = c.__treeExpanded ?? !1, f = document.createElement("span");
3899
- if (f.style.display = "flex", f.style.alignItems = "center", f.style.paddingLeft = `${h * t}px`, g && n) {
3900
- const w = document.createElement("span");
3901
- w.className = "tree-toggle", this.setIcon(w, this.resolveIcon(p ? "collapse" : "expand")), w.style.cursor = "pointer", w.style.marginRight = "4px", w.style.fontSize = "10px", w.setAttribute("data-tree-key", c.__treeKey), f.appendChild(w);
3902
- } else if (n) {
3903
- const w = document.createElement("span");
3904
- w.style.width = "14px", w.style.display = "inline-block", f.appendChild(w);
3905
- }
3906
- const m = document.createElement("span");
3907
- if (s) {
3908
- const w = s(a);
3909
- w instanceof Node ? m.appendChild(w) : m.textContent = String(w ?? d ?? "");
3910
- } else
3911
- m.textContent = String(d ?? "");
3912
- return f.appendChild(m), f;
4202
+ /** Assign stable keys to rows (preserves key across sort operations) */
4203
+ withStableKeys(e, t = null) {
4204
+ const n = this.config.childrenField ?? "children";
4205
+ return e.map((o, i) => {
4206
+ const r = o.id !== void 0 ? String(o.id) : o.__stableKey ?? (t ? `${t}-${i}` : String(i)), l = o[n], a = Array.isArray(l) && l.length > 0;
4207
+ return {
4208
+ ...o,
4209
+ __stableKey: r,
4210
+ ...a ? { [n]: this.withStableKeys(l, r) } : {}
3913
4211
  };
3914
- l.__treeWrapped = !0, i.viewRenderer = l, o[0] = i;
4212
+ });
4213
+ }
4214
+ /** Flatten tree using stable keys */
4215
+ flattenTree(e, t, n = 0) {
4216
+ const o = this.config.childrenField ?? "children", i = [];
4217
+ for (const r of e) {
4218
+ const l = r.__stableKey ?? r.id ?? "?", a = r[o], d = Array.isArray(a) && a.length > 0, c = t.has(l);
4219
+ i.push({
4220
+ key: l,
4221
+ data: r,
4222
+ depth: n,
4223
+ hasChildren: d,
4224
+ isExpanded: c,
4225
+ parentKey: n > 0 && l.substring(0, l.lastIndexOf("-")) || null
4226
+ }), d && c && i.push(...this.flattenTree(a, t, n + 1));
3915
4227
  }
3916
- return o;
4228
+ return i;
4229
+ }
4230
+ /** Sort tree recursively, keeping children with parents */
4231
+ sortTree(e, t, n) {
4232
+ const o = this.config.childrenField ?? "children";
4233
+ return [...e].sort((r, l) => {
4234
+ const a = r[t], d = l[t];
4235
+ return a == null && d == null ? 0 : a == null ? -1 : d == null ? 1 : a > d ? n : a < d ? -n : 0;
4236
+ }).map((r) => {
4237
+ const l = r[o];
4238
+ return Array.isArray(l) && l.length > 0 ? { ...r, [o]: this.sortTree(l, t, n) } : r;
4239
+ });
4240
+ }
4241
+ processColumns(e) {
4242
+ if (this.flattenedRows.length === 0) return [...e];
4243
+ const t = [...e];
4244
+ if (t.length === 0) return t;
4245
+ const n = { ...t[0] }, o = n.viewRenderer;
4246
+ if (o?.__treeWrapped) return t;
4247
+ const i = () => this.config, r = this.setIcon.bind(this), l = this.resolveIcon.bind(this), a = (d) => {
4248
+ const { value: c, row: u } = d, { indentWidth: h = 20, showExpandIcons: g = !0 } = i(), f = document.createElement("span");
4249
+ if (f.className = "tree-cell", f.style.setProperty("--tree-depth", String(u.__treeDepth ?? 0)), f.style.setProperty("--tbw-tree-indent", `${h}px`), u.__treeHasChildren && g) {
4250
+ const p = document.createElement("span");
4251
+ p.className = `tree-toggle${u.__treeExpanded ? " expanded" : ""}`, r(p, l(u.__treeExpanded ? "collapse" : "expand")), p.setAttribute("data-tree-key", u.__treeKey), f.appendChild(p);
4252
+ } else if (g) {
4253
+ const p = document.createElement("span");
4254
+ p.className = "tree-spacer", f.appendChild(p);
4255
+ }
4256
+ const m = document.createElement("span");
4257
+ if (o) {
4258
+ const p = o(d);
4259
+ p instanceof Node ? m.appendChild(p) : m.textContent = String(p ?? c ?? "");
4260
+ } else
4261
+ m.textContent = String(c ?? "");
4262
+ return f.appendChild(m), f;
4263
+ };
4264
+ return a.__treeWrapped = !0, n.viewRenderer = a, t[0] = n, t;
3917
4265
  }
3918
4266
  // #endregion
3919
4267
  // #region Event Handlers
3920
4268
  onCellClick(e) {
3921
4269
  const t = e.originalEvent?.target;
3922
4270
  if (!t?.classList.contains("tree-toggle")) return !1;
3923
- const n = t.getAttribute("data-tree-key");
3924
- if (!n) return !1;
3925
- const o = this.rowKeyMap.get(n);
3926
- return o ? (this.expandedKeys = Le(this.expandedKeys, n), this.emit("tree-expand", {
4271
+ const n = t.getAttribute("data-tree-key"), o = n ? this.rowKeyMap.get(n) : null;
4272
+ return o ? (this.expandedKeys = Fe(this.expandedKeys, n), this.emit("tree-expand", {
3927
4273
  key: n,
3928
4274
  row: o.data,
3929
4275
  expanded: this.expandedKeys.has(n),
3930
4276
  depth: o.depth
3931
4277
  }), this.requestRender(), !0) : !1;
3932
4278
  }
4279
+ onHeaderClick(e) {
4280
+ if (this.flattenedRows.length === 0 || !e.column.sortable) return !1;
4281
+ const { field: t } = e.column;
4282
+ !this.sortState || this.sortState.field !== t ? this.sortState = { field: t, direction: 1 } : this.sortState.direction === 1 ? this.sortState = { field: t, direction: -1 } : this.sortState = null;
4283
+ const n = this.grid;
4284
+ return n._sortState !== void 0 && (n._sortState = this.sortState ? { ...this.sortState } : null), this.emit("sort-change", { field: t, direction: this.sortState?.direction ?? 0 }), this.requestRender(), !0;
4285
+ }
4286
+ afterRender() {
4287
+ const e = this.animationStyle;
4288
+ if (e === !1 || this.keysToAnimate.size === 0) return;
4289
+ const t = this.shadowRoot?.querySelector(".rows");
4290
+ if (!t) return;
4291
+ const n = e === "fade" ? "tbw-tree-fade-in" : "tbw-tree-slide-in";
4292
+ for (const o of t.querySelectorAll(".data-grid-row")) {
4293
+ const i = o.querySelector(".cell[data-row]"), r = i ? parseInt(i.getAttribute("data-row") ?? "-1", 10) : -1, l = this.flattenedRows[r]?.key;
4294
+ l && this.keysToAnimate.has(l) && (o.classList.add(n), o.addEventListener("animationend", () => o.classList.remove(n), { once: !0 }));
4295
+ }
4296
+ this.keysToAnimate.clear();
4297
+ }
3933
4298
  // #endregion
3934
4299
  // #region Public API
3935
- /**
3936
- * Expand a specific node by key.
3937
- */
3938
4300
  expand(e) {
3939
4301
  this.expandedKeys.add(e), this.requestRender();
3940
4302
  }
3941
- /**
3942
- * Collapse a specific node by key.
3943
- */
3944
4303
  collapse(e) {
3945
4304
  this.expandedKeys.delete(e), this.requestRender();
3946
4305
  }
3947
- /**
3948
- * Toggle the expansion state of a node.
3949
- */
3950
4306
  toggle(e) {
3951
- this.expandedKeys = Le(this.expandedKeys, e), this.requestRender();
4307
+ this.expandedKeys = Fe(this.expandedKeys, e), this.requestRender();
3952
4308
  }
3953
- /**
3954
- * Expand all nodes in the tree.
3955
- */
3956
4309
  expandAll() {
3957
- this.expandedKeys = J(this.rows, this.config), this.requestRender();
4310
+ this.expandedKeys = Q(this.rows, this.config), this.requestRender();
3958
4311
  }
3959
- /**
3960
- * Collapse all nodes in the tree.
3961
- */
3962
4312
  collapseAll() {
3963
- this.expandedKeys = sn(), this.requestRender();
4313
+ this.expandedKeys = ln(), this.requestRender();
3964
4314
  }
3965
- /**
3966
- * Check if a node is currently expanded.
3967
- */
3968
4315
  isExpanded(e) {
3969
4316
  return this.expandedKeys.has(e);
3970
4317
  }
3971
- /**
3972
- * Get all currently expanded keys.
3973
- */
3974
4318
  getExpandedKeys() {
3975
4319
  return [...this.expandedKeys];
3976
4320
  }
3977
- /**
3978
- * Get the flattened tree rows with metadata.
3979
- */
3980
4321
  getFlattenedRows() {
3981
4322
  return [...this.flattenedRows];
3982
4323
  }
3983
- /**
3984
- * Get a row's original data by its key.
3985
- */
3986
4324
  getRowByKey(e) {
3987
4325
  return this.rowKeyMap.get(e)?.data;
3988
4326
  }
3989
- /**
3990
- * Expand all ancestors of a node to make it visible.
3991
- */
3992
4327
  expandToKey(e) {
3993
- this.expandedKeys = ln(this.rows, e, this.config, this.expandedKeys), this.requestRender();
4328
+ this.expandedKeys = an(this.rows, e, this.config, this.expandedKeys), this.requestRender();
3994
4329
  }
3995
4330
  // #endregion
3996
- // #region Styles
3997
- styles = dn;
3998
- // #endregion
3999
4331
  }
4000
- function cn(r, e, t) {
4001
- const n = [...r.undoStack, e];
4332
+ function un(s, e, t) {
4333
+ const n = [...s.undoStack, e];
4002
4334
  for (; n.length > t; )
4003
4335
  n.shift();
4004
4336
  return {
@@ -4007,50 +4339,50 @@ function cn(r, e, t) {
4007
4339
  // Clear redo on new action
4008
4340
  };
4009
4341
  }
4010
- function Te(r) {
4011
- if (r.undoStack.length === 0)
4012
- return { newState: r, action: null };
4013
- const e = [...r.undoStack], t = e.pop();
4342
+ function Me(s) {
4343
+ if (s.undoStack.length === 0)
4344
+ return { newState: s, action: null };
4345
+ const e = [...s.undoStack], t = e.pop();
4014
4346
  return t ? {
4015
4347
  newState: {
4016
4348
  undoStack: e,
4017
- redoStack: [...r.redoStack, t]
4349
+ redoStack: [...s.redoStack, t]
4018
4350
  },
4019
4351
  action: t
4020
- } : { newState: r, action: null };
4352
+ } : { newState: s, action: null };
4021
4353
  }
4022
- function Me(r) {
4023
- if (r.redoStack.length === 0)
4024
- return { newState: r, action: null };
4025
- const e = [...r.redoStack], t = e.pop();
4354
+ function Ke(s) {
4355
+ if (s.redoStack.length === 0)
4356
+ return { newState: s, action: null };
4357
+ const e = [...s.redoStack], t = e.pop();
4026
4358
  return t ? {
4027
4359
  newState: {
4028
- undoStack: [...r.undoStack, t],
4360
+ undoStack: [...s.undoStack, t],
4029
4361
  redoStack: e
4030
4362
  },
4031
4363
  action: t
4032
- } : { newState: r, action: null };
4364
+ } : { newState: s, action: null };
4033
4365
  }
4034
- function un(r) {
4035
- return r.undoStack.length > 0;
4366
+ function hn(s) {
4367
+ return s.undoStack.length > 0;
4036
4368
  }
4037
- function hn(r) {
4038
- return r.redoStack.length > 0;
4369
+ function gn(s) {
4370
+ return s.redoStack.length > 0;
4039
4371
  }
4040
- function gn() {
4372
+ function fn() {
4041
4373
  return { undoStack: [], redoStack: [] };
4042
4374
  }
4043
- function pn(r, e, t, n) {
4375
+ function pn(s, e, t, n) {
4044
4376
  return {
4045
4377
  type: "cell-edit",
4046
- rowIndex: r,
4378
+ rowIndex: s,
4047
4379
  field: e,
4048
4380
  oldValue: t,
4049
4381
  newValue: n,
4050
4382
  timestamp: Date.now()
4051
4383
  };
4052
4384
  }
4053
- class Fn extends x {
4385
+ class Fn extends v {
4054
4386
  name = "undoRedo";
4055
4387
  version = "1.0.0";
4056
4388
  get defaultConfig() {
@@ -4075,7 +4407,7 @@ class Fn extends x {
4075
4407
  onKeyDown(e) {
4076
4408
  const t = (e.ctrlKey || e.metaKey) && e.key === "z" && !e.shiftKey, n = (e.ctrlKey || e.metaKey) && (e.key === "y" || e.key === "z" && e.shiftKey);
4077
4409
  if (t) {
4078
- const o = Te({ undoStack: this.undoStack, redoStack: this.redoStack });
4410
+ const o = Me({ undoStack: this.undoStack, redoStack: this.redoStack });
4079
4411
  if (o.action) {
4080
4412
  const i = this.rows;
4081
4413
  i[o.action.rowIndex] && (i[o.action.rowIndex][o.action.field] = o.action.oldValue), this.undoStack = o.newState.undoStack, this.redoStack = o.newState.redoStack, this.emit("undo", {
@@ -4086,7 +4418,7 @@ class Fn extends x {
4086
4418
  return !0;
4087
4419
  }
4088
4420
  if (n) {
4089
- const o = Me({ undoStack: this.undoStack, redoStack: this.redoStack });
4421
+ const o = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
4090
4422
  if (o.action) {
4091
4423
  const i = this.rows;
4092
4424
  i[o.action.rowIndex] && (i[o.action.rowIndex][o.action.field] = o.action.newValue), this.undoStack = o.newState.undoStack, this.redoStack = o.newState.redoStack, this.emit("redo", {
@@ -4109,12 +4441,12 @@ class Fn extends x {
4109
4441
  * @param newValue - The value after the edit
4110
4442
  */
4111
4443
  recordEdit(e, t, n, o) {
4112
- const i = pn(e, t, n, o), s = cn(
4444
+ const i = pn(e, t, n, o), r = un(
4113
4445
  { undoStack: this.undoStack, redoStack: this.redoStack },
4114
4446
  i,
4115
4447
  this.config.maxHistorySize ?? 100
4116
4448
  );
4117
- this.undoStack = s.undoStack, this.redoStack = s.redoStack;
4449
+ this.undoStack = r.undoStack, this.redoStack = r.redoStack;
4118
4450
  }
4119
4451
  /**
4120
4452
  * Programmatically undo the last action.
@@ -4122,7 +4454,7 @@ class Fn extends x {
4122
4454
  * @returns The undone action, or null if nothing to undo
4123
4455
  */
4124
4456
  undo() {
4125
- const e = Te({ undoStack: this.undoStack, redoStack: this.redoStack });
4457
+ const e = Me({ undoStack: this.undoStack, redoStack: this.redoStack });
4126
4458
  if (e.action) {
4127
4459
  const t = this.rows;
4128
4460
  t[e.action.rowIndex] && (t[e.action.rowIndex][e.action.field] = e.action.oldValue), this.undoStack = e.newState.undoStack, this.redoStack = e.newState.redoStack, this.requestRender();
@@ -4135,7 +4467,7 @@ class Fn extends x {
4135
4467
  * @returns The redone action, or null if nothing to redo
4136
4468
  */
4137
4469
  redo() {
4138
- const e = Me({ undoStack: this.undoStack, redoStack: this.redoStack });
4470
+ const e = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
4139
4471
  if (e.action) {
4140
4472
  const t = this.rows;
4141
4473
  t[e.action.rowIndex] && (t[e.action.rowIndex][e.action.field] = e.action.newValue), this.undoStack = e.newState.undoStack, this.redoStack = e.newState.redoStack, this.requestRender();
@@ -4146,19 +4478,19 @@ class Fn extends x {
4146
4478
  * Check if there are any actions that can be undone.
4147
4479
  */
4148
4480
  canUndo() {
4149
- return un({ undoStack: this.undoStack, redoStack: this.redoStack });
4481
+ return hn({ undoStack: this.undoStack, redoStack: this.redoStack });
4150
4482
  }
4151
4483
  /**
4152
4484
  * Check if there are any actions that can be redone.
4153
4485
  */
4154
4486
  canRedo() {
4155
- return hn({ undoStack: this.undoStack, redoStack: this.redoStack });
4487
+ return gn({ undoStack: this.undoStack, redoStack: this.redoStack });
4156
4488
  }
4157
4489
  /**
4158
4490
  * Clear all undo/redo history.
4159
4491
  */
4160
4492
  clearHistory() {
4161
- const e = gn();
4493
+ const e = fn();
4162
4494
  this.undoStack = e.undoStack, this.redoStack = e.redoStack;
4163
4495
  }
4164
4496
  /**
@@ -4175,12 +4507,12 @@ class Fn extends x {
4175
4507
  }
4176
4508
  // #endregion
4177
4509
  }
4178
- const fn = '.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:8px}.tbw-visibility-row{display:flex;align-items:center;gap:8px;padding:6px 4px;cursor:pointer;font-size:13px;border-radius:var(--tbw-border-radius, 4px);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted, #888)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted, #888);font-size:10px;letter-spacing:-2px;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg, #1f2937)}.tbw-visibility-label{display:flex;align-items:center;gap:8px;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-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-show-all{margin:8px;padding:8px 12px;border:1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));border-radius:var(--tbw-border-radius, 4px);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));color:var(--tbw-color-fg, #1f2937);cursor:pointer;font-size:13px}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}';
4179
- function Ne(r) {
4180
- const e = r.meta ?? {};
4510
+ const mn = '.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:8px}.tbw-visibility-row{display:flex;align-items:center;gap:8px;padding:6px 4px;cursor:pointer;font-size:13px;border-radius:var(--tbw-border-radius, 4px);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted, #888)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted, #888);font-size:10px;letter-spacing:-2px;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg, #1f2937)}.tbw-visibility-label{display:flex;align-items:center;gap:8px;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-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-show-all{margin:8px;padding:8px 12px;border:1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));border-radius:var(--tbw-border-radius, 4px);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));color:var(--tbw-color-fg, #1f2937);cursor:pointer;font-size:13px}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}';
4511
+ function Ne(s) {
4512
+ const e = s.meta ?? {};
4181
4513
  return e.lockPosition !== !0 && e.suppressMovable !== !0;
4182
4514
  }
4183
- class T extends x {
4515
+ class F extends v {
4184
4516
  name = "visibility";
4185
4517
  version = "1.0.0";
4186
4518
  /** Tool panel ID for shell integration */
@@ -4209,7 +4541,7 @@ class T extends x {
4209
4541
  */
4210
4542
  getToolPanel() {
4211
4543
  return {
4212
- id: T.PANEL_ID,
4544
+ id: F.PANEL_ID,
4213
4545
  title: "Columns",
4214
4546
  icon: "☰",
4215
4547
  tooltip: "Column visibility",
@@ -4224,7 +4556,7 @@ class T extends x {
4224
4556
  * Show the visibility sidebar panel.
4225
4557
  */
4226
4558
  show() {
4227
- this.grid.openToolPanel(T.PANEL_ID);
4559
+ this.grid.openToolPanel(F.PANEL_ID);
4228
4560
  }
4229
4561
  /**
4230
4562
  * Hide the visibility sidebar panel.
@@ -4236,7 +4568,7 @@ class T extends x {
4236
4568
  * Toggle the visibility sidebar panel.
4237
4569
  */
4238
4570
  toggle() {
4239
- this.grid.toggleToolPanel(T.PANEL_ID);
4571
+ this.grid.toggleToolPanel(F.PANEL_ID);
4240
4572
  }
4241
4573
  /**
4242
4574
  * Check if a specific column is visible.
@@ -4314,7 +4646,7 @@ class T extends x {
4314
4646
  * @returns True if the panel is open
4315
4647
  */
4316
4648
  isPanelVisible() {
4317
- return this.grid.activeToolPanel === T.PANEL_ID;
4649
+ return this.grid.activeToolPanel === F.PANEL_ID;
4318
4650
  }
4319
4651
  // #endregion
4320
4652
  // #region Private Methods
@@ -4350,16 +4682,16 @@ class T extends x {
4350
4682
  e.innerHTML = "";
4351
4683
  const o = t.getAllColumns();
4352
4684
  for (let i = 0; i < o.length; i++) {
4353
- const s = o[i], l = s.header || s.field, a = document.createElement("div");
4354
- a.className = s.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", a.setAttribute("data-field", s.field), a.setAttribute("data-index", String(i)), n && Ne(s) && (a.draggable = !0, a.classList.add("reorderable"), this.setupDragListeners(a, s.field, i, e));
4685
+ const r = o[i], l = r.header || r.field, a = document.createElement("div");
4686
+ a.className = r.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", a.setAttribute("data-field", r.field), a.setAttribute("data-index", String(i)), n && Ne(r) && (a.draggable = !0, a.classList.add("reorderable"), this.setupDragListeners(a, r.field, i, e));
4355
4687
  const d = document.createElement("label");
4356
4688
  d.className = "tbw-visibility-label";
4357
4689
  const c = document.createElement("input");
4358
- c.type = "checkbox", c.checked = s.visible, c.disabled = s.lockVisible ?? !1, c.addEventListener("change", () => {
4359
- t.toggleColumnVisibility(s.field), setTimeout(() => this.rebuildToggles(e), 0);
4690
+ c.type = "checkbox", c.checked = r.visible, c.disabled = r.lockVisible ?? !1, c.addEventListener("change", () => {
4691
+ t.toggleColumnVisibility(r.field), setTimeout(() => this.rebuildToggles(e), 0);
4360
4692
  });
4361
4693
  const u = document.createElement("span");
4362
- if (u.textContent = l, d.appendChild(c), d.appendChild(u), n && Ne(s)) {
4694
+ if (u.textContent = l, d.appendChild(c), d.appendChild(u), n && Ne(r)) {
4363
4695
  const h = document.createElement("span");
4364
4696
  h.className = "tbw-visibility-handle", this.setIcon(h, this.resolveIcon("dragHandle")), h.title = "Drag to reorder", a.appendChild(h);
4365
4697
  }
@@ -4379,7 +4711,7 @@ class T extends x {
4379
4711
  });
4380
4712
  }), e.addEventListener("dragover", (i) => {
4381
4713
  if (i.preventDefault(), !this.isDragging || this.draggedField === t) return;
4382
- const s = e.getBoundingClientRect(), l = s.top + s.height / 2;
4714
+ const r = e.getBoundingClientRect(), l = r.top + r.height / 2;
4383
4715
  this.dropIndex = i.clientY < l ? n : n + 1, o.querySelectorAll(".tbw-visibility-row").forEach((a) => {
4384
4716
  a !== e && a.classList.remove("drop-target", "drop-before", "drop-after");
4385
4717
  }), e.classList.add("drop-target"), e.classList.toggle("drop-before", i.clientY < l), e.classList.toggle("drop-after", i.clientY >= l);
@@ -4387,13 +4719,13 @@ class T extends x {
4387
4719
  e.classList.remove("drop-target", "drop-before", "drop-after");
4388
4720
  }), e.addEventListener("drop", (i) => {
4389
4721
  i.preventDefault();
4390
- const s = this.draggedField, l = this.draggedIndex, a = this.dropIndex;
4391
- if (!this.isDragging || s === null || l === null || a === null)
4722
+ const r = this.draggedField, l = this.draggedIndex, a = this.dropIndex;
4723
+ if (!this.isDragging || r === null || l === null || a === null)
4392
4724
  return;
4393
4725
  const d = a > l ? a - 1 : a;
4394
4726
  if (d !== l) {
4395
4727
  const c = {
4396
- field: s,
4728
+ field: r,
4397
4729
  fromIndex: l,
4398
4730
  toIndex: d
4399
4731
  };
@@ -4405,48 +4737,51 @@ class T extends x {
4405
4737
  }
4406
4738
  // #endregion
4407
4739
  // #region Styles
4408
- styles = fn;
4740
+ styles = mn;
4409
4741
  // #endregion
4410
4742
  }
4411
4743
  export {
4412
- x as BaseGridPlugin,
4413
- wn as ClipboardPlugin,
4414
- bn as ColumnVirtualizationPlugin,
4415
- vn as ContextMenuPlugin,
4416
- He as DEFAULT_GRID_ICONS,
4744
+ v as BaseGridPlugin,
4745
+ bn as ClipboardPlugin,
4746
+ vn as ColumnVirtualizationPlugin,
4747
+ xn as ContextMenuPlugin,
4748
+ Kn as DEFAULT_ANIMATION_CONFIG,
4749
+ Ve as DEFAULT_GRID_ICONS,
4417
4750
  Nn as DGEvents,
4418
- Pn as DataGridElement,
4419
- xn as ExportPlugin,
4751
+ qn as DataGridElement,
4752
+ yn as ExportPlugin,
4420
4753
  A as FilteringPlugin,
4421
- qn as FitModeEnum,
4422
- Dn as GridCSSVars,
4423
- Kn as GridClasses,
4424
- Hn as GridDataAttrs,
4754
+ Dn as FitModeEnum,
4755
+ Hn as GridCSSVars,
4756
+ Vn as GridClasses,
4757
+ On as GridDataAttrs,
4425
4758
  Gn as GridElement,
4426
- On as GridSelectors,
4427
- yn as GroupingColumnsPlugin,
4428
- Cn as GroupingRowsPlugin,
4429
- Rn as MasterDetailPlugin,
4430
- Sn as MultiSortPlugin,
4431
- Pe as PLUGIN_QUERIES,
4759
+ Bn as GridSelectors,
4760
+ Cn as GroupingColumnsPlugin,
4761
+ Rn as GroupingRowsPlugin,
4762
+ Sn as MasterDetailPlugin,
4763
+ kn as MultiSortPlugin,
4764
+ N as PLUGIN_QUERIES,
4432
4765
  En as PinnedColumnsPlugin,
4433
- kn as PinnedRowsPlugin,
4434
- F as PivotPlugin,
4435
- Bn as PluginEvents,
4436
- Vn as PluginManager,
4437
- An as ReorderPlugin,
4438
- _n as SelectionPlugin,
4439
- In as ServerSidePlugin,
4440
- Ln as TreePlugin,
4766
+ An as PinnedRowsPlugin,
4767
+ T as PivotPlugin,
4768
+ zn as PluginEvents,
4769
+ Wn as PluginManager,
4770
+ _n as ReorderPlugin,
4771
+ In as SelectionPlugin,
4772
+ Ln as ServerSidePlugin,
4773
+ Tn as TreePlugin,
4441
4774
  Fn as UndoRedoPlugin,
4442
- T as VisibilityPlugin,
4443
- zn as aggregatorRegistry,
4444
- Ge as getAggregator,
4775
+ F as VisibilityPlugin,
4776
+ $n as aggregatorRegistry,
4777
+ jn as builtInSort,
4778
+ Un as defaultComparator,
4779
+ le as getAggregator,
4445
4780
  Oe as getValueAggregator,
4446
- Wn as listAggregators,
4447
- $n as registerAggregator,
4781
+ Yn as listAggregators,
4782
+ Zn as registerAggregator,
4448
4783
  se as runAggregator,
4449
- jn as runValueAggregator,
4450
- Un as unregisterAggregator
4784
+ Xn as runValueAggregator,
4785
+ Jn as unregisterAggregator
4451
4786
  };
4452
4787
  //# sourceMappingURL=all.js.map