@toolbox-web/grid 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -13
- package/all.js +1101 -1048
- package/all.js.map +1 -1
- package/index.js +245 -137
- package/index.js.map +1 -1
- package/lib/core/grid.d.ts +10 -0
- package/lib/core/grid.d.ts.map +1 -1
- package/lib/core/internal/config-manager.d.ts +1 -0
- package/lib/core/internal/config-manager.d.ts.map +1 -1
- package/lib/core/internal/keyboard.d.ts.map +1 -1
- package/lib/core/internal/utils.d.ts +1 -0
- package/lib/core/internal/utils.d.ts.map +1 -1
- package/lib/core/plugin/base-plugin.d.ts +57 -1
- package/lib/core/plugin/base-plugin.d.ts.map +1 -1
- package/lib/core/plugin/expander-column.d.ts +51 -0
- package/lib/core/plugin/expander-column.d.ts.map +1 -0
- package/lib/core/plugin/types.d.ts +117 -1
- package/lib/core/plugin/types.d.ts.map +1 -1
- package/lib/core/types.d.ts +4 -2
- package/lib/core/types.d.ts.map +1 -1
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts +5 -4
- package/lib/plugins/clipboard/ClipboardPlugin.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.d.ts +1 -1
- package/lib/plugins/clipboard/index.d.ts.map +1 -1
- package/lib/plugins/clipboard/index.js +282 -188
- package/lib/plugins/clipboard/index.js.map +1 -1
- package/lib/plugins/clipboard/types.d.ts +72 -2
- package/lib/plugins/clipboard/types.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts +0 -1
- package/lib/plugins/column-virtualization/ColumnVirtualizationPlugin.d.ts.map +1 -1
- package/lib/plugins/column-virtualization/index.js +102 -26
- package/lib/plugins/column-virtualization/index.js.map +1 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts +0 -1
- package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
- package/lib/plugins/context-menu/index.js +154 -78
- package/lib/plugins/context-menu/index.js.map +1 -1
- package/lib/plugins/editing/EditingPlugin.d.ts +1 -7
- package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
- package/lib/plugins/editing/index.js +200 -136
- package/lib/plugins/editing/index.js.map +1 -1
- package/lib/plugins/export/ExportPlugin.d.ts +0 -1
- package/lib/plugins/export/ExportPlugin.d.ts.map +1 -1
- package/lib/plugins/export/index.js +175 -99
- package/lib/plugins/export/index.js.map +1 -1
- package/lib/plugins/filtering/FilteringPlugin.d.ts +5 -2
- package/lib/plugins/filtering/FilteringPlugin.d.ts.map +1 -1
- package/lib/plugins/filtering/index.js +129 -43
- package/lib/plugins/filtering/index.js.map +1 -1
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +1 -2
- package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts +1 -1
- package/lib/plugins/grouping-columns/grouping-columns.d.ts.map +1 -1
- package/lib/plugins/grouping-columns/index.js +144 -66
- package/lib/plugins/grouping-columns/index.js.map +1 -1
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts +14 -2
- package/lib/plugins/grouping-rows/GroupingRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/grouping-rows/index.js +230 -138
- package/lib/plugins/grouping-rows/index.js.map +1 -1
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +13 -11
- package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
- package/lib/plugins/master-detail/index.js +265 -196
- package/lib/plugins/master-detail/index.js.map +1 -1
- package/lib/plugins/master-detail/types.d.ts +0 -10
- package/lib/plugins/master-detail/types.d.ts.map +1 -1
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts +1 -2
- package/lib/plugins/multi-sort/MultiSortPlugin.d.ts.map +1 -1
- package/lib/plugins/multi-sort/index.js +105 -31
- package/lib/plugins/multi-sort/index.js.map +1 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts +0 -1
- package/lib/plugins/pinned-columns/PinnedColumnsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-columns/index.js +128 -52
- package/lib/plugins/pinned-columns/index.js.map +1 -1
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts +1 -2
- package/lib/plugins/pinned-rows/PinnedRowsPlugin.d.ts.map +1 -1
- package/lib/plugins/pinned-rows/index.js +162 -88
- package/lib/plugins/pinned-rows/index.js.map +1 -1
- package/lib/plugins/pivot/PivotPlugin.d.ts +26 -4
- package/lib/plugins/pivot/PivotPlugin.d.ts.map +1 -1
- package/lib/plugins/pivot/index.js +398 -310
- package/lib/plugins/pivot/index.js.map +1 -1
- package/lib/plugins/pivot/pivot-rows.d.ts +2 -1
- package/lib/plugins/pivot/pivot-rows.d.ts.map +1 -1
- package/lib/plugins/reorder/ReorderPlugin.d.ts +13 -10
- package/lib/plugins/reorder/ReorderPlugin.d.ts.map +1 -1
- package/lib/plugins/reorder/index.js +288 -226
- package/lib/plugins/reorder/index.js.map +1 -1
- package/lib/plugins/selection/SelectionPlugin.d.ts +21 -3
- package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
- package/lib/plugins/selection/index.d.ts +2 -2
- package/lib/plugins/selection/index.d.ts.map +1 -1
- package/lib/plugins/selection/index.js +276 -145
- package/lib/plugins/selection/index.js.map +1 -1
- package/lib/plugins/selection/types.d.ts +24 -0
- package/lib/plugins/selection/types.d.ts.map +1 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts +0 -1
- package/lib/plugins/server-side/ServerSidePlugin.d.ts.map +1 -1
- package/lib/plugins/server-side/index.js +83 -7
- package/lib/plugins/server-side/index.js.map +1 -1
- package/lib/plugins/tree/TreePlugin.d.ts +5 -1
- package/lib/plugins/tree/TreePlugin.d.ts.map +1 -1
- package/lib/plugins/tree/index.js +197 -112
- package/lib/plugins/tree/index.js.map +1 -1
- package/lib/plugins/tree/types.d.ts +0 -10
- package/lib/plugins/tree/types.d.ts.map +1 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts +0 -1
- package/lib/plugins/undo-redo/UndoRedoPlugin.d.ts.map +1 -1
- package/lib/plugins/undo-redo/index.js +93 -17
- package/lib/plugins/undo-redo/index.js.map +1 -1
- package/lib/plugins/visibility/VisibilityPlugin.d.ts +7 -4
- package/lib/plugins/visibility/VisibilityPlugin.d.ts.map +1 -1
- package/lib/plugins/visibility/index.js +144 -65
- package/lib/plugins/visibility/index.js.map +1 -1
- package/package.json +1 -1
- package/umd/grid.all.umd.js +17 -19
- package/umd/grid.all.umd.js.map +1 -1
- package/umd/grid.umd.js +7 -7
- package/umd/grid.umd.js.map +1 -1
- package/umd/plugins/clipboard.umd.js +5 -7
- package/umd/plugins/clipboard.umd.js.map +1 -1
- package/umd/plugins/column-virtualization.umd.js +1 -1
- package/umd/plugins/column-virtualization.umd.js.map +1 -1
- package/umd/plugins/context-menu.umd.js +1 -1
- package/umd/plugins/context-menu.umd.js.map +1 -1
- package/umd/plugins/editing.umd.js +1 -1
- package/umd/plugins/editing.umd.js.map +1 -1
- package/umd/plugins/export.umd.js +1 -1
- package/umd/plugins/export.umd.js.map +1 -1
- package/umd/plugins/filtering.umd.js +1 -1
- package/umd/plugins/filtering.umd.js.map +1 -1
- package/umd/plugins/grouping-columns.umd.js +1 -1
- package/umd/plugins/grouping-columns.umd.js.map +1 -1
- package/umd/plugins/grouping-rows.umd.js +1 -1
- package/umd/plugins/grouping-rows.umd.js.map +1 -1
- package/umd/plugins/master-detail.umd.js +1 -1
- package/umd/plugins/master-detail.umd.js.map +1 -1
- package/umd/plugins/multi-sort.umd.js +1 -1
- package/umd/plugins/multi-sort.umd.js.map +1 -1
- package/umd/plugins/pinned-columns.umd.js +1 -1
- package/umd/plugins/pinned-columns.umd.js.map +1 -1
- package/umd/plugins/pinned-rows.umd.js +1 -1
- package/umd/plugins/pinned-rows.umd.js.map +1 -1
- package/umd/plugins/pivot.umd.js +1 -1
- package/umd/plugins/pivot.umd.js.map +1 -1
- package/umd/plugins/reorder.umd.js +1 -1
- package/umd/plugins/reorder.umd.js.map +1 -1
- package/umd/plugins/selection.umd.js +1 -1
- package/umd/plugins/selection.umd.js.map +1 -1
- package/umd/plugins/server-side.umd.js +1 -1
- package/umd/plugins/server-side.umd.js.map +1 -1
- package/umd/plugins/tree.umd.js +1 -1
- package/umd/plugins/tree.umd.js.map +1 -1
- package/umd/plugins/undo-redo.umd.js +1 -1
- package/umd/plugins/undo-redo.umd.js.map +1 -1
- package/umd/plugins/visibility.umd.js +1 -1
- package/umd/plugins/visibility.umd.js.map +1 -1
- package/lib/core/internal/editing.d.ts +0 -76
- package/lib/core/internal/editing.d.ts.map +0 -1
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,28 +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 {
|
|
64
82
|
/**
|
|
65
|
-
* Plugin dependencies - ClipboardPlugin
|
|
83
|
+
* Plugin dependencies - ClipboardPlugin works best with SelectionPlugin.
|
|
66
84
|
*
|
|
67
|
-
*
|
|
85
|
+
* Without SelectionPlugin: copies entire grid, pastes at row 0 col 0.
|
|
86
|
+
* With SelectionPlugin: copies/pastes based on selection.
|
|
68
87
|
*/
|
|
69
88
|
static dependencies = [
|
|
70
|
-
{ name: "selection", required: !
|
|
89
|
+
{ name: "selection", required: !1, reason: "Enables copy/paste of selected cells instead of entire grid" }
|
|
71
90
|
];
|
|
72
91
|
name = "clipboard";
|
|
73
|
-
version = "1.0.0";
|
|
74
92
|
get defaultConfig() {
|
|
75
93
|
return {
|
|
76
94
|
includeHeaders: !1,
|
|
@@ -85,65 +103,107 @@ class Tn extends x {
|
|
|
85
103
|
lastCopied = null;
|
|
86
104
|
// #endregion
|
|
87
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
|
+
}
|
|
88
113
|
detach() {
|
|
89
114
|
this.lastCopied = null;
|
|
90
115
|
}
|
|
91
116
|
// #endregion
|
|
92
117
|
// #region Event Handlers
|
|
93
118
|
onKeyDown(e) {
|
|
94
|
-
|
|
95
|
-
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;
|
|
96
120
|
}
|
|
97
121
|
// #endregion
|
|
98
122
|
// #region Private Methods
|
|
99
123
|
/**
|
|
100
|
-
* 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
|
|
101
131
|
*/
|
|
102
132
|
#e(e) {
|
|
103
|
-
const t = this.#
|
|
104
|
-
let
|
|
105
|
-
if (
|
|
106
|
-
a =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
if (!
|
|
123
|
-
|
|
124
|
-
} else {
|
|
125
|
-
const h = this.#s(e);
|
|
126
|
-
if (!h) return;
|
|
127
|
-
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 };
|
|
128
154
|
}
|
|
129
|
-
|
|
130
|
-
|
|
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
|
+
});
|
|
131
162
|
});
|
|
132
163
|
}
|
|
133
164
|
/**
|
|
134
|
-
* 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
|
|
178
|
+
*/
|
|
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.
|
|
135
196
|
*/
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
});
|
|
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);
|
|
142
202
|
}
|
|
143
203
|
/**
|
|
144
204
|
* Get the selection plugin instance if available.
|
|
145
205
|
*/
|
|
146
|
-
#
|
|
206
|
+
#n() {
|
|
147
207
|
try {
|
|
148
208
|
const e = this.grid?.getPluginByName("selection");
|
|
149
209
|
if (e)
|
|
@@ -151,71 +211,45 @@ class Tn extends x {
|
|
|
151
211
|
} catch {
|
|
152
212
|
}
|
|
153
213
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Build text for a single cell by row/col index.
|
|
156
|
-
*/
|
|
157
|
-
#n(e, t) {
|
|
158
|
-
const n = this.rows[e];
|
|
159
|
-
if (!n) return null;
|
|
160
|
-
const i = this.columns[t];
|
|
161
|
-
if (!i) return null;
|
|
162
|
-
const o = n[i.field], r = i.header || i.field;
|
|
163
|
-
let l;
|
|
164
|
-
if (this.config.includeHeaders) {
|
|
165
|
-
const a = o == null ? "" : String(o);
|
|
166
|
-
l = `${r}: ${a}`;
|
|
167
|
-
} else
|
|
168
|
-
l = o == null ? "" : String(o);
|
|
169
|
-
return { text: l };
|
|
170
|
-
}
|
|
171
214
|
/**
|
|
172
215
|
* Build text for a rectangular range of cells.
|
|
216
|
+
* Utility columns (like expander columns) are automatically excluded.
|
|
173
217
|
*/
|
|
174
218
|
#i(e) {
|
|
175
|
-
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 ?? " ",
|
|
176
|
-
`,
|
|
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));
|
|
177
221
|
if (this.config.includeHeaders) {
|
|
178
222
|
const g = f.map((p) => p.header || p.field);
|
|
179
|
-
|
|
223
|
+
h.push(g.join(c));
|
|
180
224
|
}
|
|
181
225
|
for (let g = r; g <= l; g++) {
|
|
182
226
|
const p = this.rows[g];
|
|
183
227
|
if (!p) continue;
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
return
|
|
228
|
+
const b = f.map((m) => {
|
|
229
|
+
const w = p[m.field];
|
|
230
|
+
return w == null ? "" : w instanceof Date ? w.toISOString() : String(w);
|
|
187
231
|
});
|
|
188
|
-
|
|
232
|
+
h.push(b.join(c));
|
|
189
233
|
}
|
|
190
234
|
return {
|
|
191
|
-
text:
|
|
235
|
+
text: h.join(u),
|
|
192
236
|
rowCount: l - r + 1,
|
|
193
237
|
columnCount: d - a + 1
|
|
194
238
|
};
|
|
195
239
|
}
|
|
196
240
|
/**
|
|
197
|
-
*
|
|
198
|
-
* Used
|
|
241
|
+
* Get focused cell coordinates from DOM.
|
|
242
|
+
* Used as fallback when SelectionPlugin has no selection.
|
|
199
243
|
*/
|
|
200
244
|
#s(e) {
|
|
201
245
|
const t = e.closest("[data-field-cache]");
|
|
202
246
|
if (!t) return null;
|
|
203
|
-
const n = t.dataset.fieldCache;
|
|
204
|
-
if (!n) return null;
|
|
205
|
-
const i = t.dataset.row;
|
|
206
|
-
if (!i) return null;
|
|
247
|
+
const n = t.dataset.fieldCache, i = t.dataset.row;
|
|
248
|
+
if (!n || !i) return null;
|
|
207
249
|
const o = parseInt(i, 10);
|
|
208
250
|
if (isNaN(o)) return null;
|
|
209
|
-
const r = this.
|
|
210
|
-
|
|
211
|
-
const l = r[n], d = this.columns.find((h) => h.field === n)?.header || n;
|
|
212
|
-
let c;
|
|
213
|
-
if (this.config.includeHeaders) {
|
|
214
|
-
const h = l == null ? "" : String(l);
|
|
215
|
-
c = `${d}: ${h}`;
|
|
216
|
-
} else
|
|
217
|
-
c = l == null ? "" : String(l);
|
|
218
|
-
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 };
|
|
219
253
|
}
|
|
220
254
|
// #endregion
|
|
221
255
|
// #region Public API
|
|
@@ -224,13 +258,19 @@ class Tn extends x {
|
|
|
224
258
|
* @returns The copied text
|
|
225
259
|
*/
|
|
226
260
|
async copy() {
|
|
227
|
-
const t = this.#
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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;
|
|
234
274
|
}
|
|
235
275
|
/**
|
|
236
276
|
* Copy specific rows by index to clipboard.
|
|
@@ -238,21 +278,22 @@ class Tn extends x {
|
|
|
238
278
|
* @returns The copied text
|
|
239
279
|
*/
|
|
240
280
|
async copyRows(e) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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;
|
|
248
289
|
}
|
|
249
290
|
/**
|
|
250
291
|
* Read and parse clipboard content.
|
|
251
292
|
* @returns Parsed 2D array of cell values, or null if clipboard is empty
|
|
252
293
|
*/
|
|
253
294
|
async paste() {
|
|
254
|
-
const e = await
|
|
255
|
-
return e ?
|
|
295
|
+
const e = await tt();
|
|
296
|
+
return e ? ue(e, this.config) : null;
|
|
256
297
|
}
|
|
257
298
|
/**
|
|
258
299
|
* Get the last copied text and timestamp.
|
|
@@ -263,33 +304,33 @@ class Tn extends x {
|
|
|
263
304
|
}
|
|
264
305
|
// #endregion
|
|
265
306
|
}
|
|
266
|
-
const
|
|
267
|
-
function
|
|
307
|
+
const he = 100;
|
|
308
|
+
function oe(s) {
|
|
268
309
|
if (s == null)
|
|
269
|
-
return
|
|
310
|
+
return he;
|
|
270
311
|
if (typeof s == "number")
|
|
271
312
|
return s;
|
|
272
313
|
const e = parseFloat(s);
|
|
273
|
-
return isNaN(e) ?
|
|
314
|
+
return isNaN(e) ? he : e;
|
|
274
315
|
}
|
|
275
|
-
function
|
|
276
|
-
return s.map((e) =>
|
|
316
|
+
function fe(s) {
|
|
317
|
+
return s.map((e) => oe(e.width));
|
|
277
318
|
}
|
|
278
|
-
function
|
|
319
|
+
function ge(s) {
|
|
279
320
|
const e = [];
|
|
280
321
|
let t = 0;
|
|
281
322
|
for (const n of s)
|
|
282
|
-
e.push(t), t +=
|
|
323
|
+
e.push(t), t += oe(n.width);
|
|
283
324
|
return e;
|
|
284
325
|
}
|
|
285
|
-
function
|
|
286
|
-
return s.reduce((e, t) => e +
|
|
326
|
+
function pe(s) {
|
|
327
|
+
return s.reduce((e, t) => e + oe(t.width), 0);
|
|
287
328
|
}
|
|
288
|
-
function
|
|
329
|
+
function it(s, e, t, n, i) {
|
|
289
330
|
const o = t.length;
|
|
290
331
|
if (o === 0)
|
|
291
332
|
return { startCol: 0, endCol: 0, visibleColumns: [] };
|
|
292
|
-
let r =
|
|
333
|
+
let r = ot(s, t, n);
|
|
293
334
|
r = Math.max(0, r - i);
|
|
294
335
|
const l = s + e;
|
|
295
336
|
let a = r;
|
|
@@ -306,7 +347,7 @@ function Ye(s, e, t, n, i) {
|
|
|
306
347
|
d.push(c);
|
|
307
348
|
return { startCol: r, endCol: a, visibleColumns: d };
|
|
308
349
|
}
|
|
309
|
-
function
|
|
350
|
+
function ot(s, e, t) {
|
|
310
351
|
let n = 0, i = e.length - 1;
|
|
311
352
|
for (; n < i; ) {
|
|
312
353
|
const o = Math.floor((n + i) / 2);
|
|
@@ -314,12 +355,11 @@ function Je(s, e, t) {
|
|
|
314
355
|
}
|
|
315
356
|
return n;
|
|
316
357
|
}
|
|
317
|
-
function
|
|
358
|
+
function rt(s, e, t) {
|
|
318
359
|
return t ? s > e : !1;
|
|
319
360
|
}
|
|
320
|
-
class
|
|
361
|
+
class Nn extends x {
|
|
321
362
|
name = "columnVirtualization";
|
|
322
|
-
version = "1.0.0";
|
|
323
363
|
get defaultConfig() {
|
|
324
364
|
return {
|
|
325
365
|
autoEnable: !0,
|
|
@@ -340,7 +380,7 @@ class In extends x {
|
|
|
340
380
|
attach(e) {
|
|
341
381
|
super.attach(e);
|
|
342
382
|
const t = this.columns;
|
|
343
|
-
this.columnWidths =
|
|
383
|
+
this.columnWidths = fe(t), this.columnOffsets = ge(t), this.totalWidth = pe(t), this.endCol = t.length - 1;
|
|
344
384
|
}
|
|
345
385
|
detach() {
|
|
346
386
|
this.columnWidths = [], this.columnOffsets = [], this.isVirtualized = !1, this.startCol = 0, this.endCol = 0, this.scrollLeft = 0, this.totalWidth = 0;
|
|
@@ -348,10 +388,10 @@ class In extends x {
|
|
|
348
388
|
// #endregion
|
|
349
389
|
// #region Hooks
|
|
350
390
|
processColumns(e) {
|
|
351
|
-
const t =
|
|
352
|
-
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)
|
|
353
393
|
return this.startCol = 0, this.endCol = e.length - 1, [...e];
|
|
354
|
-
const n = this.grid.clientWidth || 800, i =
|
|
394
|
+
const n = this.grid.clientWidth || 800, i = it(
|
|
355
395
|
this.scrollLeft,
|
|
356
396
|
n,
|
|
357
397
|
this.columnOffsets,
|
|
@@ -411,14 +451,14 @@ class In extends x {
|
|
|
411
451
|
}
|
|
412
452
|
// #endregion
|
|
413
453
|
}
|
|
414
|
-
const
|
|
415
|
-
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) {
|
|
416
456
|
return (typeof s == "function" ? s(e) : s).filter((n) => !(n.hidden === !0 || typeof n.hidden == "function" && n.hidden(e)));
|
|
417
457
|
}
|
|
418
|
-
function
|
|
458
|
+
function st(s, e) {
|
|
419
459
|
return s.disabled === !0 ? !0 : typeof s.disabled == "function" ? s.disabled(e) : !1;
|
|
420
460
|
}
|
|
421
|
-
function
|
|
461
|
+
function te(s, e, t, n = $e.submenuArrow) {
|
|
422
462
|
const i = document.createElement("div");
|
|
423
463
|
i.className = "tbw-context-menu", i.setAttribute("role", "menu");
|
|
424
464
|
for (const o of s) {
|
|
@@ -429,7 +469,7 @@ function ne(s, e, t, n = ze.submenuArrow) {
|
|
|
429
469
|
}
|
|
430
470
|
const r = document.createElement("div");
|
|
431
471
|
r.className = "tbw-context-menu-item", o.cssClass && r.classList.add(o.cssClass), r.setAttribute("role", "menuitem"), r.setAttribute("data-id", o.id);
|
|
432
|
-
const l =
|
|
472
|
+
const l = st(o, e);
|
|
433
473
|
if (l && (r.classList.add("disabled"), r.setAttribute("aria-disabled", "true")), o.icon) {
|
|
434
474
|
const d = document.createElement("span");
|
|
435
475
|
d.className = "tbw-context-menu-icon", d.innerHTML = o.icon, r.appendChild(d);
|
|
@@ -443,8 +483,8 @@ function ne(s, e, t, n = ze.submenuArrow) {
|
|
|
443
483
|
const d = document.createElement("span");
|
|
444
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", () => {
|
|
445
485
|
if (r.querySelector(".tbw-context-menu") || !o.subMenu) return;
|
|
446
|
-
const
|
|
447
|
-
|
|
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);
|
|
448
488
|
}), r.addEventListener("mouseleave", () => {
|
|
449
489
|
const c = r.querySelector(".tbw-context-menu");
|
|
450
490
|
c && c.remove();
|
|
@@ -456,13 +496,13 @@ function ne(s, e, t, n = ze.submenuArrow) {
|
|
|
456
496
|
}
|
|
457
497
|
return i;
|
|
458
498
|
}
|
|
459
|
-
function
|
|
499
|
+
function me(s, e, t) {
|
|
460
500
|
s.style.position = "fixed", s.style.left = `${e}px`, s.style.top = `${t}px`, s.style.visibility = "hidden", s.style.zIndex = "10000";
|
|
461
501
|
const n = s.getBoundingClientRect(), i = window.innerWidth, o = window.innerHeight;
|
|
462
502
|
let r = e, l = t;
|
|
463
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";
|
|
464
504
|
}
|
|
465
|
-
let
|
|
505
|
+
let T = null, I = null, k = null, $ = 0;
|
|
466
506
|
const j = [
|
|
467
507
|
{
|
|
468
508
|
id: "copy",
|
|
@@ -481,9 +521,8 @@ const j = [
|
|
|
481
521
|
}
|
|
482
522
|
}
|
|
483
523
|
];
|
|
484
|
-
class
|
|
524
|
+
class Hn extends x {
|
|
485
525
|
name = "contextMenu";
|
|
486
|
-
version = "1.0.0";
|
|
487
526
|
get defaultConfig() {
|
|
488
527
|
return {
|
|
489
528
|
items: j
|
|
@@ -497,7 +536,7 @@ class Fn extends x {
|
|
|
497
536
|
// #endregion
|
|
498
537
|
// #region Lifecycle
|
|
499
538
|
attach(e) {
|
|
500
|
-
super.attach(e), this.installGlobalHandlers(),
|
|
539
|
+
super.attach(e), this.installGlobalHandlers(), $++;
|
|
501
540
|
}
|
|
502
541
|
detach() {
|
|
503
542
|
this.menuElement && (this.menuElement.remove(), this.menuElement = null), this.isOpen = !1, this.params = null, this.uninstallGlobalHandlers();
|
|
@@ -505,18 +544,18 @@ class Fn extends x {
|
|
|
505
544
|
// #endregion
|
|
506
545
|
// #region Private Methods
|
|
507
546
|
installGlobalHandlers() {
|
|
508
|
-
!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 = () => {
|
|
509
548
|
document.querySelectorAll(".tbw-context-menu").forEach((t) => t.remove());
|
|
510
|
-
}, document.addEventListener("click",
|
|
549
|
+
}, document.addEventListener("click", T)), I || (I = (e) => {
|
|
511
550
|
e.key === "Escape" && document.querySelectorAll(".tbw-context-menu").forEach((n) => n.remove());
|
|
512
|
-
}, document.addEventListener("keydown",
|
|
551
|
+
}, document.addEventListener("keydown", I));
|
|
513
552
|
}
|
|
514
553
|
/**
|
|
515
554
|
* Clean up global handlers when the last instance detaches.
|
|
516
555
|
* Uses reference counting to ensure handlers persist while any grid uses the plugin.
|
|
517
556
|
*/
|
|
518
557
|
uninstallGlobalHandlers() {
|
|
519
|
-
|
|
558
|
+
$--, !($ > 0) && (T && (document.removeEventListener("click", T), T = null), I && (document.removeEventListener("keydown", I), I = null), k && (k.remove(), k = null));
|
|
520
559
|
}
|
|
521
560
|
// #endregion
|
|
522
561
|
// #region Hooks
|
|
@@ -530,25 +569,25 @@ class Fn extends x {
|
|
|
530
569
|
const o = i.target, r = o.closest("[data-row][data-col]"), l = o.closest(".header-cell");
|
|
531
570
|
let a;
|
|
532
571
|
if (r) {
|
|
533
|
-
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];
|
|
534
573
|
a = {
|
|
535
574
|
row: f,
|
|
536
575
|
rowIndex: c,
|
|
537
|
-
column:
|
|
538
|
-
columnIndex:
|
|
539
|
-
field:
|
|
540
|
-
value: f?.[
|
|
576
|
+
column: h,
|
|
577
|
+
columnIndex: u,
|
|
578
|
+
field: h?.field ?? "",
|
|
579
|
+
value: f?.[h?.field] ?? null,
|
|
541
580
|
isHeader: !1,
|
|
542
581
|
event: i
|
|
543
582
|
};
|
|
544
583
|
} else if (l) {
|
|
545
|
-
const c = parseInt(l.getAttribute("data-col") ?? "-1", 10),
|
|
584
|
+
const c = parseInt(l.getAttribute("data-col") ?? "-1", 10), u = this.columns[c];
|
|
546
585
|
a = {
|
|
547
586
|
row: null,
|
|
548
587
|
rowIndex: -1,
|
|
549
|
-
column:
|
|
588
|
+
column: u,
|
|
550
589
|
columnIndex: c,
|
|
551
|
-
field:
|
|
590
|
+
field: u?.field ?? "",
|
|
552
591
|
value: null,
|
|
553
592
|
isHeader: !0,
|
|
554
593
|
event: i
|
|
@@ -556,15 +595,15 @@ class Fn extends x {
|
|
|
556
595
|
} else
|
|
557
596
|
return;
|
|
558
597
|
this.params = a, this.position = { x: i.clientX, y: i.clientY };
|
|
559
|
-
const d =
|
|
560
|
-
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(
|
|
561
600
|
d,
|
|
562
601
|
a,
|
|
563
602
|
(c) => {
|
|
564
603
|
c.action && c.action(a), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
565
604
|
},
|
|
566
605
|
this.gridIcons.submenuArrow
|
|
567
|
-
), 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 }));
|
|
568
607
|
}));
|
|
569
608
|
}
|
|
570
609
|
// #endregion
|
|
@@ -585,15 +624,15 @@ class Fn extends x {
|
|
|
585
624
|
value: n.value ?? null,
|
|
586
625
|
isHeader: n.isHeader ?? !1,
|
|
587
626
|
event: n.event ?? new MouseEvent("contextmenu")
|
|
588
|
-
}, o =
|
|
589
|
-
this.menuElement && this.menuElement.remove(), this.menuElement =
|
|
627
|
+
}, o = ee(this.config.items ?? j, i);
|
|
628
|
+
this.menuElement && this.menuElement.remove(), this.menuElement = te(
|
|
590
629
|
o,
|
|
591
630
|
i,
|
|
592
631
|
(r) => {
|
|
593
632
|
r.action && r.action(i), this.menuElement?.remove(), this.menuElement = null, this.isOpen = !1;
|
|
594
633
|
},
|
|
595
634
|
this.gridIcons.submenuArrow
|
|
596
|
-
), document.body.appendChild(this.menuElement),
|
|
635
|
+
), document.body.appendChild(this.menuElement), me(this.menuElement, e, t), this.isOpen = !0;
|
|
597
636
|
}
|
|
598
637
|
/**
|
|
599
638
|
* Hide the context menu.
|
|
@@ -611,7 +650,7 @@ class Fn extends x {
|
|
|
611
650
|
// #endregion
|
|
612
651
|
// Styles are injected globally via installGlobalHandlers() since menu renders in document.body
|
|
613
652
|
}
|
|
614
|
-
function
|
|
653
|
+
function lt(s) {
|
|
615
654
|
switch (s.type) {
|
|
616
655
|
case "number":
|
|
617
656
|
return (e) => {
|
|
@@ -665,30 +704,30 @@ function tt(s) {
|
|
|
665
704
|
}
|
|
666
705
|
}
|
|
667
706
|
const U = 'input,select,textarea,[contenteditable="true"],[contenteditable=""],[tabindex]:not([tabindex="-1"])';
|
|
668
|
-
function
|
|
707
|
+
function P(s) {
|
|
669
708
|
return !(typeof s != "string" || s === "__proto__" || s === "constructor" || s === "prototype");
|
|
670
709
|
}
|
|
671
|
-
function
|
|
710
|
+
function On(s) {
|
|
672
711
|
return (s.__editingCellCount ?? 0) > 0;
|
|
673
712
|
}
|
|
674
|
-
function
|
|
713
|
+
function at(s) {
|
|
675
714
|
const e = (s.__editingCellCount ?? 0) + 1;
|
|
676
715
|
s.__editingCellCount = e, s.setAttribute("data-has-editing", "");
|
|
677
716
|
}
|
|
678
|
-
function
|
|
717
|
+
function dt(s) {
|
|
679
718
|
s.__editingCellCount = 0, s.removeAttribute("data-has-editing");
|
|
680
719
|
}
|
|
681
|
-
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) {
|
|
682
724
|
const n = s.querySelector("input,textarea,select");
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
n.addEventListener("
|
|
686
|
-
t(i());
|
|
687
|
-
}), 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))));
|
|
688
728
|
}
|
|
689
|
-
class
|
|
729
|
+
class Gn extends x {
|
|
690
730
|
name = "editing";
|
|
691
|
-
version = "1.0.0";
|
|
692
731
|
get defaultConfig() {
|
|
693
732
|
return {
|
|
694
733
|
editOn: "click"
|
|
@@ -740,15 +779,6 @@ class Pn extends x {
|
|
|
740
779
|
this.#e = -1, this.#t = -1, this.#r.clear(), this.#n.clear(), this.#i.clear(), super.detach();
|
|
741
780
|
}
|
|
742
781
|
// #endregion
|
|
743
|
-
// #region Config Augmentation (processColumns hook)
|
|
744
|
-
/**
|
|
745
|
-
* Augment columns with editing metadata.
|
|
746
|
-
* This enables the grid to recognize editable columns without core knowledge.
|
|
747
|
-
*/
|
|
748
|
-
processColumns(e) {
|
|
749
|
-
return e;
|
|
750
|
-
}
|
|
751
|
-
// #endregion
|
|
752
782
|
// #region Event Handlers (event distribution)
|
|
753
783
|
/**
|
|
754
784
|
* Handle cell clicks - start editing if configured for click mode.
|
|
@@ -776,7 +806,7 @@ class Pn extends x {
|
|
|
776
806
|
const o = t._visibleColumns[i], r = t._rows[n];
|
|
777
807
|
if (o?.editable && o.type === "boolean" && r) {
|
|
778
808
|
const l = o.field;
|
|
779
|
-
if (
|
|
809
|
+
if (P(l)) {
|
|
780
810
|
const d = !r[l];
|
|
781
811
|
return this.#a(n, o, d, r), e.preventDefault(), this.requestRender(), !0;
|
|
782
812
|
}
|
|
@@ -951,10 +981,10 @@ class Pn extends x {
|
|
|
951
981
|
if (isNaN(d)) return;
|
|
952
982
|
const c = n._visibleColumns[d];
|
|
953
983
|
if (!c) return;
|
|
954
|
-
const
|
|
955
|
-
if (
|
|
956
|
-
|
|
957
|
-
|
|
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);
|
|
958
988
|
}
|
|
959
989
|
}), t && i && o)
|
|
960
990
|
Object.keys(i).forEach((l) => {
|
|
@@ -974,7 +1004,7 @@ class Pn extends x {
|
|
|
974
1004
|
for (const l of this.#i)
|
|
975
1005
|
l.startsWith(`${e}:`) && this.#i.delete(l);
|
|
976
1006
|
r && (r.querySelectorAll(".cell.editing").forEach((l) => {
|
|
977
|
-
l.classList.remove("editing"),
|
|
1007
|
+
l.classList.remove("editing"), dt(l.parentElement);
|
|
978
1008
|
}), this.requestRender()), this.#s = !0, r || (this.#u(n), this.#s = !1);
|
|
979
1009
|
}
|
|
980
1010
|
/**
|
|
@@ -982,65 +1012,68 @@ class Pn extends x {
|
|
|
982
1012
|
*/
|
|
983
1013
|
#a(e, t, n, i) {
|
|
984
1014
|
const o = t.field;
|
|
985
|
-
if (!
|
|
986
|
-
i[o]
|
|
1015
|
+
if (!P(o)) return;
|
|
1016
|
+
const r = i[o];
|
|
1017
|
+
if (r === n) return;
|
|
987
1018
|
const l = !this.#n.has(e);
|
|
988
|
-
this
|
|
989
|
-
const d = this.grid.findRenderedRowElement?.(e);
|
|
990
|
-
d && d.classList.add("changed"), this.emit("cell-commit", {
|
|
1019
|
+
if (this.emitCancelable("cell-commit", {
|
|
991
1020
|
row: i,
|
|
992
1021
|
field: o,
|
|
1022
|
+
oldValue: r,
|
|
993
1023
|
value: n,
|
|
994
1024
|
rowIndex: e,
|
|
995
1025
|
changedRows: this.changedRows,
|
|
996
1026
|
changedRowIndices: this.changedRowIndices,
|
|
997
1027
|
firstTimeForRow: l
|
|
998
|
-
});
|
|
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");
|
|
999
1032
|
}
|
|
1000
1033
|
/**
|
|
1001
1034
|
* Inject an editor into a cell.
|
|
1002
1035
|
*/
|
|
1003
1036
|
#d(e, t, n, i, o, r) {
|
|
1004
1037
|
if (!n.editable || o.classList.contains("editing")) return;
|
|
1005
|
-
const l =
|
|
1038
|
+
const l = P(n.field) ? e[n.field] : void 0;
|
|
1006
1039
|
o.classList.add("editing"), this.#i.add(`${t}:${i}`);
|
|
1007
1040
|
const a = o.parentElement;
|
|
1008
|
-
a &&
|
|
1041
|
+
a && at(a);
|
|
1009
1042
|
let d = !1;
|
|
1010
1043
|
const c = (m) => {
|
|
1011
1044
|
d || this.#e === -1 || this.#a(t, n, m, e);
|
|
1012
|
-
},
|
|
1013
|
-
d = !0,
|
|
1014
|
-
},
|
|
1015
|
-
|
|
1016
|
-
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));
|
|
1017
1050
|
});
|
|
1018
|
-
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;
|
|
1019
1052
|
if (p === "template" && g)
|
|
1020
|
-
this.#f(
|
|
1053
|
+
this.#f(h, f, e, l, c, u, r, t);
|
|
1021
1054
|
else if (typeof p == "string") {
|
|
1022
1055
|
const m = document.createElement(p);
|
|
1023
|
-
m.value =
|
|
1024
|
-
|
|
1056
|
+
m.value = b, m.addEventListener("change", () => c(m.value)), h.appendChild(m), r || queueMicrotask(() => {
|
|
1057
|
+
h.querySelector(U)?.focus({ preventScroll: !0 });
|
|
1025
1058
|
});
|
|
1026
1059
|
} else if (typeof p == "function") {
|
|
1027
|
-
const m = { row: e, value:
|
|
1028
|
-
typeof
|
|
1029
|
-
|
|
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 });
|
|
1030
1063
|
});
|
|
1031
1064
|
} else if (p && typeof p == "object") {
|
|
1032
|
-
const m = this.grid,
|
|
1033
|
-
|
|
1034
|
-
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 };
|
|
1035
1068
|
if (p.mount)
|
|
1036
1069
|
try {
|
|
1037
|
-
p.mount({ placeholder:
|
|
1070
|
+
p.mount({ placeholder: w, context: A, spec: p });
|
|
1038
1071
|
} catch (q) {
|
|
1039
1072
|
console.warn(`[tbw-grid] External editor mount error for column '${n.field}':`, q);
|
|
1040
1073
|
}
|
|
1041
1074
|
else
|
|
1042
1075
|
m.dispatchEvent(
|
|
1043
|
-
new CustomEvent("mount-external-editor", { detail: { placeholder:
|
|
1076
|
+
new CustomEvent("mount-external-editor", { detail: { placeholder: w, spec: p, context: A } })
|
|
1044
1077
|
);
|
|
1045
1078
|
}
|
|
1046
1079
|
}
|
|
@@ -1050,8 +1083,8 @@ class Pn extends x {
|
|
|
1050
1083
|
#f(e, t, n, i, o, r, l, a) {
|
|
1051
1084
|
const d = t.__editorTemplate;
|
|
1052
1085
|
if (!d) return;
|
|
1053
|
-
const c = d.cloneNode(!0),
|
|
1054
|
-
|
|
1086
|
+
const c = d.cloneNode(!0), u = t.__compiledEditor;
|
|
1087
|
+
u ? c.innerHTML = u({
|
|
1055
1088
|
row: n,
|
|
1056
1089
|
value: i,
|
|
1057
1090
|
field: t.field,
|
|
@@ -1060,30 +1093,23 @@ class Pn extends x {
|
|
|
1060
1093
|
cancel: r
|
|
1061
1094
|
}) : c.querySelectorAll("*").forEach((f) => {
|
|
1062
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) => {
|
|
1063
|
-
if (!
|
|
1064
|
-
const
|
|
1065
|
-
return
|
|
1096
|
+
if (!P(p)) return "";
|
|
1097
|
+
const b = n[p];
|
|
1098
|
+
return b == null ? "" : String(b);
|
|
1066
1099
|
}) || "");
|
|
1067
1100
|
});
|
|
1068
|
-
const
|
|
1101
|
+
const h = c.querySelector(
|
|
1069
1102
|
"input,textarea,select"
|
|
1070
1103
|
);
|
|
1071
|
-
if (
|
|
1072
|
-
|
|
1104
|
+
if (h) {
|
|
1105
|
+
h instanceof HTMLInputElement && h.type === "checkbox" ? h.checked = !!i : h.value = String(i ?? "");
|
|
1073
1106
|
let f = !1;
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
o(g);
|
|
1078
|
-
}), u.addEventListener("keydown", (g) => {
|
|
1107
|
+
h.addEventListener("blur", () => {
|
|
1108
|
+
f || o(K(h, t));
|
|
1109
|
+
}), h.addEventListener("keydown", (g) => {
|
|
1079
1110
|
const p = g;
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
const w = u instanceof HTMLInputElement && u.type === "checkbox" ? u.checked : u.value;
|
|
1083
|
-
o(w), this.#o(a, !1);
|
|
1084
|
-
}
|
|
1085
|
-
p.key === "Escape" && (p.stopPropagation(), p.preventDefault(), r(), this.#o(a, !0));
|
|
1086
|
-
}), 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);
|
|
1087
1113
|
}
|
|
1088
1114
|
e.appendChild(c);
|
|
1089
1115
|
}
|
|
@@ -1107,7 +1133,7 @@ class Pn extends x {
|
|
|
1107
1133
|
}
|
|
1108
1134
|
// #endregion
|
|
1109
1135
|
}
|
|
1110
|
-
function
|
|
1136
|
+
function we(s, e = !0) {
|
|
1111
1137
|
if (s == null) return "";
|
|
1112
1138
|
if (s instanceof Date) return s.toISOString();
|
|
1113
1139
|
if (typeof s == "object") return JSON.stringify(s);
|
|
@@ -1115,37 +1141,37 @@ function ve(s, e = !0) {
|
|
|
1115
1141
|
return e && (t.includes(",") || t.includes('"') || t.includes(`
|
|
1116
1142
|
`) || t.includes("\r")) ? `"${t.replace(/"/g, '""')}"` : t;
|
|
1117
1143
|
}
|
|
1118
|
-
function
|
|
1144
|
+
function ut(s, e, t, n = {}) {
|
|
1119
1145
|
const i = n.delimiter ?? ",", o = n.newline ?? `
|
|
1120
1146
|
`, r = [], l = n.bom ? "\uFEFF" : "";
|
|
1121
1147
|
if (t.includeHeaders !== !1) {
|
|
1122
1148
|
const a = e.map((d) => {
|
|
1123
|
-
const c = d.header || d.field,
|
|
1124
|
-
return
|
|
1149
|
+
const c = d.header || d.field, u = t.processHeader ? t.processHeader(c, d.field) : c;
|
|
1150
|
+
return we(u);
|
|
1125
1151
|
});
|
|
1126
1152
|
r.push(a.join(i));
|
|
1127
1153
|
}
|
|
1128
1154
|
for (const a of s) {
|
|
1129
1155
|
const d = e.map((c) => {
|
|
1130
|
-
let
|
|
1131
|
-
return t.processCell && (
|
|
1156
|
+
let u = a[c.field];
|
|
1157
|
+
return t.processCell && (u = t.processCell(u, c.field, a)), we(u);
|
|
1132
1158
|
});
|
|
1133
1159
|
r.push(d.join(i));
|
|
1134
1160
|
}
|
|
1135
1161
|
return l + r.join(o);
|
|
1136
1162
|
}
|
|
1137
|
-
function
|
|
1163
|
+
function re(s, e) {
|
|
1138
1164
|
const t = URL.createObjectURL(s), n = document.createElement("a");
|
|
1139
1165
|
n.href = t, n.download = e, n.style.display = "none", document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(t);
|
|
1140
1166
|
}
|
|
1141
|
-
function
|
|
1167
|
+
function ht(s, e) {
|
|
1142
1168
|
const t = new Blob([s], { type: "text/csv;charset=utf-8;" });
|
|
1143
|
-
|
|
1169
|
+
re(t, e);
|
|
1144
1170
|
}
|
|
1145
|
-
function
|
|
1171
|
+
function be(s) {
|
|
1146
1172
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1147
1173
|
}
|
|
1148
|
-
function
|
|
1174
|
+
function ft(s, e, t) {
|
|
1149
1175
|
let n = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1150
1176
|
<?mso-application progid="Excel.Sheet"?>
|
|
1151
1177
|
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
|
@@ -1157,7 +1183,7 @@ function lt(s, e, t) {
|
|
|
1157
1183
|
<Row>`;
|
|
1158
1184
|
for (const i of e) {
|
|
1159
1185
|
const o = i.header || i.field, r = t.processHeader ? t.processHeader(o, i.field) : o;
|
|
1160
|
-
n += `<Cell><Data ss:Type="String">${
|
|
1186
|
+
n += `<Cell><Data ss:Type="String">${be(r)}</Data></Cell>`;
|
|
1161
1187
|
}
|
|
1162
1188
|
n += "</Row>";
|
|
1163
1189
|
}
|
|
@@ -1168,7 +1194,7 @@ function lt(s, e, t) {
|
|
|
1168
1194
|
let r = i[o.field];
|
|
1169
1195
|
t.processCell && (r = t.processCell(r, o.field, i));
|
|
1170
1196
|
let l = "String", a = "";
|
|
1171
|
-
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>`;
|
|
1172
1198
|
}
|
|
1173
1199
|
n += "</Row>";
|
|
1174
1200
|
}
|
|
@@ -1177,15 +1203,14 @@ function lt(s, e, t) {
|
|
|
1177
1203
|
</Worksheet>
|
|
1178
1204
|
</Workbook>`, n;
|
|
1179
1205
|
}
|
|
1180
|
-
function
|
|
1206
|
+
function gt(s, e) {
|
|
1181
1207
|
const t = e.endsWith(".xls") ? e : `${e}.xls`, n = new Blob([s], {
|
|
1182
1208
|
type: "application/vnd.ms-excel;charset=utf-8;"
|
|
1183
1209
|
});
|
|
1184
|
-
|
|
1210
|
+
re(n, t);
|
|
1185
1211
|
}
|
|
1186
|
-
class
|
|
1212
|
+
class Bn extends x {
|
|
1187
1213
|
name = "export";
|
|
1188
|
-
version = "1.0.0";
|
|
1189
1214
|
get defaultConfig() {
|
|
1190
1215
|
return {
|
|
1191
1216
|
fileName: "export",
|
|
@@ -1217,34 +1242,34 @@ class qn extends x {
|
|
|
1217
1242
|
let r = [...this.rows];
|
|
1218
1243
|
if (n.onlySelected) {
|
|
1219
1244
|
const a = this.getSelectionState();
|
|
1220
|
-
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));
|
|
1221
1246
|
}
|
|
1222
1247
|
t?.rowIndices && (r = t.rowIndices.map((a) => this.rows[a]).filter(Boolean)), this.isExportingFlag = !0;
|
|
1223
1248
|
let l = i.fileName;
|
|
1224
1249
|
try {
|
|
1225
1250
|
switch (e) {
|
|
1226
1251
|
case "csv": {
|
|
1227
|
-
const a =
|
|
1228
|
-
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);
|
|
1229
1254
|
break;
|
|
1230
1255
|
}
|
|
1231
1256
|
case "excel": {
|
|
1232
|
-
const a =
|
|
1233
|
-
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);
|
|
1234
1259
|
break;
|
|
1235
1260
|
}
|
|
1236
1261
|
case "json": {
|
|
1237
|
-
const a = r.map((
|
|
1238
|
-
const
|
|
1262
|
+
const a = r.map((u) => {
|
|
1263
|
+
const h = {};
|
|
1239
1264
|
for (const f of o) {
|
|
1240
|
-
let g =
|
|
1241
|
-
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;
|
|
1242
1267
|
}
|
|
1243
|
-
return
|
|
1268
|
+
return h;
|
|
1244
1269
|
}), d = JSON.stringify(a, null, 2);
|
|
1245
1270
|
l = l.endsWith(".json") ? l : `${l}.json`;
|
|
1246
1271
|
const c = new Blob([d], { type: "application/json" });
|
|
1247
|
-
|
|
1272
|
+
re(c, l);
|
|
1248
1273
|
break;
|
|
1249
1274
|
}
|
|
1250
1275
|
}
|
|
@@ -1304,7 +1329,7 @@ class qn extends x {
|
|
|
1304
1329
|
}
|
|
1305
1330
|
// #endregion
|
|
1306
1331
|
}
|
|
1307
|
-
function
|
|
1332
|
+
function pt(s) {
|
|
1308
1333
|
const { totalRows: e, viewportHeight: t, scrollTop: n, rowHeight: i, overscan: o } = s, r = Math.ceil(t / i);
|
|
1309
1334
|
let l = Math.floor(n / i) - o;
|
|
1310
1335
|
l < 0 && (l = 0);
|
|
@@ -1316,10 +1341,10 @@ function dt(s) {
|
|
|
1316
1341
|
totalHeight: e * i
|
|
1317
1342
|
};
|
|
1318
1343
|
}
|
|
1319
|
-
function
|
|
1344
|
+
function mt(s, e) {
|
|
1320
1345
|
return s <= e;
|
|
1321
1346
|
}
|
|
1322
|
-
function
|
|
1347
|
+
function wt(s, e, t = !1) {
|
|
1323
1348
|
const n = s[e.field];
|
|
1324
1349
|
if (e.operator === "blank")
|
|
1325
1350
|
return n == null || n === "";
|
|
@@ -1361,10 +1386,10 @@ function ut(s, e, t = !1) {
|
|
|
1361
1386
|
return !0;
|
|
1362
1387
|
}
|
|
1363
1388
|
}
|
|
1364
|
-
function
|
|
1365
|
-
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;
|
|
1366
1391
|
}
|
|
1367
|
-
function
|
|
1392
|
+
function vt(s) {
|
|
1368
1393
|
return JSON.stringify(
|
|
1369
1394
|
s.map((e) => ({
|
|
1370
1395
|
field: e.field,
|
|
@@ -1374,7 +1399,7 @@ function ft(s) {
|
|
|
1374
1399
|
}))
|
|
1375
1400
|
);
|
|
1376
1401
|
}
|
|
1377
|
-
function
|
|
1402
|
+
function ve(s, e) {
|
|
1378
1403
|
const t = /* @__PURE__ */ new Set();
|
|
1379
1404
|
for (const n of s) {
|
|
1380
1405
|
const i = n[e];
|
|
@@ -1382,10 +1407,10 @@ function xe(s, e) {
|
|
|
1382
1407
|
}
|
|
1383
1408
|
return [...t].sort((n, i) => typeof n == "number" && typeof i == "number" ? n - i : String(n).localeCompare(String(i)));
|
|
1384
1409
|
}
|
|
1385
|
-
const
|
|
1386
|
-
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 {
|
|
1387
1412
|
name = "filtering";
|
|
1388
|
-
|
|
1413
|
+
styles = yt;
|
|
1389
1414
|
get defaultConfig() {
|
|
1390
1415
|
return {
|
|
1391
1416
|
debounceMs: 300,
|
|
@@ -1410,6 +1435,12 @@ class _ extends x {
|
|
|
1410
1435
|
static LIST_OVERSCAN = 3;
|
|
1411
1436
|
static LIST_BYPASS_THRESHOLD = 50;
|
|
1412
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
|
+
}
|
|
1413
1444
|
// #endregion
|
|
1414
1445
|
// #region Lifecycle
|
|
1415
1446
|
attach(e) {
|
|
@@ -1425,10 +1456,10 @@ class _ extends x {
|
|
|
1425
1456
|
if (!t.length) return [...e];
|
|
1426
1457
|
if (this.config.filterHandler)
|
|
1427
1458
|
return this.cachedResult ? this.cachedResult : [...e];
|
|
1428
|
-
const n =
|
|
1459
|
+
const n = vt(t);
|
|
1429
1460
|
if (this.cacheKey === n && this.cachedResult)
|
|
1430
1461
|
return this.cachedResult;
|
|
1431
|
-
const i =
|
|
1462
|
+
const i = bt([...e], t, this.config.caseSensitive);
|
|
1432
1463
|
return this.cachedResult = i, this.cacheKey = n, i;
|
|
1433
1464
|
}
|
|
1434
1465
|
afterRender() {
|
|
@@ -1461,7 +1492,13 @@ class _ extends x {
|
|
|
1461
1492
|
* Pass null to remove the filter.
|
|
1462
1493
|
*/
|
|
1463
1494
|
setFilter(e, t) {
|
|
1464
|
-
|
|
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", {
|
|
1465
1502
|
filters: [...this.filters.values()],
|
|
1466
1503
|
filteredRowCount: 0
|
|
1467
1504
|
// Will be accurate after processRows
|
|
@@ -1491,7 +1528,7 @@ class _ extends x {
|
|
|
1491
1528
|
setFilterModel(e) {
|
|
1492
1529
|
this.filters.clear(), this.excludedValues.clear();
|
|
1493
1530
|
for (const t of e)
|
|
1494
|
-
this.filters.set(t.field, t),
|
|
1531
|
+
this.filters.set(t.field, t), this.syncExcludedValues(t.field, t);
|
|
1495
1532
|
this.cachedResult = null, this.cacheKey = null, this.emit("filter-change", {
|
|
1496
1533
|
filters: [...this.filters.values()],
|
|
1497
1534
|
filteredRowCount: 0
|
|
@@ -1532,7 +1569,7 @@ class _ extends x {
|
|
|
1532
1569
|
* Uses sourceRows to include all values regardless of current filter.
|
|
1533
1570
|
*/
|
|
1534
1571
|
getUniqueValues(e) {
|
|
1535
|
-
return
|
|
1572
|
+
return ve(this.sourceRows, e);
|
|
1536
1573
|
}
|
|
1537
1574
|
// #endregion
|
|
1538
1575
|
// #region Private Methods
|
|
@@ -1546,7 +1583,7 @@ class _ extends x {
|
|
|
1546
1583
|
return;
|
|
1547
1584
|
}
|
|
1548
1585
|
const e = document.createElement("style");
|
|
1549
|
-
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;
|
|
1550
1587
|
}
|
|
1551
1588
|
/**
|
|
1552
1589
|
* Toggle the filter panel for a field
|
|
@@ -1564,7 +1601,7 @@ class _ extends x {
|
|
|
1564
1601
|
});
|
|
1565
1602
|
return;
|
|
1566
1603
|
}
|
|
1567
|
-
const o =
|
|
1604
|
+
const o = ve(this.sourceRows, e);
|
|
1568
1605
|
this.renderPanelContent(e, t, i, o), document.body.appendChild(i), this.positionPanel(i, n), this.setupPanelCloseHandler(i, n);
|
|
1569
1606
|
}
|
|
1570
1607
|
/**
|
|
@@ -1582,8 +1619,8 @@ class _ extends x {
|
|
|
1582
1619
|
applySetFilter: (d) => {
|
|
1583
1620
|
this.applySetFilter(e, d), this.closeFilterPanel();
|
|
1584
1621
|
},
|
|
1585
|
-
applyTextFilter: (d, c,
|
|
1586
|
-
this.applyTextFilter(e, d, c,
|
|
1622
|
+
applyTextFilter: (d, c, u) => {
|
|
1623
|
+
this.applyTextFilter(e, d, c, u), this.closeFilterPanel();
|
|
1587
1624
|
},
|
|
1588
1625
|
clearFilter: () => {
|
|
1589
1626
|
this.clearFieldFilter(e), this.closeFilterPanel();
|
|
@@ -1637,17 +1674,17 @@ class _ extends x {
|
|
|
1637
1674
|
d.className = "tbw-filter-value-item", d.style.padding = "0", d.style.margin = "0";
|
|
1638
1675
|
const c = document.createElement("input");
|
|
1639
1676
|
c.type = "checkbox", c.className = "tbw-filter-checkbox";
|
|
1640
|
-
const
|
|
1641
|
-
|
|
1642
|
-
const
|
|
1643
|
-
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);
|
|
1644
1681
|
c.checked = R, c.indeterminate = !R && !E;
|
|
1645
1682
|
};
|
|
1646
1683
|
c.addEventListener("change", () => {
|
|
1647
|
-
const
|
|
1648
|
-
for (const R of
|
|
1649
|
-
|
|
1650
|
-
|
|
1684
|
+
const v = c.checked;
|
|
1685
|
+
for (const R of b.keys())
|
|
1686
|
+
b.set(R, v);
|
|
1687
|
+
h(), A();
|
|
1651
1688
|
}), e.appendChild(a);
|
|
1652
1689
|
const f = document.createElement("div");
|
|
1653
1690
|
f.className = "tbw-filter-values";
|
|
@@ -1655,44 +1692,44 @@ class _ extends x {
|
|
|
1655
1692
|
g.className = "tbw-filter-values-spacer", f.appendChild(g);
|
|
1656
1693
|
const p = document.createElement("div");
|
|
1657
1694
|
p.className = "tbw-filter-values-content", f.appendChild(p);
|
|
1658
|
-
const
|
|
1659
|
-
n.forEach((
|
|
1660
|
-
const R =
|
|
1661
|
-
|
|
1662
|
-
}),
|
|
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();
|
|
1663
1700
|
let m = [];
|
|
1664
|
-
const
|
|
1665
|
-
const E =
|
|
1666
|
-
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";
|
|
1667
1704
|
const S = document.createElement("input");
|
|
1668
|
-
S.type = "checkbox", S.className = "tbw-filter-checkbox", S.checked =
|
|
1669
|
-
|
|
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();
|
|
1670
1707
|
});
|
|
1671
|
-
const
|
|
1672
|
-
return
|
|
1708
|
+
const ae = document.createElement("span");
|
|
1709
|
+
return ae.textContent = E, y.appendChild(S), y.appendChild(ae), y;
|
|
1673
1710
|
}, A = () => {
|
|
1674
|
-
const
|
|
1675
|
-
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)) {
|
|
1676
1713
|
p.innerHTML = "", p.style.transform = "translateY(0px)", m.forEach((y, S) => {
|
|
1677
|
-
p.appendChild(
|
|
1714
|
+
p.appendChild(w(y, S));
|
|
1678
1715
|
});
|
|
1679
1716
|
return;
|
|
1680
1717
|
}
|
|
1681
|
-
const C =
|
|
1682
|
-
totalRows:
|
|
1718
|
+
const C = pt({
|
|
1719
|
+
totalRows: v,
|
|
1683
1720
|
viewportHeight: R,
|
|
1684
1721
|
scrollTop: E,
|
|
1685
|
-
rowHeight:
|
|
1686
|
-
overscan:
|
|
1722
|
+
rowHeight: L.LIST_ITEM_HEIGHT,
|
|
1723
|
+
overscan: L.LIST_OVERSCAN
|
|
1687
1724
|
});
|
|
1688
1725
|
p.style.transform = `translateY(${C.offsetY}px)`, p.innerHTML = "";
|
|
1689
1726
|
for (let y = C.start; y < C.end; y++)
|
|
1690
|
-
p.appendChild(
|
|
1691
|
-
}, q = (
|
|
1692
|
-
const R =
|
|
1727
|
+
p.appendChild(w(m[y], y - C.start));
|
|
1728
|
+
}, q = (v) => {
|
|
1729
|
+
const R = v.toLowerCase();
|
|
1693
1730
|
if (m = n.filter((E) => {
|
|
1694
1731
|
const C = E == null ? "(Blank)" : String(E);
|
|
1695
|
-
return !
|
|
1732
|
+
return !v || C.toLowerCase().includes(R);
|
|
1696
1733
|
}), m.length === 0) {
|
|
1697
1734
|
g.style.height = "0px", p.innerHTML = "";
|
|
1698
1735
|
const E = document.createElement("div");
|
|
@@ -1708,31 +1745,31 @@ class _ extends x {
|
|
|
1708
1745
|
},
|
|
1709
1746
|
{ passive: !0 }
|
|
1710
1747
|
), q(l.value), e.appendChild(f);
|
|
1711
|
-
let
|
|
1748
|
+
let le;
|
|
1712
1749
|
l.addEventListener("input", () => {
|
|
1713
|
-
clearTimeout(
|
|
1750
|
+
clearTimeout(le), le = setTimeout(() => {
|
|
1714
1751
|
this.searchText.set(o, l.value), q(l.value);
|
|
1715
1752
|
}, this.config.debounceMs ?? 150);
|
|
1716
1753
|
});
|
|
1717
1754
|
const N = document.createElement("div");
|
|
1718
1755
|
N.className = "tbw-filter-buttons";
|
|
1719
|
-
const
|
|
1720
|
-
|
|
1721
|
-
const
|
|
1722
|
-
for (const [R, E] of
|
|
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)
|
|
1723
1760
|
if (!E)
|
|
1724
1761
|
if (R === "__null__")
|
|
1725
|
-
|
|
1762
|
+
v.push(null);
|
|
1726
1763
|
else {
|
|
1727
1764
|
const C = n.find((y) => String(y) === R);
|
|
1728
|
-
|
|
1765
|
+
v.push(C !== void 0 ? C : R);
|
|
1729
1766
|
}
|
|
1730
|
-
t.applySetFilter(
|
|
1731
|
-
}), N.appendChild(
|
|
1732
|
-
const
|
|
1733
|
-
|
|
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", () => {
|
|
1734
1771
|
t.clearFilter();
|
|
1735
|
-
}), N.appendChild(
|
|
1772
|
+
}), N.appendChild(O), e.appendChild(N);
|
|
1736
1773
|
}
|
|
1737
1774
|
/**
|
|
1738
1775
|
* Apply a set filter (exclude values)
|
|
@@ -1815,11 +1852,8 @@ class _ extends x {
|
|
|
1815
1852
|
this.filters.set(e, n), this.cachedResult = null, this.cacheKey = null;
|
|
1816
1853
|
}
|
|
1817
1854
|
// #endregion
|
|
1818
|
-
// #region Styles
|
|
1819
|
-
styles = gt;
|
|
1820
|
-
// #endregion
|
|
1821
1855
|
}
|
|
1822
|
-
function
|
|
1856
|
+
function ye(s) {
|
|
1823
1857
|
if (!s.length) return [];
|
|
1824
1858
|
const e = /* @__PURE__ */ new Map(), t = [], n = (r, l) => {
|
|
1825
1859
|
if (!l.length) return;
|
|
@@ -1854,7 +1888,7 @@ function mt(s) {
|
|
|
1854
1888
|
}, e.set(d, c), t.push(c)), c.columns.push(r);
|
|
1855
1889
|
}), i.length && n(o, i), t.length === 1 && t[0].implicit && t[0].columns.length === s.length ? [] : t;
|
|
1856
1890
|
}
|
|
1857
|
-
function
|
|
1891
|
+
function Ct(s, e, t) {
|
|
1858
1892
|
if (!e.length || !s) return;
|
|
1859
1893
|
const n = /* @__PURE__ */ new Map();
|
|
1860
1894
|
for (const o of e)
|
|
@@ -1870,23 +1904,25 @@ function wt(s, e, t) {
|
|
|
1870
1904
|
l && l.classList.add("group-end");
|
|
1871
1905
|
}
|
|
1872
1906
|
}
|
|
1873
|
-
function
|
|
1907
|
+
function Rt(s, e) {
|
|
1874
1908
|
if (s.length === 0) return null;
|
|
1875
1909
|
const t = document.createElement("div");
|
|
1876
1910
|
t.className = "header-group-row", t.setAttribute("role", "row");
|
|
1877
1911
|
for (const n of s) {
|
|
1878
|
-
const i = n.
|
|
1879
|
-
|
|
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);
|
|
1880
1916
|
}
|
|
1881
1917
|
return t;
|
|
1882
1918
|
}
|
|
1883
|
-
function
|
|
1919
|
+
function Et(s) {
|
|
1884
1920
|
return s.some((e) => e.group != null);
|
|
1885
1921
|
}
|
|
1886
|
-
const
|
|
1887
|
-
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 {
|
|
1888
1924
|
name = "groupingColumns";
|
|
1889
|
-
|
|
1925
|
+
styles = St;
|
|
1890
1926
|
get defaultConfig() {
|
|
1891
1927
|
return {
|
|
1892
1928
|
showGroupBorders: !0
|
|
@@ -1910,7 +1946,7 @@ class Nn extends x {
|
|
|
1910
1946
|
if (t?.columnGroups && Array.isArray(t.columnGroups) && t.columnGroups.length > 0)
|
|
1911
1947
|
return !0;
|
|
1912
1948
|
const n = t?.columns;
|
|
1913
|
-
return Array.isArray(n) ?
|
|
1949
|
+
return Array.isArray(n) ? Et(n) : !1;
|
|
1914
1950
|
}
|
|
1915
1951
|
// #endregion
|
|
1916
1952
|
// #region Hooks
|
|
@@ -1928,27 +1964,29 @@ class Nn extends x {
|
|
|
1928
1964
|
});
|
|
1929
1965
|
} else
|
|
1930
1966
|
n = [...e];
|
|
1931
|
-
const i =
|
|
1967
|
+
const i = ye(n);
|
|
1932
1968
|
return i.length === 0 ? (this.isActive = !1, this.groups = [], n) : (this.isActive = !0, this.groups = i, n);
|
|
1933
1969
|
}
|
|
1934
1970
|
afterRender() {
|
|
1935
|
-
if (!this.isActive
|
|
1936
|
-
const
|
|
1937
|
-
|
|
1971
|
+
if (!this.isActive) {
|
|
1972
|
+
const a = this.shadowRoot?.querySelector(".header")?.querySelector(".header-group-row");
|
|
1973
|
+
a && a.remove();
|
|
1938
1974
|
return;
|
|
1939
1975
|
}
|
|
1940
1976
|
const e = this.shadowRoot?.querySelector(".header");
|
|
1941
1977
|
if (!e) return;
|
|
1942
1978
|
const t = e.querySelector(".header-group-row");
|
|
1943
1979
|
t && t.remove();
|
|
1944
|
-
const n =
|
|
1945
|
-
if (
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
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);
|
|
1949
1987
|
}
|
|
1950
|
-
const
|
|
1951
|
-
|
|
1988
|
+
const r = e.querySelector(".header-row");
|
|
1989
|
+
r && (r.classList.toggle("no-group-borders", !this.config.showGroupBorders), Ct(r, i));
|
|
1952
1990
|
}
|
|
1953
1991
|
// #endregion
|
|
1954
1992
|
// #region Public API
|
|
@@ -1982,11 +2020,8 @@ class Nn extends x {
|
|
|
1982
2020
|
this.requestRender();
|
|
1983
2021
|
}
|
|
1984
2022
|
// #endregion
|
|
1985
|
-
// #region Styles
|
|
1986
|
-
styles = yt;
|
|
1987
|
-
// #endregion
|
|
1988
2023
|
}
|
|
1989
|
-
function
|
|
2024
|
+
function kt({ rows: s, config: e, expanded: t }) {
|
|
1990
2025
|
const n = e.groupOn;
|
|
1991
2026
|
if (typeof n != "function")
|
|
1992
2027
|
return [];
|
|
@@ -1995,10 +2030,10 @@ function xt({ rows: s, config: e, expanded: t }) {
|
|
|
1995
2030
|
let a = n(l);
|
|
1996
2031
|
a == null || a === !1 ? a = ["__ungrouped__"] : Array.isArray(a) || (a = [a]);
|
|
1997
2032
|
let d = i;
|
|
1998
|
-
a.forEach((c,
|
|
1999
|
-
const
|
|
2000
|
-
let g = d.children.get(
|
|
2001
|
-
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;
|
|
2002
2037
|
}), d.rows.push(l);
|
|
2003
2038
|
}), i.children.size === 1 && i.children.has("__ungrouped__") && i.children.get("__ungrouped__").rows.length === s.length)
|
|
2004
2039
|
return [];
|
|
@@ -2019,26 +2054,26 @@ function xt({ rows: s, config: e, expanded: t }) {
|
|
|
2019
2054
|
};
|
|
2020
2055
|
return r(i), o;
|
|
2021
2056
|
}
|
|
2022
|
-
function
|
|
2057
|
+
function At(s, e) {
|
|
2023
2058
|
const t = new Set(s);
|
|
2024
2059
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
2025
2060
|
}
|
|
2026
|
-
function
|
|
2061
|
+
function _t(s) {
|
|
2027
2062
|
const e = /* @__PURE__ */ new Set();
|
|
2028
2063
|
for (const t of s)
|
|
2029
2064
|
t.kind === "group" && e.add(t.key);
|
|
2030
2065
|
return e;
|
|
2031
2066
|
}
|
|
2032
|
-
function
|
|
2067
|
+
function Lt() {
|
|
2033
2068
|
return /* @__PURE__ */ new Set();
|
|
2034
2069
|
}
|
|
2035
|
-
function
|
|
2070
|
+
function Tt(s) {
|
|
2036
2071
|
return s.kind !== "group" ? 0 : s.rows.length;
|
|
2037
2072
|
}
|
|
2038
|
-
const
|
|
2039
|
-
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 {
|
|
2040
2075
|
name = "groupingRows";
|
|
2041
|
-
|
|
2076
|
+
styles = It;
|
|
2042
2077
|
get defaultConfig() {
|
|
2043
2078
|
return {
|
|
2044
2079
|
defaultExpanded: !1,
|
|
@@ -2056,15 +2091,12 @@ class Kn extends x {
|
|
|
2056
2091
|
keysToAnimate = /* @__PURE__ */ new Set();
|
|
2057
2092
|
// #endregion
|
|
2058
2093
|
// #region Animation
|
|
2094
|
+
/**
|
|
2095
|
+
* Get expand/collapse animation style from plugin config.
|
|
2096
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
2097
|
+
*/
|
|
2059
2098
|
get animationStyle() {
|
|
2060
|
-
|
|
2061
|
-
if (t === !1 || t === "off") return !1;
|
|
2062
|
-
if (t !== !0 && t !== "on") {
|
|
2063
|
-
const n = this.shadowRoot?.host;
|
|
2064
|
-
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
2065
|
-
return !1;
|
|
2066
|
-
}
|
|
2067
|
-
return this.config.animation ?? "slide";
|
|
2099
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
2068
2100
|
}
|
|
2069
2101
|
// #endregion
|
|
2070
2102
|
// #region Lifecycle
|
|
@@ -2084,7 +2116,7 @@ class Kn extends x {
|
|
|
2084
2116
|
const t = this.config;
|
|
2085
2117
|
if (typeof t.groupOn != "function")
|
|
2086
2118
|
return this.isActive = !1, this.flattenedRows = [], [...e];
|
|
2087
|
-
const n =
|
|
2119
|
+
const n = kt({
|
|
2088
2120
|
rows: [...e],
|
|
2089
2121
|
config: t,
|
|
2090
2122
|
expanded: this.expandedKeys
|
|
@@ -2105,7 +2137,7 @@ class Kn extends x {
|
|
|
2105
2137
|
__groupDepth: o.depth,
|
|
2106
2138
|
__groupRows: o.rows,
|
|
2107
2139
|
__groupExpanded: o.expanded,
|
|
2108
|
-
__groupRowCount:
|
|
2140
|
+
__groupRowCount: Tt(o)
|
|
2109
2141
|
} : o.row);
|
|
2110
2142
|
}
|
|
2111
2143
|
onCellClick(e) {
|
|
@@ -2113,6 +2145,12 @@ class Kn extends x {
|
|
|
2113
2145
|
if (t?.__isGroupRow && e.originalEvent.target?.closest(".group-toggle"))
|
|
2114
2146
|
return this.toggle(t.__groupKey), !0;
|
|
2115
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
|
+
}
|
|
2116
2154
|
/**
|
|
2117
2155
|
* Render a row. Returns true if we handled the row (group row), false otherwise.
|
|
2118
2156
|
*/
|
|
@@ -2132,12 +2170,12 @@ class Kn extends x {
|
|
|
2132
2170
|
toggleExpand: l
|
|
2133
2171
|
});
|
|
2134
2172
|
if (a)
|
|
2135
|
-
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;
|
|
2136
2174
|
}
|
|
2137
2175
|
const o = () => {
|
|
2138
2176
|
this.toggle(e.__groupKey);
|
|
2139
2177
|
};
|
|
2140
|
-
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;
|
|
2141
2179
|
}
|
|
2142
2180
|
afterRender() {
|
|
2143
2181
|
const e = this.animationStyle;
|
|
@@ -2153,52 +2191,63 @@ class Kn extends x {
|
|
|
2153
2191
|
}
|
|
2154
2192
|
// #endregion
|
|
2155
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
|
+
}
|
|
2156
2210
|
renderFullWidthGroupRow(e, t, n) {
|
|
2157
2211
|
const i = this.config, o = document.createElement("div");
|
|
2158
|
-
o.className = "cell group-full", o.style.gridColumn = "1 / -1", o.setAttribute("role", "gridcell");
|
|
2159
|
-
const r = document.createElement("
|
|
2160
|
-
r.
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
const l = document.createElement("span");
|
|
2164
|
-
l.className = "group-label";
|
|
2165
|
-
const a = i.formatLabel ? i.formatLabel(e.__groupValue, e.__groupDepth || 0, e.__groupKey) : String(e.__groupValue);
|
|
2166
|
-
if (l.textContent = a, o.appendChild(l), i.showRowCount !== !1) {
|
|
2167
|
-
const d = document.createElement("span");
|
|
2168
|
-
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);
|
|
2169
2217
|
}
|
|
2170
2218
|
t.appendChild(o);
|
|
2171
2219
|
}
|
|
2172
2220
|
renderPerColumnGroupRow(e, t, n) {
|
|
2173
2221
|
const i = this.config, o = i.aggregators ?? {}, r = this.columns, l = e.__groupRows ?? [], d = this.shadowRoot?.querySelector(".body")?.style.gridTemplateColumns || "";
|
|
2174
|
-
d && (t.style.display = "grid", t.style.gridTemplateColumns = d)
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
if (u.appendChild(g), i.showRowCount !== !1) {
|
|
2190
|
-
const w = document.createElement("span");
|
|
2191
|
-
w.className = "group-count", w.textContent = ` (${l.length})`, u.appendChild(w);
|
|
2192
|
-
}
|
|
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 = "";
|
|
2193
2237
|
} else {
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
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);
|
|
2198
2243
|
} else
|
|
2199
|
-
|
|
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
|
+
}
|
|
2200
2249
|
}
|
|
2201
|
-
t.appendChild(
|
|
2250
|
+
t.appendChild(f);
|
|
2202
2251
|
});
|
|
2203
2252
|
}
|
|
2204
2253
|
// #endregion
|
|
@@ -2207,20 +2256,20 @@ class Kn extends x {
|
|
|
2207
2256
|
* Expand all groups.
|
|
2208
2257
|
*/
|
|
2209
2258
|
expandAll() {
|
|
2210
|
-
this.expandedKeys =
|
|
2259
|
+
this.expandedKeys = _t(this.flattenedRows), this.requestRender();
|
|
2211
2260
|
}
|
|
2212
2261
|
/**
|
|
2213
2262
|
* Collapse all groups.
|
|
2214
2263
|
*/
|
|
2215
2264
|
collapseAll() {
|
|
2216
|
-
this.expandedKeys =
|
|
2265
|
+
this.expandedKeys = Lt(), this.requestRender();
|
|
2217
2266
|
}
|
|
2218
2267
|
/**
|
|
2219
2268
|
* Toggle expansion of a specific group.
|
|
2220
2269
|
* @param key - The group key to toggle
|
|
2221
2270
|
*/
|
|
2222
2271
|
toggle(e) {
|
|
2223
|
-
this.expandedKeys =
|
|
2272
|
+
this.expandedKeys = At(this.expandedKeys, e);
|
|
2224
2273
|
const t = this.flattenedRows.find((n) => n.kind === "group" && n.key === e);
|
|
2225
2274
|
this.emit("group-toggle", {
|
|
2226
2275
|
key: e,
|
|
@@ -2310,26 +2359,23 @@ class Kn extends x {
|
|
|
2310
2359
|
this.config.groupOn = e, this.requestRender();
|
|
2311
2360
|
}
|
|
2312
2361
|
// #endregion
|
|
2313
|
-
// #region Styles
|
|
2314
|
-
styles = kt;
|
|
2315
|
-
// #endregion
|
|
2316
2362
|
}
|
|
2317
|
-
function
|
|
2363
|
+
function xe(s, e) {
|
|
2318
2364
|
const t = new Set(s);
|
|
2319
2365
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
2320
2366
|
}
|
|
2321
|
-
function
|
|
2367
|
+
function Ft(s, e) {
|
|
2322
2368
|
const t = new Set(s);
|
|
2323
2369
|
return t.add(e), t;
|
|
2324
2370
|
}
|
|
2325
|
-
function
|
|
2371
|
+
function Mt(s, e) {
|
|
2326
2372
|
const t = new Set(s);
|
|
2327
2373
|
return t.delete(e), t;
|
|
2328
2374
|
}
|
|
2329
|
-
function
|
|
2375
|
+
function Pt(s, e) {
|
|
2330
2376
|
return s.has(e);
|
|
2331
2377
|
}
|
|
2332
|
-
function
|
|
2378
|
+
function Dt(s, e, t, n) {
|
|
2333
2379
|
const i = document.createElement("div");
|
|
2334
2380
|
i.className = "master-detail-row", i.setAttribute("data-detail-for", String(e)), i.setAttribute("role", "row");
|
|
2335
2381
|
const o = document.createElement("div");
|
|
@@ -2337,10 +2383,10 @@ function Tt(s, e, t, n) {
|
|
|
2337
2383
|
const r = t(s, e);
|
|
2338
2384
|
return typeof r == "string" ? o.innerHTML = r : r instanceof HTMLElement && o.appendChild(r), i.appendChild(o), i;
|
|
2339
2385
|
}
|
|
2340
|
-
const
|
|
2341
|
-
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 {
|
|
2342
2388
|
name = "masterDetail";
|
|
2343
|
-
|
|
2389
|
+
styles = Kt;
|
|
2344
2390
|
get defaultConfig() {
|
|
2345
2391
|
return {
|
|
2346
2392
|
detailHeight: "auto",
|
|
@@ -2388,50 +2434,29 @@ class Dn extends x {
|
|
|
2388
2434
|
if (!t) return;
|
|
2389
2435
|
const n = e;
|
|
2390
2436
|
if (n.__frameworkAdapter?.parseDetailElement) {
|
|
2391
|
-
const
|
|
2392
|
-
if (
|
|
2393
|
-
this.config = { ...this.config, detailRenderer:
|
|
2437
|
+
const u = n.__frameworkAdapter.parseDetailElement(t);
|
|
2438
|
+
if (u) {
|
|
2439
|
+
this.config = { ...this.config, detailRenderer: u };
|
|
2394
2440
|
return;
|
|
2395
2441
|
}
|
|
2396
2442
|
}
|
|
2397
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 = {};
|
|
2398
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));
|
|
2399
2445
|
const c = t.innerHTML.trim();
|
|
2400
|
-
c && !this.config.detailRenderer && (d.detailRenderer = (
|
|
2401
|
-
const f =
|
|
2402
|
-
return
|
|
2446
|
+
c && !this.config.detailRenderer && (d.detailRenderer = (u, h) => {
|
|
2447
|
+
const f = je(c, { value: u, row: u });
|
|
2448
|
+
return Ue(f);
|
|
2403
2449
|
}), Object.keys(d).length > 0 && (this.config = { ...this.config, ...d });
|
|
2404
2450
|
}
|
|
2405
2451
|
// #endregion
|
|
2406
2452
|
// #region Animation Helpers
|
|
2407
|
-
/**
|
|
2408
|
-
* Check if animations are enabled at the grid level.
|
|
2409
|
-
* Respects gridConfig.animation.mode and CSS variable.
|
|
2410
|
-
*/
|
|
2411
|
-
get isAnimationEnabled() {
|
|
2412
|
-
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
2413
|
-
if (t === !1 || t === "off") return !1;
|
|
2414
|
-
if (t === !0 || t === "on") return !0;
|
|
2415
|
-
const n = this.shadowRoot?.host;
|
|
2416
|
-
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
2417
|
-
}
|
|
2418
2453
|
/**
|
|
2419
2454
|
* Get expand/collapse animation style from plugin config.
|
|
2455
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
2420
2456
|
*/
|
|
2421
2457
|
get animationStyle() {
|
|
2422
2458
|
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
2423
2459
|
}
|
|
2424
|
-
/**
|
|
2425
|
-
* Get animation duration from CSS variable (set by grid).
|
|
2426
|
-
*/
|
|
2427
|
-
get animationDuration() {
|
|
2428
|
-
const e = this.shadowRoot?.host;
|
|
2429
|
-
if (e) {
|
|
2430
|
-
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
2431
|
-
if (!isNaN(n)) return n;
|
|
2432
|
-
}
|
|
2433
|
-
return 200;
|
|
2434
|
-
}
|
|
2435
2460
|
/**
|
|
2436
2461
|
* Apply expand animation to a detail element.
|
|
2437
2462
|
*/
|
|
@@ -2462,6 +2487,25 @@ class Dn extends x {
|
|
|
2462
2487
|
// #region Internal State
|
|
2463
2488
|
expandedRows = /* @__PURE__ */ new Set();
|
|
2464
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
|
+
}
|
|
2465
2509
|
// #endregion
|
|
2466
2510
|
// #region Lifecycle
|
|
2467
2511
|
detach() {
|
|
@@ -2470,49 +2514,36 @@ class Dn extends x {
|
|
|
2470
2514
|
// #endregion
|
|
2471
2515
|
// #region Hooks
|
|
2472
2516
|
processColumns(e) {
|
|
2473
|
-
if (!this.config.detailRenderer)
|
|
2517
|
+
if (!this.config.detailRenderer || this.config.showExpandColumn === !1)
|
|
2474
2518
|
return [...e];
|
|
2475
2519
|
const t = [...e];
|
|
2476
|
-
if (t
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
const o = (r)
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
const u = document.createElement("span");
|
|
2486
|
-
if (i) {
|
|
2487
|
-
const f = i(r);
|
|
2488
|
-
f instanceof Node ? u.appendChild(f) : u.textContent = String(f ?? l ?? "");
|
|
2489
|
-
} else
|
|
2490
|
-
u.textContent = String(l ?? "");
|
|
2491
|
-
return c.appendChild(u), c;
|
|
2492
|
-
};
|
|
2493
|
-
o.__masterDetailWrapped = !0, n.viewRenderer = o, t[0] = n;
|
|
2494
|
-
}
|
|
2495
|
-
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];
|
|
2496
2529
|
}
|
|
2497
2530
|
onRowClick(e) {
|
|
2498
2531
|
if (!(!this.config.expandOnRowClick || !this.config.detailRenderer))
|
|
2499
|
-
return this.
|
|
2500
|
-
rowIndex: e.rowIndex,
|
|
2501
|
-
row: e.row,
|
|
2502
|
-
expanded: this.expandedRows.has(e.row)
|
|
2503
|
-
}), this.requestRender(), !1;
|
|
2532
|
+
return this.toggleAndEmit(e.row, e.rowIndex), !1;
|
|
2504
2533
|
}
|
|
2505
2534
|
onCellClick(e) {
|
|
2506
|
-
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
2507
|
-
|
|
2508
|
-
return this.expandedRows = Z(this.expandedRows, n), this.emit("detail-expand", {
|
|
2509
|
-
rowIndex: i,
|
|
2510
|
-
row: n,
|
|
2511
|
-
expanded: this.expandedRows.has(n)
|
|
2512
|
-
}), this.requestRender(), !0;
|
|
2513
|
-
}
|
|
2535
|
+
if (e.originalEvent?.target?.classList.contains("master-detail-toggle"))
|
|
2536
|
+
return this.toggleAndEmit(e.row, e.rowIndex), !0;
|
|
2514
2537
|
this.expandedRows.size > 0 && queueMicrotask(() => this.#e());
|
|
2515
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
|
+
}
|
|
2516
2547
|
afterRender() {
|
|
2517
2548
|
this.#e();
|
|
2518
2549
|
}
|
|
@@ -2549,7 +2580,7 @@ class Dn extends x {
|
|
|
2549
2580
|
d.previousElementSibling !== l && l.after(d);
|
|
2550
2581
|
continue;
|
|
2551
2582
|
}
|
|
2552
|
-
const c =
|
|
2583
|
+
const c = Dt(a, r, this.config.detailRenderer, i);
|
|
2553
2584
|
typeof this.config.detailHeight == "number" && (c.style.height = `${this.config.detailHeight}px`), l.after(c), this.detailElements.set(a, c), this.animateExpand(c);
|
|
2554
2585
|
}
|
|
2555
2586
|
}
|
|
@@ -2559,15 +2590,8 @@ class Dn extends x {
|
|
|
2559
2590
|
*/
|
|
2560
2591
|
getExtraHeight() {
|
|
2561
2592
|
let e = 0;
|
|
2562
|
-
for (const t of this.expandedRows)
|
|
2563
|
-
|
|
2564
|
-
if (n)
|
|
2565
|
-
e += n.offsetHeight;
|
|
2566
|
-
else {
|
|
2567
|
-
const i = this.config?.detailHeight;
|
|
2568
|
-
e += typeof i == "number" ? i : 150;
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2593
|
+
for (const t of this.expandedRows)
|
|
2594
|
+
e += this.getDetailHeight(t);
|
|
2571
2595
|
return e;
|
|
2572
2596
|
}
|
|
2573
2597
|
/**
|
|
@@ -2578,15 +2602,7 @@ class Dn extends x {
|
|
|
2578
2602
|
let t = 0;
|
|
2579
2603
|
for (const n of this.expandedRows) {
|
|
2580
2604
|
const i = this.rows.indexOf(n);
|
|
2581
|
-
|
|
2582
|
-
const o = this.detailElements.get(n);
|
|
2583
|
-
if (o)
|
|
2584
|
-
t += o.offsetHeight;
|
|
2585
|
-
else {
|
|
2586
|
-
const r = this.config?.detailHeight;
|
|
2587
|
-
t += typeof r == "number" ? r : 150;
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2605
|
+
i >= 0 && i < e && (t += this.getDetailHeight(n));
|
|
2590
2606
|
}
|
|
2591
2607
|
return t;
|
|
2592
2608
|
}
|
|
@@ -2604,8 +2620,8 @@ class Dn extends x {
|
|
|
2604
2620
|
i.sort((l, a) => l.index - a.index);
|
|
2605
2621
|
let o = e, r = 0;
|
|
2606
2622
|
for (const { index: l, row: a } of i) {
|
|
2607
|
-
const d = l * n + r,
|
|
2608
|
-
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);
|
|
2609
2625
|
}
|
|
2610
2626
|
return o;
|
|
2611
2627
|
}
|
|
@@ -2617,7 +2633,7 @@ class Dn extends x {
|
|
|
2617
2633
|
*/
|
|
2618
2634
|
expand(e) {
|
|
2619
2635
|
const t = this.rows[e];
|
|
2620
|
-
t && (this.expandedRows =
|
|
2636
|
+
t && (this.expandedRows = Ft(this.expandedRows, t), this.requestRender());
|
|
2621
2637
|
}
|
|
2622
2638
|
/**
|
|
2623
2639
|
* Collapse the detail row at the given index.
|
|
@@ -2625,7 +2641,7 @@ class Dn extends x {
|
|
|
2625
2641
|
*/
|
|
2626
2642
|
collapse(e) {
|
|
2627
2643
|
const t = this.rows[e];
|
|
2628
|
-
t && (this.expandedRows =
|
|
2644
|
+
t && (this.expandedRows = Mt(this.expandedRows, t), this.requestRender());
|
|
2629
2645
|
}
|
|
2630
2646
|
/**
|
|
2631
2647
|
* Toggle the detail row at the given index.
|
|
@@ -2633,7 +2649,7 @@ class Dn extends x {
|
|
|
2633
2649
|
*/
|
|
2634
2650
|
toggle(e) {
|
|
2635
2651
|
const t = this.rows[e];
|
|
2636
|
-
t && (this.expandedRows =
|
|
2652
|
+
t && (this.expandedRows = xe(this.expandedRows, t), this.requestRender());
|
|
2637
2653
|
}
|
|
2638
2654
|
/**
|
|
2639
2655
|
* Check if the detail row at the given index is expanded.
|
|
@@ -2642,7 +2658,7 @@ class Dn extends x {
|
|
|
2642
2658
|
*/
|
|
2643
2659
|
isExpanded(e) {
|
|
2644
2660
|
const t = this.rows[e];
|
|
2645
|
-
return t ?
|
|
2661
|
+
return t ? Pt(this.expandedRows, t) : !1;
|
|
2646
2662
|
}
|
|
2647
2663
|
/**
|
|
2648
2664
|
* Expand all detail rows.
|
|
@@ -2694,24 +2710,21 @@ class Dn extends x {
|
|
|
2694
2710
|
}
|
|
2695
2711
|
}
|
|
2696
2712
|
// #endregion
|
|
2697
|
-
// #region Styles
|
|
2698
|
-
styles = It;
|
|
2699
|
-
// #endregion
|
|
2700
2713
|
}
|
|
2701
|
-
function
|
|
2714
|
+
function qt(s, e, t) {
|
|
2702
2715
|
return e.length ? [...s].sort((n, i) => {
|
|
2703
2716
|
for (const o of e) {
|
|
2704
|
-
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);
|
|
2705
2718
|
if (c !== 0)
|
|
2706
2719
|
return o.direction === "asc" ? c : -c;
|
|
2707
2720
|
}
|
|
2708
2721
|
return 0;
|
|
2709
2722
|
}) : [...s];
|
|
2710
2723
|
}
|
|
2711
|
-
function
|
|
2724
|
+
function Nt(s, e) {
|
|
2712
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));
|
|
2713
2726
|
}
|
|
2714
|
-
function
|
|
2727
|
+
function Ht(s, e, t, n) {
|
|
2715
2728
|
const i = s.find((o) => o.field === e);
|
|
2716
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" }];
|
|
2717
2730
|
}
|
|
@@ -2722,10 +2735,10 @@ function Ce(s, e) {
|
|
|
2722
2735
|
function Re(s, e) {
|
|
2723
2736
|
return s.find((t) => t.field === e)?.direction;
|
|
2724
2737
|
}
|
|
2725
|
-
const
|
|
2726
|
-
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 {
|
|
2727
2740
|
name = "multiSort";
|
|
2728
|
-
|
|
2741
|
+
styles = Ot;
|
|
2729
2742
|
get defaultConfig() {
|
|
2730
2743
|
return {
|
|
2731
2744
|
maxSortColumns: 3,
|
|
@@ -2742,12 +2755,12 @@ class Hn extends x {
|
|
|
2742
2755
|
// #endregion
|
|
2743
2756
|
// #region Hooks
|
|
2744
2757
|
processRows(e) {
|
|
2745
|
-
return this.sortModel.length === 0 ? [...e] :
|
|
2758
|
+
return this.sortModel.length === 0 ? [...e] : qt([...e], this.sortModel, [...this.columns]);
|
|
2746
2759
|
}
|
|
2747
2760
|
onHeaderClick(e) {
|
|
2748
2761
|
if (!this.columns.find((o) => o.field === e.field)?.sortable) return !1;
|
|
2749
2762
|
const n = e.originalEvent.shiftKey, i = this.config.maxSortColumns ?? 3;
|
|
2750
|
-
return this.sortModel =
|
|
2763
|
+
return this.sortModel = Ht(this.sortModel, e.field, n, i), this.emit("sort-change", { sortModel: [...this.sortModel] }), this.requestRender(), !0;
|
|
2751
2764
|
}
|
|
2752
2765
|
afterRender() {
|
|
2753
2766
|
const e = this.shadowRoot;
|
|
@@ -2761,7 +2774,7 @@ class Hn extends x {
|
|
|
2761
2774
|
i.querySelector('[part~="sort-indicator"], .sort-indicator')?.remove(), i.setAttribute("data-sort", l);
|
|
2762
2775
|
const c = document.createElement("span");
|
|
2763
2776
|
c.className = "sort-indicator", this.setIcon(c, this.resolveIcon(l === "asc" ? "sortAsc" : "sortDesc"));
|
|
2764
|
-
const
|
|
2777
|
+
const u = i.querySelector(".tbw-filter-btn"), h = i.querySelector(".resize-handle"), f = u ?? h;
|
|
2765
2778
|
if (f ? i.insertBefore(c, f) : i.appendChild(c), t && this.sortModel.length > 1 && r !== void 0) {
|
|
2766
2779
|
const g = document.createElement("span");
|
|
2767
2780
|
g.className = "sort-index", g.textContent = String(r), c.nextSibling ? i.insertBefore(g, c.nextSibling) : i.appendChild(g);
|
|
@@ -2838,14 +2851,11 @@ class Hn extends x {
|
|
|
2838
2851
|
n !== -1 ? this.sortModel[n] = i : this.sortModel.splice(t.sort.priority, 0, i);
|
|
2839
2852
|
}
|
|
2840
2853
|
// #endregion
|
|
2841
|
-
// #region Styles
|
|
2842
|
-
styles = qt;
|
|
2843
|
-
// #endregion
|
|
2844
2854
|
}
|
|
2845
|
-
function
|
|
2855
|
+
function Gt(s) {
|
|
2846
2856
|
return s.filter((e) => e.sticky === "left");
|
|
2847
2857
|
}
|
|
2848
|
-
function
|
|
2858
|
+
function Bt(s) {
|
|
2849
2859
|
return s.filter((e) => e.sticky === "right");
|
|
2850
2860
|
}
|
|
2851
2861
|
function X(s) {
|
|
@@ -2884,9 +2894,8 @@ function Se(s) {
|
|
|
2884
2894
|
n.classList.remove("sticky-left", "sticky-right"), n.style.position = "", n.style.left = "", n.style.right = "";
|
|
2885
2895
|
});
|
|
2886
2896
|
}
|
|
2887
|
-
class
|
|
2897
|
+
class $n extends x {
|
|
2888
2898
|
name = "pinnedColumns";
|
|
2889
|
-
version = "1.0.0";
|
|
2890
2899
|
get defaultConfig() {
|
|
2891
2900
|
return {};
|
|
2892
2901
|
}
|
|
@@ -2930,7 +2939,7 @@ class On extends x {
|
|
|
2930
2939
|
*/
|
|
2931
2940
|
onPluginQuery(e) {
|
|
2932
2941
|
switch (e.type) {
|
|
2933
|
-
case
|
|
2942
|
+
case He.CAN_MOVE_COLUMN: {
|
|
2934
2943
|
const t = e.context, n = t.sticky;
|
|
2935
2944
|
if (n === "left" || n === "right")
|
|
2936
2945
|
return !1;
|
|
@@ -2955,14 +2964,14 @@ class On extends x {
|
|
|
2955
2964
|
*/
|
|
2956
2965
|
getLeftPinnedColumns() {
|
|
2957
2966
|
const e = [...this.columns];
|
|
2958
|
-
return
|
|
2967
|
+
return Gt(e);
|
|
2959
2968
|
}
|
|
2960
2969
|
/**
|
|
2961
2970
|
* Get columns pinned to the right.
|
|
2962
2971
|
*/
|
|
2963
2972
|
getRightPinnedColumns() {
|
|
2964
2973
|
const e = [...this.columns];
|
|
2965
|
-
return
|
|
2974
|
+
return Bt(e);
|
|
2966
2975
|
}
|
|
2967
2976
|
/**
|
|
2968
2977
|
* Clear all sticky positioning.
|
|
@@ -2996,10 +3005,10 @@ class On extends x {
|
|
|
2996
3005
|
}
|
|
2997
3006
|
// #endregion
|
|
2998
3007
|
}
|
|
2999
|
-
function
|
|
3008
|
+
function Vt(s) {
|
|
3000
3009
|
return typeof s == "object" && s !== null && "aggFunc" in s;
|
|
3001
3010
|
}
|
|
3002
|
-
function
|
|
3011
|
+
function Z(s, e) {
|
|
3003
3012
|
const t = document.createElement("div");
|
|
3004
3013
|
t.className = "tbw-pinned-rows", t.setAttribute("role", "presentation"), t.setAttribute("aria-live", "polite");
|
|
3005
3014
|
const n = document.createElement("div");
|
|
@@ -3021,7 +3030,7 @@ function Y(s, e) {
|
|
|
3021
3030
|
}
|
|
3022
3031
|
if (s.customPanels)
|
|
3023
3032
|
for (const r of s.customPanels) {
|
|
3024
|
-
const l =
|
|
3033
|
+
const l = zt(r, e);
|
|
3025
3034
|
switch (r.position) {
|
|
3026
3035
|
case "left":
|
|
3027
3036
|
n.appendChild(l);
|
|
@@ -3054,23 +3063,23 @@ function Ae(s, e, t, n) {
|
|
|
3054
3063
|
let a, d;
|
|
3055
3064
|
const c = i.aggregators?.[r.field];
|
|
3056
3065
|
if (c)
|
|
3057
|
-
if (
|
|
3058
|
-
const
|
|
3059
|
-
|
|
3066
|
+
if (Vt(c)) {
|
|
3067
|
+
const u = ce(c.aggFunc);
|
|
3068
|
+
u && (a = u(n, r.field, r)), d = c.formatter;
|
|
3060
3069
|
} else {
|
|
3061
|
-
const
|
|
3062
|
-
|
|
3070
|
+
const u = ce(c);
|
|
3071
|
+
u && (a = u(n, r.field, r));
|
|
3063
3072
|
}
|
|
3064
3073
|
else if (i.cells && Object.prototype.hasOwnProperty.call(i.cells, r.field)) {
|
|
3065
|
-
const
|
|
3066
|
-
typeof
|
|
3074
|
+
const u = i.cells[r.field];
|
|
3075
|
+
typeof u == "function" ? a = u(n, r.field, r) : a = u;
|
|
3067
3076
|
}
|
|
3068
3077
|
a != null ? l.textContent = d ? d(a, r.field, r) : String(a) : l.textContent = "", o.appendChild(l);
|
|
3069
3078
|
}
|
|
3070
3079
|
s.appendChild(o);
|
|
3071
3080
|
}
|
|
3072
3081
|
}
|
|
3073
|
-
function
|
|
3082
|
+
function zt(s, e) {
|
|
3074
3083
|
const t = document.createElement("div");
|
|
3075
3084
|
t.className = "tbw-status-panel tbw-status-panel-custom", t.id = `status-panel-${s.id}`;
|
|
3076
3085
|
const n = s.render(e);
|
|
@@ -3086,10 +3095,10 @@ function _e(s, e, t, n, i) {
|
|
|
3086
3095
|
grid: t
|
|
3087
3096
|
};
|
|
3088
3097
|
}
|
|
3089
|
-
const
|
|
3090
|
-
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 {
|
|
3091
3100
|
name = "pinnedRows";
|
|
3092
|
-
|
|
3101
|
+
styles = Wt;
|
|
3093
3102
|
get defaultConfig() {
|
|
3094
3103
|
return {
|
|
3095
3104
|
position: "bottom",
|
|
@@ -3122,12 +3131,12 @@ class Gn extends x {
|
|
|
3122
3131
|
this.grid,
|
|
3123
3132
|
n,
|
|
3124
3133
|
i
|
|
3125
|
-
), 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");
|
|
3126
3135
|
if (l.length > 0) {
|
|
3127
3136
|
if (!this.topAggregationContainer) {
|
|
3128
3137
|
this.topAggregationContainer = ke("top");
|
|
3129
|
-
const
|
|
3130
|
-
|
|
3138
|
+
const h = e.querySelector(".header");
|
|
3139
|
+
h && h.nextSibling ? t.insertBefore(this.topAggregationContainer, h.nextSibling) : t.appendChild(this.topAggregationContainer);
|
|
3131
3140
|
}
|
|
3132
3141
|
Ae(
|
|
3133
3142
|
this.topAggregationContainer,
|
|
@@ -3136,21 +3145,21 @@ class Gn extends x {
|
|
|
3136
3145
|
this.rows
|
|
3137
3146
|
);
|
|
3138
3147
|
} else this.topAggregationContainer && (this.topAggregationContainer.remove(), this.topAggregationContainer = null);
|
|
3139
|
-
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;
|
|
3140
3149
|
if (d && this.config.position === "top")
|
|
3141
3150
|
if (!this.infoBarElement)
|
|
3142
|
-
this.infoBarElement =
|
|
3151
|
+
this.infoBarElement = Z(this.config, o), t.insertBefore(this.infoBarElement, t.firstChild);
|
|
3143
3152
|
else {
|
|
3144
|
-
const
|
|
3145
|
-
this.infoBarElement.replaceWith(
|
|
3153
|
+
const h = Z(this.config, o);
|
|
3154
|
+
this.infoBarElement.replaceWith(h), this.infoBarElement = h;
|
|
3146
3155
|
}
|
|
3147
3156
|
else this.config.position === "top" && this.infoBarElement && (this.infoBarElement.remove(), this.infoBarElement = null);
|
|
3148
|
-
|
|
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(
|
|
3149
3158
|
this.bottomAggregationContainer,
|
|
3150
3159
|
a,
|
|
3151
3160
|
this.visibleColumns,
|
|
3152
3161
|
this.rows
|
|
3153
|
-
)), c && (this.infoBarElement =
|
|
3162
|
+
)), c && (this.infoBarElement = Z(this.config, o), this.footerWrapper.appendChild(this.infoBarElement))) : this.cleanupFooter();
|
|
3154
3163
|
}
|
|
3155
3164
|
// #endregion
|
|
3156
3165
|
// #region Private Methods
|
|
@@ -3225,20 +3234,17 @@ class Gn extends x {
|
|
|
3225
3234
|
this.config.aggregationRows && (this.config.aggregationRows = this.config.aggregationRows.filter((t) => t.id !== e), this.requestRender());
|
|
3226
3235
|
}
|
|
3227
3236
|
// #endregion
|
|
3228
|
-
// #region Styles
|
|
3229
|
-
styles = Ot;
|
|
3230
|
-
// #endregion
|
|
3231
3237
|
}
|
|
3232
|
-
const
|
|
3233
|
-
function
|
|
3238
|
+
const $t = Xe;
|
|
3239
|
+
function jt(s) {
|
|
3234
3240
|
const e = [];
|
|
3235
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;
|
|
3236
3242
|
}
|
|
3237
|
-
function
|
|
3243
|
+
function se(s, e) {
|
|
3238
3244
|
return [...s, e].join("|");
|
|
3239
3245
|
}
|
|
3240
|
-
function
|
|
3241
|
-
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(
|
|
3242
3248
|
s,
|
|
3243
3249
|
t,
|
|
3244
3250
|
n,
|
|
@@ -3248,7 +3254,7 @@ function Bt(s, e) {
|
|
|
3248
3254
|
// starting depth
|
|
3249
3255
|
""
|
|
3250
3256
|
// parent key prefix
|
|
3251
|
-
), l =
|
|
3257
|
+
), l = Yt(r, o, i), a = Object.values(l).reduce((d, c) => d + c, 0);
|
|
3252
3258
|
return {
|
|
3253
3259
|
rows: r,
|
|
3254
3260
|
columnKeys: o,
|
|
@@ -3256,7 +3262,7 @@ function Bt(s, e) {
|
|
|
3256
3262
|
grandTotal: a
|
|
3257
3263
|
};
|
|
3258
3264
|
}
|
|
3259
|
-
function
|
|
3265
|
+
function Xt(s, e) {
|
|
3260
3266
|
if (e.length === 0) return ["value"];
|
|
3261
3267
|
const t = /* @__PURE__ */ new Set();
|
|
3262
3268
|
for (const n of s) {
|
|
@@ -3265,7 +3271,7 @@ function zt(s, e) {
|
|
|
3265
3271
|
}
|
|
3266
3272
|
return [...t].sort();
|
|
3267
3273
|
}
|
|
3268
|
-
function
|
|
3274
|
+
function Zt(s, e) {
|
|
3269
3275
|
const t = /* @__PURE__ */ new Map();
|
|
3270
3276
|
for (const n of s) {
|
|
3271
3277
|
const i = String(n[e] ?? ""), o = t.get(i);
|
|
@@ -3273,25 +3279,25 @@ function $t(s, e) {
|
|
|
3273
3279
|
}
|
|
3274
3280
|
return t;
|
|
3275
3281
|
}
|
|
3276
|
-
function
|
|
3282
|
+
function Be(s, e, t, n, i, o, r) {
|
|
3277
3283
|
const l = [];
|
|
3278
3284
|
if (e.length === 0) {
|
|
3279
|
-
const
|
|
3285
|
+
const h = Le(s, t, n, i), f = Te(h);
|
|
3280
3286
|
return l.push({
|
|
3281
3287
|
rowKey: r || "all",
|
|
3282
3288
|
rowLabel: r || "All",
|
|
3283
3289
|
depth: o,
|
|
3284
|
-
values:
|
|
3290
|
+
values: h,
|
|
3285
3291
|
total: f,
|
|
3286
3292
|
isGroup: !1,
|
|
3287
3293
|
rowCount: s.length
|
|
3288
3294
|
}), l;
|
|
3289
3295
|
}
|
|
3290
|
-
const a = e[0], d = e.slice(1), c = d.length > 0,
|
|
3291
|
-
for (const [
|
|
3292
|
-
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);
|
|
3293
3299
|
let m;
|
|
3294
|
-
c && (m =
|
|
3300
|
+
c && (m = Be(
|
|
3295
3301
|
f,
|
|
3296
3302
|
d,
|
|
3297
3303
|
t,
|
|
@@ -3301,10 +3307,10 @@ function Ge(s, e, t, n, i, o, r) {
|
|
|
3301
3307
|
g
|
|
3302
3308
|
)), l.push({
|
|
3303
3309
|
rowKey: g,
|
|
3304
|
-
rowLabel:
|
|
3310
|
+
rowLabel: h || "(blank)",
|
|
3305
3311
|
depth: o,
|
|
3306
3312
|
values: p,
|
|
3307
|
-
total:
|
|
3313
|
+
total: b,
|
|
3308
3314
|
isGroup: c,
|
|
3309
3315
|
children: m,
|
|
3310
3316
|
rowCount: f.length
|
|
@@ -3316,8 +3322,8 @@ function Le(s, e, t, n) {
|
|
|
3316
3322
|
const i = {};
|
|
3317
3323
|
for (const o of t)
|
|
3318
3324
|
for (const r of n) {
|
|
3319
|
-
const a = (e.length > 0 ? s.filter((
|
|
3320
|
-
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;
|
|
3321
3327
|
}
|
|
3322
3328
|
return i;
|
|
3323
3329
|
}
|
|
@@ -3327,21 +3333,21 @@ function Te(s) {
|
|
|
3327
3333
|
e += t ?? 0;
|
|
3328
3334
|
return e;
|
|
3329
3335
|
}
|
|
3330
|
-
function
|
|
3336
|
+
function Yt(s, e, t) {
|
|
3331
3337
|
const n = {};
|
|
3332
3338
|
function i(o) {
|
|
3333
3339
|
for (const r of o)
|
|
3334
3340
|
if (!r.isGroup || !r.children?.length)
|
|
3335
3341
|
for (const l of e)
|
|
3336
3342
|
for (const a of t) {
|
|
3337
|
-
const d =
|
|
3343
|
+
const d = se([l], a.field);
|
|
3338
3344
|
n[d] = (n[d] ?? 0) + (r.values[d] ?? 0);
|
|
3339
3345
|
}
|
|
3340
3346
|
else r.children && i(r.children);
|
|
3341
3347
|
}
|
|
3342
3348
|
return i(s), n;
|
|
3343
3349
|
}
|
|
3344
|
-
function
|
|
3350
|
+
function Jt(s, e, t = !0) {
|
|
3345
3351
|
const n = [];
|
|
3346
3352
|
function i(o) {
|
|
3347
3353
|
n.push(o);
|
|
@@ -3354,7 +3360,7 @@ function jt(s, e, t = !0) {
|
|
|
3354
3360
|
i(o);
|
|
3355
3361
|
return n;
|
|
3356
3362
|
}
|
|
3357
|
-
function
|
|
3363
|
+
function Qt(s) {
|
|
3358
3364
|
const e = [];
|
|
3359
3365
|
function t(n) {
|
|
3360
3366
|
if (n.isGroup && e.push(n.rowKey), n.children)
|
|
@@ -3365,14 +3371,14 @@ function J(s) {
|
|
|
3365
3371
|
t(n);
|
|
3366
3372
|
return e;
|
|
3367
3373
|
}
|
|
3368
|
-
const
|
|
3369
|
-
function
|
|
3374
|
+
const en = ["sum", "avg", "count", "min", "max", "first", "last"];
|
|
3375
|
+
function tn(s, e, t, n) {
|
|
3370
3376
|
const i = new AbortController(), o = { config: e, callbacks: n, signal: i.signal }, r = document.createElement("div");
|
|
3371
|
-
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), () => {
|
|
3372
3378
|
i.abort(), r.remove();
|
|
3373
3379
|
};
|
|
3374
3380
|
}
|
|
3375
|
-
function
|
|
3381
|
+
function D(s, e) {
|
|
3376
3382
|
const t = document.createElement("div");
|
|
3377
3383
|
t.className = "tbw-pivot-section";
|
|
3378
3384
|
const n = document.createElement("div");
|
|
@@ -3389,7 +3395,7 @@ function Ie(s, e) {
|
|
|
3389
3395
|
l.className = "tbw-pivot-placeholder", l.textContent = "Drag fields here or click to add", o.appendChild(l);
|
|
3390
3396
|
} else
|
|
3391
3397
|
for (const l of r)
|
|
3392
|
-
o.appendChild(
|
|
3398
|
+
o.appendChild(nn(l, s, e));
|
|
3393
3399
|
return o.addEventListener(
|
|
3394
3400
|
"dragover",
|
|
3395
3401
|
(l) => {
|
|
@@ -3412,7 +3418,7 @@ function Ie(s, e) {
|
|
|
3412
3418
|
{ signal: i }
|
|
3413
3419
|
), o;
|
|
3414
3420
|
}
|
|
3415
|
-
function
|
|
3421
|
+
function nn(s, e, t) {
|
|
3416
3422
|
const { callbacks: n, signal: i } = t, o = document.createElement("div");
|
|
3417
3423
|
o.className = "tbw-pivot-field-chip", o.draggable = !0;
|
|
3418
3424
|
const r = n.getAvailableFields().find((d) => d.field === s), l = document.createElement("span");
|
|
@@ -3438,7 +3444,7 @@ function Xt(s, e, t) {
|
|
|
3438
3444
|
{ signal: i }
|
|
3439
3445
|
), o;
|
|
3440
3446
|
}
|
|
3441
|
-
function
|
|
3447
|
+
function on(s) {
|
|
3442
3448
|
const { config: e, callbacks: t, signal: n } = s, i = document.createElement("div");
|
|
3443
3449
|
i.className = "tbw-pivot-drop-zone tbw-pivot-values-zone", i.setAttribute("data-zone", "values");
|
|
3444
3450
|
const o = e.valueFields ?? [];
|
|
@@ -3447,7 +3453,7 @@ function Yt(s) {
|
|
|
3447
3453
|
r.className = "tbw-pivot-placeholder", r.textContent = "Drag numeric fields here for aggregation", i.appendChild(r);
|
|
3448
3454
|
} else
|
|
3449
3455
|
for (const r of o)
|
|
3450
|
-
i.appendChild(
|
|
3456
|
+
i.appendChild(rn(r, s));
|
|
3451
3457
|
return i.addEventListener(
|
|
3452
3458
|
"dragover",
|
|
3453
3459
|
(r) => {
|
|
@@ -3470,7 +3476,7 @@ function Yt(s) {
|
|
|
3470
3476
|
{ signal: n }
|
|
3471
3477
|
), i;
|
|
3472
3478
|
}
|
|
3473
|
-
function
|
|
3479
|
+
function rn(s, e) {
|
|
3474
3480
|
const { callbacks: t, signal: n } = e, i = document.createElement("div");
|
|
3475
3481
|
i.className = "tbw-pivot-field-chip tbw-pivot-value-chip";
|
|
3476
3482
|
const o = t.getAvailableFields().find((c) => c.field === s.field), r = document.createElement("div");
|
|
@@ -3479,9 +3485,9 @@ function Jt(s, e) {
|
|
|
3479
3485
|
l.className = "tbw-pivot-chip-label", l.textContent = o?.header ?? s.field;
|
|
3480
3486
|
const a = document.createElement("select");
|
|
3481
3487
|
a.className = "tbw-pivot-agg-select", a.title = "Aggregation function";
|
|
3482
|
-
for (const c of
|
|
3483
|
-
const
|
|
3484
|
-
|
|
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);
|
|
3485
3491
|
}
|
|
3486
3492
|
a.addEventListener(
|
|
3487
3493
|
"change",
|
|
@@ -3499,7 +3505,7 @@ function Jt(s, e) {
|
|
|
3499
3505
|
{ signal: n }
|
|
3500
3506
|
), r.appendChild(l), r.appendChild(a), i.appendChild(r), i.appendChild(d), i;
|
|
3501
3507
|
}
|
|
3502
|
-
function
|
|
3508
|
+
function sn(s) {
|
|
3503
3509
|
const { config: e, callbacks: t, signal: n } = s, i = document.createElement("div");
|
|
3504
3510
|
i.className = "tbw-pivot-available-fields";
|
|
3505
3511
|
const o = t.getAvailableFields(), r = /* @__PURE__ */ new Set([
|
|
@@ -3529,10 +3535,10 @@ function Qt(s) {
|
|
|
3529
3535
|
}
|
|
3530
3536
|
return i;
|
|
3531
3537
|
}
|
|
3532
|
-
function
|
|
3538
|
+
function ln(s, e) {
|
|
3533
3539
|
const { config: t, callbacks: n, signal: i } = e, o = document.createElement("div");
|
|
3534
3540
|
return o.className = "tbw-pivot-options", o.appendChild(
|
|
3535
|
-
|
|
3541
|
+
Y(
|
|
3536
3542
|
"Enable Pivot View",
|
|
3537
3543
|
s,
|
|
3538
3544
|
(r) => {
|
|
@@ -3541,7 +3547,7 @@ function en(s, e) {
|
|
|
3541
3547
|
i
|
|
3542
3548
|
)
|
|
3543
3549
|
), o.appendChild(
|
|
3544
|
-
|
|
3550
|
+
Y(
|
|
3545
3551
|
"Show Row Totals",
|
|
3546
3552
|
t.showTotals ?? !0,
|
|
3547
3553
|
(r) => {
|
|
@@ -3550,7 +3556,7 @@ function en(s, e) {
|
|
|
3550
3556
|
i
|
|
3551
3557
|
)
|
|
3552
3558
|
), o.appendChild(
|
|
3553
|
-
|
|
3559
|
+
Y(
|
|
3554
3560
|
"Show Grand Total",
|
|
3555
3561
|
t.showGrandTotal ?? !0,
|
|
3556
3562
|
(r) => {
|
|
@@ -3560,7 +3566,7 @@ function en(s, e) {
|
|
|
3560
3566
|
)
|
|
3561
3567
|
), o;
|
|
3562
3568
|
}
|
|
3563
|
-
function
|
|
3569
|
+
function Y(s, e, t, n) {
|
|
3564
3570
|
const i = document.createElement("label");
|
|
3565
3571
|
i.className = "tbw-pivot-checkbox";
|
|
3566
3572
|
const o = document.createElement("input");
|
|
@@ -3568,15 +3574,15 @@ function Q(s, e, t, n) {
|
|
|
3568
3574
|
const r = document.createElement("span");
|
|
3569
3575
|
return r.textContent = s, i.appendChild(o), i.appendChild(r), i;
|
|
3570
3576
|
}
|
|
3571
|
-
function
|
|
3572
|
-
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) => {
|
|
3573
3579
|
const o = document.createElement("div");
|
|
3574
|
-
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) {
|
|
3575
3581
|
const r = Number(s.__pivotIndent) || 0;
|
|
3576
3582
|
o.style.paddingLeft = `${r}px`;
|
|
3577
3583
|
const l = String(s.__pivotRowKey), a = document.createElement("button");
|
|
3578
|
-
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", (
|
|
3579
|
-
|
|
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);
|
|
3580
3586
|
}), o.appendChild(a);
|
|
3581
3587
|
const d = document.createElement("span");
|
|
3582
3588
|
d.className = "pivot-label", d.textContent = String(s.__pivotLabel ?? ""), o.appendChild(d);
|
|
@@ -3589,22 +3595,22 @@ function tn(s, e, t) {
|
|
|
3589
3595
|
e.appendChild(o);
|
|
3590
3596
|
}), !0;
|
|
3591
3597
|
}
|
|
3592
|
-
function
|
|
3593
|
-
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((
|
|
3594
|
-
const
|
|
3595
|
-
if (
|
|
3596
|
-
const
|
|
3597
|
-
|
|
3598
|
-
const
|
|
3599
|
-
|
|
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);
|
|
3600
3606
|
} else {
|
|
3601
|
-
const
|
|
3602
|
-
|
|
3607
|
+
const l = s[i.field];
|
|
3608
|
+
r.textContent = l != null ? String(l) : "";
|
|
3603
3609
|
}
|
|
3604
|
-
e.appendChild(
|
|
3610
|
+
e.appendChild(r);
|
|
3605
3611
|
}), !0;
|
|
3606
3612
|
}
|
|
3607
|
-
function
|
|
3613
|
+
function cn(s, e, t) {
|
|
3608
3614
|
return e.className = "pivot-grand-total-row", e.setAttribute("role", "presentation"), e.innerHTML = "", t.forEach((n, i) => {
|
|
3609
3615
|
const o = document.createElement("div");
|
|
3610
3616
|
if (o.className = "cell", o.setAttribute("data-col", String(i)), i === 0) {
|
|
@@ -3617,10 +3623,10 @@ function on(s, e, t) {
|
|
|
3617
3623
|
e.appendChild(o);
|
|
3618
3624
|
}), !0;
|
|
3619
3625
|
}
|
|
3620
|
-
const
|
|
3621
|
-
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 {
|
|
3622
3628
|
name = "pivot";
|
|
3623
|
-
|
|
3629
|
+
styles = un;
|
|
3624
3630
|
/** Tool panel ID for shell integration */
|
|
3625
3631
|
static PANEL_ID = "pivot";
|
|
3626
3632
|
get defaultConfig() {
|
|
@@ -3651,17 +3657,11 @@ class M extends x {
|
|
|
3651
3657
|
return (this.config.valueFields?.length ?? 0) > 0;
|
|
3652
3658
|
}
|
|
3653
3659
|
/**
|
|
3654
|
-
* Get animation style
|
|
3660
|
+
* Get expand/collapse animation style from plugin config.
|
|
3661
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
3655
3662
|
*/
|
|
3656
3663
|
get animationStyle() {
|
|
3657
|
-
|
|
3658
|
-
if (t === !1 || t === "off") return !1;
|
|
3659
|
-
if (t !== !0 && t !== "on") {
|
|
3660
|
-
const n = this.shadowRoot?.host;
|
|
3661
|
-
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
3662
|
-
return !1;
|
|
3663
|
-
}
|
|
3664
|
-
return this.config.animation ?? "slide";
|
|
3664
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
3665
3665
|
}
|
|
3666
3666
|
// #endregion
|
|
3667
3667
|
// #region Lifecycle
|
|
@@ -3673,7 +3673,7 @@ class M extends x {
|
|
|
3673
3673
|
getToolPanel() {
|
|
3674
3674
|
if ((this.config?.showToolPanel ?? this.userConfig?.showToolPanel ?? !0) !== !1)
|
|
3675
3675
|
return {
|
|
3676
|
-
id:
|
|
3676
|
+
id: F.PANEL_ID,
|
|
3677
3677
|
title: "Pivot",
|
|
3678
3678
|
icon: "⊞",
|
|
3679
3679
|
tooltip: "Configure pivot table",
|
|
@@ -3686,20 +3686,11 @@ class M extends x {
|
|
|
3686
3686
|
processRows(e) {
|
|
3687
3687
|
if (!this.hasInitialized && this.config.active !== !1 && this.hasValidPivotConfig() && (this.hasInitialized = !0, this.isActive = !0), !this.isActive)
|
|
3688
3688
|
return [...e];
|
|
3689
|
-
const t =
|
|
3689
|
+
const t = jt(this.config);
|
|
3690
3690
|
if (t.length > 0)
|
|
3691
3691
|
return this.warn(`Config errors: ${t.join(", ")}`), [...e];
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
for (const l of r)
|
|
3695
|
-
this.expandedKeys.add(l);
|
|
3696
|
-
}
|
|
3697
|
-
if (this.pivotResult = Bt(e, this.config), this.expandedKeys.size === 0 && this.defaultExpanded) {
|
|
3698
|
-
const r = J(this.pivotResult.rows);
|
|
3699
|
-
for (const l of r)
|
|
3700
|
-
this.expandedKeys.add(l);
|
|
3701
|
-
}
|
|
3702
|
-
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(
|
|
3703
3694
|
this.pivotResult.rows,
|
|
3704
3695
|
this.expandedKeys,
|
|
3705
3696
|
this.defaultExpanded
|
|
@@ -3734,7 +3725,7 @@ class M extends x {
|
|
|
3734
3725
|
});
|
|
3735
3726
|
for (const i of this.pivotResult.columnKeys)
|
|
3736
3727
|
for (const o of this.config.valueFields ?? []) {
|
|
3737
|
-
const r =
|
|
3728
|
+
const r = se([i], o.field), l = o.header || this.fieldHeaderMap.get(o.field) || o.field;
|
|
3738
3729
|
t.push({
|
|
3739
3730
|
field: r,
|
|
3740
3731
|
header: `${i} - ${l} (${o.aggFunc})`,
|
|
@@ -3749,14 +3740,15 @@ class M extends x {
|
|
|
3749
3740
|
type: "number"
|
|
3750
3741
|
}), t;
|
|
3751
3742
|
}
|
|
3752
|
-
renderRow(e, t) {
|
|
3753
|
-
const
|
|
3754
|
-
return
|
|
3743
|
+
renderRow(e, t, n) {
|
|
3744
|
+
const i = e;
|
|
3745
|
+
return i.__pivotRowKey && i.__pivotHasChildren ? an(i, t, {
|
|
3755
3746
|
columns: this.gridColumns,
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
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);
|
|
3760
3752
|
}
|
|
3761
3753
|
/**
|
|
3762
3754
|
* Remove pivot-specific classes, attributes, and inline styles from a row element.
|
|
@@ -3766,6 +3758,12 @@ class M extends x {
|
|
|
3766
3758
|
cleanupPivotStyling(e) {
|
|
3767
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 = "");
|
|
3768
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
|
+
}
|
|
3769
3767
|
afterRender() {
|
|
3770
3768
|
this.isActive && this.config.showGrandTotal && this.pivotResult ? this.renderGrandTotalFooter() : this.cleanupGrandTotalFooter();
|
|
3771
3769
|
const e = this.animationStyle;
|
|
@@ -3796,7 +3794,7 @@ class M extends x {
|
|
|
3796
3794
|
__pivotTotal: this.pivotResult.grandTotal,
|
|
3797
3795
|
...this.pivotResult.totals
|
|
3798
3796
|
};
|
|
3799
|
-
|
|
3797
|
+
cn(n, this.grandTotalFooter, this.gridColumns);
|
|
3800
3798
|
}
|
|
3801
3799
|
/**
|
|
3802
3800
|
* Remove the grand total footer element.
|
|
@@ -3816,16 +3814,20 @@ class M extends x {
|
|
|
3816
3814
|
this.expandedKeys.delete(e), this.requestRender();
|
|
3817
3815
|
}
|
|
3818
3816
|
expandAll() {
|
|
3819
|
-
|
|
3820
|
-
const e = J(this.pivotResult.rows);
|
|
3821
|
-
for (const t of e)
|
|
3822
|
-
this.expandedKeys.add(t);
|
|
3823
|
-
this.requestRender();
|
|
3824
|
-
}
|
|
3817
|
+
this.expandAllKeys(), this.requestRender();
|
|
3825
3818
|
}
|
|
3826
3819
|
collapseAll() {
|
|
3827
3820
|
this.expandedKeys.clear(), this.requestRender();
|
|
3828
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
|
+
}
|
|
3829
3831
|
isExpanded(e) {
|
|
3830
3832
|
return this.expandedKeys.has(e);
|
|
3831
3833
|
}
|
|
@@ -3857,23 +3859,42 @@ class M extends x {
|
|
|
3857
3859
|
}
|
|
3858
3860
|
// #endregion
|
|
3859
3861
|
// #region Tool Panel API
|
|
3862
|
+
/**
|
|
3863
|
+
* Show the pivot tool panel.
|
|
3864
|
+
* Opens the tool panel and ensures this section is expanded.
|
|
3865
|
+
*/
|
|
3860
3866
|
showPanel() {
|
|
3861
|
-
this.grid.openToolPanel(
|
|
3867
|
+
this.grid.openToolPanel(), this.grid.expandedToolPanelSections.includes(F.PANEL_ID) || this.grid.toggleToolPanelSection(F.PANEL_ID);
|
|
3862
3868
|
}
|
|
3869
|
+
/**
|
|
3870
|
+
* Hide the tool panel.
|
|
3871
|
+
*/
|
|
3863
3872
|
hidePanel() {
|
|
3864
3873
|
this.grid.closeToolPanel();
|
|
3865
3874
|
}
|
|
3875
|
+
/**
|
|
3876
|
+
* Toggle the pivot tool panel section.
|
|
3877
|
+
*/
|
|
3866
3878
|
togglePanel() {
|
|
3867
|
-
this.grid.
|
|
3879
|
+
this.grid.isToolPanelOpen || this.grid.openToolPanel(), this.grid.toggleToolPanelSection(F.PANEL_ID);
|
|
3868
3880
|
}
|
|
3881
|
+
/**
|
|
3882
|
+
* Check if the pivot panel section is currently expanded.
|
|
3883
|
+
*/
|
|
3869
3884
|
isPanelVisible() {
|
|
3870
|
-
return this.grid.
|
|
3885
|
+
return this.grid.isToolPanelOpen && this.grid.expandedToolPanelSections.includes(F.PANEL_ID);
|
|
3871
3886
|
}
|
|
3872
3887
|
// #endregion
|
|
3873
3888
|
// #region Private Helpers
|
|
3874
3889
|
get gridColumns() {
|
|
3875
3890
|
return this.grid.columns ?? [];
|
|
3876
3891
|
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Refresh pivot and update tool panel if active.
|
|
3894
|
+
*/
|
|
3895
|
+
refreshIfActive() {
|
|
3896
|
+
this.isActive && this.refresh(), this.refreshPanel();
|
|
3897
|
+
}
|
|
3877
3898
|
buildFieldHeaderMap() {
|
|
3878
3899
|
const e = this.getAvailableFields();
|
|
3879
3900
|
this.fieldHeaderMap.clear();
|
|
@@ -3884,12 +3905,11 @@ class M extends x {
|
|
|
3884
3905
|
return this.originalColumns.length > 0 ? this.originalColumns : this.captureOriginalColumns();
|
|
3885
3906
|
}
|
|
3886
3907
|
captureOriginalColumns() {
|
|
3887
|
-
const e = this.grid;
|
|
3888
3908
|
try {
|
|
3889
|
-
const
|
|
3890
|
-
return this.originalColumns =
|
|
3891
|
-
field:
|
|
3892
|
-
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
|
|
3893
3913
|
})), this.originalColumns;
|
|
3894
3914
|
} catch {
|
|
3895
3915
|
return [];
|
|
@@ -3911,7 +3931,7 @@ class M extends x {
|
|
|
3911
3931
|
},
|
|
3912
3932
|
getAvailableFields: () => this.getAvailableFields()
|
|
3913
3933
|
};
|
|
3914
|
-
return
|
|
3934
|
+
return tn(e, this.config, this.isActive, t);
|
|
3915
3935
|
}
|
|
3916
3936
|
refreshPanel() {
|
|
3917
3937
|
this.panelContainer && (this.panelContainer.innerHTML = "", this.renderPanel(this.panelContainer));
|
|
@@ -3924,43 +3944,40 @@ class M extends x {
|
|
|
3924
3944
|
const n = this.config.columnGroupFields ?? [];
|
|
3925
3945
|
n.includes(e) || (this.config.columnGroupFields = [...n, e]);
|
|
3926
3946
|
}
|
|
3927
|
-
this.removeFromOtherZones(e, t), this.
|
|
3947
|
+
this.removeFromOtherZones(e, t), this.refreshIfActive();
|
|
3928
3948
|
}
|
|
3929
3949
|
removeFieldFromZone(e, t) {
|
|
3930
|
-
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();
|
|
3931
3951
|
}
|
|
3932
3952
|
removeFromOtherZones(e, t) {
|
|
3933
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));
|
|
3934
3954
|
}
|
|
3935
3955
|
addValueField(e, t) {
|
|
3936
3956
|
const n = this.config.valueFields ?? [];
|
|
3937
|
-
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();
|
|
3938
3958
|
}
|
|
3939
3959
|
removeValueField(e) {
|
|
3940
|
-
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();
|
|
3941
3961
|
}
|
|
3942
3962
|
updateValueAggFunc(e, t) {
|
|
3943
3963
|
const n = this.config.valueFields ?? [], i = n.findIndex((o) => o.field === e);
|
|
3944
3964
|
i >= 0 && (n[i] = { ...n[i], aggFunc: t }, this.config.valueFields = [...n]), this.isActive && this.refresh();
|
|
3945
3965
|
}
|
|
3946
3966
|
// #endregion
|
|
3947
|
-
// #region Styles
|
|
3948
|
-
styles = rn;
|
|
3949
|
-
// #endregion
|
|
3950
3967
|
}
|
|
3951
|
-
function
|
|
3968
|
+
function hn(s) {
|
|
3952
3969
|
const e = s.meta ?? {};
|
|
3953
3970
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
3954
3971
|
}
|
|
3955
|
-
function
|
|
3972
|
+
function Fe(s, e, t) {
|
|
3956
3973
|
if (e === t || e < 0 || e >= s.length || t < 0 || t > s.length) return s;
|
|
3957
3974
|
const n = [...s], [i] = n.splice(e, 1);
|
|
3958
3975
|
return n.splice(t, 0, i), n;
|
|
3959
3976
|
}
|
|
3960
|
-
const
|
|
3961
|
-
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 {
|
|
3962
3979
|
name = "reorder";
|
|
3963
|
-
|
|
3980
|
+
styles = fn;
|
|
3964
3981
|
get defaultConfig() {
|
|
3965
3982
|
return {
|
|
3966
3983
|
animation: "flip"
|
|
@@ -3969,40 +3986,40 @@ class Vn extends x {
|
|
|
3969
3986
|
}
|
|
3970
3987
|
/**
|
|
3971
3988
|
* Resolve animation type from plugin config.
|
|
3972
|
-
*
|
|
3989
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
3973
3990
|
*/
|
|
3974
3991
|
get animationType() {
|
|
3975
3992
|
return this.isAnimationEnabled ? this.config.animation !== void 0 ? this.config.animation : this.config.viewTransition === !1 ? !1 : (this.config.viewTransition === !0, "flip") : !1;
|
|
3976
3993
|
}
|
|
3977
3994
|
/**
|
|
3978
|
-
*
|
|
3979
|
-
*
|
|
3980
|
-
*/
|
|
3981
|
-
get isAnimationEnabled() {
|
|
3982
|
-
const t = this.grid.effectiveConfig?.animation?.mode ?? "reduced-motion";
|
|
3983
|
-
if (t === !1 || t === "off") return !1;
|
|
3984
|
-
if (t === !0 || t === "on") return !0;
|
|
3985
|
-
const n = this.shadowRoot?.host;
|
|
3986
|
-
return n ? getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() !== "0" : !0;
|
|
3987
|
-
}
|
|
3988
|
-
/**
|
|
3989
|
-
* 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.
|
|
3990
3997
|
*/
|
|
3991
3998
|
get animationDuration() {
|
|
3992
|
-
|
|
3993
|
-
return this.config.animationDuration;
|
|
3994
|
-
const e = this.shadowRoot?.host;
|
|
3995
|
-
if (e) {
|
|
3996
|
-
const t = getComputedStyle(e).getPropertyValue("--tbw-animation-duration").trim(), n = parseInt(t, 10);
|
|
3997
|
-
if (!isNaN(n)) return n;
|
|
3998
|
-
}
|
|
3999
|
-
return 200;
|
|
3999
|
+
return this.config.animationDuration !== void 0 ? this.config.animationDuration : super.animationDuration;
|
|
4000
4000
|
}
|
|
4001
4001
|
// #region Internal State
|
|
4002
4002
|
isDragging = !1;
|
|
4003
4003
|
draggedField = null;
|
|
4004
4004
|
draggedIndex = null;
|
|
4005
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
|
+
}
|
|
4006
4023
|
// #endregion
|
|
4007
4024
|
// #region Lifecycle
|
|
4008
4025
|
attach(e) {
|
|
@@ -4026,39 +4043,34 @@ class Vn extends x {
|
|
|
4026
4043
|
e.querySelectorAll(".header-row > .cell").forEach((n) => {
|
|
4027
4044
|
const i = n, o = i.getAttribute("data-field");
|
|
4028
4045
|
if (!o) return;
|
|
4029
|
-
const r = this.columns.find((
|
|
4030
|
-
|
|
4031
|
-
context: r
|
|
4032
|
-
}).includes(!1);
|
|
4033
|
-
if (!r || !Fe(r) || !d) {
|
|
4046
|
+
const r = this.columns.find((l) => l.field === o);
|
|
4047
|
+
if (!this.canMoveColumnWithPlugins(r)) {
|
|
4034
4048
|
i.draggable = !1;
|
|
4035
4049
|
return;
|
|
4036
4050
|
}
|
|
4037
|
-
i.draggable = !0, !i.getAttribute("data-dragstart-bound") && (i.setAttribute("data-dragstart-bound", "true"), i.addEventListener("dragstart", (
|
|
4038
|
-
const
|
|
4039
|
-
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");
|
|
4040
4054
|
}), i.addEventListener("dragend", () => {
|
|
4041
|
-
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null,
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
const h = i.getBoundingClientRect(), u = h.left + h.width / 2, g = this.getColumnOrder().indexOf(o);
|
|
4047
|
-
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);
|
|
4048
4060
|
}), i.addEventListener("dragleave", () => {
|
|
4049
4061
|
i.classList.remove("drop-target", "drop-before", "drop-after");
|
|
4050
|
-
}), i.addEventListener("drop", (
|
|
4051
|
-
|
|
4052
|
-
const
|
|
4053
|
-
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)
|
|
4054
4066
|
return;
|
|
4055
|
-
const
|
|
4056
|
-
field:
|
|
4057
|
-
fromIndex:
|
|
4058
|
-
toIndex:
|
|
4059
|
-
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
|
|
4060
4072
|
};
|
|
4061
|
-
this.updateColumnOrder(
|
|
4073
|
+
this.updateColumnOrder(f), this.emitCancelable("column-move", g) && this.updateColumnOrder(h);
|
|
4062
4074
|
}));
|
|
4063
4075
|
});
|
|
4064
4076
|
}
|
|
@@ -4071,22 +4083,14 @@ class Vn extends x {
|
|
|
4071
4083
|
const t = this.grid, n = t._focusCol, i = t._visibleColumns;
|
|
4072
4084
|
if (n < 0 || n >= i.length) return;
|
|
4073
4085
|
const o = i[n];
|
|
4074
|
-
if (!
|
|
4075
|
-
const r = this.
|
|
4076
|
-
if (
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
const c = e.key === "ArrowLeft" ? d - 1 : d + 1;
|
|
4083
|
-
if (c < 0 || c >= a.length) return;
|
|
4084
|
-
const h = i.find((u) => u.field === a[c]);
|
|
4085
|
-
if (!(h && r.queryPlugins({
|
|
4086
|
-
type: H.CAN_MOVE_COLUMN,
|
|
4087
|
-
context: h
|
|
4088
|
-
}).includes(!1)))
|
|
4089
|
-
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;
|
|
4090
4094
|
}
|
|
4091
4095
|
// #endregion
|
|
4092
4096
|
// #region Public API
|
|
@@ -4105,13 +4109,13 @@ class Vn extends x {
|
|
|
4105
4109
|
moveColumn(e, t) {
|
|
4106
4110
|
const n = this.getColumnOrder(), i = n.indexOf(e);
|
|
4107
4111
|
if (i === -1) return;
|
|
4108
|
-
const o =
|
|
4109
|
-
this.updateColumnOrder(o), this.
|
|
4112
|
+
const o = Fe(n, i, t);
|
|
4113
|
+
this.updateColumnOrder(o), this.emitCancelable("column-move", {
|
|
4110
4114
|
field: e,
|
|
4111
4115
|
fromIndex: i,
|
|
4112
4116
|
toIndex: t,
|
|
4113
4117
|
columnOrder: o
|
|
4114
|
-
});
|
|
4118
|
+
}) && this.updateColumnOrder(n);
|
|
4115
4119
|
}
|
|
4116
4120
|
/**
|
|
4117
4121
|
* Set a specific column order.
|
|
@@ -4214,21 +4218,47 @@ class Vn extends x {
|
|
|
4214
4218
|
* Update column order with configured animation.
|
|
4215
4219
|
*/
|
|
4216
4220
|
updateColumnOrder(e) {
|
|
4217
|
-
const t = this.
|
|
4218
|
-
if (
|
|
4219
|
-
const
|
|
4220
|
-
|
|
4221
|
-
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);
|
|
4222
4226
|
});
|
|
4223
|
-
} else
|
|
4224
|
-
|
|
4227
|
+
} else t === "fade" ? this.animateFade(() => this.grid.setColumnOrder(e)) : this.grid.setColumnOrder(e);
|
|
4228
|
+
this.grid.requestStateChange?.();
|
|
4225
4229
|
}
|
|
4226
4230
|
// #endregion
|
|
4227
|
-
// #region Styles
|
|
4228
|
-
styles = sn;
|
|
4229
|
-
// #endregion
|
|
4230
4231
|
}
|
|
4231
|
-
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) {
|
|
4232
4262
|
return {
|
|
4233
4263
|
startRow: Math.min(s.startRow, s.endRow),
|
|
4234
4264
|
startCol: Math.min(s.startCol, s.endCol),
|
|
@@ -4236,38 +4266,38 @@ function G(s) {
|
|
|
4236
4266
|
endCol: Math.max(s.startCol, s.endCol)
|
|
4237
4267
|
};
|
|
4238
4268
|
}
|
|
4239
|
-
function
|
|
4240
|
-
const e =
|
|
4269
|
+
function gn(s) {
|
|
4270
|
+
const e = B(s);
|
|
4241
4271
|
return {
|
|
4242
4272
|
from: { row: e.startRow, col: e.startCol },
|
|
4243
4273
|
to: { row: e.endRow, col: e.endCol }
|
|
4244
4274
|
};
|
|
4245
4275
|
}
|
|
4246
|
-
function
|
|
4247
|
-
return s.map(
|
|
4276
|
+
function Ve(s) {
|
|
4277
|
+
return s.map(gn);
|
|
4248
4278
|
}
|
|
4249
|
-
function
|
|
4250
|
-
const n =
|
|
4279
|
+
function pn(s, e, t) {
|
|
4280
|
+
const n = B(t);
|
|
4251
4281
|
return s >= n.startRow && s <= n.endRow && e >= n.startCol && e <= n.endCol;
|
|
4252
4282
|
}
|
|
4253
|
-
function
|
|
4254
|
-
return t.some((n) =>
|
|
4283
|
+
function Me(s, e, t) {
|
|
4284
|
+
return t.some((n) => pn(s, e, n));
|
|
4255
4285
|
}
|
|
4256
|
-
function
|
|
4257
|
-
const e = [], t =
|
|
4286
|
+
function mn(s) {
|
|
4287
|
+
const e = [], t = B(s);
|
|
4258
4288
|
for (let n = t.startRow; n <= t.endRow; n++)
|
|
4259
4289
|
for (let i = t.startCol; i <= t.endCol; i++)
|
|
4260
4290
|
e.push({ row: n, col: i });
|
|
4261
4291
|
return e;
|
|
4262
4292
|
}
|
|
4263
|
-
function
|
|
4293
|
+
function wn(s) {
|
|
4264
4294
|
const e = /* @__PURE__ */ new Map();
|
|
4265
4295
|
for (const t of s)
|
|
4266
|
-
for (const n of
|
|
4296
|
+
for (const n of mn(t))
|
|
4267
4297
|
e.set(`${n.row},${n.col}`, n);
|
|
4268
4298
|
return [...e.values()];
|
|
4269
4299
|
}
|
|
4270
|
-
function
|
|
4300
|
+
function J(s, e) {
|
|
4271
4301
|
return {
|
|
4272
4302
|
startRow: s.row,
|
|
4273
4303
|
startCol: s.col,
|
|
@@ -4275,8 +4305,8 @@ function ee(s, e) {
|
|
|
4275
4305
|
endCol: e.col
|
|
4276
4306
|
};
|
|
4277
4307
|
}
|
|
4278
|
-
const
|
|
4279
|
-
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) {
|
|
4280
4310
|
if (s === "cell" && e.selectedCell)
|
|
4281
4311
|
return {
|
|
4282
4312
|
mode: s,
|
|
@@ -4294,11 +4324,11 @@ function hn(s, e, t) {
|
|
|
4294
4324
|
}));
|
|
4295
4325
|
return { mode: s, ranges: n };
|
|
4296
4326
|
}
|
|
4297
|
-
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: [] };
|
|
4298
4328
|
}
|
|
4299
|
-
class
|
|
4329
|
+
class Jn extends x {
|
|
4300
4330
|
name = "selection";
|
|
4301
|
-
|
|
4331
|
+
styles = bn;
|
|
4302
4332
|
get defaultConfig() {
|
|
4303
4333
|
return {
|
|
4304
4334
|
mode: "cell"
|
|
@@ -4326,32 +4356,34 @@ class Bn extends x {
|
|
|
4326
4356
|
// #endregion
|
|
4327
4357
|
// #region Event Handlers
|
|
4328
4358
|
onCellClick(e) {
|
|
4329
|
-
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);
|
|
4330
4360
|
if (o === "cell")
|
|
4331
|
-
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;
|
|
4332
4362
|
if (o === "row")
|
|
4333
4363
|
return this.selected.clear(), this.selected.add(t), this.lastSelected = t, this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
|
|
4334
4364
|
if (o === "range") {
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
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 = {
|
|
4341
4373
|
startRow: t,
|
|
4342
4374
|
startCol: n,
|
|
4343
4375
|
endRow: t,
|
|
4344
4376
|
endCol: n
|
|
4345
4377
|
};
|
|
4346
|
-
this.ranges.push(
|
|
4378
|
+
this.ranges.push(c), this.activeRange = c, this.cellAnchor = { row: t, col: n };
|
|
4347
4379
|
} else {
|
|
4348
|
-
const
|
|
4380
|
+
const c = {
|
|
4349
4381
|
startRow: t,
|
|
4350
4382
|
startCol: n,
|
|
4351
4383
|
endRow: t,
|
|
4352
4384
|
endCol: n
|
|
4353
4385
|
};
|
|
4354
|
-
this.ranges = [
|
|
4386
|
+
this.ranges = [c], this.activeRange = c, this.cellAnchor = { row: t, col: n };
|
|
4355
4387
|
}
|
|
4356
4388
|
return this.emit("selection-change", this.#t()), this.requestAfterRender(), !1;
|
|
4357
4389
|
}
|
|
@@ -4388,23 +4420,31 @@ class Bn extends x {
|
|
|
4388
4420
|
return !1;
|
|
4389
4421
|
}
|
|
4390
4422
|
onCellMouseDown(e) {
|
|
4391
|
-
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)
|
|
4392
4426
|
return;
|
|
4393
4427
|
this.isDragging = !0;
|
|
4394
|
-
const
|
|
4395
|
-
this.cellAnchor = { row:
|
|
4396
|
-
const
|
|
4397
|
-
startRow:
|
|
4398
|
-
startCol:
|
|
4399
|
-
endRow:
|
|
4400
|
-
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
|
|
4401
4435
|
};
|
|
4402
|
-
return this.ranges.push(
|
|
4436
|
+
return this.ranges.push(r), this.activeRange = r, this.emit("selection-change", this.#t()), this.requestAfterRender(), !0;
|
|
4403
4437
|
}
|
|
4404
4438
|
onCellMouseMove(e) {
|
|
4405
4439
|
if (this.config.mode !== "range" || !this.isDragging || !this.cellAnchor || e.rowIndex === void 0 || e.colIndex === void 0 || e.rowIndex < 0) return;
|
|
4406
|
-
|
|
4407
|
-
|
|
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;
|
|
4408
4448
|
}
|
|
4409
4449
|
onCellMouseUp(e) {
|
|
4410
4450
|
if (this.config.mode === "range" && this.isDragging)
|
|
@@ -4425,14 +4465,23 @@ class Bn extends x {
|
|
|
4425
4465
|
if (i.forEach((o) => {
|
|
4426
4466
|
o.classList.remove("selected", "row-focus");
|
|
4427
4467
|
}), t === "row" && (V(e), i.forEach((o) => {
|
|
4428
|
-
const r = o.querySelector(".cell[data-row]"), l =
|
|
4468
|
+
const r = o.querySelector(".cell[data-row]"), l = Ye(r);
|
|
4429
4469
|
l >= 0 && this.selected.has(l) && o.classList.add("selected", "row-focus");
|
|
4430
4470
|
})), t === "range" && this.ranges.length > 0) {
|
|
4431
4471
|
V(e);
|
|
4432
|
-
const o = this.activeRange ?
|
|
4433
|
-
e.querySelectorAll(".cell[data-row][data-col]").forEach((
|
|
4434
|
-
const
|
|
4435
|
-
|
|
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
|
+
}
|
|
4436
4485
|
});
|
|
4437
4486
|
}
|
|
4438
4487
|
t === "cell" && this.selectedCell && V(e);
|
|
@@ -4446,7 +4495,7 @@ class Bn extends x {
|
|
|
4446
4495
|
this.pendingKeyboardUpdate = null;
|
|
4447
4496
|
const o = this.grid._focusRow, r = this.grid._focusCol;
|
|
4448
4497
|
if (i && this.cellAnchor) {
|
|
4449
|
-
const l =
|
|
4498
|
+
const l = J(this.cellAnchor, { row: o, col: r });
|
|
4450
4499
|
this.ranges = [l], this.activeRange = l;
|
|
4451
4500
|
} else i || (this.ranges = [], this.activeRange = null, this.cellAnchor = { row: o, col: r });
|
|
4452
4501
|
this.emit("selection-change", this.#t());
|
|
@@ -4462,35 +4511,62 @@ class Bn extends x {
|
|
|
4462
4511
|
}
|
|
4463
4512
|
// #endregion
|
|
4464
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
|
+
}
|
|
4465
4536
|
/**
|
|
4466
4537
|
* Get the selected cell (cell mode only).
|
|
4538
|
+
* @deprecated Use `getSelection()` instead for a unified API across all modes.
|
|
4467
4539
|
*/
|
|
4468
4540
|
getSelectedCell() {
|
|
4469
|
-
|
|
4541
|
+
const { mode: e, ranges: t } = this.getSelection();
|
|
4542
|
+
return e === "cell" && t.length > 0 ? t[0].from : null;
|
|
4470
4543
|
}
|
|
4471
4544
|
/**
|
|
4472
4545
|
* Get all selected row indices (row mode).
|
|
4546
|
+
* @deprecated Use `getSelection().ranges` instead - each range represents a full row.
|
|
4473
4547
|
*/
|
|
4474
4548
|
getSelectedRows() {
|
|
4475
|
-
|
|
4549
|
+
const { mode: e, ranges: t } = this.getSelection();
|
|
4550
|
+
return e === "row" ? t.map((n) => n.from.row) : [];
|
|
4476
4551
|
}
|
|
4477
4552
|
/**
|
|
4478
4553
|
* Get all selected cell ranges in public format.
|
|
4554
|
+
* @deprecated Use `getSelection().ranges` instead.
|
|
4479
4555
|
*/
|
|
4480
4556
|
getRanges() {
|
|
4481
|
-
return
|
|
4557
|
+
return this.getSelection().ranges;
|
|
4482
4558
|
}
|
|
4483
4559
|
/**
|
|
4484
4560
|
* Get all selected cells across all ranges.
|
|
4485
4561
|
*/
|
|
4486
4562
|
getSelectedCells() {
|
|
4487
|
-
return
|
|
4563
|
+
return wn(this.ranges);
|
|
4488
4564
|
}
|
|
4489
4565
|
/**
|
|
4490
4566
|
* Check if a specific cell is in range selection.
|
|
4491
4567
|
*/
|
|
4492
4568
|
isCellSelected(e, t) {
|
|
4493
|
-
return
|
|
4569
|
+
return Me(e, t, this.ranges);
|
|
4494
4570
|
}
|
|
4495
4571
|
/**
|
|
4496
4572
|
* Clear all selection.
|
|
@@ -4509,13 +4585,13 @@ class Bn extends x {
|
|
|
4509
4585
|
endCol: t.to.col
|
|
4510
4586
|
})), this.activeRange = this.ranges.length > 0 ? this.ranges[this.ranges.length - 1] : null, this.emit("selection-change", {
|
|
4511
4587
|
mode: this.config.mode,
|
|
4512
|
-
ranges:
|
|
4588
|
+
ranges: Ve(this.ranges)
|
|
4513
4589
|
}), this.requestAfterRender();
|
|
4514
4590
|
}
|
|
4515
4591
|
// #endregion
|
|
4516
4592
|
// #region Private Helpers
|
|
4517
4593
|
#t() {
|
|
4518
|
-
return
|
|
4594
|
+
return vn(
|
|
4519
4595
|
this.config.mode,
|
|
4520
4596
|
{
|
|
4521
4597
|
selectedCell: this.selectedCell,
|
|
@@ -4526,56 +4602,24 @@ class Bn extends x {
|
|
|
4526
4602
|
);
|
|
4527
4603
|
}
|
|
4528
4604
|
// #endregion
|
|
4529
|
-
// #region Styles
|
|
4530
|
-
styles = un;
|
|
4531
|
-
// #endregion
|
|
4532
|
-
}
|
|
4533
|
-
function zn(s, e, t, n) {
|
|
4534
|
-
const i = new Set(s.selected);
|
|
4535
|
-
let o = s.anchor;
|
|
4536
|
-
if (t === "single")
|
|
4537
|
-
i.clear(), i.add(e), o = e;
|
|
4538
|
-
else if (t === "multiple") {
|
|
4539
|
-
const r = n.ctrlKey || n.metaKey;
|
|
4540
|
-
if (n.shiftKey && s.anchor !== null) {
|
|
4541
|
-
const l = Math.min(s.anchor, e), a = Math.max(s.anchor, e);
|
|
4542
|
-
for (let d = l; d <= a; d++)
|
|
4543
|
-
i.add(d);
|
|
4544
|
-
} else r ? (i.has(e) ? i.delete(e) : i.add(e), o = e) : (i.clear(), i.add(e), o = e);
|
|
4545
|
-
}
|
|
4546
|
-
return { selected: i, lastSelected: e, anchor: o };
|
|
4547
|
-
}
|
|
4548
|
-
function $n(s) {
|
|
4549
|
-
const e = /* @__PURE__ */ new Set();
|
|
4550
|
-
for (let t = 0; t < s; t++)
|
|
4551
|
-
e.add(t);
|
|
4552
|
-
return e;
|
|
4553
4605
|
}
|
|
4554
|
-
function
|
|
4555
|
-
const t = [], n = [];
|
|
4556
|
-
for (const i of e)
|
|
4557
|
-
s.has(i) || t.push(i);
|
|
4558
|
-
for (const i of s)
|
|
4559
|
-
e.has(i) || n.push(i);
|
|
4560
|
-
return { added: t, removed: n };
|
|
4561
|
-
}
|
|
4562
|
-
function O(s, e) {
|
|
4606
|
+
function G(s, e) {
|
|
4563
4607
|
return Math.floor(s / e);
|
|
4564
4608
|
}
|
|
4565
|
-
function
|
|
4609
|
+
function yn(s, e) {
|
|
4566
4610
|
return {
|
|
4567
4611
|
start: s * e,
|
|
4568
4612
|
end: (s + 1) * e
|
|
4569
4613
|
};
|
|
4570
4614
|
}
|
|
4571
|
-
function
|
|
4572
|
-
const n =
|
|
4615
|
+
function xn(s, e, t) {
|
|
4616
|
+
const n = G(s, t), i = G(e - 1, t), o = [];
|
|
4573
4617
|
for (let r = n; r <= i; r++)
|
|
4574
4618
|
o.push(r);
|
|
4575
4619
|
return o;
|
|
4576
4620
|
}
|
|
4577
|
-
async function
|
|
4578
|
-
const i =
|
|
4621
|
+
async function Pe(s, e, t, n) {
|
|
4622
|
+
const i = yn(e, t);
|
|
4579
4623
|
return s.getRows({
|
|
4580
4624
|
startRow: i.start,
|
|
4581
4625
|
endRow: i.end,
|
|
@@ -4583,16 +4627,15 @@ async function qe(s, e, t, n) {
|
|
|
4583
4627
|
filterModel: n.filterModel
|
|
4584
4628
|
});
|
|
4585
4629
|
}
|
|
4586
|
-
function
|
|
4587
|
-
const n =
|
|
4630
|
+
function Cn(s, e, t) {
|
|
4631
|
+
const n = G(s, e), i = t.get(n);
|
|
4588
4632
|
if (!i) return;
|
|
4589
4633
|
const o = s % e;
|
|
4590
4634
|
return i[o];
|
|
4591
4635
|
}
|
|
4592
|
-
const
|
|
4593
|
-
class
|
|
4636
|
+
const Rn = 100;
|
|
4637
|
+
class Qn extends x {
|
|
4594
4638
|
name = "serverSide";
|
|
4595
|
-
version = "1.0.0";
|
|
4596
4639
|
get defaultConfig() {
|
|
4597
4640
|
return {
|
|
4598
4641
|
pageSize: 100,
|
|
@@ -4619,12 +4662,12 @@ class jn extends x {
|
|
|
4619
4662
|
*/
|
|
4620
4663
|
loadRequiredBlocks() {
|
|
4621
4664
|
if (!this.dataSource) return;
|
|
4622
|
-
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);
|
|
4623
4666
|
for (const o of i)
|
|
4624
4667
|
if (!(this.loadedBlocks.has(o) || this.loadingBlocks.has(o))) {
|
|
4625
4668
|
if (this.loadingBlocks.size >= (this.config.maxConcurrentRequests ?? 2))
|
|
4626
4669
|
break;
|
|
4627
|
-
this.loadingBlocks.add(o),
|
|
4670
|
+
this.loadingBlocks.add(o), Pe(this.dataSource, o, t, {}).then((r) => {
|
|
4628
4671
|
this.loadedBlocks.set(o, r.rows), this.totalRowCount = r.totalRowCount, this.loadingBlocks.delete(o), this.requestRender(), this.loadRequiredBlocks();
|
|
4629
4672
|
}).catch(() => {
|
|
4630
4673
|
this.loadingBlocks.delete(o);
|
|
@@ -4637,7 +4680,7 @@ class jn extends x {
|
|
|
4637
4680
|
if (!this.dataSource) return [...e];
|
|
4638
4681
|
const t = [];
|
|
4639
4682
|
for (let n = 0; n < this.totalRowCount; n++) {
|
|
4640
|
-
const i =
|
|
4683
|
+
const i = Cn(n, this.config.cacheBlockSize ?? 100, this.loadedBlocks);
|
|
4641
4684
|
t.push(i ?? { __loading: !0, __index: n });
|
|
4642
4685
|
}
|
|
4643
4686
|
return t;
|
|
@@ -4645,7 +4688,7 @@ class jn extends x {
|
|
|
4645
4688
|
onScroll(e) {
|
|
4646
4689
|
this.dataSource && (this.loadRequiredBlocks(), this.scrollDebounceTimer && clearTimeout(this.scrollDebounceTimer), this.scrollDebounceTimer = setTimeout(() => {
|
|
4647
4690
|
this.loadRequiredBlocks();
|
|
4648
|
-
},
|
|
4691
|
+
}, Rn));
|
|
4649
4692
|
}
|
|
4650
4693
|
// #endregion
|
|
4651
4694
|
// #region Public API
|
|
@@ -4656,7 +4699,7 @@ class jn extends x {
|
|
|
4656
4699
|
setDataSource(e) {
|
|
4657
4700
|
this.dataSource = e, this.loadedBlocks.clear(), this.loadingBlocks.clear();
|
|
4658
4701
|
const t = this.config.cacheBlockSize ?? 100;
|
|
4659
|
-
|
|
4702
|
+
Pe(e, 0, t, {}).then((n) => {
|
|
4660
4703
|
this.loadedBlocks.set(0, n.rows), this.totalRowCount = n.totalRowCount, this.requestRender();
|
|
4661
4704
|
});
|
|
4662
4705
|
}
|
|
@@ -4683,7 +4726,7 @@ class jn extends x {
|
|
|
4683
4726
|
* @param rowIndex - Row index to check
|
|
4684
4727
|
*/
|
|
4685
4728
|
isRowLoaded(e) {
|
|
4686
|
-
const t = this.config.cacheBlockSize ?? 100, n =
|
|
4729
|
+
const t = this.config.cacheBlockSize ?? 100, n = G(e, t);
|
|
4687
4730
|
return this.loadedBlocks.has(n);
|
|
4688
4731
|
}
|
|
4689
4732
|
/**
|
|
@@ -4694,52 +4737,52 @@ class jn extends x {
|
|
|
4694
4737
|
}
|
|
4695
4738
|
// #endregion
|
|
4696
4739
|
}
|
|
4697
|
-
function
|
|
4740
|
+
function ze(s, e, t) {
|
|
4698
4741
|
return s.id !== void 0 ? String(s.id) : t ? `${t}-${e}` : String(e);
|
|
4699
4742
|
}
|
|
4700
|
-
function
|
|
4743
|
+
function Q(s, e) {
|
|
4701
4744
|
const t = new Set(s);
|
|
4702
4745
|
return t.has(e) ? t.delete(e) : t.add(e), t;
|
|
4703
4746
|
}
|
|
4704
|
-
function
|
|
4747
|
+
function ne(s, e, t = null, n = 0) {
|
|
4705
4748
|
const i = e.childrenField ?? "children", o = /* @__PURE__ */ new Set();
|
|
4706
4749
|
for (let r = 0; r < s.length; r++) {
|
|
4707
|
-
const l = s[r], a =
|
|
4750
|
+
const l = s[r], a = ze(l, r, t), d = l[i];
|
|
4708
4751
|
if (Array.isArray(d) && d.length > 0) {
|
|
4709
4752
|
o.add(a);
|
|
4710
|
-
const c =
|
|
4711
|
-
for (const
|
|
4753
|
+
const c = ne(d, e, a, n + 1);
|
|
4754
|
+
for (const u of c) o.add(u);
|
|
4712
4755
|
}
|
|
4713
4756
|
}
|
|
4714
4757
|
return o;
|
|
4715
4758
|
}
|
|
4716
|
-
function
|
|
4759
|
+
function En() {
|
|
4717
4760
|
return /* @__PURE__ */ new Set();
|
|
4718
4761
|
}
|
|
4719
|
-
function
|
|
4762
|
+
function We(s, e, t, n = null, i = 0) {
|
|
4720
4763
|
const o = t.childrenField ?? "children";
|
|
4721
4764
|
for (let r = 0; r < s.length; r++) {
|
|
4722
|
-
const l = s[r], a =
|
|
4765
|
+
const l = s[r], a = ze(l, r, n);
|
|
4723
4766
|
if (a === e)
|
|
4724
4767
|
return [a];
|
|
4725
4768
|
const d = l[o];
|
|
4726
4769
|
if (Array.isArray(d) && d.length > 0) {
|
|
4727
|
-
const c =
|
|
4770
|
+
const c = We(d, e, t, a, i + 1);
|
|
4728
4771
|
if (c)
|
|
4729
4772
|
return [a, ...c];
|
|
4730
4773
|
}
|
|
4731
4774
|
}
|
|
4732
4775
|
return null;
|
|
4733
4776
|
}
|
|
4734
|
-
function
|
|
4735
|
-
const i =
|
|
4777
|
+
function Sn(s, e, t, n) {
|
|
4778
|
+
const i = We(s, e, t);
|
|
4736
4779
|
if (!i) return n;
|
|
4737
4780
|
const o = new Set(n);
|
|
4738
4781
|
for (let r = 0; r < i.length - 1; r++)
|
|
4739
4782
|
o.add(i[r]);
|
|
4740
4783
|
return o;
|
|
4741
4784
|
}
|
|
4742
|
-
function
|
|
4785
|
+
function De(s, e = "children") {
|
|
4743
4786
|
if (!Array.isArray(s) || s.length === 0) return !1;
|
|
4744
4787
|
for (const t of s) {
|
|
4745
4788
|
if (!t) continue;
|
|
@@ -4749,7 +4792,7 @@ function Ke(s, e = "children") {
|
|
|
4749
4792
|
}
|
|
4750
4793
|
return !1;
|
|
4751
4794
|
}
|
|
4752
|
-
function
|
|
4795
|
+
function kn(s) {
|
|
4753
4796
|
if (!Array.isArray(s) || s.length === 0) return null;
|
|
4754
4797
|
const e = ["children", "items", "nodes", "subRows", "nested"];
|
|
4755
4798
|
for (const t of s)
|
|
@@ -4761,35 +4804,34 @@ function vn(s) {
|
|
|
4761
4804
|
}
|
|
4762
4805
|
return null;
|
|
4763
4806
|
}
|
|
4764
|
-
function
|
|
4807
|
+
function An(s, e = "children", t = 0) {
|
|
4765
4808
|
if (!Array.isArray(s) || s.length === 0) return t;
|
|
4766
4809
|
let n = t;
|
|
4767
4810
|
for (const i of s) {
|
|
4768
4811
|
if (!i) continue;
|
|
4769
4812
|
const o = i[e];
|
|
4770
4813
|
if (Array.isArray(o) && o.length > 0) {
|
|
4771
|
-
const r =
|
|
4814
|
+
const r = An(o, e, t + 1);
|
|
4772
4815
|
r > n && (n = r);
|
|
4773
4816
|
}
|
|
4774
4817
|
}
|
|
4775
4818
|
return n;
|
|
4776
4819
|
}
|
|
4777
|
-
function
|
|
4820
|
+
function _n(s, e = "children") {
|
|
4778
4821
|
if (!Array.isArray(s)) return 0;
|
|
4779
4822
|
let t = 0;
|
|
4780
4823
|
for (const n of s) {
|
|
4781
4824
|
if (!n) continue;
|
|
4782
4825
|
t++;
|
|
4783
4826
|
const i = n[e];
|
|
4784
|
-
Array.isArray(i) && (t +=
|
|
4827
|
+
Array.isArray(i) && (t += _n(i, e));
|
|
4785
4828
|
}
|
|
4786
4829
|
return t;
|
|
4787
4830
|
}
|
|
4788
|
-
const
|
|
4789
|
-
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 {
|
|
4790
4833
|
name = "tree";
|
|
4791
|
-
|
|
4792
|
-
styles = Cn;
|
|
4834
|
+
styles = Ln;
|
|
4793
4835
|
get defaultConfig() {
|
|
4794
4836
|
return {
|
|
4795
4837
|
childrenField: "children",
|
|
@@ -4813,31 +4855,28 @@ class Un extends x {
|
|
|
4813
4855
|
}
|
|
4814
4856
|
// #endregion
|
|
4815
4857
|
// #region Animation
|
|
4858
|
+
/**
|
|
4859
|
+
* Get expand/collapse animation style from plugin config.
|
|
4860
|
+
* Uses base class isAnimationEnabled to respect grid-level settings.
|
|
4861
|
+
*/
|
|
4816
4862
|
get animationStyle() {
|
|
4817
|
-
|
|
4818
|
-
if (t === !1 || t === "off") return !1;
|
|
4819
|
-
if (t !== !0 && t !== "on") {
|
|
4820
|
-
const n = this.shadowRoot?.host;
|
|
4821
|
-
if (n && getComputedStyle(n).getPropertyValue("--tbw-animation-enabled").trim() === "0")
|
|
4822
|
-
return !1;
|
|
4823
|
-
}
|
|
4824
|
-
return this.config.animation ?? "slide";
|
|
4863
|
+
return this.isAnimationEnabled ? this.config.animation ?? "slide" : !1;
|
|
4825
4864
|
}
|
|
4826
4865
|
// #endregion
|
|
4827
4866
|
// #region Auto-Detection
|
|
4828
4867
|
detect(e) {
|
|
4829
4868
|
if (!this.config.autoDetect) return !1;
|
|
4830
|
-
const t = e, n = this.config.childrenField ??
|
|
4831
|
-
return
|
|
4869
|
+
const t = e, n = this.config.childrenField ?? kn(t) ?? "children";
|
|
4870
|
+
return De(t, n);
|
|
4832
4871
|
}
|
|
4833
4872
|
// #endregion
|
|
4834
4873
|
// #region Data Processing
|
|
4835
4874
|
processRows(e) {
|
|
4836
4875
|
const t = this.config.childrenField ?? "children", n = e;
|
|
4837
|
-
if (!
|
|
4876
|
+
if (!De(n, t))
|
|
4838
4877
|
return this.flattenedRows = [], this.rowKeyMap.clear(), this.previousVisibleKeys.clear(), [...e];
|
|
4839
4878
|
let i = this.withStableKeys(n);
|
|
4840
|
-
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();
|
|
4841
4880
|
const o = /* @__PURE__ */ new Set();
|
|
4842
4881
|
for (const r of this.flattenedRows)
|
|
4843
4882
|
this.rowKeyMap.set(r.key, r), o.add(r.key), !this.previousVisibleKeys.has(r.key) && r.depth > 0 && this.keysToAnimate.add(r.key);
|
|
@@ -4865,15 +4904,15 @@ class Un extends x {
|
|
|
4865
4904
|
flattenTree(e, t, n = 0) {
|
|
4866
4905
|
const i = this.config.childrenField ?? "children", o = [];
|
|
4867
4906
|
for (const r of e) {
|
|
4868
|
-
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);
|
|
4869
4908
|
o.push({
|
|
4870
4909
|
key: a,
|
|
4871
4910
|
data: r,
|
|
4872
4911
|
depth: n,
|
|
4873
4912
|
hasChildren: c,
|
|
4874
|
-
isExpanded:
|
|
4913
|
+
isExpanded: u,
|
|
4875
4914
|
parentKey: n > 0 && a.substring(0, a.lastIndexOf("-")) || null
|
|
4876
|
-
}), c &&
|
|
4915
|
+
}), c && u && o.push(...this.flattenTree(d, t, n + 1));
|
|
4877
4916
|
}
|
|
4878
4917
|
return o;
|
|
4879
4918
|
}
|
|
@@ -4892,40 +4931,52 @@ class Un extends x {
|
|
|
4892
4931
|
if (this.flattenedRows.length === 0) return [...e];
|
|
4893
4932
|
const t = [...e];
|
|
4894
4933
|
if (t.length === 0) return t;
|
|
4895
|
-
const n =
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
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);
|
|
4910
4948
|
} else
|
|
4911
|
-
|
|
4912
|
-
return
|
|
4949
|
+
m.textContent = u != null ? String(u) : "";
|
|
4950
|
+
return b.appendChild(m), b;
|
|
4913
4951
|
};
|
|
4914
|
-
return
|
|
4952
|
+
return t[0] = { ...n, viewRenderer: a }, t;
|
|
4915
4953
|
}
|
|
4916
4954
|
// #endregion
|
|
4917
4955
|
// #region Event Handlers
|
|
4918
4956
|
onCellClick(e) {
|
|
4919
4957
|
const t = e.originalEvent?.target;
|
|
4920
4958
|
if (!t?.classList.contains("tree-toggle")) return !1;
|
|
4921
|
-
const n = t.getAttribute("data-tree-key")
|
|
4922
|
-
|
|
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", {
|
|
4923
4963
|
key: n,
|
|
4924
4964
|
row: i.data,
|
|
4925
4965
|
expanded: this.expandedKeys.has(n),
|
|
4926
4966
|
depth: i.depth
|
|
4927
4967
|
}), this.requestRender(), !0) : !1;
|
|
4928
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
|
+
}
|
|
4929
4980
|
onHeaderClick(e) {
|
|
4930
4981
|
if (this.flattenedRows.length === 0 || !e.column.sortable) return !1;
|
|
4931
4982
|
const { field: t } = e.column;
|
|
@@ -4954,13 +5005,13 @@ class Un extends x {
|
|
|
4954
5005
|
this.expandedKeys.delete(e), this.requestRender();
|
|
4955
5006
|
}
|
|
4956
5007
|
toggle(e) {
|
|
4957
|
-
this.expandedKeys =
|
|
5008
|
+
this.expandedKeys = Q(this.expandedKeys, e), this.requestRender();
|
|
4958
5009
|
}
|
|
4959
5010
|
expandAll() {
|
|
4960
|
-
this.expandedKeys =
|
|
5011
|
+
this.expandedKeys = ne(this.rows, this.config), this.requestRender();
|
|
4961
5012
|
}
|
|
4962
5013
|
collapseAll() {
|
|
4963
|
-
this.expandedKeys =
|
|
5014
|
+
this.expandedKeys = En(), this.requestRender();
|
|
4964
5015
|
}
|
|
4965
5016
|
isExpanded(e) {
|
|
4966
5017
|
return this.expandedKeys.has(e);
|
|
@@ -4975,11 +5026,11 @@ class Un extends x {
|
|
|
4975
5026
|
return this.rowKeyMap.get(e)?.data;
|
|
4976
5027
|
}
|
|
4977
5028
|
expandToKey(e) {
|
|
4978
|
-
this.expandedKeys =
|
|
5029
|
+
this.expandedKeys = Sn(this.rows, e, this.config, this.expandedKeys), this.requestRender();
|
|
4979
5030
|
}
|
|
4980
5031
|
// #endregion
|
|
4981
5032
|
}
|
|
4982
|
-
function
|
|
5033
|
+
function Tn(s, e, t) {
|
|
4983
5034
|
const n = [...s.undoStack, e];
|
|
4984
5035
|
for (; n.length > t; )
|
|
4985
5036
|
n.shift();
|
|
@@ -4989,7 +5040,7 @@ function Rn(s, e, t) {
|
|
|
4989
5040
|
// Clear redo on new action
|
|
4990
5041
|
};
|
|
4991
5042
|
}
|
|
4992
|
-
function
|
|
5043
|
+
function Ke(s) {
|
|
4993
5044
|
if (s.undoStack.length === 0)
|
|
4994
5045
|
return { newState: s, action: null };
|
|
4995
5046
|
const e = [...s.undoStack], t = e.pop();
|
|
@@ -5001,7 +5052,7 @@ function De(s) {
|
|
|
5001
5052
|
action: t
|
|
5002
5053
|
} : { newState: s, action: null };
|
|
5003
5054
|
}
|
|
5004
|
-
function
|
|
5055
|
+
function qe(s) {
|
|
5005
5056
|
if (s.redoStack.length === 0)
|
|
5006
5057
|
return { newState: s, action: null };
|
|
5007
5058
|
const e = [...s.redoStack], t = e.pop();
|
|
@@ -5013,16 +5064,16 @@ function He(s) {
|
|
|
5013
5064
|
action: t
|
|
5014
5065
|
} : { newState: s, action: null };
|
|
5015
5066
|
}
|
|
5016
|
-
function
|
|
5067
|
+
function In(s) {
|
|
5017
5068
|
return s.undoStack.length > 0;
|
|
5018
5069
|
}
|
|
5019
|
-
function
|
|
5070
|
+
function Fn(s) {
|
|
5020
5071
|
return s.redoStack.length > 0;
|
|
5021
5072
|
}
|
|
5022
|
-
function
|
|
5073
|
+
function Mn() {
|
|
5023
5074
|
return { undoStack: [], redoStack: [] };
|
|
5024
5075
|
}
|
|
5025
|
-
function
|
|
5076
|
+
function Pn(s, e, t, n) {
|
|
5026
5077
|
return {
|
|
5027
5078
|
type: "cell-edit",
|
|
5028
5079
|
rowIndex: s,
|
|
@@ -5032,7 +5083,7 @@ function An(s, e, t, n) {
|
|
|
5032
5083
|
timestamp: Date.now()
|
|
5033
5084
|
};
|
|
5034
5085
|
}
|
|
5035
|
-
class
|
|
5086
|
+
class ti extends x {
|
|
5036
5087
|
/**
|
|
5037
5088
|
* Plugin dependencies - UndoRedoPlugin requires EditingPlugin to track edits.
|
|
5038
5089
|
*
|
|
@@ -5042,7 +5093,6 @@ class Zn extends x {
|
|
|
5042
5093
|
{ name: "editing", required: !0, reason: "UndoRedoPlugin tracks cell edit history" }
|
|
5043
5094
|
];
|
|
5044
5095
|
name = "undoRedo";
|
|
5045
|
-
version = "1.0.0";
|
|
5046
5096
|
get defaultConfig() {
|
|
5047
5097
|
return {
|
|
5048
5098
|
maxHistorySize: 100
|
|
@@ -5065,7 +5115,7 @@ class Zn extends x {
|
|
|
5065
5115
|
onKeyDown(e) {
|
|
5066
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);
|
|
5067
5117
|
if (t) {
|
|
5068
|
-
const i =
|
|
5118
|
+
const i = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5069
5119
|
if (i.action) {
|
|
5070
5120
|
const o = this.rows;
|
|
5071
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", {
|
|
@@ -5076,7 +5126,7 @@ class Zn extends x {
|
|
|
5076
5126
|
return !0;
|
|
5077
5127
|
}
|
|
5078
5128
|
if (n) {
|
|
5079
|
-
const i =
|
|
5129
|
+
const i = qe({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5080
5130
|
if (i.action) {
|
|
5081
5131
|
const o = this.rows;
|
|
5082
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", {
|
|
@@ -5099,7 +5149,7 @@ class Zn extends x {
|
|
|
5099
5149
|
* @param newValue - The value after the edit
|
|
5100
5150
|
*/
|
|
5101
5151
|
recordEdit(e, t, n, i) {
|
|
5102
|
-
const o =
|
|
5152
|
+
const o = Pn(e, t, n, i), r = Tn(
|
|
5103
5153
|
{ undoStack: this.undoStack, redoStack: this.redoStack },
|
|
5104
5154
|
o,
|
|
5105
5155
|
this.config.maxHistorySize ?? 100
|
|
@@ -5112,7 +5162,7 @@ class Zn extends x {
|
|
|
5112
5162
|
* @returns The undone action, or null if nothing to undo
|
|
5113
5163
|
*/
|
|
5114
5164
|
undo() {
|
|
5115
|
-
const e =
|
|
5165
|
+
const e = Ke({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5116
5166
|
if (e.action) {
|
|
5117
5167
|
const t = this.rows;
|
|
5118
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();
|
|
@@ -5125,7 +5175,7 @@ class Zn extends x {
|
|
|
5125
5175
|
* @returns The redone action, or null if nothing to redo
|
|
5126
5176
|
*/
|
|
5127
5177
|
redo() {
|
|
5128
|
-
const e =
|
|
5178
|
+
const e = qe({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5129
5179
|
if (e.action) {
|
|
5130
5180
|
const t = this.rows;
|
|
5131
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();
|
|
@@ -5136,19 +5186,19 @@ class Zn extends x {
|
|
|
5136
5186
|
* Check if there are any actions that can be undone.
|
|
5137
5187
|
*/
|
|
5138
5188
|
canUndo() {
|
|
5139
|
-
return
|
|
5189
|
+
return In({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5140
5190
|
}
|
|
5141
5191
|
/**
|
|
5142
5192
|
* Check if there are any actions that can be redone.
|
|
5143
5193
|
*/
|
|
5144
5194
|
canRedo() {
|
|
5145
|
-
return
|
|
5195
|
+
return Fn({ undoStack: this.undoStack, redoStack: this.redoStack });
|
|
5146
5196
|
}
|
|
5147
5197
|
/**
|
|
5148
5198
|
* Clear all undo/redo history.
|
|
5149
5199
|
*/
|
|
5150
5200
|
clearHistory() {
|
|
5151
|
-
const e =
|
|
5201
|
+
const e = Mn();
|
|
5152
5202
|
this.undoStack = e.undoStack, this.redoStack = e.redoStack;
|
|
5153
5203
|
}
|
|
5154
5204
|
/**
|
|
@@ -5165,12 +5215,12 @@ class Zn extends x {
|
|
|
5165
5215
|
}
|
|
5166
5216
|
// #endregion
|
|
5167
5217
|
}
|
|
5168
|
-
const
|
|
5169
|
-
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) {
|
|
5170
5220
|
const e = s.meta ?? {};
|
|
5171
5221
|
return e.lockPosition !== !0 && e.suppressMovable !== !0;
|
|
5172
5222
|
}
|
|
5173
|
-
class
|
|
5223
|
+
class M extends x {
|
|
5174
5224
|
/**
|
|
5175
5225
|
* Plugin dependencies - VisibilityPlugin optionally uses ReorderPlugin for drag-drop reordering.
|
|
5176
5226
|
*
|
|
@@ -5180,9 +5230,9 @@ class P extends x {
|
|
|
5180
5230
|
{ name: "reorder", required: !1, reason: "Enables drag-to-reorder columns in visibility panel" }
|
|
5181
5231
|
];
|
|
5182
5232
|
name = "visibility";
|
|
5183
|
-
version = "1.0.0";
|
|
5184
5233
|
/** Tool panel ID for shell integration */
|
|
5185
5234
|
static PANEL_ID = "columns";
|
|
5235
|
+
styles = Dn;
|
|
5186
5236
|
get defaultConfig() {
|
|
5187
5237
|
return {
|
|
5188
5238
|
allowHideAll: !1
|
|
@@ -5195,6 +5245,12 @@ class P extends x {
|
|
|
5195
5245
|
draggedField = null;
|
|
5196
5246
|
draggedIndex = null;
|
|
5197
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
|
+
}
|
|
5198
5254
|
// #endregion
|
|
5199
5255
|
// #region Lifecycle
|
|
5200
5256
|
detach() {
|
|
@@ -5207,7 +5263,7 @@ class P extends x {
|
|
|
5207
5263
|
*/
|
|
5208
5264
|
getToolPanel() {
|
|
5209
5265
|
return {
|
|
5210
|
-
id:
|
|
5266
|
+
id: M.PANEL_ID,
|
|
5211
5267
|
title: "Columns",
|
|
5212
5268
|
icon: "☰",
|
|
5213
5269
|
tooltip: "Column visibility",
|
|
@@ -5220,9 +5276,10 @@ class P extends x {
|
|
|
5220
5276
|
// #region Public API
|
|
5221
5277
|
/**
|
|
5222
5278
|
* Show the visibility sidebar panel.
|
|
5279
|
+
* Opens the tool panel and ensures this section is expanded.
|
|
5223
5280
|
*/
|
|
5224
5281
|
show() {
|
|
5225
|
-
this.grid.openToolPanel(
|
|
5282
|
+
this.grid.openToolPanel(), this.grid.expandedToolPanelSections.includes(M.PANEL_ID) || this.grid.toggleToolPanelSection(M.PANEL_ID);
|
|
5226
5283
|
}
|
|
5227
5284
|
/**
|
|
5228
5285
|
* Hide the visibility sidebar panel.
|
|
@@ -5231,10 +5288,10 @@ class P extends x {
|
|
|
5231
5288
|
this.grid.closeToolPanel();
|
|
5232
5289
|
}
|
|
5233
5290
|
/**
|
|
5234
|
-
* Toggle the visibility sidebar panel.
|
|
5291
|
+
* Toggle the visibility sidebar panel section.
|
|
5235
5292
|
*/
|
|
5236
5293
|
toggle() {
|
|
5237
|
-
this.grid.
|
|
5294
|
+
this.grid.isToolPanelOpen || this.grid.openToolPanel(), this.grid.toggleToolPanelSection(M.PANEL_ID);
|
|
5238
5295
|
}
|
|
5239
5296
|
/**
|
|
5240
5297
|
* Check if a specific column is visible.
|
|
@@ -5259,14 +5316,14 @@ class P extends x {
|
|
|
5259
5316
|
* @returns Array of visible field names
|
|
5260
5317
|
*/
|
|
5261
5318
|
getVisibleColumns() {
|
|
5262
|
-
return this.grid.getAllColumns().filter((
|
|
5319
|
+
return this.grid.getAllColumns().filter((e) => e.visible).map((e) => e.field);
|
|
5263
5320
|
}
|
|
5264
5321
|
/**
|
|
5265
5322
|
* Get list of all hidden column fields.
|
|
5266
5323
|
* @returns Array of hidden field names
|
|
5267
5324
|
*/
|
|
5268
5325
|
getHiddenColumns() {
|
|
5269
|
-
return this.grid.getAllColumns().filter((
|
|
5326
|
+
return this.grid.getAllColumns().filter((e) => !e.visible).map((e) => e.field);
|
|
5270
5327
|
}
|
|
5271
5328
|
/**
|
|
5272
5329
|
* Show all columns.
|
|
@@ -5289,7 +5346,7 @@ class P extends x {
|
|
|
5289
5346
|
* @param field - The field name of the column to show
|
|
5290
5347
|
*/
|
|
5291
5348
|
showColumn(e) {
|
|
5292
|
-
this.
|
|
5349
|
+
this.setColumnVisible(e, !0);
|
|
5293
5350
|
}
|
|
5294
5351
|
/**
|
|
5295
5352
|
* Hide a specific column.
|
|
@@ -5297,7 +5354,7 @@ class P extends x {
|
|
|
5297
5354
|
* @param field - The field name of the column to hide
|
|
5298
5355
|
*/
|
|
5299
5356
|
hideColumn(e) {
|
|
5300
|
-
this.
|
|
5357
|
+
this.setColumnVisible(e, !1);
|
|
5301
5358
|
}
|
|
5302
5359
|
/**
|
|
5303
5360
|
* Get all columns with their visibility status.
|
|
@@ -5309,10 +5366,10 @@ class P extends x {
|
|
|
5309
5366
|
}
|
|
5310
5367
|
/**
|
|
5311
5368
|
* Check if the sidebar panel is currently open.
|
|
5312
|
-
* @returns True if the panel is
|
|
5369
|
+
* @returns True if the panel section is expanded
|
|
5313
5370
|
*/
|
|
5314
5371
|
isPanelVisible() {
|
|
5315
|
-
return this.grid.
|
|
5372
|
+
return this.grid.isToolPanelOpen && this.grid.expandedToolPanelSections.includes(M.PANEL_ID);
|
|
5316
5373
|
}
|
|
5317
5374
|
// #endregion
|
|
5318
5375
|
// #region Private Methods
|
|
@@ -5321,15 +5378,15 @@ class P extends x {
|
|
|
5321
5378
|
* Returns a cleanup function.
|
|
5322
5379
|
*/
|
|
5323
5380
|
renderPanelContent(e) {
|
|
5324
|
-
const t =
|
|
5325
|
-
|
|
5326
|
-
const
|
|
5327
|
-
|
|
5328
|
-
const
|
|
5329
|
-
return
|
|
5330
|
-
|
|
5331
|
-
}),
|
|
5332
|
-
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();
|
|
5333
5390
|
};
|
|
5334
5391
|
}
|
|
5335
5392
|
/**
|
|
@@ -5344,24 +5401,24 @@ class P extends x {
|
|
|
5344
5401
|
* When a reorder plugin is present, adds drag handles for reordering.
|
|
5345
5402
|
*/
|
|
5346
5403
|
rebuildToggles(e) {
|
|
5347
|
-
const t = this.
|
|
5404
|
+
const t = this.hasReorderPlugin();
|
|
5348
5405
|
e.innerHTML = "";
|
|
5349
|
-
const
|
|
5350
|
-
for (let
|
|
5351
|
-
const
|
|
5352
|
-
|
|
5353
|
-
const
|
|
5354
|
-
|
|
5355
|
-
const
|
|
5356
|
-
|
|
5357
|
-
|
|
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);
|
|
5358
5415
|
});
|
|
5359
|
-
const
|
|
5360
|
-
if (
|
|
5416
|
+
const c = document.createElement("span");
|
|
5417
|
+
if (c.textContent = r, a.appendChild(d), a.appendChild(c), t && Ne(o)) {
|
|
5361
5418
|
const u = document.createElement("span");
|
|
5362
|
-
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);
|
|
5363
5420
|
}
|
|
5364
|
-
|
|
5421
|
+
l.appendChild(a), e.appendChild(l);
|
|
5365
5422
|
}
|
|
5366
5423
|
}
|
|
5367
5424
|
/**
|
|
@@ -5372,9 +5429,7 @@ class P extends x {
|
|
|
5372
5429
|
e.addEventListener("dragstart", (o) => {
|
|
5373
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");
|
|
5374
5431
|
}), e.addEventListener("dragend", () => {
|
|
5375
|
-
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null,
|
|
5376
|
-
o.classList.remove("dragging", "drop-target", "drop-before", "drop-after");
|
|
5377
|
-
});
|
|
5432
|
+
this.isDragging = !1, this.draggedField = null, this.draggedIndex = null, this.dropIndex = null, this.clearDragClasses(i);
|
|
5378
5433
|
}), e.addEventListener("dragover", (o) => {
|
|
5379
5434
|
if (o.preventDefault(), !this.isDragging || this.draggedField === t) return;
|
|
5380
5435
|
const r = e.getBoundingClientRect(), l = r.top + r.height / 2;
|
|
@@ -5402,57 +5457,55 @@ class P extends x {
|
|
|
5402
5457
|
});
|
|
5403
5458
|
}
|
|
5404
5459
|
// #endregion
|
|
5405
|
-
// #region Styles
|
|
5406
|
-
styles = _n;
|
|
5407
|
-
// #endregion
|
|
5408
5460
|
}
|
|
5409
5461
|
export {
|
|
5410
5462
|
x as BaseGridPlugin,
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
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,
|
|
5420
5472
|
U as FOCUSABLE_EDITOR_SELECTOR,
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
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
|
|
5457
5510
|
};
|
|
5458
5511
|
//# sourceMappingURL=all.js.map
|