@toolbox-web/grid 0.0.4 → 0.0.6

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 (64) hide show
  1. package/README.md +24 -0
  2. package/all.d.ts +1709 -135
  3. package/all.js +745 -645
  4. package/all.js.map +1 -1
  5. package/index.d.ts +161 -1
  6. package/index.js +1050 -913
  7. package/index.js.map +1 -1
  8. package/lib/plugins/clipboard/index.js +110 -52
  9. package/lib/plugins/clipboard/index.js.map +1 -1
  10. package/lib/plugins/column-virtualization/index.js +78 -20
  11. package/lib/plugins/column-virtualization/index.js.map +1 -1
  12. package/lib/plugins/context-menu/index.js +163 -95
  13. package/lib/plugins/context-menu/index.js.map +1 -1
  14. package/lib/plugins/export/index.js +93 -35
  15. package/lib/plugins/export/index.js.map +1 -1
  16. package/lib/plugins/filtering/index.js +188 -133
  17. package/lib/plugins/filtering/index.js.map +1 -1
  18. package/lib/plugins/grouping-columns/index.js +69 -11
  19. package/lib/plugins/grouping-columns/index.js.map +1 -1
  20. package/lib/plugins/grouping-rows/index.js +111 -55
  21. package/lib/plugins/grouping-rows/index.js.map +1 -1
  22. package/lib/plugins/master-detail/index.js +196 -51
  23. package/lib/plugins/master-detail/index.js.map +1 -1
  24. package/lib/plugins/multi-sort/index.js +104 -46
  25. package/lib/plugins/multi-sort/index.js.map +1 -1
  26. package/lib/plugins/pinned-columns/index.js +74 -16
  27. package/lib/plugins/pinned-columns/index.js.map +1 -1
  28. package/lib/plugins/pinned-rows/index.js +65 -7
  29. package/lib/plugins/pinned-rows/index.js.map +1 -1
  30. package/lib/plugins/pivot/index.js +117 -59
  31. package/lib/plugins/pivot/index.js.map +1 -1
  32. package/lib/plugins/reorder/index.js +103 -45
  33. package/lib/plugins/reorder/index.js.map +1 -1
  34. package/lib/plugins/selection/index.js +139 -81
  35. package/lib/plugins/selection/index.js.map +1 -1
  36. package/lib/plugins/server-side/index.js +96 -38
  37. package/lib/plugins/server-side/index.js.map +1 -1
  38. package/lib/plugins/tree/index.js +108 -47
  39. package/lib/plugins/tree/index.js.map +1 -1
  40. package/lib/plugins/undo-redo/index.js +70 -12
  41. package/lib/plugins/undo-redo/index.js.map +1 -1
  42. package/lib/plugins/visibility/index.js +82 -24
  43. package/lib/plugins/visibility/index.js.map +1 -1
  44. package/package.json +1 -1
  45. package/umd/grid.all.umd.js +31 -31
  46. package/umd/grid.all.umd.js.map +1 -1
  47. package/umd/grid.umd.js +15 -15
  48. package/umd/grid.umd.js.map +1 -1
  49. package/umd/plugins/context-menu.umd.js +2 -2
  50. package/umd/plugins/context-menu.umd.js.map +1 -1
  51. package/umd/plugins/filtering.umd.js +3 -3
  52. package/umd/plugins/filtering.umd.js.map +1 -1
  53. package/umd/plugins/grouping-rows.umd.js +2 -2
  54. package/umd/plugins/grouping-rows.umd.js.map +1 -1
  55. package/umd/plugins/master-detail.umd.js +2 -2
  56. package/umd/plugins/master-detail.umd.js.map +1 -1
  57. package/umd/plugins/multi-sort.umd.js +1 -1
  58. package/umd/plugins/multi-sort.umd.js.map +1 -1
  59. package/umd/plugins/reorder.umd.js +1 -1
  60. package/umd/plugins/reorder.umd.js.map +1 -1
  61. package/umd/plugins/tree.umd.js +2 -2
  62. package/umd/plugins/tree.umd.js.map +1 -1
  63. package/umd/plugins/visibility.umd.js +1 -1
  64. package/umd/plugins/visibility.umd.js.map +1 -1
@@ -1,4 +1,28 @@
1
- class P {
1
+ function M(f) {
2
+ const { totalRows: e, viewportHeight: t, scrollTop: r, rowHeight: l, overscan: a } = f, i = Math.ceil(t / l);
3
+ let n = Math.floor(r / l) - a;
4
+ n < 0 && (n = 0);
5
+ let u = n + i + a * 2;
6
+ return u > e && (u = e), u === e && n > 0 && (n = Math.max(0, u - i - a * 2)), {
7
+ start: n,
8
+ end: u,
9
+ offsetY: n * l,
10
+ totalHeight: e * l
11
+ };
12
+ }
13
+ function P(f, e) {
14
+ return f <= e;
15
+ }
16
+ const _ = {
17
+ expand: "▶",
18
+ collapse: "▼",
19
+ sortAsc: "▲",
20
+ sortDesc: "▼",
21
+ sortNone: "⇅",
22
+ submenuArrow: "▶",
23
+ dragHandle: "⋮⋮"
24
+ };
25
+ class V {
2
26
  /** Plugin version - override in subclass if needed */
3
27
  version = "1.0.0";
4
28
  /** CSS styles to inject into the grid's shadow DOM */
@@ -97,6 +121,55 @@ class P {
97
121
  get shadowRoot() {
98
122
  return this.grid?.shadowRoot ?? null;
99
123
  }
124
+ /**
125
+ * Get the disconnect signal for event listener cleanup.
126
+ * This signal is aborted when the grid disconnects from the DOM.
127
+ * Use this when adding event listeners that should be cleaned up automatically.
128
+ *
129
+ * Best for:
130
+ * - Document/window-level listeners added in attach()
131
+ * - Listeners on the grid element itself
132
+ * - Any listener that should persist across renders
133
+ *
134
+ * Not needed for:
135
+ * - Listeners on elements created in afterRender() (removed with element)
136
+ *
137
+ * @example
138
+ * element.addEventListener('click', handler, { signal: this.disconnectSignal });
139
+ * document.addEventListener('keydown', handler, { signal: this.disconnectSignal });
140
+ */
141
+ get disconnectSignal() {
142
+ return this.grid?.disconnectSignal;
143
+ }
144
+ /**
145
+ * Get the grid-level icons configuration.
146
+ * Returns merged icons (user config + defaults).
147
+ */
148
+ get gridIcons() {
149
+ const e = this.grid?.gridConfig?.icons ?? {};
150
+ return { ..._, ...e };
151
+ }
152
+ /**
153
+ * Resolve an icon value to string or HTMLElement.
154
+ * Checks plugin config first, then grid-level icons, then defaults.
155
+ *
156
+ * @param iconKey - The icon key in GridIcons (e.g., 'expand', 'collapse')
157
+ * @param pluginOverride - Optional plugin-level override
158
+ * @returns The resolved icon value
159
+ */
160
+ resolveIcon(e, t) {
161
+ return t !== void 0 ? t : this.gridIcons[e];
162
+ }
163
+ /**
164
+ * Set an icon value on an element.
165
+ * Handles both string (text/HTML) and HTMLElement values.
166
+ *
167
+ * @param element - The element to set the icon on
168
+ * @param icon - The icon value (string or HTMLElement)
169
+ */
170
+ setIcon(e, t) {
171
+ typeof t == "string" ? e.innerHTML = t : t instanceof HTMLElement && (e.innerHTML = "", e.appendChild(t.cloneNode(!0)));
172
+ }
100
173
  /**
101
174
  * Log a warning message.
102
175
  */
@@ -104,43 +177,28 @@ class P {
104
177
  console.warn(`[tbw-grid:${this.name}] ${e}`);
105
178
  }
106
179
  }
107
- function A(f) {
108
- const { totalRows: e, viewportHeight: t, scrollTop: r, rowHeight: l, overscan: s } = f, i = Math.ceil(t / l);
109
- let n = Math.floor(r / l) - s;
110
- n < 0 && (n = 0);
111
- let u = n + i + s * 2;
112
- return u > e && (u = e), u === e && n > 0 && (n = Math.max(0, u - i - s * 2)), {
113
- start: n,
114
- end: u,
115
- offsetY: n * l,
116
- totalHeight: e * l
117
- };
118
- }
119
- function V(f, e) {
120
- return f <= e;
121
- }
122
- function _(f, e, t = !1) {
180
+ function q(f, e, t = !1) {
123
181
  const r = f[e.field];
124
182
  if (e.operator === "blank")
125
183
  return r == null || r === "";
126
184
  if (e.operator === "notBlank")
127
185
  return r != null && r !== "";
128
186
  if (r == null) return !1;
129
- const l = String(r), s = t ? l : l.toLowerCase(), i = t ? String(e.value) : String(e.value).toLowerCase();
187
+ const l = String(r), a = t ? l : l.toLowerCase(), i = t ? String(e.value) : String(e.value).toLowerCase();
130
188
  switch (e.operator) {
131
189
  // Text operators
132
190
  case "contains":
133
- return s.includes(i);
191
+ return a.includes(i);
134
192
  case "notContains":
135
- return !s.includes(i);
193
+ return !a.includes(i);
136
194
  case "equals":
137
- return s === i;
195
+ return a === i;
138
196
  case "notEquals":
139
- return s !== i;
197
+ return a !== i;
140
198
  case "startsWith":
141
- return s.startsWith(i);
199
+ return a.startsWith(i);
142
200
  case "endsWith":
143
- return s.endsWith(i);
201
+ return a.endsWith(i);
144
202
  // Number/Date operators (use raw numeric values)
145
203
  case "lessThan":
146
204
  return Number(r) < Number(e.value);
@@ -161,10 +219,10 @@ function _(f, e, t = !1) {
161
219
  return !0;
162
220
  }
163
221
  }
164
- function q(f, e, t = !1) {
165
- return e.length ? f.filter((r) => e.every((l) => _(r, l, t))) : f;
222
+ function B(f, e, t = !1) {
223
+ return e.length ? f.filter((r) => e.every((l) => q(r, l, t))) : f;
166
224
  }
167
- function B(f) {
225
+ function z(f) {
168
226
  return JSON.stringify(
169
227
  f.map((e) => ({
170
228
  field: e.field,
@@ -174,7 +232,7 @@ function B(f) {
174
232
  }))
175
233
  );
176
234
  }
177
- function M(f, e) {
235
+ function H(f, e) {
178
236
  const t = /* @__PURE__ */ new Set();
179
237
  for (const r of f) {
180
238
  const l = r[e];
@@ -182,7 +240,7 @@ function M(f, e) {
182
240
  }
183
241
  return [...t].sort((r, l) => typeof r == "number" && typeof l == "number" ? r - l : String(r).localeCompare(String(l)));
184
242
  }
185
- const z = `
243
+ const K = `
186
244
  .tbw-filter-panel {
187
245
  position: fixed;
188
246
  background: var(--tbw-filter-panel-bg, var(--tbw-color-panel-bg, light-dark(#eeeeee, #222222)));
@@ -324,7 +382,7 @@ const z = `
324
382
  background: var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)));
325
383
  }
326
384
  `;
327
- class y extends P {
385
+ class x extends V {
328
386
  name = "filtering";
329
387
  version = "1.0.0";
330
388
  get defaultConfig() {
@@ -344,7 +402,8 @@ class y extends P {
344
402
  panelElement = null;
345
403
  searchText = /* @__PURE__ */ new Map();
346
404
  excludedValues = /* @__PURE__ */ new Map();
347
- documentClickHandler = null;
405
+ panelAbortController = null;
406
+ // For panel-scoped listeners
348
407
  globalStylesInjected = !1;
349
408
  // Virtualization constants for filter value list
350
409
  static LIST_ITEM_HEIGHT = 28;
@@ -356,16 +415,16 @@ class y extends P {
356
415
  super.attach(e), this.injectGlobalStyles();
357
416
  }
358
417
  detach() {
359
- this.filters.clear(), this.cachedResult = null, this.cacheKey = null, this.openPanelField = null, this.panelElement && (this.panelElement.remove(), this.panelElement = null), this.searchText.clear(), this.excludedValues.clear(), this.removeDocumentClickHandler();
418
+ this.filters.clear(), this.cachedResult = null, this.cacheKey = null, this.openPanelField = null, this.panelElement && (this.panelElement.remove(), this.panelElement = null), this.searchText.clear(), this.excludedValues.clear(), this.panelAbortController?.abort(), this.panelAbortController = null;
360
419
  }
361
420
  // ===== Hooks =====
362
421
  processRows(e) {
363
422
  const t = [...this.filters.values()];
364
423
  if (!t.length) return [...e];
365
- const r = B(t);
424
+ const r = z(t);
366
425
  if (this.cacheKey === r && this.cachedResult)
367
426
  return this.cachedResult;
368
- const l = q([...e], t, this.config.caseSensitive);
427
+ const l = B([...e], t, this.config.caseSensitive);
369
428
  return this.cachedResult = l, this.cacheKey = r, l;
370
429
  }
371
430
  afterRender() {
@@ -375,13 +434,13 @@ class y extends P {
375
434
  e.querySelectorAll('[part~="header-cell"]').forEach((r) => {
376
435
  const l = r.getAttribute("data-col");
377
436
  if (l === null) return;
378
- const s = this.columns[parseInt(l, 10)];
379
- if (!s || s.filterable === !1 || r.querySelector(".tbw-filter-btn")) return;
380
- const i = s.field;
437
+ const a = this.columns[parseInt(l, 10)];
438
+ if (!a || a.filterable === !1 || r.querySelector(".tbw-filter-btn")) return;
439
+ const i = a.field;
381
440
  if (!i) return;
382
441
  const n = document.createElement("button");
383
- n.className = "tbw-filter-btn", n.setAttribute("aria-label", `Filter ${s.header ?? i}`), n.innerHTML = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', this.filters.has(i) && (n.classList.add("active"), r.classList.add("filtered")), n.addEventListener("click", (u) => {
384
- u.stopPropagation(), this.toggleFilterPanel(i, s, n);
442
+ n.className = "tbw-filter-btn", n.setAttribute("aria-label", `Filter ${a.header ?? i}`), n.innerHTML = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', this.filters.has(i) && (n.classList.add("active"), r.classList.add("filtered")), n.addEventListener("click", (u) => {
443
+ u.stopPropagation(), this.toggleFilterPanel(i, a, n);
385
444
  }), r.appendChild(n);
386
445
  });
387
446
  }
@@ -468,7 +527,7 @@ class y extends P {
468
527
  * Uses sourceRows to include all values regardless of current filter.
469
528
  */
470
529
  getUniqueValues(e) {
471
- return M(this.sourceRows, e);
530
+ return H(this.sourceRows, e);
472
531
  }
473
532
  // ===== Private Methods =====
474
533
  /**
@@ -481,7 +540,7 @@ class y extends P {
481
540
  return;
482
541
  }
483
542
  const e = document.createElement("style");
484
- e.id = "tbw-filter-panel-styles", e.textContent = z, document.head.appendChild(e), this.globalStylesInjected = !0;
543
+ e.id = "tbw-filter-panel-styles", e.textContent = K, document.head.appendChild(e), this.globalStylesInjected = !0;
485
544
  }
486
545
  /**
487
546
  * Toggle the filter panel for a field
@@ -494,20 +553,20 @@ class y extends P {
494
553
  this.closeFilterPanel();
495
554
  const l = document.createElement("div");
496
555
  l.className = "tbw-filter-panel", this.panelElement = l, this.openPanelField = e;
497
- const s = M(this.sourceRows, e);
556
+ const a = H(this.sourceRows, e);
498
557
  let i = this.excludedValues.get(e);
499
558
  i || (i = /* @__PURE__ */ new Set(), this.excludedValues.set(e, i));
500
559
  const n = this.searchText.get(e) ?? "", u = {
501
560
  field: e,
502
561
  column: t,
503
- uniqueValues: s,
562
+ uniqueValues: a,
504
563
  excludedValues: i,
505
564
  searchText: n,
506
- applySetFilter: (m) => {
507
- this.applySetFilter(e, m), this.closeFilterPanel();
565
+ applySetFilter: (h) => {
566
+ this.applySetFilter(e, h), this.closeFilterPanel();
508
567
  },
509
- applyTextFilter: (m, k, w) => {
510
- this.applyTextFilter(e, m, k, w), this.closeFilterPanel();
568
+ applyTextFilter: (h, E, C) => {
569
+ this.applyTextFilter(e, h, E, C), this.closeFilterPanel();
511
570
  },
512
571
  clearFilter: () => {
513
572
  this.clearFieldFilter(e), this.closeFilterPanel();
@@ -515,25 +574,21 @@ class y extends P {
515
574
  closePanel: () => this.closeFilterPanel()
516
575
  };
517
576
  let g = !1;
518
- this.config.filterPanelRenderer && (this.config.filterPanelRenderer(l, u), g = l.children.length > 0), g || this.renderDefaultFilterPanel(l, u, s, i), document.body.appendChild(l), this.positionPanel(l, r);
519
- const p = (m) => {
520
- !l.contains(m.target) && m.target !== r && this.closeFilterPanel();
521
- };
522
- this.documentClickHandler = p, setTimeout(() => {
523
- document.addEventListener("click", p);
577
+ this.config.filterPanelRenderer && (this.config.filterPanelRenderer(l, u), g = l.children.length > 0), g || this.renderDefaultFilterPanel(l, u, a, i), document.body.appendChild(l), this.positionPanel(l, r), this.panelAbortController = new AbortController(), setTimeout(() => {
578
+ document.addEventListener(
579
+ "click",
580
+ (h) => {
581
+ !l.contains(h.target) && h.target !== r && this.closeFilterPanel();
582
+ },
583
+ { signal: this.panelAbortController?.signal }
584
+ );
524
585
  }, 0);
525
586
  }
526
587
  /**
527
588
  * Close the filter panel
528
589
  */
529
590
  closeFilterPanel() {
530
- this.panelElement && (this.panelElement.remove(), this.panelElement = null), this.openPanelField = null, this.removeDocumentClickHandler();
531
- }
532
- /**
533
- * Remove the document click handler
534
- */
535
- removeDocumentClickHandler() {
536
- this.documentClickHandler && (document.removeEventListener("click", this.documentClickHandler), this.documentClickHandler = null);
591
+ this.panelElement && (this.panelElement.remove(), this.panelElement = null), this.openPanelField = null, this.panelAbortController?.abort(), this.panelAbortController = null;
537
592
  }
538
593
  /**
539
594
  * Position the panel below the button
@@ -549,112 +604,112 @@ class y extends P {
549
604
  * Render the default filter panel content
550
605
  */
551
606
  renderDefaultFilterPanel(e, t, r, l) {
552
- const { field: s } = t, i = document.createElement("div");
607
+ const { field: a } = t, i = document.createElement("div");
553
608
  i.className = "tbw-filter-search";
554
609
  const n = document.createElement("input");
555
- n.type = "text", n.placeholder = "Search...", n.className = "tbw-filter-search-input", n.value = this.searchText.get(s) ?? "", i.appendChild(n), e.appendChild(i);
610
+ n.type = "text", n.placeholder = "Search...", n.className = "tbw-filter-search-input", n.value = this.searchText.get(a) ?? "", i.appendChild(n), e.appendChild(i);
556
611
  const u = document.createElement("div");
557
612
  u.className = "tbw-filter-actions";
558
613
  const g = document.createElement("label");
559
614
  g.className = "tbw-filter-value-item", g.style.padding = "0", g.style.margin = "0";
560
- const p = document.createElement("input");
561
- p.type = "checkbox", p.className = "tbw-filter-checkbox";
562
- const m = document.createElement("span");
563
- m.textContent = "Select All", g.appendChild(p), g.appendChild(m), u.appendChild(g);
564
- const k = () => {
565
- const a = [...x.values()], d = a.every((c) => c), h = a.every((c) => !c);
566
- p.checked = d, p.indeterminate = !d && !h;
615
+ const h = document.createElement("input");
616
+ h.type = "checkbox", h.className = "tbw-filter-checkbox";
617
+ const E = document.createElement("span");
618
+ E.textContent = "Select All", g.appendChild(h), g.appendChild(E), u.appendChild(g);
619
+ const C = () => {
620
+ const s = [...v.values()], d = s.every((c) => c), p = s.every((c) => !c);
621
+ h.checked = d, h.indeterminate = !d && !p;
567
622
  };
568
- p.addEventListener("change", () => {
569
- const a = p.checked;
570
- for (const d of x.keys())
571
- x.set(d, a);
572
- k(), F();
623
+ h.addEventListener("change", () => {
624
+ const s = h.checked;
625
+ for (const d of v.keys())
626
+ v.set(d, s);
627
+ C(), F();
573
628
  }), e.appendChild(u);
574
- const w = document.createElement("div");
575
- w.className = "tbw-filter-values";
576
- const E = document.createElement("div");
577
- E.className = "tbw-filter-values-spacer", w.appendChild(E);
629
+ const m = document.createElement("div");
630
+ m.className = "tbw-filter-values";
631
+ const R = document.createElement("div");
632
+ R.className = "tbw-filter-values-spacer", m.appendChild(R);
578
633
  const b = document.createElement("div");
579
- b.className = "tbw-filter-values-content", w.appendChild(b);
580
- const x = /* @__PURE__ */ new Map();
581
- r.forEach((a) => {
582
- const d = a == null ? "__null__" : String(a);
583
- x.set(d, !l.has(a));
584
- }), k();
585
- let C = [];
586
- const H = (a, d) => {
587
- const h = a == null ? "(Blank)" : String(a), c = a == null ? "__null__" : String(a), o = document.createElement("label");
588
- o.className = "tbw-filter-value-item", o.style.position = "absolute", o.style.top = `${d * y.LIST_ITEM_HEIGHT}px`, o.style.left = "0", o.style.right = "0", o.style.height = `${y.LIST_ITEM_HEIGHT}px`, o.style.boxSizing = "border-box";
589
- const v = document.createElement("input");
590
- v.type = "checkbox", v.className = "tbw-filter-checkbox", v.checked = x.get(c) ?? !0, v.dataset.value = c, v.addEventListener("change", () => {
591
- x.set(c, v.checked), k();
634
+ b.className = "tbw-filter-values-content", m.appendChild(b);
635
+ const v = /* @__PURE__ */ new Map();
636
+ r.forEach((s) => {
637
+ const d = s == null ? "__null__" : String(s);
638
+ v.set(d, !l.has(s));
639
+ }), C();
640
+ let y = [];
641
+ const I = (s, d) => {
642
+ const p = s == null ? "(Blank)" : String(s), c = s == null ? "__null__" : String(s), o = document.createElement("label");
643
+ o.className = "tbw-filter-value-item", o.style.position = "absolute", o.style.top = `${d * x.LIST_ITEM_HEIGHT}px`, o.style.left = "0", o.style.right = "0", o.style.height = `${x.LIST_ITEM_HEIGHT}px`, o.style.boxSizing = "border-box";
644
+ const w = document.createElement("input");
645
+ w.type = "checkbox", w.className = "tbw-filter-checkbox", w.checked = v.get(c) ?? !0, w.dataset.value = c, w.addEventListener("change", () => {
646
+ v.set(c, w.checked), C();
592
647
  });
593
- const N = document.createElement("span");
594
- return N.textContent = h, o.appendChild(v), o.appendChild(N), o;
648
+ const A = document.createElement("span");
649
+ return A.textContent = p, o.appendChild(w), o.appendChild(A), o;
595
650
  }, F = () => {
596
- const a = C.length, d = w.clientHeight, h = w.scrollTop;
597
- if (E.style.height = `${a * y.LIST_ITEM_HEIGHT}px`, V(a, y.LIST_BYPASS_THRESHOLD / 3)) {
598
- b.innerHTML = "", b.style.transform = "translateY(0px)", C.forEach((o, v) => {
599
- b.appendChild(H(o, v));
651
+ const s = y.length, d = m.clientHeight, p = m.scrollTop;
652
+ if (R.style.height = `${s * x.LIST_ITEM_HEIGHT}px`, P(s, x.LIST_BYPASS_THRESHOLD / 3)) {
653
+ b.innerHTML = "", b.style.transform = "translateY(0px)", y.forEach((o, w) => {
654
+ b.appendChild(I(o, w));
600
655
  });
601
656
  return;
602
657
  }
603
- const c = A({
604
- totalRows: a,
658
+ const c = M({
659
+ totalRows: s,
605
660
  viewportHeight: d,
606
- scrollTop: h,
607
- rowHeight: y.LIST_ITEM_HEIGHT,
608
- overscan: y.LIST_OVERSCAN
661
+ scrollTop: p,
662
+ rowHeight: x.LIST_ITEM_HEIGHT,
663
+ overscan: x.LIST_OVERSCAN
609
664
  });
610
665
  b.style.transform = `translateY(${c.offsetY}px)`, b.innerHTML = "";
611
666
  for (let o = c.start; o < c.end; o++)
612
- b.appendChild(H(C[o], o - c.start));
613
- }, I = (a) => {
614
- const d = a.toLowerCase();
615
- if (C = r.filter((h) => {
616
- const c = h == null ? "(Blank)" : String(h);
617
- return !a || c.toLowerCase().includes(d);
618
- }), C.length === 0) {
619
- E.style.height = "0px", b.innerHTML = "";
620
- const h = document.createElement("div");
621
- h.className = "tbw-filter-no-match", h.textContent = "No matching values", b.appendChild(h);
667
+ b.appendChild(I(y[o], o - c.start));
668
+ }, L = (s) => {
669
+ const d = s.toLowerCase();
670
+ if (y = r.filter((p) => {
671
+ const c = p == null ? "(Blank)" : String(p);
672
+ return !s || c.toLowerCase().includes(d);
673
+ }), y.length === 0) {
674
+ R.style.height = "0px", b.innerHTML = "";
675
+ const p = document.createElement("div");
676
+ p.className = "tbw-filter-no-match", p.textContent = "No matching values", b.appendChild(p);
622
677
  return;
623
678
  }
624
679
  F();
625
680
  };
626
- w.addEventListener(
681
+ m.addEventListener(
627
682
  "scroll",
628
683
  () => {
629
- C.length > 0 && F();
684
+ y.length > 0 && F();
630
685
  },
631
686
  { passive: !0 }
632
- ), I(n.value), e.appendChild(w);
633
- let L;
687
+ ), L(n.value), e.appendChild(m);
688
+ let N;
634
689
  n.addEventListener("input", () => {
635
- clearTimeout(L), L = setTimeout(() => {
636
- this.searchText.set(s, n.value), I(n.value);
690
+ clearTimeout(N), N = setTimeout(() => {
691
+ this.searchText.set(a, n.value), L(n.value);
637
692
  }, this.config.debounceMs ?? 150);
638
693
  });
639
- const R = document.createElement("div");
640
- R.className = "tbw-filter-buttons";
641
- const S = document.createElement("button");
642
- S.className = "tbw-filter-apply-btn", S.textContent = "Apply", S.addEventListener("click", () => {
643
- const a = [];
644
- for (const [d, h] of x)
645
- if (!h)
694
+ const S = document.createElement("div");
695
+ S.className = "tbw-filter-buttons";
696
+ const T = document.createElement("button");
697
+ T.className = "tbw-filter-apply-btn", T.textContent = "Apply", T.addEventListener("click", () => {
698
+ const s = [];
699
+ for (const [d, p] of v)
700
+ if (!p)
646
701
  if (d === "__null__")
647
- a.push(null);
702
+ s.push(null);
648
703
  else {
649
704
  const c = r.find((o) => String(o) === d);
650
- a.push(c !== void 0 ? c : d);
705
+ s.push(c !== void 0 ? c : d);
651
706
  }
652
- t.applySetFilter(a);
653
- }), R.appendChild(S);
654
- const T = document.createElement("button");
655
- T.className = "tbw-filter-clear-btn", T.textContent = "Clear Filter", T.addEventListener("click", () => {
707
+ t.applySetFilter(s);
708
+ }), S.appendChild(T);
709
+ const k = document.createElement("button");
710
+ k.className = "tbw-filter-clear-btn", k.textContent = "Clear Filter", k.addEventListener("click", () => {
656
711
  t.clearFilter();
657
- }), R.appendChild(T), e.appendChild(R);
712
+ }), S.appendChild(k), e.appendChild(S);
658
713
  }
659
714
  /**
660
715
  * Apply a set filter (exclude values)
@@ -754,6 +809,6 @@ class y extends P {
754
809
  `;
755
810
  }
756
811
  export {
757
- y as FilteringPlugin
812
+ x as FilteringPlugin
758
813
  };
759
814
  //# sourceMappingURL=index.js.map