@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.
- package/README.md +24 -0
- package/all.d.ts +1709 -135
- package/all.js +745 -645
- package/all.js.map +1 -1
- package/index.d.ts +161 -1
- package/index.js +1050 -913
- package/index.js.map +1 -1
- package/lib/plugins/clipboard/index.js +110 -52
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js +78 -20
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/index.js +163 -95
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/export/index.js +93 -35
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js +188 -133
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/index.js +69 -11
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/index.js +111 -55
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/index.js +196 -51
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js +104 -46
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js +74 -16
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +65 -7
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +117 -59
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/reorder/index.js +103 -45
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +139 -81
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js +96 -38
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js +108 -47
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js +70 -12
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js +82 -24
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +31 -31
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +15 -15
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +2 -2
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +3 -3
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +2 -2
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +2 -2
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +2 -2
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
|
|
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
|
|
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),
|
|
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
|
|
191
|
+
return a.includes(i);
|
|
134
192
|
case "notContains":
|
|
135
|
-
return !
|
|
193
|
+
return !a.includes(i);
|
|
136
194
|
case "equals":
|
|
137
|
-
return
|
|
195
|
+
return a === i;
|
|
138
196
|
case "notEquals":
|
|
139
|
-
return
|
|
197
|
+
return a !== i;
|
|
140
198
|
case "startsWith":
|
|
141
|
-
return
|
|
199
|
+
return a.startsWith(i);
|
|
142
200
|
case "endsWith":
|
|
143
|
-
return
|
|
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
|
|
165
|
-
return e.length ? f.filter((r) => e.every((l) =>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
424
|
+
const r = z(t);
|
|
366
425
|
if (this.cacheKey === r && this.cachedResult)
|
|
367
426
|
return this.cachedResult;
|
|
368
|
-
const l =
|
|
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
|
|
379
|
-
if (!
|
|
380
|
-
const i =
|
|
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 ${
|
|
384
|
-
u.stopPropagation(), this.toggleFilterPanel(i,
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
562
|
+
uniqueValues: a,
|
|
504
563
|
excludedValues: i,
|
|
505
564
|
searchText: n,
|
|
506
|
-
applySetFilter: (
|
|
507
|
-
this.applySetFilter(e,
|
|
565
|
+
applySetFilter: (h) => {
|
|
566
|
+
this.applySetFilter(e, h), this.closeFilterPanel();
|
|
508
567
|
},
|
|
509
|
-
applyTextFilter: (
|
|
510
|
-
this.applyTextFilter(e,
|
|
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,
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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.
|
|
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:
|
|
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(
|
|
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
|
|
561
|
-
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
const
|
|
565
|
-
const
|
|
566
|
-
|
|
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
|
-
|
|
569
|
-
const
|
|
570
|
-
for (const d of
|
|
571
|
-
|
|
572
|
-
|
|
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
|
|
575
|
-
|
|
576
|
-
const
|
|
577
|
-
|
|
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",
|
|
580
|
-
const
|
|
581
|
-
r.forEach((
|
|
582
|
-
const d =
|
|
583
|
-
|
|
584
|
-
}),
|
|
585
|
-
let
|
|
586
|
-
const
|
|
587
|
-
const
|
|
588
|
-
o.className = "tbw-filter-value-item", o.style.position = "absolute", o.style.top = `${d *
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
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
|
|
594
|
-
return
|
|
648
|
+
const A = document.createElement("span");
|
|
649
|
+
return A.textContent = p, o.appendChild(w), o.appendChild(A), o;
|
|
595
650
|
}, F = () => {
|
|
596
|
-
const
|
|
597
|
-
if (
|
|
598
|
-
b.innerHTML = "", b.style.transform = "translateY(0px)",
|
|
599
|
-
b.appendChild(
|
|
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 =
|
|
604
|
-
totalRows:
|
|
658
|
+
const c = M({
|
|
659
|
+
totalRows: s,
|
|
605
660
|
viewportHeight: d,
|
|
606
|
-
scrollTop:
|
|
607
|
-
rowHeight:
|
|
608
|
-
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(
|
|
613
|
-
},
|
|
614
|
-
const d =
|
|
615
|
-
if (
|
|
616
|
-
const c =
|
|
617
|
-
return !
|
|
618
|
-
}),
|
|
619
|
-
|
|
620
|
-
const
|
|
621
|
-
|
|
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
|
-
|
|
681
|
+
m.addEventListener(
|
|
627
682
|
"scroll",
|
|
628
683
|
() => {
|
|
629
|
-
|
|
684
|
+
y.length > 0 && F();
|
|
630
685
|
},
|
|
631
686
|
{ passive: !0 }
|
|
632
|
-
),
|
|
633
|
-
let
|
|
687
|
+
), L(n.value), e.appendChild(m);
|
|
688
|
+
let N;
|
|
634
689
|
n.addEventListener("input", () => {
|
|
635
|
-
clearTimeout(
|
|
636
|
-
this.searchText.set(
|
|
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
|
|
640
|
-
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
const
|
|
644
|
-
for (const [d,
|
|
645
|
-
if (!
|
|
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
|
-
|
|
702
|
+
s.push(null);
|
|
648
703
|
else {
|
|
649
704
|
const c = r.find((o) => String(o) === d);
|
|
650
|
-
|
|
705
|
+
s.push(c !== void 0 ? c : d);
|
|
651
706
|
}
|
|
652
|
-
t.applySetFilter(
|
|
653
|
-
}),
|
|
654
|
-
const
|
|
655
|
-
|
|
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
|
-
}),
|
|
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
|
-
|
|
812
|
+
x as FilteringPlugin
|
|
758
813
|
};
|
|
759
814
|
//# sourceMappingURL=index.js.map
|