@toolbox-web/grid 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/all.d.ts +1 -0
  2. package/all.d.ts.map +1 -1
  3. package/all.js +997 -710
  4. package/all.js.map +1 -1
  5. package/index.js +642 -599
  6. package/index.js.map +1 -1
  7. package/lib/core/grid.d.ts.map +1 -1
  8. package/lib/core/internal/header.d.ts +7 -0
  9. package/lib/core/internal/header.d.ts.map +1 -1
  10. package/lib/core/types.d.ts +151 -0
  11. package/lib/core/types.d.ts.map +1 -1
  12. package/lib/plugins/clipboard/index.js +19 -16
  13. package/lib/plugins/clipboard/index.js.map +1 -1
  14. package/lib/plugins/column-virtualization/index.js +42 -39
  15. package/lib/plugins/column-virtualization/index.js.map +1 -1
  16. package/lib/plugins/context-menu/index.js +25 -22
  17. package/lib/plugins/context-menu/index.js.map +1 -1
  18. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  19. package/lib/plugins/editing/index.js +53 -48
  20. package/lib/plugins/editing/index.js.map +1 -1
  21. package/lib/plugins/export/index.js +23 -20
  22. package/lib/plugins/export/index.js.map +1 -1
  23. package/lib/plugins/filtering/FilteringPlugin.d.ts +11 -1
  24. package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
  25. package/lib/plugins/filtering/index.js +186 -150
  26. package/lib/plugins/filtering/index.js.map +1 -1
  27. package/lib/plugins/grouping-columns/index.js +21 -18
  28. package/lib/plugins/grouping-columns/index.js.map +1 -1
  29. package/lib/plugins/grouping-rows/index.js +67 -64
  30. package/lib/plugins/grouping-rows/index.js.map +1 -1
  31. package/lib/plugins/master-detail/index.js +52 -49
  32. package/lib/plugins/master-detail/index.js.map +1 -1
  33. package/lib/plugins/multi-sort/index.js +18 -15
  34. package/lib/plugins/multi-sort/index.js.map +1 -1
  35. package/lib/plugins/pinned-columns/index.js +25 -22
  36. package/lib/plugins/pinned-columns/index.js.map +1 -1
  37. package/lib/plugins/pinned-rows/index.js +26 -23
  38. package/lib/plugins/pinned-rows/index.js.map +1 -1
  39. package/lib/plugins/pivot/index.js +50 -47
  40. package/lib/plugins/pivot/index.js.map +1 -1
  41. package/lib/plugins/print/PrintPlugin.d.ts +98 -0
  42. package/lib/plugins/print/PrintPlugin.d.ts.map +1 -0
  43. package/lib/plugins/print/index.d.ts +10 -0
  44. package/lib/plugins/print/index.d.ts.map +1 -0
  45. package/lib/plugins/print/index.js +626 -0
  46. package/lib/plugins/print/index.js.map +1 -0
  47. package/lib/plugins/print/print-isolated.d.ts +26 -0
  48. package/lib/plugins/print/print-isolated.d.ts.map +1 -0
  49. package/lib/plugins/print/types.d.ts +147 -0
  50. package/lib/plugins/print/types.d.ts.map +1 -0
  51. package/lib/plugins/reorder/index.js +25 -22
  52. package/lib/plugins/reorder/index.js.map +1 -1
  53. package/lib/plugins/responsive/index.js +20 -17
  54. package/lib/plugins/responsive/index.js.map +1 -1
  55. package/lib/plugins/row-reorder/index.js +39 -36
  56. package/lib/plugins/row-reorder/index.js.map +1 -1
  57. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  58. package/lib/plugins/selection/index.js +115 -101
  59. package/lib/plugins/selection/index.js.map +1 -1
  60. package/lib/plugins/server-side/index.js +35 -32
  61. package/lib/plugins/server-side/index.js.map +1 -1
  62. package/lib/plugins/tree/index.js +26 -23
  63. package/lib/plugins/tree/index.js.map +1 -1
  64. package/lib/plugins/undo-redo/index.js +23 -20
  65. package/lib/plugins/undo-redo/index.js.map +1 -1
  66. package/lib/plugins/visibility/index.js +22 -19
  67. package/lib/plugins/visibility/index.js.map +1 -1
  68. package/package.json +1 -1
  69. package/public.d.ts +1 -1
  70. package/public.d.ts.map +1 -1
  71. package/umd/grid.all.umd.js +98 -24
  72. package/umd/grid.all.umd.js.map +1 -1
  73. package/umd/grid.umd.js +11 -11
  74. package/umd/grid.umd.js.map +1 -1
  75. package/umd/plugins/editing.umd.js +1 -1
  76. package/umd/plugins/editing.umd.js.map +1 -1
  77. package/umd/plugins/filtering.umd.js +1 -1
  78. package/umd/plugins/filtering.umd.js.map +1 -1
  79. package/umd/plugins/print.umd.js +76 -0
  80. package/umd/plugins/print.umd.js.map +1 -0
  81. package/umd/plugins/selection.umd.js +2 -2
  82. package/umd/plugins/selection.umd.js.map +1 -1
@@ -113,9 +113,14 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
113
113
  private excludedValues;
114
114
  private panelAbortController;
115
115
  private globalStylesInjected;
116
- private static readonly LIST_ITEM_HEIGHT;
116
+ private static readonly DEFAULT_LIST_ITEM_HEIGHT;
117
117
  private static readonly LIST_OVERSCAN;
118
118
  private static readonly LIST_BYPASS_THRESHOLD;
119
+ /**
120
+ * Get the item height from CSS variable or fallback to default.
121
+ * Reads --tbw-filter-item-height from the panel element.
122
+ */
123
+ private getListItemHeight;
119
124
  /**
120
125
  * Sync excludedValues map from a filter model (for set filters).
121
126
  */
@@ -174,6 +179,11 @@ export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
174
179
  * Uses sourceRows to include all values regardless of current filter.
175
180
  */
176
181
  getUniqueValues(field: string): unknown[];
182
+ /**
183
+ * Copy CSS classes and data attributes from grid to filter panel.
184
+ * This ensures theme classes (e.g., .eds-theme) cascade to the panel.
185
+ */
186
+ private copyGridThemeContext;
177
187
  /**
178
188
  * Inject global styles for filter panel (rendered in document.body)
179
189
  */
@@ -1 +1 @@
1
- {"version":3,"file":"FilteringPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/filtering/FilteringPlugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FilteringPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/filtering/FilteringPlugin.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,19 @@
1
- function P(h) {
2
- const { totalRows: e, viewportHeight: t, scrollTop: r, rowHeight: n, overscan: i } = h, l = Math.ceil(t / n);
3
- let a = Math.floor(r / n) - i;
4
- a < 0 && (a = 0);
5
- let o = a + l + i * 2;
6
- return o > e && (o = e), o === e && a > 0 && (a = Math.max(0, o - l - i * 2)), {
7
- start: a,
8
- end: o,
9
- offsetY: a * n,
10
- totalHeight: e * n
1
+ function _(h) {
2
+ const { totalRows: e, viewportHeight: t, scrollTop: r, rowHeight: i, overscan: n } = h, a = Math.ceil(t / i);
3
+ let o = Math.floor(r / i) - n;
4
+ o < 0 && (o = 0);
5
+ let l = o + a + n * 2;
6
+ return l > e && (l = e), l === e && o > 0 && (o = Math.max(0, l - a - n * 2)), {
7
+ start: o,
8
+ end: l,
9
+ offsetY: o * i,
10
+ totalHeight: e * i
11
11
  };
12
12
  }
13
- function V(h, e) {
13
+ function M(h, e) {
14
14
  return h <= e;
15
15
  }
16
- const _ = {
16
+ const H = '<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>', z = {
17
17
  expand: "▶",
18
18
  collapse: "▼",
19
19
  sortAsc: "▲",
@@ -21,9 +21,12 @@ const _ = {
21
21
  sortNone: "⇅",
22
22
  submenuArrow: "▶",
23
23
  dragHandle: "⋮⋮",
24
- toolPanel: "☰"
24
+ toolPanel: "☰",
25
+ filter: H,
26
+ filterActive: H,
27
+ print: "🖨️"
25
28
  };
26
- class M {
29
+ class q {
27
30
  /**
28
31
  * Plugin dependencies - declare other plugins this one requires.
29
32
  *
@@ -247,7 +250,7 @@ class M {
247
250
  */
248
251
  get gridIcons() {
249
252
  const e = this.grid?.gridConfig?.icons ?? {};
250
- return { ..._, ...e };
253
+ return { ...z, ...e };
251
254
  }
252
255
  // #region Animation Helpers
253
256
  /**
@@ -323,31 +326,31 @@ class M {
323
326
  }
324
327
  // #endregion
325
328
  }
326
- function z(h) {
329
+ function B(h) {
327
330
  return h.meta?.utility === !0;
328
331
  }
329
- function q(h, e, t = !1) {
332
+ function Y(h, e, t = !1) {
330
333
  const r = h[e.field];
331
334
  if (e.operator === "blank")
332
335
  return r == null || r === "";
333
336
  if (e.operator === "notBlank")
334
337
  return r != null && r !== "";
335
338
  if (r == null) return !1;
336
- const n = String(r), i = t ? n : n.toLowerCase(), l = t ? String(e.value) : String(e.value).toLowerCase();
339
+ const i = String(r), n = t ? i : i.toLowerCase(), a = t ? String(e.value) : String(e.value).toLowerCase();
337
340
  switch (e.operator) {
338
341
  // Text operators
339
342
  case "contains":
340
- return i.includes(l);
343
+ return n.includes(a);
341
344
  case "notContains":
342
- return !i.includes(l);
345
+ return !n.includes(a);
343
346
  case "equals":
344
- return i === l;
347
+ return n === a;
345
348
  case "notEquals":
346
- return i !== l;
349
+ return n !== a;
347
350
  case "startsWith":
348
- return i.startsWith(l);
351
+ return n.startsWith(a);
349
352
  case "endsWith":
350
- return i.endsWith(l);
353
+ return n.endsWith(a);
351
354
  // Number/Date operators (use raw numeric values)
352
355
  case "lessThan":
353
356
  return Number(r) < Number(e.value);
@@ -368,10 +371,10 @@ function q(h, e, t = !1) {
368
371
  return !0;
369
372
  }
370
373
  }
371
- function B(h, e, t = !1) {
372
- return e.length ? h.filter((r) => e.every((n) => q(r, n, t))) : h;
374
+ function D(h, e, t = !1) {
375
+ return e.length ? h.filter((r) => e.every((i) => Y(r, i, t))) : h;
373
376
  }
374
- function Y(h) {
377
+ function $(h) {
375
378
  return JSON.stringify(
376
379
  h.map((e) => ({
377
380
  field: e.field,
@@ -381,16 +384,16 @@ function Y(h) {
381
384
  }))
382
385
  );
383
386
  }
384
- function H(h, e) {
387
+ function V(h, e) {
385
388
  const t = /* @__PURE__ */ new Set();
386
389
  for (const r of h) {
387
- const n = r[e];
388
- n != null && t.add(n);
390
+ const i = r[e];
391
+ i != null && t.add(i);
389
392
  }
390
- return [...t].sort((r, n) => typeof r == "number" && typeof n == "number" ? r - n : String(r).localeCompare(String(n)));
393
+ return [...t].sort((r, i) => typeof r == "number" && typeof i == "number" ? r - i : String(r).localeCompare(String(i)));
391
394
  }
392
- const G = '@layer tbw-plugins{tbw-grid .tbw-quick-filter-input{flex:1;max-width:300px;height:var(--tbw-input-height, 1.75rem);padding:var(--tbw-input-padding, 0 .5rem);border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);color:var(--tbw-color-fg);font-size:var(--tbw-font-size-sm, .8125rem)}tbw-grid .tbw-quick-filter-input:focus{outline:none;border-color:var(--tbw-color-accent)}tbw-grid .header-cell.filtered:before{content:"";position:absolute;top:var(--tbw-spacing-xs, .25rem);right:var(--tbw-spacing-xs, .25rem);width:var(--tbw-indicator-size, .375rem);height:var(--tbw-indicator-size, .375rem);background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));border-radius:50%}tbw-grid .tbw-filter-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:2px;margin-left:var(--tbw-spacing-xs, .25rem);opacity:.4;transition:opacity .15s;color:inherit;vertical-align:middle}tbw-grid .tbw-filter-btn:hover,tbw-grid .tbw-filter-btn.active{opacity:1}tbw-grid .tbw-filter-btn.active{color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}}', $ = "@layer tbw-plugins{.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, .25rem));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:var(--tbw-panel-padding, var(--tbw-spacing-lg, .75rem));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, .8125rem);transform-origin:top center}.tbw-filter-panel.tbw-filter-panel-above{transform-origin:bottom center}.tbw-filter-panel.tbw-filter-panel-animated{animation:tbw-filter-panel-enter var(--tbw-animation-duration, .15s) var(--tbw-animation-easing, ease-out)}.tbw-filter-panel.tbw-filter-panel-above.tbw-filter-panel-animated{animation:tbw-filter-panel-enter-above var(--tbw-animation-duration, .15s) var(--tbw-animation-easing, ease-out)}@keyframes tbw-filter-panel-enter{0%{opacity:0;transform:scaleY(.3) translateY(-10px)}to{opacity:1;transform:scaleY(1) translateY(0)}}@keyframes tbw-filter-panel-enter-above{0%{opacity:0;transform:scaleY(.3) translateY(10px)}to{opacity:1;transform:scaleY(1) translateY(0)}}@supports (anchor-name: --test){.tbw-filter-panel{position-anchor:--tbw-filter-anchor;top:anchor(bottom);left:anchor(left);margin-top:4px;position-try-fallbacks:flip-inline,flip-block,flip-block flip-inline}}.tbw-filter-search{margin-bottom:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem))}.tbw-filter-search-input{width:100%;padding:var(--tbw-button-padding, .375rem .625rem);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, var(--tbw-border-radius, .25rem));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:var(--tbw-button-padding-sm, .25rem .125rem);margin-bottom:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));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:var(--tbw-font-size-xs, .75rem);padding:2px 0}.tbw-filter-action-btn:hover{text-decoration:underline}.tbw-filter-values{flex:1;overflow-y:auto;margin-bottom:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));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:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding:var(--tbw-button-padding-sm, .25rem .125rem);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:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem)) 0;text-align:center;font-style:italic}.tbw-filter-buttons{display:flex;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding-top:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));border-top:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-apply-btn{flex:1;padding:var(--tbw-button-padding, .375rem .75rem);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:var(--tbw-border-radius, .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem)}.tbw-filter-apply-btn:hover{filter:brightness(.9)}.tbw-filter-clear-btn{flex:1;padding:var(--tbw-button-padding, .375rem .75rem);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:var(--tbw-border-radius, .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem)}.tbw-filter-clear-btn:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}}";
393
- class g extends M {
395
+ const G = '@layer tbw-plugins{tbw-grid .tbw-quick-filter-input{flex:1;max-width:300px;height:var(--tbw-input-height, 1.75rem);padding:var(--tbw-input-padding, 0 .5rem);border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);color:var(--tbw-color-fg);font-size:var(--tbw-font-size-sm, .8125rem)}tbw-grid .tbw-quick-filter-input:focus{outline:none;border-color:var(--tbw-color-accent)}tbw-grid .header-cell.filtered:before{content:"";position:absolute;top:var(--tbw-spacing-xs, .25rem);right:var(--tbw-spacing-xs, .25rem);width:var(--tbw-indicator-size, .375rem);height:var(--tbw-indicator-size, .375rem);background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));border-radius:50%}tbw-grid .tbw-filter-btn{display:var(--tbw-filter-btn-display, inline-flex);visibility:var(--tbw-filter-btn-visibility, visible);align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:2px;margin-left:var(--tbw-spacing-xs, .25rem);opacity:.4;transition:opacity .15s,visibility 0s,display 0s allow-discrete;color:inherit;vertical-align:middle;transition-behavior:allow-discrete}tbw-grid .tbw-filter-btn:hover,tbw-grid .tbw-filter-btn.active{opacity:1;visibility:visible;display:inline-flex}tbw-grid .tbw-filter-btn.active{color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}tbw-grid .header-row .cell:hover .tbw-filter-btn,tbw-grid .header-row .cell.filtered .tbw-filter-btn{display:inline-flex;visibility:visible}}', K = "@layer tbw-plugins{.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, .25rem));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:var(--tbw-panel-padding, var(--tbw-spacing-lg, .75rem));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, .8125rem);transform-origin:top center}.tbw-filter-panel.tbw-filter-panel-above{transform-origin:bottom center}.tbw-filter-panel.tbw-filter-panel-animated{animation:tbw-filter-panel-enter var(--tbw-animation-duration, .15s) var(--tbw-animation-easing, ease-out)}.tbw-filter-panel.tbw-filter-panel-above.tbw-filter-panel-animated{animation:tbw-filter-panel-enter-above var(--tbw-animation-duration, .15s) var(--tbw-animation-easing, ease-out)}@keyframes tbw-filter-panel-enter{0%{opacity:0;transform:scaleY(.3) translateY(-10px)}to{opacity:1;transform:scaleY(1) translateY(0)}}@keyframes tbw-filter-panel-enter-above{0%{opacity:0;transform:scaleY(.3) translateY(10px)}to{opacity:1;transform:scaleY(1) translateY(0)}}@supports (anchor-name: --test){.tbw-filter-panel{position-anchor:--tbw-filter-anchor;top:anchor(bottom);left:anchor(left);margin-top:4px;position-try-fallbacks:flip-inline,flip-block,flip-block flip-inline}}.tbw-filter-search{margin-bottom:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem))}.tbw-filter-search-input{width:100%;padding:var(--tbw-filter-search-padding, var(--tbw-spacing-sm, .375rem) var(--tbw-spacing-md, .5rem));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, var(--tbw-border-radius, .25rem));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:var(--tbw-button-padding-sm, .25rem .125rem);margin-bottom:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));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:var(--tbw-font-size-xs, .75rem);padding:2px 0}.tbw-filter-action-btn:hover{text-decoration:underline}.tbw-filter-values{flex:1;overflow-y:auto;margin-bottom:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));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:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding:var(--tbw-button-padding-sm, .25rem .125rem);cursor:pointer;border-radius:3px;min-height:var(--tbw-filter-item-height, 28px)}.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:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem)) 0;text-align:center;font-style:italic}.tbw-filter-buttons{display:flex;gap:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));padding-top:var(--tbw-panel-gap, var(--tbw-spacing-md, .5rem));border-top:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-apply-btn{flex:1;padding:var(--tbw-filter-btn-padding, var(--tbw-button-padding, .375rem .75rem));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:var(--tbw-border-radius, .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem);font-weight:var(--tbw-filter-btn-font-weight, 500);min-height:var(--tbw-filter-btn-min-height, auto)}.tbw-filter-apply-btn:hover{filter:brightness(.9)}.tbw-filter-clear-btn{flex:1;padding:var(--tbw-filter-btn-padding, var(--tbw-button-padding, .375rem .75rem));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:var(--tbw-border-radius, .25rem);cursor:pointer;font-size:var(--tbw-font-size-sm, .8125rem);font-weight:var(--tbw-filter-btn-font-weight, 500);min-height:var(--tbw-filter-btn-min-height, auto)}.tbw-filter-clear-btn:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}}";
396
+ class v extends q {
394
397
  /** @internal */
395
398
  name = "filtering";
396
399
  /** @internal */
@@ -418,10 +421,25 @@ class g extends M {
418
421
  // For panel-scoped listeners
419
422
  globalStylesInjected = !1;
420
423
  // Virtualization constants for filter value list
421
- static LIST_ITEM_HEIGHT = 28;
424
+ static DEFAULT_LIST_ITEM_HEIGHT = 28;
422
425
  static LIST_OVERSCAN = 3;
423
426
  static LIST_BYPASS_THRESHOLD = 50;
424
427
  // Don't virtualize if < 50 items
428
+ /**
429
+ * Get the item height from CSS variable or fallback to default.
430
+ * Reads --tbw-filter-item-height from the panel element.
431
+ */
432
+ getListItemHeight() {
433
+ if (this.panelElement) {
434
+ const e = getComputedStyle(this.panelElement).getPropertyValue("--tbw-filter-item-height");
435
+ if (e && e.trim()) {
436
+ const t = parseFloat(e);
437
+ if (!isNaN(t) && t > 0)
438
+ return t;
439
+ }
440
+ }
441
+ return v.DEFAULT_LIST_ITEM_HEIGHT;
442
+ }
425
443
  /**
426
444
  * Sync excludedValues map from a filter model (for set filters).
427
445
  */
@@ -446,34 +464,40 @@ class g extends M {
446
464
  if (!t.length) return [...e];
447
465
  if (this.config.filterHandler)
448
466
  return this.cachedResult ? this.cachedResult : [...e];
449
- const r = Y(t);
467
+ const r = $(t);
450
468
  if (this.cacheKey === r && this.cachedResult)
451
469
  return this.cachedResult;
452
- const n = B([...e], t, this.config.caseSensitive);
453
- return this.cachedResult = n, this.cacheKey = r, n;
470
+ const i = D([...e], t, this.config.caseSensitive);
471
+ return this.cachedResult = i, this.cacheKey = r, i;
454
472
  }
455
473
  /** @internal */
456
474
  afterRender() {
457
475
  const e = this.gridElement;
458
476
  if (!e) return;
459
477
  e.querySelectorAll('[part~="header-cell"]').forEach((r) => {
460
- const n = r.getAttribute("data-col");
461
- if (n === null) return;
462
- const i = this.visibleColumns[parseInt(n, 10)];
463
- if (!i || i.filterable === !1 || z(i)) return;
464
- const l = i.field;
465
- if (!l) return;
466
- const a = this.filters.has(l);
467
- let o = r.querySelector(".tbw-filter-btn");
468
- if (o) {
469
- o.classList.toggle("active", a), r.classList.toggle("filtered", a);
478
+ const i = r.getAttribute("data-col");
479
+ if (i === null) return;
480
+ const n = this.visibleColumns[parseInt(i, 10)];
481
+ if (!n || n.filterable === !1 || B(n)) return;
482
+ const a = n.field;
483
+ if (!a) return;
484
+ const o = this.filters.has(a);
485
+ let l = r.querySelector(".tbw-filter-btn");
486
+ if (l) {
487
+ const b = l.classList.contains("active");
488
+ if (l.classList.toggle("active", o), r.classList.toggle("filtered", o), b !== o) {
489
+ const E = o ? "filterActive" : "filter";
490
+ this.setIcon(l, this.resolveIcon(E));
491
+ }
470
492
  return;
471
493
  }
472
- o = document.createElement("button"), o.className = "tbw-filter-btn", o.setAttribute("aria-label", `Filter ${i.header ?? l}`), o.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>', a && (o.classList.add("active"), r.classList.add("filtered")), o.addEventListener("click", (b) => {
473
- b.stopPropagation(), this.toggleFilterPanel(l, i, o);
494
+ l = document.createElement("button"), l.className = "tbw-filter-btn", l.setAttribute("aria-label", `Filter ${n.header ?? a}`);
495
+ const m = o ? "filterActive" : "filter";
496
+ this.setIcon(l, this.resolveIcon(m)), o && (l.classList.add("active"), r.classList.add("filtered")), l.addEventListener("click", (b) => {
497
+ b.stopPropagation(), this.toggleFilterPanel(a, n, l);
474
498
  });
475
499
  const p = r.querySelector(".resize-handle");
476
- p ? r.insertBefore(o, p) : r.appendChild(o);
500
+ p ? r.insertBefore(l, p) : r.appendChild(l);
477
501
  });
478
502
  }
479
503
  // #endregion
@@ -560,10 +584,22 @@ class g extends M {
560
584
  * Uses sourceRows to include all values regardless of current filter.
561
585
  */
562
586
  getUniqueValues(e) {
563
- return H(this.sourceRows, e);
587
+ return V(this.sourceRows, e);
564
588
  }
565
589
  // #endregion
566
590
  // #region Private Methods
591
+ /**
592
+ * Copy CSS classes and data attributes from grid to filter panel.
593
+ * This ensures theme classes (e.g., .eds-theme) cascade to the panel.
594
+ */
595
+ copyGridThemeContext(e) {
596
+ const t = this.gridElement;
597
+ if (!t) return;
598
+ for (const i of t.classList)
599
+ i.startsWith("tbw-") || i === "selecting" || e.classList.add(i);
600
+ const r = t.dataset.theme;
601
+ r && (e.dataset.theme = r);
602
+ }
567
603
  /**
568
604
  * Inject global styles for filter panel (rendered in document.body)
569
605
  */
@@ -574,7 +610,7 @@ class g extends M {
574
610
  return;
575
611
  }
576
612
  const e = document.createElement("style");
577
- e.id = "tbw-filter-panel-styles", e.textContent = $, document.head.appendChild(e), this.globalStylesInjected = !0;
613
+ e.id = "tbw-filter-panel-styles", e.textContent = K, document.head.appendChild(e), this.globalStylesInjected = !0;
578
614
  }
579
615
  /**
580
616
  * Toggle the filter panel for a field
@@ -585,41 +621,41 @@ class g extends M {
585
621
  return;
586
622
  }
587
623
  this.closeFilterPanel();
588
- const n = document.createElement("div");
589
- if (n.className = "tbw-filter-panel", this.isAnimationEnabled && n.classList.add("tbw-filter-panel-animated"), this.panelElement = n, this.openPanelField = e, this.config.valuesHandler) {
590
- n.innerHTML = '<div class="tbw-filter-loading">Loading...</div>', document.body.appendChild(n), this.positionPanel(n, r), this.setupPanelCloseHandler(n, r), this.config.valuesHandler(e, t).then((l) => {
591
- this.openPanelField !== e || !this.panelElement || (n.innerHTML = "", this.renderPanelContent(e, t, n, l));
624
+ const i = document.createElement("div");
625
+ if (i.className = "tbw-filter-panel", this.copyGridThemeContext(i), this.isAnimationEnabled && i.classList.add("tbw-filter-panel-animated"), this.panelElement = i, this.openPanelField = e, this.config.valuesHandler) {
626
+ i.innerHTML = '<div class="tbw-filter-loading">Loading...</div>', document.body.appendChild(i), this.positionPanel(i, r), this.setupPanelCloseHandler(i, r), this.config.valuesHandler(e, t).then((a) => {
627
+ this.openPanelField !== e || !this.panelElement || (i.innerHTML = "", this.renderPanelContent(e, t, i, a));
592
628
  });
593
629
  return;
594
630
  }
595
- const i = H(this.sourceRows, e);
596
- this.renderPanelContent(e, t, n, i), document.body.appendChild(n), this.positionPanel(n, r), this.setupPanelCloseHandler(n, r);
631
+ const n = V(this.sourceRows, e);
632
+ this.renderPanelContent(e, t, i, n), document.body.appendChild(i), this.positionPanel(i, r), this.setupPanelCloseHandler(i, r);
597
633
  }
598
634
  /**
599
635
  * Render filter panel content with given values
600
636
  */
601
- renderPanelContent(e, t, r, n) {
602
- let i = this.excludedValues.get(e);
603
- i || (i = /* @__PURE__ */ new Set(), this.excludedValues.set(e, i));
604
- const l = this.searchText.get(e) ?? "", a = {
637
+ renderPanelContent(e, t, r, i) {
638
+ let n = this.excludedValues.get(e);
639
+ n || (n = /* @__PURE__ */ new Set(), this.excludedValues.set(e, n));
640
+ const a = this.searchText.get(e) ?? "", o = {
605
641
  field: e,
606
642
  column: t,
607
- uniqueValues: n,
608
- excludedValues: i,
609
- searchText: l,
610
- applySetFilter: (p) => {
611
- this.applySetFilter(e, p), this.closeFilterPanel();
643
+ uniqueValues: i,
644
+ excludedValues: n,
645
+ searchText: a,
646
+ applySetFilter: (m) => {
647
+ this.applySetFilter(e, m), this.closeFilterPanel();
612
648
  },
613
- applyTextFilter: (p, b, C) => {
614
- this.applyTextFilter(e, p, b, C), this.closeFilterPanel();
649
+ applyTextFilter: (m, p, b) => {
650
+ this.applyTextFilter(e, m, p, b), this.closeFilterPanel();
615
651
  },
616
652
  clearFilter: () => {
617
653
  this.clearFieldFilter(e), this.closeFilterPanel();
618
654
  },
619
655
  closePanel: () => this.closeFilterPanel()
620
656
  };
621
- let o = !1;
622
- this.config.filterPanelRenderer && (this.config.filterPanelRenderer(r, a), o = r.children.length > 0), o || this.renderDefaultFilterPanel(r, a, n, i);
657
+ let l = !1;
658
+ this.config.filterPanelRenderer && (this.config.filterPanelRenderer(r, o), l = r.children.length > 0), l || this.renderDefaultFilterPanel(r, o, i, n);
623
659
  }
624
660
  /**
625
661
  * Setup click-outside handler to close the panel
@@ -648,124 +684,124 @@ class g extends M {
648
684
  * Check if browser supports CSS Anchor Positioning
649
685
  */
650
686
  static checkAnchorPositioningSupport() {
651
- return g.supportsAnchorPositioning === null && (g.supportsAnchorPositioning = CSS.supports("anchor-name", "--test")), g.supportsAnchorPositioning;
687
+ return v.supportsAnchorPositioning === null && (v.supportsAnchorPositioning = CSS.supports("anchor-name", "--test")), v.supportsAnchorPositioning;
652
688
  }
653
689
  /**
654
690
  * Position the panel below the header cell
655
691
  * Uses CSS Anchor Positioning if supported, falls back to JS positioning
656
692
  */
657
693
  positionPanel(e, t) {
658
- const n = t.closest(".cell") ?? t;
659
- if (n.style.anchorName = "--tbw-filter-anchor", this.panelAnchorElement = n, g.checkAnchorPositioningSupport()) {
694
+ const i = t.closest(".cell") ?? t;
695
+ if (i.style.anchorName = "--tbw-filter-anchor", this.panelAnchorElement = i, v.checkAnchorPositioningSupport()) {
660
696
  requestAnimationFrame(() => {
661
- const l = e.getBoundingClientRect(), a = n.getBoundingClientRect();
662
- l.top < a.top && e.classList.add("tbw-filter-panel-above");
697
+ const a = e.getBoundingClientRect(), o = i.getBoundingClientRect();
698
+ a.top < o.top && e.classList.add("tbw-filter-panel-above");
663
699
  });
664
700
  return;
665
701
  }
666
- const i = n.getBoundingClientRect();
667
- e.style.position = "fixed", e.style.top = `${i.bottom + 4}px`, e.style.left = `${i.left}px`, requestAnimationFrame(() => {
668
- const l = e.getBoundingClientRect();
669
- l.right > window.innerWidth - 8 && (e.style.left = `${i.right - l.width}px`), l.bottom > window.innerHeight - 8 && (e.style.top = `${i.top - l.height - 4}px`, e.classList.add("tbw-filter-panel-above"));
702
+ const n = i.getBoundingClientRect();
703
+ e.style.position = "fixed", e.style.top = `${n.bottom + 4}px`, e.style.left = `${n.left}px`, requestAnimationFrame(() => {
704
+ const a = e.getBoundingClientRect();
705
+ a.right > window.innerWidth - 8 && (e.style.left = `${n.right - a.width}px`), a.bottom > window.innerHeight - 8 && (e.style.top = `${n.top - a.height - 4}px`, e.classList.add("tbw-filter-panel-above"));
670
706
  });
671
707
  }
672
708
  /**
673
709
  * Render the default filter panel content
674
710
  */
675
- renderDefaultFilterPanel(e, t, r, n) {
676
- const { field: i } = t, l = document.createElement("div");
677
- l.className = "tbw-filter-search";
678
- const a = document.createElement("input");
679
- a.type = "text", a.placeholder = "Search...", a.className = "tbw-filter-search-input", a.value = this.searchText.get(i) ?? "", l.appendChild(a), e.appendChild(l);
680
- const o = document.createElement("div");
681
- o.className = "tbw-filter-actions";
711
+ renderDefaultFilterPanel(e, t, r, i) {
712
+ const { field: n } = t, a = this.getListItemHeight(), o = document.createElement("div");
713
+ o.className = "tbw-filter-search";
714
+ const l = document.createElement("input");
715
+ l.type = "text", l.placeholder = "Search...", l.className = "tbw-filter-search-input", l.value = this.searchText.get(n) ?? "", o.appendChild(l), e.appendChild(o);
716
+ const m = document.createElement("div");
717
+ m.className = "tbw-filter-actions";
682
718
  const p = document.createElement("label");
683
719
  p.className = "tbw-filter-value-item", p.style.padding = "0", p.style.margin = "0";
684
720
  const b = document.createElement("input");
685
721
  b.type = "checkbox", b.className = "tbw-filter-checkbox";
686
- const C = document.createElement("span");
687
- C.textContent = "Select All", p.appendChild(b), p.appendChild(C), o.appendChild(p);
688
- const T = () => {
689
- const s = [...y.values()], u = s.every((c) => c), w = s.every((c) => !c);
722
+ const E = document.createElement("span");
723
+ E.textContent = "Select All", p.appendChild(b), p.appendChild(E), m.appendChild(p);
724
+ const F = () => {
725
+ const s = [...x.values()], u = s.every((c) => c), w = s.every((c) => !c);
690
726
  b.checked = u, b.indeterminate = !u && !w;
691
727
  };
692
728
  b.addEventListener("change", () => {
693
729
  const s = b.checked;
694
- for (const u of y.keys())
695
- y.set(u, s);
696
- T(), A();
697
- }), e.appendChild(o);
698
- const v = document.createElement("div");
699
- v.className = "tbw-filter-values";
700
- const E = document.createElement("div");
701
- E.className = "tbw-filter-values-spacer", v.appendChild(E);
702
- const m = document.createElement("div");
703
- m.className = "tbw-filter-values-content", v.appendChild(m);
704
- const y = /* @__PURE__ */ new Map();
730
+ for (const u of x.keys())
731
+ x.set(u, s);
732
+ F(), T();
733
+ }), e.appendChild(m);
734
+ const y = document.createElement("div");
735
+ y.className = "tbw-filter-values";
736
+ const S = document.createElement("div");
737
+ S.className = "tbw-filter-values-spacer", y.appendChild(S);
738
+ const g = document.createElement("div");
739
+ g.className = "tbw-filter-values-content", y.appendChild(g);
740
+ const x = /* @__PURE__ */ new Map();
705
741
  r.forEach((s) => {
706
742
  const u = s == null ? "__null__" : String(s);
707
- y.set(u, !n.has(s));
708
- }), T();
709
- let x = [];
710
- const F = (s, u) => {
743
+ x.set(u, !i.has(s));
744
+ }), F();
745
+ let C = [];
746
+ const I = (s, u) => {
711
747
  const w = s == null ? "(Blank)" : String(s), c = s == null ? "__null__" : String(s), d = document.createElement("label");
712
- d.className = "tbw-filter-value-item", d.style.position = "absolute", d.style.top = `${u * g.LIST_ITEM_HEIGHT}px`, d.style.left = "0", d.style.right = "0", d.style.height = `${g.LIST_ITEM_HEIGHT}px`, d.style.boxSizing = "border-box";
748
+ d.className = "tbw-filter-value-item", d.style.position = "absolute", d.style.top = `${u * a}px`, d.style.left = "0", d.style.right = "0", d.style.height = `${a}px`, d.style.boxSizing = "border-box";
713
749
  const f = document.createElement("input");
714
- f.type = "checkbox", f.className = "tbw-filter-checkbox", f.checked = y.get(c) ?? !0, f.dataset.value = c, f.addEventListener("change", () => {
715
- y.set(c, f.checked), T();
750
+ f.type = "checkbox", f.className = "tbw-filter-checkbox", f.checked = x.get(c) ?? !0, f.dataset.value = c, f.addEventListener("change", () => {
751
+ x.set(c, f.checked), F();
716
752
  });
717
- const N = document.createElement("span");
718
- return N.textContent = w, d.appendChild(f), d.appendChild(N), d;
719
- }, A = () => {
720
- const s = x.length, u = v.clientHeight, w = v.scrollTop;
721
- if (E.style.height = `${s * g.LIST_ITEM_HEIGHT}px`, V(s, g.LIST_BYPASS_THRESHOLD / 3)) {
722
- m.innerHTML = "", m.style.transform = "translateY(0px)", x.forEach((d, f) => {
723
- m.appendChild(F(d, f));
753
+ const P = document.createElement("span");
754
+ return P.textContent = w, d.appendChild(f), d.appendChild(P), d;
755
+ }, T = () => {
756
+ const s = C.length, u = y.clientHeight, w = y.scrollTop;
757
+ if (S.style.height = `${s * a}px`, M(s, v.LIST_BYPASS_THRESHOLD / 3)) {
758
+ g.innerHTML = "", g.style.transform = "translateY(0px)", C.forEach((d, f) => {
759
+ g.appendChild(I(d, f));
724
760
  });
725
761
  return;
726
762
  }
727
- const c = P({
763
+ const c = _({
728
764
  totalRows: s,
729
765
  viewportHeight: u,
730
766
  scrollTop: w,
731
- rowHeight: g.LIST_ITEM_HEIGHT,
732
- overscan: g.LIST_OVERSCAN
767
+ rowHeight: a,
768
+ overscan: v.LIST_OVERSCAN
733
769
  });
734
- m.style.transform = `translateY(${c.offsetY}px)`, m.innerHTML = "";
770
+ g.style.transform = `translateY(${c.offsetY}px)`, g.innerHTML = "";
735
771
  for (let d = c.start; d < c.end; d++)
736
- m.appendChild(F(x[d], d - c.start));
737
- }, I = (s) => {
772
+ g.appendChild(I(C[d], d - c.start));
773
+ }, L = (s) => {
738
774
  const u = this.config.caseSensitive ?? !1, w = u ? s : s.toLowerCase();
739
- if (x = r.filter((c) => {
775
+ if (C = r.filter((c) => {
740
776
  const d = c == null ? "(Blank)" : String(c), f = u ? d : d.toLowerCase();
741
777
  return !s || f.includes(w);
742
- }), x.length === 0) {
743
- E.style.height = "0px", m.innerHTML = "";
778
+ }), C.length === 0) {
779
+ S.style.height = "0px", g.innerHTML = "";
744
780
  const c = document.createElement("div");
745
- c.className = "tbw-filter-no-match", c.textContent = "No matching values", m.appendChild(c);
781
+ c.className = "tbw-filter-no-match", c.textContent = "No matching values", g.appendChild(c);
746
782
  return;
747
783
  }
748
- A();
784
+ T();
749
785
  };
750
- v.addEventListener(
786
+ y.addEventListener(
751
787
  "scroll",
752
788
  () => {
753
- x.length > 0 && A();
789
+ C.length > 0 && T();
754
790
  },
755
791
  { passive: !0 }
756
- ), I(a.value), e.appendChild(v);
757
- let L;
758
- a.addEventListener("input", () => {
759
- clearTimeout(L), L = setTimeout(() => {
760
- this.searchText.set(i, a.value), I(a.value);
792
+ ), L(l.value), e.appendChild(y);
793
+ let N;
794
+ l.addEventListener("input", () => {
795
+ clearTimeout(N), N = setTimeout(() => {
796
+ this.searchText.set(n, l.value), L(l.value);
761
797
  }, this.config.debounceMs ?? 150);
762
798
  });
763
- const S = document.createElement("div");
764
- S.className = "tbw-filter-buttons";
765
- const R = document.createElement("button");
766
- R.className = "tbw-filter-apply-btn", R.textContent = "Apply", R.addEventListener("click", () => {
799
+ const R = document.createElement("div");
800
+ R.className = "tbw-filter-buttons";
801
+ const k = document.createElement("button");
802
+ k.className = "tbw-filter-apply-btn", k.textContent = "Apply", k.addEventListener("click", () => {
767
803
  const s = [];
768
- for (const [u, w] of y)
804
+ for (const [u, w] of x)
769
805
  if (!w)
770
806
  if (u === "__null__")
771
807
  s.push(null);
@@ -774,11 +810,11 @@ class g extends M {
774
810
  s.push(c !== void 0 ? c : u);
775
811
  }
776
812
  t.applySetFilter(s);
777
- }), S.appendChild(R);
778
- const k = document.createElement("button");
779
- k.className = "tbw-filter-clear-btn", k.textContent = "Clear Filter", k.addEventListener("click", () => {
813
+ }), R.appendChild(k);
814
+ const A = document.createElement("button");
815
+ A.className = "tbw-filter-clear-btn", A.textContent = "Clear Filter", A.addEventListener("click", () => {
780
816
  t.clearFilter();
781
- }), S.appendChild(k), e.appendChild(S);
817
+ }), R.appendChild(A), e.appendChild(R);
782
818
  }
783
819
  /**
784
820
  * Apply a set filter (exclude values)
@@ -794,13 +830,13 @@ class g extends M {
794
830
  /**
795
831
  * Apply a text filter
796
832
  */
797
- applyTextFilter(e, t, r, n) {
833
+ applyTextFilter(e, t, r, i) {
798
834
  this.filters.set(e, {
799
835
  field: e,
800
836
  type: "text",
801
837
  operator: t,
802
838
  value: r,
803
- valueTo: n
839
+ valueTo: i
804
840
  }), this.applyFiltersInternal();
805
841
  }
806
842
  /**
@@ -812,13 +848,13 @@ class g extends M {
812
848
  if (this.config.filterHandler) {
813
849
  const t = this.grid;
814
850
  t.setAttribute("aria-busy", "true");
815
- const r = this.config.filterHandler(e, this.sourceRows), n = (i) => {
816
- t.removeAttribute("aria-busy"), this.cachedResult = i, this.grid.rows = i, this.emit("filter-change", {
851
+ const r = this.config.filterHandler(e, this.sourceRows), i = (n) => {
852
+ t.removeAttribute("aria-busy"), this.cachedResult = n, this.grid.rows = n, this.emit("filter-change", {
817
853
  filters: e,
818
- filteredRowCount: i.length
854
+ filteredRowCount: n.length
819
855
  }), this.requestRender();
820
856
  };
821
- r && typeof r.then == "function" ? r.then(n) : n(r);
857
+ r && typeof r.then == "function" ? r.then(i) : i(r);
822
858
  return;
823
859
  }
824
860
  this.emit("filter-change", {
@@ -865,6 +901,6 @@ class g extends M {
865
901
  // #endregion
866
902
  }
867
903
  export {
868
- g as FilteringPlugin
904
+ v as FilteringPlugin
869
905
  };
870
906
  //# sourceMappingURL=index.js.map