@toolbox-web/grid 1.12.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 +806 -785
- package/all.js.map +1 -1
- package/index.js +1459 -1431
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +2 -1
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/types.d.ts +5 -1
- 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/index.js.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/index.js.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +7 -0
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +183 -144
- 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.map +1 -1
- 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/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 +24 -24
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +18 -18
- 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/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.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/selection.umd.js +2 -2
- package/umd/plugins/selection.umd.js.map +1 -1
|
@@ -131,6 +131,9 @@ export declare class MasterDetailPlugin extends BaseGridPlugin<MasterDetailConfi
|
|
|
131
131
|
private get animationStyle();
|
|
132
132
|
/**
|
|
133
133
|
* Apply expand animation to a detail element.
|
|
134
|
+
* Returns true if animation was applied, false if skipped.
|
|
135
|
+
* When animated, height measurement is deferred to animationend to avoid
|
|
136
|
+
* measuring during the max-height: 0 CSS animation constraint.
|
|
134
137
|
*/
|
|
135
138
|
private animateExpand;
|
|
136
139
|
/**
|
|
@@ -141,11 +144,15 @@ export declare class MasterDetailPlugin extends BaseGridPlugin<MasterDetailConfi
|
|
|
141
144
|
private detailElements;
|
|
142
145
|
/** Cached measured heights - persists even when elements are virtualized out */
|
|
143
146
|
private measuredDetailHeights;
|
|
147
|
+
/** Rows that were just expanded by user action and should animate.
|
|
148
|
+
* Prevents re-animation when rows scroll back into the virtual window. */
|
|
149
|
+
private rowsToAnimate;
|
|
144
150
|
/** Default height for detail rows when not configured */
|
|
145
151
|
private static readonly DEFAULT_DETAIL_HEIGHT;
|
|
146
152
|
/**
|
|
147
153
|
* Get the estimated height for a detail row.
|
|
148
154
|
* Uses cached measured height when available (survives virtualization).
|
|
155
|
+
* Avoids reading offsetHeight during CSS animations to prevent poisoning the cache.
|
|
149
156
|
*/
|
|
150
157
|
private getDetailHeight;
|
|
151
158
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MasterDetailPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/master-detail/MasterDetailPlugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE3G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AASrD,OAAO,KAAK,EAA+C,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE/F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,qBAAa,kBAAmB,SAAQ,cAAc,CAAC,kBAAkB,CAAC;;IACxE,gBAAgB;IAChB,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,gBAAgB;IAChB,SAAkB,MAAM,SAAU;IAElC,gBAAgB;IAChB,cAAuB,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAUlE;IAID;;;;OAIG;IACM,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAKxC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,mBAAmB;IAqE3B;;;OAGG;IACH,OAAO,KAAK,cAAc,GAGzB;IAED
|
|
1
|
+
{"version":3,"file":"MasterDetailPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/master-detail/MasterDetailPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,76 +23,76 @@ const E = /{{\s*([^}]+)\s*}}/g, u = "__DG_EMPTY__", v = /^[\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();
|
|
37
|
-
if (
|
|
37
|
+
if (y.has(s)) {
|
|
38
38
|
e.push(i);
|
|
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
|
|
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 p = '<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 k {
|
|
|
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 k {
|
|
|
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
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 q(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,19 +578,19 @@ class x extends k {
|
|
|
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 && (
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
const
|
|
592
|
-
return
|
|
593
|
-
}), Object.keys(
|
|
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
|
+
}), Object.keys(d).length > 0 && (this.config = { ...this.config, ...d });
|
|
594
594
|
}
|
|
595
595
|
// #endregion
|
|
596
596
|
// #region Animation Helpers
|
|
@@ -603,15 +603,18 @@ class x extends k {
|
|
|
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,43 +630,61 @@ class x extends k {
|
|
|
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();
|
|
634
649
|
/** Cached measured heights - persists even when elements are virtualized out */
|
|
635
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();
|
|
636
654
|
/** Default height for detail rows when not configured */
|
|
637
655
|
static DEFAULT_DETAIL_HEIGHT = 150;
|
|
638
656
|
/**
|
|
639
657
|
* Get the estimated height for a detail row.
|
|
640
658
|
* Uses cached measured height when available (survives virtualization).
|
|
659
|
+
* Avoids reading offsetHeight during CSS animations to prevent poisoning the cache.
|
|
641
660
|
*/
|
|
642
661
|
getDetailHeight(e) {
|
|
643
662
|
const t = this.detailElements.get(e);
|
|
644
|
-
if (t) {
|
|
645
|
-
const
|
|
646
|
-
if (
|
|
647
|
-
return this.measuredDetailHeights.set(e,
|
|
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;
|
|
648
667
|
}
|
|
649
668
|
const i = this.measuredDetailHeights.get(e);
|
|
650
|
-
return i && i > 0 ? i : typeof this.config?.detailHeight == "number" ? this.config.detailHeight :
|
|
669
|
+
return i && i > 0 ? i : typeof this.config?.detailHeight == "number" ? this.config.detailHeight : v.DEFAULT_DETAIL_HEIGHT;
|
|
651
670
|
}
|
|
652
671
|
/**
|
|
653
672
|
* Toggle a row's detail and emit event.
|
|
654
673
|
*/
|
|
655
674
|
toggleAndEmit(e, t) {
|
|
656
|
-
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", {
|
|
657
678
|
rowIndex: t,
|
|
658
679
|
row: e,
|
|
659
|
-
expanded:
|
|
680
|
+
expanded: i
|
|
660
681
|
}), this.requestRender();
|
|
661
682
|
}
|
|
662
683
|
// #endregion
|
|
663
684
|
// #region Lifecycle
|
|
664
685
|
/** @internal */
|
|
665
686
|
detach() {
|
|
666
|
-
this.expandedRows.clear(), this.detailElements.clear(), this.measuredDetailHeights.clear();
|
|
687
|
+
this.expandedRows.clear(), this.detailElements.clear(), this.measuredDetailHeights.clear(), this.rowsToAnimate.clear();
|
|
667
688
|
}
|
|
668
689
|
// #endregion
|
|
669
690
|
// #region Hooks
|
|
@@ -672,15 +693,15 @@ class x extends k {
|
|
|
672
693
|
if (!(this.config.showExpandColumn === !0 || this.config.showExpandColumn !== !1 && !!this.config.detailRenderer))
|
|
673
694
|
return [...e];
|
|
674
695
|
const i = [...e];
|
|
675
|
-
if (
|
|
696
|
+
if (M(i))
|
|
676
697
|
return i;
|
|
677
|
-
const
|
|
678
|
-
return
|
|
679
|
-
const { row:
|
|
680
|
-
|
|
681
|
-
const
|
|
682
|
-
return
|
|
683
|
-
}, [
|
|
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");
|
|
701
|
+
d.className = "master-detail-expander expander-cell";
|
|
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];
|
|
684
705
|
}
|
|
685
706
|
/** @internal */
|
|
686
707
|
onRowClick(e) {
|
|
@@ -691,20 +712,20 @@ class x extends k {
|
|
|
691
712
|
onCellClick(e) {
|
|
692
713
|
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
693
714
|
return this.toggleAndEmit(e.row, e.rowIndex), !0;
|
|
694
|
-
this.expandedRows.size > 0 && queueMicrotask(() => this.#
|
|
715
|
+
this.expandedRows.size > 0 && queueMicrotask(() => this.#t());
|
|
695
716
|
}
|
|
696
717
|
/** @internal */
|
|
697
718
|
onKeyDown(e) {
|
|
698
719
|
if (e.key !== " ") return;
|
|
699
720
|
const t = this.grid._focusCol, i = this.grid._focusRow, s = this.columns[t];
|
|
700
|
-
if (!s || !
|
|
701
|
-
const
|
|
702
|
-
if (
|
|
703
|
-
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;
|
|
704
725
|
}
|
|
705
726
|
/** @internal */
|
|
706
727
|
afterRender() {
|
|
707
|
-
this.#
|
|
728
|
+
this.#t();
|
|
708
729
|
}
|
|
709
730
|
/**
|
|
710
731
|
* Called on scroll to sync detail elements with visible rows.
|
|
@@ -712,44 +733,52 @@ class x extends k {
|
|
|
712
733
|
* @internal
|
|
713
734
|
*/
|
|
714
735
|
onScrollRender() {
|
|
715
|
-
!this.config.detailRenderer || this.expandedRows.size === 0 || this.#
|
|
736
|
+
!this.config.detailRenderer || this.expandedRows.size === 0 || this.#t();
|
|
716
737
|
}
|
|
717
738
|
/**
|
|
718
739
|
* Full sync of detail rows - cleans up stale elements and creates new ones.
|
|
719
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).
|
|
720
745
|
*/
|
|
721
|
-
#
|
|
746
|
+
#t() {
|
|
722
747
|
if (!this.config.detailRenderer) return;
|
|
723
748
|
const e = this.gridElement?.querySelector(".rows");
|
|
724
749
|
if (!e) return;
|
|
725
|
-
const t =
|
|
726
|
-
|
|
727
|
-
const
|
|
728
|
-
|
|
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
|
+
}
|
|
729
763
|
}
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
(!l || !c) && (d.remove(), o && this.detailElements.delete(o));
|
|
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));
|
|
734
767
|
}
|
|
735
|
-
for (const [
|
|
736
|
-
const
|
|
737
|
-
if (!
|
|
738
|
-
const
|
|
739
|
-
if (
|
|
740
|
-
|
|
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);
|
|
741
774
|
continue;
|
|
742
775
|
}
|
|
743
|
-
const
|
|
744
|
-
typeof this.config.detailHeight == "number" && (
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
this.measuredDetailHeights.set(o, h), g !== h && this.grid.invalidateRowHeight(d);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}), this.animateExpand(c);
|
|
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
|
+
});
|
|
753
782
|
}
|
|
754
783
|
}
|
|
755
784
|
/**
|
|
@@ -790,8 +819,8 @@ class x extends k {
|
|
|
790
819
|
getRowHeight(e, t) {
|
|
791
820
|
if (!this.expandedRows.has(e))
|
|
792
821
|
return;
|
|
793
|
-
const s = this.grid.defaultRowHeight ?? 28,
|
|
794
|
-
return s +
|
|
822
|
+
const s = this.grid.defaultRowHeight ?? 28, r = this.getDetailHeight(e);
|
|
823
|
+
return s + r;
|
|
795
824
|
}
|
|
796
825
|
/**
|
|
797
826
|
* Adjust the virtualization start index to keep expanded row visible while its detail is visible.
|
|
@@ -799,18 +828,28 @@ class x extends k {
|
|
|
799
828
|
*/
|
|
800
829
|
adjustVirtualStart(e, t, i) {
|
|
801
830
|
if (this.expandedRows.size === 0) return e;
|
|
802
|
-
const s =
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
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
|
+
}
|
|
812
851
|
}
|
|
813
|
-
return
|
|
852
|
+
return r;
|
|
814
853
|
}
|
|
815
854
|
// #endregion
|
|
816
855
|
// #region Public API
|
|
@@ -820,7 +859,7 @@ class x extends k {
|
|
|
820
859
|
*/
|
|
821
860
|
expand(e) {
|
|
822
861
|
const t = this.rows[e];
|
|
823
|
-
t && (this.expandedRows =
|
|
862
|
+
t && (this.rowsToAnimate.add(t), this.expandedRows = F(this.expandedRows, t), this.requestRender());
|
|
824
863
|
}
|
|
825
864
|
/**
|
|
826
865
|
* Collapse the detail row at the given index.
|
|
@@ -828,7 +867,7 @@ class x extends k {
|
|
|
828
867
|
*/
|
|
829
868
|
collapse(e) {
|
|
830
869
|
const t = this.rows[e];
|
|
831
|
-
t && (this.expandedRows =
|
|
870
|
+
t && (this.expandedRows = U(this.expandedRows, t), this.requestRender());
|
|
832
871
|
}
|
|
833
872
|
/**
|
|
834
873
|
* Toggle the detail row at the given index.
|
|
@@ -836,7 +875,7 @@ class x extends k {
|
|
|
836
875
|
*/
|
|
837
876
|
toggle(e) {
|
|
838
877
|
const t = this.rows[e];
|
|
839
|
-
t && (this.expandedRows =
|
|
878
|
+
t && (this.expandedRows = x(this.expandedRows, t), this.expandedRows.has(t) && this.rowsToAnimate.add(t), this.requestRender());
|
|
840
879
|
}
|
|
841
880
|
/**
|
|
842
881
|
* Check if the detail row at the given index is expanded.
|
|
@@ -845,14 +884,14 @@ class x extends k {
|
|
|
845
884
|
*/
|
|
846
885
|
isExpanded(e) {
|
|
847
886
|
const t = this.rows[e];
|
|
848
|
-
return t ?
|
|
887
|
+
return t ? z(this.expandedRows, t) : !1;
|
|
849
888
|
}
|
|
850
889
|
/**
|
|
851
890
|
* Expand all detail rows.
|
|
852
891
|
*/
|
|
853
892
|
expandAll() {
|
|
854
893
|
for (const e of this.rows)
|
|
855
|
-
this.expandedRows.add(e);
|
|
894
|
+
this.rowsToAnimate.add(e), this.expandedRows.add(e);
|
|
856
895
|
this.requestRender();
|
|
857
896
|
}
|
|
858
897
|
/**
|
|
@@ -899,6 +938,6 @@ class x extends k {
|
|
|
899
938
|
// #endregion
|
|
900
939
|
}
|
|
901
940
|
export {
|
|
902
|
-
|
|
941
|
+
v as MasterDetailPlugin
|
|
903
942
|
};
|
|
904
943
|
//# sourceMappingURL=index.js.map
|