@toolbox-web/grid 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all.js +694 -525
- package/all.js.map +1 -1
- package/index.js +1468 -1449
- 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/internal/sanitize.d.ts.map +1 -1
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/core/types.d.ts +9 -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/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/editors.d.ts.map +1 -1
- package/lib/plugins/editing/index.d.ts +1 -1
- package/lib/plugins/editing/index.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +187 -170
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/editing/types.d.ts +44 -0
- 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 +9 -9
- 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 +185 -145
- 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 +40 -39
- package/lib/plugins/responsive/index.js.map +1 -1
- package/lib/plugins/row-reorder/index.js.map +1 -1
- package/lib/plugins/selection/SelectionPlugin.d.ts +51 -0
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
- package/lib/plugins/selection/index.js +325 -131
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/types.d.ts +18 -0
- package/lib/plugins/selection/types.d.ts.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/public.d.ts +2 -0
- package/public.d.ts.map +1 -1
- package/themes/dg-theme-bootstrap.css +192 -8
- package/themes/dg-theme-material.css +243 -0
- package/umd/grid.all.umd.js +43 -43
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +19 -19
- 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/filtering.umd.js +1 -1
- package/umd/plugins/filtering.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 C = /{{\s*([^}]+)\s*}}/g, g = "__DG_EMPTY__", _ = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, y = /__(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/, D = /* @__PURE__ */ new Set([
|
|
2
2
|
"script",
|
|
3
3
|
"iframe",
|
|
4
4
|
"object",
|
|
@@ -23,76 +23,77 @@ const E = /{{\s*([^}]+)\s*}}/g, u = "__DG_EMPTY__", v = /^[\w$. '?+\-*/%:()!<>=,
|
|
|
23
23
|
"plaintext",
|
|
24
24
|
"xmp",
|
|
25
25
|
"listing"
|
|
26
|
-
]),
|
|
27
|
-
function
|
|
26
|
+
]), b = /^on\w+$/i, S = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), H = /^\s*(javascript|vbscript|data|blob):/i;
|
|
27
|
+
function T(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, L(e.content), e.innerHTML;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function L(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 (D.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) => b.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 (b.test(o)) {
|
|
51
|
+
r.push(a.name);
|
|
52
52
|
continue;
|
|
53
53
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
54
|
+
if (S.has(o) && H.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 I(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
|
|
69
|
+
const t = [], i = n.replace(C, (o, c) => {
|
|
70
|
+
const d = O(c, e);
|
|
71
|
+
return t.push({ expr: c.trim(), result: d }), d;
|
|
72
|
+
}), s = k(i), r = t.length && t.every((o) => o.result === "" || o.result === g);
|
|
73
|
+
return p.test(n) || r ? "" : s;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
if (n = (n || "").trim(), !n ||
|
|
77
|
-
if (n === "value") return e.value == null ?
|
|
75
|
+
function O(n, e) {
|
|
76
|
+
if (n = (n || "").trim(), !n || p.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 || !_.test(n) || y.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
|
|
86
|
+
const s = new Function("value", "row", `return (${n});`)(e.value, e.row), r = s == null ? "" : String(s);
|
|
87
|
+
return p.test(r) ? g : r || g;
|
|
88
88
|
} catch {
|
|
89
|
-
return
|
|
89
|
+
return g;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const p = /Reflect|Proxy|ownKeys/;
|
|
93
|
+
function k(n) {
|
|
94
|
+
return n && n.replace(new RegExp(g, "g"), "").replace(/Reflect\.[^<>{}\s]+|\bProxy\b|ownKeys\([^)]*\)/g, "");
|
|
94
95
|
}
|
|
95
|
-
const
|
|
96
|
+
const x = '<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>', N = {
|
|
96
97
|
expand: "▶",
|
|
97
98
|
collapse: "▼",
|
|
98
99
|
sortAsc: "▲",
|
|
@@ -101,11 +102,11 @@ const p = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
|
|
|
101
102
|
submenuArrow: "▶",
|
|
102
103
|
dragHandle: "⋮⋮",
|
|
103
104
|
toolPanel: "☰",
|
|
104
|
-
filter:
|
|
105
|
-
filterActive:
|
|
105
|
+
filter: x,
|
|
106
|
+
filterActive: x,
|
|
106
107
|
print: "🖨️"
|
|
107
108
|
};
|
|
108
|
-
class
|
|
109
|
+
class M {
|
|
109
110
|
/**
|
|
110
111
|
* Plugin dependencies - declare other plugins this one requires.
|
|
111
112
|
*
|
|
@@ -395,7 +396,7 @@ class k {
|
|
|
395
396
|
*/
|
|
396
397
|
get gridIcons() {
|
|
397
398
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
398
|
-
return { ...
|
|
399
|
+
return { ...N, ...e };
|
|
399
400
|
}
|
|
400
401
|
// #region Animation Helpers
|
|
401
402
|
/**
|
|
@@ -471,19 +472,19 @@ class k {
|
|
|
471
472
|
}
|
|
472
473
|
// #endregion
|
|
473
474
|
}
|
|
474
|
-
const
|
|
475
|
-
function
|
|
476
|
-
return n.field ===
|
|
475
|
+
const E = "__tbw_expander", q = 32;
|
|
476
|
+
function v(n) {
|
|
477
|
+
return n.field === E;
|
|
477
478
|
}
|
|
478
|
-
function
|
|
479
|
-
return n.find(
|
|
479
|
+
function P(n) {
|
|
480
|
+
return n.find(v);
|
|
480
481
|
}
|
|
481
|
-
function
|
|
482
|
+
function F(n) {
|
|
482
483
|
return {
|
|
483
|
-
field:
|
|
484
|
+
field: E,
|
|
484
485
|
header: "",
|
|
485
486
|
// No header text - visually merges with next column
|
|
486
|
-
width:
|
|
487
|
+
width: q,
|
|
487
488
|
resizable: !1,
|
|
488
489
|
sortable: !1,
|
|
489
490
|
filterable: !1,
|
|
@@ -498,35 +499,35 @@ function q(n) {
|
|
|
498
499
|
}
|
|
499
500
|
};
|
|
500
501
|
}
|
|
501
|
-
function
|
|
502
|
+
function R(n, e) {
|
|
502
503
|
const t = new Set(n);
|
|
503
504
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
504
505
|
}
|
|
505
|
-
function
|
|
506
|
+
function U(n, e) {
|
|
506
507
|
const t = new Set(n);
|
|
507
508
|
return t.add(e), t;
|
|
508
509
|
}
|
|
509
|
-
function
|
|
510
|
+
function z(n, e) {
|
|
510
511
|
const t = new Set(n);
|
|
511
512
|
return t.delete(e), t;
|
|
512
513
|
}
|
|
513
|
-
function
|
|
514
|
+
function G(n, e) {
|
|
514
515
|
return n.has(e);
|
|
515
516
|
}
|
|
516
|
-
function
|
|
517
|
+
function W(n, e, t, i) {
|
|
517
518
|
const s = document.createElement("div");
|
|
518
519
|
s.className = "master-detail-row", s.setAttribute("data-detail-for", String(e)), s.setAttribute("role", "row");
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
const
|
|
522
|
-
return typeof
|
|
520
|
+
const r = document.createElement("div");
|
|
521
|
+
r.className = "master-detail-cell", r.setAttribute("role", "cell"), r.style.gridColumn = `1 / ${i + 1}`;
|
|
522
|
+
const a = t(n, e);
|
|
523
|
+
return typeof a == "string" ? r.innerHTML = a : a instanceof HTMLElement && r.appendChild(a), s.appendChild(r), s;
|
|
523
524
|
}
|
|
524
|
-
const
|
|
525
|
-
class
|
|
525
|
+
const $ = "@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}}}";
|
|
526
|
+
class A extends M {
|
|
526
527
|
/** @internal */
|
|
527
528
|
name = "masterDetail";
|
|
528
529
|
/** @internal */
|
|
529
|
-
styles =
|
|
530
|
+
styles = $;
|
|
530
531
|
/** @internal */
|
|
531
532
|
get defaultConfig() {
|
|
532
533
|
return {
|
|
@@ -578,19 +579,19 @@ class x extends k {
|
|
|
578
579
|
if (!t) return;
|
|
579
580
|
const i = e;
|
|
580
581
|
if (i.__frameworkAdapter?.parseDetailElement) {
|
|
581
|
-
const
|
|
582
|
-
if (
|
|
583
|
-
this.config = { ...this.config, detailRenderer:
|
|
582
|
+
const u = i.__frameworkAdapter.parseDetailElement(t);
|
|
583
|
+
if (u) {
|
|
584
|
+
this.config = { ...this.config, detailRenderer: u };
|
|
584
585
|
return;
|
|
585
586
|
}
|
|
586
587
|
}
|
|
587
|
-
const s = t.getAttribute("animation"),
|
|
588
|
-
s !== null && (
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
const
|
|
592
|
-
return
|
|
593
|
-
}), Object.keys(
|
|
588
|
+
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 = {};
|
|
589
|
+
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));
|
|
590
|
+
const l = t.innerHTML.trim();
|
|
591
|
+
l && !this.config.detailRenderer && (d.detailRenderer = (u, h) => {
|
|
592
|
+
const f = I(l, { value: u, row: u });
|
|
593
|
+
return T(f);
|
|
594
|
+
}), Object.keys(d).length > 0 && (this.config = { ...this.config, ...d });
|
|
594
595
|
}
|
|
595
596
|
// #endregion
|
|
596
597
|
// #region Animation Helpers
|
|
@@ -603,15 +604,18 @@ class x extends k {
|
|
|
603
604
|
}
|
|
604
605
|
/**
|
|
605
606
|
* Apply expand animation to a detail element.
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
)
|
|
607
|
+
* Returns true if animation was applied, false if skipped.
|
|
608
|
+
* When animated, height measurement is deferred to animationend to avoid
|
|
609
|
+
* measuring during the max-height: 0 CSS animation constraint.
|
|
610
|
+
*/
|
|
611
|
+
animateExpand(e, t, i) {
|
|
612
|
+
if (!this.isAnimationEnabled || this.animationStyle === !1) return !1;
|
|
613
|
+
e.classList.add("tbw-expanding");
|
|
614
|
+
let s = !1;
|
|
615
|
+
const r = () => {
|
|
616
|
+
s || (s = !0, e.classList.remove("tbw-expanding"), t !== void 0 && i !== void 0 && this.#e(e, t, i));
|
|
617
|
+
};
|
|
618
|
+
return e.addEventListener("animationend", r, { once: !0 }), setTimeout(r, this.animationDuration + 50), !0;
|
|
615
619
|
}
|
|
616
620
|
/**
|
|
617
621
|
* Apply collapse animation to a detail element and remove after animation.
|
|
@@ -627,43 +631,61 @@ class x extends k {
|
|
|
627
631
|
};
|
|
628
632
|
e.addEventListener("animationend", i, { once: !0 }), setTimeout(i, this.animationDuration + 50);
|
|
629
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* Measure a detail element's height and update the position cache if it changed.
|
|
636
|
+
* Used after layout settles (RAF) or after animation completes (animationend).
|
|
637
|
+
*/
|
|
638
|
+
#e(e, t, i) {
|
|
639
|
+
if (!e.isConnected) return;
|
|
640
|
+
const s = e.offsetHeight;
|
|
641
|
+
if (s > 0) {
|
|
642
|
+
const r = this.measuredDetailHeights.get(t);
|
|
643
|
+
this.measuredDetailHeights.set(t, s), r !== s && this.grid.invalidateRowHeight(i);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
630
646
|
// #endregion
|
|
631
647
|
// #region Internal State
|
|
632
648
|
expandedRows = /* @__PURE__ */ new Set();
|
|
633
649
|
detailElements = /* @__PURE__ */ new Map();
|
|
634
650
|
/** Cached measured heights - persists even when elements are virtualized out */
|
|
635
651
|
measuredDetailHeights = /* @__PURE__ */ new Map();
|
|
652
|
+
/** Rows that were just expanded by user action and should animate.
|
|
653
|
+
* Prevents re-animation when rows scroll back into the virtual window. */
|
|
654
|
+
rowsToAnimate = /* @__PURE__ */ new Set();
|
|
636
655
|
/** Default height for detail rows when not configured */
|
|
637
656
|
static DEFAULT_DETAIL_HEIGHT = 150;
|
|
638
657
|
/**
|
|
639
658
|
* Get the estimated height for a detail row.
|
|
640
659
|
* Uses cached measured height when available (survives virtualization).
|
|
660
|
+
* Avoids reading offsetHeight during CSS animations to prevent poisoning the cache.
|
|
641
661
|
*/
|
|
642
662
|
getDetailHeight(e) {
|
|
643
663
|
const t = this.detailElements.get(e);
|
|
644
|
-
if (t) {
|
|
645
|
-
const
|
|
646
|
-
if (
|
|
647
|
-
return this.measuredDetailHeights.set(e,
|
|
664
|
+
if (t && !(t.classList.contains("tbw-expanding") || t.classList.contains("tbw-collapsing"))) {
|
|
665
|
+
const r = t.offsetHeight;
|
|
666
|
+
if (r > 0)
|
|
667
|
+
return this.measuredDetailHeights.set(e, r), r;
|
|
648
668
|
}
|
|
649
669
|
const i = this.measuredDetailHeights.get(e);
|
|
650
|
-
return i && i > 0 ? i : typeof this.config?.detailHeight == "number" ? this.config.detailHeight :
|
|
670
|
+
return i && i > 0 ? i : typeof this.config?.detailHeight == "number" ? this.config.detailHeight : A.DEFAULT_DETAIL_HEIGHT;
|
|
651
671
|
}
|
|
652
672
|
/**
|
|
653
673
|
* Toggle a row's detail and emit event.
|
|
654
674
|
*/
|
|
655
675
|
toggleAndEmit(e, t) {
|
|
656
|
-
this.expandedRows =
|
|
676
|
+
this.expandedRows = R(this.expandedRows, e);
|
|
677
|
+
const i = this.expandedRows.has(e);
|
|
678
|
+
i && this.rowsToAnimate.add(e), this.emit("detail-expand", {
|
|
657
679
|
rowIndex: t,
|
|
658
680
|
row: e,
|
|
659
|
-
expanded:
|
|
681
|
+
expanded: i
|
|
660
682
|
}), this.requestRender();
|
|
661
683
|
}
|
|
662
684
|
// #endregion
|
|
663
685
|
// #region Lifecycle
|
|
664
686
|
/** @internal */
|
|
665
687
|
detach() {
|
|
666
|
-
this.expandedRows.clear(), this.detailElements.clear(), this.measuredDetailHeights.clear();
|
|
688
|
+
this.expandedRows.clear(), this.detailElements.clear(), this.measuredDetailHeights.clear(), this.rowsToAnimate.clear();
|
|
667
689
|
}
|
|
668
690
|
// #endregion
|
|
669
691
|
// #region Hooks
|
|
@@ -672,15 +694,15 @@ class x extends k {
|
|
|
672
694
|
if (!(this.config.showExpandColumn === !0 || this.config.showExpandColumn !== !1 && !!this.config.detailRenderer))
|
|
673
695
|
return [...e];
|
|
674
696
|
const i = [...e];
|
|
675
|
-
if (
|
|
697
|
+
if (P(i))
|
|
676
698
|
return i;
|
|
677
|
-
const
|
|
678
|
-
return
|
|
679
|
-
const { row:
|
|
680
|
-
|
|
681
|
-
const
|
|
682
|
-
return
|
|
683
|
-
}, [
|
|
699
|
+
const r = F(this.name);
|
|
700
|
+
return r.viewRenderer = (a) => {
|
|
701
|
+
const { row: o } = a, c = this.expandedRows.has(o), d = document.createElement("span");
|
|
702
|
+
d.className = "master-detail-expander expander-cell";
|
|
703
|
+
const l = document.createElement("span");
|
|
704
|
+
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;
|
|
705
|
+
}, [r, ...i];
|
|
684
706
|
}
|
|
685
707
|
/** @internal */
|
|
686
708
|
onRowClick(e) {
|
|
@@ -691,20 +713,20 @@ class x extends k {
|
|
|
691
713
|
onCellClick(e) {
|
|
692
714
|
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
693
715
|
return this.toggleAndEmit(e.row, e.rowIndex), !0;
|
|
694
|
-
this.expandedRows.size > 0 && queueMicrotask(() => this.#
|
|
716
|
+
this.expandedRows.size > 0 && queueMicrotask(() => this.#t());
|
|
695
717
|
}
|
|
696
718
|
/** @internal */
|
|
697
719
|
onKeyDown(e) {
|
|
698
720
|
if (e.key !== " ") return;
|
|
699
721
|
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(
|
|
722
|
+
if (!s || !v(s)) return;
|
|
723
|
+
const r = this.rows[i];
|
|
724
|
+
if (r)
|
|
725
|
+
return e.preventDefault(), this.toggleAndEmit(r, i), this.requestRenderWithFocus(), !0;
|
|
704
726
|
}
|
|
705
727
|
/** @internal */
|
|
706
728
|
afterRender() {
|
|
707
|
-
this.#
|
|
729
|
+
this.#t();
|
|
708
730
|
}
|
|
709
731
|
/**
|
|
710
732
|
* Called on scroll to sync detail elements with visible rows.
|
|
@@ -712,44 +734,52 @@ class x extends k {
|
|
|
712
734
|
* @internal
|
|
713
735
|
*/
|
|
714
736
|
onScrollRender() {
|
|
715
|
-
!this.config.detailRenderer || this.expandedRows.size === 0 || this.#
|
|
737
|
+
!this.config.detailRenderer || this.expandedRows.size === 0 || this.#t();
|
|
716
738
|
}
|
|
717
739
|
/**
|
|
718
740
|
* Full sync of detail rows - cleans up stale elements and creates new ones.
|
|
719
741
|
* Detail rows are inserted as siblings AFTER their master row to survive row rebuilds.
|
|
742
|
+
*
|
|
743
|
+
* PERF: Uses the grid's row pool (_rowPool) and virtual window (_virtualization.start/end)
|
|
744
|
+
* to avoid querySelectorAll on every scroll frame. The pool is index-aligned with the
|
|
745
|
+
* virtual window, so pool[i] corresponds to row index (start + i).
|
|
720
746
|
*/
|
|
721
|
-
#
|
|
747
|
+
#t() {
|
|
722
748
|
if (!this.config.detailRenderer) return;
|
|
723
749
|
const e = this.gridElement?.querySelector(".rows");
|
|
724
750
|
if (!e) return;
|
|
725
|
-
const t =
|
|
726
|
-
|
|
727
|
-
const
|
|
728
|
-
|
|
751
|
+
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();
|
|
752
|
+
if (i) {
|
|
753
|
+
const l = Math.min(i.length, c - o);
|
|
754
|
+
for (let u = 0; u < l; u++) {
|
|
755
|
+
const h = i[u];
|
|
756
|
+
h.parentNode === e && d.set(o + u, h);
|
|
757
|
+
}
|
|
758
|
+
} else {
|
|
759
|
+
const l = e.querySelectorAll(".data-grid-row");
|
|
760
|
+
for (const u of l) {
|
|
761
|
+
const h = u.querySelector(".cell[data-row]"), f = h ? parseInt(h.getAttribute("data-row") ?? "-1", 10) : -1;
|
|
762
|
+
f >= 0 && d.set(f, u);
|
|
763
|
+
}
|
|
729
764
|
}
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
(!l || !c) && (d.remove(), o && this.detailElements.delete(o));
|
|
765
|
+
for (const [l, u] of this.detailElements) {
|
|
766
|
+
const h = this.rows.indexOf(l), f = this.expandedRows.has(l), m = h >= 0 && d.has(h);
|
|
767
|
+
(!f || !m) && (u.parentNode && u.remove(), this.detailElements.delete(l));
|
|
734
768
|
}
|
|
735
|
-
for (const [
|
|
736
|
-
const
|
|
737
|
-
if (!
|
|
738
|
-
const
|
|
739
|
-
if (
|
|
740
|
-
|
|
769
|
+
for (const [l, u] of d) {
|
|
770
|
+
const h = this.rows[l];
|
|
771
|
+
if (!h || !this.expandedRows.has(h)) continue;
|
|
772
|
+
const f = this.detailElements.get(h);
|
|
773
|
+
if (f) {
|
|
774
|
+
f.previousElementSibling !== u && u.after(f);
|
|
741
775
|
continue;
|
|
742
776
|
}
|
|
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);
|
|
777
|
+
const m = W(h, l, this.config.detailRenderer, a);
|
|
778
|
+
typeof this.config.detailHeight == "number" && (m.style.height = `${this.config.detailHeight}px`), u.after(m), this.detailElements.set(h, m);
|
|
779
|
+
const w = this.rowsToAnimate.has(h);
|
|
780
|
+
w && this.rowsToAnimate.delete(h), w && this.animateExpand(m, h, l) || requestAnimationFrame(() => {
|
|
781
|
+
this.#e(m, h, l);
|
|
782
|
+
});
|
|
753
783
|
}
|
|
754
784
|
}
|
|
755
785
|
/**
|
|
@@ -790,8 +820,8 @@ class x extends k {
|
|
|
790
820
|
getRowHeight(e, t) {
|
|
791
821
|
if (!this.expandedRows.has(e))
|
|
792
822
|
return;
|
|
793
|
-
const s = this.grid.defaultRowHeight ?? 28,
|
|
794
|
-
return s +
|
|
823
|
+
const s = this.grid.defaultRowHeight ?? 28, r = this.getDetailHeight(e);
|
|
824
|
+
return s + r;
|
|
795
825
|
}
|
|
796
826
|
/**
|
|
797
827
|
* Adjust the virtualization start index to keep expanded row visible while its detail is visible.
|
|
@@ -799,18 +829,28 @@ class x extends k {
|
|
|
799
829
|
*/
|
|
800
830
|
adjustVirtualStart(e, t, i) {
|
|
801
831
|
if (this.expandedRows.size === 0) return e;
|
|
802
|
-
const s =
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
832
|
+
const s = this.grid?._virtualization?.positionCache;
|
|
833
|
+
let r = e;
|
|
834
|
+
if (s && s.length > 0)
|
|
835
|
+
for (const a of this.expandedRows) {
|
|
836
|
+
const o = this.rows.indexOf(a);
|
|
837
|
+
if (o < 0 || o >= e) continue;
|
|
838
|
+
s[o].offset + s[o].height > t && o < r && (r = o);
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
const a = [];
|
|
842
|
+
for (const c of this.expandedRows) {
|
|
843
|
+
const d = this.rows.indexOf(c);
|
|
844
|
+
d >= 0 && a.push({ index: d, row: c });
|
|
845
|
+
}
|
|
846
|
+
a.sort((c, d) => c.index - d.index);
|
|
847
|
+
let o = 0;
|
|
848
|
+
for (const { index: c, row: d } of a) {
|
|
849
|
+
const l = c * i + o, u = this.getDetailHeight(d), h = l + i + u;
|
|
850
|
+
o += u, !(c >= e) && h > t && c < r && (r = c);
|
|
851
|
+
}
|
|
812
852
|
}
|
|
813
|
-
return
|
|
853
|
+
return r;
|
|
814
854
|
}
|
|
815
855
|
// #endregion
|
|
816
856
|
// #region Public API
|
|
@@ -820,7 +860,7 @@ class x extends k {
|
|
|
820
860
|
*/
|
|
821
861
|
expand(e) {
|
|
822
862
|
const t = this.rows[e];
|
|
823
|
-
t && (this.expandedRows =
|
|
863
|
+
t && (this.rowsToAnimate.add(t), this.expandedRows = U(this.expandedRows, t), this.requestRender());
|
|
824
864
|
}
|
|
825
865
|
/**
|
|
826
866
|
* Collapse the detail row at the given index.
|
|
@@ -828,7 +868,7 @@ class x extends k {
|
|
|
828
868
|
*/
|
|
829
869
|
collapse(e) {
|
|
830
870
|
const t = this.rows[e];
|
|
831
|
-
t && (this.expandedRows =
|
|
871
|
+
t && (this.expandedRows = z(this.expandedRows, t), this.requestRender());
|
|
832
872
|
}
|
|
833
873
|
/**
|
|
834
874
|
* Toggle the detail row at the given index.
|
|
@@ -836,7 +876,7 @@ class x extends k {
|
|
|
836
876
|
*/
|
|
837
877
|
toggle(e) {
|
|
838
878
|
const t = this.rows[e];
|
|
839
|
-
t && (this.expandedRows =
|
|
879
|
+
t && (this.expandedRows = R(this.expandedRows, t), this.expandedRows.has(t) && this.rowsToAnimate.add(t), this.requestRender());
|
|
840
880
|
}
|
|
841
881
|
/**
|
|
842
882
|
* Check if the detail row at the given index is expanded.
|
|
@@ -845,14 +885,14 @@ class x extends k {
|
|
|
845
885
|
*/
|
|
846
886
|
isExpanded(e) {
|
|
847
887
|
const t = this.rows[e];
|
|
848
|
-
return t ?
|
|
888
|
+
return t ? G(this.expandedRows, t) : !1;
|
|
849
889
|
}
|
|
850
890
|
/**
|
|
851
891
|
* Expand all detail rows.
|
|
852
892
|
*/
|
|
853
893
|
expandAll() {
|
|
854
894
|
for (const e of this.rows)
|
|
855
|
-
this.expandedRows.add(e);
|
|
895
|
+
this.rowsToAnimate.add(e), this.expandedRows.add(e);
|
|
856
896
|
this.requestRender();
|
|
857
897
|
}
|
|
858
898
|
/**
|
|
@@ -899,6 +939,6 @@ class x extends k {
|
|
|
899
939
|
// #endregion
|
|
900
940
|
}
|
|
901
941
|
export {
|
|
902
|
-
|
|
942
|
+
A as MasterDetailPlugin
|
|
903
943
|
};
|
|
904
944
|
//# sourceMappingURL=index.js.map
|