@toolbox-web/grid 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -13
- package/all.js +1101 -1048
- package/all.js.map +1 -1
- package/index.js +245 -137
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +10 -0
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/config-manager.d.ts +1 -0
- package/lib/core/internal/config-manager.d.ts.map +1 -1
- package/lib/core/internal/keyboard.d.ts.map +1 -1
- package/lib/core/internal/utils.d.ts +1 -0
- package/lib/core/internal/utils.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +57 -1
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/expander-column.d.ts +51 -0
- package/lib/core/plugin/expander-column.d.ts.map +1 -0
- package/lib/core/plugin/types.d.ts +117 -1
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +4 -2
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts +5 -4
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.d.ts +1 -1
- package/lib/plugins/clipboard/index.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js +282 -188
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/clipboard/types.d.ts +72 -2
- package/lib/plugins/clipboard/types.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts +0 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/index.js +102 -26
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +0 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +154 -78
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +1 -7
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +200 -136
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/ExportPlugin.d.ts +0 -1
- package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
- package/lib/plugins/export/index.js +175 -99
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts +5 -2
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +129 -43
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +1 -2
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +144 -66
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +14 -2
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +230 -138
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +13 -11
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +265 -196
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/master-detail/types.d.ts +0 -10
- package/lib/plugins/master-detail/types.d.ts.map +1 -1
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +1 -2
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts.map +1 -1
- package/lib/plugins/multi-sort/index.js +105 -31
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +0 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/index.js +128 -52
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +1 -2
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-rows/index.js +162 -88
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/PivotPlugin.d.ts +26 -4
- package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -1
- package/lib/plugins/pivot/index.js +398 -310
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/pivot/pivot-rows.d.ts +2 -1
- package/lib/plugins/pivot/pivot-rows.d.ts.map +1 -1
- package/lib/plugins/reorder/ReorderPlugin.d.ts +13 -10
- package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
- package/lib/plugins/reorder/index.js +288 -226
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/SelectionPlugin.d.ts +21 -3
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
- package/lib/plugins/selection/index.d.ts +2 -2
- package/lib/plugins/selection/index.d.ts.map +1 -1
- package/lib/plugins/selection/index.js +276 -145
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/types.d.ts +24 -0
- package/lib/plugins/selection/types.d.ts.map +1 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts +0 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts.map +1 -1
- package/lib/plugins/server-side/index.js +83 -7
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +5 -1
- package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
- package/lib/plugins/tree/index.js +197 -112
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/types.d.ts +0 -10
- package/lib/plugins/tree/types.d.ts.map +1 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +0 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +93 -17
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +7 -4
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
- package/lib/plugins/visibility/index.js +144 -65
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +17 -19
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +7 -7
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +5 -7
- package/umd/plugins/clipboard.umd.js.map +1 -1
- package/umd/plugins/column-virtualization.umd.js +1 -1
- package/umd/plugins/column-virtualization.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/export.umd.js +1 -1
- package/umd/plugins/export.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/grouping-rows.umd.js +1 -1
- 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/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pinned-columns.umd.js +1 -1
- package/umd/plugins/pinned-columns.umd.js.map +1 -1
- package/umd/plugins/pinned-rows.umd.js +1 -1
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/server-side.umd.js +1 -1
- package/umd/plugins/server-side.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/undo-redo.umd.js +1 -1
- package/umd/plugins/undo-redo.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
- package/lib/core/internal/editing.d.ts +0 -76
- package/lib/core/internal/editing.d.ts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const R = /{{\s*([^}]+)\s*}}/g, u = "__DG_EMPTY__", b = /^[\w$. '?+\-*/%:()!<>=,&|]+$/, E = /__(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/, v = /* @__PURE__ */ new Set([
|
|
2
2
|
"script",
|
|
3
3
|
"iframe",
|
|
4
4
|
"object",
|
|
@@ -23,76 +23,76 @@ const m = /{{\s*([^}]+)\s*}}/g, f = "__DG_EMPTY__", R = /^[\w$. '?+\-*/%:()!<>=,
|
|
|
23
23
|
"plaintext",
|
|
24
24
|
"xmp",
|
|
25
25
|
"listing"
|
|
26
|
-
]),
|
|
27
|
-
function
|
|
28
|
-
if (!
|
|
29
|
-
if (
|
|
26
|
+
]), h = /^on\w+$/i, y = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "data", "srcdoc", "xlink:href", "poster", "srcset"]), C = /^\s*(javascript|vbscript|data|blob):/i;
|
|
27
|
+
function _(n) {
|
|
28
|
+
if (!n || typeof n != "string") return "";
|
|
29
|
+
if (n.indexOf("<") === -1) return n;
|
|
30
30
|
const e = document.createElement("template");
|
|
31
|
-
return e.innerHTML =
|
|
31
|
+
return e.innerHTML = n, A(e.content), e.innerHTML;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
const e = [], t =
|
|
35
|
-
for (const
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
e.push(
|
|
33
|
+
function A(n) {
|
|
34
|
+
const e = [], t = n.querySelectorAll("*");
|
|
35
|
+
for (const i of t) {
|
|
36
|
+
const r = i.tagName.toLowerCase();
|
|
37
|
+
if (v.has(r)) {
|
|
38
|
+
e.push(i);
|
|
39
39
|
continue;
|
|
40
40
|
}
|
|
41
|
-
if ((
|
|
42
|
-
(
|
|
41
|
+
if ((r === "svg" || i.namespaceURI === "http://www.w3.org/2000/svg") && Array.from(i.attributes).some(
|
|
42
|
+
(s) => h.test(s.name) || s.name === "href" || s.name === "xlink:href"
|
|
43
43
|
)) {
|
|
44
|
-
e.push(
|
|
44
|
+
e.push(i);
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
|
-
const
|
|
48
|
-
for (const
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
|
|
47
|
+
const l = [];
|
|
48
|
+
for (const o of i.attributes) {
|
|
49
|
+
const s = o.name.toLowerCase();
|
|
50
|
+
if (h.test(s)) {
|
|
51
|
+
l.push(o.name);
|
|
52
52
|
continue;
|
|
53
53
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
54
|
+
if (y.has(s) && C.test(o.value)) {
|
|
55
|
+
l.push(o.name);
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
|
-
if (
|
|
59
|
-
|
|
58
|
+
if (s === "style" && /expression\s*\(|javascript:|behavior\s*:/i.test(o.value)) {
|
|
59
|
+
l.push(o.name);
|
|
60
60
|
continue;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
l.forEach((o) => i.removeAttribute(o));
|
|
64
64
|
}
|
|
65
|
-
e.forEach((
|
|
65
|
+
e.forEach((i) => i.remove());
|
|
66
66
|
}
|
|
67
|
-
function
|
|
68
|
-
if (!
|
|
69
|
-
const t = [],
|
|
70
|
-
const d =
|
|
71
|
-
return t.push({ expr:
|
|
72
|
-
}),
|
|
73
|
-
return /Reflect\.|\bProxy\b|ownKeys\(/.test(
|
|
67
|
+
function D(n, e) {
|
|
68
|
+
if (!n || n.indexOf("{{") === -1) return n;
|
|
69
|
+
const t = [], i = n.replace(R, (s, a) => {
|
|
70
|
+
const d = S(a, e);
|
|
71
|
+
return t.push({ expr: a.trim(), result: d }), d;
|
|
72
|
+
}), r = L(i), l = t.length && t.every((s) => s.result === "" || s.result === u);
|
|
73
|
+
return /Reflect\.|\bProxy\b|ownKeys\(/.test(n) || l ? "" : r;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
if (
|
|
77
|
-
if (
|
|
78
|
-
if (
|
|
79
|
-
const
|
|
80
|
-
return
|
|
81
|
-
}
|
|
82
|
-
if (
|
|
83
|
-
const t =
|
|
84
|
-
if (t && t.length > 1) return
|
|
75
|
+
function S(n, e) {
|
|
76
|
+
if (n = (n || "").trim(), !n || /\b(Reflect|Proxy|ownKeys)\b/.test(n)) return u;
|
|
77
|
+
if (n === "value") return e.value == null ? u : String(e.value);
|
|
78
|
+
if (n.startsWith("row.") && !/[()?]/.test(n) && !n.includes(":")) {
|
|
79
|
+
const i = n.slice(4), r = e.row ? e.row[i] : void 0;
|
|
80
|
+
return r == null ? u : String(r);
|
|
81
|
+
}
|
|
82
|
+
if (n.length > 80 || !b.test(n) || E.test(n)) return u;
|
|
83
|
+
const t = n.match(/\./g);
|
|
84
|
+
if (t && t.length > 1) return u;
|
|
85
85
|
try {
|
|
86
|
-
const
|
|
87
|
-
return /Reflect|Proxy|ownKeys/.test(
|
|
86
|
+
const r = new Function("value", "row", `return (${n});`)(e.value, e.row), l = r == null ? "" : String(r);
|
|
87
|
+
return /Reflect|Proxy|ownKeys/.test(l) ? u : l || u;
|
|
88
88
|
} catch {
|
|
89
|
-
return
|
|
89
|
+
return u;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
function
|
|
93
|
-
return
|
|
92
|
+
function L(n) {
|
|
93
|
+
return n && n.replace(new RegExp(u, "g"), "").replace(/Reflect\.[^<>{}\s]+/g, "").replace(/\bProxy\b/g, "").replace(/ownKeys\([^)]*\)/g, "");
|
|
94
94
|
}
|
|
95
|
-
const
|
|
95
|
+
const I = {
|
|
96
96
|
expand: "▶",
|
|
97
97
|
collapse: "▼",
|
|
98
98
|
sortAsc: "▲",
|
|
@@ -102,7 +102,7 @@ const H = {
|
|
|
102
102
|
dragHandle: "⋮⋮",
|
|
103
103
|
toolPanel: "☰"
|
|
104
104
|
};
|
|
105
|
-
class
|
|
105
|
+
class T {
|
|
106
106
|
/**
|
|
107
107
|
* Plugin dependencies - declare other plugins this one requires.
|
|
108
108
|
*
|
|
@@ -119,8 +119,11 @@ class _ {
|
|
|
119
119
|
* ```
|
|
120
120
|
*/
|
|
121
121
|
static dependencies;
|
|
122
|
-
/**
|
|
123
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Plugin version - defaults to grid version for built-in plugins.
|
|
124
|
+
* Third-party plugins can override with their own semver.
|
|
125
|
+
*/
|
|
126
|
+
version = typeof __GRID_VERSION__ < "u" ? __GRID_VERSION__ : "dev";
|
|
124
127
|
/** CSS styles to inject into the grid's shadow DOM */
|
|
125
128
|
styles;
|
|
126
129
|
/** Custom cell renderers keyed by type name */
|
|
@@ -207,12 +210,28 @@ class _ {
|
|
|
207
210
|
emit(e, t) {
|
|
208
211
|
this.grid?.dispatchEvent?.(new CustomEvent(e, { detail: t, bubbles: !0 }));
|
|
209
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Emit a cancelable custom event from the grid.
|
|
215
|
+
* @returns `true` if the event was cancelled (preventDefault called), `false` otherwise
|
|
216
|
+
*/
|
|
217
|
+
emitCancelable(e, t) {
|
|
218
|
+
const i = new CustomEvent(e, { detail: t, bubbles: !0, cancelable: !0 });
|
|
219
|
+
return this.grid?.dispatchEvent?.(i), i.defaultPrevented;
|
|
220
|
+
}
|
|
210
221
|
/**
|
|
211
222
|
* Request a re-render of the grid.
|
|
212
223
|
*/
|
|
213
224
|
requestRender() {
|
|
214
225
|
this.grid?.requestRender?.();
|
|
215
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Request a re-render and restore focus styling afterward.
|
|
229
|
+
* Use this when a plugin action (like expand/collapse) triggers a render
|
|
230
|
+
* but needs to maintain keyboard navigation focus.
|
|
231
|
+
*/
|
|
232
|
+
requestRenderWithFocus() {
|
|
233
|
+
this.grid?.requestRenderWithFocus?.();
|
|
234
|
+
}
|
|
216
235
|
/**
|
|
217
236
|
* Request a lightweight style update without rebuilding DOM.
|
|
218
237
|
* Use this instead of requestRender() when only CSS classes need updating.
|
|
@@ -246,6 +265,19 @@ class _ {
|
|
|
246
265
|
get visibleColumns() {
|
|
247
266
|
return this.grid?._visibleColumns ?? [];
|
|
248
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Get the grid as an HTMLElement for direct DOM operations.
|
|
270
|
+
* Use sparingly - prefer the typed GridElementRef API when possible.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```ts
|
|
274
|
+
* const width = this.gridElement.clientWidth;
|
|
275
|
+
* this.gridElement.classList.add('my-plugin-active');
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
get gridElement() {
|
|
279
|
+
return this.grid;
|
|
280
|
+
}
|
|
249
281
|
/**
|
|
250
282
|
* Get the shadow root of the grid.
|
|
251
283
|
*/
|
|
@@ -278,8 +310,53 @@ class _ {
|
|
|
278
310
|
*/
|
|
279
311
|
get gridIcons() {
|
|
280
312
|
const e = this.grid?.gridConfig?.icons ?? {};
|
|
281
|
-
return { ...
|
|
313
|
+
return { ...I, ...e };
|
|
282
314
|
}
|
|
315
|
+
// #region Animation Helpers
|
|
316
|
+
/**
|
|
317
|
+
* Check if animations are enabled at the grid level.
|
|
318
|
+
* Respects gridConfig.animation.mode and the CSS variable set by the grid.
|
|
319
|
+
*
|
|
320
|
+
* Plugins should use this to skip animations when:
|
|
321
|
+
* - Animation mode is 'off' or `false`
|
|
322
|
+
* - User prefers reduced motion and mode is 'reduced-motion' (default)
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* private get animationStyle(): 'slide' | 'fade' | false {
|
|
327
|
+
* if (!this.isAnimationEnabled) return false;
|
|
328
|
+
* return this.config.animation ?? 'slide';
|
|
329
|
+
* }
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
get isAnimationEnabled() {
|
|
333
|
+
const e = this.grid?.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
334
|
+
if (e === !1 || e === "off") return !1;
|
|
335
|
+
if (e === !0 || e === "on") return !0;
|
|
336
|
+
const t = this.shadowRoot?.host;
|
|
337
|
+
return t ? getComputedStyle(t).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Get the animation duration in milliseconds from CSS variable.
|
|
341
|
+
* Falls back to 200ms if not set.
|
|
342
|
+
*
|
|
343
|
+
* Plugins can use this for their animation timing to stay consistent
|
|
344
|
+
* with the grid-level animation.duration setting.
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* element.animate(keyframes, { duration: this.animationDuration });
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
get animationDuration() {
|
|
352
|
+
const e = this.shadowRoot?.host;
|
|
353
|
+
if (e) {
|
|
354
|
+
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), i = parseInt(t, 10);
|
|
355
|
+
if (!isNaN(i)) return i;
|
|
356
|
+
}
|
|
357
|
+
return 200;
|
|
358
|
+
}
|
|
359
|
+
// #endregion
|
|
283
360
|
/**
|
|
284
361
|
* Resolve an icon value to string or HTMLElement.
|
|
285
362
|
* Checks plugin config first, then grid-level icons, then defaults.
|
|
@@ -309,33 +386,58 @@ class _ {
|
|
|
309
386
|
}
|
|
310
387
|
// #endregion
|
|
311
388
|
}
|
|
312
|
-
|
|
313
|
-
|
|
389
|
+
const p = "__tbw_expander", H = 32;
|
|
390
|
+
function m(n) {
|
|
391
|
+
return n.field === p;
|
|
392
|
+
}
|
|
393
|
+
function k(n) {
|
|
394
|
+
return n.find(m);
|
|
395
|
+
}
|
|
396
|
+
function O(n) {
|
|
397
|
+
return {
|
|
398
|
+
field: p,
|
|
399
|
+
header: "",
|
|
400
|
+
// No header text - visually merges with next column
|
|
401
|
+
width: H,
|
|
402
|
+
resizable: !1,
|
|
403
|
+
sortable: !1,
|
|
404
|
+
meta: {
|
|
405
|
+
lockPosition: !0,
|
|
406
|
+
suppressMovable: !0,
|
|
407
|
+
expanderColumn: !0,
|
|
408
|
+
expanderPlugin: n,
|
|
409
|
+
utility: !0
|
|
410
|
+
// Marks this as a utility column (excluded from selection, clipboard, etc.)
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function g(n, e) {
|
|
415
|
+
const t = new Set(n);
|
|
314
416
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
315
417
|
}
|
|
316
|
-
function
|
|
317
|
-
const t = new Set(
|
|
418
|
+
function N(n, e) {
|
|
419
|
+
const t = new Set(n);
|
|
318
420
|
return t.add(e), t;
|
|
319
421
|
}
|
|
320
|
-
function
|
|
321
|
-
const t = new Set(
|
|
422
|
+
function q(n, e) {
|
|
423
|
+
const t = new Set(n);
|
|
322
424
|
return t.delete(e), t;
|
|
323
425
|
}
|
|
324
|
-
function
|
|
325
|
-
return
|
|
426
|
+
function P(n, e) {
|
|
427
|
+
return n.has(e);
|
|
326
428
|
}
|
|
327
|
-
function
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
return typeof
|
|
429
|
+
function M(n, e, t, i) {
|
|
430
|
+
const r = document.createElement("div");
|
|
431
|
+
r.className = "master-detail-row", r.setAttribute("data-detail-for", String(e)), r.setAttribute("role", "row");
|
|
432
|
+
const l = document.createElement("div");
|
|
433
|
+
l.className = "master-detail-cell", l.setAttribute("role", "cell"), l.style.gridColumn = `1 / ${i + 1}`;
|
|
434
|
+
const o = t(n, e);
|
|
435
|
+
return typeof o == "string" ? l.innerHTML = o : o instanceof HTMLElement && l.appendChild(o), r.appendChild(l), r;
|
|
334
436
|
}
|
|
335
|
-
const
|
|
336
|
-
class
|
|
437
|
+
const F = ".cell[data-field=__tbw_expander]{border-right:none!important;padding:0;display:flex;align-items:center;justify-content:center}.header-row .cell[data-field=__tbw_expander]{visibility:hidden;border:none!important;padding:0;overflow:hidden}.header-row .cell[data-field=__tbw_expander]+.cell{margin-left:-32px;padding-left:calc(var(--tbw-cell-padding, 8px) + 32px)}.master-detail-expander{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.master-detail-toggle{cursor:pointer;opacity:.7;-webkit-user-select:none;user-select:none;display:inline-flex;align-items:center;justify-content:center}.master-detail-toggle:hover{opacity:1}.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}.master-detail-cell{padding:16px;overflow:auto}.master-detail-row.tbw-expanding{animation:tbw-detail-expand var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}.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:500px;padding-top:16px;padding-bottom:16px}}@keyframes tbw-detail-collapse{0%{opacity:1;max-height:500px}to{opacity:0;max-height:0}}";
|
|
438
|
+
class w extends T {
|
|
337
439
|
name = "masterDetail";
|
|
338
|
-
|
|
440
|
+
styles = F;
|
|
339
441
|
get defaultConfig() {
|
|
340
442
|
return {
|
|
341
443
|
detailHeight: "auto",
|
|
@@ -381,52 +483,31 @@ class q extends _ {
|
|
|
381
483
|
if (!e || typeof e.querySelector != "function") return;
|
|
382
484
|
const t = e.querySelector("tbw-grid-detail");
|
|
383
485
|
if (!t) return;
|
|
384
|
-
const
|
|
385
|
-
if (
|
|
386
|
-
const
|
|
387
|
-
if (
|
|
388
|
-
this.config = { ...this.config, detailRenderer:
|
|
486
|
+
const i = e;
|
|
487
|
+
if (i.__frameworkAdapter?.parseDetailElement) {
|
|
488
|
+
const f = i.__frameworkAdapter.parseDetailElement(t);
|
|
489
|
+
if (f) {
|
|
490
|
+
this.config = { ...this.config, detailRenderer: f };
|
|
389
491
|
return;
|
|
390
492
|
}
|
|
391
493
|
}
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
return
|
|
494
|
+
const r = t.getAttribute("animation"), l = t.getAttribute("show-expand-column"), o = t.getAttribute("expand-on-row-click"), s = t.getAttribute("collapse-on-click-outside"), a = t.getAttribute("height"), d = {};
|
|
495
|
+
r !== null && (d.animation = r === "false" ? !1 : r), l !== null && (d.showExpandColumn = l !== "false"), o !== null && (d.expandOnRowClick = o === "true"), s !== null && (d.collapseOnClickOutside = s === "true"), a !== null && (d.detailHeight = a === "auto" ? "auto" : parseInt(a, 10));
|
|
496
|
+
const c = t.innerHTML.trim();
|
|
497
|
+
c && !this.config.detailRenderer && (d.detailRenderer = (f, G) => {
|
|
498
|
+
const x = D(c, { value: f, row: f });
|
|
499
|
+
return _(x);
|
|
398
500
|
}), Object.keys(d).length > 0 && (this.config = { ...this.config, ...d });
|
|
399
501
|
}
|
|
400
502
|
// #endregion
|
|
401
503
|
// #region Animation Helpers
|
|
402
|
-
/**
|
|
403
|
-
* Check if animations are enabled at the grid level.
|
|
404
|
-
* Respects gridConfig.animation.mode and CSS variable.
|
|
405
|
-
*/
|
|
406
|
-
get isAnimationEnabled() {
|
|
407
|
-
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
408
|
-
if (t === !1 || t === "off") return !1;
|
|
409
|
-
if (t === !0 || t === "on") return !0;
|
|
410
|
-
const n = this.shadowRoot?.host;
|
|
411
|
-
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
412
|
-
}
|
|
413
504
|
/**
|
|
414
505
|
* Get expand/collapse animation style from plugin config.
|
|
506
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
415
507
|
*/
|
|
416
508
|
get animationStyle() {
|
|
417
509
|
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
418
510
|
}
|
|
419
|
-
/**
|
|
420
|
-
* Get animation duration from CSS variable (set by grid).
|
|
421
|
-
*/
|
|
422
|
-
get animationDuration() {
|
|
423
|
-
const e = this.shadowRoot?.host;
|
|
424
|
-
if (e) {
|
|
425
|
-
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
426
|
-
if (!isNaN(n)) return n;
|
|
427
|
-
}
|
|
428
|
-
return 200;
|
|
429
|
-
}
|
|
430
511
|
/**
|
|
431
512
|
* Apply expand animation to a detail element.
|
|
432
513
|
*/
|
|
@@ -448,15 +529,34 @@ class q extends _ {
|
|
|
448
529
|
return;
|
|
449
530
|
}
|
|
450
531
|
e.classList.add("tbw-collapsing");
|
|
451
|
-
const
|
|
532
|
+
const i = () => {
|
|
452
533
|
e.classList.remove("tbw-collapsing"), t();
|
|
453
534
|
};
|
|
454
|
-
e.addEventListener("animationend",
|
|
535
|
+
e.addEventListener("animationend", i, { once: !0 }), setTimeout(i, this.animationDuration + 50);
|
|
455
536
|
}
|
|
456
537
|
// #endregion
|
|
457
538
|
// #region Internal State
|
|
458
539
|
expandedRows = /* @__PURE__ */ new Set();
|
|
459
540
|
detailElements = /* @__PURE__ */ new Map();
|
|
541
|
+
/** Default height for detail rows when not configured */
|
|
542
|
+
static DEFAULT_DETAIL_HEIGHT = 150;
|
|
543
|
+
/**
|
|
544
|
+
* Get the estimated height for a detail row.
|
|
545
|
+
*/
|
|
546
|
+
getDetailHeight(e) {
|
|
547
|
+
const t = this.detailElements.get(e);
|
|
548
|
+
return t ? t.offsetHeight : typeof this.config?.detailHeight == "number" ? this.config.detailHeight : w.DEFAULT_DETAIL_HEIGHT;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Toggle a row's detail and emit event.
|
|
552
|
+
*/
|
|
553
|
+
toggleAndEmit(e, t) {
|
|
554
|
+
this.expandedRows = g(this.expandedRows, e), this.emit("detail-expand", {
|
|
555
|
+
rowIndex: t,
|
|
556
|
+
row: e,
|
|
557
|
+
expanded: this.expandedRows.has(e)
|
|
558
|
+
}), this.requestRender();
|
|
559
|
+
}
|
|
460
560
|
// #endregion
|
|
461
561
|
// #region Lifecycle
|
|
462
562
|
detach() {
|
|
@@ -465,49 +565,36 @@ class q extends _ {
|
|
|
465
565
|
// #endregion
|
|
466
566
|
// #region Hooks
|
|
467
567
|
processColumns(e) {
|
|
468
|
-
if (!this.config.detailRenderer)
|
|
568
|
+
if (!this.config.detailRenderer || this.config.showExpandColumn === !1)
|
|
469
569
|
return [...e];
|
|
470
570
|
const t = [...e];
|
|
471
|
-
if (t
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
const h = document.createElement("span");
|
|
481
|
-
if (s) {
|
|
482
|
-
const g = s(r);
|
|
483
|
-
g instanceof Node ? h.appendChild(g) : h.textContent = String(g ?? o ?? "");
|
|
484
|
-
} else
|
|
485
|
-
h.textContent = String(o ?? "");
|
|
486
|
-
return u.appendChild(h), u;
|
|
487
|
-
};
|
|
488
|
-
a.__masterDetailWrapped = !0, n.viewRenderer = a, t[0] = n;
|
|
489
|
-
}
|
|
490
|
-
return t;
|
|
571
|
+
if (k(t))
|
|
572
|
+
return t;
|
|
573
|
+
const r = O(this.name);
|
|
574
|
+
return r.viewRenderer = (l) => {
|
|
575
|
+
const { row: o } = l, s = this.expandedRows.has(o), a = document.createElement("span");
|
|
576
|
+
a.className = "master-detail-expander expander-cell";
|
|
577
|
+
const d = document.createElement("span");
|
|
578
|
+
return d.className = `master-detail-toggle${s ? " expanded" : ""}`, this.setIcon(d, this.resolveIcon(s ? "collapse" : "expand")), d.setAttribute("role", "button"), d.setAttribute("tabindex", "0"), d.setAttribute("aria-expanded", String(s)), d.setAttribute("aria-label", s ? "Collapse details" : "Expand details"), a.appendChild(d), a;
|
|
579
|
+
}, [r, ...t];
|
|
491
580
|
}
|
|
492
581
|
onRowClick(e) {
|
|
493
582
|
if (!(!this.config.expandOnRowClick || !this.config.detailRenderer))
|
|
494
|
-
return this.
|
|
495
|
-
rowIndex: e.rowIndex,
|
|
496
|
-
row: e.row,
|
|
497
|
-
expanded: this.expandedRows.has(e.row)
|
|
498
|
-
}), this.requestRender(), !1;
|
|
583
|
+
return this.toggleAndEmit(e.row, e.rowIndex), !1;
|
|
499
584
|
}
|
|
500
585
|
onCellClick(e) {
|
|
501
|
-
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
502
|
-
|
|
503
|
-
return this.expandedRows = p(this.expandedRows, n), this.emit("detail-expand", {
|
|
504
|
-
rowIndex: s,
|
|
505
|
-
row: n,
|
|
506
|
-
expanded: this.expandedRows.has(n)
|
|
507
|
-
}), this.requestRender(), !0;
|
|
508
|
-
}
|
|
586
|
+
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
587
|
+
return this.toggleAndEmit(e.row, e.rowIndex), !0;
|
|
509
588
|
this.expandedRows.size > 0 && queueMicrotask(() => this.#e());
|
|
510
589
|
}
|
|
590
|
+
onKeyDown(e) {
|
|
591
|
+
if (e.key !== " ") return;
|
|
592
|
+
const t = this.grid._focusCol, i = this.grid._focusRow, r = this.columns[t];
|
|
593
|
+
if (!r || !m(r)) return;
|
|
594
|
+
const l = this.rows[i];
|
|
595
|
+
if (l)
|
|
596
|
+
return e.preventDefault(), this.toggleAndEmit(l, i), this.requestRenderWithFocus(), !0;
|
|
597
|
+
}
|
|
511
598
|
afterRender() {
|
|
512
599
|
this.#e();
|
|
513
600
|
}
|
|
@@ -526,26 +613,26 @@ class q extends _ {
|
|
|
526
613
|
if (!this.config.detailRenderer) return;
|
|
527
614
|
const e = this.shadowRoot?.querySelector(".rows");
|
|
528
615
|
if (!e) return;
|
|
529
|
-
const t = /* @__PURE__ */ new Map(),
|
|
530
|
-
for (const
|
|
531
|
-
const
|
|
532
|
-
|
|
616
|
+
const t = /* @__PURE__ */ new Map(), i = e.querySelectorAll(".data-grid-row"), r = this.columns.length;
|
|
617
|
+
for (const o of i) {
|
|
618
|
+
const s = o.querySelector(".cell[data-row]"), a = s ? parseInt(s.getAttribute("data-row") ?? "-1", 10) : -1;
|
|
619
|
+
a >= 0 && t.set(a, o);
|
|
533
620
|
}
|
|
534
|
-
const
|
|
535
|
-
for (const
|
|
536
|
-
const
|
|
537
|
-
(!d || !
|
|
621
|
+
const l = e.querySelectorAll(".master-detail-row");
|
|
622
|
+
for (const o of l) {
|
|
623
|
+
const s = parseInt(o.getAttribute("data-detail-for") ?? "-1", 10), a = s >= 0 ? this.rows[s] : void 0, d = a && this.expandedRows.has(a), c = t.has(s);
|
|
624
|
+
(!d || !c) && (o.remove(), a && this.detailElements.delete(a));
|
|
538
625
|
}
|
|
539
|
-
for (const [
|
|
540
|
-
const
|
|
541
|
-
if (!
|
|
542
|
-
const d = this.detailElements.get(
|
|
626
|
+
for (const [o, s] of t) {
|
|
627
|
+
const a = this.rows[o];
|
|
628
|
+
if (!a || !this.expandedRows.has(a)) continue;
|
|
629
|
+
const d = this.detailElements.get(a);
|
|
543
630
|
if (d) {
|
|
544
|
-
d.previousElementSibling !==
|
|
631
|
+
d.previousElementSibling !== s && s.after(d);
|
|
545
632
|
continue;
|
|
546
633
|
}
|
|
547
|
-
const
|
|
548
|
-
typeof this.config.detailHeight == "number" && (
|
|
634
|
+
const c = M(a, o, this.config.detailRenderer, r);
|
|
635
|
+
typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), s.after(c), this.detailElements.set(a, c), this.animateExpand(c);
|
|
549
636
|
}
|
|
550
637
|
}
|
|
551
638
|
/**
|
|
@@ -554,15 +641,8 @@ class q extends _ {
|
|
|
554
641
|
*/
|
|
555
642
|
getExtraHeight() {
|
|
556
643
|
let e = 0;
|
|
557
|
-
for (const t of this.expandedRows)
|
|
558
|
-
|
|
559
|
-
if (n)
|
|
560
|
-
e += n.offsetHeight;
|
|
561
|
-
else {
|
|
562
|
-
const s = this.config?.detailHeight;
|
|
563
|
-
e += typeof s == "number" ? s : 150;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
644
|
+
for (const t of this.expandedRows)
|
|
645
|
+
e += this.getDetailHeight(t);
|
|
566
646
|
return e;
|
|
567
647
|
}
|
|
568
648
|
/**
|
|
@@ -571,17 +651,9 @@ class q extends _ {
|
|
|
571
651
|
*/
|
|
572
652
|
getExtraHeightBefore(e) {
|
|
573
653
|
let t = 0;
|
|
574
|
-
for (const
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
const a = this.detailElements.get(n);
|
|
578
|
-
if (a)
|
|
579
|
-
t += a.offsetHeight;
|
|
580
|
-
else {
|
|
581
|
-
const r = this.config?.detailHeight;
|
|
582
|
-
t += typeof r == "number" ? r : 150;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
654
|
+
for (const i of this.expandedRows) {
|
|
655
|
+
const r = this.rows.indexOf(i);
|
|
656
|
+
r >= 0 && r < e && (t += this.getDetailHeight(i));
|
|
585
657
|
}
|
|
586
658
|
return t;
|
|
587
659
|
}
|
|
@@ -589,20 +661,20 @@ class q extends _ {
|
|
|
589
661
|
* Adjust the virtualization start index to keep expanded row visible while its detail is visible.
|
|
590
662
|
* This ensures the detail scrolls smoothly out of view instead of disappearing abruptly.
|
|
591
663
|
*/
|
|
592
|
-
adjustVirtualStart(e, t,
|
|
664
|
+
adjustVirtualStart(e, t, i) {
|
|
593
665
|
if (this.expandedRows.size === 0) return e;
|
|
594
|
-
const
|
|
595
|
-
for (const
|
|
596
|
-
const
|
|
597
|
-
|
|
666
|
+
const r = [];
|
|
667
|
+
for (const s of this.expandedRows) {
|
|
668
|
+
const a = this.rows.indexOf(s);
|
|
669
|
+
a >= 0 && r.push({ index: a, row: s });
|
|
598
670
|
}
|
|
599
|
-
|
|
600
|
-
let
|
|
601
|
-
for (const { index:
|
|
602
|
-
const d =
|
|
603
|
-
|
|
671
|
+
r.sort((s, a) => s.index - a.index);
|
|
672
|
+
let l = e, o = 0;
|
|
673
|
+
for (const { index: s, row: a } of r) {
|
|
674
|
+
const d = s * i + o, c = this.getDetailHeight(a), f = d + i + c;
|
|
675
|
+
o += c, !(s >= e) && f > t && s < l && (l = s);
|
|
604
676
|
}
|
|
605
|
-
return
|
|
677
|
+
return l;
|
|
606
678
|
}
|
|
607
679
|
// #endregion
|
|
608
680
|
// #region Public API
|
|
@@ -612,7 +684,7 @@ class q extends _ {
|
|
|
612
684
|
*/
|
|
613
685
|
expand(e) {
|
|
614
686
|
const t = this.rows[e];
|
|
615
|
-
t && (this.expandedRows =
|
|
687
|
+
t && (this.expandedRows = N(this.expandedRows, t), this.requestRender());
|
|
616
688
|
}
|
|
617
689
|
/**
|
|
618
690
|
* Collapse the detail row at the given index.
|
|
@@ -620,7 +692,7 @@ class q extends _ {
|
|
|
620
692
|
*/
|
|
621
693
|
collapse(e) {
|
|
622
694
|
const t = this.rows[e];
|
|
623
|
-
t && (this.expandedRows =
|
|
695
|
+
t && (this.expandedRows = q(this.expandedRows, t), this.requestRender());
|
|
624
696
|
}
|
|
625
697
|
/**
|
|
626
698
|
* Toggle the detail row at the given index.
|
|
@@ -628,7 +700,7 @@ class q extends _ {
|
|
|
628
700
|
*/
|
|
629
701
|
toggle(e) {
|
|
630
702
|
const t = this.rows[e];
|
|
631
|
-
t && (this.expandedRows =
|
|
703
|
+
t && (this.expandedRows = g(this.expandedRows, t), this.requestRender());
|
|
632
704
|
}
|
|
633
705
|
/**
|
|
634
706
|
* Check if the detail row at the given index is expanded.
|
|
@@ -637,7 +709,7 @@ class q extends _ {
|
|
|
637
709
|
*/
|
|
638
710
|
isExpanded(e) {
|
|
639
711
|
const t = this.rows[e];
|
|
640
|
-
return t ?
|
|
712
|
+
return t ? P(this.expandedRows, t) : !1;
|
|
641
713
|
}
|
|
642
714
|
/**
|
|
643
715
|
* Expand all detail rows.
|
|
@@ -660,8 +732,8 @@ class q extends _ {
|
|
|
660
732
|
getExpandedRows() {
|
|
661
733
|
const e = [];
|
|
662
734
|
for (const t of this.expandedRows) {
|
|
663
|
-
const
|
|
664
|
-
|
|
735
|
+
const i = this.rows.indexOf(t);
|
|
736
|
+
i >= 0 && e.push(i);
|
|
665
737
|
}
|
|
666
738
|
return e;
|
|
667
739
|
}
|
|
@@ -689,11 +761,8 @@ class q extends _ {
|
|
|
689
761
|
}
|
|
690
762
|
}
|
|
691
763
|
// #endregion
|
|
692
|
-
// #region Styles
|
|
693
|
-
styles = O;
|
|
694
|
-
// #endregion
|
|
695
764
|
}
|
|
696
765
|
export {
|
|
697
|
-
|
|
766
|
+
w as MasterDetailPlugin
|
|
698
767
|
};
|
|
699
768
|
//# sourceMappingURL=index.js.map
|