@toolbox-web/grid 0.2.6 → 0.2.8

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 (52) hide show
  1. package/all.d.ts +434 -61
  2. package/all.js +844 -541
  3. package/all.js.map +1 -1
  4. package/index-YjW60MHD.js +3235 -0
  5. package/index-YjW60MHD.js.map +1 -0
  6. package/index.d.ts +210 -6
  7. package/index.js +25 -3194
  8. package/index.js.map +1 -1
  9. package/lib/plugins/clipboard/index.js.map +1 -1
  10. package/lib/plugins/column-virtualization/index.js.map +1 -1
  11. package/lib/plugins/context-menu/index.js.map +1 -1
  12. package/lib/plugins/export/index.js.map +1 -1
  13. package/lib/plugins/filtering/index.js +183 -148
  14. package/lib/plugins/filtering/index.js.map +1 -1
  15. package/lib/plugins/grouping-columns/index.js.map +1 -1
  16. package/lib/plugins/grouping-rows/index.js +116 -82
  17. package/lib/plugins/grouping-rows/index.js.map +1 -1
  18. package/lib/plugins/master-detail/index.js +139 -81
  19. package/lib/plugins/master-detail/index.js.map +1 -1
  20. package/lib/plugins/multi-sort/index.js +17 -17
  21. package/lib/plugins/multi-sort/index.js.map +1 -1
  22. package/lib/plugins/pinned-columns/index.js.map +1 -1
  23. package/lib/plugins/pinned-rows/index.js.map +1 -1
  24. package/lib/plugins/pivot/index.js +369 -337
  25. package/lib/plugins/pivot/index.js.map +1 -1
  26. package/lib/plugins/reorder/index.js +264 -91
  27. package/lib/plugins/reorder/index.js.map +1 -1
  28. package/lib/plugins/selection/index.js.map +1 -1
  29. package/lib/plugins/server-side/index.js.map +1 -1
  30. package/lib/plugins/tree/index.js +180 -169
  31. package/lib/plugins/tree/index.js.map +1 -1
  32. package/lib/plugins/undo-redo/index.js.map +1 -1
  33. package/lib/plugins/visibility/index.js.map +1 -1
  34. package/package.json +1 -1
  35. package/umd/grid.all.umd.js +21 -21
  36. package/umd/grid.all.umd.js.map +1 -1
  37. package/umd/grid.umd.js +12 -12
  38. package/umd/grid.umd.js.map +1 -1
  39. package/umd/plugins/filtering.umd.js +1 -1
  40. package/umd/plugins/filtering.umd.js.map +1 -1
  41. package/umd/plugins/grouping-rows.umd.js +1 -1
  42. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  43. package/umd/plugins/master-detail.umd.js +1 -1
  44. package/umd/plugins/master-detail.umd.js.map +1 -1
  45. package/umd/plugins/multi-sort.umd.js +1 -1
  46. package/umd/plugins/multi-sort.umd.js.map +1 -1
  47. package/umd/plugins/pivot.umd.js +1 -1
  48. package/umd/plugins/pivot.umd.js.map +1 -1
  49. package/umd/plugins/reorder.umd.js +1 -1
  50. package/umd/plugins/reorder.umd.js.map +1 -1
  51. package/umd/plugins/tree.umd.js +1 -1
  52. package/umd/plugins/tree.umd.js.map +1 -1
@@ -1,4 +1,4 @@
1
- const P = {
1
+ const E = {
2
2
  expand: "▶",
3
3
  collapse: "▼",
4
4
  sortAsc: "▲",
@@ -8,7 +8,7 @@ const P = {
8
8
  dragHandle: "⋮⋮",
9
9
  toolPanel: "☰"
10
10
  };
11
- class N {
11
+ class P {
12
12
  /** Plugin version - override in subclass if needed */
13
13
  version = "1.0.0";
14
14
  /** CSS styles to inject into the grid's shadow DOM */
@@ -59,8 +59,8 @@ class N {
59
59
  /**
60
60
  * Emit a custom event from the grid.
61
61
  */
62
- emit(e, o) {
63
- this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: o, bubbles: !0 }));
62
+ emit(e, t) {
63
+ this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
64
64
  }
65
65
  /**
66
66
  * Request a re-render of the grid.
@@ -133,7 +133,7 @@ class N {
133
133
  */
134
134
  get gridIcons() {
135
135
  const e = this.grid?.gridConfig?.icons ?? {};
136
- return { ...P, ...e };
136
+ return { ...E, ...e };
137
137
  }
138
138
  /**
139
139
  * Resolve an icon value to string or HTMLElement.
@@ -143,8 +143,8 @@ class N {
143
143
  * @param pluginOverride - Optional plugin-level override
144
144
  * @returns The resolved icon value
145
145
  */
146
- resolveIcon(e, o) {
147
- return o !== void 0 ? o : this.gridIcons[e];
146
+ resolveIcon(e, t) {
147
+ return t !== void 0 ? t : this.gridIcons[e];
148
148
  }
149
149
  /**
150
150
  * Set an icon value on an element.
@@ -153,8 +153,8 @@ class N {
153
153
  * @param element - The element to set the icon on
154
154
  * @param icon - The icon value (string or HTMLElement)
155
155
  */
156
- setIcon(e, o) {
157
- typeof o == "string" ? e.innerHTML = o : o instanceof HTMLElement && (e.innerHTML = "", e.appendChild(o.cloneNode(!0)));
156
+ setIcon(e, t) {
157
+ typeof t == "string" ? e.innerHTML = t : t instanceof HTMLElement && (e.innerHTML = "", e.appendChild(t.cloneNode(!0)));
158
158
  }
159
159
  /**
160
160
  * Log a warning message.
@@ -165,48 +165,48 @@ class N {
165
165
  // #endregion
166
166
  }
167
167
  const m = {
168
- sum: (t, e) => t.reduce((o, i) => o + (Number(i[e]) || 0), 0),
169
- avg: (t, e) => {
170
- const o = t.reduce((i, r) => i + (Number(r[e]) || 0), 0);
171
- return t.length ? o / t.length : 0;
168
+ sum: (i, e) => i.reduce((t, o) => t + (Number(o[e]) || 0), 0),
169
+ avg: (i, e) => {
170
+ const t = i.reduce((o, n) => o + (Number(n[e]) || 0), 0);
171
+ return i.length ? t / i.length : 0;
172
172
  },
173
- count: (t) => t.length,
174
- min: (t, e) => Math.min(...t.map((o) => Number(o[e]) || 1 / 0)),
175
- max: (t, e) => Math.max(...t.map((o) => Number(o[e]) || -1 / 0)),
176
- first: (t, e) => t[0]?.[e],
177
- last: (t, e) => t[t.length - 1]?.[e]
173
+ count: (i) => i.length,
174
+ min: (i, e) => Math.min(...i.map((t) => Number(t[e]) || 1 / 0)),
175
+ max: (i, e) => Math.max(...i.map((t) => Number(t[e]) || -1 / 0)),
176
+ first: (i, e) => i[0]?.[e],
177
+ last: (i, e) => i[i.length - 1]?.[e]
178
178
  }, v = /* @__PURE__ */ new Map(), h = {
179
179
  /**
180
180
  * Register a custom aggregator function.
181
181
  */
182
- register(t, e) {
183
- v.set(t, e);
182
+ register(i, e) {
183
+ v.set(i, e);
184
184
  },
185
185
  /**
186
186
  * Unregister a custom aggregator function.
187
187
  */
188
- unregister(t) {
189
- v.delete(t);
188
+ unregister(i) {
189
+ v.delete(i);
190
190
  },
191
191
  /**
192
192
  * Get an aggregator function by reference.
193
193
  */
194
- get(t) {
195
- if (t !== void 0)
196
- return typeof t == "function" ? t : v.get(t) ?? m[t];
194
+ get(i) {
195
+ if (i !== void 0)
196
+ return typeof i == "function" ? i : v.get(i) ?? m[i];
197
197
  },
198
198
  /**
199
199
  * Run an aggregator on a set of rows.
200
200
  */
201
- run(t, e, o, i) {
202
- const r = this.get(t);
203
- return r ? r(e, o, i) : void 0;
201
+ run(i, e, t, o) {
202
+ const n = this.get(i);
203
+ return n ? n(e, t, o) : void 0;
204
204
  },
205
205
  /**
206
206
  * Check if an aggregator exists.
207
207
  */
208
- has(t) {
209
- return v.has(t) || t in m;
208
+ has(i) {
209
+ return v.has(i) || i in m;
210
210
  },
211
211
  /**
212
212
  * List all available aggregator names.
@@ -215,98 +215,98 @@ const m = {
215
215
  return [...Object.keys(m), ...v.keys()];
216
216
  }
217
217
  }, A = {
218
- sum: (t) => t.reduce((e, o) => e + o, 0),
219
- avg: (t) => t.length ? t.reduce((e, o) => e + o, 0) / t.length : 0,
220
- count: (t) => t.length,
221
- min: (t) => t.length ? Math.min(...t) : 0,
222
- max: (t) => t.length ? Math.max(...t) : 0,
223
- first: (t) => t[0] ?? 0,
224
- last: (t) => t[t.length - 1] ?? 0
218
+ sum: (i) => i.reduce((e, t) => e + t, 0),
219
+ avg: (i) => i.length ? i.reduce((e, t) => e + t, 0) / i.length : 0,
220
+ count: (i) => i.length,
221
+ min: (i) => i.length ? Math.min(...i) : 0,
222
+ max: (i) => i.length ? Math.max(...i) : 0,
223
+ first: (i) => i[0] ?? 0,
224
+ last: (i) => i[i.length - 1] ?? 0
225
225
  };
226
- function k(t) {
227
- return A[t] ?? A.sum;
226
+ function N(i) {
227
+ return A[i] ?? A.sum;
228
228
  }
229
229
  h.register.bind(h);
230
230
  h.unregister.bind(h);
231
231
  h.get.bind(h);
232
232
  h.run.bind(h);
233
233
  h.list.bind(h);
234
- const K = k;
235
- function I(t) {
234
+ const K = N;
235
+ function S(i) {
236
236
  const e = [];
237
- return !t.rowGroupFields?.length && !t.columnGroupFields?.length && e.push("At least one row or column group field is required"), t.valueFields?.length || e.push("At least one value field is required"), e;
237
+ return !i.rowGroupFields?.length && !i.columnGroupFields?.length && e.push("At least one row or column group field is required"), i.valueFields?.length || e.push("At least one value field is required"), e;
238
238
  }
239
- function C(t, e) {
240
- return [...t, e].join("|");
239
+ function C(i, e) {
240
+ return [...i, e].join("|");
241
241
  }
242
- function S(t, e) {
243
- const o = e.rowGroupFields ?? [], i = e.columnGroupFields ?? [], r = e.valueFields ?? [], n = V(t, i), s = L(
242
+ function I(i, e) {
243
+ const t = e.rowGroupFields ?? [], o = e.columnGroupFields ?? [], n = e.valueFields ?? [], r = V(i, o), s = L(
244
+ i,
244
245
  t,
245
246
  o,
246
- i,
247
- n,
248
247
  r,
248
+ n,
249
249
  0,
250
250
  // starting depth
251
251
  ""
252
252
  // parent key prefix
253
- ), a = H(s, n, r), l = Object.values(a).reduce((d, c) => d + c, 0);
253
+ ), a = D(s, r, n), l = Object.values(a).reduce((d, c) => d + c, 0);
254
254
  return {
255
255
  rows: s,
256
- columnKeys: n,
256
+ columnKeys: r,
257
257
  totals: a,
258
258
  grandTotal: l
259
259
  };
260
260
  }
261
- function V(t, e) {
261
+ function V(i, e) {
262
262
  if (e.length === 0) return ["value"];
263
- const o = /* @__PURE__ */ new Set();
264
- for (const i of t) {
265
- const r = e.map((n) => String(i[n] ?? "")).join("|");
266
- o.add(r);
263
+ const t = /* @__PURE__ */ new Set();
264
+ for (const o of i) {
265
+ const n = e.map((r) => String(o[r] ?? "")).join("|");
266
+ t.add(n);
267
267
  }
268
- return [...o].sort();
268
+ return [...t].sort();
269
269
  }
270
- function M(t, e) {
271
- const o = /* @__PURE__ */ new Map();
272
- for (const i of t) {
273
- const r = String(i[e] ?? ""), n = o.get(r);
274
- n ? n.push(i) : o.set(r, [i]);
270
+ function M(i, e) {
271
+ const t = /* @__PURE__ */ new Map();
272
+ for (const o of i) {
273
+ const n = String(o[e] ?? ""), r = t.get(n);
274
+ r ? r.push(o) : t.set(n, [o]);
275
275
  }
276
- return o;
276
+ return t;
277
277
  }
278
- function L(t, e, o, i, r, n, s) {
278
+ function L(i, e, t, o, n, r, s) {
279
279
  const a = [];
280
280
  if (e.length === 0) {
281
- const u = T(t, o, i, r), g = _(u);
281
+ const u = T(i, t, o, n), g = _(u);
282
282
  return a.push({
283
283
  rowKey: s || "all",
284
284
  rowLabel: s || "All",
285
- depth: n,
285
+ depth: r,
286
286
  values: u,
287
287
  total: g,
288
288
  isGroup: !1,
289
- rowCount: t.length
289
+ rowCount: i.length
290
290
  }), a;
291
291
  }
292
- const l = e[0], d = e.slice(1), c = d.length > 0, p = M(t, l);
292
+ const l = e[0], d = e.slice(1), c = d.length > 0, p = M(i, l);
293
293
  for (const [u, g] of p) {
294
- const F = s ? `${s}|${u}` : u, y = T(g, o, i, r), E = _(y);
294
+ const y = s ? `${s}|${u}` : u, F = T(g, t, o, n), k = _(F);
295
295
  let R;
296
296
  c && (R = L(
297
297
  g,
298
298
  d,
299
+ t,
299
300
  o,
300
- i,
301
- r,
302
- n + 1,
303
- F
301
+ n,
302
+ r + 1,
303
+ y
304
304
  )), a.push({
305
- rowKey: F,
305
+ rowKey: y,
306
306
  rowLabel: u || "(blank)",
307
- depth: n,
308
- values: y,
309
- total: E,
307
+ depth: r,
308
+ values: F,
309
+ total: k,
310
310
  isGroup: c,
311
311
  children: R,
312
312
  rowCount: g.length
@@ -314,204 +314,204 @@ function L(t, e, o, i, r, n, s) {
314
314
  }
315
315
  return a;
316
316
  }
317
- function T(t, e, o, i) {
318
- const r = {};
319
- for (const n of o)
320
- for (const s of i) {
321
- const l = (e.length > 0 ? t.filter((u) => e.map((g) => String(u[g] ?? "")).join("|") === n) : t).map((u) => Number(u[s.field]) || 0), d = K(s.aggFunc), c = l.length > 0 ? d(l) : null, p = C([n], s.field);
322
- r[p] = c;
317
+ function T(i, e, t, o) {
318
+ const n = {};
319
+ for (const r of t)
320
+ for (const s of o) {
321
+ const l = (e.length > 0 ? i.filter((u) => e.map((g) => String(u[g] ?? "")).join("|") === r) : i).map((u) => Number(u[s.field]) || 0), d = K(s.aggFunc), c = l.length > 0 ? d(l) : null, p = C([r], s.field);
322
+ n[p] = c;
323
323
  }
324
- return r;
324
+ return n;
325
325
  }
326
- function _(t) {
326
+ function _(i) {
327
327
  let e = 0;
328
- for (const o of Object.values(t))
329
- e += o ?? 0;
328
+ for (const t of Object.values(i))
329
+ e += t ?? 0;
330
330
  return e;
331
331
  }
332
- function H(t, e, o) {
333
- const i = {};
334
- function r(n) {
335
- for (const s of n)
332
+ function D(i, e, t) {
333
+ const o = {};
334
+ function n(r) {
335
+ for (const s of r)
336
336
  if (!s.isGroup || !s.children?.length)
337
337
  for (const a of e)
338
- for (const l of o) {
338
+ for (const l of t) {
339
339
  const d = C([a], l.field);
340
- i[d] = (i[d] ?? 0) + (s.values[d] ?? 0);
340
+ o[d] = (o[d] ?? 0) + (s.values[d] ?? 0);
341
341
  }
342
- else s.children && r(s.children);
342
+ else s.children && n(s.children);
343
343
  }
344
- return r(t), i;
344
+ return n(i), o;
345
345
  }
346
- function D(t, e, o = !0) {
347
- const i = [];
348
- function r(n) {
349
- i.push(n);
350
- const s = e ? e.has(n.rowKey) : o;
351
- if (n.children && s)
352
- for (const a of n.children)
353
- r(a);
354
- }
355
- for (const n of t)
356
- r(n);
357
- return i;
346
+ function H(i, e, t = !0) {
347
+ const o = [];
348
+ function n(r) {
349
+ o.push(r);
350
+ const s = e ? e.has(r.rowKey) : t;
351
+ if (r.children && s)
352
+ for (const a of r.children)
353
+ n(a);
354
+ }
355
+ for (const r of i)
356
+ n(r);
357
+ return o;
358
358
  }
359
- function w(t) {
359
+ function w(i) {
360
360
  const e = [];
361
- function o(i) {
362
- if (i.isGroup && e.push(i.rowKey), i.children)
363
- for (const r of i.children)
364
- o(r);
361
+ function t(o) {
362
+ if (o.isGroup && e.push(o.rowKey), o.children)
363
+ for (const n of o.children)
364
+ t(n);
365
365
  }
366
- for (const i of t)
367
- o(i);
366
+ for (const o of i)
367
+ t(o);
368
368
  return e;
369
369
  }
370
- const z = ["sum", "avg", "count", "min", "max", "first", "last"];
371
- function q(t, e, o, i) {
372
- const r = new AbortController(), n = { config: e, callbacks: i, signal: r.signal }, s = document.createElement("div");
373
- return s.className = "tbw-pivot-panel", s.appendChild(f("Options", () => U(o, n))), s.appendChild(f("Row Groups", () => G("rowGroups", n))), s.appendChild(f("Column Groups", () => G("columnGroups", n))), s.appendChild(f("Values", () => Z(n))), s.appendChild(f("Available Fields", () => j(n))), t.appendChild(s), () => {
374
- r.abort(), s.remove();
370
+ const q = ["sum", "avg", "count", "min", "max", "first", "last"];
371
+ function z(i, e, t, o) {
372
+ const n = new AbortController(), r = { config: e, callbacks: o, signal: n.signal }, s = document.createElement("div");
373
+ return s.className = "tbw-pivot-panel", s.appendChild(f("Options", () => U(t, r))), s.appendChild(f("Row Groups", () => G("rowGroups", r))), s.appendChild(f("Column Groups", () => G("columnGroups", r))), s.appendChild(f("Values", () => Z(r))), s.appendChild(f("Available Fields", () => j(r))), i.appendChild(s), () => {
374
+ n.abort(), s.remove();
375
375
  };
376
376
  }
377
- function f(t, e) {
377
+ function f(i, e) {
378
+ const t = document.createElement("div");
379
+ t.className = "tbw-pivot-section";
378
380
  const o = document.createElement("div");
379
- o.className = "tbw-pivot-section";
380
- const i = document.createElement("div");
381
- i.className = "tbw-pivot-section-header", i.textContent = t;
382
- const r = document.createElement("div");
383
- return r.className = "tbw-pivot-section-content", r.appendChild(e()), o.appendChild(i), o.appendChild(r), o;
381
+ o.className = "tbw-pivot-section-header", o.textContent = i;
382
+ const n = document.createElement("div");
383
+ return n.className = "tbw-pivot-section-content", n.appendChild(e()), t.appendChild(o), t.appendChild(n), t;
384
384
  }
385
- function G(t, e) {
386
- const { config: o, callbacks: i, signal: r } = e, n = document.createElement("div");
387
- n.className = "tbw-pivot-drop-zone", n.setAttribute("data-zone", t);
388
- const s = t === "rowGroups" ? o.rowGroupFields ?? [] : o.columnGroupFields ?? [];
385
+ function G(i, e) {
386
+ const { config: t, callbacks: o, signal: n } = e, r = document.createElement("div");
387
+ r.className = "tbw-pivot-drop-zone", r.setAttribute("data-zone", i);
388
+ const s = i === "rowGroups" ? t.rowGroupFields ?? [] : t.columnGroupFields ?? [];
389
389
  if (s.length === 0) {
390
390
  const a = document.createElement("div");
391
- a.className = "tbw-pivot-placeholder", a.textContent = "Drag fields here or click to add", n.appendChild(a);
391
+ a.className = "tbw-pivot-placeholder", a.textContent = "Drag fields here or click to add", r.appendChild(a);
392
392
  } else
393
393
  for (const a of s)
394
- n.appendChild(O(a, t, e));
395
- return n.addEventListener(
394
+ r.appendChild(O(a, i, e));
395
+ return r.addEventListener(
396
396
  "dragover",
397
397
  (a) => {
398
- a.preventDefault(), n.classList.add("drag-over");
398
+ a.preventDefault(), r.classList.add("drag-over");
399
399
  },
400
- { signal: r }
401
- ), n.addEventListener(
400
+ { signal: n }
401
+ ), r.addEventListener(
402
402
  "dragleave",
403
403
  () => {
404
- n.classList.remove("drag-over");
404
+ r.classList.remove("drag-over");
405
405
  },
406
- { signal: r }
407
- ), n.addEventListener(
406
+ { signal: n }
407
+ ), r.addEventListener(
408
408
  "drop",
409
409
  (a) => {
410
- a.preventDefault(), n.classList.remove("drag-over");
410
+ a.preventDefault(), r.classList.remove("drag-over");
411
411
  const l = a.dataTransfer?.getData("text/plain");
412
- l && i.onAddFieldToZone(l, t);
412
+ l && o.onAddFieldToZone(l, i);
413
413
  },
414
- { signal: r }
415
- ), n;
414
+ { signal: n }
415
+ ), r;
416
416
  }
417
- function O(t, e, o) {
418
- const { callbacks: i, signal: r } = o, n = document.createElement("div");
419
- n.className = "tbw-pivot-field-chip", n.draggable = !0;
420
- const s = i.getAvailableFields().find((d) => d.field === t), a = document.createElement("span");
421
- a.className = "tbw-pivot-chip-label", a.textContent = s?.header ?? t;
417
+ function O(i, e, t) {
418
+ const { callbacks: o, signal: n } = t, r = document.createElement("div");
419
+ r.className = "tbw-pivot-field-chip", r.draggable = !0;
420
+ const s = o.getAvailableFields().find((d) => d.field === i), a = document.createElement("span");
421
+ a.className = "tbw-pivot-chip-label", a.textContent = s?.header ?? i;
422
422
  const l = document.createElement("button");
423
423
  return l.className = "tbw-pivot-chip-remove", l.innerHTML = "×", l.title = "Remove field", l.addEventListener(
424
424
  "click",
425
425
  (d) => {
426
- d.stopPropagation(), i.onRemoveFieldFromZone(t, e);
426
+ d.stopPropagation(), o.onRemoveFieldFromZone(i, e);
427
427
  },
428
- { signal: r }
429
- ), n.appendChild(a), n.appendChild(l), n.addEventListener(
428
+ { signal: n }
429
+ ), r.appendChild(a), r.appendChild(l), r.addEventListener(
430
430
  "dragstart",
431
431
  (d) => {
432
- d.dataTransfer?.setData("text/plain", t), d.dataTransfer?.setData("source-zone", e), n.classList.add("dragging");
432
+ d.dataTransfer?.setData("text/plain", i), d.dataTransfer?.setData("source-zone", e), r.classList.add("dragging");
433
433
  },
434
- { signal: r }
435
- ), n.addEventListener(
434
+ { signal: n }
435
+ ), r.addEventListener(
436
436
  "dragend",
437
437
  () => {
438
- n.classList.remove("dragging");
438
+ r.classList.remove("dragging");
439
439
  },
440
- { signal: r }
441
- ), n;
440
+ { signal: n }
441
+ ), r;
442
442
  }
443
- function Z(t) {
444
- const { config: e, callbacks: o, signal: i } = t, r = document.createElement("div");
445
- r.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", r.setAttribute("data-zone", "values");
446
- const n = e.valueFields ?? [];
447
- if (n.length === 0) {
443
+ function Z(i) {
444
+ const { config: e, callbacks: t, signal: o } = i, n = document.createElement("div");
445
+ n.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", n.setAttribute("data-zone", "values");
446
+ const r = e.valueFields ?? [];
447
+ if (r.length === 0) {
448
448
  const s = document.createElement("div");
449
- s.className = "tbw-pivot-placeholder", s.textContent = "Drag numeric fields here for aggregation", r.appendChild(s);
449
+ s.className = "tbw-pivot-placeholder", s.textContent = "Drag numeric fields here for aggregation", n.appendChild(s);
450
450
  } else
451
- for (const s of n)
452
- r.appendChild($(s, t));
453
- return r.addEventListener(
451
+ for (const s of r)
452
+ n.appendChild($(s, i));
453
+ return n.addEventListener(
454
454
  "dragover",
455
455
  (s) => {
456
- s.preventDefault(), r.classList.add("drag-over");
456
+ s.preventDefault(), n.classList.add("drag-over");
457
457
  },
458
- { signal: i }
459
- ), r.addEventListener(
458
+ { signal: o }
459
+ ), n.addEventListener(
460
460
  "dragleave",
461
461
  () => {
462
- r.classList.remove("drag-over");
462
+ n.classList.remove("drag-over");
463
463
  },
464
- { signal: i }
465
- ), r.addEventListener(
464
+ { signal: o }
465
+ ), n.addEventListener(
466
466
  "drop",
467
467
  (s) => {
468
- s.preventDefault(), r.classList.remove("drag-over");
468
+ s.preventDefault(), n.classList.remove("drag-over");
469
469
  const a = s.dataTransfer?.getData("text/plain");
470
- a && o.onAddValueField(a, "sum");
470
+ a && t.onAddValueField(a, "sum");
471
471
  },
472
- { signal: i }
473
- ), r;
472
+ { signal: o }
473
+ ), n;
474
474
  }
475
- function $(t, e) {
476
- const { callbacks: o, signal: i } = e, r = document.createElement("div");
477
- r.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
478
- const n = o.getAvailableFields().find((c) => c.field === t.field), s = document.createElement("div");
475
+ function $(i, e) {
476
+ const { callbacks: t, signal: o } = e, n = document.createElement("div");
477
+ n.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
478
+ const r = t.getAvailableFields().find((c) => c.field === i.field), s = document.createElement("div");
479
479
  s.className = "tbw-pivot-value-label-wrapper";
480
480
  const a = document.createElement("span");
481
- a.className = "tbw-pivot-chip-label", a.textContent = n?.header ?? t.field;
481
+ a.className = "tbw-pivot-chip-label", a.textContent = r?.header ?? i.field;
482
482
  const l = document.createElement("select");
483
483
  l.className = "tbw-pivot-agg-select", l.title = "Aggregation function";
484
- for (const c of z) {
484
+ for (const c of q) {
485
485
  const p = document.createElement("option");
486
- p.value = c, p.textContent = c.toUpperCase(), p.selected = c === t.aggFunc, l.appendChild(p);
486
+ p.value = c, p.textContent = c.toUpperCase(), p.selected = c === i.aggFunc, l.appendChild(p);
487
487
  }
488
488
  l.addEventListener(
489
489
  "change",
490
490
  () => {
491
- o.onUpdateValueAggFunc(t.field, l.value);
491
+ t.onUpdateValueAggFunc(i.field, l.value);
492
492
  },
493
- { signal: i }
493
+ { signal: o }
494
494
  );
495
495
  const d = document.createElement("button");
496
496
  return d.className = "tbw-pivot-chip-remove", d.innerHTML = "×", d.title = "Remove value field", d.addEventListener(
497
497
  "click",
498
498
  (c) => {
499
- c.stopPropagation(), o.onRemoveValueField(t.field);
499
+ c.stopPropagation(), t.onRemoveValueField(i.field);
500
500
  },
501
- { signal: i }
502
- ), s.appendChild(a), s.appendChild(l), r.appendChild(s), r.appendChild(d), r;
501
+ { signal: o }
502
+ ), s.appendChild(a), s.appendChild(l), n.appendChild(s), n.appendChild(d), n;
503
503
  }
504
- function j(t) {
505
- const { config: e, callbacks: o, signal: i } = t, r = document.createElement("div");
506
- r.className = "tbw-pivot-available-fields";
507
- const n = o.getAvailableFields(), s = /* @__PURE__ */ new Set([
504
+ function j(i) {
505
+ const { config: e, callbacks: t, signal: o } = i, n = document.createElement("div");
506
+ n.className = "tbw-pivot-available-fields";
507
+ const r = t.getAvailableFields(), s = /* @__PURE__ */ new Set([
508
508
  ...e.rowGroupFields ?? [],
509
509
  ...e.columnGroupFields ?? [],
510
510
  ...e.valueFields?.map((l) => l.field) ?? []
511
- ]), a = n.filter((l) => !s.has(l.field));
511
+ ]), a = r.filter((l) => !s.has(l.field));
512
512
  if (a.length === 0) {
513
513
  const l = document.createElement("div");
514
- l.className = "tbw-pivot-placeholder", l.textContent = "All fields are in use", r.appendChild(l);
514
+ l.className = "tbw-pivot-placeholder", l.textContent = "All fields are in use", n.appendChild(l);
515
515
  } else
516
516
  for (const l of a) {
517
517
  const d = document.createElement("div");
@@ -520,107 +520,107 @@ function j(t) {
520
520
  (c) => {
521
521
  c.dataTransfer?.setData("text/plain", l.field), d.classList.add("dragging");
522
522
  },
523
- { signal: i }
523
+ { signal: o }
524
524
  ), d.addEventListener(
525
525
  "dragend",
526
526
  () => {
527
527
  d.classList.remove("dragging");
528
528
  },
529
- { signal: i }
530
- ), r.appendChild(d);
529
+ { signal: o }
530
+ ), n.appendChild(d);
531
531
  }
532
- return r;
532
+ return n;
533
533
  }
534
- function U(t, e) {
535
- const { config: o, callbacks: i, signal: r } = e, n = document.createElement("div");
536
- return n.className = "tbw-pivot-options", n.appendChild(
534
+ function U(i, e) {
535
+ const { config: t, callbacks: o, signal: n } = e, r = document.createElement("div");
536
+ return r.className = "tbw-pivot-options", r.appendChild(
537
537
  x(
538
538
  "Enable Pivot View",
539
- t,
539
+ i,
540
540
  (s) => {
541
- i.onTogglePivot(s);
541
+ o.onTogglePivot(s);
542
542
  },
543
- r
543
+ n
544
544
  )
545
- ), n.appendChild(
545
+ ), r.appendChild(
546
546
  x(
547
547
  "Show Row Totals",
548
- o.showTotals ?? !0,
548
+ t.showTotals ?? !0,
549
549
  (s) => {
550
- i.onOptionChange("showTotals", s);
550
+ o.onOptionChange("showTotals", s);
551
551
  },
552
- r
552
+ n
553
553
  )
554
- ), n.appendChild(
554
+ ), r.appendChild(
555
555
  x(
556
556
  "Show Grand Total",
557
- o.showGrandTotal ?? !0,
557
+ t.showGrandTotal ?? !0,
558
558
  (s) => {
559
- i.onOptionChange("showGrandTotal", s);
559
+ o.onOptionChange("showGrandTotal", s);
560
560
  },
561
- r
561
+ n
562
562
  )
563
- ), n;
563
+ ), r;
564
564
  }
565
- function x(t, e, o, i) {
566
- const r = document.createElement("label");
567
- r.className = "tbw-pivot-checkbox";
568
- const n = document.createElement("input");
569
- n.type = "checkbox", n.checked = e, n.addEventListener("change", () => o(n.checked), { signal: i });
565
+ function x(i, e, t, o) {
566
+ const n = document.createElement("label");
567
+ n.className = "tbw-pivot-checkbox";
568
+ const r = document.createElement("input");
569
+ r.type = "checkbox", r.checked = e, r.addEventListener("change", () => t(r.checked), { signal: o });
570
570
  const s = document.createElement("span");
571
- return s.textContent = t, r.appendChild(n), r.appendChild(s), r;
571
+ return s.textContent = i, n.appendChild(r), n.appendChild(s), n;
572
572
  }
573
- function B(t, e, o) {
574
- return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(t.__pivotDepth ?? 0)), e.setAttribute("role", "row"), e.innerHTML = "", o.columns.forEach((i, r) => {
575
- const n = document.createElement("div");
576
- if (n.className = "cell", n.setAttribute("data-col", String(r)), n.setAttribute("role", "gridcell"), r === 0) {
577
- const s = Number(t.__pivotIndent) || 0;
578
- n.style.paddingLeft = `${s}px`;
579
- const a = String(t.__pivotRowKey), l = document.createElement("button");
580
- l.type = "button", l.className = "pivot-toggle", l.setAttribute("aria-label", t.__pivotExpanded ? "Collapse group" : "Expand group"), o.setIcon(l, o.resolveIcon(t.__pivotExpanded ? "collapse" : "expand")), l.addEventListener("click", (p) => {
581
- p.stopPropagation(), o.onToggle(a);
582
- }), n.appendChild(l);
573
+ function B(i, e, t) {
574
+ return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(i.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(i.__pivotRowKey ?? "")), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((o, n) => {
575
+ const r = document.createElement("div");
576
+ if (r.className = "cell", r.setAttribute("data-col", String(n)), r.setAttribute("role", "gridcell"), n === 0) {
577
+ const s = Number(i.__pivotIndent) || 0;
578
+ r.style.paddingLeft = `${s}px`;
579
+ const a = String(i.__pivotRowKey), l = document.createElement("button");
580
+ l.type = "button", l.className = "pivot-toggle", l.setAttribute("aria-label", i.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(l, t.resolveIcon(i.__pivotExpanded ? "collapse" : "expand")), l.addEventListener("click", (p) => {
581
+ p.stopPropagation(), t.onToggle(a);
582
+ }), r.appendChild(l);
583
583
  const d = document.createElement("span");
584
- d.className = "pivot-label", d.textContent = String(t.__pivotLabel ?? ""), n.appendChild(d);
584
+ d.className = "pivot-label", d.textContent = String(i.__pivotLabel ?? ""), r.appendChild(d);
585
585
  const c = document.createElement("span");
586
- c.className = "pivot-count", c.textContent = ` (${Number(t.__pivotRowCount) || 0})`, n.appendChild(c);
586
+ c.className = "pivot-count", c.textContent = ` (${Number(i.__pivotRowCount) || 0})`, r.appendChild(c);
587
587
  } else {
588
- const s = t[i.field];
589
- n.textContent = s != null ? String(s) : "";
588
+ const s = i[o.field];
589
+ r.textContent = s != null ? String(s) : "";
590
590
  }
591
- e.appendChild(n);
591
+ e.appendChild(r);
592
592
  }), !0;
593
593
  }
594
- function W(t, e, o) {
595
- return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(t.__pivotDepth ?? 0)), e.innerHTML = "", o.forEach((i, r) => {
596
- const n = document.createElement("div");
597
- if (n.className = "cell", n.setAttribute("data-col", String(r)), n.setAttribute("role", "gridcell"), r === 0) {
598
- const s = Number(t.__pivotIndent) || 0;
599
- n.style.paddingLeft = `${s + 20}px`;
594
+ function W(i, e, t) {
595
+ return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(i.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(i.__pivotRowKey ?? "")), e.innerHTML = "", t.forEach((o, n) => {
596
+ const r = document.createElement("div");
597
+ if (r.className = "cell", r.setAttribute("data-col", String(n)), r.setAttribute("role", "gridcell"), n === 0) {
598
+ const s = Number(i.__pivotIndent) || 0;
599
+ r.style.paddingLeft = `${s + 20}px`;
600
600
  const a = document.createElement("span");
601
- a.className = "pivot-label", a.textContent = String(t.__pivotLabel ?? ""), n.appendChild(a);
601
+ a.className = "pivot-label", a.textContent = String(i.__pivotLabel ?? ""), r.appendChild(a);
602
602
  } else {
603
- const s = t[i.field];
604
- n.textContent = s != null ? String(s) : "";
603
+ const s = i[o.field];
604
+ r.textContent = s != null ? String(s) : "";
605
605
  }
606
- e.appendChild(n);
606
+ e.appendChild(r);
607
607
  }), !0;
608
608
  }
609
- function J(t, e, o) {
610
- return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", o.forEach((i, r) => {
611
- const n = document.createElement("div");
612
- if (n.className = "cell", n.setAttribute("data-col", String(r)), r === 0) {
609
+ function J(i, e, t) {
610
+ return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", t.forEach((o, n) => {
611
+ const r = document.createElement("div");
612
+ if (r.className = "cell", r.setAttribute("data-col", String(n)), n === 0) {
613
613
  const s = document.createElement("span");
614
- s.className = "pivot-label", s.textContent = "Grand Total", n.appendChild(s);
614
+ s.className = "pivot-label", s.textContent = "Grand Total", r.appendChild(s);
615
615
  } else {
616
- const s = t[i.field];
617
- n.textContent = s != null ? String(s) : "";
616
+ const s = i[o.field];
617
+ r.textContent = s != null ? String(s) : "";
618
618
  }
619
- e.appendChild(n);
619
+ e.appendChild(r);
620
620
  }), !0;
621
621
  }
622
- const Q = '.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}';
623
- class b extends N {
622
+ const Q = '.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}}';
623
+ class b extends P {
624
624
  name = "pivot";
625
625
  version = "1.0.0";
626
626
  /** Tool panel ID for shell integration */
@@ -630,7 +630,8 @@ class b extends N {
630
630
  active: !0,
631
631
  showTotals: !0,
632
632
  showGrandTotal: !0,
633
- showToolPanel: !0
633
+ showToolPanel: !0,
634
+ animation: "slide"
634
635
  };
635
636
  }
636
637
  // #region Internal State
@@ -643,16 +644,31 @@ class b extends N {
643
644
  originalColumns = [];
644
645
  panelContainer = null;
645
646
  grandTotalFooter = null;
647
+ previousVisibleKeys = /* @__PURE__ */ new Set();
648
+ keysToAnimate = /* @__PURE__ */ new Set();
646
649
  /**
647
650
  * Check if the plugin has valid pivot configuration (at least value fields).
648
651
  */
649
652
  hasValidPivotConfig() {
650
653
  return (this.config.valueFields?.length ?? 0) > 0;
651
654
  }
655
+ /**
656
+ * Get animation style respecting grid-level animation mode.
657
+ */
658
+ get animationStyle() {
659
+ const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
660
+ if (t === !1 || t === "off") return !1;
661
+ if (t !== !0 && t !== "on") {
662
+ const o = this.shadowRoot?.host;
663
+ if (o && getComputedStyle(o).getPropertyValue("--tbw-animation-enabled").trim() === "0")
664
+ return !1;
665
+ }
666
+ return this.config.animation ?? "slide";
667
+ }
652
668
  // #endregion
653
669
  // #region Lifecycle
654
670
  detach() {
655
- this.isActive = !1, this.hasInitialized = !1, this.pivotResult = null, this.fieldHeaderMap.clear(), this.originalColumns = [], this.panelContainer = null, this.cleanupGrandTotalFooter();
671
+ 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();
656
672
  }
657
673
  // #endregion
658
674
  // #region Shell Integration
@@ -664,7 +680,7 @@ class b extends N {
664
680
  icon: "⊞",
665
681
  tooltip: "Configure pivot table",
666
682
  order: 90,
667
- render: (o) => this.renderPanel(o)
683
+ render: (t) => this.renderPanel(t)
668
684
  };
669
685
  }
670
686
  // #endregion
@@ -672,71 +688,77 @@ class b extends N {
672
688
  processRows(e) {
673
689
  if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
674
690
  return [...e];
675
- const o = I(this.config);
676
- if (o.length > 0)
677
- return this.warn(`Config errors: ${o.join(", ")}`), [...e];
691
+ const t = S(this.config);
692
+ if (t.length > 0)
693
+ return this.warn(`Config errors: ${t.join(", ")}`), [...e];
678
694
  if (this.buildFieldHeaderMap(), this.defaultExpanded = this.config.defaultExpanded ?? !0, this.expandedKeys.size === 0 && this.defaultExpanded && this.pivotResult) {
679
- const n = w(this.pivotResult.rows);
680
- for (const s of n)
681
- this.expandedKeys.add(s);
695
+ const s = w(this.pivotResult.rows);
696
+ for (const a of s)
697
+ this.expandedKeys.add(a);
682
698
  }
683
- if (this.pivotResult = S(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
684
- const n = w(this.pivotResult.rows);
685
- for (const s of n)
686
- this.expandedKeys.add(s);
699
+ if (this.pivotResult = I(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
700
+ const s = w(this.pivotResult.rows);
701
+ for (const a of s)
702
+ this.expandedKeys.add(a);
687
703
  }
688
- const i = this.config.indentWidth ?? 20;
689
- return D(
704
+ const o = this.config.indentWidth ?? 20, n = H(
690
705
  this.pivotResult.rows,
691
706
  this.expandedKeys,
692
707
  this.defaultExpanded
693
- ).map((n) => ({
694
- __pivotRowKey: n.rowKey,
695
- __pivotLabel: n.rowLabel,
696
- __pivotDepth: n.depth,
697
- __pivotIsGroup: n.isGroup,
698
- __pivotHasChildren: !!n.children?.length,
699
- __pivotExpanded: this.expandedKeys.has(n.rowKey),
700
- __pivotRowCount: n.rowCount ?? 0,
701
- __pivotIndent: n.depth * i,
702
- __pivotTotal: n.total,
703
- ...n.values
708
+ ).map((s) => ({
709
+ __pivotRowKey: s.rowKey,
710
+ __pivotLabel: s.rowLabel,
711
+ __pivotDepth: s.depth,
712
+ __pivotIsGroup: s.isGroup,
713
+ __pivotHasChildren: !!s.children?.length,
714
+ __pivotExpanded: this.expandedKeys.has(s.rowKey),
715
+ __pivotRowCount: s.rowCount ?? 0,
716
+ __pivotIndent: s.depth * o,
717
+ __pivotTotal: s.total,
718
+ ...s.values
704
719
  }));
720
+ this.keysToAnimate.clear();
721
+ const r = /* @__PURE__ */ new Set();
722
+ for (const s of n) {
723
+ const a = s.__pivotRowKey;
724
+ r.add(a), !this.previousVisibleKeys.has(a) && s.__pivotDepth > 0 && this.keysToAnimate.add(a);
725
+ }
726
+ return this.previousVisibleKeys = r, n;
705
727
  }
706
728
  processColumns(e) {
707
729
  if (!this.isActive || !this.pivotResult)
708
730
  return [...e];
709
- const o = [], i = (this.config.rowGroupFields ?? []).map((r) => this.fieldHeaderMap.get(r) ?? r).join(" / ");
710
- o.push({
731
+ const t = [], o = (this.config.rowGroupFields ?? []).map((n) => this.fieldHeaderMap.get(n) ?? n).join(" / ");
732
+ t.push({
711
733
  field: "__pivotLabel",
712
- header: i || "Group",
734
+ header: o || "Group",
713
735
  width: 200
714
736
  });
715
- for (const r of this.pivotResult.columnKeys)
716
- for (const n of this.config.valueFields ?? []) {
717
- const s = C([r], n.field), a = n.header || this.fieldHeaderMap.get(n.field) || n.field;
718
- o.push({
737
+ for (const n of this.pivotResult.columnKeys)
738
+ for (const r of this.config.valueFields ?? []) {
739
+ const s = C([n], r.field), a = r.header || this.fieldHeaderMap.get(r.field) || r.field;
740
+ t.push({
719
741
  field: s,
720
- header: `${r} - ${a} (${n.aggFunc})`,
742
+ header: `${n} - ${a} (${r.aggFunc})`,
721
743
  width: 120,
722
744
  type: "number"
723
745
  });
724
746
  }
725
- return this.config.showTotals && o.push({
747
+ return this.config.showTotals && t.push({
726
748
  field: "__pivotTotal",
727
749
  header: "Total",
728
750
  width: 100,
729
751
  type: "number"
730
- }), o;
752
+ }), t;
731
753
  }
732
- renderRow(e, o) {
733
- const i = e;
734
- return i.__pivotRowKey && i.__pivotHasChildren ? B(i, o, {
754
+ renderRow(e, t) {
755
+ const o = e;
756
+ return o.__pivotRowKey && o.__pivotHasChildren ? B(o, t, {
735
757
  columns: this.gridColumns,
736
- onToggle: (r) => this.toggle(r),
737
- resolveIcon: (r) => this.resolveIcon(r),
738
- setIcon: (r, n) => this.setIcon(r, n)
739
- }) : i.__pivotRowKey !== void 0 && this.isActive ? W(i, o, this.gridColumns) : (this.cleanupPivotStyling(o), !1);
758
+ onToggle: (n) => this.toggle(n),
759
+ resolveIcon: (n) => this.resolveIcon(n),
760
+ setIcon: (n, r) => this.setIcon(n, r)
761
+ }) : o.__pivotRowKey !== void 0 && this.isActive ? W(o, t, this.gridColumns) : (this.cleanupPivotStyling(t), !1);
740
762
  }
741
763
  /**
742
764
  * Remove pivot-specific classes, attributes, and inline styles from a row element.
@@ -748,6 +770,16 @@ class b extends N {
748
770
  }
749
771
  afterRender() {
750
772
  this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
773
+ const e = this.animationStyle;
774
+ if (e === !1 || this.keysToAnimate.size === 0) return;
775
+ const t = this.shadowRoot?.querySelector(".rows");
776
+ if (!t) return;
777
+ const o = e === "fade" ? "tbw-pivot-fade-in" : "tbw-pivot-slide-in";
778
+ for (const n of t.querySelectorAll(".pivot-group-row, .pivot-leaf-row")) {
779
+ const r = n.dataset.pivotKey;
780
+ r && this.keysToAnimate.has(r) && (n.classList.add(o), n.addEventListener("animationend", () => n.classList.remove(o), { once: !0 }));
781
+ }
782
+ this.keysToAnimate.clear();
751
783
  }
752
784
  /**
753
785
  * Render the grand total row as a sticky footer pinned to the bottom.
@@ -756,17 +788,17 @@ class b extends N {
756
788
  if (!this.pivotResult) return;
757
789
  const e = this.shadowRoot;
758
790
  if (!e) return;
759
- const o = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
760
- if (!o) return;
761
- this.grandTotalFooter || (this.grandTotalFooter = document.createElement("div"), this.grandTotalFooter.className = "pivot-grand-total-footer", o.appendChild(this.grandTotalFooter));
762
- const i = {
791
+ const t = e.querySelector(".tbw-scroll-area") ?? e.querySelector(".tbw-grid-content") ?? e.children[0];
792
+ if (!t) return;
793
+ this.grandTotalFooter || (this.grandTotalFooter = document.createElement("div"), this.grandTotalFooter.className = "pivot-grand-total-footer", t.appendChild(this.grandTotalFooter));
794
+ const o = {
763
795
  __pivotRowKey: "__grandTotal",
764
796
  __pivotLabel: "Grand Total",
765
797
  __pivotIsGrandTotal: !0,
766
798
  __pivotTotal: this.pivotResult.grandTotal,
767
799
  ...this.pivotResult.totals
768
800
  };
769
- J(i, this.grandTotalFooter, this.gridColumns);
801
+ J(o, this.grandTotalFooter, this.gridColumns);
770
802
  }
771
803
  /**
772
804
  * Remove the grand total footer element.
@@ -788,8 +820,8 @@ class b extends N {
788
820
  expandAll() {
789
821
  if (this.pivotResult) {
790
822
  const e = w(this.pivotResult.rows);
791
- for (const o of e)
792
- this.expandedKeys.add(o);
823
+ for (const t of e)
824
+ this.expandedKeys.add(t);
793
825
  this.requestRender();
794
826
  }
795
827
  }
@@ -847,8 +879,8 @@ class b extends N {
847
879
  buildFieldHeaderMap() {
848
880
  const e = this.getAvailableFields();
849
881
  this.fieldHeaderMap.clear();
850
- for (const o of e)
851
- this.fieldHeaderMap.set(o.field, o.header);
882
+ for (const t of e)
883
+ this.fieldHeaderMap.set(t.field, t.header);
852
884
  }
853
885
  getAvailableFields() {
854
886
  return this.originalColumns.length > 0 ? this.originalColumns : this.captureOriginalColumns();
@@ -856,10 +888,10 @@ class b extends N {
856
888
  captureOriginalColumns() {
857
889
  const e = this.grid;
858
890
  try {
859
- const o = e.getAllColumns?.() ?? e.columns ?? [];
860
- return this.originalColumns = o.filter((i) => !i.field.startsWith("__pivot")).map((i) => ({
861
- field: i.field,
862
- header: i.header ?? i.field
891
+ const t = e.getAllColumns?.() ?? e.columns ?? [];
892
+ return this.originalColumns = t.filter((o) => !o.field.startsWith("__pivot")).map((o) => ({
893
+ field: o.field,
894
+ header: o.header ?? o.field
863
895
  })), this.originalColumns;
864
896
  } catch {
865
897
  return [];
@@ -867,51 +899,51 @@ class b extends N {
867
899
  }
868
900
  renderPanel(e) {
869
901
  this.panelContainer = e, this.originalColumns.length === 0 && this.captureOriginalColumns();
870
- const o = {
871
- onTogglePivot: (i) => {
872
- i ? this.enablePivot() : this.disablePivot(), this.refreshPanel();
902
+ const t = {
903
+ onTogglePivot: (o) => {
904
+ o ? this.enablePivot() : this.disablePivot(), this.refreshPanel();
873
905
  },
874
- onAddFieldToZone: (i, r) => this.addFieldToZone(i, r),
875
- onRemoveFieldFromZone: (i, r) => this.removeFieldFromZone(i, r),
876
- onAddValueField: (i, r) => this.addValueField(i, r),
877
- onRemoveValueField: (i) => this.removeValueField(i),
878
- onUpdateValueAggFunc: (i, r) => this.updateValueAggFunc(i, r),
879
- onOptionChange: (i, r) => {
880
- this.config[i] = r, this.isActive && this.refresh();
906
+ onAddFieldToZone: (o, n) => this.addFieldToZone(o, n),
907
+ onRemoveFieldFromZone: (o, n) => this.removeFieldFromZone(o, n),
908
+ onAddValueField: (o, n) => this.addValueField(o, n),
909
+ onRemoveValueField: (o) => this.removeValueField(o),
910
+ onUpdateValueAggFunc: (o, n) => this.updateValueAggFunc(o, n),
911
+ onOptionChange: (o, n) => {
912
+ this.config[o] = n, this.isActive && this.refresh();
881
913
  },
882
914
  getAvailableFields: () => this.getAvailableFields()
883
915
  };
884
- return q(e, this.config, this.isActive, o);
916
+ return z(e, this.config, this.isActive, t);
885
917
  }
886
918
  refreshPanel() {
887
919
  this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
888
920
  }
889
- addFieldToZone(e, o) {
890
- if (o === "rowGroups") {
891
- const i = this.config.rowGroupFields ?? [];
892
- i.includes(e) || (this.config.rowGroupFields = [...i, e]);
921
+ addFieldToZone(e, t) {
922
+ if (t === "rowGroups") {
923
+ const o = this.config.rowGroupFields ?? [];
924
+ o.includes(e) || (this.config.rowGroupFields = [...o, e]);
893
925
  } else {
894
- const i = this.config.columnGroupFields ?? [];
895
- i.includes(e) || (this.config.columnGroupFields = [...i, e]);
926
+ const o = this.config.columnGroupFields ?? [];
927
+ o.includes(e) || (this.config.columnGroupFields = [...o, e]);
896
928
  }
897
- this.removeFromOtherZones(e, o), this.isActive && this.refresh(), this.refreshPanel();
929
+ this.removeFromOtherZones(e, t), this.isActive && this.refresh(), this.refreshPanel();
898
930
  }
899
- removeFieldFromZone(e, o) {
900
- o === "rowGroups" ? this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((i) => i !== e) : this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((i) => i !== e), this.isActive && this.refresh(), this.refreshPanel();
931
+ removeFieldFromZone(e, t) {
932
+ t === "rowGroups" ? this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((o) => o !== e) : this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((o) => o !== e), this.isActive && this.refresh(), this.refreshPanel();
901
933
  }
902
- removeFromOtherZones(e, o) {
903
- o !== "rowGroups" && (this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((i) => i !== e)), o !== "columnGroups" && (this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((i) => i !== e)), o !== "values" && (this.config.valueFields = (this.config.valueFields ?? []).filter((i) => i.field !== e));
934
+ removeFromOtherZones(e, t) {
935
+ t !== "rowGroups" && (this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((o) => o !== e)), t !== "columnGroups" && (this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((o) => o !== e)), t !== "values" && (this.config.valueFields = (this.config.valueFields ?? []).filter((o) => o.field !== e));
904
936
  }
905
- addValueField(e, o) {
906
- const i = this.config.valueFields ?? [];
907
- i.some((r) => r.field === e) || (this.config.valueFields = [...i, { field: e, aggFunc: o }]), this.removeFromOtherZones(e, "values"), this.isActive && this.refresh(), this.refreshPanel();
937
+ addValueField(e, t) {
938
+ const o = this.config.valueFields ?? [];
939
+ o.some((n) => n.field === e) || (this.config.valueFields = [...o, { field: e, aggFunc: t }]), this.removeFromOtherZones(e, "values"), this.isActive && this.refresh(), this.refreshPanel();
908
940
  }
909
941
  removeValueField(e) {
910
- this.config.valueFields = (this.config.valueFields ?? []).filter((o) => o.field !== e), this.isActive && this.refresh(), this.refreshPanel();
942
+ this.config.valueFields = (this.config.valueFields ?? []).filter((t) => t.field !== e), this.isActive && this.refresh(), this.refreshPanel();
911
943
  }
912
- updateValueAggFunc(e, o) {
913
- const i = this.config.valueFields ?? [], r = i.findIndex((n) => n.field === e);
914
- r >= 0 && (i[r] = { ...i[r], aggFunc: o }, this.config.valueFields = [...i]), this.isActive && this.refresh();
944
+ updateValueAggFunc(e, t) {
945
+ const o = this.config.valueFields ?? [], n = o.findIndex((r) => r.field === e);
946
+ n >= 0 && (o[n] = { ...o[n], aggFunc: t }, this.config.valueFields = [...o]), this.isActive && this.refresh();
915
947
  }
916
948
  // #endregion
917
949
  // #region Styles