@toolbox-web/grid 1.11.0 → 1.12.1
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/all.js +1224 -1110
- package/all.js.map +1 -1
- package/index.js +2000 -1700
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +21 -1
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/aria.d.ts +52 -0
- package/lib/core/internal/aria.d.ts.map +1 -0
- package/lib/core/internal/config-manager.d.ts.map +1 -1
- package/lib/core/internal/idle-scheduler.d.ts +0 -27
- package/lib/core/internal/idle-scheduler.d.ts.map +1 -1
- package/lib/core/internal/loading.d.ts +0 -38
- package/lib/core/internal/loading.d.ts.map +1 -1
- package/lib/core/internal/row-animation.d.ts.map +1 -1
- package/lib/core/internal/shell.d.ts +6 -0
- package/lib/core/internal/shell.d.ts.map +1 -1
- package/lib/core/internal/style-injector.d.ts +0 -8
- package/lib/core/internal/style-injector.d.ts.map +1 -1
- package/lib/core/internal/utils.d.ts +6 -4
- package/lib/core/internal/utils.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/core/internal/virtualization.d.ts +177 -23
- package/lib/core/internal/virtualization.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +50 -0
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/plugin-manager.d.ts +18 -0
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/core/plugin/types.d.ts +16 -0
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +56 -3
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +1 -1
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +7 -5
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +379 -278
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/editing/types.d.ts +14 -1
- package/lib/plugins/editing/types.d.ts.map +1 -1
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +8 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +59 -60
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +14 -0
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +88 -69
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/grouping-rows/types.d.ts +17 -0
- package/lib/plugins/grouping-rows/types.d.ts.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +24 -0
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +203 -128
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/index.js +2 -2
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/index.js +2 -2
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/print/index.js.map +1 -1
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/responsive/ResponsivePlugin.d.ts +13 -0
- package/lib/plugins/responsive/ResponsivePlugin.d.ts.map +1 -1
- package/lib/plugins/responsive/index.js +65 -49
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/row-reorder/index.js.map +1 -1
- package/lib/plugins/selection/index.js +5 -5
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +27 -25
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +18 -16
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.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 +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/responsive.umd.js +1 -1
- package/umd/plugins/responsive.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +2 -2
- package/umd/plugins/selection.umd.js.map +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const A = /{{\s*([^}]+)\s*}}/g, g = "__DG_EMPTY__", C = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, _ = /__(proto|defineGetter|defineSetter)|constructor|window|globalThis|global|process|Function|import|eval|Reflect|Proxy|Error|arguments|document|location|cookie|localStorage|sessionStorage|indexedDB|fetch|XMLHttpRequest|WebSocket|Worker|SharedWorker|ServiceWorker|opener|parent|top|frames|self|this\b/, y = /* @__PURE__ */ new Set([
|
|
2
2
|
"script",
|
|
3
3
|
"iframe",
|
|
4
4
|
"object",
|
|
@@ -23,14 +23,14 @@ const R = /{{\s*([^}]+)\s*}}/g, u = "__DG_EMPTY__", E = /^[\w$. '?+\-*/%:()!<>=,
|
|
|
23
23
|
"plaintext",
|
|
24
24
|
"xmp",
|
|
25
25
|
"listing"
|
|
26
|
-
]),
|
|
27
|
-
function
|
|
26
|
+
]), w = /^on\w+$/i, D = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), S = /^\s*(javascript|vbscript|data|blob):/i;
|
|
27
|
+
function H(n) {
|
|
28
28
|
if (!n || typeof n != "string") return "";
|
|
29
29
|
if (n.indexOf("<") === -1) return n;
|
|
30
30
|
const e = document.createElement("template");
|
|
31
|
-
return e.innerHTML = n,
|
|
31
|
+
return e.innerHTML = n, T(e.content), e.innerHTML;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function T(n) {
|
|
34
34
|
const e = [], t = n.querySelectorAll("*");
|
|
35
35
|
for (const i of t) {
|
|
36
36
|
const s = i.tagName.toLowerCase();
|
|
@@ -39,60 +39,60 @@ function D(n) {
|
|
|
39
39
|
continue;
|
|
40
40
|
}
|
|
41
41
|
if ((s === "svg" || i.namespaceURI === "http://www.w3.org/2000/svg") && Array.from(i.attributes).some(
|
|
42
|
-
(
|
|
42
|
+
(o) => w.test(o.name) || o.name === "href" || o.name === "xlink:href"
|
|
43
43
|
)) {
|
|
44
44
|
e.push(i);
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
|
-
const
|
|
48
|
-
for (const
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
|
|
47
|
+
const r = [];
|
|
48
|
+
for (const a of i.attributes) {
|
|
49
|
+
const o = a.name.toLowerCase();
|
|
50
|
+
if (w.test(o)) {
|
|
51
|
+
r.push(a.name);
|
|
52
52
|
continue;
|
|
53
53
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
54
|
+
if (D.has(o) && S.test(a.value)) {
|
|
55
|
+
r.push(a.name);
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
|
-
if (
|
|
59
|
-
|
|
58
|
+
if (o === "style" && /expression\s*\(|javascript:|behavior\s*:/i.test(a.value)) {
|
|
59
|
+
r.push(a.name);
|
|
60
60
|
continue;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
r.forEach((a) => i.removeAttribute(a));
|
|
64
64
|
}
|
|
65
65
|
e.forEach((i) => i.remove());
|
|
66
66
|
}
|
|
67
|
-
function
|
|
67
|
+
function L(n, e) {
|
|
68
68
|
if (!n || n.indexOf("{{") === -1) return n;
|
|
69
|
-
const t = [], i = n.replace(
|
|
70
|
-
const d =
|
|
71
|
-
return t.push({ expr:
|
|
72
|
-
}), s =
|
|
73
|
-
return /Reflect\.|\bProxy\b|ownKeys\(/.test(n) ||
|
|
69
|
+
const t = [], i = n.replace(A, (o, c) => {
|
|
70
|
+
const d = I(c, e);
|
|
71
|
+
return t.push({ expr: c.trim(), result: d }), d;
|
|
72
|
+
}), s = O(i), r = t.length && t.every((o) => o.result === "" || o.result === g);
|
|
73
|
+
return /Reflect\.|\bProxy\b|ownKeys\(/.test(n) || r ? "" : s;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
if (n = (n || "").trim(), !n || /\b(Reflect|Proxy|ownKeys)\b/.test(n)) return
|
|
77
|
-
if (n === "value") return e.value == null ?
|
|
75
|
+
function I(n, e) {
|
|
76
|
+
if (n = (n || "").trim(), !n || /\b(Reflect|Proxy|ownKeys)\b/.test(n)) return g;
|
|
77
|
+
if (n === "value") return e.value == null ? g : String(e.value);
|
|
78
78
|
if (n.startsWith("row.") && !/[()?]/.test(n) && !n.includes(":")) {
|
|
79
79
|
const i = n.slice(4), s = e.row ? e.row[i] : void 0;
|
|
80
|
-
return s == null ?
|
|
80
|
+
return s == null ? g : String(s);
|
|
81
81
|
}
|
|
82
|
-
if (n.length > 80 || !
|
|
82
|
+
if (n.length > 80 || !C.test(n) || _.test(n)) return g;
|
|
83
83
|
const t = n.match(/\./g);
|
|
84
|
-
if (t && t.length > 1) return
|
|
84
|
+
if (t && t.length > 1) return g;
|
|
85
85
|
try {
|
|
86
|
-
const s = new Function("value", "row", `return (${n});`)(e.value, e.row),
|
|
87
|
-
return /Reflect|Proxy|ownKeys/.test(
|
|
86
|
+
const s = new Function("value", "row", `return (${n});`)(e.value, e.row), r = s == null ? "" : String(s);
|
|
87
|
+
return /Reflect|Proxy|ownKeys/.test(r) ? g : r || g;
|
|
88
88
|
} catch {
|
|
89
|
-
return
|
|
89
|
+
return g;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
function
|
|
93
|
-
return n && n.replace(new RegExp(
|
|
92
|
+
function O(n) {
|
|
93
|
+
return n && n.replace(new RegExp(g, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
|
|
94
94
|
}
|
|
95
|
-
const
|
|
95
|
+
const b = '<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>', k = {
|
|
96
96
|
expand: "▶",
|
|
97
97
|
collapse: "▼",
|
|
98
98
|
sortAsc: "▲",
|
|
@@ -101,11 +101,11 @@ const h = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
|
|
|
101
101
|
submenuArrow: "▶",
|
|
102
102
|
dragHandle: "⋮⋮",
|
|
103
103
|
toolPanel: "☰",
|
|
104
|
-
filter:
|
|
105
|
-
filterActive:
|
|
104
|
+
filter: b,
|
|
105
|
+
filterActive: b,
|
|
106
106
|
print: "🖨️"
|
|
107
107
|
};
|
|
108
|
-
class
|
|
108
|
+
class N {
|
|
109
109
|
/**
|
|
110
110
|
* Plugin dependencies - declare other plugins this one requires.
|
|
111
111
|
*
|
|
@@ -395,7 +395,7 @@ class H {
|
|
|
395
395
|
*/
|
|
396
396
|
get gridIcons() {
|
|
397
397
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
398
|
-
return { ...
|
|
398
|
+
return { ...k, ...e };
|
|
399
399
|
}
|
|
400
400
|
// #region Animation Helpers
|
|
401
401
|
/**
|
|
@@ -471,19 +471,19 @@ class H {
|
|
|
471
471
|
}
|
|
472
472
|
// #endregion
|
|
473
473
|
}
|
|
474
|
-
const
|
|
475
|
-
function
|
|
476
|
-
return n.field ===
|
|
474
|
+
const R = "__tbw_expander", P = 32;
|
|
475
|
+
function E(n) {
|
|
476
|
+
return n.field === R;
|
|
477
477
|
}
|
|
478
|
-
function
|
|
479
|
-
return n.find(
|
|
478
|
+
function M(n) {
|
|
479
|
+
return n.find(E);
|
|
480
480
|
}
|
|
481
|
-
function
|
|
481
|
+
function q(n) {
|
|
482
482
|
return {
|
|
483
|
-
field:
|
|
483
|
+
field: R,
|
|
484
484
|
header: "",
|
|
485
485
|
// No header text - visually merges with next column
|
|
486
|
-
width:
|
|
486
|
+
width: P,
|
|
487
487
|
resizable: !1,
|
|
488
488
|
sortable: !1,
|
|
489
489
|
filterable: !1,
|
|
@@ -498,35 +498,35 @@ function N(n) {
|
|
|
498
498
|
}
|
|
499
499
|
};
|
|
500
500
|
}
|
|
501
|
-
function
|
|
501
|
+
function x(n, e) {
|
|
502
502
|
const t = new Set(n);
|
|
503
503
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
504
504
|
}
|
|
505
|
-
function
|
|
505
|
+
function F(n, e) {
|
|
506
506
|
const t = new Set(n);
|
|
507
507
|
return t.add(e), t;
|
|
508
508
|
}
|
|
509
|
-
function
|
|
509
|
+
function U(n, e) {
|
|
510
510
|
const t = new Set(n);
|
|
511
511
|
return t.delete(e), t;
|
|
512
512
|
}
|
|
513
|
-
function
|
|
513
|
+
function z(n, e) {
|
|
514
514
|
return n.has(e);
|
|
515
515
|
}
|
|
516
|
-
function
|
|
516
|
+
function G(n, e, t, i) {
|
|
517
517
|
const s = document.createElement("div");
|
|
518
518
|
s.className = "master-detail-row", s.setAttribute("data-detail-for", String(e)), s.setAttribute("role", "row");
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
const
|
|
522
|
-
return typeof
|
|
519
|
+
const r = document.createElement("div");
|
|
520
|
+
r.className = "master-detail-cell", r.setAttribute("role", "cell"), r.style.gridColumn = `1 / ${i + 1}`;
|
|
521
|
+
const a = t(n, e);
|
|
522
|
+
return typeof a == "string" ? r.innerHTML = a : a instanceof HTMLElement && r.appendChild(a), s.appendChild(r), s;
|
|
523
523
|
}
|
|
524
|
-
const
|
|
525
|
-
class
|
|
524
|
+
const W = "@layer tbw-plugins{tbw-grid .cell[data-field=__tbw_expander]{border-right:none!important;padding:0;display:flex;align-items:center;justify-content:center}tbw-grid .header-row .cell[data-field=__tbw_expander]{display:none}tbw-grid .header-row .cell[data-field=__tbw_expander]+.cell{grid-column:1 / 3}tbw-grid .master-detail-expander{display:flex;align-items:center;justify-content:center;width:100%;height:100%}tbw-grid .master-detail-toggle{cursor:pointer;opacity:.7;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center}tbw-grid .master-detail-toggle:hover{opacity:1}tbw-grid .master-detail-row{grid-column:1 / -1;display:grid;background:var(--tbw-master-detail-bg, var(--tbw-color-row-alt));border-bottom:1px solid var(--tbw-master-detail-border, var(--tbw-color-border));overflow:hidden}tbw-grid .master-detail-cell{padding:var(--tbw-detail-padding, var(--tbw-spacing-xl, 1rem));overflow:auto}tbw-grid .master-detail-row.tbw-expanding{animation:tbw-detail-expand var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}tbw-grid .master-detail-row.tbw-collapsing{animation:tbw-detail-collapse var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-detail-expand{0%{opacity:0;max-height:0;padding-top:0;padding-bottom:0}to{opacity:1;max-height:var(--tbw-detail-max-height, 31.25rem);padding-top:var(--tbw-detail-padding, var(--tbw-spacing-xl, 1rem));padding-bottom:var(--tbw-detail-padding, var(--tbw-spacing-xl, 1rem))}}@keyframes tbw-detail-collapse{0%{opacity:1;max-height:var(--tbw-detail-max-height, 31.25rem)}to{opacity:0;max-height:0}}}";
|
|
525
|
+
class v extends N {
|
|
526
526
|
/** @internal */
|
|
527
527
|
name = "masterDetail";
|
|
528
528
|
/** @internal */
|
|
529
|
-
styles =
|
|
529
|
+
styles = W;
|
|
530
530
|
/** @internal */
|
|
531
531
|
get defaultConfig() {
|
|
532
532
|
return {
|
|
@@ -578,18 +578,18 @@ class b extends H {
|
|
|
578
578
|
if (!t) return;
|
|
579
579
|
const i = e;
|
|
580
580
|
if (i.__frameworkAdapter?.parseDetailElement) {
|
|
581
|
-
const
|
|
582
|
-
if (
|
|
583
|
-
this.config = { ...this.config, detailRenderer:
|
|
581
|
+
const u = i.__frameworkAdapter.parseDetailElement(t);
|
|
582
|
+
if (u) {
|
|
583
|
+
this.config = { ...this.config, detailRenderer: u };
|
|
584
584
|
return;
|
|
585
585
|
}
|
|
586
586
|
}
|
|
587
|
-
const s = t.getAttribute("animation"),
|
|
588
|
-
s !== null && (d.animation = s === "false" ? !1 : s),
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
const
|
|
592
|
-
return
|
|
587
|
+
const s = t.getAttribute("animation"), r = t.getAttribute("show-expand-column"), a = t.getAttribute("expand-on-row-click"), o = t.getAttribute("collapse-on-click-outside"), c = t.getAttribute("height"), d = {};
|
|
588
|
+
s !== null && (d.animation = s === "false" ? !1 : s), r !== null && (d.showExpandColumn = r !== "false"), a !== null && (d.expandOnRowClick = a === "true"), o !== null && (d.collapseOnClickOutside = o === "true"), c !== null && (d.detailHeight = c === "auto" ? "auto" : parseInt(c, 10));
|
|
589
|
+
const l = t.innerHTML.trim();
|
|
590
|
+
l && !this.config.detailRenderer && (d.detailRenderer = (u, h) => {
|
|
591
|
+
const f = L(l, { value: u, row: u });
|
|
592
|
+
return H(f);
|
|
593
593
|
}), Object.keys(d).length > 0 && (this.config = { ...this.config, ...d });
|
|
594
594
|
}
|
|
595
595
|
// #endregion
|
|
@@ -603,15 +603,18 @@ class b extends H {
|
|
|
603
603
|
}
|
|
604
604
|
/**
|
|
605
605
|
* Apply expand animation to a detail element.
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
)
|
|
606
|
+
* Returns true if animation was applied, false if skipped.
|
|
607
|
+
* When animated, height measurement is deferred to animationend to avoid
|
|
608
|
+
* measuring during the max-height: 0 CSS animation constraint.
|
|
609
|
+
*/
|
|
610
|
+
animateExpand(e, t, i) {
|
|
611
|
+
if (!this.isAnimationEnabled || this.animationStyle === !1) return !1;
|
|
612
|
+
e.classList.add("tbw-expanding");
|
|
613
|
+
let s = !1;
|
|
614
|
+
const r = () => {
|
|
615
|
+
s || (s = !0, e.classList.remove("tbw-expanding"), t !== void 0 && i !== void 0 && this.#e(e, t, i));
|
|
616
|
+
};
|
|
617
|
+
return e.addEventListener("animationend", r, { once: !0 }), setTimeout(r, this.animationDuration + 50), !0;
|
|
615
618
|
}
|
|
616
619
|
/**
|
|
617
620
|
* Apply collapse animation to a detail element and remove after animation.
|
|
@@ -627,34 +630,61 @@ class b extends H {
|
|
|
627
630
|
};
|
|
628
631
|
e.addEventListener("animationend", i, { once: !0 }), setTimeout(i, this.animationDuration + 50);
|
|
629
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* Measure a detail element's height and update the position cache if it changed.
|
|
635
|
+
* Used after layout settles (RAF) or after animation completes (animationend).
|
|
636
|
+
*/
|
|
637
|
+
#e(e, t, i) {
|
|
638
|
+
if (!e.isConnected) return;
|
|
639
|
+
const s = e.offsetHeight;
|
|
640
|
+
if (s > 0) {
|
|
641
|
+
const r = this.measuredDetailHeights.get(t);
|
|
642
|
+
this.measuredDetailHeights.set(t, s), r !== s && this.grid.invalidateRowHeight(i);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
630
645
|
// #endregion
|
|
631
646
|
// #region Internal State
|
|
632
647
|
expandedRows = /* @__PURE__ */ new Set();
|
|
633
648
|
detailElements = /* @__PURE__ */ new Map();
|
|
649
|
+
/** Cached measured heights - persists even when elements are virtualized out */
|
|
650
|
+
measuredDetailHeights = /* @__PURE__ */ new Map();
|
|
651
|
+
/** Rows that were just expanded by user action and should animate.
|
|
652
|
+
* Prevents re-animation when rows scroll back into the virtual window. */
|
|
653
|
+
rowsToAnimate = /* @__PURE__ */ new Set();
|
|
634
654
|
/** Default height for detail rows when not configured */
|
|
635
655
|
static DEFAULT_DETAIL_HEIGHT = 150;
|
|
636
656
|
/**
|
|
637
657
|
* Get the estimated height for a detail row.
|
|
658
|
+
* Uses cached measured height when available (survives virtualization).
|
|
659
|
+
* Avoids reading offsetHeight during CSS animations to prevent poisoning the cache.
|
|
638
660
|
*/
|
|
639
661
|
getDetailHeight(e) {
|
|
640
662
|
const t = this.detailElements.get(e);
|
|
641
|
-
|
|
663
|
+
if (t && !(t.classList.contains("tbw-expanding") || t.classList.contains("tbw-collapsing"))) {
|
|
664
|
+
const r = t.offsetHeight;
|
|
665
|
+
if (r > 0)
|
|
666
|
+
return this.measuredDetailHeights.set(e, r), r;
|
|
667
|
+
}
|
|
668
|
+
const i = this.measuredDetailHeights.get(e);
|
|
669
|
+
return i && i > 0 ? i : typeof this.config?.detailHeight == "number" ? this.config.detailHeight : v.DEFAULT_DETAIL_HEIGHT;
|
|
642
670
|
}
|
|
643
671
|
/**
|
|
644
672
|
* Toggle a row's detail and emit event.
|
|
645
673
|
*/
|
|
646
674
|
toggleAndEmit(e, t) {
|
|
647
|
-
this.expandedRows =
|
|
675
|
+
this.expandedRows = x(this.expandedRows, e);
|
|
676
|
+
const i = this.expandedRows.has(e);
|
|
677
|
+
i && this.rowsToAnimate.add(e), this.emit("detail-expand", {
|
|
648
678
|
rowIndex: t,
|
|
649
679
|
row: e,
|
|
650
|
-
expanded:
|
|
680
|
+
expanded: i
|
|
651
681
|
}), this.requestRender();
|
|
652
682
|
}
|
|
653
683
|
// #endregion
|
|
654
684
|
// #region Lifecycle
|
|
655
685
|
/** @internal */
|
|
656
686
|
detach() {
|
|
657
|
-
this.expandedRows.clear(), this.detailElements.clear();
|
|
687
|
+
this.expandedRows.clear(), this.detailElements.clear(), this.measuredDetailHeights.clear(), this.rowsToAnimate.clear();
|
|
658
688
|
}
|
|
659
689
|
// #endregion
|
|
660
690
|
// #region Hooks
|
|
@@ -663,15 +693,15 @@ class b extends H {
|
|
|
663
693
|
if (!(this.config.showExpandColumn === !0 || this.config.showExpandColumn !== !1 && !!this.config.detailRenderer))
|
|
664
694
|
return [...e];
|
|
665
695
|
const i = [...e];
|
|
666
|
-
if (
|
|
696
|
+
if (M(i))
|
|
667
697
|
return i;
|
|
668
|
-
const
|
|
669
|
-
return
|
|
670
|
-
const { row:
|
|
698
|
+
const r = q(this.name);
|
|
699
|
+
return r.viewRenderer = (a) => {
|
|
700
|
+
const { row: o } = a, c = this.expandedRows.has(o), d = document.createElement("span");
|
|
671
701
|
d.className = "master-detail-expander expander-cell";
|
|
672
|
-
const
|
|
673
|
-
return
|
|
674
|
-
}, [
|
|
702
|
+
const l = document.createElement("span");
|
|
703
|
+
return l.className = `master-detail-toggle${c ? " expanded" : ""}`, this.setIcon(l, this.resolveIcon(c ? "collapse" : "expand")), l.setAttribute("role", "button"), l.setAttribute("tabindex", "0"), l.setAttribute("aria-expanded", String(c)), l.setAttribute("aria-label", c ? "Collapse details" : "Expand details"), d.appendChild(l), d;
|
|
704
|
+
}, [r, ...i];
|
|
675
705
|
}
|
|
676
706
|
/** @internal */
|
|
677
707
|
onRowClick(e) {
|
|
@@ -682,20 +712,20 @@ class b extends H {
|
|
|
682
712
|
onCellClick(e) {
|
|
683
713
|
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
684
714
|
return this.toggleAndEmit(e.row, e.rowIndex), !0;
|
|
685
|
-
this.expandedRows.size > 0 && queueMicrotask(() => this.#
|
|
715
|
+
this.expandedRows.size > 0 && queueMicrotask(() => this.#t());
|
|
686
716
|
}
|
|
687
717
|
/** @internal */
|
|
688
718
|
onKeyDown(e) {
|
|
689
719
|
if (e.key !== " ") return;
|
|
690
720
|
const t = this.grid._focusCol, i = this.grid._focusRow, s = this.columns[t];
|
|
691
|
-
if (!s || !
|
|
692
|
-
const
|
|
693
|
-
if (
|
|
694
|
-
return e.preventDefault(), this.toggleAndEmit(
|
|
721
|
+
if (!s || !E(s)) return;
|
|
722
|
+
const r = this.rows[i];
|
|
723
|
+
if (r)
|
|
724
|
+
return e.preventDefault(), this.toggleAndEmit(r, i), this.requestRenderWithFocus(), !0;
|
|
695
725
|
}
|
|
696
726
|
/** @internal */
|
|
697
727
|
afterRender() {
|
|
698
|
-
this.#
|
|
728
|
+
this.#t();
|
|
699
729
|
}
|
|
700
730
|
/**
|
|
701
731
|
* Called on scroll to sync detail elements with visible rows.
|
|
@@ -703,41 +733,59 @@ class b extends H {
|
|
|
703
733
|
* @internal
|
|
704
734
|
*/
|
|
705
735
|
onScrollRender() {
|
|
706
|
-
!this.config.detailRenderer || this.expandedRows.size === 0 || this.#
|
|
736
|
+
!this.config.detailRenderer || this.expandedRows.size === 0 || this.#t();
|
|
707
737
|
}
|
|
708
738
|
/**
|
|
709
739
|
* Full sync of detail rows - cleans up stale elements and creates new ones.
|
|
710
740
|
* Detail rows are inserted as siblings AFTER their master row to survive row rebuilds.
|
|
741
|
+
*
|
|
742
|
+
* PERF: Uses the grid's row pool (_rowPool) and virtual window (_virtualization.start/end)
|
|
743
|
+
* to avoid querySelectorAll on every scroll frame. The pool is index-aligned with the
|
|
744
|
+
* virtual window, so pool[i] corresponds to row index (start + i).
|
|
711
745
|
*/
|
|
712
|
-
#
|
|
746
|
+
#t() {
|
|
713
747
|
if (!this.config.detailRenderer) return;
|
|
714
748
|
const e = this.gridElement?.querySelector(".rows");
|
|
715
749
|
if (!e) return;
|
|
716
|
-
const t =
|
|
717
|
-
|
|
718
|
-
const
|
|
719
|
-
|
|
750
|
+
const t = this.grid, i = t._rowPool, s = t._virtualization?.start ?? 0, r = t._virtualization?.end ?? 0, a = this.columns.length, o = s, c = r, d = /* @__PURE__ */ new Map();
|
|
751
|
+
if (i) {
|
|
752
|
+
const l = Math.min(i.length, c - o);
|
|
753
|
+
for (let u = 0; u < l; u++) {
|
|
754
|
+
const h = i[u];
|
|
755
|
+
h.parentNode === e && d.set(o + u, h);
|
|
756
|
+
}
|
|
757
|
+
} else {
|
|
758
|
+
const l = e.querySelectorAll(".data-grid-row");
|
|
759
|
+
for (const u of l) {
|
|
760
|
+
const h = u.querySelector(".cell[data-row]"), f = h ? parseInt(h.getAttribute("data-row") ?? "-1", 10) : -1;
|
|
761
|
+
f >= 0 && d.set(f, u);
|
|
762
|
+
}
|
|
720
763
|
}
|
|
721
|
-
const l
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
(!d || !c) && (o.remove(), a && this.detailElements.delete(a));
|
|
764
|
+
for (const [l, u] of this.detailElements) {
|
|
765
|
+
const h = this.rows.indexOf(l), f = this.expandedRows.has(l), m = h >= 0 && d.has(h);
|
|
766
|
+
(!f || !m) && (u.parentNode && u.remove(), this.detailElements.delete(l));
|
|
725
767
|
}
|
|
726
|
-
for (const [
|
|
727
|
-
const
|
|
728
|
-
if (!
|
|
729
|
-
const
|
|
730
|
-
if (
|
|
731
|
-
|
|
768
|
+
for (const [l, u] of d) {
|
|
769
|
+
const h = this.rows[l];
|
|
770
|
+
if (!h || !this.expandedRows.has(h)) continue;
|
|
771
|
+
const f = this.detailElements.get(h);
|
|
772
|
+
if (f) {
|
|
773
|
+
f.previousElementSibling !== u && u.after(f);
|
|
732
774
|
continue;
|
|
733
775
|
}
|
|
734
|
-
const
|
|
735
|
-
typeof this.config.detailHeight == "number" && (
|
|
776
|
+
const m = G(h, l, this.config.detailRenderer, a);
|
|
777
|
+
typeof this.config.detailHeight == "number" && (m.style.height = `${this.config.detailHeight}px`), u.after(m), this.detailElements.set(h, m);
|
|
778
|
+
const p = this.rowsToAnimate.has(h);
|
|
779
|
+
p && this.rowsToAnimate.delete(h), p && this.animateExpand(m, h, l) || requestAnimationFrame(() => {
|
|
780
|
+
this.#e(m, h, l);
|
|
781
|
+
});
|
|
736
782
|
}
|
|
737
783
|
}
|
|
738
784
|
/**
|
|
739
785
|
* Return total extra height from all expanded detail rows.
|
|
740
786
|
* Used by grid virtualization to adjust scrollbar height.
|
|
787
|
+
*
|
|
788
|
+
* @deprecated Use getRowHeight() instead. This hook will be removed in v3.0.
|
|
741
789
|
*/
|
|
742
790
|
getExtraHeight() {
|
|
743
791
|
let e = 0;
|
|
@@ -748,6 +796,8 @@ class b extends H {
|
|
|
748
796
|
/**
|
|
749
797
|
* Return extra height that appears before a given row index.
|
|
750
798
|
* This is the sum of heights of all expanded details whose parent row is before the given index.
|
|
799
|
+
*
|
|
800
|
+
* @deprecated Use getRowHeight() instead. This hook will be removed in v3.0.
|
|
751
801
|
*/
|
|
752
802
|
getExtraHeightBefore(e) {
|
|
753
803
|
let t = 0;
|
|
@@ -757,24 +807,49 @@ class b extends H {
|
|
|
757
807
|
}
|
|
758
808
|
return t;
|
|
759
809
|
}
|
|
810
|
+
/**
|
|
811
|
+
* Get the height of a specific row, including any expanded detail content.
|
|
812
|
+
* Always returns a height to ensure the position cache uses plugin-controlled values
|
|
813
|
+
* rather than stale DOM measurements.
|
|
814
|
+
*
|
|
815
|
+
* @param row - The row data
|
|
816
|
+
* @param _index - The row index (unused, but part of the interface)
|
|
817
|
+
* @returns The row height in pixels (base height for collapsed, base + detail for expanded)
|
|
818
|
+
*/
|
|
819
|
+
getRowHeight(e, t) {
|
|
820
|
+
if (!this.expandedRows.has(e))
|
|
821
|
+
return;
|
|
822
|
+
const s = this.grid.defaultRowHeight ?? 28, r = this.getDetailHeight(e);
|
|
823
|
+
return s + r;
|
|
824
|
+
}
|
|
760
825
|
/**
|
|
761
826
|
* Adjust the virtualization start index to keep expanded row visible while its detail is visible.
|
|
762
827
|
* This ensures the detail scrolls smoothly out of view instead of disappearing abruptly.
|
|
763
828
|
*/
|
|
764
829
|
adjustVirtualStart(e, t, i) {
|
|
765
830
|
if (this.expandedRows.size === 0) return e;
|
|
766
|
-
const s =
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
831
|
+
const s = this.grid?._virtualization?.positionCache;
|
|
832
|
+
let r = e;
|
|
833
|
+
if (s && s.length > 0)
|
|
834
|
+
for (const a of this.expandedRows) {
|
|
835
|
+
const o = this.rows.indexOf(a);
|
|
836
|
+
if (o < 0 || o >= e) continue;
|
|
837
|
+
s[o].offset + s[o].height > t && o < r && (r = o);
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
const a = [];
|
|
841
|
+
for (const c of this.expandedRows) {
|
|
842
|
+
const d = this.rows.indexOf(c);
|
|
843
|
+
d >= 0 && a.push({ index: d, row: c });
|
|
844
|
+
}
|
|
845
|
+
a.sort((c, d) => c.index - d.index);
|
|
846
|
+
let o = 0;
|
|
847
|
+
for (const { index: c, row: d } of a) {
|
|
848
|
+
const l = c * i + o, u = this.getDetailHeight(d), h = l + i + u;
|
|
849
|
+
o += u, !(c >= e) && h > t && c < r && (r = c);
|
|
850
|
+
}
|
|
776
851
|
}
|
|
777
|
-
return
|
|
852
|
+
return r;
|
|
778
853
|
}
|
|
779
854
|
// #endregion
|
|
780
855
|
// #region Public API
|
|
@@ -784,7 +859,7 @@ class b extends H {
|
|
|
784
859
|
*/
|
|
785
860
|
expand(e) {
|
|
786
861
|
const t = this.rows[e];
|
|
787
|
-
t && (this.expandedRows =
|
|
862
|
+
t && (this.rowsToAnimate.add(t), this.expandedRows = F(this.expandedRows, t), this.requestRender());
|
|
788
863
|
}
|
|
789
864
|
/**
|
|
790
865
|
* Collapse the detail row at the given index.
|
|
@@ -792,7 +867,7 @@ class b extends H {
|
|
|
792
867
|
*/
|
|
793
868
|
collapse(e) {
|
|
794
869
|
const t = this.rows[e];
|
|
795
|
-
t && (this.expandedRows =
|
|
870
|
+
t && (this.expandedRows = U(this.expandedRows, t), this.requestRender());
|
|
796
871
|
}
|
|
797
872
|
/**
|
|
798
873
|
* Toggle the detail row at the given index.
|
|
@@ -800,7 +875,7 @@ class b extends H {
|
|
|
800
875
|
*/
|
|
801
876
|
toggle(e) {
|
|
802
877
|
const t = this.rows[e];
|
|
803
|
-
t && (this.expandedRows =
|
|
878
|
+
t && (this.expandedRows = x(this.expandedRows, t), this.expandedRows.has(t) && this.rowsToAnimate.add(t), this.requestRender());
|
|
804
879
|
}
|
|
805
880
|
/**
|
|
806
881
|
* Check if the detail row at the given index is expanded.
|
|
@@ -809,14 +884,14 @@ class b extends H {
|
|
|
809
884
|
*/
|
|
810
885
|
isExpanded(e) {
|
|
811
886
|
const t = this.rows[e];
|
|
812
|
-
return t ?
|
|
887
|
+
return t ? z(this.expandedRows, t) : !1;
|
|
813
888
|
}
|
|
814
889
|
/**
|
|
815
890
|
* Expand all detail rows.
|
|
816
891
|
*/
|
|
817
892
|
expandAll() {
|
|
818
893
|
for (const e of this.rows)
|
|
819
|
-
this.expandedRows.add(e);
|
|
894
|
+
this.rowsToAnimate.add(e), this.expandedRows.add(e);
|
|
820
895
|
this.requestRender();
|
|
821
896
|
}
|
|
822
897
|
/**
|
|
@@ -863,6 +938,6 @@ class b extends H {
|
|
|
863
938
|
// #endregion
|
|
864
939
|
}
|
|
865
940
|
export {
|
|
866
|
-
|
|
941
|
+
v as MasterDetailPlugin
|
|
867
942
|
};
|
|
868
943
|
//# sourceMappingURL=index.js.map
|