@toolbox-web/grid 0.4.0 → 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 +1124 -1047
- package/all.js.map +1 -1
- package/index.js +688 -515
- 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/internal/validate-config.d.ts +14 -0
- package/lib/core/internal/validate-config.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +105 -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/index.d.ts +1 -0
- package/lib/core/plugin/index.d.ts.map +1 -1
- package/lib/core/plugin/plugin-manager.d.ts +1 -1
- package/lib/core/plugin/plugin-manager.d.ts.map +1 -1
- 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 +9 -2
- 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 +303 -185
- 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 +116 -24
- 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 +164 -72
- 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 +213 -133
- 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 +195 -103
- 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 +145 -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 +162 -68
- 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 +246 -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 +281 -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 +121 -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 +144 -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 +178 -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 +414 -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 +304 -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 +292 -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 +95 -3
- 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 +213 -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 +7 -2
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +112 -12
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +14 -5
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
- package/lib/plugins/visibility/index.js +168 -65
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +21 -17
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +14 -8
- 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/all.js
CHANGED
|
@@ -1,35 +1,32 @@
|
|
|
1
|
-
import { BaseGridPlugin as x, DEFAULT_GRID_ICONS as
|
|
2
|
-
import { DEFAULT_ANIMATION_CONFIG as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (s == null) return "";
|
|
7
|
-
if (s instanceof Date) return s.toISOString();
|
|
8
|
-
if (typeof s == "object") return JSON.stringify(s);
|
|
9
|
-
const i = String(s), o = n.delimiter ?? " ", r = n.newline ?? `
|
|
10
|
-
`;
|
|
11
|
-
return n.quoteStrings || i.includes(o) || i.includes(r) || i.includes('"') ? `"${i.replace(/"/g, '""')}"` : i;
|
|
1
|
+
import { BaseGridPlugin as x, DEFAULT_GRID_ICONS as $e, runAggregator as de, e as je, s as Ue, PLUGIN_QUERIES as He, getAggregator as ce, getValueAggregator as Xe, a as Ze, c as V, g as Ye } from "./index.js";
|
|
2
|
+
import { DEFAULT_ANIMATION_CONFIG as oi, DGEvents as ri, DataGridElement as si, FitModeEnum as li, GridCSSVars as ai, GridClasses as di, GridDataAttrs as ci, DataGridElement as ui, GridSelectors as hi, PluginEvents as fi, PluginManager as gi, RenderPhase as pi, builtInSort as mi, defaultComparator as wi } from "./index.js";
|
|
3
|
+
const Oe = "__tbw_expander", Je = 32;
|
|
4
|
+
function ie(s) {
|
|
5
|
+
return s.field === Oe;
|
|
12
6
|
}
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
function _(s) {
|
|
8
|
+
return s.meta?.utility === !0;
|
|
9
|
+
}
|
|
10
|
+
function Qe(s) {
|
|
11
|
+
return s.find(ie);
|
|
12
|
+
}
|
|
13
|
+
function et(s) {
|
|
14
|
+
return {
|
|
15
|
+
field: Oe,
|
|
16
|
+
header: "",
|
|
17
|
+
// No header text - visually merges with next column
|
|
18
|
+
width: Je,
|
|
19
|
+
resizable: !1,
|
|
20
|
+
sortable: !1,
|
|
21
|
+
meta: {
|
|
22
|
+
lockPosition: !0,
|
|
23
|
+
suppressMovable: !0,
|
|
24
|
+
expanderColumn: !0,
|
|
25
|
+
expanderPlugin: s,
|
|
26
|
+
utility: !0
|
|
27
|
+
// Marks this as a utility column (excluded from selection, clipboard, etc.)
|
|
28
|
+
}
|
|
29
|
+
};
|
|
33
30
|
}
|
|
34
31
|
async function z(s) {
|
|
35
32
|
try {
|
|
@@ -41,7 +38,7 @@ async function z(s) {
|
|
|
41
38
|
return document.body.removeChild(e), t;
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
|
-
function
|
|
41
|
+
function ue(s, e) {
|
|
45
42
|
const t = e.delimiter ?? " ", n = e.newline ?? `
|
|
46
43
|
`, i = s.replace(/\r\n/g, `
|
|
47
44
|
`).replace(/\r/g, `
|
|
@@ -49,20 +46,49 @@ function he(s, e) {
|
|
|
49
46
|
let r = [], l = "", a = !1;
|
|
50
47
|
for (let d = 0; d < i.length; d++) {
|
|
51
48
|
const c = i[d];
|
|
52
|
-
c === '"' && !a ? a = !0 : c === '"' && a ? i[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (r.push(l), l = "") : c === n && !a ? (r.push(l), l = "", (r.length > 1 || r.some((
|
|
49
|
+
c === '"' && !a ? a = !0 : c === '"' && a ? i[d + 1] === '"' ? (l += '"', d++) : a = !1 : c === t && !a ? (r.push(l), l = "") : c === n && !a ? (r.push(l), l = "", (r.length > 1 || r.some((u) => u.trim() !== "")) && o.push(r), r = []) : l += c;
|
|
53
50
|
}
|
|
54
51
|
return r.push(l), (r.length > 1 || r.some((d) => d.trim() !== "")) && o.push(r), o;
|
|
55
52
|
}
|
|
56
|
-
async function
|
|
53
|
+
async function tt() {
|
|
57
54
|
try {
|
|
58
55
|
return await navigator.clipboard.readText();
|
|
59
56
|
} catch {
|
|
60
57
|
return "";
|
|
61
58
|
}
|
|
62
59
|
}
|
|
63
|
-
|
|
60
|
+
function nt(s, e) {
|
|
61
|
+
const { rows: t, target: n, fields: i } = s;
|
|
62
|
+
if (!n) return;
|
|
63
|
+
const o = e.rows, l = (e.effectiveConfig.columns ?? []).map((c) => c.field), a = [...o], d = n.bounds ? n.bounds.endRow : 1 / 0;
|
|
64
|
+
t.forEach((c, u) => {
|
|
65
|
+
const h = n.row + u;
|
|
66
|
+
if (!(h > d)) {
|
|
67
|
+
if (n.bounds) {
|
|
68
|
+
if (h >= a.length)
|
|
69
|
+
return;
|
|
70
|
+
} else for (; h >= a.length; ) {
|
|
71
|
+
const f = {};
|
|
72
|
+
l.forEach((g) => f[g] = ""), a.push(f);
|
|
73
|
+
}
|
|
74
|
+
a[h] = { ...a[h] }, c.forEach((f, g) => {
|
|
75
|
+
const p = i[g];
|
|
76
|
+
p && (a[h][p] = f);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}), e.rows = a;
|
|
80
|
+
}
|
|
81
|
+
class qn extends x {
|
|
82
|
+
/**
|
|
83
|
+
* Plugin dependencies - ClipboardPlugin works best with SelectionPlugin.
|
|
84
|
+
*
|
|
85
|
+
* Without SelectionPlugin: copies entire grid, pastes at row 0 col 0.
|
|
86
|
+
* With SelectionPlugin: copies/pastes based on selection.
|
|
87
|
+
*/
|
|
88
|
+
static dependencies = [
|
|
89
|
+
{ name: "selection", required: !1, reason: "Enables copy/paste of selected cells instead of entire grid" }
|
|
90
|
+
];
|
|
64
91
|
name = "clipboard";
|
|
65
|
-
version = "1.0.0";
|
|
66
92
|
get defaultConfig() {
|
|
67
93
|
return {
|
|
68
94
|
includeHeaders: !1,
|
|
@@ -77,65 +103,107 @@ class Tn extends x {
|
|
|
77
103
|
lastCopied = null;
|
|
78
104
|
// #endregion
|
|
79
105
|
// #region Lifecycle
|
|
106
|
+
attach(e) {
|
|
107
|
+
super.attach(e), e.addEventListener(
|
|
108
|
+
"paste",
|
|
109
|
+
(t) => this.#t(t),
|
|
110
|
+
{ signal: this.disconnectSignal }
|
|
111
|
+
);
|
|
112
|
+
}
|
|
80
113
|
detach() {
|
|
81
114
|
this.lastCopied = null;
|
|
82
115
|
}
|
|
83
116
|
// #endregion
|
|
84
117
|
// #region Event Handlers
|
|
85
118
|
onKeyDown(e) {
|
|
86
|
-
|
|
87
|
-
return t ? (this.#e(e.target), !0) : n ? (this.#t(), !0) : !1;
|
|
119
|
+
return (e.ctrlKey || e.metaKey) && e.key === "c" ? (this.#e(e.target), !0) : !1;
|
|
88
120
|
}
|
|
89
121
|
// #endregion
|
|
90
122
|
// #region Private Methods
|
|
91
123
|
/**
|
|
92
|
-
* Handle copy operation
|
|
124
|
+
* Handle copy operation.
|
|
125
|
+
*
|
|
126
|
+
* Everything is treated as a range:
|
|
127
|
+
* - With selection: copies the selected range
|
|
128
|
+
* - Row mode: range spanning all columns for selected rows
|
|
129
|
+
* - No selection plugin: entire grid as a range
|
|
130
|
+
* - No selection: try to get focused cell from DOM as 1x1 range
|
|
93
131
|
*/
|
|
94
132
|
#e(e) {
|
|
95
|
-
const t = this.#
|
|
96
|
-
let
|
|
97
|
-
if (
|
|
98
|
-
a =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
if (!
|
|
115
|
-
|
|
116
|
-
} else {
|
|
117
|
-
const h = this.#s(e);
|
|
118
|
-
if (!h) return;
|
|
119
|
-
a = h.text, d = 1, c = 1;
|
|
133
|
+
const t = this.#n(), n = t?.getSelection(), i = this.columns.length - 1, o = this.rows.length - 1;
|
|
134
|
+
let r;
|
|
135
|
+
if (n && n.ranges.length > 0) {
|
|
136
|
+
const { mode: a, ranges: d } = n, c = d[d.length - 1];
|
|
137
|
+
a === "row" ? r = {
|
|
138
|
+
startRow: c.from.row,
|
|
139
|
+
startCol: 0,
|
|
140
|
+
endRow: c.to.row,
|
|
141
|
+
endCol: i
|
|
142
|
+
} : r = {
|
|
143
|
+
startRow: c.from.row,
|
|
144
|
+
startCol: c.from.col,
|
|
145
|
+
endRow: c.to.row,
|
|
146
|
+
endCol: c.to.col
|
|
147
|
+
};
|
|
148
|
+
} else if (!t)
|
|
149
|
+
r = { startRow: 0, startCol: 0, endRow: o, endCol: i };
|
|
150
|
+
else {
|
|
151
|
+
const a = this.#s(e);
|
|
152
|
+
if (!a) return;
|
|
153
|
+
r = { startRow: a.row, startCol: a.col, endRow: a.row, endCol: a.col };
|
|
120
154
|
}
|
|
121
|
-
|
|
122
|
-
|
|
155
|
+
const l = this.#i(r);
|
|
156
|
+
z(l.text).then(() => {
|
|
157
|
+
this.lastCopied = { text: l.text, timestamp: Date.now() }, this.emit("copy", {
|
|
158
|
+
text: l.text,
|
|
159
|
+
rowCount: l.rowCount,
|
|
160
|
+
columnCount: l.columnCount
|
|
161
|
+
});
|
|
123
162
|
});
|
|
124
163
|
}
|
|
125
164
|
/**
|
|
126
|
-
* Handle paste
|
|
165
|
+
* Handle native paste event (preferred method - works in iframes).
|
|
166
|
+
* Uses synchronous clipboardData from the native paste event.
|
|
167
|
+
*
|
|
168
|
+
* Flow:
|
|
169
|
+
* 1. Parse clipboard text
|
|
170
|
+
* 2. Build target/fields info from selection
|
|
171
|
+
* 3. Emit 'paste' event (for listeners)
|
|
172
|
+
* 4. Call paste handler (if configured) to apply data to grid
|
|
173
|
+
*
|
|
174
|
+
* Selection behavior:
|
|
175
|
+
* - Single cell: paste starts at cell, expands freely
|
|
176
|
+
* - Range/row: paste is clipped to fit within selection bounds
|
|
177
|
+
* - No selection: paste starts at row 0, col 0
|
|
127
178
|
*/
|
|
128
|
-
#t() {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
179
|
+
#t(e) {
|
|
180
|
+
const t = e.clipboardData?.getData("text/plain");
|
|
181
|
+
if (!t) return;
|
|
182
|
+
e.preventDefault();
|
|
183
|
+
const n = ue(t, this.config), o = this.#n()?.getSelection(), r = o?.ranges?.[0], l = r?.from.row ?? 0, a = r?.from.col ?? 0, c = r && (o?.mode === "range" || o?.mode === "row") && (r.from.row !== r.to.row || r.from.col !== r.to.col) ? { endRow: r.to.row, endCol: r.to.col } : null, u = c?.endCol ?? this.columns.length - 1, h = this.columns[a], f = h ? { row: l, col: a, field: h.field, bounds: c } : null, g = [], p = n[0]?.length ?? 0;
|
|
184
|
+
for (let m = 0; m < p && a + m <= u; m++) {
|
|
185
|
+
const w = this.columns[a + m];
|
|
186
|
+
w && !w.hidden && g.push(w.field);
|
|
187
|
+
}
|
|
188
|
+
const b = { rows: n, text: t, target: f, fields: g };
|
|
189
|
+
this.emit("paste", b), this.#r(b);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Apply the paste handler to update grid data.
|
|
193
|
+
*
|
|
194
|
+
* Uses the configured `pasteHandler`, or the default handler if not specified.
|
|
195
|
+
* Set `pasteHandler: null` in config to disable auto-paste.
|
|
196
|
+
*/
|
|
197
|
+
#r(e) {
|
|
198
|
+
if (!this.grid) return;
|
|
199
|
+
const { pasteHandler: t } = this.config;
|
|
200
|
+
if (t === null) return;
|
|
201
|
+
(t ?? nt)(e, this.grid);
|
|
134
202
|
}
|
|
135
203
|
/**
|
|
136
204
|
* Get the selection plugin instance if available.
|
|
137
205
|
*/
|
|
138
|
-
#
|
|
206
|
+
#n() {
|
|
139
207
|
try {
|
|
140
208
|
const e = this.grid?.getPluginByName("selection");
|
|
141
209
|
if (e)
|
|
@@ -143,71 +211,45 @@ class Tn extends x {
|
|
|
143
211
|
} catch {
|
|
144
212
|
}
|
|
145
213
|
}
|
|
146
|
-
/**
|
|
147
|
-
* Build text for a single cell by row/col index.
|
|
148
|
-
*/
|
|
149
|
-
#n(e, t) {
|
|
150
|
-
const n = this.rows[e];
|
|
151
|
-
if (!n) return null;
|
|
152
|
-
const i = this.columns[t];
|
|
153
|
-
if (!i) return null;
|
|
154
|
-
const o = n[i.field], r = i.header || i.field;
|
|
155
|
-
let l;
|
|
156
|
-
if (this.config.includeHeaders) {
|
|
157
|
-
const a = o == null ? "" : String(o);
|
|
158
|
-
l = `${r}: ${a}`;
|
|
159
|
-
} else
|
|
160
|
-
l = o == null ? "" : String(o);
|
|
161
|
-
return { text: l };
|
|
162
|
-
}
|
|
163
214
|
/**
|
|
164
215
|
* Build text for a rectangular range of cells.
|
|
216
|
+
* Utility columns (like expander columns) are automatically excluded.
|
|
165
217
|
*/
|
|
166
218
|
#i(e) {
|
|
167
|
-
const { startRow: t, startCol: n, endRow: i, endCol: o } = e, r = Math.min(t, i), l = Math.max(t, i), a = Math.min(n, o), d = Math.max(n, o), c = this.config.delimiter ?? " ",
|
|
168
|
-
`,
|
|
219
|
+
const { startRow: t, startCol: n, endRow: i, endCol: o } = e, r = Math.min(t, i), l = Math.max(t, i), a = Math.min(n, o), d = Math.max(n, o), c = this.config.delimiter ?? " ", u = this.config.newline ?? `
|
|
220
|
+
`, h = [], f = this.columns.slice(a, d + 1).filter((g) => !_(g));
|
|
169
221
|
if (this.config.includeHeaders) {
|
|
170
222
|
const g = f.map((p) => p.header || p.field);
|
|
171
|
-
|
|
223
|
+
h.push(g.join(c));
|
|
172
224
|
}
|
|
173
225
|
for (let g = r; g <= l; g++) {
|
|
174
226
|
const p = this.rows[g];
|
|
175
227
|
if (!p) continue;
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
return
|
|
228
|
+
const b = f.map((m) => {
|
|
229
|
+
const w = p[m.field];
|
|
230
|
+
return w == null ? "" : w instanceof Date ? w.toISOString() : String(w);
|
|
179
231
|
});
|
|
180
|
-
|
|
232
|
+
h.push(b.join(c));
|
|
181
233
|
}
|
|
182
234
|
return {
|
|
183
|
-
text:
|
|
235
|
+
text: h.join(u),
|
|
184
236
|
rowCount: l - r + 1,
|
|
185
237
|
columnCount: d - a + 1
|
|
186
238
|
};
|
|
187
239
|
}
|
|
188
240
|
/**
|
|
189
|
-
*
|
|
190
|
-
* Used
|
|
241
|
+
* Get focused cell coordinates from DOM.
|
|
242
|
+
* Used as fallback when SelectionPlugin has no selection.
|
|
191
243
|
*/
|
|
192
244
|
#s(e) {
|
|
193
245
|
const t = e.closest("[data-field-cache]");
|
|
194
246
|
if (!t) return null;
|
|
195
|
-
const n = t.dataset.fieldCache;
|
|
196
|
-
if (!n) return null;
|
|
197
|
-
const i = t.dataset.row;
|
|
198
|
-
if (!i) return null;
|
|
247
|
+
const n = t.dataset.fieldCache, i = t.dataset.row;
|
|
248
|
+
if (!n || !i) return null;
|
|
199
249
|
const o = parseInt(i, 10);
|
|
200
250
|
if (isNaN(o)) return null;
|
|
201
|
-
const r = this.
|
|
202
|
-
|
|
203
|
-
const l = r[n], d = this.columns.find((h) => h.field === n)?.header || n;
|
|
204
|
-
let c;
|
|
205
|
-
if (this.config.includeHeaders) {
|
|
206
|
-
const h = l == null ? "" : String(l);
|
|
207
|
-
c = `${d}: ${h}`;
|
|
208
|
-
} else
|
|
209
|
-
c = l == null ? "" : String(l);
|
|
210
|
-
return { text: c, field: n, value: l };
|
|
251
|
+
const r = this.columns.findIndex((l) => l.field === n);
|
|
252
|
+
return r === -1 ? null : { row: o, col: r };
|
|
211
253
|
}
|
|
212
254
|
// #endregion
|
|
213
255
|
// #region Public API
|
|
@@ -216,13 +258,19 @@ class Tn extends x {
|
|
|
216
258
|
* @returns The copied text
|
|
217
259
|
*/
|
|
218
260
|
async copy() {
|
|
219
|
-
const t = this.#
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
261
|
+
const t = this.#n()?.getSelection(), n = this.columns.length - 1;
|
|
262
|
+
let i = { startRow: 0, startCol: 0, endRow: this.rows.length - 1, endCol: n };
|
|
263
|
+
if (t && t.ranges.length > 0) {
|
|
264
|
+
const r = t.ranges[t.ranges.length - 1];
|
|
265
|
+
t.mode === "row" ? i = { startRow: r.from.row, startCol: 0, endRow: r.to.row, endCol: n } : i = {
|
|
266
|
+
startRow: r.from.row,
|
|
267
|
+
startCol: r.from.col,
|
|
268
|
+
endRow: r.to.row,
|
|
269
|
+
endCol: r.to.col
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const o = this.#i(i);
|
|
273
|
+
return await z(o.text), this.lastCopied = { text: o.text, timestamp: Date.now() }, o.text;
|
|
226
274
|
}
|
|
227
275
|
/**
|
|
228
276
|
* Copy specific rows by index to clipboard.
|
|
@@ -230,21 +278,22 @@ class Tn extends x {
|
|
|
230
278
|
* @returns The copied text
|
|
231
279
|
*/
|
|
232
280
|
async copyRows(e) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
281
|
+
if (e.length === 0) return "";
|
|
282
|
+
const t = [...e].sort((r, l) => r - l), n = this.columns.length - 1, i = {
|
|
283
|
+
startRow: t[0],
|
|
284
|
+
startCol: 0,
|
|
285
|
+
endRow: t[t.length - 1],
|
|
286
|
+
endCol: n
|
|
287
|
+
}, o = this.#i(i);
|
|
288
|
+
return await z(o.text), this.lastCopied = { text: o.text, timestamp: Date.now() }, o.text;
|
|
240
289
|
}
|
|
241
290
|
/**
|
|
242
291
|
* Read and parse clipboard content.
|
|
243
292
|
* @returns Parsed 2D array of cell values, or null if clipboard is empty
|
|
244
293
|
*/
|
|
245
294
|
async paste() {
|
|
246
|
-
const e = await
|
|
247
|
-
return e ?
|
|
295
|
+
const e = await tt();
|
|
296
|
+
return e ? ue(e, this.config) : null;
|
|
248
297
|
}
|
|
249
298
|
/**
|
|
250
299
|
* Get the last copied text and timestamp.
|
|
@@ -255,33 +304,33 @@ class Tn extends x {
|
|
|
255
304
|
}
|
|
256
305
|
// #endregion
|
|
257
306
|
}
|
|
258
|
-
const
|
|
259
|
-
function
|
|
307
|
+
const he = 100;
|
|
308
|
+
function oe(s) {
|
|
260
309
|
if (s == null)
|
|
261
|
-
return
|
|
310
|
+
return he;
|
|
262
311
|
if (typeof s == "number")
|
|
263
312
|
return s;
|
|
264
313
|
const e = parseFloat(s);
|
|
265
|
-
return isNaN(e) ?
|
|
314
|
+
return isNaN(e) ? he : e;
|
|
266
315
|
}
|
|
267
|
-
function
|
|
268
|
-
return s.map((e) =>
|
|
316
|
+
function fe(s) {
|
|
317
|
+
return s.map((e) => oe(e.width));
|
|
269
318
|
}
|
|
270
|
-
function
|
|
319
|
+
function ge(s) {
|
|
271
320
|
const e = [];
|
|
272
321
|
let t = 0;
|
|
273
322
|
for (const n of s)
|
|
274
|
-
e.push(t), t +=
|
|
323
|
+
e.push(t), t += oe(n.width);
|
|
275
324
|
return e;
|
|
276
325
|
}
|
|
277
|
-
function
|
|
278
|
-
return s.reduce((e, t) => e +
|
|
326
|
+
function pe(s) {
|
|
327
|
+
return s.reduce((e, t) => e + oe(t.width), 0);
|
|
279
328
|
}
|
|
280
|
-
function
|
|
329
|
+
function it(s, e, t, n, i) {
|
|
281
330
|
const o = t.length;
|
|
282
331
|
if (o === 0)
|
|
283
332
|
return { startCol: 0, endCol: 0, visibleColumns: [] };
|
|
284
|
-
let r =
|
|
333
|
+
let r = ot(s, t, n);
|
|
285
334
|
r = Math.max(0, r - i);
|
|
286
335
|
const l = s + e;
|
|
287
336
|
let a = r;
|
|
@@ -298,7 +347,7 @@ function Ye(s, e, t, n, i) {
|
|
|
298
347
|
d.push(c);
|
|
299
348
|
return { startCol: r, endCol: a, visibleColumns: d };
|
|
300
349
|
}
|
|
301
|
-
function
|
|
350
|
+
function ot(s, e, t) {
|
|
302
351
|
let n = 0, i = e.length - 1;
|
|
303
352
|
for (; n < i; ) {
|
|
304
353
|
const o = Math.floor((n + i) / 2);
|
|
@@ -306,12 +355,11 @@ function Je(s, e, t) {
|
|
|
306
355
|
}
|
|
307
356
|
return n;
|
|
308
357
|
}
|
|
309
|
-
function
|
|
358
|
+
function rt(s, e, t) {
|
|
310
359
|
return t ? s > e : !1;
|
|
311
360
|
}
|
|
312
|
-
class
|
|
361
|
+
class Nn extends x {
|
|
313
362
|
name = "columnVirtualization";
|
|
314
|
-
version = "1.0.0";
|
|
315
363
|
get defaultConfig() {
|
|
316
364
|
return {
|
|
317
365
|
autoEnable: !0,
|
|
@@ -332,7 +380,7 @@ class In extends x {
|
|
|
332
380
|
attach(e) {
|
|
333
381
|
super.attach(e);
|
|
334
382
|
const t = this.columns;
|
|
335
|
-
this.columnWidths =
|
|
383
|
+
this.columnWidths = fe(t), this.columnOffsets = ge(t), this.totalWidth = pe(t), this.endCol = t.length - 1;
|
|
336
384
|
}
|
|
337
385
|
detach() {
|
|
338
386
|
this.columnWidths = [], this.columnOffsets = [], this.isVirtualized = !1, this.startCol = 0, this.endCol = 0, this.scrollLeft = 0, this.totalWidth = 0;
|
|
@@ -340,10 +388,10 @@ class In extends x {
|
|
|
340
388
|
// #endregion
|
|
341
389
|
// #region Hooks
|
|
342
390
|
processColumns(e) {
|
|
343
|
-
const t =
|
|
344
|
-
if (this.isVirtualized = t ?? !1, this.columnWidths =
|
|
391
|
+
const t = rt(e.length, this.config.threshold ?? 30, this.config.autoEnable ?? !0);
|
|
392
|
+
if (this.isVirtualized = t ?? !1, this.columnWidths = fe(e), this.columnOffsets = ge(e), this.totalWidth = pe(e), !t)
|
|
345
393
|
return this.startCol = 0, this.endCol = e.length - 1, [...e];
|
|
346
|
-
const n = this.grid.clientWidth || 800, i =
|
|
394
|
+
const n = this.grid.clientWidth || 800, i = it(
|
|
347
395
|
this.scrollLeft,
|
|
348
396
|
n,
|
|
349
397
|
this.columnOffsets,
|
|
@@ -403,14 +451,14 @@ class In extends x {
|
|
|
403
451
|
}
|
|
404
452
|
// #endregion
|
|
405
453
|
}
|
|
406
|
-
const
|
|
407
|
-
function
|
|
454
|
+
const W = ".tbw-context-menu{position:fixed;background:light-dark(#f5f5f5,#2a2a2a);color:light-dark(#222,#eee);border:1px solid light-dark(#d0d0d4,#454545);border-radius:4px;box-shadow:0 2px 10px #00000026;min-width:160px;padding:4px 0;z-index:10000;font-size:13px;font-family:system-ui,sans-serif}.tbw-context-menu-item{display:flex;align-items:center;padding:6px 12px;cursor:pointer;gap:8px}.tbw-context-menu-item:hover:not(.disabled){background:light-dark(#e8e8e8,#3a3a3a)}.tbw-context-menu-item.disabled{opacity:.5;cursor:default}.tbw-context-menu-item.danger{color:light-dark(#c00,#f66)}.tbw-context-menu-icon{width:16px;text-align:center}.tbw-context-menu-label{flex:1}.tbw-context-menu-shortcut{color:light-dark(#888,#888);font-size:11px}.tbw-context-menu-arrow{font-size:10px;color:light-dark(#888,#888)}.tbw-context-menu-separator{height:1px;background:light-dark(#d0d0d4,#454545);margin:4px 0}";
|
|
455
|
+
function ee(s, e) {
|
|
408
456
|
return (typeof s == "function" ? s(e) : s).filter((n) => !(n.hidden === !0 || typeof n.hidden == "function" && n.hidden(e)));
|
|
409
457
|
}
|
|
410
|
-
function
|
|
458
|
+
function st(s, e) {
|
|
411
459
|
return s.disabled === !0 ? !0 : typeof s.disabled == "function" ? s.disabled(e) : !1;
|
|
412
460
|
}
|
|
413
|
-
function
|
|
461
|
+
function te(s, e, t, n = $e.submenuArrow) {
|
|
414
462
|
const i = document.createElement("div");
|
|
415
463
|
i.className = "tbw-context-menu", i.setAttribute("role", "menu");
|
|
416
464
|
for (const o of s) {
|
|
@@ -421,7 +469,7 @@ function ne(s, e, t, n = ze.submenuArrow) {
|
|
|
421
469
|
}
|
|
422
470
|
const r = document.createElement("div");
|
|
423
471
|
r.className = "tbw-context-menu-item", o.cssClass && r.classList.add(o.cssClass), r.setAttribute("role", "menuitem"), r.setAttribute("data-id", o.id);
|
|
424
|
-
const l =
|
|
472
|
+
const l = st(o, e);
|
|
425
473
|
if (l && (r.classList.add("disabled"), r.setAttribute("aria-disabled", "true")), o.icon) {
|
|
426
474
|
const d = document.createElement("span");
|
|
427
475
|
d.className = "tbw-context-menu-icon", d.innerHTML = o.icon, r.appendChild(d);
|
|
@@ -435,8 +483,8 @@ function ne(s, e, t, n = ze.submenuArrow) {
|
|
|
435
483
|
const d = document.createElement("span");
|
|
436
484
|
d.className = "tbw-context-menu-arrow", typeof n == "string" ? d.innerHTML = n : n instanceof HTMLElement && d.appendChild(n.cloneNode(!0)), r.appendChild(d), r.addEventListener("mouseenter", () => {
|
|
437
485
|
if (r.querySelector(".tbw-context-menu") || !o.subMenu) return;
|
|
438
|
-
const
|
|
439
|
-
|
|
486
|
+
const u = ee(o.subMenu, e), h = te(u, e, t, n);
|
|
487
|
+
h.classList.add("tbw-context-submenu"), h.style.position = "absolute", h.style.left = "100%", h.style.top = "0", r.style.position = "relative", r.appendChild(h);
|
|
440
488
|
}), r.addEventListener("mouseleave", () => {
|
|
441
489
|
const c = r.querySelector(".tbw-context-menu");
|
|
442
490
|
c && c.remove();
|
|
@@ -448,13 +496,13 @@ function ne(s, e, t, n = ze.submenuArrow) {
|
|
|
448
496
|
}
|
|
449
497
|
return i;
|
|
450
498
|
}
|
|
451
|
-
function
|
|
499
|
+
function me(s, e, t) {
|
|
452
500
|
s.style.position = "fixed", s.style.left = `${e}px`, s.style.top = `${t}px`, s.style.visibility = "hidden", s.style.zIndex = "10000";
|
|
453
501
|
const n = s.getBoundingClientRect(), i = window.innerWidth, o = window.innerHeight;
|
|
454
502
|
let r = e, l = t;
|
|
455
503
|
e + n.width > i && (r = e - n.width), t + n.height > o && (l = t - n.height), r = Math.max(0, r), l = Math.max(0, l), s.style.left = `${r}px`, s.style.top = `${l}px`, s.style.visibility = "visible";
|
|
456
504
|
}
|
|
457
|
-
let
|
|
505
|
+
let T = null, I = null, k = null, $ = 0;
|
|
458
506
|
const j = [
|
|
459
507
|
{
|
|
460
508
|
id: "copy",
|
|
@@ -473,9 +521,8 @@ const j = [
|
|
|
473
521
|
}
|
|
474
522
|
}
|
|
475
523
|
];
|
|
476
|
-
class
|
|
524
|
+
class Hn extends x {
|
|
477
525
|
name = "contextMenu";
|
|
478
|
-
version = "1.0.0";
|
|
479
526
|
get defaultConfig() {
|
|
480
527
|
return {
|
|
481
528
|
items: j
|
|
@@ -489,7 +536,7 @@ class Fn extends x {
|
|
|
489
536
|
// #endregion
|
|
490
537
|
// #region Lifecycle
|
|
491
538
|
attach(e) {
|
|
492
|
-
super.attach(e), this.installGlobalHandlers(),
|
|
539
|
+
super.attach(e), this.installGlobalHandlers(), $++;
|
|
493
540
|
}
|
|
494
541
|
detach() {
|
|
495
542
|
this.menuElement && (this.menuElement.remove(), this.menuElement = null), this.isOpen = !1, this.params = null, this.uninstallGlobalHandlers();
|
|
@@ -497,18 +544,18 @@ class Fn extends x {
|
|
|
497
544
|
// #endregion
|
|
498
545
|
// #region Private Methods
|
|
499
546
|
installGlobalHandlers() {
|
|
500
|
-
!k && typeof document < "u" && typeof
|
|
547
|
+
!k && typeof document < "u" && typeof W == "string" && W && (k = document.createElement("style"), k.id = "tbw-context-menu-styles", k.textContent = W, document.head.appendChild(k)), T || (T = () => {
|
|
501
548
|
document.querySelectorAll(".tbw-context-menu").forEach((t) => t.remove());
|
|
502
|
-
}, document.addEventListener("click",
|
|
549
|
+
}, document.addEventListener("click", T)), I || (I = (e) => {
|
|
503
550
|
e.key === "Escape" && document.querySelectorAll(".tbw-context-menu").forEach((n) => n.remove());
|
|
504
|
-
}, document.addEventListener("keydown",
|
|
551
|
+
}, document.addEventListener("keydown", I));
|
|
505
552
|
}
|
|
506
553
|
/**
|
|
507
554
|
* Clean up global handlers when the last instance detaches.
|
|
508
555
|
* Uses reference counting to ensure handlers persist while any grid uses the plugin.
|
|
509
556
|
*/
|
|
510
557
|
uninstallGlobalHandlers() {
|
|
511
|
-
|
|
558
|
+
$--, !($ > 0) && (T && (document.removeEventListener("click", T), T = null), I && (document.removeEventListener("keydown", I), I = null), k && (k.remove(), k = null));
|
|
512
559
|
}
|
|
513
560
|
// #endregion
|
|
514
561
|
// #region Hooks
|
|
@@ -522,25 +569,25 @@ class Fn extends x {
|
|
|
522
569
|
const o = i.target, r = o.closest("[data-row][data-col]"), l = o.closest(".header-cell");
|
|
523
570
|
let a;
|
|
524
571
|
if (r) {
|
|
525
|
-
const c = parseInt(r.getAttribute("data-row") ?? "-1", 10),
|
|
572
|
+
const c = parseInt(r.getAttribute("data-row") ?? "-1", 10), u = parseInt(r.getAttribute("data-col") ?? "-1", 10), h = this.columns[u], f = this.rows[c];
|
|
526
573
|
a = {
|
|
527
574
|
row: f,
|
|
528
575
|
rowIndex: c,
|
|
529
|
-
column:
|
|
530
|
-
columnIndex:
|
|
531
|
-
field:
|
|
532
|
-
value: f?.[
|
|
576
|
+
column: h,
|
|
577
|
+
columnIndex: u,
|
|
578
|
+
field: h?.field ?? "",
|
|
579
|
+
value: f?.[h?.field] ?? null,
|
|
533
580
|
isHeader: !1,
|
|
534
581
|
event: i
|
|
535
582
|
};
|
|
536
583
|
} else if (l) {
|
|
537
|
-
const c = parseInt(l.getAttribute("data-col") ?? "-1", 10),
|
|
584
|
+
const c = parseInt(l.getAttribute("data-col") ?? "-1", 10), u = this.columns[c];
|
|
538
585
|
a = {
|
|
539
586
|
row: null,
|
|
540
587
|
rowIndex: -1,
|
|
541
|
-
column:
|
|
588
|
+
column: u,
|
|
542
589
|
columnIndex: c,
|
|
543
|
-
field:
|
|
590
|
+
field: u?.field ?? "",
|
|
544
591
|
value: null,
|
|
545
592
|
isHeader: !0,
|
|
546
593
|
event: i
|
|
@@ -548,15 +595,15 @@ class Fn extends x {
|
|
|
548
595
|
} else
|
|
549
596
|
return;
|
|
550
597
|
this.params = a, this.position = { x: i.clientX, y: i.clientY };
|
|
551
|
-
const d =
|
|
552
|
-
d.length && (this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
598
|
+
const d = ee(this.config.items ?? j, a);
|
|
599
|
+
d.length && (this.menuElement && this.menuElement.remove(), this.menuElement = te(
|
|
553
600
|
d,
|
|
554
601
|
a,
|
|
555
602
|
(c) => {
|
|
556
603
|
c.action && c.action(a), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
557
604
|
},
|
|
558
605
|
this.gridIcons.submenuArrow
|
|
559
|
-
), document.body.appendChild(this.menuElement),
|
|
606
|
+
), document.body.appendChild(this.menuElement), me(this.menuElement, i.clientX, i.clientY), this.isOpen = !0, this.emit("context-menu-open", { params: a, items: d }));
|
|
560
607
|
}));
|
|
561
608
|
}
|
|
562
609
|
// #endregion
|
|
@@ -577,15 +624,15 @@ class Fn extends x {
|
|
|
577
624
|
value: n.value ?? null,
|
|
578
625
|
isHeader: n.isHeader ?? !1,
|
|
579
626
|
event: n.event ?? new MouseEvent("contextmenu")
|
|
580
|
-
}, o =
|
|
581
|
-
this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
627
|
+
}, o = ee(this.config.items ?? j, i);
|
|
628
|
+
this.menuElement && this.menuElement.remove(), this.menuElement = te(
|
|
582
629
|
o,
|
|
583
630
|
i,
|
|
584
631
|
(r) => {
|
|
585
632
|
r.action && r.action(i), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
586
633
|
},
|
|
587
634
|
this.gridIcons.submenuArrow
|
|
588
|
-
), document.body.appendChild(this.menuElement),
|
|
635
|
+
), document.body.appendChild(this.menuElement), me(this.menuElement, e, t), this.isOpen = !0;
|
|
589
636
|
}
|
|
590
637
|
/**
|
|
591
638
|
* Hide the context menu.
|
|
@@ -603,7 +650,7 @@ class Fn extends x {
|
|
|
603
650
|
// #endregion
|
|
604
651
|
// Styles are injected globally via installGlobalHandlers() since menu renders in document.body
|
|
605
652
|
}
|
|
606
|
-
function
|
|
653
|
+
function lt(s) {
|
|
607
654
|
switch (s.type) {
|
|
608
655
|
case "number":
|
|
609
656
|
return (e) => {
|
|
@@ -657,30 +704,30 @@ function tt(s) {
|
|
|
657
704
|
}
|
|
658
705
|
}
|
|
659
706
|
const U = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
|
|
660
|
-
function
|
|
707
|
+
function P(s) {
|
|
661
708
|
return !(typeof s != "string" || s === "__proto__" || s === "constructor" || s === "prototype");
|
|
662
709
|
}
|
|
663
|
-
function
|
|
710
|
+
function On(s) {
|
|
664
711
|
return (s.__editingCellCount ?? 0) > 0;
|
|
665
712
|
}
|
|
666
|
-
function
|
|
713
|
+
function at(s) {
|
|
667
714
|
const e = (s.__editingCellCount ?? 0) + 1;
|
|
668
715
|
s.__editingCellCount = e, s.setAttribute("data-has-editing", "");
|
|
669
716
|
}
|
|
670
|
-
function
|
|
717
|
+
function dt(s) {
|
|
671
718
|
s.__editingCellCount = 0, s.removeAttribute("data-has-editing");
|
|
672
719
|
}
|
|
673
|
-
function
|
|
720
|
+
function K(s, e) {
|
|
721
|
+
return s instanceof HTMLInputElement ? s.type === "checkbox" ? s.checked : s.type === "number" ? s.value === "" ? null : Number(s.value) : s.type === "date" ? s.valueAsDate : s.value : e?.type === "number" && s.value !== "" ? Number(s.value) : s.value;
|
|
722
|
+
}
|
|
723
|
+
function ct(s, e, t) {
|
|
674
724
|
const n = s.querySelector("input,textarea,select");
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
n.addEventListener("
|
|
678
|
-
t(i());
|
|
679
|
-
}), n instanceof HTMLInputElement && n.type === "checkbox" ? n.addEventListener("change", () => t(n.checked)) : n instanceof HTMLSelectElement && n.addEventListener("change", () => t(i()));
|
|
725
|
+
n && (n.addEventListener("blur", () => {
|
|
726
|
+
t(K(n, e));
|
|
727
|
+
}), n instanceof HTMLInputElement && n.type === "checkbox" ? n.addEventListener("change", () => t(n.checked)) : n instanceof HTMLSelectElement && n.addEventListener("change", () => t(K(n, e))));
|
|
680
728
|
}
|
|
681
|
-
class
|
|
729
|
+
class Gn extends x {
|
|
682
730
|
name = "editing";
|
|
683
|
-
version = "1.0.0";
|
|
684
731
|
get defaultConfig() {
|
|
685
732
|
return {
|
|
686
733
|
editOn: "click"
|
|
@@ -732,15 +779,6 @@ class Pn extends x {
|
|
|
732
779
|
this.#e = -1, this.#t = -1, this.#r.clear(), this.#n.clear(), this.#i.clear(), super.detach();
|
|
733
780
|
}
|
|
734
781
|
// #endregion
|
|
735
|
-
// #region Config Augmentation (processColumns hook)
|
|
736
|
-
/**
|
|
737
|
-
* Augment columns with editing metadata.
|
|
738
|
-
* This enables the grid to recognize editable columns without core knowledge.
|
|
739
|
-
*/
|
|
740
|
-
processColumns(e) {
|
|
741
|
-
return e;
|
|
742
|
-
}
|
|
743
|
-
// #endregion
|
|
744
782
|
// #region Event Handlers (event distribution)
|
|
745
783
|
/**
|
|
746
784
|
* Handle cell clicks - start editing if configured for click mode.
|
|
@@ -768,7 +806,7 @@ class Pn extends x {
|
|
|
768
806
|
const o = t._visibleColumns[i], r = t._rows[n];
|
|
769
807
|
if (o?.editable && o.type === "boolean" && r) {
|
|
770
808
|
const l = o.field;
|
|
771
|
-
if (
|
|
809
|
+
if (P(l)) {
|
|
772
810
|
const d = !r[l];
|
|
773
811
|
return this.#a(n, o, d, r), e.preventDefault(), this.requestRender(), !0;
|
|
774
812
|
}
|
|
@@ -943,10 +981,10 @@ class Pn extends x {
|
|
|
943
981
|
if (isNaN(d)) return;
|
|
944
982
|
const c = n._visibleColumns[d];
|
|
945
983
|
if (!c) return;
|
|
946
|
-
const
|
|
947
|
-
if (
|
|
948
|
-
|
|
949
|
-
|
|
984
|
+
const u = a.querySelector("input,textarea,select");
|
|
985
|
+
if (u) {
|
|
986
|
+
const h = K(u, c);
|
|
987
|
+
o[c.field] !== h && this.#a(e, c, h, o);
|
|
950
988
|
}
|
|
951
989
|
}), t && i && o)
|
|
952
990
|
Object.keys(i).forEach((l) => {
|
|
@@ -966,7 +1004,7 @@ class Pn extends x {
|
|
|
966
1004
|
for (const l of this.#i)
|
|
967
1005
|
l.startsWith(`${e}:`) && this.#i.delete(l);
|
|
968
1006
|
r && (r.querySelectorAll(".cell.editing").forEach((l) => {
|
|
969
|
-
l.classList.remove("editing"),
|
|
1007
|
+
l.classList.remove("editing"), dt(l.parentElement);
|
|
970
1008
|
}), this.requestRender()), this.#s = !0, r || (this.#u(n), this.#s = !1);
|
|
971
1009
|
}
|
|
972
1010
|
/**
|
|
@@ -974,65 +1012,68 @@ class Pn extends x {
|
|
|
974
1012
|
*/
|
|
975
1013
|
#a(e, t, n, i) {
|
|
976
1014
|
const o = t.field;
|
|
977
|
-
if (!
|
|
978
|
-
i[o]
|
|
1015
|
+
if (!P(o)) return;
|
|
1016
|
+
const r = i[o];
|
|
1017
|
+
if (r === n) return;
|
|
979
1018
|
const l = !this.#n.has(e);
|
|
980
|
-
this
|
|
981
|
-
const d = this.grid.findRenderedRowElement?.(e);
|
|
982
|
-
d && d.classList.add("changed"), this.emit("cell-commit", {
|
|
1019
|
+
if (this.emitCancelable("cell-commit", {
|
|
983
1020
|
row: i,
|
|
984
1021
|
field: o,
|
|
1022
|
+
oldValue: r,
|
|
985
1023
|
value: n,
|
|
986
1024
|
rowIndex: e,
|
|
987
1025
|
changedRows: this.changedRows,
|
|
988
1026
|
changedRowIndices: this.changedRowIndices,
|
|
989
1027
|
firstTimeForRow: l
|
|
990
|
-
});
|
|
1028
|
+
})) return;
|
|
1029
|
+
i[o] = n, this.#n.add(e), this.#l();
|
|
1030
|
+
const c = this.grid.findRenderedRowElement?.(e);
|
|
1031
|
+
c && c.classList.add("changed");
|
|
991
1032
|
}
|
|
992
1033
|
/**
|
|
993
1034
|
* Inject an editor into a cell.
|
|
994
1035
|
*/
|
|
995
1036
|
#d(e, t, n, i, o, r) {
|
|
996
1037
|
if (!n.editable || o.classList.contains("editing")) return;
|
|
997
|
-
const l =
|
|
1038
|
+
const l = P(n.field) ? e[n.field] : void 0;
|
|
998
1039
|
o.classList.add("editing"), this.#i.add(`${t}:${i}`);
|
|
999
1040
|
const a = o.parentElement;
|
|
1000
|
-
a &&
|
|
1041
|
+
a && at(a);
|
|
1001
1042
|
let d = !1;
|
|
1002
1043
|
const c = (m) => {
|
|
1003
1044
|
d || this.#e === -1 || this.#a(t, n, m, e);
|
|
1004
|
-
},
|
|
1005
|
-
d = !0,
|
|
1006
|
-
},
|
|
1007
|
-
|
|
1008
|
-
m.key === "Enter" && (m.stopPropagation(), m.preventDefault(), d = !0, this.#o(t, !1)), m.key === "Escape" && (m.stopPropagation(), m.preventDefault(),
|
|
1045
|
+
}, u = () => {
|
|
1046
|
+
d = !0, P(n.field) && (e[n.field] = l);
|
|
1047
|
+
}, h = document.createElement("div");
|
|
1048
|
+
h.className = "tbw-editor-host", o.innerHTML = "", o.appendChild(h), h.addEventListener("keydown", (m) => {
|
|
1049
|
+
m.key === "Enter" && (m.stopPropagation(), m.preventDefault(), d = !0, this.#o(t, !1)), m.key === "Escape" && (m.stopPropagation(), m.preventDefault(), u(), this.#o(t, !0));
|
|
1009
1050
|
});
|
|
1010
|
-
const f = n, g = f.__editorTemplate, p = f.editor || (g ? "template" :
|
|
1051
|
+
const f = n, g = f.__editorTemplate, p = f.editor || (g ? "template" : lt(n)), b = l;
|
|
1011
1052
|
if (p === "template" && g)
|
|
1012
|
-
this.#f(
|
|
1053
|
+
this.#f(h, f, e, l, c, u, r, t);
|
|
1013
1054
|
else if (typeof p == "string") {
|
|
1014
1055
|
const m = document.createElement(p);
|
|
1015
|
-
m.value =
|
|
1016
|
-
|
|
1056
|
+
m.value = b, m.addEventListener("change", () => c(m.value)), h.appendChild(m), r || queueMicrotask(() => {
|
|
1057
|
+
h.querySelector(U)?.focus({ preventScroll: !0 });
|
|
1017
1058
|
});
|
|
1018
1059
|
} else if (typeof p == "function") {
|
|
1019
|
-
const m = { row: e, value:
|
|
1020
|
-
typeof
|
|
1021
|
-
|
|
1060
|
+
const m = { row: e, value: b, field: n.field, column: n, commit: c, cancel: u }, w = p(m);
|
|
1061
|
+
typeof w == "string" ? (h.innerHTML = w, ct(h, n, c)) : w instanceof Node && h.appendChild(w), r || queueMicrotask(() => {
|
|
1062
|
+
h.querySelector(U)?.focus({ preventScroll: !0 });
|
|
1022
1063
|
});
|
|
1023
1064
|
} else if (p && typeof p == "object") {
|
|
1024
|
-
const m = this.grid,
|
|
1025
|
-
|
|
1026
|
-
const A = { row: e, value:
|
|
1065
|
+
const m = this.grid, w = document.createElement("div");
|
|
1066
|
+
w.setAttribute("data-external-editor", ""), w.setAttribute("data-field", n.field), h.appendChild(w);
|
|
1067
|
+
const A = { row: e, value: b, field: n.field, column: n, commit: c, cancel: u };
|
|
1027
1068
|
if (p.mount)
|
|
1028
1069
|
try {
|
|
1029
|
-
p.mount({ placeholder:
|
|
1070
|
+
p.mount({ placeholder: w, context: A, spec: p });
|
|
1030
1071
|
} catch (q) {
|
|
1031
1072
|
console.warn(`[tbw-grid] External editor mount error for column '${n.field}':`, q);
|
|
1032
1073
|
}
|
|
1033
1074
|
else
|
|
1034
1075
|
m.dispatchEvent(
|
|
1035
|
-
new CustomEvent("mount-external-editor", { detail: { placeholder:
|
|
1076
|
+
new CustomEvent("mount-external-editor", { detail: { placeholder: w, spec: p, context: A } })
|
|
1036
1077
|
);
|
|
1037
1078
|
}
|
|
1038
1079
|
}
|
|
@@ -1042,8 +1083,8 @@ class Pn extends x {
|
|
|
1042
1083
|
#f(e, t, n, i, o, r, l, a) {
|
|
1043
1084
|
const d = t.__editorTemplate;
|
|
1044
1085
|
if (!d) return;
|
|
1045
|
-
const c = d.cloneNode(!0),
|
|
1046
|
-
|
|
1086
|
+
const c = d.cloneNode(!0), u = t.__compiledEditor;
|
|
1087
|
+
u ? c.innerHTML = u({
|
|
1047
1088
|
row: n,
|
|
1048
1089
|
value: i,
|
|
1049
1090
|
field: t.field,
|
|
@@ -1052,30 +1093,23 @@ class Pn extends x {
|
|
|
1052
1093
|
cancel: r
|
|
1053
1094
|
}) : c.querySelectorAll("*").forEach((f) => {
|
|
1054
1095
|
f.childNodes.length === 1 && f.firstChild?.nodeType === Node.TEXT_NODE && (f.textContent = f.textContent?.replace(/{{\s*value\s*}}/g, i == null ? "" : String(i)).replace(/{{\s*row\.([a-zA-Z0-9_]+)\s*}}/g, (g, p) => {
|
|
1055
|
-
if (!
|
|
1056
|
-
const
|
|
1057
|
-
return
|
|
1096
|
+
if (!P(p)) return "";
|
|
1097
|
+
const b = n[p];
|
|
1098
|
+
return b == null ? "" : String(b);
|
|
1058
1099
|
}) || "");
|
|
1059
1100
|
});
|
|
1060
|
-
const
|
|
1101
|
+
const h = c.querySelector(
|
|
1061
1102
|
"input,textarea,select"
|
|
1062
1103
|
);
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1104
|
+
if (h) {
|
|
1105
|
+
h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked = !!i : h.value = String(i ?? "");
|
|
1065
1106
|
let f = !1;
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
o(g);
|
|
1070
|
-
}), u.addEventListener("keydown", (g) => {
|
|
1107
|
+
h.addEventListener("blur", () => {
|
|
1108
|
+
f || o(K(h, t));
|
|
1109
|
+
}), h.addEventListener("keydown", (g) => {
|
|
1071
1110
|
const p = g;
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
const w = u instanceof HTMLInputElement && u.type === "checkbox" ? u.checked : u.value;
|
|
1075
|
-
o(w), this.#o(a, !1);
|
|
1076
|
-
}
|
|
1077
|
-
p.key === "Escape" && (p.stopPropagation(), p.preventDefault(), r(), this.#o(a, !0));
|
|
1078
|
-
}), u instanceof HTMLInputElement && u.type === "checkbox" && u.addEventListener("change", () => o(u.checked)), l || setTimeout(() => u.focus({ preventScroll: !0 }), 0);
|
|
1111
|
+
p.key === "Enter" && (p.stopPropagation(), p.preventDefault(), f = !0, o(K(h, t)), this.#o(a, !1)), p.key === "Escape" && (p.stopPropagation(), p.preventDefault(), r(), this.#o(a, !0));
|
|
1112
|
+
}), h instanceof HTMLInputElement && h.type === "checkbox" && h.addEventListener("change", () => o(h.checked)), l || setTimeout(() => h.focus({ preventScroll: !0 }), 0);
|
|
1079
1113
|
}
|
|
1080
1114
|
e.appendChild(c);
|
|
1081
1115
|
}
|
|
@@ -1099,7 +1133,7 @@ class Pn extends x {
|
|
|
1099
1133
|
}
|
|
1100
1134
|
// #endregion
|
|
1101
1135
|
}
|
|
1102
|
-
function
|
|
1136
|
+
function we(s, e = !0) {
|
|
1103
1137
|
if (s == null) return "";
|
|
1104
1138
|
if (s instanceof Date) return s.toISOString();
|
|
1105
1139
|
if (typeof s == "object") return JSON.stringify(s);
|
|
@@ -1107,37 +1141,37 @@ function ve(s, e = !0) {
|
|
|
1107
1141
|
return e && (t.includes(",") || t.includes('"') || t.includes(`
|
|
1108
1142
|
`) || t.includes("\r")) ? `"${t.replace(/"/g, '""')}"` : t;
|
|
1109
1143
|
}
|
|
1110
|
-
function
|
|
1144
|
+
function ut(s, e, t, n = {}) {
|
|
1111
1145
|
const i = n.delimiter ?? ",", o = n.newline ?? `
|
|
1112
1146
|
`, r = [], l = n.bom ? "\uFEFF" : "";
|
|
1113
1147
|
if (t.includeHeaders !== !1) {
|
|
1114
1148
|
const a = e.map((d) => {
|
|
1115
|
-
const c = d.header || d.field,
|
|
1116
|
-
return
|
|
1149
|
+
const c = d.header || d.field, u = t.processHeader ? t.processHeader(c, d.field) : c;
|
|
1150
|
+
return we(u);
|
|
1117
1151
|
});
|
|
1118
1152
|
r.push(a.join(i));
|
|
1119
1153
|
}
|
|
1120
1154
|
for (const a of s) {
|
|
1121
1155
|
const d = e.map((c) => {
|
|
1122
|
-
let
|
|
1123
|
-
return t.processCell && (
|
|
1156
|
+
let u = a[c.field];
|
|
1157
|
+
return t.processCell && (u = t.processCell(u, c.field, a)), we(u);
|
|
1124
1158
|
});
|
|
1125
1159
|
r.push(d.join(i));
|
|
1126
1160
|
}
|
|
1127
1161
|
return l + r.join(o);
|
|
1128
1162
|
}
|
|
1129
|
-
function
|
|
1163
|
+
function re(s, e) {
|
|
1130
1164
|
const t = URL.createObjectURL(s), n = document.createElement("a");
|
|
1131
1165
|
n.href = t, n.download = e, n.style.display = "none", document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(t);
|
|
1132
1166
|
}
|
|
1133
|
-
function
|
|
1167
|
+
function ht(s, e) {
|
|
1134
1168
|
const t = new Blob([s], { type: "text/csv;charset=utf-8;" });
|
|
1135
|
-
|
|
1169
|
+
re(t, e);
|
|
1136
1170
|
}
|
|
1137
|
-
function
|
|
1171
|
+
function be(s) {
|
|
1138
1172
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1139
1173
|
}
|
|
1140
|
-
function
|
|
1174
|
+
function ft(s, e, t) {
|
|
1141
1175
|
let n = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1142
1176
|
<?mso-application progid="Excel.Sheet"?>
|
|
1143
1177
|
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
|
@@ -1149,7 +1183,7 @@ function lt(s, e, t) {
|
|
|
1149
1183
|
<Row>`;
|
|
1150
1184
|
for (const i of e) {
|
|
1151
1185
|
const o = i.header || i.field, r = t.processHeader ? t.processHeader(o, i.field) : o;
|
|
1152
|
-
n += `<Cell><Data ss:Type="String">${
|
|
1186
|
+
n += `<Cell><Data ss:Type="String">${be(r)}</Data></Cell>`;
|
|
1153
1187
|
}
|
|
1154
1188
|
n += "</Row>";
|
|
1155
1189
|
}
|
|
@@ -1160,7 +1194,7 @@ function lt(s, e, t) {
|
|
|
1160
1194
|
let r = i[o.field];
|
|
1161
1195
|
t.processCell && (r = t.processCell(r, o.field, i));
|
|
1162
1196
|
let l = "String", a = "";
|
|
1163
|
-
r == null ? a = "" : typeof r == "number" && !isNaN(r) ? (l = "Number", a = String(r)) : r instanceof Date ? (l = "DateTime", a = r.toISOString()) : a =
|
|
1197
|
+
r == null ? a = "" : typeof r == "number" && !isNaN(r) ? (l = "Number", a = String(r)) : r instanceof Date ? (l = "DateTime", a = r.toISOString()) : a = be(String(r)), n += `<Cell><Data ss:Type="${l}">${a}</Data></Cell>`;
|
|
1164
1198
|
}
|
|
1165
1199
|
n += "</Row>";
|
|
1166
1200
|
}
|
|
@@ -1169,15 +1203,14 @@ function lt(s, e, t) {
|
|
|
1169
1203
|
</Worksheet>
|
|
1170
1204
|
</Workbook>`, n;
|
|
1171
1205
|
}
|
|
1172
|
-
function
|
|
1206
|
+
function gt(s, e) {
|
|
1173
1207
|
const t = e.endsWith(".xls") ? e : `${e}.xls`, n = new Blob([s], {
|
|
1174
1208
|
type: "application/vnd.ms-excel;charset=utf-8;"
|
|
1175
1209
|
});
|
|
1176
|
-
|
|
1210
|
+
re(n, t);
|
|
1177
1211
|
}
|
|
1178
|
-
class
|
|
1212
|
+
class Bn extends x {
|
|
1179
1213
|
name = "export";
|
|
1180
|
-
version = "1.0.0";
|
|
1181
1214
|
get defaultConfig() {
|
|
1182
1215
|
return {
|
|
1183
1216
|
fileName: "export",
|
|
@@ -1209,34 +1242,34 @@ class qn extends x {
|
|
|
1209
1242
|
let r = [...this.rows];
|
|
1210
1243
|
if (n.onlySelected) {
|
|
1211
1244
|
const a = this.getSelectionState();
|
|
1212
|
-
a?.selected?.size && (r = [...a.selected].sort((c,
|
|
1245
|
+
a?.selected?.size && (r = [...a.selected].sort((c, u) => c - u).map((c) => this.rows[c]).filter(Boolean));
|
|
1213
1246
|
}
|
|
1214
1247
|
t?.rowIndices && (r = t.rowIndices.map((a) => this.rows[a]).filter(Boolean)), this.isExportingFlag = !0;
|
|
1215
1248
|
let l = i.fileName;
|
|
1216
1249
|
try {
|
|
1217
1250
|
switch (e) {
|
|
1218
1251
|
case "csv": {
|
|
1219
|
-
const a =
|
|
1220
|
-
l = l.endsWith(".csv") ? l : `${l}.csv`,
|
|
1252
|
+
const a = ut(r, o, i, { bom: !0 });
|
|
1253
|
+
l = l.endsWith(".csv") ? l : `${l}.csv`, ht(a, l);
|
|
1221
1254
|
break;
|
|
1222
1255
|
}
|
|
1223
1256
|
case "excel": {
|
|
1224
|
-
const a =
|
|
1225
|
-
l = l.endsWith(".xls") ? l : `${l}.xls`,
|
|
1257
|
+
const a = ft(r, o, i);
|
|
1258
|
+
l = l.endsWith(".xls") ? l : `${l}.xls`, gt(a, l);
|
|
1226
1259
|
break;
|
|
1227
1260
|
}
|
|
1228
1261
|
case "json": {
|
|
1229
|
-
const a = r.map((
|
|
1230
|
-
const
|
|
1262
|
+
const a = r.map((u) => {
|
|
1263
|
+
const h = {};
|
|
1231
1264
|
for (const f of o) {
|
|
1232
|
-
let g =
|
|
1233
|
-
i.processCell && (g = i.processCell(g, f.field,
|
|
1265
|
+
let g = u[f.field];
|
|
1266
|
+
i.processCell && (g = i.processCell(g, f.field, u)), h[f.field] = g;
|
|
1234
1267
|
}
|
|
1235
|
-
return
|
|
1268
|
+
return h;
|
|
1236
1269
|
}), d = JSON.stringify(a, null, 2);
|
|
1237
1270
|
l = l.endsWith(".json") ? l : `${l}.json`;
|
|
1238
1271
|
const c = new Blob([d], { type: "application/json" });
|
|
1239
|
-
|
|
1272
|
+
re(c, l);
|
|
1240
1273
|
break;
|
|
1241
1274
|
}
|
|
1242
1275
|
}
|
|
@@ -1296,7 +1329,7 @@ class qn extends x {
|
|
|
1296
1329
|
}
|
|
1297
1330
|
// #endregion
|
|
1298
1331
|
}
|
|
1299
|
-
function
|
|
1332
|
+
function pt(s) {
|
|
1300
1333
|
const { totalRows: e, viewportHeight: t, scrollTop: n, rowHeight: i, overscan: o } = s, r = Math.ceil(t / i);
|
|
1301
1334
|
let l = Math.floor(n / i) - o;
|
|
1302
1335
|
l < 0 && (l = 0);
|
|
@@ -1308,10 +1341,10 @@ function dt(s) {
|
|
|
1308
1341
|
totalHeight: e * i
|
|
1309
1342
|
};
|
|
1310
1343
|
}
|
|
1311
|
-
function
|
|
1344
|
+
function mt(s, e) {
|
|
1312
1345
|
return s <= e;
|
|
1313
1346
|
}
|
|
1314
|
-
function
|
|
1347
|
+
function wt(s, e, t = !1) {
|
|
1315
1348
|
const n = s[e.field];
|
|
1316
1349
|
if (e.operator === "blank")
|
|
1317
1350
|
return n == null || n === "";
|
|
@@ -1353,10 +1386,10 @@ function ut(s, e, t = !1) {
|
|
|
1353
1386
|
return !0;
|
|
1354
1387
|
}
|
|
1355
1388
|
}
|
|
1356
|
-
function
|
|
1357
|
-
return e.length ? s.filter((n) => e.every((i) =>
|
|
1389
|
+
function bt(s, e, t = !1) {
|
|
1390
|
+
return e.length ? s.filter((n) => e.every((i) => wt(n, i, t))) : s;
|
|
1358
1391
|
}
|
|
1359
|
-
function
|
|
1392
|
+
function vt(s) {
|
|
1360
1393
|
return JSON.stringify(
|
|
1361
1394
|
s.map((e) => ({
|
|
1362
1395
|
field: e.field,
|
|
@@ -1366,7 +1399,7 @@ function ft(s) {
|
|
|
1366
1399
|
}))
|
|
1367
1400
|
);
|
|
1368
1401
|
}
|
|
1369
|
-
function
|
|
1402
|
+
function ve(s, e) {
|
|
1370
1403
|
const t = /* @__PURE__ */ new Set();
|
|
1371
1404
|
for (const n of s) {
|
|
1372
1405
|
const i = n[e];
|
|
@@ -1374,10 +1407,10 @@ function xe(s, e) {
|
|
|
1374
1407
|
}
|
|
1375
1408
|
return [...t].sort((n, i) => typeof n == "number" && typeof i == "number" ? n - i : String(n).localeCompare(String(i)));
|
|
1376
1409
|
}
|
|
1377
|
-
const
|
|
1378
|
-
class
|
|
1410
|
+
const yt = ':host .tbw-quick-filter-input{flex:1;max-width:300px;height:28px;padding:0 8px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);color:var(--tbw-color-fg);font-size:13px}:host .tbw-quick-filter-input:focus{outline:none;border-color:var(--tbw-color-accent)}:host .header-cell.filtered:before{content:"";position:absolute;top:4px;right:4px;width:6px;height:6px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));border-radius:50%}:host .tbw-filter-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:2px;margin-left:4px;opacity:.4;transition:opacity .15s;color:inherit;vertical-align:middle}:host .tbw-filter-btn:hover,:host .tbw-filter-btn.active{opacity:1}:host .tbw-filter-btn.active{color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}', xt = ".tbw-filter-panel{position:fixed;background:var(--tbw-filter-panel-bg, var(--tbw-color-panel-bg, light-dark(#eeeeee, #222222)));color:var(--tbw-filter-panel-fg, var(--tbw-color-fg, light-dark(#222222, #eeeeee)));border:1px solid var(--tbw-filter-panel-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-panel-radius, var(--tbw-border-radius, 4px));box-shadow:0 4px 16px var(--tbw-filter-panel-shadow, var(--tbw-color-shadow, light-dark(rgba(0, 0, 0, .1), rgba(0, 0, 0, .3))));padding:12px;z-index:10000;min-width:200px;max-width:280px;max-height:350px;display:flex;flex-direction:column;font-family:var(--tbw-font-family, system-ui, sans-serif);font-size:var(--tbw-font-size, 13px)}.tbw-filter-search{margin-bottom:8px}.tbw-filter-search-input{width:100%;padding:6px 10px;background:var(--tbw-filter-input-bg, var(--tbw-color-bg, transparent));color:inherit;border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:var(--tbw-filter-input-radius, 4px);font-size:inherit;box-sizing:border-box}.tbw-filter-search-input:focus{outline:none;border-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));box-shadow:0 0 0 2px rgba(from var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6)) r g b / 15%)}.tbw-filter-actions{display:flex;padding:4px 2px;margin-bottom:8px;border-bottom:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-action-btn{background:transparent;border:none;color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));cursor:pointer;font-size:12px;padding:2px 0}.tbw-filter-action-btn:hover{text-decoration:underline}.tbw-filter-values{flex:1;overflow-y:auto;margin-bottom:8px;max-height:180px;position:relative}.tbw-filter-values-spacer{width:1px}.tbw-filter-values-content{position:absolute;top:0;left:0;right:0}.tbw-filter-value-item{display:flex;align-items:center;gap:8px;padding:4px 2px;cursor:pointer;border-radius:3px}.tbw-filter-value-item:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}.tbw-filter-checkbox{margin:0;cursor:pointer;accent-color:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6))}.tbw-filter-no-match{color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));padding:8px 0;text-align:center;font-style:italic}.tbw-filter-buttons{display:flex;gap:8px;padding-top:8px;border-top:1px solid var(--tbw-filter-divider, var(--tbw-color-border, light-dark(#d0d0d4, #454545)))}.tbw-filter-apply-btn{flex:1;padding:6px 12px;background:var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));color:var(--tbw-filter-accent-fg, var(--tbw-color-accent-fg, light-dark(#ffffff, #000000)));border:none;border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-apply-btn:hover{filter:brightness(.9)}.tbw-filter-clear-btn{flex:1;padding:6px 12px;background:transparent;color:var(--tbw-filter-muted, var(--tbw-color-fg-muted, light-dark(#555555, #aaaaaa)));border:1px solid var(--tbw-filter-input-border, var(--tbw-color-border, light-dark(#d0d0d4, #454545)));border-radius:4px;cursor:pointer;font-size:13px}.tbw-filter-clear-btn:hover{background:var(--tbw-filter-hover, var(--tbw-color-row-hover, light-dark(#f0f6ff, #1c1c1c)))}";
|
|
1411
|
+
class L extends x {
|
|
1379
1412
|
name = "filtering";
|
|
1380
|
-
|
|
1413
|
+
styles = yt;
|
|
1381
1414
|
get defaultConfig() {
|
|
1382
1415
|
return {
|
|
1383
1416
|
debounceMs: 300,
|
|
@@ -1402,6 +1435,12 @@ class _ extends x {
|
|
|
1402
1435
|
static LIST_OVERSCAN = 3;
|
|
1403
1436
|
static LIST_BYPASS_THRESHOLD = 50;
|
|
1404
1437
|
// Don't virtualize if < 50 items
|
|
1438
|
+
/**
|
|
1439
|
+
* Sync excludedValues map from a filter model (for set filters).
|
|
1440
|
+
*/
|
|
1441
|
+
syncExcludedValues(e, t) {
|
|
1442
|
+
t ? t.type === "set" && t.operator === "notIn" && Array.isArray(t.value) ? this.excludedValues.set(e, new Set(t.value)) : t.type === "set" && this.excludedValues.delete(e) : this.excludedValues.delete(e);
|
|
1443
|
+
}
|
|
1405
1444
|
// #endregion
|
|
1406
1445
|
// #region Lifecycle
|
|
1407
1446
|
attach(e) {
|
|
@@ -1417,10 +1456,10 @@ class _ extends x {
|
|
|
1417
1456
|
if (!t.length) return [...e];
|
|
1418
1457
|
if (this.config.filterHandler)
|
|
1419
1458
|
return this.cachedResult ? this.cachedResult : [...e];
|
|
1420
|
-
const n =
|
|
1459
|
+
const n = vt(t);
|
|
1421
1460
|
if (this.cacheKey === n && this.cachedResult)
|
|
1422
1461
|
return this.cachedResult;
|
|
1423
|
-
const i =
|
|
1462
|
+
const i = bt([...e], t, this.config.caseSensitive);
|
|
1424
1463
|
return this.cachedResult = i, this.cacheKey = n, i;
|
|
1425
1464
|
}
|
|
1426
1465
|
afterRender() {
|
|
@@ -1453,7 +1492,13 @@ class _ extends x {
|
|
|
1453
1492
|
* Pass null to remove the filter.
|
|
1454
1493
|
*/
|
|
1455
1494
|
setFilter(e, t) {
|
|
1456
|
-
|
|
1495
|
+
if (t === null)
|
|
1496
|
+
this.filters.delete(e), this.syncExcludedValues(e, null);
|
|
1497
|
+
else {
|
|
1498
|
+
const n = { ...t, field: e };
|
|
1499
|
+
this.filters.set(e, n), this.syncExcludedValues(e, n);
|
|
1500
|
+
}
|
|
1501
|
+
this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
1457
1502
|
filters: [...this.filters.values()],
|
|
1458
1503
|
filteredRowCount: 0
|
|
1459
1504
|
// Will be accurate after processRows
|
|
@@ -1483,7 +1528,7 @@ class _ extends x {
|
|
|
1483
1528
|
setFilterModel(e) {
|
|
1484
1529
|
this.filters.clear(), this.excludedValues.clear();
|
|
1485
1530
|
for (const t of e)
|
|
1486
|
-
this.filters.set(t.field, t),
|
|
1531
|
+
this.filters.set(t.field, t), this.syncExcludedValues(t.field, t);
|
|
1487
1532
|
this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
1488
1533
|
filters: [...this.filters.values()],
|
|
1489
1534
|
filteredRowCount: 0
|
|
@@ -1524,7 +1569,7 @@ class _ extends x {
|
|
|
1524
1569
|
* Uses sourceRows to include all values regardless of current filter.
|
|
1525
1570
|
*/
|
|
1526
1571
|
getUniqueValues(e) {
|
|
1527
|
-
return
|
|
1572
|
+
return ve(this.sourceRows, e);
|
|
1528
1573
|
}
|
|
1529
1574
|
// #endregion
|
|
1530
1575
|
// #region Private Methods
|
|
@@ -1538,7 +1583,7 @@ class _ extends x {
|
|
|
1538
1583
|
return;
|
|
1539
1584
|
}
|
|
1540
1585
|
const e = document.createElement("style");
|
|
1541
|
-
e.id = "tbw-filter-panel-styles", e.textContent =
|
|
1586
|
+
e.id = "tbw-filter-panel-styles", e.textContent = xt, document.head.appendChild(e), this.globalStylesInjected = !0;
|
|
1542
1587
|
}
|
|
1543
1588
|
/**
|
|
1544
1589
|
* Toggle the filter panel for a field
|
|
@@ -1556,7 +1601,7 @@ class _ extends x {
|
|
|
1556
1601
|
});
|
|
1557
1602
|
return;
|
|
1558
1603
|
}
|
|
1559
|
-
const o =
|
|
1604
|
+
const o = ve(this.sourceRows, e);
|
|
1560
1605
|
this.renderPanelContent(e, t, i, o), document.body.appendChild(i), this.positionPanel(i, n), this.setupPanelCloseHandler(i, n);
|
|
1561
1606
|
}
|
|
1562
1607
|
/**
|
|
@@ -1574,8 +1619,8 @@ class _ extends x {
|
|
|
1574
1619
|
applySetFilter: (d) => {
|
|
1575
1620
|
this.applySetFilter(e, d), this.closeFilterPanel();
|
|
1576
1621
|
},
|
|
1577
|
-
applyTextFilter: (d, c,
|
|
1578
|
-
this.applyTextFilter(e, d, c,
|
|
1622
|
+
applyTextFilter: (d, c, u) => {
|
|
1623
|
+
this.applyTextFilter(e, d, c, u), this.closeFilterPanel();
|
|
1579
1624
|
},
|
|
1580
1625
|
clearFilter: () => {
|
|
1581
1626
|
this.clearFieldFilter(e), this.closeFilterPanel();
|
|
@@ -1629,17 +1674,17 @@ class _ extends x {
|
|
|
1629
1674
|
d.className = "tbw-filter-value-item", d.style.padding = "0", d.style.margin = "0";
|
|
1630
1675
|
const c = document.createElement("input");
|
|
1631
1676
|
c.type = "checkbox", c.className = "tbw-filter-checkbox";
|
|
1632
|
-
const
|
|
1633
|
-
|
|
1634
|
-
const
|
|
1635
|
-
const
|
|
1677
|
+
const u = document.createElement("span");
|
|
1678
|
+
u.textContent = "Select All", d.appendChild(c), d.appendChild(u), a.appendChild(d);
|
|
1679
|
+
const h = () => {
|
|
1680
|
+
const v = [...b.values()], R = v.every((C) => C), E = v.every((C) => !C);
|
|
1636
1681
|
c.checked = R, c.indeterminate = !R && !E;
|
|
1637
1682
|
};
|
|
1638
1683
|
c.addEventListener("change", () => {
|
|
1639
|
-
const
|
|
1640
|
-
for (const R of
|
|
1641
|
-
|
|
1642
|
-
|
|
1684
|
+
const v = c.checked;
|
|
1685
|
+
for (const R of b.keys())
|
|
1686
|
+
b.set(R, v);
|
|
1687
|
+
h(), A();
|
|
1643
1688
|
}), e.appendChild(a);
|
|
1644
1689
|
const f = document.createElement("div");
|
|
1645
1690
|
f.className = "tbw-filter-values";
|
|
@@ -1647,44 +1692,44 @@ class _ extends x {
|
|
|
1647
1692
|
g.className = "tbw-filter-values-spacer", f.appendChild(g);
|
|
1648
1693
|
const p = document.createElement("div");
|
|
1649
1694
|
p.className = "tbw-filter-values-content", f.appendChild(p);
|
|
1650
|
-
const
|
|
1651
|
-
n.forEach((
|
|
1652
|
-
const R =
|
|
1653
|
-
|
|
1654
|
-
}),
|
|
1695
|
+
const b = /* @__PURE__ */ new Map();
|
|
1696
|
+
n.forEach((v) => {
|
|
1697
|
+
const R = v == null ? "__null__" : String(v);
|
|
1698
|
+
b.set(R, !i.has(v));
|
|
1699
|
+
}), h();
|
|
1655
1700
|
let m = [];
|
|
1656
|
-
const
|
|
1657
|
-
const E =
|
|
1658
|
-
y.className = "tbw-filter-value-item", y.style.position = "absolute", y.style.top = `${R *
|
|
1701
|
+
const w = (v, R) => {
|
|
1702
|
+
const E = v == null ? "(Blank)" : String(v), C = v == null ? "__null__" : String(v), y = document.createElement("label");
|
|
1703
|
+
y.className = "tbw-filter-value-item", y.style.position = "absolute", y.style.top = `${R * L.LIST_ITEM_HEIGHT}px`, y.style.left = "0", y.style.right = "0", y.style.height = `${L.LIST_ITEM_HEIGHT}px`, y.style.boxSizing = "border-box";
|
|
1659
1704
|
const S = document.createElement("input");
|
|
1660
|
-
S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked =
|
|
1661
|
-
|
|
1705
|
+
S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked = b.get(C) ?? !0, S.dataset.value = C, S.addEventListener("change", () => {
|
|
1706
|
+
b.set(C, S.checked), h();
|
|
1662
1707
|
});
|
|
1663
|
-
const
|
|
1664
|
-
return
|
|
1708
|
+
const ae = document.createElement("span");
|
|
1709
|
+
return ae.textContent = E, y.appendChild(S), y.appendChild(ae), y;
|
|
1665
1710
|
}, A = () => {
|
|
1666
|
-
const
|
|
1667
|
-
if (g.style.height = `${
|
|
1711
|
+
const v = m.length, R = f.clientHeight, E = f.scrollTop;
|
|
1712
|
+
if (g.style.height = `${v * L.LIST_ITEM_HEIGHT}px`, mt(v, L.LIST_BYPASS_THRESHOLD / 3)) {
|
|
1668
1713
|
p.innerHTML = "", p.style.transform = "translateY(0px)", m.forEach((y, S) => {
|
|
1669
|
-
p.appendChild(
|
|
1714
|
+
p.appendChild(w(y, S));
|
|
1670
1715
|
});
|
|
1671
1716
|
return;
|
|
1672
1717
|
}
|
|
1673
|
-
const C =
|
|
1674
|
-
totalRows:
|
|
1718
|
+
const C = pt({
|
|
1719
|
+
totalRows: v,
|
|
1675
1720
|
viewportHeight: R,
|
|
1676
1721
|
scrollTop: E,
|
|
1677
|
-
rowHeight:
|
|
1678
|
-
overscan:
|
|
1722
|
+
rowHeight: L.LIST_ITEM_HEIGHT,
|
|
1723
|
+
overscan: L.LIST_OVERSCAN
|
|
1679
1724
|
});
|
|
1680
1725
|
p.style.transform = `translateY(${C.offsetY}px)`, p.innerHTML = "";
|
|
1681
1726
|
for (let y = C.start; y < C.end; y++)
|
|
1682
|
-
p.appendChild(
|
|
1683
|
-
}, q = (
|
|
1684
|
-
const R =
|
|
1727
|
+
p.appendChild(w(m[y], y - C.start));
|
|
1728
|
+
}, q = (v) => {
|
|
1729
|
+
const R = v.toLowerCase();
|
|
1685
1730
|
if (m = n.filter((E) => {
|
|
1686
1731
|
const C = E == null ? "(Blank)" : String(E);
|
|
1687
|
-
return !
|
|
1732
|
+
return !v || C.toLowerCase().includes(R);
|
|
1688
1733
|
}), m.length === 0) {
|
|
1689
1734
|
g.style.height = "0px", p.innerHTML = "";
|
|
1690
1735
|
const E = document.createElement("div");
|
|
@@ -1700,31 +1745,31 @@ class _ extends x {
|
|
|
1700
1745
|
},
|
|
1701
1746
|
{ passive: !0 }
|
|
1702
1747
|
), q(l.value), e.appendChild(f);
|
|
1703
|
-
let
|
|
1748
|
+
let le;
|
|
1704
1749
|
l.addEventListener("input", () => {
|
|
1705
|
-
clearTimeout(
|
|
1750
|
+
clearTimeout(le), le = setTimeout(() => {
|
|
1706
1751
|
this.searchText.set(o, l.value), q(l.value);
|
|
1707
1752
|
}, this.config.debounceMs ?? 150);
|
|
1708
1753
|
});
|
|
1709
|
-
const
|
|
1710
|
-
|
|
1711
|
-
const
|
|
1712
|
-
|
|
1713
|
-
const
|
|
1714
|
-
for (const [R, E] of
|
|
1754
|
+
const N = document.createElement("div");
|
|
1755
|
+
N.className = "tbw-filter-buttons";
|
|
1756
|
+
const H = document.createElement("button");
|
|
1757
|
+
H.className = "tbw-filter-apply-btn", H.textContent = "Apply", H.addEventListener("click", () => {
|
|
1758
|
+
const v = [];
|
|
1759
|
+
for (const [R, E] of b)
|
|
1715
1760
|
if (!E)
|
|
1716
1761
|
if (R === "__null__")
|
|
1717
|
-
|
|
1762
|
+
v.push(null);
|
|
1718
1763
|
else {
|
|
1719
1764
|
const C = n.find((y) => String(y) === R);
|
|
1720
|
-
|
|
1765
|
+
v.push(C !== void 0 ? C : R);
|
|
1721
1766
|
}
|
|
1722
|
-
t.applySetFilter(
|
|
1723
|
-
}),
|
|
1724
|
-
const
|
|
1725
|
-
|
|
1767
|
+
t.applySetFilter(v);
|
|
1768
|
+
}), N.appendChild(H);
|
|
1769
|
+
const O = document.createElement("button");
|
|
1770
|
+
O.className = "tbw-filter-clear-btn", O.textContent = "Clear Filter", O.addEventListener("click", () => {
|
|
1726
1771
|
t.clearFilter();
|
|
1727
|
-
}),
|
|
1772
|
+
}), N.appendChild(O), e.appendChild(N);
|
|
1728
1773
|
}
|
|
1729
1774
|
/**
|
|
1730
1775
|
* Apply a set filter (exclude values)
|
|
@@ -1807,11 +1852,8 @@ class _ extends x {
|
|
|
1807
1852
|
this.filters.set(e, n), this.cachedResult = null, this.cacheKey = null;
|
|
1808
1853
|
}
|
|
1809
1854
|
// #endregion
|
|
1810
|
-
// #region Styles
|
|
1811
|
-
styles = gt;
|
|
1812
|
-
// #endregion
|
|
1813
1855
|
}
|
|
1814
|
-
function
|
|
1856
|
+
function ye(s) {
|
|
1815
1857
|
if (!s.length) return [];
|
|
1816
1858
|
const e = /* @__PURE__ */ new Map(), t = [], n = (r, l) => {
|
|
1817
1859
|
if (!l.length) return;
|
|
@@ -1846,7 +1888,7 @@ function mt(s) {
|
|
|
1846
1888
|
}, e.set(d, c), t.push(c)), c.columns.push(r);
|
|
1847
1889
|
}), i.length && n(o, i), t.length === 1 && t[0].implicit && t[0].columns.length === s.length ? [] : t;
|
|
1848
1890
|
}
|
|
1849
|
-
function
|
|
1891
|
+
function Ct(s, e, t) {
|
|
1850
1892
|
if (!e.length || !s) return;
|
|
1851
1893
|
const n = /* @__PURE__ */ new Map();
|
|
1852
1894
|
for (const o of e)
|
|
@@ -1862,23 +1904,25 @@ function wt(s, e, t) {
|
|
|
1862
1904
|
l && l.classList.add("group-end");
|
|
1863
1905
|
}
|
|
1864
1906
|
}
|
|
1865
|
-
function
|
|
1907
|
+
function Rt(s, e) {
|
|
1866
1908
|
if (s.length === 0) return null;
|
|
1867
1909
|
const t = document.createElement("div");
|
|
1868
1910
|
t.className = "header-group-row", t.setAttribute("role", "row");
|
|
1869
1911
|
for (const n of s) {
|
|
1870
|
-
const i = n.
|
|
1871
|
-
|
|
1912
|
+
const i = n.columns[0], o = i ? e.findIndex((d) => d.field === i.field) : -1;
|
|
1913
|
+
if (o === -1) continue;
|
|
1914
|
+
const r = String(n.id).startsWith("__implicit__"), l = r ? "" : n.label || n.id, a = document.createElement("div");
|
|
1915
|
+
a.className = "cell header-group-cell", r && a.classList.add("implicit-group"), a.setAttribute("data-group", String(n.id)), a.style.gridColumn = `${o + 1} / span ${n.columns.length}`, a.textContent = l, t.appendChild(a);
|
|
1872
1916
|
}
|
|
1873
1917
|
return t;
|
|
1874
1918
|
}
|
|
1875
|
-
function
|
|
1919
|
+
function Et(s) {
|
|
1876
1920
|
return s.some((e) => e.group != null);
|
|
1877
1921
|
}
|
|
1878
|
-
const
|
|
1879
|
-
class
|
|
1922
|
+
const St = ".header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:4px 8px;font-weight:600;font-size:.9em;text-transform:uppercase;letter-spacing:.5px;border-right:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong))}.header-row .cell.group-end:last-child{border-right:none}.header-group-row.no-borders{border-bottom:none}.header-group-row.no-borders .header-group-cell{border-right:none}.header-row.no-group-borders .cell.group-end{border-right:1px solid var(--tbw-color-border)}";
|
|
1923
|
+
class Vn extends x {
|
|
1880
1924
|
name = "groupingColumns";
|
|
1881
|
-
|
|
1925
|
+
styles = St;
|
|
1882
1926
|
get defaultConfig() {
|
|
1883
1927
|
return {
|
|
1884
1928
|
showGroupBorders: !0
|
|
@@ -1902,7 +1946,7 @@ class Kn extends x {
|
|
|
1902
1946
|
if (t?.columnGroups && Array.isArray(t.columnGroups) && t.columnGroups.length > 0)
|
|
1903
1947
|
return !0;
|
|
1904
1948
|
const n = t?.columns;
|
|
1905
|
-
return Array.isArray(n) ?
|
|
1949
|
+
return Array.isArray(n) ? Et(n) : !1;
|
|
1906
1950
|
}
|
|
1907
1951
|
// #endregion
|
|
1908
1952
|
// #region Hooks
|
|
@@ -1920,27 +1964,29 @@ class Kn extends x {
|
|
|
1920
1964
|
});
|
|
1921
1965
|
} else
|
|
1922
1966
|
n = [...e];
|
|
1923
|
-
const i =
|
|
1967
|
+
const i = ye(n);
|
|
1924
1968
|
return i.length === 0 ? (this.isActive = !1, this.groups = [], n) : (this.isActive = !0, this.groups = i, n);
|
|
1925
1969
|
}
|
|
1926
1970
|
afterRender() {
|
|
1927
|
-
if (!this.isActive
|
|
1928
|
-
const
|
|
1929
|
-
|
|
1971
|
+
if (!this.isActive) {
|
|
1972
|
+
const a = this.shadowRoot?.querySelector(".header")?.querySelector(".header-group-row");
|
|
1973
|
+
a && a.remove();
|
|
1930
1974
|
return;
|
|
1931
1975
|
}
|
|
1932
1976
|
const e = this.shadowRoot?.querySelector(".header");
|
|
1933
1977
|
if (!e) return;
|
|
1934
1978
|
const t = e.querySelector(".header-group-row");
|
|
1935
1979
|
t && t.remove();
|
|
1936
|
-
const n =
|
|
1937
|
-
if (
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
o
|
|
1980
|
+
const n = this.columns, i = ye(n);
|
|
1981
|
+
if (i.length === 0) return;
|
|
1982
|
+
const o = Rt(i, n);
|
|
1983
|
+
if (o) {
|
|
1984
|
+
o.classList.toggle("no-borders", !this.config.showGroupBorders);
|
|
1985
|
+
const l = e.querySelector(".header-row");
|
|
1986
|
+
l ? e.insertBefore(o, l) : e.appendChild(o);
|
|
1941
1987
|
}
|
|
1942
|
-
const
|
|
1943
|
-
|
|
1988
|
+
const r = e.querySelector(".header-row");
|
|
1989
|
+
r && (r.classList.toggle("no-group-borders", !this.config.showGroupBorders), Ct(r, i));
|
|
1944
1990
|
}
|
|
1945
1991
|
// #endregion
|
|
1946
1992
|
// #region Public API
|
|
@@ -1974,11 +2020,8 @@ class Kn extends x {
|
|
|
1974
2020
|
this.requestRender();
|
|
1975
2021
|
}
|
|
1976
2022
|
// #endregion
|
|
1977
|
-
// #region Styles
|
|
1978
|
-
styles = yt;
|
|
1979
|
-
// #endregion
|
|
1980
2023
|
}
|
|
1981
|
-
function
|
|
2024
|
+
function kt({ rows: s, config: e, expanded: t }) {
|
|
1982
2025
|
const n = e.groupOn;
|
|
1983
2026
|
if (typeof n != "function")
|
|
1984
2027
|
return [];
|
|
@@ -1987,10 +2030,10 @@ function xt({ rows: s, config: e, expanded: t }) {
|
|
|
1987
2030
|
let a = n(l);
|
|
1988
2031
|
a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
|
|
1989
2032
|
let d = i;
|
|
1990
|
-
a.forEach((c,
|
|
1991
|
-
const
|
|
1992
|
-
let g = d.children.get(
|
|
1993
|
-
g || (g = { key: f, value: c, depth:
|
|
2033
|
+
a.forEach((c, u) => {
|
|
2034
|
+
const h = c == null ? "∅" : String(c), f = d.key === "__root__" ? h : d.key + "||" + h;
|
|
2035
|
+
let g = d.children.get(h);
|
|
2036
|
+
g || (g = { key: f, value: c, depth: u, rows: [], children: /* @__PURE__ */ new Map(), parent: d }, d.children.set(h, g)), d = g;
|
|
1994
2037
|
}), d.rows.push(l);
|
|
1995
2038
|
}), i.children.size === 1 && i.children.has("__ungrouped__") && i.children.get("__ungrouped__").rows.length === s.length)
|
|
1996
2039
|
return [];
|
|
@@ -2011,26 +2054,26 @@ function xt({ rows: s, config: e, expanded: t }) {
|
|
|
2011
2054
|
};
|
|
2012
2055
|
return r(i), o;
|
|
2013
2056
|
}
|
|
2014
|
-
function
|
|
2057
|
+
function At(s, e) {
|
|
2015
2058
|
const t = new Set(s);
|
|
2016
2059
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
2017
2060
|
}
|
|
2018
|
-
function
|
|
2061
|
+
function _t(s) {
|
|
2019
2062
|
const e = /* @__PURE__ */ new Set();
|
|
2020
2063
|
for (const t of s)
|
|
2021
2064
|
t.kind === "group" && e.add(t.key);
|
|
2022
2065
|
return e;
|
|
2023
2066
|
}
|
|
2024
|
-
function
|
|
2067
|
+
function Lt() {
|
|
2025
2068
|
return /* @__PURE__ */ new Set();
|
|
2026
2069
|
}
|
|
2027
|
-
function
|
|
2070
|
+
function Tt(s) {
|
|
2028
2071
|
return s.kind !== "group" ? 0 : s.rows.length;
|
|
2029
2072
|
}
|
|
2030
|
-
const
|
|
2031
|
-
class
|
|
2073
|
+
const It = '.group-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));font-weight:500;border-bottom:var(--tbw-row-divider);min-height:var(--tbw-row-height)}.group-row .cell{display:flex;align-items:center;padding:var(--tbw-cell-padding, 2px 8px)}.group-row:hover{background:var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover))}.group-toggle{cursor:pointer;user-select:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:4px;background:none;border:0;font:inherit}.group-toggle:hover{background:var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));border-radius:2px}.group-label{display:inline-flex;align-items:center;gap:8px}.group-count{color:var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));font-size:.85em;font-weight:400}[data-group-depth="0"] .group-label{padding-left:0}[data-group-depth="1"] .group-label{padding-left:20px}[data-group-depth="2"] .group-label{padding-left:40px}[data-group-depth="3"] .group-label{padding-left:60px}[data-group-depth="4"] .group-label{padding-left:80px}.data-grid-row.tbw-group-slide-in{animation:tbw-group-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-group-fade-in{animation:tbw-group-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-group-fade-in{0%{opacity:0}to{opacity:1}}';
|
|
2074
|
+
class zn extends x {
|
|
2032
2075
|
name = "groupingRows";
|
|
2033
|
-
|
|
2076
|
+
styles = It;
|
|
2034
2077
|
get defaultConfig() {
|
|
2035
2078
|
return {
|
|
2036
2079
|
defaultExpanded: !1,
|
|
@@ -2048,15 +2091,12 @@ class Nn extends x {
|
|
|
2048
2091
|
keysToAnimate = /* @__PURE__ */ new Set();
|
|
2049
2092
|
// #endregion
|
|
2050
2093
|
// #region Animation
|
|
2094
|
+
/**
|
|
2095
|
+
* Get expand/collapse animation style from plugin config.
|
|
2096
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
2097
|
+
*/
|
|
2051
2098
|
get animationStyle() {
|
|
2052
|
-
|
|
2053
|
-
if (t === !1 || t === "off") return !1;
|
|
2054
|
-
if (t !== !0 && t !== "on") {
|
|
2055
|
-
const n = this.shadowRoot?.host;
|
|
2056
|
-
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
2057
|
-
return !1;
|
|
2058
|
-
}
|
|
2059
|
-
return this.config.animation ?? "slide";
|
|
2099
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
2060
2100
|
}
|
|
2061
2101
|
// #endregion
|
|
2062
2102
|
// #region Lifecycle
|
|
@@ -2076,7 +2116,7 @@ class Nn extends x {
|
|
|
2076
2116
|
const t = this.config;
|
|
2077
2117
|
if (typeof t.groupOn != "function")
|
|
2078
2118
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
2079
|
-
const n =
|
|
2119
|
+
const n = kt({
|
|
2080
2120
|
rows: [...e],
|
|
2081
2121
|
config: t,
|
|
2082
2122
|
expanded: this.expandedKeys
|
|
@@ -2097,7 +2137,7 @@ class Nn extends x {
|
|
|
2097
2137
|
__groupDepth: o.depth,
|
|
2098
2138
|
__groupRows: o.rows,
|
|
2099
2139
|
__groupExpanded: o.expanded,
|
|
2100
|
-
__groupRowCount:
|
|
2140
|
+
__groupRowCount: Tt(o)
|
|
2101
2141
|
} : o.row);
|
|
2102
2142
|
}
|
|
2103
2143
|
onCellClick(e) {
|
|
@@ -2105,6 +2145,12 @@ class Nn extends x {
|
|
|
2105
2145
|
if (t?.__isGroupRow && e.originalEvent.target?.closest(".group-toggle"))
|
|
2106
2146
|
return this.toggle(t.__groupKey), !0;
|
|
2107
2147
|
}
|
|
2148
|
+
onKeyDown(e) {
|
|
2149
|
+
if (e.key !== " ") return;
|
|
2150
|
+
const t = this.grid._focusRow, n = this.rows[t];
|
|
2151
|
+
if (n?.__isGroupRow)
|
|
2152
|
+
return e.preventDefault(), this.toggle(n.__groupKey), this.requestRenderWithFocus(), !0;
|
|
2153
|
+
}
|
|
2108
2154
|
/**
|
|
2109
2155
|
* Render a row. Returns true if we handled the row (group row), false otherwise.
|
|
2110
2156
|
*/
|
|
@@ -2124,12 +2170,12 @@ class Nn extends x {
|
|
|
2124
2170
|
toggleExpand: l
|
|
2125
2171
|
});
|
|
2126
2172
|
if (a)
|
|
2127
|
-
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), typeof a == "string" ? t.innerHTML = a : (t.innerHTML = "", t.appendChild(a)), !0;
|
|
2173
|
+
return t.className = "data-grid-row group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), typeof a == "string" ? t.innerHTML = a : (t.innerHTML = "", t.appendChild(a)), !0;
|
|
2128
2174
|
}
|
|
2129
2175
|
const o = () => {
|
|
2130
2176
|
this.toggle(e.__groupKey);
|
|
2131
2177
|
};
|
|
2132
|
-
return t.className = "group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), t.setAttribute("role", "row"), t.setAttribute("aria-expanded", String(e.__groupExpanded)), t.style.paddingLeft = `${(e.__groupDepth || 0) * (i.indentWidth ?? 20)}px`, t.innerHTML = "", i.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, o) : this.renderPerColumnGroupRow(e, t, o), !0;
|
|
2178
|
+
return t.className = "data-grid-row group-row", t.__isCustomRow = !0, t.setAttribute("data-group-depth", String(e.__groupDepth)), t.setAttribute("role", "row"), t.setAttribute("aria-expanded", String(e.__groupExpanded)), t.style.paddingLeft = `${(e.__groupDepth || 0) * (i.indentWidth ?? 20)}px`, t.innerHTML = "", i.fullWidth !== !1 ? this.renderFullWidthGroupRow(e, t, o) : this.renderPerColumnGroupRow(e, t, o), !0;
|
|
2133
2179
|
}
|
|
2134
2180
|
afterRender() {
|
|
2135
2181
|
const e = this.animationStyle;
|
|
@@ -2145,52 +2191,63 @@ class Nn extends x {
|
|
|
2145
2191
|
}
|
|
2146
2192
|
// #endregion
|
|
2147
2193
|
// #region Private Rendering Helpers
|
|
2194
|
+
/**
|
|
2195
|
+
* Create a toggle button for expanding/collapsing a group.
|
|
2196
|
+
*/
|
|
2197
|
+
createToggleButton(e, t) {
|
|
2198
|
+
const n = document.createElement("button");
|
|
2199
|
+
return n.type = "button", n.className = `group-toggle${e ? " expanded" : ""}`, n.setAttribute("aria-label", e ? "Collapse group" : "Expand group"), this.setIcon(n, this.resolveIcon(e ? "collapse" : "expand")), n.addEventListener("click", (i) => {
|
|
2200
|
+
i.stopPropagation(), t();
|
|
2201
|
+
}), n;
|
|
2202
|
+
}
|
|
2203
|
+
/**
|
|
2204
|
+
* Get the formatted label text for a group.
|
|
2205
|
+
*/
|
|
2206
|
+
getGroupLabelText(e, t, n) {
|
|
2207
|
+
const i = this.config;
|
|
2208
|
+
return i.formatLabel ? i.formatLabel(e, t, n) : String(e);
|
|
2209
|
+
}
|
|
2148
2210
|
renderFullWidthGroupRow(e, t, n) {
|
|
2149
2211
|
const i = this.config, o = document.createElement("div");
|
|
2150
|
-
o.className = "cell group-full", o.style.gridColumn = "1 / -1", o.setAttribute("role", "gridcell");
|
|
2151
|
-
const r = document.createElement("
|
|
2152
|
-
r.
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
const l = document.createElement("span");
|
|
2156
|
-
l.className = "group-label";
|
|
2157
|
-
const a = i.formatLabel ? i.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
2158
|
-
if (l.textContent = a, o.appendChild(l), i.showRowCount !== !1) {
|
|
2159
|
-
const d = document.createElement("span");
|
|
2160
|
-
d.className = "group-count", d.textContent = `(${e.__groupRowCount ?? e.__groupRows?.length ?? 0})`, o.appendChild(d);
|
|
2212
|
+
o.className = "cell group-full", o.style.gridColumn = "1 / -1", o.setAttribute("role", "gridcell"), o.setAttribute("data-col", "0"), o.appendChild(this.createToggleButton(e.__groupExpanded, n));
|
|
2213
|
+
const r = document.createElement("span");
|
|
2214
|
+
if (r.className = "group-label", r.textContent = this.getGroupLabelText(e.__groupValue, e.__groupDepth || 0, e.__groupKey), o.appendChild(r), i.showRowCount !== !1) {
|
|
2215
|
+
const l = document.createElement("span");
|
|
2216
|
+
l.className = "group-count", l.textContent = `(${e.__groupRowCount ?? e.__groupRows?.length ?? 0})`, o.appendChild(l);
|
|
2161
2217
|
}
|
|
2162
2218
|
t.appendChild(o);
|
|
2163
2219
|
}
|
|
2164
2220
|
renderPerColumnGroupRow(e, t, n) {
|
|
2165
2221
|
const i = this.config, o = i.aggregators ?? {}, r = this.columns, l = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
|
|
2166
|
-
d && (t.style.display = "grid", t.style.gridTemplateColumns = d)
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
if (u.appendChild(g), i.showRowCount !== !1) {
|
|
2182
|
-
const w = document.createElement("span");
|
|
2183
|
-
w.className = "group-count", w.textContent = ` (${l.length})`, u.appendChild(w);
|
|
2184
|
-
}
|
|
2222
|
+
d && (t.style.display = "grid", t.style.gridTemplateColumns = d);
|
|
2223
|
+
let c = !1;
|
|
2224
|
+
r.forEach((u, h) => {
|
|
2225
|
+
const f = document.createElement("div");
|
|
2226
|
+
if (f.className = "cell group-cell", f.setAttribute("data-col", String(h)), f.setAttribute("role", "gridcell"), ie(u)) {
|
|
2227
|
+
f.setAttribute("data-field", u.field), t.appendChild(f);
|
|
2228
|
+
return;
|
|
2229
|
+
}
|
|
2230
|
+
if (c) {
|
|
2231
|
+
const g = o[u.field];
|
|
2232
|
+
if (g) {
|
|
2233
|
+
const p = de(g, l, u.field, u);
|
|
2234
|
+
f.textContent = p != null ? String(p) : "";
|
|
2235
|
+
} else
|
|
2236
|
+
f.textContent = "";
|
|
2185
2237
|
} else {
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2238
|
+
c = !0, f.appendChild(this.createToggleButton(e.__groupExpanded, n));
|
|
2239
|
+
const g = document.createElement("span"), p = o[u.field];
|
|
2240
|
+
if (p) {
|
|
2241
|
+
const b = de(p, l, u.field, u);
|
|
2242
|
+
g.textContent = b != null ? String(b) : String(e.__groupValue);
|
|
2190
2243
|
} else
|
|
2191
|
-
|
|
2244
|
+
g.textContent = this.getGroupLabelText(e.__groupValue, e.__groupDepth || 0, e.__groupKey);
|
|
2245
|
+
if (f.appendChild(g), i.showRowCount !== !1) {
|
|
2246
|
+
const b = document.createElement("span");
|
|
2247
|
+
b.className = "group-count", b.textContent = ` (${l.length})`, f.appendChild(b);
|
|
2248
|
+
}
|
|
2192
2249
|
}
|
|
2193
|
-
t.appendChild(
|
|
2250
|
+
t.appendChild(f);
|
|
2194
2251
|
});
|
|
2195
2252
|
}
|
|
2196
2253
|
// #endregion
|
|
@@ -2199,20 +2256,20 @@ class Nn extends x {
|
|
|
2199
2256
|
* Expand all groups.
|
|
2200
2257
|
*/
|
|
2201
2258
|
expandAll() {
|
|
2202
|
-
this.expandedKeys =
|
|
2259
|
+
this.expandedKeys = _t(this.flattenedRows), this.requestRender();
|
|
2203
2260
|
}
|
|
2204
2261
|
/**
|
|
2205
2262
|
* Collapse all groups.
|
|
2206
2263
|
*/
|
|
2207
2264
|
collapseAll() {
|
|
2208
|
-
this.expandedKeys =
|
|
2265
|
+
this.expandedKeys = Lt(), this.requestRender();
|
|
2209
2266
|
}
|
|
2210
2267
|
/**
|
|
2211
2268
|
* Toggle expansion of a specific group.
|
|
2212
2269
|
* @param key - The group key to toggle
|
|
2213
2270
|
*/
|
|
2214
2271
|
toggle(e) {
|
|
2215
|
-
this.expandedKeys =
|
|
2272
|
+
this.expandedKeys = At(this.expandedKeys, e);
|
|
2216
2273
|
const t = this.flattenedRows.find((n) => n.kind === "group" && n.key === e);
|
|
2217
2274
|
this.emit("group-toggle", {
|
|
2218
2275
|
key: e,
|
|
@@ -2302,26 +2359,23 @@ class Nn extends x {
|
|
|
2302
2359
|
this.config.groupOn = e, this.requestRender();
|
|
2303
2360
|
}
|
|
2304
2361
|
// #endregion
|
|
2305
|
-
// #region Styles
|
|
2306
|
-
styles = kt;
|
|
2307
|
-
// #endregion
|
|
2308
2362
|
}
|
|
2309
|
-
function
|
|
2363
|
+
function xe(s, e) {
|
|
2310
2364
|
const t = new Set(s);
|
|
2311
2365
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
2312
2366
|
}
|
|
2313
|
-
function
|
|
2367
|
+
function Ft(s, e) {
|
|
2314
2368
|
const t = new Set(s);
|
|
2315
2369
|
return t.add(e), t;
|
|
2316
2370
|
}
|
|
2317
|
-
function
|
|
2371
|
+
function Mt(s, e) {
|
|
2318
2372
|
const t = new Set(s);
|
|
2319
2373
|
return t.delete(e), t;
|
|
2320
2374
|
}
|
|
2321
|
-
function
|
|
2375
|
+
function Pt(s, e) {
|
|
2322
2376
|
return s.has(e);
|
|
2323
2377
|
}
|
|
2324
|
-
function
|
|
2378
|
+
function Dt(s, e, t, n) {
|
|
2325
2379
|
const i = document.createElement("div");
|
|
2326
2380
|
i.className = "master-detail-row", i.setAttribute("data-detail-for", String(e)), i.setAttribute("role", "row");
|
|
2327
2381
|
const o = document.createElement("div");
|
|
@@ -2329,10 +2383,10 @@ function Tt(s, e, t, n) {
|
|
|
2329
2383
|
const r = t(s, e);
|
|
2330
2384
|
return typeof r == "string" ? o.innerHTML = r : r instanceof HTMLElement && o.appendChild(r), i.appendChild(o), i;
|
|
2331
2385
|
}
|
|
2332
|
-
const
|
|
2333
|
-
class
|
|
2386
|
+
const Kt = ".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;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}}";
|
|
2387
|
+
class Ge extends x {
|
|
2334
2388
|
name = "masterDetail";
|
|
2335
|
-
|
|
2389
|
+
styles = Kt;
|
|
2336
2390
|
get defaultConfig() {
|
|
2337
2391
|
return {
|
|
2338
2392
|
detailHeight: "auto",
|
|
@@ -2380,50 +2434,29 @@ class Dn extends x {
|
|
|
2380
2434
|
if (!t) return;
|
|
2381
2435
|
const n = e;
|
|
2382
2436
|
if (n.__frameworkAdapter?.parseDetailElement) {
|
|
2383
|
-
const
|
|
2384
|
-
if (
|
|
2385
|
-
this.config = { ...this.config, detailRenderer:
|
|
2437
|
+
const u = n.__frameworkAdapter.parseDetailElement(t);
|
|
2438
|
+
if (u) {
|
|
2439
|
+
this.config = { ...this.config, detailRenderer: u };
|
|
2386
2440
|
return;
|
|
2387
2441
|
}
|
|
2388
2442
|
}
|
|
2389
2443
|
const i = t.getAttribute("animation"), o = t.getAttribute("show-expand-column"), r = t.getAttribute("expand-on-row-click"), l = t.getAttribute("collapse-on-click-outside"), a = t.getAttribute("height"), d = {};
|
|
2390
2444
|
i !== null && (d.animation = i === "false" ? !1 : i), o !== null && (d.showExpandColumn = o !== "false"), r !== null && (d.expandOnRowClick = r === "true"), l !== null && (d.collapseOnClickOutside = l === "true"), a !== null && (d.detailHeight = a === "auto" ? "auto" : parseInt(a, 10));
|
|
2391
2445
|
const c = t.innerHTML.trim();
|
|
2392
|
-
c && !this.config.detailRenderer && (d.detailRenderer = (
|
|
2393
|
-
const f =
|
|
2394
|
-
return
|
|
2446
|
+
c && !this.config.detailRenderer && (d.detailRenderer = (u, h) => {
|
|
2447
|
+
const f = je(c, { value: u, row: u });
|
|
2448
|
+
return Ue(f);
|
|
2395
2449
|
}), Object.keys(d).length > 0 && (this.config = { ...this.config, ...d });
|
|
2396
2450
|
}
|
|
2397
2451
|
// #endregion
|
|
2398
2452
|
// #region Animation Helpers
|
|
2399
|
-
/**
|
|
2400
|
-
* Check if animations are enabled at the grid level.
|
|
2401
|
-
* Respects gridConfig.animation.mode and CSS variable.
|
|
2402
|
-
*/
|
|
2403
|
-
get isAnimationEnabled() {
|
|
2404
|
-
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
2405
|
-
if (t === !1 || t === "off") return !1;
|
|
2406
|
-
if (t === !0 || t === "on") return !0;
|
|
2407
|
-
const n = this.shadowRoot?.host;
|
|
2408
|
-
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
2409
|
-
}
|
|
2410
2453
|
/**
|
|
2411
2454
|
* Get expand/collapse animation style from plugin config.
|
|
2455
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
2412
2456
|
*/
|
|
2413
2457
|
get animationStyle() {
|
|
2414
2458
|
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
2415
2459
|
}
|
|
2416
|
-
/**
|
|
2417
|
-
* Get animation duration from CSS variable (set by grid).
|
|
2418
|
-
*/
|
|
2419
|
-
get animationDuration() {
|
|
2420
|
-
const e = this.shadowRoot?.host;
|
|
2421
|
-
if (e) {
|
|
2422
|
-
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
2423
|
-
if (!isNaN(n)) return n;
|
|
2424
|
-
}
|
|
2425
|
-
return 200;
|
|
2426
|
-
}
|
|
2427
2460
|
/**
|
|
2428
2461
|
* Apply expand animation to a detail element.
|
|
2429
2462
|
*/
|
|
@@ -2454,6 +2487,25 @@ class Dn extends x {
|
|
|
2454
2487
|
// #region Internal State
|
|
2455
2488
|
expandedRows = /* @__PURE__ */ new Set();
|
|
2456
2489
|
detailElements = /* @__PURE__ */ new Map();
|
|
2490
|
+
/** Default height for detail rows when not configured */
|
|
2491
|
+
static DEFAULT_DETAIL_HEIGHT = 150;
|
|
2492
|
+
/**
|
|
2493
|
+
* Get the estimated height for a detail row.
|
|
2494
|
+
*/
|
|
2495
|
+
getDetailHeight(e) {
|
|
2496
|
+
const t = this.detailElements.get(e);
|
|
2497
|
+
return t ? t.offsetHeight : typeof this.config?.detailHeight == "number" ? this.config.detailHeight : Ge.DEFAULT_DETAIL_HEIGHT;
|
|
2498
|
+
}
|
|
2499
|
+
/**
|
|
2500
|
+
* Toggle a row's detail and emit event.
|
|
2501
|
+
*/
|
|
2502
|
+
toggleAndEmit(e, t) {
|
|
2503
|
+
this.expandedRows = xe(this.expandedRows, e), this.emit("detail-expand", {
|
|
2504
|
+
rowIndex: t,
|
|
2505
|
+
row: e,
|
|
2506
|
+
expanded: this.expandedRows.has(e)
|
|
2507
|
+
}), this.requestRender();
|
|
2508
|
+
}
|
|
2457
2509
|
// #endregion
|
|
2458
2510
|
// #region Lifecycle
|
|
2459
2511
|
detach() {
|
|
@@ -2462,49 +2514,36 @@ class Dn extends x {
|
|
|
2462
2514
|
// #endregion
|
|
2463
2515
|
// #region Hooks
|
|
2464
2516
|
processColumns(e) {
|
|
2465
|
-
if (!this.config.detailRenderer)
|
|
2517
|
+
if (!this.config.detailRenderer || this.config.showExpandColumn === !1)
|
|
2466
2518
|
return [...e];
|
|
2467
2519
|
const t = [...e];
|
|
2468
|
-
if (t
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
const o = (r)
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
const u = document.createElement("span");
|
|
2478
|
-
if (i) {
|
|
2479
|
-
const f = i(r);
|
|
2480
|
-
f instanceof Node ? u.appendChild(f) : u.textContent = String(f ?? l ?? "");
|
|
2481
|
-
} else
|
|
2482
|
-
u.textContent = String(l ?? "");
|
|
2483
|
-
return c.appendChild(u), c;
|
|
2484
|
-
};
|
|
2485
|
-
o.__masterDetailWrapped = !0, n.viewRenderer = o, t[0] = n;
|
|
2486
|
-
}
|
|
2487
|
-
return t;
|
|
2520
|
+
if (Qe(t))
|
|
2521
|
+
return t;
|
|
2522
|
+
const i = et(this.name);
|
|
2523
|
+
return i.viewRenderer = (o) => {
|
|
2524
|
+
const { row: r } = o, l = this.expandedRows.has(r), a = document.createElement("span");
|
|
2525
|
+
a.className = "master-detail-expander expander-cell";
|
|
2526
|
+
const d = document.createElement("span");
|
|
2527
|
+
return d.className = `master-detail-toggle${l ? " expanded" : ""}`, this.setIcon(d, this.resolveIcon(l ? "collapse" : "expand")), d.setAttribute("role", "button"), d.setAttribute("tabindex", "0"), d.setAttribute("aria-expanded", String(l)), d.setAttribute("aria-label", l ? "Collapse details" : "Expand details"), a.appendChild(d), a;
|
|
2528
|
+
}, [i, ...t];
|
|
2488
2529
|
}
|
|
2489
2530
|
onRowClick(e) {
|
|
2490
2531
|
if (!(!this.config.expandOnRowClick || !this.config.detailRenderer))
|
|
2491
|
-
return this.
|
|
2492
|
-
rowIndex: e.rowIndex,
|
|
2493
|
-
row: e.row,
|
|
2494
|
-
expanded: this.expandedRows.has(e.row)
|
|
2495
|
-
}), this.requestRender(), !1;
|
|
2532
|
+
return this.toggleAndEmit(e.row, e.rowIndex), !1;
|
|
2496
2533
|
}
|
|
2497
2534
|
onCellClick(e) {
|
|
2498
|
-
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
2499
|
-
|
|
2500
|
-
return this.expandedRows = Z(this.expandedRows, n), this.emit("detail-expand", {
|
|
2501
|
-
rowIndex: i,
|
|
2502
|
-
row: n,
|
|
2503
|
-
expanded: this.expandedRows.has(n)
|
|
2504
|
-
}), this.requestRender(), !0;
|
|
2505
|
-
}
|
|
2535
|
+
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
2536
|
+
return this.toggleAndEmit(e.row, e.rowIndex), !0;
|
|
2506
2537
|
this.expandedRows.size > 0 && queueMicrotask(() => this.#e());
|
|
2507
2538
|
}
|
|
2539
|
+
onKeyDown(e) {
|
|
2540
|
+
if (e.key !== " ") return;
|
|
2541
|
+
const t = this.grid._focusCol, n = this.grid._focusRow, i = this.columns[t];
|
|
2542
|
+
if (!i || !ie(i)) return;
|
|
2543
|
+
const o = this.rows[n];
|
|
2544
|
+
if (o)
|
|
2545
|
+
return e.preventDefault(), this.toggleAndEmit(o, n), this.requestRenderWithFocus(), !0;
|
|
2546
|
+
}
|
|
2508
2547
|
afterRender() {
|
|
2509
2548
|
this.#e();
|
|
2510
2549
|
}
|
|
@@ -2541,7 +2580,7 @@ class Dn extends x {
|
|
|
2541
2580
|
d.previousElementSibling !== l && l.after(d);
|
|
2542
2581
|
continue;
|
|
2543
2582
|
}
|
|
2544
|
-
const c =
|
|
2583
|
+
const c = Dt(a, r, this.config.detailRenderer, i);
|
|
2545
2584
|
typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c), this.animateExpand(c);
|
|
2546
2585
|
}
|
|
2547
2586
|
}
|
|
@@ -2551,15 +2590,8 @@ class Dn extends x {
|
|
|
2551
2590
|
*/
|
|
2552
2591
|
getExtraHeight() {
|
|
2553
2592
|
let e = 0;
|
|
2554
|
-
for (const t of this.expandedRows)
|
|
2555
|
-
|
|
2556
|
-
if (n)
|
|
2557
|
-
e += n.offsetHeight;
|
|
2558
|
-
else {
|
|
2559
|
-
const i = this.config?.detailHeight;
|
|
2560
|
-
e += typeof i == "number" ? i : 150;
|
|
2561
|
-
}
|
|
2562
|
-
}
|
|
2593
|
+
for (const t of this.expandedRows)
|
|
2594
|
+
e += this.getDetailHeight(t);
|
|
2563
2595
|
return e;
|
|
2564
2596
|
}
|
|
2565
2597
|
/**
|
|
@@ -2570,15 +2602,7 @@ class Dn extends x {
|
|
|
2570
2602
|
let t = 0;
|
|
2571
2603
|
for (const n of this.expandedRows) {
|
|
2572
2604
|
const i = this.rows.indexOf(n);
|
|
2573
|
-
|
|
2574
|
-
const o = this.detailElements.get(n);
|
|
2575
|
-
if (o)
|
|
2576
|
-
t += o.offsetHeight;
|
|
2577
|
-
else {
|
|
2578
|
-
const r = this.config?.detailHeight;
|
|
2579
|
-
t += typeof r == "number" ? r : 150;
|
|
2580
|
-
}
|
|
2581
|
-
}
|
|
2605
|
+
i >= 0 && i < e && (t += this.getDetailHeight(n));
|
|
2582
2606
|
}
|
|
2583
2607
|
return t;
|
|
2584
2608
|
}
|
|
@@ -2596,8 +2620,8 @@ class Dn extends x {
|
|
|
2596
2620
|
i.sort((l, a) => l.index - a.index);
|
|
2597
2621
|
let o = e, r = 0;
|
|
2598
2622
|
for (const { index: l, row: a } of i) {
|
|
2599
|
-
const d = l * n + r,
|
|
2600
|
-
r +=
|
|
2623
|
+
const d = l * n + r, c = this.getDetailHeight(a), u = d + n + c;
|
|
2624
|
+
r += c, !(l >= e) && u > t && l < o && (o = l);
|
|
2601
2625
|
}
|
|
2602
2626
|
return o;
|
|
2603
2627
|
}
|
|
@@ -2609,7 +2633,7 @@ class Dn extends x {
|
|
|
2609
2633
|
*/
|
|
2610
2634
|
expand(e) {
|
|
2611
2635
|
const t = this.rows[e];
|
|
2612
|
-
t && (this.expandedRows =
|
|
2636
|
+
t && (this.expandedRows = Ft(this.expandedRows, t), this.requestRender());
|
|
2613
2637
|
}
|
|
2614
2638
|
/**
|
|
2615
2639
|
* Collapse the detail row at the given index.
|
|
@@ -2617,7 +2641,7 @@ class Dn extends x {
|
|
|
2617
2641
|
*/
|
|
2618
2642
|
collapse(e) {
|
|
2619
2643
|
const t = this.rows[e];
|
|
2620
|
-
t && (this.expandedRows =
|
|
2644
|
+
t && (this.expandedRows = Mt(this.expandedRows, t), this.requestRender());
|
|
2621
2645
|
}
|
|
2622
2646
|
/**
|
|
2623
2647
|
* Toggle the detail row at the given index.
|
|
@@ -2625,7 +2649,7 @@ class Dn extends x {
|
|
|
2625
2649
|
*/
|
|
2626
2650
|
toggle(e) {
|
|
2627
2651
|
const t = this.rows[e];
|
|
2628
|
-
t && (this.expandedRows =
|
|
2652
|
+
t && (this.expandedRows = xe(this.expandedRows, t), this.requestRender());
|
|
2629
2653
|
}
|
|
2630
2654
|
/**
|
|
2631
2655
|
* Check if the detail row at the given index is expanded.
|
|
@@ -2634,7 +2658,7 @@ class Dn extends x {
|
|
|
2634
2658
|
*/
|
|
2635
2659
|
isExpanded(e) {
|
|
2636
2660
|
const t = this.rows[e];
|
|
2637
|
-
return t ?
|
|
2661
|
+
return t ? Pt(this.expandedRows, t) : !1;
|
|
2638
2662
|
}
|
|
2639
2663
|
/**
|
|
2640
2664
|
* Expand all detail rows.
|
|
@@ -2686,24 +2710,21 @@ class Dn extends x {
|
|
|
2686
2710
|
}
|
|
2687
2711
|
}
|
|
2688
2712
|
// #endregion
|
|
2689
|
-
// #region Styles
|
|
2690
|
-
styles = It;
|
|
2691
|
-
// #endregion
|
|
2692
2713
|
}
|
|
2693
|
-
function
|
|
2714
|
+
function qt(s, e, t) {
|
|
2694
2715
|
return e.length ? [...s].sort((n, i) => {
|
|
2695
2716
|
for (const o of e) {
|
|
2696
|
-
const l = t.find((
|
|
2717
|
+
const l = t.find((u) => u.field === o.field)?.sortComparator ?? Nt, a = n[o.field], d = i[o.field], c = l(a, d, n, i);
|
|
2697
2718
|
if (c !== 0)
|
|
2698
2719
|
return o.direction === "asc" ? c : -c;
|
|
2699
2720
|
}
|
|
2700
2721
|
return 0;
|
|
2701
2722
|
}) : [...s];
|
|
2702
2723
|
}
|
|
2703
|
-
function
|
|
2724
|
+
function Nt(s, e) {
|
|
2704
2725
|
return s == null && e == null ? 0 : s == null ? 1 : e == null ? -1 : typeof s == "number" && typeof e == "number" ? s - e : s instanceof Date && e instanceof Date ? s.getTime() - e.getTime() : typeof s == "boolean" && typeof e == "boolean" ? s === e ? 0 : s ? -1 : 1 : String(s).localeCompare(String(e));
|
|
2705
2726
|
}
|
|
2706
|
-
function
|
|
2727
|
+
function Ht(s, e, t, n) {
|
|
2707
2728
|
const i = s.find((o) => o.field === e);
|
|
2708
2729
|
return t ? i ? i.direction === "asc" ? s.map((o) => o.field === e ? { ...o, direction: "desc" } : o) : s.filter((o) => o.field !== e) : s.length < n ? [...s, { field: e, direction: "asc" }] : s : i?.direction === "asc" ? [{ field: e, direction: "desc" }] : i?.direction === "desc" ? [] : [{ field: e, direction: "asc" }];
|
|
2709
2730
|
}
|
|
@@ -2714,10 +2735,10 @@ function Ce(s, e) {
|
|
|
2714
2735
|
function Re(s, e) {
|
|
2715
2736
|
return s.find((t) => t.field === e)?.direction;
|
|
2716
2737
|
}
|
|
2717
|
-
const
|
|
2718
|
-
class
|
|
2738
|
+
const Ot = '.header-cell[data-sort=asc]:after{content:"↑";margin-left:4px;opacity:.8}.header-cell[data-sort=desc]:after{content:"↓";margin-left:4px;opacity:.8}.sort-indicator{margin-left:4px;opacity:.8}.sort-index{font-size:10px;background:var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));color:var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));border-radius:50%;width:14px;height:14px;display:inline-flex;align-items:center;justify-content:center;margin-left:2px;font-weight:600}';
|
|
2739
|
+
class Wn extends x {
|
|
2719
2740
|
name = "multiSort";
|
|
2720
|
-
|
|
2741
|
+
styles = Ot;
|
|
2721
2742
|
get defaultConfig() {
|
|
2722
2743
|
return {
|
|
2723
2744
|
maxSortColumns: 3,
|
|
@@ -2734,12 +2755,12 @@ class Hn extends x {
|
|
|
2734
2755
|
// #endregion
|
|
2735
2756
|
// #region Hooks
|
|
2736
2757
|
processRows(e) {
|
|
2737
|
-
return this.sortModel.length === 0 ? [...e] :
|
|
2758
|
+
return this.sortModel.length === 0 ? [...e] : qt([...e], this.sortModel, [...this.columns]);
|
|
2738
2759
|
}
|
|
2739
2760
|
onHeaderClick(e) {
|
|
2740
2761
|
if (!this.columns.find((o) => o.field === e.field)?.sortable) return !1;
|
|
2741
2762
|
const n = e.originalEvent.shiftKey, i = this.config.maxSortColumns ?? 3;
|
|
2742
|
-
return this.sortModel =
|
|
2763
|
+
return this.sortModel = Ht(this.sortModel, e.field, n, i), this.emit("sort-change", { sortModel: [...this.sortModel] }), this.requestRender(), !0;
|
|
2743
2764
|
}
|
|
2744
2765
|
afterRender() {
|
|
2745
2766
|
const e = this.shadowRoot;
|
|
@@ -2753,7 +2774,7 @@ class Hn extends x {
|
|
|
2753
2774
|
i.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove(), i.setAttribute("data-sort", l);
|
|
2754
2775
|
const c = document.createElement("span");
|
|
2755
2776
|
c.className = "sort-indicator", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc"));
|
|
2756
|
-
const
|
|
2777
|
+
const u = i.querySelector(".tbw-filter-btn"), h = i.querySelector(".resize-handle"), f = u ?? h;
|
|
2757
2778
|
if (f ? i.insertBefore(c, f) : i.appendChild(c), t && this.sortModel.length > 1 && r !== void 0) {
|
|
2758
2779
|
const g = document.createElement("span");
|
|
2759
2780
|
g.className = "sort-index", g.textContent = String(r), c.nextSibling ? i.insertBefore(g, c.nextSibling) : i.appendChild(g);
|
|
@@ -2830,14 +2851,11 @@ class Hn extends x {
|
|
|
2830
2851
|
n !== -1 ? this.sortModel[n] = i : this.sortModel.splice(t.sort.priority, 0, i);
|
|
2831
2852
|
}
|
|
2832
2853
|
// #endregion
|
|
2833
|
-
// #region Styles
|
|
2834
|
-
styles = qt;
|
|
2835
|
-
// #endregion
|
|
2836
2854
|
}
|
|
2837
|
-
function
|
|
2855
|
+
function Gt(s) {
|
|
2838
2856
|
return s.filter((e) => e.sticky === "left");
|
|
2839
2857
|
}
|
|
2840
|
-
function
|
|
2858
|
+
function Bt(s) {
|
|
2841
2859
|
return s.filter((e) => e.sticky === "right");
|
|
2842
2860
|
}
|
|
2843
2861
|
function X(s) {
|
|
@@ -2876,9 +2894,8 @@ function Se(s) {
|
|
|
2876
2894
|
n.classList.remove("sticky-left", "sticky-right"), n.style.position = "", n.style.left = "", n.style.right = "";
|
|
2877
2895
|
});
|
|
2878
2896
|
}
|
|
2879
|
-
class
|
|
2897
|
+
class $n extends x {
|
|
2880
2898
|
name = "pinnedColumns";
|
|
2881
|
-
version = "1.0.0";
|
|
2882
2899
|
get defaultConfig() {
|
|
2883
2900
|
return {};
|
|
2884
2901
|
}
|
|
@@ -2922,7 +2939,7 @@ class On extends x {
|
|
|
2922
2939
|
*/
|
|
2923
2940
|
onPluginQuery(e) {
|
|
2924
2941
|
switch (e.type) {
|
|
2925
|
-
case
|
|
2942
|
+
case He.CAN_MOVE_COLUMN: {
|
|
2926
2943
|
const t = e.context, n = t.sticky;
|
|
2927
2944
|
if (n === "left" || n === "right")
|
|
2928
2945
|
return !1;
|
|
@@ -2947,14 +2964,14 @@ class On extends x {
|
|
|
2947
2964
|
*/
|
|
2948
2965
|
getLeftPinnedColumns() {
|
|
2949
2966
|
const e = [...this.columns];
|
|
2950
|
-
return
|
|
2967
|
+
return Gt(e);
|
|
2951
2968
|
}
|
|
2952
2969
|
/**
|
|
2953
2970
|
* Get columns pinned to the right.
|
|
2954
2971
|
*/
|
|
2955
2972
|
getRightPinnedColumns() {
|
|
2956
2973
|
const e = [...this.columns];
|
|
2957
|
-
return
|
|
2974
|
+
return Bt(e);
|
|
2958
2975
|
}
|
|
2959
2976
|
/**
|
|
2960
2977
|
* Clear all sticky positioning.
|
|
@@ -2988,10 +3005,10 @@ class On extends x {
|
|
|
2988
3005
|
}
|
|
2989
3006
|
// #endregion
|
|
2990
3007
|
}
|
|
2991
|
-
function
|
|
3008
|
+
function Vt(s) {
|
|
2992
3009
|
return typeof s == "object" && s !== null && "aggFunc" in s;
|
|
2993
3010
|
}
|
|
2994
|
-
function
|
|
3011
|
+
function Z(s, e) {
|
|
2995
3012
|
const t = document.createElement("div");
|
|
2996
3013
|
t.className = "tbw-pinned-rows", t.setAttribute("role", "presentation"), t.setAttribute("aria-live", "polite");
|
|
2997
3014
|
const n = document.createElement("div");
|
|
@@ -3013,7 +3030,7 @@ function Y(s, e) {
|
|
|
3013
3030
|
}
|
|
3014
3031
|
if (s.customPanels)
|
|
3015
3032
|
for (const r of s.customPanels) {
|
|
3016
|
-
const l =
|
|
3033
|
+
const l = zt(r, e);
|
|
3017
3034
|
switch (r.position) {
|
|
3018
3035
|
case "left":
|
|
3019
3036
|
n.appendChild(l);
|
|
@@ -3046,23 +3063,23 @@ function Ae(s, e, t, n) {
|
|
|
3046
3063
|
let a, d;
|
|
3047
3064
|
const c = i.aggregators?.[r.field];
|
|
3048
3065
|
if (c)
|
|
3049
|
-
if (
|
|
3050
|
-
const
|
|
3051
|
-
|
|
3066
|
+
if (Vt(c)) {
|
|
3067
|
+
const u = ce(c.aggFunc);
|
|
3068
|
+
u && (a = u(n, r.field, r)), d = c.formatter;
|
|
3052
3069
|
} else {
|
|
3053
|
-
const
|
|
3054
|
-
|
|
3070
|
+
const u = ce(c);
|
|
3071
|
+
u && (a = u(n, r.field, r));
|
|
3055
3072
|
}
|
|
3056
3073
|
else if (i.cells && Object.prototype.hasOwnProperty.call(i.cells, r.field)) {
|
|
3057
|
-
const
|
|
3058
|
-
typeof
|
|
3074
|
+
const u = i.cells[r.field];
|
|
3075
|
+
typeof u == "function" ? a = u(n, r.field, r) : a = u;
|
|
3059
3076
|
}
|
|
3060
3077
|
a != null ? l.textContent = d ? d(a, r.field, r) : String(a) : l.textContent = "", o.appendChild(l);
|
|
3061
3078
|
}
|
|
3062
3079
|
s.appendChild(o);
|
|
3063
3080
|
}
|
|
3064
3081
|
}
|
|
3065
|
-
function
|
|
3082
|
+
function zt(s, e) {
|
|
3066
3083
|
const t = document.createElement("div");
|
|
3067
3084
|
t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${s.id}`;
|
|
3068
3085
|
const n = s.render(e);
|
|
@@ -3078,10 +3095,10 @@ function _e(s, e, t, n, i) {
|
|
|
3078
3095
|
grid: t
|
|
3079
3096
|
};
|
|
3080
3097
|
}
|
|
3081
|
-
const
|
|
3082
|
-
class
|
|
3098
|
+
const Wt = ".tbw-footer{flex-shrink:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-color-panel-bg)}.tbw-pinned-rows{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--tbw-pinned-rows-bg, var(--tbw-color-panel-bg));border-top:1px solid var(--tbw-pinned-rows-border, var(--tbw-color-border));font-size:12px;color:var(--tbw-pinned-rows-color, var(--tbw-color-fg-muted));min-height:32px;box-sizing:border-box;min-width:fit-content}.tbw-pinned-rows-left,.tbw-pinned-rows-center,.tbw-pinned-rows-right{display:flex;align-items:center;gap:16px}.tbw-pinned-rows-left{justify-content:flex-start}.tbw-pinned-rows-center{justify-content:center;flex:1}.tbw-pinned-rows-right{justify-content:flex-end}.tbw-status-panel{white-space:nowrap}.tbw-aggregation-rows{min-width:fit-content;background:var(--tbw-aggregation-bg, var(--tbw-color-header-bg))}.tbw-aggregation-rows-top{border-bottom:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-rows-bottom{border-top:1px solid var(--tbw-aggregation-border, var(--tbw-color-border))}.tbw-aggregation-row{display:grid;grid-template-columns:var(--tbw-column-template);font-size:var(--tbw-aggregation-font-size, .8em);font-weight:var(--tbw-aggregation-font-weight, 600)}.tbw-aggregation-cell{padding:var(--tbw-cell-padding, 2px 8px);min-height:var(--tbw-row-height, 28px);display:flex;align-items:center;border-right:1px solid var(--tbw-color-border-cell)}.tbw-aggregation-cell:last-child{border-right:0}.tbw-aggregation-cell-full{grid-column:1 / -1;border-right:0}";
|
|
3099
|
+
class jn extends x {
|
|
3083
3100
|
name = "pinnedRows";
|
|
3084
|
-
|
|
3101
|
+
styles = Wt;
|
|
3085
3102
|
get defaultConfig() {
|
|
3086
3103
|
return {
|
|
3087
3104
|
position: "bottom",
|
|
@@ -3114,12 +3131,12 @@ class Gn extends x {
|
|
|
3114
3131
|
this.grid,
|
|
3115
3132
|
n,
|
|
3116
3133
|
i
|
|
3117
|
-
), r = this.config.aggregationRows || [], l = r.filter((
|
|
3134
|
+
), r = this.config.aggregationRows || [], l = r.filter((h) => h.position === "top"), a = r.filter((h) => h.position !== "top");
|
|
3118
3135
|
if (l.length > 0) {
|
|
3119
3136
|
if (!this.topAggregationContainer) {
|
|
3120
3137
|
this.topAggregationContainer = ke("top");
|
|
3121
|
-
const
|
|
3122
|
-
|
|
3138
|
+
const h = e.querySelector(".header");
|
|
3139
|
+
h && h.nextSibling ? t.insertBefore(this.topAggregationContainer, h.nextSibling) : t.appendChild(this.topAggregationContainer);
|
|
3123
3140
|
}
|
|
3124
3141
|
Ae(
|
|
3125
3142
|
this.topAggregationContainer,
|
|
@@ -3128,21 +3145,21 @@ class Gn extends x {
|
|
|
3128
3145
|
this.rows
|
|
3129
3146
|
);
|
|
3130
3147
|
} else this.topAggregationContainer && (this.topAggregationContainer.remove(), this.topAggregationContainer = null);
|
|
3131
|
-
const d = this.config.showRowCount !== !1 || this.config.showSelectedCount && o.selectedRows > 0 || this.config.showFilteredCount && o.filteredRows !== o.totalRows || this.config.customPanels && this.config.customPanels.length > 0, c = d && this.config.position !== "top",
|
|
3148
|
+
const d = this.config.showRowCount !== !1 || this.config.showSelectedCount && o.selectedRows > 0 || this.config.showFilteredCount && o.filteredRows !== o.totalRows || this.config.customPanels && this.config.customPanels.length > 0, c = d && this.config.position !== "top", u = a.length > 0 || c;
|
|
3132
3149
|
if (d && this.config.position === "top")
|
|
3133
3150
|
if (!this.infoBarElement)
|
|
3134
|
-
this.infoBarElement =
|
|
3151
|
+
this.infoBarElement = Z(this.config, o), t.insertBefore(this.infoBarElement, t.firstChild);
|
|
3135
3152
|
else {
|
|
3136
|
-
const
|
|
3137
|
-
this.infoBarElement.replaceWith(
|
|
3153
|
+
const h = Z(this.config, o);
|
|
3154
|
+
this.infoBarElement.replaceWith(h), this.infoBarElement = h;
|
|
3138
3155
|
}
|
|
3139
3156
|
else this.config.position === "top" && this.infoBarElement && (this.infoBarElement.remove(), this.infoBarElement = null);
|
|
3140
|
-
|
|
3157
|
+
u ? (this.footerWrapper || (this.footerWrapper = document.createElement("div"), this.footerWrapper.className = "tbw-footer", t.appendChild(this.footerWrapper)), this.footerWrapper.innerHTML = "", a.length > 0 && (this.bottomAggregationContainer || (this.bottomAggregationContainer = ke("bottom")), this.footerWrapper.appendChild(this.bottomAggregationContainer), Ae(
|
|
3141
3158
|
this.bottomAggregationContainer,
|
|
3142
3159
|
a,
|
|
3143
3160
|
this.visibleColumns,
|
|
3144
3161
|
this.rows
|
|
3145
|
-
)), c && (this.infoBarElement =
|
|
3162
|
+
)), c && (this.infoBarElement = Z(this.config, o), this.footerWrapper.appendChild(this.infoBarElement))) : this.cleanupFooter();
|
|
3146
3163
|
}
|
|
3147
3164
|
// #endregion
|
|
3148
3165
|
// #region Private Methods
|
|
@@ -3217,20 +3234,17 @@ class Gn extends x {
|
|
|
3217
3234
|
this.config.aggregationRows && (this.config.aggregationRows = this.config.aggregationRows.filter((t) => t.id !== e), this.requestRender());
|
|
3218
3235
|
}
|
|
3219
3236
|
// #endregion
|
|
3220
|
-
// #region Styles
|
|
3221
|
-
styles = Ot;
|
|
3222
|
-
// #endregion
|
|
3223
3237
|
}
|
|
3224
|
-
const
|
|
3225
|
-
function
|
|
3238
|
+
const $t = Xe;
|
|
3239
|
+
function jt(s) {
|
|
3226
3240
|
const e = [];
|
|
3227
3241
|
return !s.rowGroupFields?.length && !s.columnGroupFields?.length && e.push("At least one row or column group field is required"), s.valueFields?.length || e.push("At least one value field is required"), e;
|
|
3228
3242
|
}
|
|
3229
|
-
function
|
|
3243
|
+
function se(s, e) {
|
|
3230
3244
|
return [...s, e].join("|");
|
|
3231
3245
|
}
|
|
3232
|
-
function
|
|
3233
|
-
const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], i = e.valueFields ?? [], o =
|
|
3246
|
+
function Ut(s, e) {
|
|
3247
|
+
const t = e.rowGroupFields ?? [], n = e.columnGroupFields ?? [], i = e.valueFields ?? [], o = Xt(s, n), r = Be(
|
|
3234
3248
|
s,
|
|
3235
3249
|
t,
|
|
3236
3250
|
n,
|
|
@@ -3240,7 +3254,7 @@ function Bt(s, e) {
|
|
|
3240
3254
|
// starting depth
|
|
3241
3255
|
""
|
|
3242
3256
|
// parent key prefix
|
|
3243
|
-
), l =
|
|
3257
|
+
), l = Yt(r, o, i), a = Object.values(l).reduce((d, c) => d + c, 0);
|
|
3244
3258
|
return {
|
|
3245
3259
|
rows: r,
|
|
3246
3260
|
columnKeys: o,
|
|
@@ -3248,7 +3262,7 @@ function Bt(s, e) {
|
|
|
3248
3262
|
grandTotal: a
|
|
3249
3263
|
};
|
|
3250
3264
|
}
|
|
3251
|
-
function
|
|
3265
|
+
function Xt(s, e) {
|
|
3252
3266
|
if (e.length === 0) return ["value"];
|
|
3253
3267
|
const t = /* @__PURE__ */ new Set();
|
|
3254
3268
|
for (const n of s) {
|
|
@@ -3257,7 +3271,7 @@ function zt(s, e) {
|
|
|
3257
3271
|
}
|
|
3258
3272
|
return [...t].sort();
|
|
3259
3273
|
}
|
|
3260
|
-
function
|
|
3274
|
+
function Zt(s, e) {
|
|
3261
3275
|
const t = /* @__PURE__ */ new Map();
|
|
3262
3276
|
for (const n of s) {
|
|
3263
3277
|
const i = String(n[e] ?? ""), o = t.get(i);
|
|
@@ -3265,25 +3279,25 @@ function $t(s, e) {
|
|
|
3265
3279
|
}
|
|
3266
3280
|
return t;
|
|
3267
3281
|
}
|
|
3268
|
-
function
|
|
3282
|
+
function Be(s, e, t, n, i, o, r) {
|
|
3269
3283
|
const l = [];
|
|
3270
3284
|
if (e.length === 0) {
|
|
3271
|
-
const
|
|
3285
|
+
const h = Le(s, t, n, i), f = Te(h);
|
|
3272
3286
|
return l.push({
|
|
3273
3287
|
rowKey: r || "all",
|
|
3274
3288
|
rowLabel: r || "All",
|
|
3275
3289
|
depth: o,
|
|
3276
|
-
values:
|
|
3290
|
+
values: h,
|
|
3277
3291
|
total: f,
|
|
3278
3292
|
isGroup: !1,
|
|
3279
3293
|
rowCount: s.length
|
|
3280
3294
|
}), l;
|
|
3281
3295
|
}
|
|
3282
|
-
const a = e[0], d = e.slice(1), c = d.length > 0,
|
|
3283
|
-
for (const [
|
|
3284
|
-
const g = r ? `${r}|${
|
|
3296
|
+
const a = e[0], d = e.slice(1), c = d.length > 0, u = Zt(s, a);
|
|
3297
|
+
for (const [h, f] of u) {
|
|
3298
|
+
const g = r ? `${r}|${h}` : h, p = Le(f, t, n, i), b = Te(p);
|
|
3285
3299
|
let m;
|
|
3286
|
-
c && (m =
|
|
3300
|
+
c && (m = Be(
|
|
3287
3301
|
f,
|
|
3288
3302
|
d,
|
|
3289
3303
|
t,
|
|
@@ -3293,10 +3307,10 @@ function Ge(s, e, t, n, i, o, r) {
|
|
|
3293
3307
|
g
|
|
3294
3308
|
)), l.push({
|
|
3295
3309
|
rowKey: g,
|
|
3296
|
-
rowLabel:
|
|
3310
|
+
rowLabel: h || "(blank)",
|
|
3297
3311
|
depth: o,
|
|
3298
3312
|
values: p,
|
|
3299
|
-
total:
|
|
3313
|
+
total: b,
|
|
3300
3314
|
isGroup: c,
|
|
3301
3315
|
children: m,
|
|
3302
3316
|
rowCount: f.length
|
|
@@ -3308,8 +3322,8 @@ function Le(s, e, t, n) {
|
|
|
3308
3322
|
const i = {};
|
|
3309
3323
|
for (const o of t)
|
|
3310
3324
|
for (const r of n) {
|
|
3311
|
-
const a = (e.length > 0 ? s.filter((
|
|
3312
|
-
i[
|
|
3325
|
+
const a = (e.length > 0 ? s.filter((h) => e.map((f) => String(h[f] ?? "")).join("|") === o) : s).map((h) => Number(h[r.field]) || 0), d = $t(r.aggFunc), c = a.length > 0 ? d(a) : null, u = se([o], r.field);
|
|
3326
|
+
i[u] = c;
|
|
3313
3327
|
}
|
|
3314
3328
|
return i;
|
|
3315
3329
|
}
|
|
@@ -3319,21 +3333,21 @@ function Te(s) {
|
|
|
3319
3333
|
e += t ?? 0;
|
|
3320
3334
|
return e;
|
|
3321
3335
|
}
|
|
3322
|
-
function
|
|
3336
|
+
function Yt(s, e, t) {
|
|
3323
3337
|
const n = {};
|
|
3324
3338
|
function i(o) {
|
|
3325
3339
|
for (const r of o)
|
|
3326
3340
|
if (!r.isGroup || !r.children?.length)
|
|
3327
3341
|
for (const l of e)
|
|
3328
3342
|
for (const a of t) {
|
|
3329
|
-
const d =
|
|
3343
|
+
const d = se([l], a.field);
|
|
3330
3344
|
n[d] = (n[d] ?? 0) + (r.values[d] ?? 0);
|
|
3331
3345
|
}
|
|
3332
3346
|
else r.children && i(r.children);
|
|
3333
3347
|
}
|
|
3334
3348
|
return i(s), n;
|
|
3335
3349
|
}
|
|
3336
|
-
function
|
|
3350
|
+
function Jt(s, e, t = !0) {
|
|
3337
3351
|
const n = [];
|
|
3338
3352
|
function i(o) {
|
|
3339
3353
|
n.push(o);
|
|
@@ -3346,7 +3360,7 @@ function jt(s, e, t = !0) {
|
|
|
3346
3360
|
i(o);
|
|
3347
3361
|
return n;
|
|
3348
3362
|
}
|
|
3349
|
-
function
|
|
3363
|
+
function Qt(s) {
|
|
3350
3364
|
const e = [];
|
|
3351
3365
|
function t(n) {
|
|
3352
3366
|
if (n.isGroup && e.push(n.rowKey), n.children)
|
|
@@ -3357,14 +3371,14 @@ function J(s) {
|
|
|
3357
3371
|
t(n);
|
|
3358
3372
|
return e;
|
|
3359
3373
|
}
|
|
3360
|
-
const
|
|
3361
|
-
function
|
|
3374
|
+
const en = ["sum", "avg", "count", "min", "max", "first", "last"];
|
|
3375
|
+
function tn(s, e, t, n) {
|
|
3362
3376
|
const i = new AbortController(), o = { config: e, callbacks: n, signal: i.signal }, r = document.createElement("div");
|
|
3363
|
-
return r.className = "tbw-pivot-panel", r.appendChild(
|
|
3377
|
+
return r.className = "tbw-pivot-panel", r.appendChild(D("Options", () => ln(t, o))), r.appendChild(D("Row Groups", () => Ie("rowGroups", o))), r.appendChild(D("Column Groups", () => Ie("columnGroups", o))), r.appendChild(D("Values", () => on(o))), r.appendChild(D("Available Fields", () => sn(o))), s.appendChild(r), () => {
|
|
3364
3378
|
i.abort(), r.remove();
|
|
3365
3379
|
};
|
|
3366
3380
|
}
|
|
3367
|
-
function
|
|
3381
|
+
function D(s, e) {
|
|
3368
3382
|
const t = document.createElement("div");
|
|
3369
3383
|
t.className = "tbw-pivot-section";
|
|
3370
3384
|
const n = document.createElement("div");
|
|
@@ -3381,7 +3395,7 @@ function Ie(s, e) {
|
|
|
3381
3395
|
l.className = "tbw-pivot-placeholder", l.textContent = "Drag fields here or click to add", o.appendChild(l);
|
|
3382
3396
|
} else
|
|
3383
3397
|
for (const l of r)
|
|
3384
|
-
o.appendChild(
|
|
3398
|
+
o.appendChild(nn(l, s, e));
|
|
3385
3399
|
return o.addEventListener(
|
|
3386
3400
|
"dragover",
|
|
3387
3401
|
(l) => {
|
|
@@ -3404,7 +3418,7 @@ function Ie(s, e) {
|
|
|
3404
3418
|
{ signal: i }
|
|
3405
3419
|
), o;
|
|
3406
3420
|
}
|
|
3407
|
-
function
|
|
3421
|
+
function nn(s, e, t) {
|
|
3408
3422
|
const { callbacks: n, signal: i } = t, o = document.createElement("div");
|
|
3409
3423
|
o.className = "tbw-pivot-field-chip", o.draggable = !0;
|
|
3410
3424
|
const r = n.getAvailableFields().find((d) => d.field === s), l = document.createElement("span");
|
|
@@ -3430,7 +3444,7 @@ function Xt(s, e, t) {
|
|
|
3430
3444
|
{ signal: i }
|
|
3431
3445
|
), o;
|
|
3432
3446
|
}
|
|
3433
|
-
function
|
|
3447
|
+
function on(s) {
|
|
3434
3448
|
const { config: e, callbacks: t, signal: n } = s, i = document.createElement("div");
|
|
3435
3449
|
i.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", i.setAttribute("data-zone", "values");
|
|
3436
3450
|
const o = e.valueFields ?? [];
|
|
@@ -3439,7 +3453,7 @@ function Yt(s) {
|
|
|
3439
3453
|
r.className = "tbw-pivot-placeholder", r.textContent = "Drag numeric fields here for aggregation", i.appendChild(r);
|
|
3440
3454
|
} else
|
|
3441
3455
|
for (const r of o)
|
|
3442
|
-
i.appendChild(
|
|
3456
|
+
i.appendChild(rn(r, s));
|
|
3443
3457
|
return i.addEventListener(
|
|
3444
3458
|
"dragover",
|
|
3445
3459
|
(r) => {
|
|
@@ -3462,7 +3476,7 @@ function Yt(s) {
|
|
|
3462
3476
|
{ signal: n }
|
|
3463
3477
|
), i;
|
|
3464
3478
|
}
|
|
3465
|
-
function
|
|
3479
|
+
function rn(s, e) {
|
|
3466
3480
|
const { callbacks: t, signal: n } = e, i = document.createElement("div");
|
|
3467
3481
|
i.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
|
|
3468
3482
|
const o = t.getAvailableFields().find((c) => c.field === s.field), r = document.createElement("div");
|
|
@@ -3471,9 +3485,9 @@ function Jt(s, e) {
|
|
|
3471
3485
|
l.className = "tbw-pivot-chip-label", l.textContent = o?.header ?? s.field;
|
|
3472
3486
|
const a = document.createElement("select");
|
|
3473
3487
|
a.className = "tbw-pivot-agg-select", a.title = "Aggregation function";
|
|
3474
|
-
for (const c of
|
|
3475
|
-
const
|
|
3476
|
-
|
|
3488
|
+
for (const c of en) {
|
|
3489
|
+
const u = document.createElement("option");
|
|
3490
|
+
u.value = c, u.textContent = c.toUpperCase(), u.selected = c === s.aggFunc, a.appendChild(u);
|
|
3477
3491
|
}
|
|
3478
3492
|
a.addEventListener(
|
|
3479
3493
|
"change",
|
|
@@ -3491,7 +3505,7 @@ function Jt(s, e) {
|
|
|
3491
3505
|
{ signal: n }
|
|
3492
3506
|
), r.appendChild(l), r.appendChild(a), i.appendChild(r), i.appendChild(d), i;
|
|
3493
3507
|
}
|
|
3494
|
-
function
|
|
3508
|
+
function sn(s) {
|
|
3495
3509
|
const { config: e, callbacks: t, signal: n } = s, i = document.createElement("div");
|
|
3496
3510
|
i.className = "tbw-pivot-available-fields";
|
|
3497
3511
|
const o = t.getAvailableFields(), r = /* @__PURE__ */ new Set([
|
|
@@ -3521,10 +3535,10 @@ function Qt(s) {
|
|
|
3521
3535
|
}
|
|
3522
3536
|
return i;
|
|
3523
3537
|
}
|
|
3524
|
-
function
|
|
3538
|
+
function ln(s, e) {
|
|
3525
3539
|
const { config: t, callbacks: n, signal: i } = e, o = document.createElement("div");
|
|
3526
3540
|
return o.className = "tbw-pivot-options", o.appendChild(
|
|
3527
|
-
|
|
3541
|
+
Y(
|
|
3528
3542
|
"Enable Pivot View",
|
|
3529
3543
|
s,
|
|
3530
3544
|
(r) => {
|
|
@@ -3533,7 +3547,7 @@ function en(s, e) {
|
|
|
3533
3547
|
i
|
|
3534
3548
|
)
|
|
3535
3549
|
), o.appendChild(
|
|
3536
|
-
|
|
3550
|
+
Y(
|
|
3537
3551
|
"Show Row Totals",
|
|
3538
3552
|
t.showTotals ?? !0,
|
|
3539
3553
|
(r) => {
|
|
@@ -3542,7 +3556,7 @@ function en(s, e) {
|
|
|
3542
3556
|
i
|
|
3543
3557
|
)
|
|
3544
3558
|
), o.appendChild(
|
|
3545
|
-
|
|
3559
|
+
Y(
|
|
3546
3560
|
"Show Grand Total",
|
|
3547
3561
|
t.showGrandTotal ?? !0,
|
|
3548
3562
|
(r) => {
|
|
@@ -3552,7 +3566,7 @@ function en(s, e) {
|
|
|
3552
3566
|
)
|
|
3553
3567
|
), o;
|
|
3554
3568
|
}
|
|
3555
|
-
function
|
|
3569
|
+
function Y(s, e, t, n) {
|
|
3556
3570
|
const i = document.createElement("label");
|
|
3557
3571
|
i.className = "tbw-pivot-checkbox";
|
|
3558
3572
|
const o = document.createElement("input");
|
|
@@ -3560,15 +3574,15 @@ function Q(s, e, t, n) {
|
|
|
3560
3574
|
const r = document.createElement("span");
|
|
3561
3575
|
return r.textContent = s, i.appendChild(o), i.appendChild(r), i;
|
|
3562
3576
|
}
|
|
3563
|
-
function
|
|
3564
|
-
return e.className = "pivot-group-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((n, i) => {
|
|
3577
|
+
function an(s, e, t) {
|
|
3578
|
+
return e.className = "data-grid-row pivot-group-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.setAttribute("role", "row"), e.innerHTML = "", t.columns.forEach((n, i) => {
|
|
3565
3579
|
const o = document.createElement("div");
|
|
3566
|
-
if (o.className = "cell", o.setAttribute("data-col", String(i)), o.setAttribute("role", "gridcell"), i === 0) {
|
|
3580
|
+
if (o.className = "cell", o.setAttribute("data-col", String(i)), o.setAttribute("data-row", String(t.rowIndex)), o.setAttribute("role", "gridcell"), i === 0) {
|
|
3567
3581
|
const r = Number(s.__pivotIndent) || 0;
|
|
3568
3582
|
o.style.paddingLeft = `${r}px`;
|
|
3569
3583
|
const l = String(s.__pivotRowKey), a = document.createElement("button");
|
|
3570
|
-
a.type = "button", a.className = "pivot-toggle", a.setAttribute("aria-label", s.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(a, t.resolveIcon(s.__pivotExpanded ? "collapse" : "expand")), a.addEventListener("click", (
|
|
3571
|
-
|
|
3584
|
+
a.type = "button", a.className = "pivot-toggle", a.setAttribute("aria-label", s.__pivotExpanded ? "Collapse group" : "Expand group"), t.setIcon(a, t.resolveIcon(s.__pivotExpanded ? "collapse" : "expand")), a.addEventListener("click", (u) => {
|
|
3585
|
+
u.stopPropagation(), t.onToggle(l);
|
|
3572
3586
|
}), o.appendChild(a);
|
|
3573
3587
|
const d = document.createElement("span");
|
|
3574
3588
|
d.className = "pivot-label", d.textContent = String(s.__pivotLabel ?? ""), o.appendChild(d);
|
|
@@ -3581,22 +3595,22 @@ function tn(s, e, t) {
|
|
|
3581
3595
|
e.appendChild(o);
|
|
3582
3596
|
}), !0;
|
|
3583
3597
|
}
|
|
3584
|
-
function
|
|
3585
|
-
return e.className = "pivot-leaf-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.innerHTML = "", t.forEach((
|
|
3586
|
-
const
|
|
3587
|
-
if (
|
|
3588
|
-
const
|
|
3589
|
-
|
|
3590
|
-
const
|
|
3591
|
-
|
|
3598
|
+
function dn(s, e, t, n) {
|
|
3599
|
+
return e.className = "data-grid-row pivot-leaf-row", e.setAttribute("data-pivot-depth", String(s.__pivotDepth ?? 0)), e.setAttribute("data-pivot-key", String(s.__pivotRowKey ?? "")), e.innerHTML = "", t.forEach((i, o) => {
|
|
3600
|
+
const r = document.createElement("div");
|
|
3601
|
+
if (r.className = "cell", r.setAttribute("data-col", String(o)), r.setAttribute("data-row", String(n)), r.setAttribute("role", "gridcell"), o === 0) {
|
|
3602
|
+
const l = Number(s.__pivotIndent) || 0;
|
|
3603
|
+
r.style.paddingLeft = `${l + 20}px`;
|
|
3604
|
+
const a = document.createElement("span");
|
|
3605
|
+
a.className = "pivot-label", a.textContent = String(s.__pivotLabel ?? ""), r.appendChild(a);
|
|
3592
3606
|
} else {
|
|
3593
|
-
const
|
|
3594
|
-
|
|
3607
|
+
const l = s[i.field];
|
|
3608
|
+
r.textContent = l != null ? String(l) : "";
|
|
3595
3609
|
}
|
|
3596
|
-
e.appendChild(
|
|
3610
|
+
e.appendChild(r);
|
|
3597
3611
|
}), !0;
|
|
3598
3612
|
}
|
|
3599
|
-
function
|
|
3613
|
+
function cn(s, e, t) {
|
|
3600
3614
|
return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", t.forEach((n, i) => {
|
|
3601
3615
|
const o = document.createElement("div");
|
|
3602
3616
|
if (o.className = "cell", o.setAttribute("data-col", String(i)), i === 0) {
|
|
@@ -3609,10 +3623,10 @@ function on(s, e, t) {
|
|
|
3609
3623
|
e.appendChild(o);
|
|
3610
3624
|
}), !0;
|
|
3611
3625
|
}
|
|
3612
|
-
const
|
|
3613
|
-
class
|
|
3626
|
+
const un = '.pivot-group-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:600;background:var(--tbw-pivot-group-bg, var(--tbw-color-row-alt));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-group-row:hover{background:var(--tbw-pivot-group-hover, var(--tbw-color-row-hover))}.pivot-leaf-row{display:grid;grid-template-columns:var(--tbw-column-template);background:var(--tbw-pivot-leaf-bg, var(--tbw-color-bg));min-height:var(--tbw-row-height);border-bottom:var(--tbw-row-divider)}.pivot-grand-total-row{display:grid;grid-template-columns:var(--tbw-column-template);font-weight:700;background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-height:var(--tbw-row-height);border-top:2px solid var(--tbw-color-border-strong)}.pivot-grand-total-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-grand-total-row>.cell:last-child{border-right:0}.pivot-grand-total-footer{position:sticky;bottom:0;z-index:var(--tbw-z-layer-pinned-rows, 20);background:var(--tbw-pivot-grand-total-bg, var(--tbw-color-header-bg));min-width:fit-content}.pivot-group-row>.cell,.pivot-leaf-row>.cell{display:flex;align-items:center;padding:var(--tbw-cell-padding);border-right:1px solid var(--tbw-color-border-cell);overflow:hidden;min-width:0}.pivot-group-row>.cell:last-child,.pivot-leaf-row>.cell:last-child{border-right:0}.pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-right:6px;border:none;background:transparent;cursor:pointer;color:var(--tbw-pivot-toggle-color, var(--tbw-color-fg-muted));border-radius:var(--tbw-border-radius);transition:background .15s,color .15s}.pivot-toggle:hover{background:var(--tbw-pivot-toggle-hover-bg, var(--tbw-color-row-hover));color:var(--tbw-pivot-toggle-hover-color, var(--tbw-color-fg))}.pivot-toggle:focus{outline:var(--tbw-focus-outline);outline-offset:var(--tbw-focus-outline-offset)}.pivot-label{font-weight:inherit}.pivot-count{color:var(--tbw-pivot-count-color, var(--tbw-color-fg-muted));font-size:.9em;font-weight:400}.pivot-total-row{font-weight:700;border-top:2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong))}[data-pivot-depth="1"]{--tbw-pivot-depth: 1}[data-pivot-depth="2"]{--tbw-pivot-depth: 2}[data-pivot-depth="3"]{--tbw-pivot-depth: 3}[data-pivot-depth="4"]{--tbw-pivot-depth: 4}.tbw-pivot-panel{display:flex;flex-direction:column;gap:12px;padding:12px;height:100%;overflow-y:auto;font-size:13px}.tbw-pivot-section{border:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-section-bg, var(--tbw-color-bg))}.tbw-pivot-section-header{padding:8px 12px;font-weight:600;background:var(--tbw-pivot-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-pivot-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius) var(--tbw-border-radius) 0 0}.tbw-pivot-section-content{padding:8px}.tbw-pivot-toggle-wrapper{display:flex;align-items:center}.tbw-pivot-toggle-label{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-toggle-label input{width:16px;height:16px;cursor:pointer}.tbw-pivot-drop-zone{min-height:60px;padding:8px;border:2px dashed var(--tbw-pivot-drop-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);background:var(--tbw-pivot-drop-bg, var(--tbw-color-row-alt));display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start;transition:all .15s ease}.tbw-pivot-drop-zone.drag-over{border-color:var(--tbw-color-accent);background:var(--tbw-pivot-drop-active, var(--tbw-focus-background))}.tbw-pivot-placeholder{color:var(--tbw-color-fg-muted);font-style:italic;padding:8px;text-align:center;width:100%}.tbw-pivot-field-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;background:var(--tbw-pivot-chip-bg, var(--tbw-color-header-bg));border:1px solid var(--tbw-pivot-chip-border, var(--tbw-color-border));border-radius:var(--tbw-border-radius);cursor:grab;font-size:12px;transition:all .15s ease}.tbw-pivot-field-chip:hover{background:var(--tbw-pivot-chip-hover, var(--tbw-color-row-hover));border-color:var(--tbw-color-accent)}.tbw-pivot-field-chip.available{background:var(--tbw-color-bg)}.tbw-pivot-field-chip.dragging{opacity:.5;cursor:grabbing}.tbw-pivot-chip-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.tbw-pivot-chip-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:var(--tbw-color-fg-muted);font-size:14px;font-weight:700;cursor:pointer;border-radius:50%;transition:all .15s ease}.tbw-pivot-chip-remove:hover{background:var(--tbw-pivot-chip-remove-hover-bg, var(--tbw-color-accent));color:var(--tbw-pivot-chip-remove-hover-fg, var(--tbw-color-accent-fg))}.tbw-pivot-value-chip{padding:4px 8px}.tbw-pivot-value-label-wrapper{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.tbw-pivot-agg-select{padding:2px 4px;font-size:11px;border:1px solid var(--tbw-color-border);border-radius:var(--tbw-border-radius);background:var(--tbw-color-bg);cursor:pointer}.tbw-pivot-available-fields{display:flex;flex-wrap:wrap;gap:6px;min-height:40px}.tbw-pivot-options{display:flex;flex-direction:column;gap:8px}.tbw-pivot-checkbox{display:flex;align-items:center;gap:8px;cursor:pointer}.tbw-pivot-checkbox input{width:14px;height:14px;cursor:pointer}.pivot-group-row.tbw-pivot-slide-in,.pivot-leaf-row.tbw-pivot-slide-in{animation:tbw-pivot-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.pivot-group-row.tbw-pivot-fade-in,.pivot-leaf-row.tbw-pivot-fade-in{animation:tbw-pivot-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-pivot-fade-in{0%{opacity:0}to{opacity:1}}';
|
|
3627
|
+
class F extends x {
|
|
3614
3628
|
name = "pivot";
|
|
3615
|
-
|
|
3629
|
+
styles = un;
|
|
3616
3630
|
/** Tool panel ID for shell integration */
|
|
3617
3631
|
static PANEL_ID = "pivot";
|
|
3618
3632
|
get defaultConfig() {
|
|
@@ -3643,17 +3657,11 @@ class M extends x {
|
|
|
3643
3657
|
return (this.config.valueFields?.length ?? 0) > 0;
|
|
3644
3658
|
}
|
|
3645
3659
|
/**
|
|
3646
|
-
* Get animation style
|
|
3660
|
+
* Get expand/collapse animation style from plugin config.
|
|
3661
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
3647
3662
|
*/
|
|
3648
3663
|
get animationStyle() {
|
|
3649
|
-
|
|
3650
|
-
if (t === !1 || t === "off") return !1;
|
|
3651
|
-
if (t !== !0 && t !== "on") {
|
|
3652
|
-
const n = this.shadowRoot?.host;
|
|
3653
|
-
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
3654
|
-
return !1;
|
|
3655
|
-
}
|
|
3656
|
-
return this.config.animation ?? "slide";
|
|
3664
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
3657
3665
|
}
|
|
3658
3666
|
// #endregion
|
|
3659
3667
|
// #region Lifecycle
|
|
@@ -3665,7 +3673,7 @@ class M extends x {
|
|
|
3665
3673
|
getToolPanel() {
|
|
3666
3674
|
if ((this.config?.showToolPanel ?? this.userConfig?.showToolPanel ?? !0) !== !1)
|
|
3667
3675
|
return {
|
|
3668
|
-
id:
|
|
3676
|
+
id: F.PANEL_ID,
|
|
3669
3677
|
title: "Pivot",
|
|
3670
3678
|
icon: "⊞",
|
|
3671
3679
|
tooltip: "Configure pivot table",
|
|
@@ -3678,20 +3686,11 @@ class M extends x {
|
|
|
3678
3686
|
processRows(e) {
|
|
3679
3687
|
if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
|
|
3680
3688
|
return [...e];
|
|
3681
|
-
const t =
|
|
3689
|
+
const t = jt(this.config);
|
|
3682
3690
|
if (t.length > 0)
|
|
3683
3691
|
return this.warn(`Config errors: ${t.join(", ")}`), [...e];
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
for (const l of r)
|
|
3687
|
-
this.expandedKeys.add(l);
|
|
3688
|
-
}
|
|
3689
|
-
if (this.pivotResult = Bt(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
|
|
3690
|
-
const r = J(this.pivotResult.rows);
|
|
3691
|
-
for (const l of r)
|
|
3692
|
-
this.expandedKeys.add(l);
|
|
3693
|
-
}
|
|
3694
|
-
const n = this.config.indentWidth ?? 20, i = jt(
|
|
3692
|
+
this.buildFieldHeaderMap(), this.defaultExpanded = this.config.defaultExpanded ?? !0, this.expandedKeys.size === 0 && this.defaultExpanded && this.pivotResult && this.expandAllKeys(), this.pivotResult = Ut(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded && this.expandAllKeys();
|
|
3693
|
+
const n = this.config.indentWidth ?? 20, i = Jt(
|
|
3695
3694
|
this.pivotResult.rows,
|
|
3696
3695
|
this.expandedKeys,
|
|
3697
3696
|
this.defaultExpanded
|
|
@@ -3726,7 +3725,7 @@ class M extends x {
|
|
|
3726
3725
|
});
|
|
3727
3726
|
for (const i of this.pivotResult.columnKeys)
|
|
3728
3727
|
for (const o of this.config.valueFields ?? []) {
|
|
3729
|
-
const r =
|
|
3728
|
+
const r = se([i], o.field), l = o.header || this.fieldHeaderMap.get(o.field) || o.field;
|
|
3730
3729
|
t.push({
|
|
3731
3730
|
field: r,
|
|
3732
3731
|
header: `${i} - ${l} (${o.aggFunc})`,
|
|
@@ -3741,14 +3740,15 @@ class M extends x {
|
|
|
3741
3740
|
type: "number"
|
|
3742
3741
|
}), t;
|
|
3743
3742
|
}
|
|
3744
|
-
renderRow(e, t) {
|
|
3745
|
-
const
|
|
3746
|
-
return
|
|
3743
|
+
renderRow(e, t, n) {
|
|
3744
|
+
const i = e;
|
|
3745
|
+
return i.__pivotRowKey && i.__pivotHasChildren ? an(i, t, {
|
|
3747
3746
|
columns: this.gridColumns,
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3747
|
+
rowIndex: n,
|
|
3748
|
+
onToggle: (o) => this.toggle(o),
|
|
3749
|
+
resolveIcon: (o) => this.resolveIcon(o),
|
|
3750
|
+
setIcon: (o, r) => this.setIcon(o, r)
|
|
3751
|
+
}) : i.__pivotRowKey !== void 0 && this.isActive ? dn(i, t, this.gridColumns, n) : (this.cleanupPivotStyling(t), !1);
|
|
3752
3752
|
}
|
|
3753
3753
|
/**
|
|
3754
3754
|
* Remove pivot-specific classes, attributes, and inline styles from a row element.
|
|
@@ -3758,6 +3758,12 @@ class M extends x {
|
|
|
3758
3758
|
cleanupPivotStyling(e) {
|
|
3759
3759
|
(e.classList.contains("pivot-group-row") || e.classList.contains("pivot-leaf-row") || e.classList.contains("pivot-grand-total-row")) && (e.classList.remove("pivot-group-row", "pivot-leaf-row", "pivot-grand-total-row"), e.classList.add("data-grid-row"), e.removeAttribute("data-pivot-depth"), e.innerHTML = "");
|
|
3760
3760
|
}
|
|
3761
|
+
onKeyDown(e) {
|
|
3762
|
+
if (e.key !== " " || !this.isActive) return;
|
|
3763
|
+
const t = this.grid._focusRow, n = this.rows[t];
|
|
3764
|
+
if (!(!n?.__pivotIsGroup || !n.__pivotHasChildren))
|
|
3765
|
+
return e.preventDefault(), this.toggle(n.__pivotRowKey), this.requestRenderWithFocus(), !0;
|
|
3766
|
+
}
|
|
3761
3767
|
afterRender() {
|
|
3762
3768
|
this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
|
|
3763
3769
|
const e = this.animationStyle;
|
|
@@ -3788,7 +3794,7 @@ class M extends x {
|
|
|
3788
3794
|
__pivotTotal: this.pivotResult.grandTotal,
|
|
3789
3795
|
...this.pivotResult.totals
|
|
3790
3796
|
};
|
|
3791
|
-
|
|
3797
|
+
cn(n, this.grandTotalFooter, this.gridColumns);
|
|
3792
3798
|
}
|
|
3793
3799
|
/**
|
|
3794
3800
|
* Remove the grand total footer element.
|
|
@@ -3808,16 +3814,20 @@ class M extends x {
|
|
|
3808
3814
|
this.expandedKeys.delete(e), this.requestRender();
|
|
3809
3815
|
}
|
|
3810
3816
|
expandAll() {
|
|
3811
|
-
|
|
3812
|
-
const e = J(this.pivotResult.rows);
|
|
3813
|
-
for (const t of e)
|
|
3814
|
-
this.expandedKeys.add(t);
|
|
3815
|
-
this.requestRender();
|
|
3816
|
-
}
|
|
3817
|
+
this.expandAllKeys(), this.requestRender();
|
|
3817
3818
|
}
|
|
3818
3819
|
collapseAll() {
|
|
3819
3820
|
this.expandedKeys.clear(), this.requestRender();
|
|
3820
3821
|
}
|
|
3822
|
+
/**
|
|
3823
|
+
* Add all group keys from the current pivot result to expandedKeys.
|
|
3824
|
+
*/
|
|
3825
|
+
expandAllKeys() {
|
|
3826
|
+
if (!this.pivotResult) return;
|
|
3827
|
+
const e = Qt(this.pivotResult.rows);
|
|
3828
|
+
for (const t of e)
|
|
3829
|
+
this.expandedKeys.add(t);
|
|
3830
|
+
}
|
|
3821
3831
|
isExpanded(e) {
|
|
3822
3832
|
return this.expandedKeys.has(e);
|
|
3823
3833
|
}
|
|
@@ -3849,23 +3859,42 @@ class M extends x {
|
|
|
3849
3859
|
}
|
|
3850
3860
|
// #endregion
|
|
3851
3861
|
// #region Tool Panel API
|
|
3862
|
+
/**
|
|
3863
|
+
* Show the pivot tool panel.
|
|
3864
|
+
* Opens the tool panel and ensures this section is expanded.
|
|
3865
|
+
*/
|
|
3852
3866
|
showPanel() {
|
|
3853
|
-
this.grid.openToolPanel(
|
|
3867
|
+
this.grid.openToolPanel(), this.grid.expandedToolPanelSections.includes(F.PANEL_ID) || this.grid.toggleToolPanelSection(F.PANEL_ID);
|
|
3854
3868
|
}
|
|
3869
|
+
/**
|
|
3870
|
+
* Hide the tool panel.
|
|
3871
|
+
*/
|
|
3855
3872
|
hidePanel() {
|
|
3856
3873
|
this.grid.closeToolPanel();
|
|
3857
3874
|
}
|
|
3875
|
+
/**
|
|
3876
|
+
* Toggle the pivot tool panel section.
|
|
3877
|
+
*/
|
|
3858
3878
|
togglePanel() {
|
|
3859
|
-
this.grid.
|
|
3879
|
+
this.grid.isToolPanelOpen || this.grid.openToolPanel(), this.grid.toggleToolPanelSection(F.PANEL_ID);
|
|
3860
3880
|
}
|
|
3881
|
+
/**
|
|
3882
|
+
* Check if the pivot panel section is currently expanded.
|
|
3883
|
+
*/
|
|
3861
3884
|
isPanelVisible() {
|
|
3862
|
-
return this.grid.
|
|
3885
|
+
return this.grid.isToolPanelOpen && this.grid.expandedToolPanelSections.includes(F.PANEL_ID);
|
|
3863
3886
|
}
|
|
3864
3887
|
// #endregion
|
|
3865
3888
|
// #region Private Helpers
|
|
3866
3889
|
get gridColumns() {
|
|
3867
3890
|
return this.grid.columns ?? [];
|
|
3868
3891
|
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Refresh pivot and update tool panel if active.
|
|
3894
|
+
*/
|
|
3895
|
+
refreshIfActive() {
|
|
3896
|
+
this.isActive && this.refresh(), this.refreshPanel();
|
|
3897
|
+
}
|
|
3869
3898
|
buildFieldHeaderMap() {
|
|
3870
3899
|
const e = this.getAvailableFields();
|
|
3871
3900
|
this.fieldHeaderMap.clear();
|
|
@@ -3876,12 +3905,11 @@ class M extends x {
|
|
|
3876
3905
|
return this.originalColumns.length > 0 ? this.originalColumns : this.captureOriginalColumns();
|
|
3877
3906
|
}
|
|
3878
3907
|
captureOriginalColumns() {
|
|
3879
|
-
const e = this.grid;
|
|
3880
3908
|
try {
|
|
3881
|
-
const
|
|
3882
|
-
return this.originalColumns =
|
|
3883
|
-
field:
|
|
3884
|
-
header:
|
|
3909
|
+
const e = this.grid.getAllColumns?.() ?? this.grid.columns ?? [];
|
|
3910
|
+
return this.originalColumns = e.filter((t) => !t.field.startsWith("__pivot")).map((t) => ({
|
|
3911
|
+
field: t.field,
|
|
3912
|
+
header: t.header ?? t.field
|
|
3885
3913
|
})), this.originalColumns;
|
|
3886
3914
|
} catch {
|
|
3887
3915
|
return [];
|
|
@@ -3903,7 +3931,7 @@ class M extends x {
|
|
|
3903
3931
|
},
|
|
3904
3932
|
getAvailableFields: () => this.getAvailableFields()
|
|
3905
3933
|
};
|
|
3906
|
-
return
|
|
3934
|
+
return tn(e, this.config, this.isActive, t);
|
|
3907
3935
|
}
|
|
3908
3936
|
refreshPanel() {
|
|
3909
3937
|
this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
|
|
@@ -3916,43 +3944,40 @@ class M extends x {
|
|
|
3916
3944
|
const n = this.config.columnGroupFields ?? [];
|
|
3917
3945
|
n.includes(e) || (this.config.columnGroupFields = [...n, e]);
|
|
3918
3946
|
}
|
|
3919
|
-
this.removeFromOtherZones(e, t), this.
|
|
3947
|
+
this.removeFromOtherZones(e, t), this.refreshIfActive();
|
|
3920
3948
|
}
|
|
3921
3949
|
removeFieldFromZone(e, t) {
|
|
3922
|
-
t === "rowGroups" ? this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((n) => n !== e) : this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((n) => n !== e), this.
|
|
3950
|
+
t === "rowGroups" ? this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((n) => n !== e) : this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((n) => n !== e), this.refreshIfActive();
|
|
3923
3951
|
}
|
|
3924
3952
|
removeFromOtherZones(e, t) {
|
|
3925
3953
|
t !== "rowGroups" && (this.config.rowGroupFields = (this.config.rowGroupFields ?? []).filter((n) => n !== e)), t !== "columnGroups" && (this.config.columnGroupFields = (this.config.columnGroupFields ?? []).filter((n) => n !== e)), t !== "values" && (this.config.valueFields = (this.config.valueFields ?? []).filter((n) => n.field !== e));
|
|
3926
3954
|
}
|
|
3927
3955
|
addValueField(e, t) {
|
|
3928
3956
|
const n = this.config.valueFields ?? [];
|
|
3929
|
-
n.some((i) => i.field === e) || (this.config.valueFields = [...n, { field: e, aggFunc: t }]), this.removeFromOtherZones(e, "values"), this.
|
|
3957
|
+
n.some((i) => i.field === e) || (this.config.valueFields = [...n, { field: e, aggFunc: t }]), this.removeFromOtherZones(e, "values"), this.refreshIfActive();
|
|
3930
3958
|
}
|
|
3931
3959
|
removeValueField(e) {
|
|
3932
|
-
this.config.valueFields = (this.config.valueFields ?? []).filter((t) => t.field !== e), this.
|
|
3960
|
+
this.config.valueFields = (this.config.valueFields ?? []).filter((t) => t.field !== e), this.refreshIfActive();
|
|
3933
3961
|
}
|
|
3934
3962
|
updateValueAggFunc(e, t) {
|
|
3935
3963
|
const n = this.config.valueFields ?? [], i = n.findIndex((o) => o.field === e);
|
|
3936
3964
|
i >= 0 && (n[i] = { ...n[i], aggFunc: t }, this.config.valueFields = [...n]), this.isActive && this.refresh();
|
|
3937
3965
|
}
|
|
3938
3966
|
// #endregion
|
|
3939
|
-
// #region Styles
|
|
3940
|
-
styles = rn;
|
|
3941
|
-
// #endregion
|
|
3942
3967
|
}
|
|
3943
|
-
function
|
|
3968
|
+
function hn(s) {
|
|
3944
3969
|
const e = s.meta ?? {};
|
|
3945
3970
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
3946
3971
|
}
|
|
3947
|
-
function
|
|
3972
|
+
function Fe(s, e, t) {
|
|
3948
3973
|
if (e === t || e < 0 || e >= s.length || t < 0 || t > s.length) return s;
|
|
3949
3974
|
const n = [...s], [i] = n.splice(e, 1);
|
|
3950
3975
|
return n.splice(t, 0, i), n;
|
|
3951
3976
|
}
|
|
3952
|
-
const
|
|
3953
|
-
class
|
|
3977
|
+
const fn = '.header-row>.cell[draggable=true]{cursor:grab;position:relative}.header-row>.cell.dragging{opacity:.5;cursor:grabbing}.header-row>.cell.drop-before:before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.header-row>.cell.drop-after:after{content:"";position:absolute;right:0;top:0;bottom:0;width:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent));z-index:1}.cell.flip-animating{transition:transform var(--tbw-animation-duration, .2s) ease-out;will-change:transform;z-index:1}@keyframes reorder-fade-in{0%{opacity:0}to{opacity:1}}.cell.fade-animating{animation:reorder-fade-in var(--tbw-animation-duration, .2s) ease-out backwards}';
|
|
3978
|
+
class Un extends x {
|
|
3954
3979
|
name = "reorder";
|
|
3955
|
-
|
|
3980
|
+
styles = fn;
|
|
3956
3981
|
get defaultConfig() {
|
|
3957
3982
|
return {
|
|
3958
3983
|
animation: "flip"
|
|
@@ -3961,40 +3986,40 @@ class Vn extends x {
|
|
|
3961
3986
|
}
|
|
3962
3987
|
/**
|
|
3963
3988
|
* Resolve animation type from plugin config.
|
|
3964
|
-
*
|
|
3989
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
3965
3990
|
*/
|
|
3966
3991
|
get animationType() {
|
|
3967
3992
|
return this.isAnimationEnabled ? this.config.animation !== void 0 ? this.config.animation : this.config.viewTransition === !1 ? !1 : (this.config.viewTransition === !0, "flip") : !1;
|
|
3968
3993
|
}
|
|
3969
3994
|
/**
|
|
3970
|
-
*
|
|
3971
|
-
*
|
|
3972
|
-
*/
|
|
3973
|
-
get isAnimationEnabled() {
|
|
3974
|
-
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
3975
|
-
if (t === !1 || t === "off") return !1;
|
|
3976
|
-
if (t === !0 || t === "on") return !0;
|
|
3977
|
-
const n = this.shadowRoot?.host;
|
|
3978
|
-
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
3979
|
-
}
|
|
3980
|
-
/**
|
|
3981
|
-
* Get animation duration from CSS variable (set by grid config).
|
|
3995
|
+
* Get animation duration, allowing plugin config override.
|
|
3996
|
+
* Uses base class animationDuration for default.
|
|
3982
3997
|
*/
|
|
3983
3998
|
get animationDuration() {
|
|
3984
|
-
|
|
3985
|
-
return this.config.animationDuration;
|
|
3986
|
-
const e = this.shadowRoot?.host;
|
|
3987
|
-
if (e) {
|
|
3988
|
-
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
3989
|
-
if (!isNaN(n)) return n;
|
|
3990
|
-
}
|
|
3991
|
-
return 200;
|
|
3999
|
+
return this.config.animationDuration !== void 0 ? this.config.animationDuration : super.animationDuration;
|
|
3992
4000
|
}
|
|
3993
4001
|
// #region Internal State
|
|
3994
4002
|
isDragging = !1;
|
|
3995
4003
|
draggedField = null;
|
|
3996
4004
|
draggedIndex = null;
|
|
3997
4005
|
dropIndex = null;
|
|
4006
|
+
/**
|
|
4007
|
+
* Check if a column can be moved, considering both column config and plugin queries.
|
|
4008
|
+
*/
|
|
4009
|
+
canMoveColumnWithPlugins(e) {
|
|
4010
|
+
return !e || !hn(e) ? !1 : !this.grid.queryPlugins({
|
|
4011
|
+
type: He.CAN_MOVE_COLUMN,
|
|
4012
|
+
context: e
|
|
4013
|
+
}).includes(!1);
|
|
4014
|
+
}
|
|
4015
|
+
/**
|
|
4016
|
+
* Clear all drag-related classes from header cells.
|
|
4017
|
+
*/
|
|
4018
|
+
clearDragClasses() {
|
|
4019
|
+
this.shadowRoot?.querySelectorAll(".header-row > .cell").forEach((e) => {
|
|
4020
|
+
e.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
|
|
4021
|
+
});
|
|
4022
|
+
}
|
|
3998
4023
|
// #endregion
|
|
3999
4024
|
// #region Lifecycle
|
|
4000
4025
|
attach(e) {
|
|
@@ -4018,39 +4043,34 @@ class Vn extends x {
|
|
|
4018
4043
|
e.querySelectorAll(".header-row > .cell").forEach((n) => {
|
|
4019
4044
|
const i = n, o = i.getAttribute("data-field");
|
|
4020
4045
|
if (!o) return;
|
|
4021
|
-
const r = this.columns.find((
|
|
4022
|
-
|
|
4023
|
-
context: r
|
|
4024
|
-
}).includes(!1);
|
|
4025
|
-
if (!r || !Fe(r) || !d) {
|
|
4046
|
+
const r = this.columns.find((l) => l.field === o);
|
|
4047
|
+
if (!this.canMoveColumnWithPlugins(r)) {
|
|
4026
4048
|
i.draggable = !1;
|
|
4027
4049
|
return;
|
|
4028
4050
|
}
|
|
4029
|
-
i.draggable = !0, !i.getAttribute("data-dragstart-bound") && (i.setAttribute("data-dragstart-bound", "true"), i.addEventListener("dragstart", (
|
|
4030
|
-
const
|
|
4031
|
-
this.isDragging = !0, this.draggedField = o, this.draggedIndex =
|
|
4051
|
+
i.draggable = !0, !i.getAttribute("data-dragstart-bound") && (i.setAttribute("data-dragstart-bound", "true"), i.addEventListener("dragstart", (l) => {
|
|
4052
|
+
const d = this.getColumnOrder().indexOf(o);
|
|
4053
|
+
this.isDragging = !0, this.draggedField = o, this.draggedIndex = d, l.dataTransfer && (l.dataTransfer.effectAllowed = "move", l.dataTransfer.setData("text/plain", o)), i.classList.add("dragging");
|
|
4032
4054
|
}), i.addEventListener("dragend", () => {
|
|
4033
|
-
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null,
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
const h = i.getBoundingClientRect(), u = h.left + h.width / 2, g = this.getColumnOrder().indexOf(o);
|
|
4039
|
-
this.dropIndex = c.clientX < u ? g : g + 1, i.classList.add("drop-target"), i.classList.toggle("drop-before", c.clientX < u), i.classList.toggle("drop-after", c.clientX >= u);
|
|
4055
|
+
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses();
|
|
4056
|
+
}), i.addEventListener("dragover", (l) => {
|
|
4057
|
+
if (l.preventDefault(), !this.isDragging || this.draggedField === o) return;
|
|
4058
|
+
const a = i.getBoundingClientRect(), d = a.left + a.width / 2, u = this.getColumnOrder().indexOf(o);
|
|
4059
|
+
this.dropIndex = l.clientX < d ? u : u + 1, i.classList.add("drop-target"), i.classList.toggle("drop-before", l.clientX < d), i.classList.toggle("drop-after", l.clientX >= d);
|
|
4040
4060
|
}), i.addEventListener("dragleave", () => {
|
|
4041
4061
|
i.classList.remove("drop-target", "drop-before", "drop-after");
|
|
4042
|
-
}), i.addEventListener("drop", (
|
|
4043
|
-
|
|
4044
|
-
const
|
|
4045
|
-
if (!this.isDragging ||
|
|
4062
|
+
}), i.addEventListener("drop", (l) => {
|
|
4063
|
+
l.preventDefault();
|
|
4064
|
+
const a = this.draggedField, d = this.draggedIndex, c = this.dropIndex;
|
|
4065
|
+
if (!this.isDragging || a === null || d === null || c === null)
|
|
4046
4066
|
return;
|
|
4047
|
-
const
|
|
4048
|
-
field:
|
|
4049
|
-
fromIndex:
|
|
4050
|
-
toIndex:
|
|
4051
|
-
columnOrder:
|
|
4067
|
+
const u = c > d ? c - 1 : c, h = this.getColumnOrder(), f = Fe(h, d, u), g = {
|
|
4068
|
+
field: a,
|
|
4069
|
+
fromIndex: d,
|
|
4070
|
+
toIndex: u,
|
|
4071
|
+
columnOrder: f
|
|
4052
4072
|
};
|
|
4053
|
-
this.updateColumnOrder(
|
|
4073
|
+
this.updateColumnOrder(f), this.emitCancelable("column-move", g) && this.updateColumnOrder(h);
|
|
4054
4074
|
}));
|
|
4055
4075
|
});
|
|
4056
4076
|
}
|
|
@@ -4063,22 +4083,14 @@ class Vn extends x {
|
|
|
4063
4083
|
const t = this.grid, n = t._focusCol, i = t._visibleColumns;
|
|
4064
4084
|
if (n < 0 || n >= i.length) return;
|
|
4065
4085
|
const o = i[n];
|
|
4066
|
-
if (!
|
|
4067
|
-
const r = this.
|
|
4068
|
-
if (
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
const c = e.key === "ArrowLeft" ? d - 1 : d + 1;
|
|
4075
|
-
if (c < 0 || c >= a.length) return;
|
|
4076
|
-
const h = i.find((u) => u.field === a[c]);
|
|
4077
|
-
if (!(h && r.queryPlugins({
|
|
4078
|
-
type: H.CAN_MOVE_COLUMN,
|
|
4079
|
-
context: h
|
|
4080
|
-
}).includes(!1)))
|
|
4081
|
-
return this.moveColumn(o.field, c), t._focusCol = c, Ue(this.grid), e.preventDefault(), e.stopPropagation(), !0;
|
|
4086
|
+
if (!this.canMoveColumnWithPlugins(o)) return;
|
|
4087
|
+
const r = this.getColumnOrder(), l = r.indexOf(o.field);
|
|
4088
|
+
if (l === -1) return;
|
|
4089
|
+
const a = e.key === "ArrowLeft" ? l - 1 : l + 1;
|
|
4090
|
+
if (a < 0 || a >= r.length) return;
|
|
4091
|
+
const d = i.find((c) => c.field === r[a]);
|
|
4092
|
+
if (this.canMoveColumnWithPlugins(d))
|
|
4093
|
+
return this.moveColumn(o.field, a), t._focusCol = a, Ze(this.grid), e.preventDefault(), e.stopPropagation(), !0;
|
|
4082
4094
|
}
|
|
4083
4095
|
// #endregion
|
|
4084
4096
|
// #region Public API
|
|
@@ -4097,13 +4109,13 @@ class Vn extends x {
|
|
|
4097
4109
|
moveColumn(e, t) {
|
|
4098
4110
|
const n = this.getColumnOrder(), i = n.indexOf(e);
|
|
4099
4111
|
if (i === -1) return;
|
|
4100
|
-
const o =
|
|
4101
|
-
this.updateColumnOrder(o), this.
|
|
4112
|
+
const o = Fe(n, i, t);
|
|
4113
|
+
this.updateColumnOrder(o), this.emitCancelable("column-move", {
|
|
4102
4114
|
field: e,
|
|
4103
4115
|
fromIndex: i,
|
|
4104
4116
|
toIndex: t,
|
|
4105
4117
|
columnOrder: o
|
|
4106
|
-
});
|
|
4118
|
+
}) && this.updateColumnOrder(n);
|
|
4107
4119
|
}
|
|
4108
4120
|
/**
|
|
4109
4121
|
* Set a specific column order.
|
|
@@ -4206,21 +4218,47 @@ class Vn extends x {
|
|
|
4206
4218
|
* Update column order with configured animation.
|
|
4207
4219
|
*/
|
|
4208
4220
|
updateColumnOrder(e) {
|
|
4209
|
-
const t = this.
|
|
4210
|
-
if (
|
|
4211
|
-
const
|
|
4212
|
-
|
|
4213
|
-
this.shadowRoot?.host?.offsetHeight, this.animateFLIP(
|
|
4221
|
+
const t = this.animationType;
|
|
4222
|
+
if (t === "flip" && this.shadowRoot) {
|
|
4223
|
+
const n = this.captureHeaderPositions();
|
|
4224
|
+
this.grid.setColumnOrder(e), requestAnimationFrame(() => {
|
|
4225
|
+
this.shadowRoot?.host?.offsetHeight, this.animateFLIP(n);
|
|
4214
4226
|
});
|
|
4215
|
-
} else
|
|
4216
|
-
|
|
4227
|
+
} else t === "fade" ? this.animateFade(() => this.grid.setColumnOrder(e)) : this.grid.setColumnOrder(e);
|
|
4228
|
+
this.grid.requestStateChange?.();
|
|
4217
4229
|
}
|
|
4218
4230
|
// #endregion
|
|
4219
|
-
// #region Styles
|
|
4220
|
-
styles = sn;
|
|
4221
|
-
// #endregion
|
|
4222
4231
|
}
|
|
4223
|
-
function
|
|
4232
|
+
function Xn(s, e, t, n) {
|
|
4233
|
+
const i = new Set(s.selected);
|
|
4234
|
+
let o = s.anchor;
|
|
4235
|
+
if (t === "single")
|
|
4236
|
+
i.clear(), i.add(e), o = e;
|
|
4237
|
+
else if (t === "multiple") {
|
|
4238
|
+
const r = n.ctrlKey || n.metaKey;
|
|
4239
|
+
if (n.shiftKey && s.anchor !== null) {
|
|
4240
|
+
const l = Math.min(s.anchor, e), a = Math.max(s.anchor, e);
|
|
4241
|
+
for (let d = l; d <= a; d++)
|
|
4242
|
+
i.add(d);
|
|
4243
|
+
} else r ? (i.has(e) ? i.delete(e) : i.add(e), o = e) : (i.clear(), i.add(e), o = e);
|
|
4244
|
+
}
|
|
4245
|
+
return { selected: i, lastSelected: e, anchor: o };
|
|
4246
|
+
}
|
|
4247
|
+
function Zn(s) {
|
|
4248
|
+
const e = /* @__PURE__ */ new Set();
|
|
4249
|
+
for (let t = 0; t < s; t++)
|
|
4250
|
+
e.add(t);
|
|
4251
|
+
return e;
|
|
4252
|
+
}
|
|
4253
|
+
function Yn(s, e) {
|
|
4254
|
+
const t = [], n = [];
|
|
4255
|
+
for (const i of e)
|
|
4256
|
+
s.has(i) || t.push(i);
|
|
4257
|
+
for (const i of s)
|
|
4258
|
+
e.has(i) || n.push(i);
|
|
4259
|
+
return { added: t, removed: n };
|
|
4260
|
+
}
|
|
4261
|
+
function B(s) {
|
|
4224
4262
|
return {
|
|
4225
4263
|
startRow: Math.min(s.startRow, s.endRow),
|
|
4226
4264
|
startCol: Math.min(s.startCol, s.endCol),
|
|
@@ -4228,38 +4266,38 @@ function G(s) {
|
|
|
4228
4266
|
endCol: Math.max(s.startCol, s.endCol)
|
|
4229
4267
|
};
|
|
4230
4268
|
}
|
|
4231
|
-
function
|
|
4232
|
-
const e =
|
|
4269
|
+
function gn(s) {
|
|
4270
|
+
const e = B(s);
|
|
4233
4271
|
return {
|
|
4234
4272
|
from: { row: e.startRow, col: e.startCol },
|
|
4235
4273
|
to: { row: e.endRow, col: e.endCol }
|
|
4236
4274
|
};
|
|
4237
4275
|
}
|
|
4238
|
-
function
|
|
4239
|
-
return s.map(
|
|
4276
|
+
function Ve(s) {
|
|
4277
|
+
return s.map(gn);
|
|
4240
4278
|
}
|
|
4241
|
-
function
|
|
4242
|
-
const n =
|
|
4279
|
+
function pn(s, e, t) {
|
|
4280
|
+
const n = B(t);
|
|
4243
4281
|
return s >= n.startRow && s <= n.endRow && e >= n.startCol && e <= n.endCol;
|
|
4244
4282
|
}
|
|
4245
|
-
function
|
|
4246
|
-
return t.some((n) =>
|
|
4283
|
+
function Me(s, e, t) {
|
|
4284
|
+
return t.some((n) => pn(s, e, n));
|
|
4247
4285
|
}
|
|
4248
|
-
function
|
|
4249
|
-
const e = [], t =
|
|
4286
|
+
function mn(s) {
|
|
4287
|
+
const e = [], t = B(s);
|
|
4250
4288
|
for (let n = t.startRow; n <= t.endRow; n++)
|
|
4251
4289
|
for (let i = t.startCol; i <= t.endCol; i++)
|
|
4252
4290
|
e.push({ row: n, col: i });
|
|
4253
4291
|
return e;
|
|
4254
4292
|
}
|
|
4255
|
-
function
|
|
4293
|
+
function wn(s) {
|
|
4256
4294
|
const e = /* @__PURE__ */ new Map();
|
|
4257
4295
|
for (const t of s)
|
|
4258
|
-
for (const n of
|
|
4296
|
+
for (const n of mn(t))
|
|
4259
4297
|
e.set(`${n.row},${n.col}`, n);
|
|
4260
4298
|
return [...e.values()];
|
|
4261
4299
|
}
|
|
4262
|
-
function
|
|
4300
|
+
function J(s, e) {
|
|
4263
4301
|
return {
|
|
4264
4302
|
startRow: s.row,
|
|
4265
4303
|
startCol: s.col,
|
|
@@ -4267,8 +4305,8 @@ function ee(s, e) {
|
|
|
4267
4305
|
endCol: e.col
|
|
4268
4306
|
};
|
|
4269
4307
|
}
|
|
4270
|
-
const
|
|
4271
|
-
function
|
|
4308
|
+
const bn = ':host .selecting .data-grid-row>.cell{user-select:none}:host([data-has-focus]) .data-grid-row.row-focus{background-color:var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%))}:host([data-selection-mode="row"]) .cell-focus{outline:none}:host .data-grid-row>.cell.selected{background-color:var(--tbw-range-selection-bg)}:host .data-grid-row>.cell.selected.top{border-top:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.bottom{border-bottom:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.first{border-left:2px solid var(--tbw-range-border-color)}:host .data-grid-row>.cell.selected.last{border-right:2px solid var(--tbw-range-border-color)}:host .tbw-selection-summary{font-size:13px;color:var(--tbw-color-fg-muted);white-space:nowrap}';
|
|
4309
|
+
function vn(s, e, t) {
|
|
4272
4310
|
if (s === "cell" && e.selectedCell)
|
|
4273
4311
|
return {
|
|
4274
4312
|
mode: s,
|
|
@@ -4286,11 +4324,11 @@ function hn(s, e, t) {
|
|
|
4286
4324
|
}));
|
|
4287
4325
|
return { mode: s, ranges: n };
|
|
4288
4326
|
}
|
|
4289
|
-
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges:
|
|
4327
|
+
return s === "range" && e.ranges.length > 0 ? { mode: s, ranges: Ve(e.ranges) } : { mode: s, ranges: [] };
|
|
4290
4328
|
}
|
|
4291
|
-
class
|
|
4329
|
+
class Jn extends x {
|
|
4292
4330
|
name = "selection";
|
|
4293
|
-
|
|
4331
|
+
styles = bn;
|
|
4294
4332
|
get defaultConfig() {
|
|
4295
4333
|
return {
|
|
4296
4334
|
mode: "cell"
|
|
@@ -4318,32 +4356,34 @@ class Bn extends x {
|
|
|
4318
4356
|
// #endregion
|
|
4319
4357
|
// #region Event Handlers
|
|
4320
4358
|
onCellClick(e) {
|
|
4321
|
-
const { rowIndex: t, colIndex: n, originalEvent: i } = e, { mode: o } = this.config;
|
|
4359
|
+
const { rowIndex: t, colIndex: n, originalEvent: i } = e, { mode: o } = this.config, r = this.columns[n], l = r && _(r);
|
|
4322
4360
|
if (o === "cell")
|
|
4323
|
-
return this.selectedCell = { row: t, col: n }, this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
|
|
4361
|
+
return l || (this.selectedCell = { row: t, col: n }, this.emit("selection-change", this.#t()), this.requestAfterRender()), !1;
|
|
4324
4362
|
if (o === "row")
|
|
4325
4363
|
return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
|
|
4326
4364
|
if (o === "range") {
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4365
|
+
if (l)
|
|
4366
|
+
return !1;
|
|
4367
|
+
const a = i.shiftKey, d = i.ctrlKey || i.metaKey;
|
|
4368
|
+
if (a && this.cellAnchor) {
|
|
4369
|
+
const c = J(this.cellAnchor, { row: t, col: n });
|
|
4370
|
+
d ? this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = c : this.ranges.push(c) : this.ranges = [c], this.activeRange = c;
|
|
4371
|
+
} else if (d) {
|
|
4372
|
+
const c = {
|
|
4333
4373
|
startRow: t,
|
|
4334
4374
|
startCol: n,
|
|
4335
4375
|
endRow: t,
|
|
4336
4376
|
endCol: n
|
|
4337
4377
|
};
|
|
4338
|
-
this.ranges.push(
|
|
4378
|
+
this.ranges.push(c), this.activeRange = c, this.cellAnchor = { row: t, col: n };
|
|
4339
4379
|
} else {
|
|
4340
|
-
const
|
|
4380
|
+
const c = {
|
|
4341
4381
|
startRow: t,
|
|
4342
4382
|
startCol: n,
|
|
4343
4383
|
endRow: t,
|
|
4344
4384
|
endCol: n
|
|
4345
4385
|
};
|
|
4346
|
-
this.ranges = [
|
|
4386
|
+
this.ranges = [c], this.activeRange = c, this.cellAnchor = { row: t, col: n };
|
|
4347
4387
|
}
|
|
4348
4388
|
return this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
|
|
4349
4389
|
}
|
|
@@ -4380,23 +4420,31 @@ class Bn extends x {
|
|
|
4380
4420
|
return !1;
|
|
4381
4421
|
}
|
|
4382
4422
|
onCellMouseDown(e) {
|
|
4383
|
-
if (this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0
|
|
4423
|
+
if (this.config.mode !== "range" || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
4424
|
+
const t = this.columns[e.colIndex];
|
|
4425
|
+
if (t && _(t) || e.originalEvent.shiftKey && this.cellAnchor)
|
|
4384
4426
|
return;
|
|
4385
4427
|
this.isDragging = !0;
|
|
4386
|
-
const
|
|
4387
|
-
this.cellAnchor = { row:
|
|
4388
|
-
const
|
|
4389
|
-
startRow:
|
|
4390
|
-
startCol:
|
|
4391
|
-
endRow:
|
|
4392
|
-
endCol:
|
|
4428
|
+
const n = e.rowIndex, i = e.colIndex;
|
|
4429
|
+
this.cellAnchor = { row: n, col: i }, e.originalEvent.ctrlKey || e.originalEvent.metaKey || (this.ranges = []);
|
|
4430
|
+
const r = {
|
|
4431
|
+
startRow: n,
|
|
4432
|
+
startCol: i,
|
|
4433
|
+
endRow: n,
|
|
4434
|
+
endCol: i
|
|
4393
4435
|
};
|
|
4394
|
-
return this.ranges.push(
|
|
4436
|
+
return this.ranges.push(r), this.activeRange = r, this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
|
|
4395
4437
|
}
|
|
4396
4438
|
onCellMouseMove(e) {
|
|
4397
4439
|
if (this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
4398
|
-
|
|
4399
|
-
|
|
4440
|
+
let t = e.colIndex;
|
|
4441
|
+
const n = this.columns[t];
|
|
4442
|
+
if (n && _(n)) {
|
|
4443
|
+
const o = this.columns.findIndex((r) => !_(r));
|
|
4444
|
+
o >= 0 && (t = o);
|
|
4445
|
+
}
|
|
4446
|
+
const i = J(this.cellAnchor, { row: e.rowIndex, col: t });
|
|
4447
|
+
return this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] = i : this.ranges.push(i), this.activeRange = i, this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
|
|
4400
4448
|
}
|
|
4401
4449
|
onCellMouseUp(e) {
|
|
4402
4450
|
if (this.config.mode === "range" && this.isDragging)
|
|
@@ -4417,14 +4465,23 @@ class Bn extends x {
|
|
|
4417
4465
|
if (i.forEach((o) => {
|
|
4418
4466
|
o.classList.remove("selected", "row-focus");
|
|
4419
4467
|
}), t === "row" && (V(e), i.forEach((o) => {
|
|
4420
|
-
const r = o.querySelector(".cell[data-row]"), l =
|
|
4468
|
+
const r = o.querySelector(".cell[data-row]"), l = Ye(r);
|
|
4421
4469
|
l >= 0 && this.selected.has(l) && o.classList.add("selected", "row-focus");
|
|
4422
4470
|
})), t === "range" && this.ranges.length > 0) {
|
|
4423
4471
|
V(e);
|
|
4424
|
-
const o = this.activeRange ?
|
|
4425
|
-
e.querySelectorAll(".cell[data-row][data-col]").forEach((
|
|
4426
|
-
const
|
|
4427
|
-
|
|
4472
|
+
const o = this.activeRange ? B(this.activeRange) : null, r = this.columns.findIndex((a) => !_(a));
|
|
4473
|
+
this.columns.length - 1, e.querySelectorAll(".cell[data-row][data-col]").forEach((a) => {
|
|
4474
|
+
const d = parseInt(a.getAttribute("data-row") ?? "-1", 10), c = parseInt(a.getAttribute("data-col") ?? "-1", 10);
|
|
4475
|
+
if (d >= 0 && c >= 0) {
|
|
4476
|
+
const u = this.columns[c];
|
|
4477
|
+
if (u && _(u))
|
|
4478
|
+
return;
|
|
4479
|
+
if (Me(d, c, this.ranges) && (a.classList.add("selected"), o)) {
|
|
4480
|
+
d === o.startRow && a.classList.add("top"), d === o.endRow && a.classList.add("bottom");
|
|
4481
|
+
const f = Math.max(o.startCol, r);
|
|
4482
|
+
c === f && a.classList.add("first"), c === o.endCol && a.classList.add("last");
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4428
4485
|
});
|
|
4429
4486
|
}
|
|
4430
4487
|
t === "cell" && this.selectedCell && V(e);
|
|
@@ -4438,7 +4495,7 @@ class Bn extends x {
|
|
|
4438
4495
|
this.pendingKeyboardUpdate = null;
|
|
4439
4496
|
const o = this.grid._focusRow, r = this.grid._focusCol;
|
|
4440
4497
|
if (i && this.cellAnchor) {
|
|
4441
|
-
const l =
|
|
4498
|
+
const l = J(this.cellAnchor, { row: o, col: r });
|
|
4442
4499
|
this.ranges = [l], this.activeRange = l;
|
|
4443
4500
|
} else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: o, col: r });
|
|
4444
4501
|
this.emit("selection-change", this.#t());
|
|
@@ -4454,35 +4511,62 @@ class Bn extends x {
|
|
|
4454
4511
|
}
|
|
4455
4512
|
// #endregion
|
|
4456
4513
|
// #region Public API
|
|
4514
|
+
/**
|
|
4515
|
+
* Get the current selection as a unified result.
|
|
4516
|
+
* Works for all selection modes and always returns ranges.
|
|
4517
|
+
*
|
|
4518
|
+
* @example
|
|
4519
|
+
* ```ts
|
|
4520
|
+
* const selection = plugin.getSelection();
|
|
4521
|
+
* if (selection.ranges.length > 0) {
|
|
4522
|
+
* const { from, to } = selection.ranges[0];
|
|
4523
|
+
* // For cell mode: from === to (single cell)
|
|
4524
|
+
* // For row mode: from.col = 0, to.col = lastCol (full row)
|
|
4525
|
+
* // For range mode: rectangular selection
|
|
4526
|
+
* }
|
|
4527
|
+
* ```
|
|
4528
|
+
*/
|
|
4529
|
+
getSelection() {
|
|
4530
|
+
return {
|
|
4531
|
+
mode: this.config.mode,
|
|
4532
|
+
ranges: this.#t().ranges,
|
|
4533
|
+
anchor: this.cellAnchor
|
|
4534
|
+
};
|
|
4535
|
+
}
|
|
4457
4536
|
/**
|
|
4458
4537
|
* Get the selected cell (cell mode only).
|
|
4538
|
+
* @deprecated Use `getSelection()` instead for a unified API across all modes.
|
|
4459
4539
|
*/
|
|
4460
4540
|
getSelectedCell() {
|
|
4461
|
-
|
|
4541
|
+
const { mode: e, ranges: t } = this.getSelection();
|
|
4542
|
+
return e === "cell" && t.length > 0 ? t[0].from : null;
|
|
4462
4543
|
}
|
|
4463
4544
|
/**
|
|
4464
4545
|
* Get all selected row indices (row mode).
|
|
4546
|
+
* @deprecated Use `getSelection().ranges` instead - each range represents a full row.
|
|
4465
4547
|
*/
|
|
4466
4548
|
getSelectedRows() {
|
|
4467
|
-
|
|
4549
|
+
const { mode: e, ranges: t } = this.getSelection();
|
|
4550
|
+
return e === "row" ? t.map((n) => n.from.row) : [];
|
|
4468
4551
|
}
|
|
4469
4552
|
/**
|
|
4470
4553
|
* Get all selected cell ranges in public format.
|
|
4554
|
+
* @deprecated Use `getSelection().ranges` instead.
|
|
4471
4555
|
*/
|
|
4472
4556
|
getRanges() {
|
|
4473
|
-
return
|
|
4557
|
+
return this.getSelection().ranges;
|
|
4474
4558
|
}
|
|
4475
4559
|
/**
|
|
4476
4560
|
* Get all selected cells across all ranges.
|
|
4477
4561
|
*/
|
|
4478
4562
|
getSelectedCells() {
|
|
4479
|
-
return
|
|
4563
|
+
return wn(this.ranges);
|
|
4480
4564
|
}
|
|
4481
4565
|
/**
|
|
4482
4566
|
* Check if a specific cell is in range selection.
|
|
4483
4567
|
*/
|
|
4484
4568
|
isCellSelected(e, t) {
|
|
4485
|
-
return
|
|
4569
|
+
return Me(e, t, this.ranges);
|
|
4486
4570
|
}
|
|
4487
4571
|
/**
|
|
4488
4572
|
* Clear all selection.
|
|
@@ -4501,13 +4585,13 @@ class Bn extends x {
|
|
|
4501
4585
|
endCol: t.to.col
|
|
4502
4586
|
})), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
|
|
4503
4587
|
mode: this.config.mode,
|
|
4504
|
-
ranges:
|
|
4588
|
+
ranges: Ve(this.ranges)
|
|
4505
4589
|
}), this.requestAfterRender();
|
|
4506
4590
|
}
|
|
4507
4591
|
// #endregion
|
|
4508
4592
|
// #region Private Helpers
|
|
4509
4593
|
#t() {
|
|
4510
|
-
return
|
|
4594
|
+
return vn(
|
|
4511
4595
|
this.config.mode,
|
|
4512
4596
|
{
|
|
4513
4597
|
selectedCell: this.selectedCell,
|
|
@@ -4518,56 +4602,24 @@ class Bn extends x {
|
|
|
4518
4602
|
);
|
|
4519
4603
|
}
|
|
4520
4604
|
// #endregion
|
|
4521
|
-
// #region Styles
|
|
4522
|
-
styles = un;
|
|
4523
|
-
// #endregion
|
|
4524
4605
|
}
|
|
4525
|
-
function
|
|
4526
|
-
const i = new Set(s.selected);
|
|
4527
|
-
let o = s.anchor;
|
|
4528
|
-
if (t === "single")
|
|
4529
|
-
i.clear(), i.add(e), o = e;
|
|
4530
|
-
else if (t === "multiple") {
|
|
4531
|
-
const r = n.ctrlKey || n.metaKey;
|
|
4532
|
-
if (n.shiftKey && s.anchor !== null) {
|
|
4533
|
-
const l = Math.min(s.anchor, e), a = Math.max(s.anchor, e);
|
|
4534
|
-
for (let d = l; d <= a; d++)
|
|
4535
|
-
i.add(d);
|
|
4536
|
-
} else r ? (i.has(e) ? i.delete(e) : i.add(e), o = e) : (i.clear(), i.add(e), o = e);
|
|
4537
|
-
}
|
|
4538
|
-
return { selected: i, lastSelected: e, anchor: o };
|
|
4539
|
-
}
|
|
4540
|
-
function $n(s) {
|
|
4541
|
-
const e = /* @__PURE__ */ new Set();
|
|
4542
|
-
for (let t = 0; t < s; t++)
|
|
4543
|
-
e.add(t);
|
|
4544
|
-
return e;
|
|
4545
|
-
}
|
|
4546
|
-
function Wn(s, e) {
|
|
4547
|
-
const t = [], n = [];
|
|
4548
|
-
for (const i of e)
|
|
4549
|
-
s.has(i) || t.push(i);
|
|
4550
|
-
for (const i of s)
|
|
4551
|
-
e.has(i) || n.push(i);
|
|
4552
|
-
return { added: t, removed: n };
|
|
4553
|
-
}
|
|
4554
|
-
function O(s, e) {
|
|
4606
|
+
function G(s, e) {
|
|
4555
4607
|
return Math.floor(s / e);
|
|
4556
4608
|
}
|
|
4557
|
-
function
|
|
4609
|
+
function yn(s, e) {
|
|
4558
4610
|
return {
|
|
4559
4611
|
start: s * e,
|
|
4560
4612
|
end: (s + 1) * e
|
|
4561
4613
|
};
|
|
4562
4614
|
}
|
|
4563
|
-
function
|
|
4564
|
-
const n =
|
|
4615
|
+
function xn(s, e, t) {
|
|
4616
|
+
const n = G(s, t), i = G(e - 1, t), o = [];
|
|
4565
4617
|
for (let r = n; r <= i; r++)
|
|
4566
4618
|
o.push(r);
|
|
4567
4619
|
return o;
|
|
4568
4620
|
}
|
|
4569
|
-
async function
|
|
4570
|
-
const i =
|
|
4621
|
+
async function Pe(s, e, t, n) {
|
|
4622
|
+
const i = yn(e, t);
|
|
4571
4623
|
return s.getRows({
|
|
4572
4624
|
startRow: i.start,
|
|
4573
4625
|
endRow: i.end,
|
|
@@ -4575,16 +4627,15 @@ async function qe(s, e, t, n) {
|
|
|
4575
4627
|
filterModel: n.filterModel
|
|
4576
4628
|
});
|
|
4577
4629
|
}
|
|
4578
|
-
function
|
|
4579
|
-
const n =
|
|
4630
|
+
function Cn(s, e, t) {
|
|
4631
|
+
const n = G(s, e), i = t.get(n);
|
|
4580
4632
|
if (!i) return;
|
|
4581
4633
|
const o = s % e;
|
|
4582
4634
|
return i[o];
|
|
4583
4635
|
}
|
|
4584
|
-
const
|
|
4585
|
-
class
|
|
4636
|
+
const Rn = 100;
|
|
4637
|
+
class Qn extends x {
|
|
4586
4638
|
name = "serverSide";
|
|
4587
|
-
version = "1.0.0";
|
|
4588
4639
|
get defaultConfig() {
|
|
4589
4640
|
return {
|
|
4590
4641
|
pageSize: 100,
|
|
@@ -4611,12 +4662,12 @@ class jn extends x {
|
|
|
4611
4662
|
*/
|
|
4612
4663
|
loadRequiredBlocks() {
|
|
4613
4664
|
if (!this.dataSource) return;
|
|
4614
|
-
const e = this.grid, t = this.config.cacheBlockSize ?? 100, n = { startRow: e._virtualization.start, endRow: e._virtualization.end }, i =
|
|
4665
|
+
const e = this.grid, t = this.config.cacheBlockSize ?? 100, n = { startRow: e._virtualization.start, endRow: e._virtualization.end }, i = xn(n.startRow, n.endRow, t);
|
|
4615
4666
|
for (const o of i)
|
|
4616
4667
|
if (!(this.loadedBlocks.has(o) || this.loadingBlocks.has(o))) {
|
|
4617
4668
|
if (this.loadingBlocks.size >= (this.config.maxConcurrentRequests ?? 2))
|
|
4618
4669
|
break;
|
|
4619
|
-
this.loadingBlocks.add(o),
|
|
4670
|
+
this.loadingBlocks.add(o), Pe(this.dataSource, o, t, {}).then((r) => {
|
|
4620
4671
|
this.loadedBlocks.set(o, r.rows), this.totalRowCount = r.totalRowCount, this.loadingBlocks.delete(o), this.requestRender(), this.loadRequiredBlocks();
|
|
4621
4672
|
}).catch(() => {
|
|
4622
4673
|
this.loadingBlocks.delete(o);
|
|
@@ -4629,7 +4680,7 @@ class jn extends x {
|
|
|
4629
4680
|
if (!this.dataSource) return [...e];
|
|
4630
4681
|
const t = [];
|
|
4631
4682
|
for (let n = 0; n < this.totalRowCount; n++) {
|
|
4632
|
-
const i =
|
|
4683
|
+
const i = Cn(n, this.config.cacheBlockSize ?? 100, this.loadedBlocks);
|
|
4633
4684
|
t.push(i ?? { __loading: !0, __index: n });
|
|
4634
4685
|
}
|
|
4635
4686
|
return t;
|
|
@@ -4637,7 +4688,7 @@ class jn extends x {
|
|
|
4637
4688
|
onScroll(e) {
|
|
4638
4689
|
this.dataSource && (this.loadRequiredBlocks(), this.scrollDebounceTimer && clearTimeout(this.scrollDebounceTimer), this.scrollDebounceTimer = setTimeout(() => {
|
|
4639
4690
|
this.loadRequiredBlocks();
|
|
4640
|
-
},
|
|
4691
|
+
}, Rn));
|
|
4641
4692
|
}
|
|
4642
4693
|
// #endregion
|
|
4643
4694
|
// #region Public API
|
|
@@ -4648,7 +4699,7 @@ class jn extends x {
|
|
|
4648
4699
|
setDataSource(e) {
|
|
4649
4700
|
this.dataSource = e, this.loadedBlocks.clear(), this.loadingBlocks.clear();
|
|
4650
4701
|
const t = this.config.cacheBlockSize ?? 100;
|
|
4651
|
-
|
|
4702
|
+
Pe(e, 0, t, {}).then((n) => {
|
|
4652
4703
|
this.loadedBlocks.set(0, n.rows), this.totalRowCount = n.totalRowCount, this.requestRender();
|
|
4653
4704
|
});
|
|
4654
4705
|
}
|
|
@@ -4675,7 +4726,7 @@ class jn extends x {
|
|
|
4675
4726
|
* @param rowIndex - Row index to check
|
|
4676
4727
|
*/
|
|
4677
4728
|
isRowLoaded(e) {
|
|
4678
|
-
const t = this.config.cacheBlockSize ?? 100, n =
|
|
4729
|
+
const t = this.config.cacheBlockSize ?? 100, n = G(e, t);
|
|
4679
4730
|
return this.loadedBlocks.has(n);
|
|
4680
4731
|
}
|
|
4681
4732
|
/**
|
|
@@ -4686,52 +4737,52 @@ class jn extends x {
|
|
|
4686
4737
|
}
|
|
4687
4738
|
// #endregion
|
|
4688
4739
|
}
|
|
4689
|
-
function
|
|
4740
|
+
function ze(s, e, t) {
|
|
4690
4741
|
return s.id !== void 0 ? String(s.id) : t ? `${t}-${e}` : String(e);
|
|
4691
4742
|
}
|
|
4692
|
-
function
|
|
4743
|
+
function Q(s, e) {
|
|
4693
4744
|
const t = new Set(s);
|
|
4694
4745
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
4695
4746
|
}
|
|
4696
|
-
function
|
|
4747
|
+
function ne(s, e, t = null, n = 0) {
|
|
4697
4748
|
const i = e.childrenField ?? "children", o = /* @__PURE__ */ new Set();
|
|
4698
4749
|
for (let r = 0; r < s.length; r++) {
|
|
4699
|
-
const l = s[r], a =
|
|
4750
|
+
const l = s[r], a = ze(l, r, t), d = l[i];
|
|
4700
4751
|
if (Array.isArray(d) && d.length > 0) {
|
|
4701
4752
|
o.add(a);
|
|
4702
|
-
const c =
|
|
4703
|
-
for (const
|
|
4753
|
+
const c = ne(d, e, a, n + 1);
|
|
4754
|
+
for (const u of c) o.add(u);
|
|
4704
4755
|
}
|
|
4705
4756
|
}
|
|
4706
4757
|
return o;
|
|
4707
4758
|
}
|
|
4708
|
-
function
|
|
4759
|
+
function En() {
|
|
4709
4760
|
return /* @__PURE__ */ new Set();
|
|
4710
4761
|
}
|
|
4711
|
-
function
|
|
4762
|
+
function We(s, e, t, n = null, i = 0) {
|
|
4712
4763
|
const o = t.childrenField ?? "children";
|
|
4713
4764
|
for (let r = 0; r < s.length; r++) {
|
|
4714
|
-
const l = s[r], a =
|
|
4765
|
+
const l = s[r], a = ze(l, r, n);
|
|
4715
4766
|
if (a === e)
|
|
4716
4767
|
return [a];
|
|
4717
4768
|
const d = l[o];
|
|
4718
4769
|
if (Array.isArray(d) && d.length > 0) {
|
|
4719
|
-
const c =
|
|
4770
|
+
const c = We(d, e, t, a, i + 1);
|
|
4720
4771
|
if (c)
|
|
4721
4772
|
return [a, ...c];
|
|
4722
4773
|
}
|
|
4723
4774
|
}
|
|
4724
4775
|
return null;
|
|
4725
4776
|
}
|
|
4726
|
-
function
|
|
4727
|
-
const i =
|
|
4777
|
+
function Sn(s, e, t, n) {
|
|
4778
|
+
const i = We(s, e, t);
|
|
4728
4779
|
if (!i) return n;
|
|
4729
4780
|
const o = new Set(n);
|
|
4730
4781
|
for (let r = 0; r < i.length - 1; r++)
|
|
4731
4782
|
o.add(i[r]);
|
|
4732
4783
|
return o;
|
|
4733
4784
|
}
|
|
4734
|
-
function
|
|
4785
|
+
function De(s, e = "children") {
|
|
4735
4786
|
if (!Array.isArray(s) || s.length === 0) return !1;
|
|
4736
4787
|
for (const t of s) {
|
|
4737
4788
|
if (!t) continue;
|
|
@@ -4741,7 +4792,7 @@ function Ne(s, e = "children") {
|
|
|
4741
4792
|
}
|
|
4742
4793
|
return !1;
|
|
4743
4794
|
}
|
|
4744
|
-
function
|
|
4795
|
+
function kn(s) {
|
|
4745
4796
|
if (!Array.isArray(s) || s.length === 0) return null;
|
|
4746
4797
|
const e = ["children", "items", "nodes", "subRows", "nested"];
|
|
4747
4798
|
for (const t of s)
|
|
@@ -4753,35 +4804,34 @@ function vn(s) {
|
|
|
4753
4804
|
}
|
|
4754
4805
|
return null;
|
|
4755
4806
|
}
|
|
4756
|
-
function
|
|
4807
|
+
function An(s, e = "children", t = 0) {
|
|
4757
4808
|
if (!Array.isArray(s) || s.length === 0) return t;
|
|
4758
4809
|
let n = t;
|
|
4759
4810
|
for (const i of s) {
|
|
4760
4811
|
if (!i) continue;
|
|
4761
4812
|
const o = i[e];
|
|
4762
4813
|
if (Array.isArray(o) && o.length > 0) {
|
|
4763
|
-
const r =
|
|
4814
|
+
const r = An(o, e, t + 1);
|
|
4764
4815
|
r > n && (n = r);
|
|
4765
4816
|
}
|
|
4766
4817
|
}
|
|
4767
4818
|
return n;
|
|
4768
4819
|
}
|
|
4769
|
-
function
|
|
4820
|
+
function _n(s, e = "children") {
|
|
4770
4821
|
if (!Array.isArray(s)) return 0;
|
|
4771
4822
|
let t = 0;
|
|
4772
4823
|
for (const n of s) {
|
|
4773
4824
|
if (!n) continue;
|
|
4774
4825
|
t++;
|
|
4775
4826
|
const i = n[e];
|
|
4776
|
-
Array.isArray(i) && (t +=
|
|
4827
|
+
Array.isArray(i) && (t += _n(i, e));
|
|
4777
4828
|
}
|
|
4778
4829
|
return t;
|
|
4779
4830
|
}
|
|
4780
|
-
const
|
|
4781
|
-
class
|
|
4831
|
+
const Ln = ".cell[data-field=__tbw_expander]{border-right:none!important;padding:0;display:flex;align-items:center;justify-content:flex-start}.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)}.tree-expander{display:flex;align-items:center;justify-content:flex-start;width:100%;height:100%;box-sizing:border-box}.tree-toggle{cursor:pointer;user-select:none;display:inline-flex;align-items:center;justify-content:center}.tree-toggle:hover{color:var(--tbw-tree-accent, var(--tbw-color-accent))}.tree-spacer{width:14px;display:inline-block}.data-grid-row.tbw-tree-slide-in{animation:tbw-tree-slide-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-slide-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.data-grid-row.tbw-tree-fade-in{animation:tbw-tree-fade-in var(--tbw-animation-duration, .2s) var(--tbw-animation-easing, ease-out) forwards}@keyframes tbw-tree-fade-in{0%{opacity:0}to{opacity:1}}";
|
|
4832
|
+
class ei extends x {
|
|
4782
4833
|
name = "tree";
|
|
4783
|
-
|
|
4784
|
-
styles = Cn;
|
|
4834
|
+
styles = Ln;
|
|
4785
4835
|
get defaultConfig() {
|
|
4786
4836
|
return {
|
|
4787
4837
|
childrenField: "children",
|
|
@@ -4805,31 +4855,28 @@ class Un extends x {
|
|
|
4805
4855
|
}
|
|
4806
4856
|
// #endregion
|
|
4807
4857
|
// #region Animation
|
|
4858
|
+
/**
|
|
4859
|
+
* Get expand/collapse animation style from plugin config.
|
|
4860
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
4861
|
+
*/
|
|
4808
4862
|
get animationStyle() {
|
|
4809
|
-
|
|
4810
|
-
if (t === !1 || t === "off") return !1;
|
|
4811
|
-
if (t !== !0 && t !== "on") {
|
|
4812
|
-
const n = this.shadowRoot?.host;
|
|
4813
|
-
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
4814
|
-
return !1;
|
|
4815
|
-
}
|
|
4816
|
-
return this.config.animation ?? "slide";
|
|
4863
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
4817
4864
|
}
|
|
4818
4865
|
// #endregion
|
|
4819
4866
|
// #region Auto-Detection
|
|
4820
4867
|
detect(e) {
|
|
4821
4868
|
if (!this.config.autoDetect) return !1;
|
|
4822
|
-
const t = e, n = this.config.childrenField ??
|
|
4823
|
-
return
|
|
4869
|
+
const t = e, n = this.config.childrenField ?? kn(t) ?? "children";
|
|
4870
|
+
return De(t, n);
|
|
4824
4871
|
}
|
|
4825
4872
|
// #endregion
|
|
4826
4873
|
// #region Data Processing
|
|
4827
4874
|
processRows(e) {
|
|
4828
4875
|
const t = this.config.childrenField ?? "children", n = e;
|
|
4829
|
-
if (!
|
|
4876
|
+
if (!De(n, t))
|
|
4830
4877
|
return this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), [...e];
|
|
4831
4878
|
let i = this.withStableKeys(n);
|
|
4832
|
-
this.sortState && (i = this.sortTree(i, this.sortState.field, this.sortState.direction)), this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys =
|
|
4879
|
+
this.sortState && (i = this.sortTree(i, this.sortState.field, this.sortState.direction)), this.config.defaultExpanded && !this.initialExpansionDone && (this.expandedKeys = ne(i, this.config), this.initialExpansionDone = !0), this.flattenedRows = this.flattenTree(i, this.expandedKeys), this.rowKeyMap.clear(), this.keysToAnimate.clear();
|
|
4833
4880
|
const o = /* @__PURE__ */ new Set();
|
|
4834
4881
|
for (const r of this.flattenedRows)
|
|
4835
4882
|
this.rowKeyMap.set(r.key, r), o.add(r.key), !this.previousVisibleKeys.has(r.key) && r.depth > 0 && this.keysToAnimate.add(r.key);
|
|
@@ -4857,15 +4904,15 @@ class Un extends x {
|
|
|
4857
4904
|
flattenTree(e, t, n = 0) {
|
|
4858
4905
|
const i = this.config.childrenField ?? "children", o = [];
|
|
4859
4906
|
for (const r of e) {
|
|
4860
|
-
const a = r.__stableKey ?? String(r.id ?? "?"), d = r[i], c = Array.isArray(d) && d.length > 0,
|
|
4907
|
+
const a = r.__stableKey ?? String(r.id ?? "?"), d = r[i], c = Array.isArray(d) && d.length > 0, u = t.has(a);
|
|
4861
4908
|
o.push({
|
|
4862
4909
|
key: a,
|
|
4863
4910
|
data: r,
|
|
4864
4911
|
depth: n,
|
|
4865
4912
|
hasChildren: c,
|
|
4866
|
-
isExpanded:
|
|
4913
|
+
isExpanded: u,
|
|
4867
4914
|
parentKey: n > 0 && a.substring(0, a.lastIndexOf("-")) || null
|
|
4868
|
-
}), c &&
|
|
4915
|
+
}), c && u && o.push(...this.flattenTree(d, t, n + 1));
|
|
4869
4916
|
}
|
|
4870
4917
|
return o;
|
|
4871
4918
|
}
|
|
@@ -4884,40 +4931,52 @@ class Un extends x {
|
|
|
4884
4931
|
if (this.flattenedRows.length === 0) return [...e];
|
|
4885
4932
|
const t = [...e];
|
|
4886
4933
|
if (t.length === 0) return t;
|
|
4887
|
-
const n =
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
m instanceof Node ? w.appendChild(m) : w.textContent = String(m ?? c ?? "");
|
|
4934
|
+
const n = t[0], i = n.viewRenderer, o = () => this.config, r = this.setIcon.bind(this), l = this.resolveIcon.bind(this), a = (d) => {
|
|
4935
|
+
const { row: c, value: u } = d, { indentWidth: h = 20, showExpandIcons: f = !0 } = o(), g = c, p = g.__treeDepth ?? 0, b = document.createElement("span");
|
|
4936
|
+
if (b.className = "tree-cell-wrapper", b.style.paddingLeft = `${Number(p) * h}px`, f)
|
|
4937
|
+
if (g.__treeHasChildren) {
|
|
4938
|
+
const w = document.createElement("span");
|
|
4939
|
+
w.className = `tree-toggle${g.__treeExpanded ? " expanded" : ""}`, r(w, l(g.__treeExpanded ? "collapse" : "expand")), w.setAttribute("data-tree-key", String(g.__treeKey ?? "")), b.appendChild(w);
|
|
4940
|
+
} else {
|
|
4941
|
+
const w = document.createElement("span");
|
|
4942
|
+
w.className = "tree-spacer", b.appendChild(w);
|
|
4943
|
+
}
|
|
4944
|
+
const m = document.createElement("span");
|
|
4945
|
+
if (m.className = "tree-content", i) {
|
|
4946
|
+
const w = i(d);
|
|
4947
|
+
w instanceof Node ? m.appendChild(w) : typeof w == "string" && (m.innerHTML = w);
|
|
4902
4948
|
} else
|
|
4903
|
-
|
|
4904
|
-
return
|
|
4949
|
+
m.textContent = u != null ? String(u) : "";
|
|
4950
|
+
return b.appendChild(m), b;
|
|
4905
4951
|
};
|
|
4906
|
-
return
|
|
4952
|
+
return t[0] = { ...n, viewRenderer: a }, t;
|
|
4907
4953
|
}
|
|
4908
4954
|
// #endregion
|
|
4909
4955
|
// #region Event Handlers
|
|
4910
4956
|
onCellClick(e) {
|
|
4911
4957
|
const t = e.originalEvent?.target;
|
|
4912
4958
|
if (!t?.classList.contains("tree-toggle")) return !1;
|
|
4913
|
-
const n = t.getAttribute("data-tree-key")
|
|
4914
|
-
|
|
4959
|
+
const n = t.getAttribute("data-tree-key");
|
|
4960
|
+
if (!n) return !1;
|
|
4961
|
+
const i = this.rowKeyMap.get(n);
|
|
4962
|
+
return i ? (this.expandedKeys = Q(this.expandedKeys, n), this.emit("tree-expand", {
|
|
4915
4963
|
key: n,
|
|
4916
4964
|
row: i.data,
|
|
4917
4965
|
expanded: this.expandedKeys.has(n),
|
|
4918
4966
|
depth: i.depth
|
|
4919
4967
|
}), this.requestRender(), !0) : !1;
|
|
4920
4968
|
}
|
|
4969
|
+
onKeyDown(e) {
|
|
4970
|
+
if (e.key !== " ") return;
|
|
4971
|
+
const t = this.grid._focusRow, n = this.flattenedRows[t];
|
|
4972
|
+
if (n?.hasChildren)
|
|
4973
|
+
return e.preventDefault(), this.expandedKeys = Q(this.expandedKeys, n.key), this.emit("tree-expand", {
|
|
4974
|
+
key: n.key,
|
|
4975
|
+
row: n.data,
|
|
4976
|
+
expanded: this.expandedKeys.has(n.key),
|
|
4977
|
+
depth: n.depth
|
|
4978
|
+
}), this.requestRenderWithFocus(), !0;
|
|
4979
|
+
}
|
|
4921
4980
|
onHeaderClick(e) {
|
|
4922
4981
|
if (this.flattenedRows.length === 0 || !e.column.sortable) return !1;
|
|
4923
4982
|
const { field: t } = e.column;
|
|
@@ -4946,13 +5005,13 @@ class Un extends x {
|
|
|
4946
5005
|
this.expandedKeys.delete(e), this.requestRender();
|
|
4947
5006
|
}
|
|
4948
5007
|
toggle(e) {
|
|
4949
|
-
this.expandedKeys =
|
|
5008
|
+
this.expandedKeys = Q(this.expandedKeys, e), this.requestRender();
|
|
4950
5009
|
}
|
|
4951
5010
|
expandAll() {
|
|
4952
|
-
this.expandedKeys =
|
|
5011
|
+
this.expandedKeys = ne(this.rows, this.config), this.requestRender();
|
|
4953
5012
|
}
|
|
4954
5013
|
collapseAll() {
|
|
4955
|
-
this.expandedKeys =
|
|
5014
|
+
this.expandedKeys = En(), this.requestRender();
|
|
4956
5015
|
}
|
|
4957
5016
|
isExpanded(e) {
|
|
4958
5017
|
return this.expandedKeys.has(e);
|
|
@@ -4967,11 +5026,11 @@ class Un extends x {
|
|
|
4967
5026
|
return this.rowKeyMap.get(e)?.data;
|
|
4968
5027
|
}
|
|
4969
5028
|
expandToKey(e) {
|
|
4970
|
-
this.expandedKeys =
|
|
5029
|
+
this.expandedKeys = Sn(this.rows, e, this.config, this.expandedKeys), this.requestRender();
|
|
4971
5030
|
}
|
|
4972
5031
|
// #endregion
|
|
4973
5032
|
}
|
|
4974
|
-
function
|
|
5033
|
+
function Tn(s, e, t) {
|
|
4975
5034
|
const n = [...s.undoStack, e];
|
|
4976
5035
|
for (; n.length > t; )
|
|
4977
5036
|
n.shift();
|
|
@@ -4981,7 +5040,7 @@ function Rn(s, e, t) {
|
|
|
4981
5040
|
// Clear redo on new action
|
|
4982
5041
|
};
|
|
4983
5042
|
}
|
|
4984
|
-
function
|
|
5043
|
+
function Ke(s) {
|
|
4985
5044
|
if (s.undoStack.length === 0)
|
|
4986
5045
|
return { newState: s, action: null };
|
|
4987
5046
|
const e = [...s.undoStack], t = e.pop();
|
|
@@ -4993,7 +5052,7 @@ function De(s) {
|
|
|
4993
5052
|
action: t
|
|
4994
5053
|
} : { newState: s, action: null };
|
|
4995
5054
|
}
|
|
4996
|
-
function
|
|
5055
|
+
function qe(s) {
|
|
4997
5056
|
if (s.redoStack.length === 0)
|
|
4998
5057
|
return { newState: s, action: null };
|
|
4999
5058
|
const e = [...s.redoStack], t = e.pop();
|
|
@@ -5005,16 +5064,16 @@ function He(s) {
|
|
|
5005
5064
|
action: t
|
|
5006
5065
|
} : { newState: s, action: null };
|
|
5007
5066
|
}
|
|
5008
|
-
function
|
|
5067
|
+
function In(s) {
|
|
5009
5068
|
return s.undoStack.length > 0;
|
|
5010
5069
|
}
|
|
5011
|
-
function
|
|
5070
|
+
function Fn(s) {
|
|
5012
5071
|
return s.redoStack.length > 0;
|
|
5013
5072
|
}
|
|
5014
|
-
function
|
|
5073
|
+
function Mn() {
|
|
5015
5074
|
return { undoStack: [], redoStack: [] };
|
|
5016
5075
|
}
|
|
5017
|
-
function
|
|
5076
|
+
function Pn(s, e, t, n) {
|
|
5018
5077
|
return {
|
|
5019
5078
|
type: "cell-edit",
|
|
5020
5079
|
rowIndex: s,
|
|
@@ -5024,9 +5083,16 @@ function An(s, e, t, n) {
|
|
|
5024
5083
|
timestamp: Date.now()
|
|
5025
5084
|
};
|
|
5026
5085
|
}
|
|
5027
|
-
class
|
|
5086
|
+
class ti extends x {
|
|
5087
|
+
/**
|
|
5088
|
+
* Plugin dependencies - UndoRedoPlugin requires EditingPlugin to track edits.
|
|
5089
|
+
*
|
|
5090
|
+
* The EditingPlugin must be loaded BEFORE this plugin in the plugins array.
|
|
5091
|
+
*/
|
|
5092
|
+
static dependencies = [
|
|
5093
|
+
{ name: "editing", required: !0, reason: "UndoRedoPlugin tracks cell edit history" }
|
|
5094
|
+
];
|
|
5028
5095
|
name = "undoRedo";
|
|
5029
|
-
version = "1.0.0";
|
|
5030
5096
|
get defaultConfig() {
|
|
5031
5097
|
return {
|
|
5032
5098
|
maxHistorySize: 100
|
|
@@ -5049,7 +5115,7 @@ class Zn extends x {
|
|
|
5049
5115
|
onKeyDown(e) {
|
|
5050
5116
|
const t = (e.ctrlKey || e.metaKey) && e.key === "z" && !e.shiftKey, n = (e.ctrlKey || e.metaKey) && (e.key === "y" || e.key === "z" && e.shiftKey);
|
|
5051
5117
|
if (t) {
|
|
5052
|
-
const i =
|
|
5118
|
+
const i = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5053
5119
|
if (i.action) {
|
|
5054
5120
|
const o = this.rows;
|
|
5055
5121
|
o[i.action.rowIndex] && (o[i.action.rowIndex][i.action.field] = i.action.oldValue), this.undoStack = i.newState.undoStack, this.redoStack = i.newState.redoStack, this.emit("undo", {
|
|
@@ -5060,7 +5126,7 @@ class Zn extends x {
|
|
|
5060
5126
|
return !0;
|
|
5061
5127
|
}
|
|
5062
5128
|
if (n) {
|
|
5063
|
-
const i =
|
|
5129
|
+
const i = qe({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5064
5130
|
if (i.action) {
|
|
5065
5131
|
const o = this.rows;
|
|
5066
5132
|
o[i.action.rowIndex] && (o[i.action.rowIndex][i.action.field] = i.action.newValue), this.undoStack = i.newState.undoStack, this.redoStack = i.newState.redoStack, this.emit("redo", {
|
|
@@ -5083,7 +5149,7 @@ class Zn extends x {
|
|
|
5083
5149
|
* @param newValue - The value after the edit
|
|
5084
5150
|
*/
|
|
5085
5151
|
recordEdit(e, t, n, i) {
|
|
5086
|
-
const o =
|
|
5152
|
+
const o = Pn(e, t, n, i), r = Tn(
|
|
5087
5153
|
{ undoStack: this.undoStack, redoStack: this.redoStack },
|
|
5088
5154
|
o,
|
|
5089
5155
|
this.config.maxHistorySize ?? 100
|
|
@@ -5096,7 +5162,7 @@ class Zn extends x {
|
|
|
5096
5162
|
* @returns The undone action, or null if nothing to undo
|
|
5097
5163
|
*/
|
|
5098
5164
|
undo() {
|
|
5099
|
-
const e =
|
|
5165
|
+
const e = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5100
5166
|
if (e.action) {
|
|
5101
5167
|
const t = this.rows;
|
|
5102
5168
|
t[e.action.rowIndex] && (t[e.action.rowIndex][e.action.field] = e.action.oldValue), this.undoStack = e.newState.undoStack, this.redoStack = e.newState.redoStack, this.requestRender();
|
|
@@ -5109,7 +5175,7 @@ class Zn extends x {
|
|
|
5109
5175
|
* @returns The redone action, or null if nothing to redo
|
|
5110
5176
|
*/
|
|
5111
5177
|
redo() {
|
|
5112
|
-
const e =
|
|
5178
|
+
const e = qe({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5113
5179
|
if (e.action) {
|
|
5114
5180
|
const t = this.rows;
|
|
5115
5181
|
t[e.action.rowIndex] && (t[e.action.rowIndex][e.action.field] = e.action.newValue), this.undoStack = e.newState.undoStack, this.redoStack = e.newState.redoStack, this.requestRender();
|
|
@@ -5120,19 +5186,19 @@ class Zn extends x {
|
|
|
5120
5186
|
* Check if there are any actions that can be undone.
|
|
5121
5187
|
*/
|
|
5122
5188
|
canUndo() {
|
|
5123
|
-
return
|
|
5189
|
+
return In({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5124
5190
|
}
|
|
5125
5191
|
/**
|
|
5126
5192
|
* Check if there are any actions that can be redone.
|
|
5127
5193
|
*/
|
|
5128
5194
|
canRedo() {
|
|
5129
|
-
return
|
|
5195
|
+
return Fn({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5130
5196
|
}
|
|
5131
5197
|
/**
|
|
5132
5198
|
* Clear all undo/redo history.
|
|
5133
5199
|
*/
|
|
5134
5200
|
clearHistory() {
|
|
5135
|
-
const e =
|
|
5201
|
+
const e = Mn();
|
|
5136
5202
|
this.undoStack = e.undoStack, this.redoStack = e.redoStack;
|
|
5137
5203
|
}
|
|
5138
5204
|
/**
|
|
@@ -5149,16 +5215,24 @@ class Zn extends x {
|
|
|
5149
5215
|
}
|
|
5150
5216
|
// #endregion
|
|
5151
5217
|
}
|
|
5152
|
-
const
|
|
5153
|
-
function
|
|
5218
|
+
const Dn = '.tbw-visibility-content{display:flex;flex-direction:column;height:100%}.tbw-visibility-list{flex:1;overflow-y:auto;padding:8px}.tbw-visibility-row{display:flex;align-items:center;gap:8px;padding:6px 4px;cursor:pointer;font-size:13px;border-radius:var(--tbw-border-radius, 4px);position:relative}.tbw-visibility-row:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}.tbw-visibility-row input[type=checkbox]{cursor:pointer}.tbw-visibility-row.locked span{color:var(--tbw-color-fg-muted, #888)}.tbw-visibility-handle{cursor:grab;color:var(--tbw-color-fg-muted, #888);font-size:10px;letter-spacing:-2px;user-select:none;flex-shrink:0}.tbw-visibility-row.reorderable:hover .tbw-visibility-handle{color:var(--tbw-color-fg, #1f2937)}.tbw-visibility-label{display:flex;align-items:center;gap:8px;flex:1;cursor:pointer}.tbw-visibility-row.dragging{opacity:.5;cursor:grabbing}.tbw-visibility-row.drop-before:before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-row.drop-after:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6))}.tbw-visibility-show-all{margin:8px;padding:8px 12px;border:1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));border-radius:var(--tbw-border-radius, 4px);background:var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));color:var(--tbw-color-fg, #1f2937);cursor:pointer;font-size:13px}.tbw-visibility-show-all:hover{background:var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6))}';
|
|
5219
|
+
function Ne(s) {
|
|
5154
5220
|
const e = s.meta ?? {};
|
|
5155
5221
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
5156
5222
|
}
|
|
5157
|
-
class
|
|
5223
|
+
class M extends x {
|
|
5224
|
+
/**
|
|
5225
|
+
* Plugin dependencies - VisibilityPlugin optionally uses ReorderPlugin for drag-drop reordering.
|
|
5226
|
+
*
|
|
5227
|
+
* When ReorderPlugin is present, columns in the visibility panel become draggable.
|
|
5228
|
+
*/
|
|
5229
|
+
static dependencies = [
|
|
5230
|
+
{ name: "reorder", required: !1, reason: "Enables drag-to-reorder columns in visibility panel" }
|
|
5231
|
+
];
|
|
5158
5232
|
name = "visibility";
|
|
5159
|
-
version = "1.0.0";
|
|
5160
5233
|
/** Tool panel ID for shell integration */
|
|
5161
5234
|
static PANEL_ID = "columns";
|
|
5235
|
+
styles = Dn;
|
|
5162
5236
|
get defaultConfig() {
|
|
5163
5237
|
return {
|
|
5164
5238
|
allowHideAll: !1
|
|
@@ -5171,6 +5245,12 @@ class P extends x {
|
|
|
5171
5245
|
draggedField = null;
|
|
5172
5246
|
draggedIndex = null;
|
|
5173
5247
|
dropIndex = null;
|
|
5248
|
+
/** Clear drag-related classes from all rows in a list. */
|
|
5249
|
+
clearDragClasses(e) {
|
|
5250
|
+
e.querySelectorAll(".tbw-visibility-row").forEach((t) => {
|
|
5251
|
+
t.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
|
|
5252
|
+
});
|
|
5253
|
+
}
|
|
5174
5254
|
// #endregion
|
|
5175
5255
|
// #region Lifecycle
|
|
5176
5256
|
detach() {
|
|
@@ -5183,7 +5263,7 @@ class P extends x {
|
|
|
5183
5263
|
*/
|
|
5184
5264
|
getToolPanel() {
|
|
5185
5265
|
return {
|
|
5186
|
-
id:
|
|
5266
|
+
id: M.PANEL_ID,
|
|
5187
5267
|
title: "Columns",
|
|
5188
5268
|
icon: "☰",
|
|
5189
5269
|
tooltip: "Column visibility",
|
|
@@ -5196,9 +5276,10 @@ class P extends x {
|
|
|
5196
5276
|
// #region Public API
|
|
5197
5277
|
/**
|
|
5198
5278
|
* Show the visibility sidebar panel.
|
|
5279
|
+
* Opens the tool panel and ensures this section is expanded.
|
|
5199
5280
|
*/
|
|
5200
5281
|
show() {
|
|
5201
|
-
this.grid.openToolPanel(
|
|
5282
|
+
this.grid.openToolPanel(), this.grid.expandedToolPanelSections.includes(M.PANEL_ID) || this.grid.toggleToolPanelSection(M.PANEL_ID);
|
|
5202
5283
|
}
|
|
5203
5284
|
/**
|
|
5204
5285
|
* Hide the visibility sidebar panel.
|
|
@@ -5207,10 +5288,10 @@ class P extends x {
|
|
|
5207
5288
|
this.grid.closeToolPanel();
|
|
5208
5289
|
}
|
|
5209
5290
|
/**
|
|
5210
|
-
* Toggle the visibility sidebar panel.
|
|
5291
|
+
* Toggle the visibility sidebar panel section.
|
|
5211
5292
|
*/
|
|
5212
5293
|
toggle() {
|
|
5213
|
-
this.grid.
|
|
5294
|
+
this.grid.isToolPanelOpen || this.grid.openToolPanel(), this.grid.toggleToolPanelSection(M.PANEL_ID);
|
|
5214
5295
|
}
|
|
5215
5296
|
/**
|
|
5216
5297
|
* Check if a specific column is visible.
|
|
@@ -5235,14 +5316,14 @@ class P extends x {
|
|
|
5235
5316
|
* @returns Array of visible field names
|
|
5236
5317
|
*/
|
|
5237
5318
|
getVisibleColumns() {
|
|
5238
|
-
return this.grid.getAllColumns().filter((
|
|
5319
|
+
return this.grid.getAllColumns().filter((e) => e.visible).map((e) => e.field);
|
|
5239
5320
|
}
|
|
5240
5321
|
/**
|
|
5241
5322
|
* Get list of all hidden column fields.
|
|
5242
5323
|
* @returns Array of hidden field names
|
|
5243
5324
|
*/
|
|
5244
5325
|
getHiddenColumns() {
|
|
5245
|
-
return this.grid.getAllColumns().filter((
|
|
5326
|
+
return this.grid.getAllColumns().filter((e) => !e.visible).map((e) => e.field);
|
|
5246
5327
|
}
|
|
5247
5328
|
/**
|
|
5248
5329
|
* Show all columns.
|
|
@@ -5265,7 +5346,7 @@ class P extends x {
|
|
|
5265
5346
|
* @param field - The field name of the column to show
|
|
5266
5347
|
*/
|
|
5267
5348
|
showColumn(e) {
|
|
5268
|
-
this.
|
|
5349
|
+
this.setColumnVisible(e, !0);
|
|
5269
5350
|
}
|
|
5270
5351
|
/**
|
|
5271
5352
|
* Hide a specific column.
|
|
@@ -5273,7 +5354,7 @@ class P extends x {
|
|
|
5273
5354
|
* @param field - The field name of the column to hide
|
|
5274
5355
|
*/
|
|
5275
5356
|
hideColumn(e) {
|
|
5276
|
-
this.
|
|
5357
|
+
this.setColumnVisible(e, !1);
|
|
5277
5358
|
}
|
|
5278
5359
|
/**
|
|
5279
5360
|
* Get all columns with their visibility status.
|
|
@@ -5285,10 +5366,10 @@ class P extends x {
|
|
|
5285
5366
|
}
|
|
5286
5367
|
/**
|
|
5287
5368
|
* Check if the sidebar panel is currently open.
|
|
5288
|
-
* @returns True if the panel is
|
|
5369
|
+
* @returns True if the panel section is expanded
|
|
5289
5370
|
*/
|
|
5290
5371
|
isPanelVisible() {
|
|
5291
|
-
return this.grid.
|
|
5372
|
+
return this.grid.isToolPanelOpen && this.grid.expandedToolPanelSections.includes(M.PANEL_ID);
|
|
5292
5373
|
}
|
|
5293
5374
|
// #endregion
|
|
5294
5375
|
// #region Private Methods
|
|
@@ -5297,15 +5378,15 @@ class P extends x {
|
|
|
5297
5378
|
* Returns a cleanup function.
|
|
5298
5379
|
*/
|
|
5299
5380
|
renderPanelContent(e) {
|
|
5300
|
-
const t =
|
|
5301
|
-
|
|
5302
|
-
const
|
|
5303
|
-
|
|
5304
|
-
const
|
|
5305
|
-
return
|
|
5306
|
-
|
|
5307
|
-
}),
|
|
5308
|
-
this.columnListElement = null,
|
|
5381
|
+
const t = document.createElement("div");
|
|
5382
|
+
t.className = "tbw-visibility-content";
|
|
5383
|
+
const n = document.createElement("div");
|
|
5384
|
+
n.className = "tbw-visibility-list", t.appendChild(n);
|
|
5385
|
+
const i = document.createElement("button");
|
|
5386
|
+
return i.className = "tbw-visibility-show-all", i.textContent = "Show All", i.addEventListener("click", () => {
|
|
5387
|
+
this.grid.showAllColumns(), this.rebuildToggles(n);
|
|
5388
|
+
}), t.appendChild(i), this.columnListElement = n, this.rebuildToggles(n), e.appendChild(t), () => {
|
|
5389
|
+
this.columnListElement = null, t.remove();
|
|
5309
5390
|
};
|
|
5310
5391
|
}
|
|
5311
5392
|
/**
|
|
@@ -5320,24 +5401,24 @@ class P extends x {
|
|
|
5320
5401
|
* When a reorder plugin is present, adds drag handles for reordering.
|
|
5321
5402
|
*/
|
|
5322
5403
|
rebuildToggles(e) {
|
|
5323
|
-
const t = this.
|
|
5404
|
+
const t = this.hasReorderPlugin();
|
|
5324
5405
|
e.innerHTML = "";
|
|
5325
|
-
const
|
|
5326
|
-
for (let
|
|
5327
|
-
const
|
|
5328
|
-
|
|
5329
|
-
const
|
|
5330
|
-
|
|
5331
|
-
const
|
|
5332
|
-
|
|
5333
|
-
|
|
5406
|
+
const n = this.grid.getAllColumns().filter((i) => !i.utility);
|
|
5407
|
+
for (let i = 0; i < n.length; i++) {
|
|
5408
|
+
const o = n[i], r = o.header || o.field, l = document.createElement("div");
|
|
5409
|
+
l.className = o.lockVisible ? "tbw-visibility-row locked" : "tbw-visibility-row", l.setAttribute("data-field", o.field), l.setAttribute("data-index", String(i)), t && Ne(o) && (l.draggable = !0, l.classList.add("reorderable"), this.setupDragListeners(l, o.field, i, e));
|
|
5410
|
+
const a = document.createElement("label");
|
|
5411
|
+
a.className = "tbw-visibility-label";
|
|
5412
|
+
const d = document.createElement("input");
|
|
5413
|
+
d.type = "checkbox", d.checked = o.visible, d.disabled = o.lockVisible ?? !1, d.addEventListener("change", () => {
|
|
5414
|
+
this.grid.toggleColumnVisibility(o.field), setTimeout(() => this.rebuildToggles(e), 0);
|
|
5334
5415
|
});
|
|
5335
|
-
const
|
|
5336
|
-
if (
|
|
5416
|
+
const c = document.createElement("span");
|
|
5417
|
+
if (c.textContent = r, a.appendChild(d), a.appendChild(c), t && Ne(o)) {
|
|
5337
5418
|
const u = document.createElement("span");
|
|
5338
|
-
u.className = "tbw-visibility-handle", this.setIcon(u, this.resolveIcon("dragHandle")), u.title = "Drag to reorder",
|
|
5419
|
+
u.className = "tbw-visibility-handle", this.setIcon(u, this.resolveIcon("dragHandle")), u.title = "Drag to reorder", l.appendChild(u);
|
|
5339
5420
|
}
|
|
5340
|
-
|
|
5421
|
+
l.appendChild(a), e.appendChild(l);
|
|
5341
5422
|
}
|
|
5342
5423
|
}
|
|
5343
5424
|
/**
|
|
@@ -5348,9 +5429,7 @@ class P extends x {
|
|
|
5348
5429
|
e.addEventListener("dragstart", (o) => {
|
|
5349
5430
|
this.isDragging = !0, this.draggedField = t, this.draggedIndex = n, o.dataTransfer && (o.dataTransfer.effectAllowed = "move", o.dataTransfer.setData("text/plain", t)), e.classList.add("dragging");
|
|
5350
5431
|
}), e.addEventListener("dragend", () => {
|
|
5351
|
-
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null,
|
|
5352
|
-
o.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
|
|
5353
|
-
});
|
|
5432
|
+
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses(i);
|
|
5354
5433
|
}), e.addEventListener("dragover", (o) => {
|
|
5355
5434
|
if (o.preventDefault(), !this.isDragging || this.draggedField === t) return;
|
|
5356
5435
|
const r = e.getBoundingClientRect(), l = r.top + r.height / 2;
|
|
@@ -5378,57 +5457,55 @@ class P extends x {
|
|
|
5378
5457
|
});
|
|
5379
5458
|
}
|
|
5380
5459
|
// #endregion
|
|
5381
|
-
// #region Styles
|
|
5382
|
-
styles = _n;
|
|
5383
|
-
// #endregion
|
|
5384
5460
|
}
|
|
5385
5461
|
export {
|
|
5386
5462
|
x as BaseGridPlugin,
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5463
|
+
qn as ClipboardPlugin,
|
|
5464
|
+
Nn as ColumnVirtualizationPlugin,
|
|
5465
|
+
Hn as ContextMenuPlugin,
|
|
5466
|
+
oi as DEFAULT_ANIMATION_CONFIG,
|
|
5467
|
+
$e as DEFAULT_GRID_ICONS,
|
|
5468
|
+
ri as DGEvents,
|
|
5469
|
+
si as DataGridElement,
|
|
5470
|
+
Gn as EditingPlugin,
|
|
5471
|
+
Bn as ExportPlugin,
|
|
5396
5472
|
U as FOCUSABLE_EDITOR_SELECTOR,
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5473
|
+
L as FilteringPlugin,
|
|
5474
|
+
li as FitModeEnum,
|
|
5475
|
+
ai as GridCSSVars,
|
|
5476
|
+
di as GridClasses,
|
|
5477
|
+
ci as GridDataAttrs,
|
|
5478
|
+
ui as GridElement,
|
|
5479
|
+
hi as GridSelectors,
|
|
5480
|
+
Vn as GroupingColumnsPlugin,
|
|
5481
|
+
zn as GroupingRowsPlugin,
|
|
5482
|
+
Ge as MasterDetailPlugin,
|
|
5483
|
+
Wn as MultiSortPlugin,
|
|
5484
|
+
He as PLUGIN_QUERIES,
|
|
5485
|
+
$n as PinnedColumnsPlugin,
|
|
5486
|
+
jn as PinnedRowsPlugin,
|
|
5487
|
+
F as PivotPlugin,
|
|
5488
|
+
fi as PluginEvents,
|
|
5489
|
+
gi as PluginManager,
|
|
5490
|
+
pi as RenderPhase,
|
|
5491
|
+
Un as ReorderPlugin,
|
|
5492
|
+
Jn as SelectionPlugin,
|
|
5493
|
+
Qn as ServerSidePlugin,
|
|
5494
|
+
ei as TreePlugin,
|
|
5495
|
+
ti as UndoRedoPlugin,
|
|
5496
|
+
M as VisibilityPlugin,
|
|
5497
|
+
mi as builtInSort,
|
|
5498
|
+
dt as clearEditingState,
|
|
5499
|
+
Yn as computeSelectionDiff,
|
|
5500
|
+
_n as countNodes,
|
|
5501
|
+
wi as defaultComparator,
|
|
5502
|
+
lt as defaultEditorFor,
|
|
5503
|
+
nt as defaultPasteHandler,
|
|
5504
|
+
De as detectTreeStructure,
|
|
5505
|
+
An as getMaxDepth,
|
|
5506
|
+
Xn as handleRowClick,
|
|
5507
|
+
On as hasEditingCells,
|
|
5508
|
+
kn as inferChildrenField,
|
|
5509
|
+
Zn as selectAll
|
|
5433
5510
|
};
|
|
5434
5511
|
//# sourceMappingURL=all.js.map
|