wandertable 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +505 -0
- package/dist/style.css +1 -0
- package/dist/types/WanderTable.d.ts +112 -0
- package/dist/types/WanderTable.d.ts.map +1 -0
- package/dist/types/__tests__/ColumnModel.test.d.ts +2 -0
- package/dist/types/__tests__/ColumnModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/CommandBus.test.d.ts +2 -0
- package/dist/types/__tests__/CommandBus.test.d.ts.map +1 -0
- package/dist/types/__tests__/DataModel.test.d.ts +2 -0
- package/dist/types/__tests__/DataModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/Export.test.d.ts +2 -0
- package/dist/types/__tests__/Export.test.d.ts.map +1 -0
- package/dist/types/__tests__/GroupedHeaders.test.d.ts +2 -0
- package/dist/types/__tests__/GroupedHeaders.test.d.ts.map +1 -0
- package/dist/types/__tests__/MergeModel.test.d.ts +2 -0
- package/dist/types/__tests__/MergeModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/SelectionModel.test.d.ts +2 -0
- package/dist/types/__tests__/SelectionModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/ViewMapping.test.d.ts +2 -0
- package/dist/types/__tests__/ViewMapping.test.d.ts.map +1 -0
- package/dist/types/columns/ColumnModel.d.ts +25 -0
- package/dist/types/columns/ColumnModel.d.ts.map +1 -0
- package/dist/types/columns/GroupedHeaders.d.ts +20 -0
- package/dist/types/columns/GroupedHeaders.d.ts.map +1 -0
- package/dist/types/core/CommandBus.d.ts +63 -0
- package/dist/types/core/CommandBus.d.ts.map +1 -0
- package/dist/types/core/DataModel.d.ts +27 -0
- package/dist/types/core/DataModel.d.ts.map +1 -0
- package/dist/types/core/EventEmitter.d.ts +10 -0
- package/dist/types/core/EventEmitter.d.ts.map +1 -0
- package/dist/types/core/MergeModel.d.ts +35 -0
- package/dist/types/core/MergeModel.d.ts.map +1 -0
- package/dist/types/core/PaginationModel.d.ts +24 -0
- package/dist/types/core/PaginationModel.d.ts.map +1 -0
- package/dist/types/core/RowGroupModel.d.ts +36 -0
- package/dist/types/core/RowGroupModel.d.ts.map +1 -0
- package/dist/types/core/SelectionModel.d.ts +47 -0
- package/dist/types/core/SelectionModel.d.ts.map +1 -0
- package/dist/types/core/ViewMapping.d.ts +37 -0
- package/dist/types/core/ViewMapping.d.ts.map +1 -0
- package/dist/types/core/ViewportModel.d.ts +9 -0
- package/dist/types/core/ViewportModel.d.ts.map +1 -0
- package/dist/types/editors/BlankEditor.d.ts +20 -0
- package/dist/types/editors/BlankEditor.d.ts.map +1 -0
- package/dist/types/editors/DropdownEditor.d.ts +23 -0
- package/dist/types/editors/DropdownEditor.d.ts.map +1 -0
- package/dist/types/editors/EditorManager.d.ts +22 -0
- package/dist/types/editors/EditorManager.d.ts.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interaction/ClipboardManager.d.ts +19 -0
- package/dist/types/interaction/ClipboardManager.d.ts.map +1 -0
- package/dist/types/interaction/ColumnReorder.d.ts +20 -0
- package/dist/types/interaction/ColumnReorder.d.ts.map +1 -0
- package/dist/types/interaction/ColumnResize.d.ts +15 -0
- package/dist/types/interaction/ColumnResize.d.ts.map +1 -0
- package/dist/types/interaction/FillHandle.d.ts +39 -0
- package/dist/types/interaction/FillHandle.d.ts.map +1 -0
- package/dist/types/interaction/KeyboardNav.d.ts +19 -0
- package/dist/types/interaction/KeyboardNav.d.ts.map +1 -0
- package/dist/types/interaction/RowResize.d.ts +15 -0
- package/dist/types/interaction/RowResize.d.ts.map +1 -0
- package/dist/types/plugins/ContextMenu.d.ts +44 -0
- package/dist/types/plugins/ContextMenu.d.ts.map +1 -0
- package/dist/types/plugins/Export.d.ts +16 -0
- package/dist/types/plugins/Export.d.ts.map +1 -0
- package/dist/types/render/AutoFit.d.ts +23 -0
- package/dist/types/render/AutoFit.d.ts.map +1 -0
- package/dist/types/render/DOMRenderer.d.ts +91 -0
- package/dist/types/render/DOMRenderer.d.ts.map +1 -0
- package/dist/types/render/LoadingOverlay.d.ts +9 -0
- package/dist/types/render/LoadingOverlay.d.ts.map +1 -0
- package/dist/types/render/PaginationBar.d.ts +20 -0
- package/dist/types/render/PaginationBar.d.ts.map +1 -0
- package/dist/types/renderers/BadgeRenderer.d.ts +5 -0
- package/dist/types/renderers/BadgeRenderer.d.ts.map +1 -0
- package/dist/types/renderers/BlankRenderer.d.ts +9 -0
- package/dist/types/renderers/BlankRenderer.d.ts.map +1 -0
- package/dist/types/renderers/CheckboxRenderer.d.ts +5 -0
- package/dist/types/renderers/CheckboxRenderer.d.ts.map +1 -0
- package/dist/types/renderers/NumberRenderer.d.ts +7 -0
- package/dist/types/renderers/NumberRenderer.d.ts.map +1 -0
- package/dist/types/renderers/ProgressRenderer.d.ts +5 -0
- package/dist/types/renderers/ProgressRenderer.d.ts.map +1 -0
- package/dist/types/renderers/RendererRegistry.d.ts +10 -0
- package/dist/types/renderers/RendererRegistry.d.ts.map +1 -0
- package/dist/types/renderers/TextRenderer.d.ts +5 -0
- package/dist/types/renderers/TextRenderer.d.ts.map +1 -0
- package/dist/types/rows/RowModel.d.ts +20 -0
- package/dist/types/rows/RowModel.d.ts.map +1 -0
- package/dist/types/themes.d.ts +5 -0
- package/dist/types/themes.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +348 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/wandertable.cjs +14 -0
- package/dist/wandertable.cjs.map +1 -0
- package/dist/wandertable.global.js +14 -0
- package/dist/wandertable.global.js.map +1 -0
- package/dist/wandertable.js +2757 -0
- package/dist/wandertable.js.map +1 -0
- package/dist/wandertable.umd.js +14 -0
- package/dist/wandertable.umd.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,2757 @@
|
|
|
1
|
+
var Y = Object.defineProperty;
|
|
2
|
+
var G = (u, e, t) => e in u ? Y(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
|
|
3
|
+
var n = (u, e, t) => G(u, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
const K = {
|
|
5
|
+
bgColor: "#ffffff",
|
|
6
|
+
cellBgColor: "#ffffff",
|
|
7
|
+
cellTextColor: "#1e293b",
|
|
8
|
+
headerBgColor: "#f8fafc",
|
|
9
|
+
headerTextColor: "#475569",
|
|
10
|
+
gridLineColor: "#e2e8f0",
|
|
11
|
+
selectionBgColor: "rgba(59, 130, 246, 0.08)",
|
|
12
|
+
selectionBorderColor: "#3b82f6",
|
|
13
|
+
focusBorderColor: "#3b82f6",
|
|
14
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
15
|
+
fontSize: 13,
|
|
16
|
+
headerFontSize: 12,
|
|
17
|
+
cellPadding: 8,
|
|
18
|
+
headerHeight: 28,
|
|
19
|
+
rowHeaderWidth: 50
|
|
20
|
+
};
|
|
21
|
+
class j {
|
|
22
|
+
constructor(e, t) {
|
|
23
|
+
n(this, "cells", /* @__PURE__ */ new Map());
|
|
24
|
+
n(this, "_rowCount");
|
|
25
|
+
n(this, "_colCount");
|
|
26
|
+
n(this, "_inTransaction", !1);
|
|
27
|
+
n(this, "_dirtyKeys", /* @__PURE__ */ new Set());
|
|
28
|
+
// Callback set by WanderTable to trigger re-render
|
|
29
|
+
n(this, "onChange", null);
|
|
30
|
+
this._rowCount = e, this._colCount = t;
|
|
31
|
+
}
|
|
32
|
+
get rowCount() {
|
|
33
|
+
return this._rowCount;
|
|
34
|
+
}
|
|
35
|
+
set rowCount(e) {
|
|
36
|
+
this._rowCount = e;
|
|
37
|
+
}
|
|
38
|
+
get colCount() {
|
|
39
|
+
return this._colCount;
|
|
40
|
+
}
|
|
41
|
+
set colCount(e) {
|
|
42
|
+
this._colCount = e;
|
|
43
|
+
}
|
|
44
|
+
key(e, t) {
|
|
45
|
+
return `${e}:${t}`;
|
|
46
|
+
}
|
|
47
|
+
getCell(e, t) {
|
|
48
|
+
return this.cells.get(this.key(e, t));
|
|
49
|
+
}
|
|
50
|
+
setCell(e, t, s) {
|
|
51
|
+
const i = this.key(e, t);
|
|
52
|
+
this.cells.set(i, s), this.markDirty(i);
|
|
53
|
+
}
|
|
54
|
+
setCellValue(e, t, s) {
|
|
55
|
+
const i = this.key(e, t), o = this.cells.get(i);
|
|
56
|
+
o ? o.value = s : this.cells.set(i, { value: s }), this.markDirty(i);
|
|
57
|
+
}
|
|
58
|
+
deleteCell(e, t) {
|
|
59
|
+
const s = this.key(e, t);
|
|
60
|
+
this.cells.delete(s), this.markDirty(s);
|
|
61
|
+
}
|
|
62
|
+
hasCell(e, t) {
|
|
63
|
+
return this.cells.has(this.key(e, t));
|
|
64
|
+
}
|
|
65
|
+
applyPatch(e) {
|
|
66
|
+
this.transaction(() => {
|
|
67
|
+
for (const t of e) {
|
|
68
|
+
const s = this.key(t.row, t.col), i = this.cells.get(s);
|
|
69
|
+
i ? Object.assign(i, t.data) : this.cells.set(s, { value: void 0, ...t.data }), this._dirtyKeys.add(s);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
transaction(e) {
|
|
74
|
+
var t;
|
|
75
|
+
if (this._inTransaction) {
|
|
76
|
+
e();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this._inTransaction = !0, this._dirtyKeys.clear();
|
|
80
|
+
try {
|
|
81
|
+
e();
|
|
82
|
+
} finally {
|
|
83
|
+
this._inTransaction = !1, this._dirtyKeys.size > 0 && ((t = this.onChange) == null || t.call(this, new Set(this._dirtyKeys)), this._dirtyKeys.clear());
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
markDirty(e) {
|
|
87
|
+
var t;
|
|
88
|
+
this._inTransaction ? this._dirtyKeys.add(e) : (t = this.onChange) == null || t.call(this, /* @__PURE__ */ new Set([e]));
|
|
89
|
+
}
|
|
90
|
+
clear() {
|
|
91
|
+
var e;
|
|
92
|
+
this.cells.clear(), (e = this.onChange) == null || e.call(this, /* @__PURE__ */ new Set());
|
|
93
|
+
}
|
|
94
|
+
/** Iterate all cells that have data */
|
|
95
|
+
forEach(e) {
|
|
96
|
+
for (const [t, s] of this.cells) {
|
|
97
|
+
const [i, o] = t.split(":").map(Number);
|
|
98
|
+
e(i, o, s);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
class q {
|
|
103
|
+
constructor() {
|
|
104
|
+
n(this, "listeners", /* @__PURE__ */ new Map());
|
|
105
|
+
}
|
|
106
|
+
on(e, t) {
|
|
107
|
+
return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), () => this.off(e, t);
|
|
108
|
+
}
|
|
109
|
+
off(e, t) {
|
|
110
|
+
var s;
|
|
111
|
+
(s = this.listeners.get(e)) == null || s.delete(t);
|
|
112
|
+
}
|
|
113
|
+
emit(e, t) {
|
|
114
|
+
var s;
|
|
115
|
+
(s = this.listeners.get(e)) == null || s.forEach((i) => {
|
|
116
|
+
try {
|
|
117
|
+
i(t);
|
|
118
|
+
} catch (o) {
|
|
119
|
+
console.error(`[WanderTable] Error in "${String(e)}" handler:`, o);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
removeAllListeners() {
|
|
124
|
+
this.listeners.clear();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
class J {
|
|
128
|
+
constructor(e, t) {
|
|
129
|
+
n(this, "_focus", null);
|
|
130
|
+
n(this, "_ranges", []);
|
|
131
|
+
n(this, "_rowCount");
|
|
132
|
+
n(this, "_colCount");
|
|
133
|
+
n(this, "onChange", null);
|
|
134
|
+
/** When true, navigation beyond bounds is allowed (grid will expand) */
|
|
135
|
+
n(this, "infinite", !1);
|
|
136
|
+
this._rowCount = e, this._colCount = t;
|
|
137
|
+
}
|
|
138
|
+
get focus() {
|
|
139
|
+
return this._focus;
|
|
140
|
+
}
|
|
141
|
+
get ranges() {
|
|
142
|
+
return this._ranges;
|
|
143
|
+
}
|
|
144
|
+
setDimensions(e, t) {
|
|
145
|
+
this._rowCount = e, this._colCount = t;
|
|
146
|
+
}
|
|
147
|
+
/** Set focus and single selection */
|
|
148
|
+
focusCell(e, t) {
|
|
149
|
+
var s;
|
|
150
|
+
e = this.clampRow(e), t = this.clampCol(t), this._focus = { row: e, col: t }, this._ranges = [{ startRow: e, startCol: t, endRow: e, endCol: t }], (s = this.onChange) == null || s.call(this);
|
|
151
|
+
}
|
|
152
|
+
/** Extend selection from focus to target */
|
|
153
|
+
extendTo(e, t) {
|
|
154
|
+
var s;
|
|
155
|
+
this._focus && (e = this.clampRow(e), t = this.clampCol(t), this._ranges = [{
|
|
156
|
+
startRow: this._focus.row,
|
|
157
|
+
startCol: this._focus.col,
|
|
158
|
+
endRow: e,
|
|
159
|
+
endCol: t
|
|
160
|
+
}], (s = this.onChange) == null || s.call(this));
|
|
161
|
+
}
|
|
162
|
+
/** Add a new range (Ctrl+Click) */
|
|
163
|
+
addRange(e) {
|
|
164
|
+
var t;
|
|
165
|
+
this._ranges.push(e), this._focus = { row: e.startRow, col: e.startCol }, (t = this.onChange) == null || t.call(this);
|
|
166
|
+
}
|
|
167
|
+
/** Select entire column */
|
|
168
|
+
selectColumn(e) {
|
|
169
|
+
var t;
|
|
170
|
+
this._focus = { row: 0, col: e }, this._ranges = [{
|
|
171
|
+
startRow: 0,
|
|
172
|
+
startCol: e,
|
|
173
|
+
endRow: 1 / 0,
|
|
174
|
+
endCol: e
|
|
175
|
+
}], (t = this.onChange) == null || t.call(this);
|
|
176
|
+
}
|
|
177
|
+
/** Select entire row */
|
|
178
|
+
selectRow(e) {
|
|
179
|
+
var t;
|
|
180
|
+
this._focus = { row: e, col: 0 }, this._ranges = [{
|
|
181
|
+
startRow: e,
|
|
182
|
+
startCol: 0,
|
|
183
|
+
endRow: e,
|
|
184
|
+
endCol: 1 / 0
|
|
185
|
+
}], (t = this.onChange) == null || t.call(this);
|
|
186
|
+
}
|
|
187
|
+
/** Select all */
|
|
188
|
+
selectAll() {
|
|
189
|
+
var e;
|
|
190
|
+
this._focus = { row: 0, col: 0 }, this._ranges = [{
|
|
191
|
+
startRow: 0,
|
|
192
|
+
startCol: 0,
|
|
193
|
+
endRow: 1 / 0,
|
|
194
|
+
endCol: 1 / 0
|
|
195
|
+
}], (e = this.onChange) == null || e.call(this);
|
|
196
|
+
}
|
|
197
|
+
/** Check if a cell is within any selected range */
|
|
198
|
+
isSelected(e, t) {
|
|
199
|
+
return this._ranges.some((s) => this.inRange(e, t, s));
|
|
200
|
+
}
|
|
201
|
+
isFocused(e, t) {
|
|
202
|
+
var s, i;
|
|
203
|
+
return ((s = this._focus) == null ? void 0 : s.row) === e && ((i = this._focus) == null ? void 0 : i.col) === t;
|
|
204
|
+
}
|
|
205
|
+
/** Iterate all selected cells (clamped to actual dimensions) */
|
|
206
|
+
forEachSelected(e) {
|
|
207
|
+
for (const t of this._ranges) {
|
|
208
|
+
const s = Math.min(t.startRow, t.endRow), i = Math.min(Math.max(t.startRow, t.endRow), this._rowCount - 1), o = Math.min(t.startCol, t.endCol), l = Math.min(Math.max(t.startCol, t.endCol), this._colCount - 1);
|
|
209
|
+
for (let r = s; r <= i; r++)
|
|
210
|
+
for (let c = o; c <= l; c++)
|
|
211
|
+
e(r, c);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/** Get the bounding box of the current selection (clamped to actual dimensions) */
|
|
215
|
+
getBounds() {
|
|
216
|
+
if (this._ranges.length === 0) return null;
|
|
217
|
+
let e = 1 / 0, t = 1 / 0, s = -1 / 0, i = -1 / 0;
|
|
218
|
+
for (const o of this._ranges)
|
|
219
|
+
e = Math.min(e, o.startRow, o.endRow), t = Math.min(t, o.startCol, o.endCol), s = Math.max(s, o.startRow, o.endRow), i = Math.max(i, o.startCol, o.endCol);
|
|
220
|
+
return s = Math.min(s, this._rowCount - 1), i = Math.min(i, this._colCount - 1), { r1: e, c1: t, r2: s, c2: i };
|
|
221
|
+
}
|
|
222
|
+
/** Get rich selection info */
|
|
223
|
+
getInfo() {
|
|
224
|
+
const e = this.getBounds();
|
|
225
|
+
let t = 0;
|
|
226
|
+
this.forEachSelected(() => {
|
|
227
|
+
t++;
|
|
228
|
+
});
|
|
229
|
+
const s = (e == null ? void 0 : e.r1) ?? 0, i = (e == null ? void 0 : e.c1) ?? 0, o = (e == null ? void 0 : e.r2) ?? 0, l = (e == null ? void 0 : e.c2) ?? 0, r = this._ranges.some((a) => a.endRow === 1 / 0 || a.startRow === 1 / 0), c = this._ranges.some((a) => a.endCol === 1 / 0 || a.startCol === 1 / 0), h = e !== null && (c || i === 0 && l === this._colCount - 1), d = e !== null && (r || s === 0 && o === this._rowCount - 1);
|
|
230
|
+
return {
|
|
231
|
+
focus: this._focus ? { ...this._focus } : null,
|
|
232
|
+
ranges: this._ranges.map((a) => ({ ...a })),
|
|
233
|
+
bounds: e ? { startRow: s, startCol: i, endRow: o, endCol: l } : null,
|
|
234
|
+
cellCount: t,
|
|
235
|
+
rangeCount: this._ranges.length,
|
|
236
|
+
isMultiCell: t > 1,
|
|
237
|
+
isFullRow: h,
|
|
238
|
+
isFullCol: d,
|
|
239
|
+
isAll: h && d,
|
|
240
|
+
isEmpty: this._ranges.length === 0,
|
|
241
|
+
rowSpan: e ? o - s + 1 : 0,
|
|
242
|
+
colSpan: e ? l - i + 1 : 0
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
clear() {
|
|
246
|
+
var e;
|
|
247
|
+
this._focus = null, this._ranges = [], (e = this.onChange) == null || e.call(this);
|
|
248
|
+
}
|
|
249
|
+
/** Move focus in a direction */
|
|
250
|
+
move(e, t, s) {
|
|
251
|
+
if (!this._focus) {
|
|
252
|
+
this.focusCell(0, 0);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const i = this.clampRow(this._focus.row + e), o = this.clampCol(this._focus.col + t);
|
|
256
|
+
s ? this.extendTo(i, o) : this.focusCell(i, o);
|
|
257
|
+
}
|
|
258
|
+
inRange(e, t, s) {
|
|
259
|
+
const i = Math.min(s.startRow, s.endRow), o = Math.max(s.startRow, s.endRow), l = Math.min(s.startCol, s.endCol), r = Math.max(s.startCol, s.endCol);
|
|
260
|
+
return e >= i && e <= o && t >= l && t <= r;
|
|
261
|
+
}
|
|
262
|
+
clampRow(e) {
|
|
263
|
+
return this.infinite ? Math.max(0, e) : Math.max(0, Math.min(this._rowCount - 1, e));
|
|
264
|
+
}
|
|
265
|
+
clampCol(e) {
|
|
266
|
+
return this.infinite ? Math.max(0, e) : Math.max(0, Math.min(this._colCount - 1, e));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
class Z {
|
|
270
|
+
constructor(e = 100) {
|
|
271
|
+
n(this, "undoStack", []);
|
|
272
|
+
n(this, "redoStack", []);
|
|
273
|
+
n(this, "limit");
|
|
274
|
+
n(this, "onChange", null);
|
|
275
|
+
this.limit = e;
|
|
276
|
+
}
|
|
277
|
+
execute(e) {
|
|
278
|
+
var t;
|
|
279
|
+
e.execute(), this.undoStack.push(e), this.undoStack.length > this.limit && this.undoStack.shift(), this.redoStack.length = 0, (t = this.onChange) == null || t.call(this);
|
|
280
|
+
}
|
|
281
|
+
undo() {
|
|
282
|
+
var t;
|
|
283
|
+
const e = this.undoStack.pop();
|
|
284
|
+
return e ? (e.undo(), this.redoStack.push(e), (t = this.onChange) == null || t.call(this), e) : null;
|
|
285
|
+
}
|
|
286
|
+
redo() {
|
|
287
|
+
var t;
|
|
288
|
+
const e = this.redoStack.pop();
|
|
289
|
+
return e ? (e.execute(), this.undoStack.push(e), (t = this.onChange) == null || t.call(this), e) : null;
|
|
290
|
+
}
|
|
291
|
+
get canUndo() {
|
|
292
|
+
return this.undoStack.length > 0;
|
|
293
|
+
}
|
|
294
|
+
get canRedo() {
|
|
295
|
+
return this.redoStack.length > 0;
|
|
296
|
+
}
|
|
297
|
+
clear() {
|
|
298
|
+
this.undoStack.length = 0, this.redoStack.length = 0;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
class $ {
|
|
302
|
+
constructor(e, t, s, i) {
|
|
303
|
+
n(this, "oldValue");
|
|
304
|
+
var o;
|
|
305
|
+
this.data = e, this.row = t, this.col = s, this.newValue = i, this.oldValue = (o = e.getCell(t, s)) == null ? void 0 : o.value;
|
|
306
|
+
}
|
|
307
|
+
execute() {
|
|
308
|
+
this.data.setCellValue(this.row, this.col, this.newValue);
|
|
309
|
+
}
|
|
310
|
+
undo() {
|
|
311
|
+
this.oldValue === void 0 ? this.data.deleteCell(this.row, this.col) : this.data.setCellValue(this.row, this.col, this.oldValue);
|
|
312
|
+
}
|
|
313
|
+
getChanges() {
|
|
314
|
+
return [{ row: this.row, col: this.col, oldValue: this.oldValue, newValue: this.newValue }];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
class F {
|
|
318
|
+
constructor(e, t) {
|
|
319
|
+
n(this, "snapshots");
|
|
320
|
+
this.data = e, this.patches = t, this.snapshots = t.map((s) => ({
|
|
321
|
+
row: s.row,
|
|
322
|
+
col: s.col,
|
|
323
|
+
old: e.getCell(s.row, s.col) ? { ...e.getCell(s.row, s.col) } : void 0
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
execute() {
|
|
327
|
+
this.data.applyPatch(this.patches);
|
|
328
|
+
}
|
|
329
|
+
undo() {
|
|
330
|
+
this.data.transaction(() => {
|
|
331
|
+
for (const e of this.snapshots)
|
|
332
|
+
e.old === void 0 ? this.data.deleteCell(e.row, e.col) : this.data.setCell(e.row, e.col, e.old);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
getChanges() {
|
|
336
|
+
return this.snapshots.map((e, t) => {
|
|
337
|
+
var s, i, o;
|
|
338
|
+
return {
|
|
339
|
+
row: e.row,
|
|
340
|
+
col: e.col,
|
|
341
|
+
oldValue: (s = e.old) == null ? void 0 : s.value,
|
|
342
|
+
newValue: (o = (i = this.patches[t]) == null ? void 0 : i.data) == null ? void 0 : o.value
|
|
343
|
+
};
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
class Q {
|
|
348
|
+
constructor(e, t) {
|
|
349
|
+
n(this, "snapshots", []);
|
|
350
|
+
this.data = e, this.cells = t;
|
|
351
|
+
for (const { row: s, col: i } of t) {
|
|
352
|
+
const o = e.getCell(s, i);
|
|
353
|
+
o && this.snapshots.push({ row: s, col: i, old: { ...o } });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
execute() {
|
|
357
|
+
this.data.transaction(() => {
|
|
358
|
+
for (const { row: e, col: t } of this.cells)
|
|
359
|
+
this.data.deleteCell(e, t);
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
undo() {
|
|
363
|
+
this.data.transaction(() => {
|
|
364
|
+
for (const e of this.snapshots)
|
|
365
|
+
this.data.setCell(e.row, e.col, e.old);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
getChanges() {
|
|
369
|
+
return this.snapshots.map((e) => ({
|
|
370
|
+
row: e.row,
|
|
371
|
+
col: e.col,
|
|
372
|
+
oldValue: e.old.value,
|
|
373
|
+
newValue: void 0
|
|
374
|
+
}));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
class P {
|
|
378
|
+
constructor(e, t, s) {
|
|
379
|
+
n(this, "configs");
|
|
380
|
+
n(this, "widths");
|
|
381
|
+
n(this, "prefixSums");
|
|
382
|
+
n(this, "defaultWidth");
|
|
383
|
+
var i;
|
|
384
|
+
this.defaultWidth = t, this.configs = s ?? [], this.widths = new Array(e);
|
|
385
|
+
for (let o = 0; o < e; o++)
|
|
386
|
+
this.widths[o] = ((i = this.configs[o]) == null ? void 0 : i.width) ?? t;
|
|
387
|
+
this.prefixSums = this.buildPrefixSums();
|
|
388
|
+
}
|
|
389
|
+
buildPrefixSums() {
|
|
390
|
+
const e = new Array(this.widths.length + 1);
|
|
391
|
+
e[0] = 0;
|
|
392
|
+
for (let t = 0; t < this.widths.length; t++)
|
|
393
|
+
e[t + 1] = e[t] + this.widths[t];
|
|
394
|
+
return e;
|
|
395
|
+
}
|
|
396
|
+
get count() {
|
|
397
|
+
return this.widths.length;
|
|
398
|
+
}
|
|
399
|
+
getWidth(e) {
|
|
400
|
+
return this.widths[e] ?? this.defaultWidth;
|
|
401
|
+
}
|
|
402
|
+
setWidth(e, t) {
|
|
403
|
+
const s = this.configs[e], i = (s == null ? void 0 : s.minWidth) ?? 30, o = (s == null ? void 0 : s.maxWidth) ?? 1 / 0;
|
|
404
|
+
this.widths[e] = Math.max(i, Math.min(o, t)), this.prefixSums = this.buildPrefixSums();
|
|
405
|
+
}
|
|
406
|
+
getX(e) {
|
|
407
|
+
return this.prefixSums[e] ?? 0;
|
|
408
|
+
}
|
|
409
|
+
getTotalWidth() {
|
|
410
|
+
return this.prefixSums[this.widths.length] ?? 0;
|
|
411
|
+
}
|
|
412
|
+
getConfig(e) {
|
|
413
|
+
return this.configs[e];
|
|
414
|
+
}
|
|
415
|
+
setCount(e) {
|
|
416
|
+
for (; this.widths.length < e; )
|
|
417
|
+
this.widths.push(this.defaultWidth);
|
|
418
|
+
this.widths.length = e, this.prefixSums = this.buildPrefixSums();
|
|
419
|
+
}
|
|
420
|
+
/** Find column at pixel X using binary search */
|
|
421
|
+
getColAtX(e) {
|
|
422
|
+
let t = 0, s = this.widths.length - 1;
|
|
423
|
+
for (; t <= s; ) {
|
|
424
|
+
const i = t + s >>> 1;
|
|
425
|
+
if (this.prefixSums[i + 1] <= e)
|
|
426
|
+
t = i + 1;
|
|
427
|
+
else if (this.prefixSums[i] > e)
|
|
428
|
+
s = i - 1;
|
|
429
|
+
else
|
|
430
|
+
return i;
|
|
431
|
+
}
|
|
432
|
+
return Math.max(0, Math.min(t, this.widths.length - 1));
|
|
433
|
+
}
|
|
434
|
+
static columnLabel(e) {
|
|
435
|
+
return z(e);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function z(u) {
|
|
439
|
+
let e = "", t = u;
|
|
440
|
+
for (; t >= 0; )
|
|
441
|
+
e = String.fromCharCode(65 + t % 26) + e, t = Math.floor(t / 26) - 1;
|
|
442
|
+
return e;
|
|
443
|
+
}
|
|
444
|
+
class tt {
|
|
445
|
+
constructor(e, t) {
|
|
446
|
+
n(this, "heights");
|
|
447
|
+
n(this, "prefixSums");
|
|
448
|
+
n(this, "defaultHeight");
|
|
449
|
+
n(this, "configs", /* @__PURE__ */ new Map());
|
|
450
|
+
this.defaultHeight = t, this.heights = new Array(e).fill(t), this.prefixSums = this.buildPrefixSums();
|
|
451
|
+
}
|
|
452
|
+
buildPrefixSums() {
|
|
453
|
+
const e = new Array(this.heights.length + 1);
|
|
454
|
+
e[0] = 0;
|
|
455
|
+
for (let t = 0; t < this.heights.length; t++)
|
|
456
|
+
e[t + 1] = e[t] + this.heights[t];
|
|
457
|
+
return e;
|
|
458
|
+
}
|
|
459
|
+
get count() {
|
|
460
|
+
return this.heights.length;
|
|
461
|
+
}
|
|
462
|
+
getHeight(e) {
|
|
463
|
+
return this.heights[e] ?? this.defaultHeight;
|
|
464
|
+
}
|
|
465
|
+
setHeight(e, t) {
|
|
466
|
+
this.heights[e] = Math.max(20, t), this.prefixSums = this.buildPrefixSums();
|
|
467
|
+
}
|
|
468
|
+
getY(e) {
|
|
469
|
+
return this.prefixSums[e] ?? 0;
|
|
470
|
+
}
|
|
471
|
+
getTotalHeight() {
|
|
472
|
+
return this.prefixSums[this.heights.length] ?? 0;
|
|
473
|
+
}
|
|
474
|
+
getConfig(e) {
|
|
475
|
+
return this.configs.get(e);
|
|
476
|
+
}
|
|
477
|
+
setConfig(e, t) {
|
|
478
|
+
this.configs.set(e, t), t.height != null && this.setHeight(e, t.height);
|
|
479
|
+
}
|
|
480
|
+
setCount(e) {
|
|
481
|
+
for (; this.heights.length < e; )
|
|
482
|
+
this.heights.push(this.defaultHeight);
|
|
483
|
+
this.heights.length = e, this.prefixSums = this.buildPrefixSums();
|
|
484
|
+
}
|
|
485
|
+
/** Find row at pixel Y using binary search */
|
|
486
|
+
getRowAtY(e) {
|
|
487
|
+
let t = 0, s = this.heights.length - 1;
|
|
488
|
+
for (; t <= s; ) {
|
|
489
|
+
const i = t + s >>> 1;
|
|
490
|
+
if (this.prefixSums[i + 1] <= e)
|
|
491
|
+
t = i + 1;
|
|
492
|
+
else if (this.prefixSums[i] > e)
|
|
493
|
+
s = i - 1;
|
|
494
|
+
else
|
|
495
|
+
return i;
|
|
496
|
+
}
|
|
497
|
+
return Math.max(0, Math.min(t, this.heights.length - 1));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
class et {
|
|
501
|
+
constructor(e) {
|
|
502
|
+
n(this, "container");
|
|
503
|
+
n(this, "scrollContainer");
|
|
504
|
+
n(this, "scrollSentinel");
|
|
505
|
+
n(this, "viewportEl");
|
|
506
|
+
n(this, "colHeaderEl");
|
|
507
|
+
n(this, "rowHeaderEl");
|
|
508
|
+
n(this, "cornerEl");
|
|
509
|
+
n(this, "rowPool", []);
|
|
510
|
+
n(this, "activeRows", /* @__PURE__ */ new Map());
|
|
511
|
+
n(this, "viewport", { startRow: 0, endRow: 0, startCol: 0, endCol: 0, scrollX: 0, scrollY: 0 });
|
|
512
|
+
n(this, "ctx");
|
|
513
|
+
n(this, "rafId", 0);
|
|
514
|
+
n(this, "needsRender", !1);
|
|
515
|
+
n(this, "onScroll", null);
|
|
516
|
+
n(this, "onCellClick", null);
|
|
517
|
+
n(this, "onCellDblClick", null);
|
|
518
|
+
n(this, "onCellContextMenu", null);
|
|
519
|
+
n(this, "onHeaderClick", null);
|
|
520
|
+
n(this, "onColumnResizeStart", null);
|
|
521
|
+
n(this, "onHeaderContextMenu", null);
|
|
522
|
+
// ── Event handlers ──
|
|
523
|
+
n(this, "handleScroll", () => {
|
|
524
|
+
this.scheduleRender();
|
|
525
|
+
});
|
|
526
|
+
n(this, "handleMouseDown", (e) => {
|
|
527
|
+
var s;
|
|
528
|
+
const t = this.getCellFromEvent(e);
|
|
529
|
+
t && ((s = this.onCellClick) == null || s.call(this, t.row, t.col, e));
|
|
530
|
+
});
|
|
531
|
+
n(this, "handleDblClick", (e) => {
|
|
532
|
+
var s;
|
|
533
|
+
const t = this.getCellFromEvent(e);
|
|
534
|
+
t && ((s = this.onCellDblClick) == null || s.call(this, t.row, t.col, e));
|
|
535
|
+
});
|
|
536
|
+
n(this, "handleContextMenu", (e) => {
|
|
537
|
+
var s;
|
|
538
|
+
const t = this.getCellFromEvent(e);
|
|
539
|
+
t && ((s = this.onCellContextMenu) == null || s.call(this, t.row, t.col, e));
|
|
540
|
+
});
|
|
541
|
+
n(this, "handleColHeaderMouse", (e) => {
|
|
542
|
+
var o, l;
|
|
543
|
+
const t = e.target.closest(".wt-col-header-cell");
|
|
544
|
+
if (!t) return;
|
|
545
|
+
const s = parseInt(t.dataset.col ?? "", 10);
|
|
546
|
+
if (isNaN(s)) return;
|
|
547
|
+
const i = t.getBoundingClientRect();
|
|
548
|
+
if (e.clientX > i.right - 5) {
|
|
549
|
+
(o = this.onColumnResizeStart) == null || o.call(this, s, e.clientX);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
(l = this.onHeaderClick) == null || l.call(this, "col", s, e);
|
|
553
|
+
});
|
|
554
|
+
n(this, "handleRowHeaderMouse", (e) => {
|
|
555
|
+
var i;
|
|
556
|
+
const t = e.target.closest(".wt-row-header-cell");
|
|
557
|
+
if (!t) return;
|
|
558
|
+
const s = parseInt(t.dataset.row ?? "", 10);
|
|
559
|
+
isNaN(s) || (i = this.onHeaderClick) == null || i.call(this, "row", s, e);
|
|
560
|
+
});
|
|
561
|
+
n(this, "handleCornerMouse", (e) => {
|
|
562
|
+
var t;
|
|
563
|
+
(t = this.onHeaderClick) == null || t.call(this, "corner", -1, e);
|
|
564
|
+
});
|
|
565
|
+
n(this, "handleColHeaderContextMenu", (e) => {
|
|
566
|
+
var i;
|
|
567
|
+
e.preventDefault();
|
|
568
|
+
const t = e.target.closest(".wt-col-header-cell");
|
|
569
|
+
if (!t) return;
|
|
570
|
+
const s = parseInt(t.dataset.col ?? "", 10);
|
|
571
|
+
isNaN(s) || (i = this.onHeaderContextMenu) == null || i.call(this, "col", s, e);
|
|
572
|
+
});
|
|
573
|
+
n(this, "handleRowHeaderContextMenu", (e) => {
|
|
574
|
+
var i;
|
|
575
|
+
e.preventDefault();
|
|
576
|
+
const t = e.target.closest(".wt-row-header-cell");
|
|
577
|
+
if (!t) return;
|
|
578
|
+
const s = parseInt(t.dataset.row ?? "", 10);
|
|
579
|
+
isNaN(s) || (i = this.onHeaderContextMenu) == null || i.call(this, "row", s, e);
|
|
580
|
+
});
|
|
581
|
+
this.container = e, this.container.classList.add("wt-root"), this.container.setAttribute("tabindex", "0"), this.cornerEl = document.createElement("div"), this.cornerEl.className = "wt-corner", this.colHeaderEl = document.createElement("div"), this.colHeaderEl.className = "wt-col-headers", this.rowHeaderEl = document.createElement("div"), this.rowHeaderEl.className = "wt-row-headers", this.scrollContainer = document.createElement("div"), this.scrollContainer.className = "wt-scroll-container", this.scrollSentinel = document.createElement("div"), this.scrollSentinel.className = "wt-scroll-sentinel", this.viewportEl = document.createElement("div"), this.viewportEl.className = "wt-viewport", this.scrollContainer.appendChild(this.scrollSentinel), this.scrollContainer.appendChild(this.viewportEl), this.container.appendChild(this.cornerEl), this.container.appendChild(this.colHeaderEl), this.container.appendChild(this.rowHeaderEl), this.container.appendChild(this.scrollContainer), this.scrollContainer.addEventListener("scroll", this.handleScroll, { passive: !0 }), this.viewportEl.addEventListener("mousedown", this.handleMouseDown), this.viewportEl.addEventListener("dblclick", this.handleDblClick), this.viewportEl.addEventListener("contextmenu", this.handleContextMenu), this.colHeaderEl.addEventListener("mousedown", this.handleColHeaderMouse), this.colHeaderEl.addEventListener("contextmenu", this.handleColHeaderContextMenu), this.rowHeaderEl.addEventListener("mousedown", this.handleRowHeaderMouse), this.rowHeaderEl.addEventListener("contextmenu", this.handleRowHeaderContextMenu), this.cornerEl.addEventListener("mousedown", this.handleCornerMouse);
|
|
582
|
+
}
|
|
583
|
+
init(e) {
|
|
584
|
+
this.ctx = e, this.container.classList.toggle("wt-root--no-gridlines", !e.showGridLines), this.container.classList.toggle("wt-root--no-border", !e.showBorder), e.layout === "auto" && (this.container.classList.add("wt-root--auto"), this.scrollContainer.classList.add("wt-scroll-container--auto")), this.applyTheme(), this.updateLayout(), this.scheduleRender();
|
|
585
|
+
}
|
|
586
|
+
applyTheme() {
|
|
587
|
+
const e = this.ctx.theme, t = this.container.style;
|
|
588
|
+
t.setProperty("--wt-bg", e.bgColor), t.setProperty("--wt-cell-bg", e.cellBgColor), t.setProperty("--wt-cell-text", e.cellTextColor), t.setProperty("--wt-header-bg", e.headerBgColor), t.setProperty("--wt-header-text", e.headerTextColor), t.setProperty("--wt-grid-line", e.gridLineColor), t.setProperty("--wt-sel-bg", e.selectionBgColor), t.setProperty("--wt-sel-border", e.selectionBorderColor), t.setProperty("--wt-focus-border", e.focusBorderColor), t.setProperty("--wt-font", e.fontFamily), t.setProperty("--wt-font-size", `${e.fontSize}px`), t.setProperty("--wt-header-font-size", `${e.headerFontSize}px`), t.setProperty("--wt-cell-padding", `${e.cellPadding}px`), t.setProperty("--wt-header-height", `${e.headerHeight}px`), t.setProperty("--wt-row-header-width", `${e.rowHeaderWidth}px`);
|
|
589
|
+
}
|
|
590
|
+
updateLayout() {
|
|
591
|
+
const { columns: e, rows: t, viewMapping: s, showColHeaders: i, showRowHeaders: o, theme: l } = this.ctx, r = e.getTotalWidth(), c = s.visibleRowCount, h = c === t.count ? t.getTotalHeight() : t.getY(c), d = this.ctx.headerRows ? this.ctx.headerRows.length : 1, a = i ? l.headerHeight * d : 0, g = o ? l.rowHeaderWidth : 0;
|
|
592
|
+
if (this.ctx.layout === "auto") {
|
|
593
|
+
if (this.container.style.display = "grid", this.container.style.gridTemplateColumns = `${g}px ${r}px`, this.container.style.gridTemplateRows = `${a}px auto`, this.container.style.width = `${g + r}px`, this.container.style.minWidth = "100%", this.cornerEl.style.display = i && o ? "" : "none", this.cornerEl.style.position = "static", this.cornerEl.style.width = "", this.cornerEl.style.height = "", this.colHeaderEl.style.display = i ? "" : "none", this.colHeaderEl.style.position = "static", this.colHeaderEl.style.left = "", this.colHeaderEl.style.right = "", this.colHeaderEl.style.height = `${a}px`, this.colHeaderEl.style.overflow = "visible", this.rowHeaderEl.style.display = o ? "" : "none", this.rowHeaderEl.style.position = "static", this.rowHeaderEl.style.top = "", this.rowHeaderEl.style.bottom = "", this.rowHeaderEl.style.width = `${g}px`, this.rowHeaderEl.style.overflow = "visible", this.scrollContainer.style.position = "static", this.scrollContainer.style.top = "", this.scrollContainer.style.left = "", this.scrollContainer.style.right = "", this.scrollContainer.style.bottom = "", this.scrollContainer.style.overflow = "visible", this.scrollContainer.style.gridColumn = o ? "2" : "1 / -1", this.scrollSentinel.style.width = `${r}px`, this.scrollSentinel.style.height = "0", this.viewportEl.style.position = "relative", this.viewportEl.style.height = `${h}px`, this.viewportEl.style.width = `${r}px`, o) {
|
|
594
|
+
const p = this.rowHeaderEl.querySelector(".wt-row-headers-inner");
|
|
595
|
+
p && (p.style.height = `${h}px`), this.rowHeaderEl.style.height = `${h}px`, this.rowHeaderEl.style.gridRow = "2", this.rowHeaderEl.style.gridColumn = "1";
|
|
596
|
+
}
|
|
597
|
+
} else
|
|
598
|
+
this.scrollSentinel.style.width = `${r}px`, this.scrollSentinel.style.height = `${h}px`, this.cornerEl.style.display = i && o ? "" : "none", this.cornerEl.style.width = `${g}px`, this.cornerEl.style.height = `${a}px`, this.colHeaderEl.style.display = i ? "" : "none", this.colHeaderEl.style.left = `${g}px`, this.colHeaderEl.style.height = `${a}px`, this.colHeaderEl.style.right = "0", this.rowHeaderEl.style.display = o ? "" : "none", this.rowHeaderEl.style.top = `${a}px`, this.rowHeaderEl.style.width = `${g}px`, this.rowHeaderEl.style.bottom = "0", this.scrollContainer.style.top = `${a}px`, this.scrollContainer.style.left = `${g}px`, this.scrollContainer.style.right = "0", this.scrollContainer.style.bottom = "0";
|
|
599
|
+
}
|
|
600
|
+
scheduleRender() {
|
|
601
|
+
this.needsRender || (this.needsRender = !0, this.rafId = requestAnimationFrame(() => {
|
|
602
|
+
this.needsRender = !1, this.render();
|
|
603
|
+
}));
|
|
604
|
+
}
|
|
605
|
+
render() {
|
|
606
|
+
var S;
|
|
607
|
+
const { columns: e, rows: t, viewMapping: s, showColHeaders: i, showRowHeaders: o } = this.ctx, l = this.scrollContainer, r = l.clientWidth, c = l.clientHeight, h = l.scrollLeft, d = l.scrollTop, a = s.visibleRowCount, g = this.ctx.layout === "auto", p = 3;
|
|
608
|
+
let w, C, E, b;
|
|
609
|
+
if (g)
|
|
610
|
+
w = 0, C = a - 1, E = 0, b = e.count - 1;
|
|
611
|
+
else {
|
|
612
|
+
const m = t.getRowAtY(d), f = t.getRowAtY(d + c), x = e.getColAtX(h), H = e.getColAtX(h + r);
|
|
613
|
+
w = Math.max(0, m - p), C = Math.min(a - 1, f + p), E = Math.max(0, x - p), b = Math.min(e.count - 1, H + p);
|
|
614
|
+
}
|
|
615
|
+
const v = {
|
|
616
|
+
startRow: w,
|
|
617
|
+
endRow: C,
|
|
618
|
+
startCol: E,
|
|
619
|
+
endCol: b,
|
|
620
|
+
scrollX: h,
|
|
621
|
+
scrollY: d
|
|
622
|
+
};
|
|
623
|
+
this.viewport = v;
|
|
624
|
+
const _ = this.ctx.frozenRows, T = this.ctx.frozenCols, k = /* @__PURE__ */ new Set();
|
|
625
|
+
for (let m = 0; m < _ && m < a; m++)
|
|
626
|
+
k.add(m);
|
|
627
|
+
for (let m = v.startRow; m <= v.endRow; m++)
|
|
628
|
+
k.add(m);
|
|
629
|
+
for (const [m, f] of this.activeRows)
|
|
630
|
+
k.has(m) || (f.el.style.display = "none", this.rowPool.push(f), this.activeRows.delete(m));
|
|
631
|
+
for (const m of k)
|
|
632
|
+
this.renderRow(m, v, h, d, _, T);
|
|
633
|
+
if (this.ctx.autoRowHeight) {
|
|
634
|
+
let m = !1;
|
|
635
|
+
for (const f of k) {
|
|
636
|
+
const x = this.activeRows.get(f);
|
|
637
|
+
if (!x) continue;
|
|
638
|
+
let H = 20;
|
|
639
|
+
for (const M of x.cells) {
|
|
640
|
+
if (M.style.display === "none") continue;
|
|
641
|
+
const L = M.scrollHeight;
|
|
642
|
+
L > H && (H = L);
|
|
643
|
+
}
|
|
644
|
+
const I = t.getHeight(f);
|
|
645
|
+
Math.abs(H - I) > 1 && (t.setHeight(f, H), m = !0);
|
|
646
|
+
}
|
|
647
|
+
if (m) {
|
|
648
|
+
this.updateLayout();
|
|
649
|
+
for (const f of k) {
|
|
650
|
+
const x = this.activeRows.get(f);
|
|
651
|
+
if (!x) continue;
|
|
652
|
+
const I = f < _ ? t.getY(f) + d : t.getY(f), M = t.getHeight(f);
|
|
653
|
+
x.el.style.transform = `translateY(${I}px)`, x.el.style.height = `${M}px`;
|
|
654
|
+
for (const L of x.cells)
|
|
655
|
+
L.style.display !== "none" && (L.style.height = `${M}px`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
i && this.renderColHeaders(v, h), o && this.renderRowHeaders(v, d), (S = this.onScroll) == null || S.call(this, v);
|
|
660
|
+
}
|
|
661
|
+
renderRow(e, t, s, i, o, l) {
|
|
662
|
+
var k;
|
|
663
|
+
const { columns: r, rows: c, data: h, selection: d, viewMapping: a } = this.ctx, g = a.toDataRow(e);
|
|
664
|
+
let p = this.activeRows.get(e);
|
|
665
|
+
const w = c.getY(e), C = c.getHeight(e), E = t.endCol - t.startCol + 1, b = e < o;
|
|
666
|
+
p || (p = this.acquireRow(E), p.rowIndex = e, this.activeRows.set(e, p));
|
|
667
|
+
const v = p.el;
|
|
668
|
+
v.style.display = "";
|
|
669
|
+
const _ = b ? w + i : w;
|
|
670
|
+
v.style.transform = `translateY(${_}px)`, v.style.height = `${C}px`, v.style.zIndex = b ? "2" : "", v.dataset.row = String(g), this.ensureCells(p, E);
|
|
671
|
+
const { merges: T } = this.ctx;
|
|
672
|
+
for (let S = 0; S < E; S++) {
|
|
673
|
+
const m = t.startCol + S, f = p.cells[S];
|
|
674
|
+
if (T.isHidden(g, m)) {
|
|
675
|
+
f.style.display = "none";
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
const x = r.getX(m);
|
|
679
|
+
let H = r.getWidth(m), I = C;
|
|
680
|
+
const M = T.getMerge(g, m);
|
|
681
|
+
if (M && M.row === g && M.col === m) {
|
|
682
|
+
for (let y = 1; y < M.colSpan; y++)
|
|
683
|
+
H += r.getWidth(m + y);
|
|
684
|
+
for (let y = 1; y < M.rowSpan; y++)
|
|
685
|
+
I += c.getHeight(e + y);
|
|
686
|
+
f.style.zIndex = "1";
|
|
687
|
+
} else
|
|
688
|
+
f.style.zIndex = "";
|
|
689
|
+
const L = m < l, U = L ? x + s : x;
|
|
690
|
+
f.style.transform = `translateX(${U}px)`, f.style.width = `${H}px`, f.style.height = `${I}px`, f.style.display = "", (L || b) && (f.style.zIndex = L && b ? "4" : "3"), f.dataset.row = String(g), f.dataset.col = String(m);
|
|
691
|
+
const R = h.getCell(g, m), B = {
|
|
692
|
+
selected: d.isSelected(g, m),
|
|
693
|
+
focused: d.isFocused(g, m),
|
|
694
|
+
editing: !1,
|
|
695
|
+
hover: !1
|
|
696
|
+
};
|
|
697
|
+
if (f.classList.toggle("wt-cell--selected", B.selected), f.classList.toggle("wt-cell--focused", B.focused), R != null && R.style) {
|
|
698
|
+
const y = R.style;
|
|
699
|
+
y.bgColor ? f.style.backgroundColor = y.bgColor : f.style.backgroundColor = "", y.textColor ? f.style.color = y.textColor : f.style.color = "", y.textAlign ? f.style.textAlign = y.textAlign : f.style.textAlign = "", y.borderLeft ? f.style.borderLeft = y.borderLeft : f.style.borderLeft = "", y.borderRight ? f.style.borderRight = y.borderRight : f.style.borderRight = "", y.borderTop ? f.style.borderTop = y.borderTop : f.style.borderTop = "", y.borderBottom ? f.style.borderBottom = y.borderBottom : f.style.borderBottom = "";
|
|
700
|
+
} else
|
|
701
|
+
f.style.backgroundColor = "", f.style.color = "", f.style.textAlign = "", f.style.borderLeft = "", f.style.borderRight = "", f.style.borderTop = "", f.style.borderBottom = "";
|
|
702
|
+
R != null && R.className && (f.className = `wt-cell ${R.className}`, B.selected && f.classList.add("wt-cell--selected"), B.focused && f.classList.add("wt-cell--focused"));
|
|
703
|
+
const X = (R == null ? void 0 : R.type) ?? ((k = this.ctx.columns.getConfig(m)) == null ? void 0 : k.type) ?? this.ctx.defaultCellType;
|
|
704
|
+
(this.ctx.renderers.get(X) ?? this.ctx.defaultRenderer).render(f, R, B);
|
|
705
|
+
}
|
|
706
|
+
for (let S = E; S < p.cells.length; S++)
|
|
707
|
+
p.cells[S].style.display = "none";
|
|
708
|
+
}
|
|
709
|
+
renderColHeaders(e, t) {
|
|
710
|
+
var r;
|
|
711
|
+
const { columns: s, theme: i } = this.ctx, o = this.ctx.headerRows;
|
|
712
|
+
this.colHeaderEl.scrollLeft = t;
|
|
713
|
+
const l = this.colHeaderEl.querySelector(".wt-col-headers-inner") ?? this.createColHeadersInner();
|
|
714
|
+
if (l.style.width = `${s.getTotalWidth()}px`, o && o.length > 1) {
|
|
715
|
+
const c = i.headerHeight, h = c * o.length;
|
|
716
|
+
this.colHeaderEl.style.height = `${h}px`, l.style.height = `${h}px`, l.innerHTML = "";
|
|
717
|
+
for (let d = 0; d < o.length; d++)
|
|
718
|
+
for (const a of o[d]) {
|
|
719
|
+
const g = document.createElement("div");
|
|
720
|
+
g.className = a.colSpan > 1 ? "wt-header-cell wt-col-header-group" : "wt-header-cell wt-col-header-cell";
|
|
721
|
+
const p = s.getX(a.col);
|
|
722
|
+
let w = 0;
|
|
723
|
+
for (let C = 0; C < a.colSpan; C++)
|
|
724
|
+
w += s.getWidth(a.col + C);
|
|
725
|
+
g.style.transform = `translate(${p}px, ${d * c}px)`, g.style.width = `${w}px`, g.style.height = `${c * a.rowSpan}px`, g.textContent = a.label, a.colSpan === 1 && (g.dataset.col = String(a.col)), l.appendChild(g);
|
|
726
|
+
}
|
|
727
|
+
} else {
|
|
728
|
+
const c = e.endCol - e.startCol + 1;
|
|
729
|
+
for (; l.children.length < c; ) {
|
|
730
|
+
const h = document.createElement("div");
|
|
731
|
+
h.className = "wt-header-cell wt-col-header-cell", l.appendChild(h);
|
|
732
|
+
}
|
|
733
|
+
for (let h = 0; h < c; h++) {
|
|
734
|
+
const d = e.startCol + h, a = l.children[h];
|
|
735
|
+
a.style.display = "", a.style.transform = `translateX(${s.getX(d)}px)`, a.style.width = `${s.getWidth(d)}px`, a.style.height = `${i.headerHeight}px`, a.textContent = ((r = this.ctx.columns.getConfig(d)) == null ? void 0 : r.label) ?? P.columnLabel(d), a.dataset.col = String(d);
|
|
736
|
+
}
|
|
737
|
+
for (let h = c; h < l.children.length; h++)
|
|
738
|
+
l.children[h].style.display = "none";
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
createColHeadersInner() {
|
|
742
|
+
const e = document.createElement("div");
|
|
743
|
+
return e.className = "wt-col-headers-inner", this.colHeaderEl.appendChild(e), e;
|
|
744
|
+
}
|
|
745
|
+
renderRowHeaders(e, t) {
|
|
746
|
+
const { rows: s, theme: i } = this.ctx;
|
|
747
|
+
this.rowHeaderEl.scrollTop = t;
|
|
748
|
+
let o = this.rowHeaderEl.querySelector(".wt-row-headers-inner");
|
|
749
|
+
o || (o = document.createElement("div"), o.className = "wt-row-headers-inner", this.rowHeaderEl.appendChild(o)), o.style.height = `${s.getTotalHeight()}px`;
|
|
750
|
+
const l = e.endRow - e.startRow + 1;
|
|
751
|
+
for (; o.children.length < l; ) {
|
|
752
|
+
const r = document.createElement("div");
|
|
753
|
+
r.className = "wt-header-cell wt-row-header-cell", o.appendChild(r);
|
|
754
|
+
}
|
|
755
|
+
for (let r = 0; r < l; r++) {
|
|
756
|
+
const c = e.startRow + r, h = o.children[r];
|
|
757
|
+
h.style.display = "", h.style.transform = `translateY(${s.getY(c)}px)`, h.style.height = `${s.getHeight(c)}px`, h.style.width = `${i.rowHeaderWidth}px`, h.textContent = String(c + 1), h.dataset.row = String(c);
|
|
758
|
+
}
|
|
759
|
+
for (let r = l; r < o.children.length; r++)
|
|
760
|
+
o.children[r].style.display = "none";
|
|
761
|
+
}
|
|
762
|
+
acquireRow(e) {
|
|
763
|
+
let t = this.rowPool.pop();
|
|
764
|
+
if (!t) {
|
|
765
|
+
const s = document.createElement("div");
|
|
766
|
+
s.className = "wt-row", this.viewportEl.appendChild(s), t = { el: s, cells: [], rowIndex: -1 };
|
|
767
|
+
}
|
|
768
|
+
return this.ensureCells(t, e), t;
|
|
769
|
+
}
|
|
770
|
+
ensureCells(e, t) {
|
|
771
|
+
for (; e.cells.length < t; ) {
|
|
772
|
+
const s = document.createElement("div");
|
|
773
|
+
s.className = "wt-cell", e.el.appendChild(s), e.cells.push(s);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
/** Resolve cell address from a mouse event target */
|
|
777
|
+
getCellFromEvent(e) {
|
|
778
|
+
const t = e.target.closest(".wt-cell");
|
|
779
|
+
if (!t) return null;
|
|
780
|
+
const s = parseInt(t.dataset.row ?? "", 10), i = parseInt(t.dataset.col ?? "", 10);
|
|
781
|
+
return isNaN(s) || isNaN(i) ? null : { row: s, col: i };
|
|
782
|
+
}
|
|
783
|
+
getViewport() {
|
|
784
|
+
return this.viewport;
|
|
785
|
+
}
|
|
786
|
+
scrollToCell(e, t) {
|
|
787
|
+
const { columns: s, rows: i } = this.ctx, o = s.getX(t), l = i.getY(e), r = s.getWidth(t), c = i.getHeight(e), h = this.scrollContainer, d = h.clientWidth, a = h.clientHeight;
|
|
788
|
+
o < h.scrollLeft ? h.scrollLeft = o : o + r > h.scrollLeft + d && (h.scrollLeft = o + r - d), l < h.scrollTop ? h.scrollTop = l : l + c > h.scrollTop + a && (h.scrollTop = l + c - a);
|
|
789
|
+
}
|
|
790
|
+
/** Get the pixel bounds of a cell relative to the scroll container */
|
|
791
|
+
getCellBounds(e, t) {
|
|
792
|
+
const { columns: s, rows: i } = this.ctx;
|
|
793
|
+
return {
|
|
794
|
+
x: s.getX(t) - this.scrollContainer.scrollLeft,
|
|
795
|
+
y: i.getY(e) - this.scrollContainer.scrollTop,
|
|
796
|
+
width: s.getWidth(t),
|
|
797
|
+
height: i.getHeight(e)
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
getScrollContainer() {
|
|
801
|
+
return this.scrollContainer;
|
|
802
|
+
}
|
|
803
|
+
getViewportEl() {
|
|
804
|
+
return this.viewportEl;
|
|
805
|
+
}
|
|
806
|
+
getContainer() {
|
|
807
|
+
return this.container;
|
|
808
|
+
}
|
|
809
|
+
destroy() {
|
|
810
|
+
cancelAnimationFrame(this.rafId), this.scrollContainer.removeEventListener("scroll", this.handleScroll), this.viewportEl.removeEventListener("mousedown", this.handleMouseDown), this.viewportEl.removeEventListener("dblclick", this.handleDblClick), this.viewportEl.removeEventListener("contextmenu", this.handleContextMenu), this.colHeaderEl.removeEventListener("mousedown", this.handleColHeaderMouse), this.colHeaderEl.removeEventListener("contextmenu", this.handleColHeaderContextMenu), this.rowHeaderEl.removeEventListener("mousedown", this.handleRowHeaderMouse), this.rowHeaderEl.removeEventListener("contextmenu", this.handleRowHeaderContextMenu), this.cornerEl.removeEventListener("mousedown", this.handleCornerMouse), this.container.innerHTML = "";
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
const st = { selected: !1, focused: !1, editing: !1, hover: !1 };
|
|
814
|
+
class it {
|
|
815
|
+
constructor(e, t, s, i, o, l) {
|
|
816
|
+
n(this, "measureEl");
|
|
817
|
+
n(this, "data");
|
|
818
|
+
n(this, "columns");
|
|
819
|
+
n(this, "renderers");
|
|
820
|
+
n(this, "defaultRenderer");
|
|
821
|
+
this.data = t, this.columns = s, this.renderers = o, this.defaultRenderer = l, this.measureEl = document.createElement("div"), this.measureEl.className = "wt-cell", this.measureEl.style.position = "absolute", this.measureEl.style.visibility = "hidden", this.measureEl.style.left = "-9999px", this.measureEl.style.top = "-9999px", this.measureEl.style.whiteSpace = "nowrap", this.measureEl.style.height = "auto", this.measureEl.style.width = "auto", e.appendChild(this.measureEl);
|
|
822
|
+
}
|
|
823
|
+
/** Measure a single cell's natural width and height */
|
|
824
|
+
measureCell(e, t) {
|
|
825
|
+
var c;
|
|
826
|
+
const s = this.data.getCell(e, t), i = (s == null ? void 0 : s.type) ?? ((c = this.columns.getConfig(t)) == null ? void 0 : c.type) ?? "text";
|
|
827
|
+
(this.renderers.get(i) ?? this.defaultRenderer).render(this.measureEl, s, st);
|
|
828
|
+
const l = this.measureEl.scrollWidth + 1, r = this.measureEl.scrollHeight + 1;
|
|
829
|
+
return this.measureEl.textContent = "", this.measureEl.innerHTML = "", { width: l, height: r };
|
|
830
|
+
}
|
|
831
|
+
/** Auto-fit a column width to its content. Samples up to `maxRows` rows. */
|
|
832
|
+
autoFitColumn(e, t = 500) {
|
|
833
|
+
var a;
|
|
834
|
+
let i = 40;
|
|
835
|
+
const o = ((a = this.columns.getConfig(e)) == null ? void 0 : a.label) ?? z(e);
|
|
836
|
+
this.measureEl.textContent = o, this.measureEl.style.fontWeight = "500", i = Math.max(i, this.measureEl.scrollWidth + 16), this.measureEl.style.fontWeight = "";
|
|
837
|
+
const l = this.data.rowCount, r = l > t ? Math.floor(l / t) : 1;
|
|
838
|
+
for (let g = 0; g < l; g += r) {
|
|
839
|
+
if (!this.data.hasCell(g, e)) continue;
|
|
840
|
+
const { width: p } = this.measureCell(g, e);
|
|
841
|
+
i = Math.max(i, p + 16);
|
|
842
|
+
}
|
|
843
|
+
const c = this.columns.getConfig(e), h = (c == null ? void 0 : c.minWidth) ?? 30, d = (c == null ? void 0 : c.maxWidth) ?? 600;
|
|
844
|
+
return Math.max(h, Math.min(d, i));
|
|
845
|
+
}
|
|
846
|
+
/** Auto-fit a row height to its content */
|
|
847
|
+
autoFitRow(e) {
|
|
848
|
+
let t = 20;
|
|
849
|
+
for (let s = 0; s < this.columns.count; s++) {
|
|
850
|
+
if (!this.data.hasCell(e, s)) continue;
|
|
851
|
+
this.measureEl.style.width = `${this.columns.getWidth(s)}px`, this.measureEl.style.whiteSpace = "normal";
|
|
852
|
+
const { height: i } = this.measureCell(e, s);
|
|
853
|
+
t = Math.max(t, i), this.measureEl.style.width = "auto", this.measureEl.style.whiteSpace = "nowrap";
|
|
854
|
+
}
|
|
855
|
+
return t;
|
|
856
|
+
}
|
|
857
|
+
destroy() {
|
|
858
|
+
this.measureEl.remove();
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
class ot {
|
|
862
|
+
render(e, t, s) {
|
|
863
|
+
const i = t == null ? void 0 : t.value;
|
|
864
|
+
if (i == null || i === "") {
|
|
865
|
+
e.textContent = "";
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
e.textContent = String(i);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
class nt {
|
|
872
|
+
render(e, t, s) {
|
|
873
|
+
const i = !!(t != null && t.value);
|
|
874
|
+
e.innerHTML = `<label class="wt-checkbox">
|
|
875
|
+
<span class="wt-checkbox-box${i ? " wt-checkbox-box--checked" : ""}">
|
|
876
|
+
${i ? '<svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2.5 6L5 8.5L9.5 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>' : ""}
|
|
877
|
+
</span>
|
|
878
|
+
</label>`;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
const A = {
|
|
882
|
+
active: { bg: "#dcfce7", text: "#166534" },
|
|
883
|
+
success: { bg: "#dcfce7", text: "#166534" },
|
|
884
|
+
inactive: { bg: "#fef2f2", text: "#991b1b" },
|
|
885
|
+
error: { bg: "#fef2f2", text: "#991b1b" },
|
|
886
|
+
pending: { bg: "#fef9c3", text: "#854d0e" },
|
|
887
|
+
warning: { bg: "#fef9c3", text: "#854d0e" },
|
|
888
|
+
info: { bg: "#dbeafe", text: "#1e40af" },
|
|
889
|
+
default: { bg: "#f1f5f9", text: "#475569" }
|
|
890
|
+
};
|
|
891
|
+
class lt {
|
|
892
|
+
render(e, t, s) {
|
|
893
|
+
var h, d;
|
|
894
|
+
if ((t == null ? void 0 : t.value) == null || t.value === "") {
|
|
895
|
+
e.textContent = "";
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
const i = String(t.value), o = i.toLowerCase(), l = A[o] ?? A.default, r = (h = t.meta) == null ? void 0 : h.badgeBg, c = (d = t.meta) == null ? void 0 : d.badgeText;
|
|
899
|
+
e.innerHTML = `<span class="wt-badge" style="background:${r ?? l.bg};color:${c ?? l.text}">${i}</span>`;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
class rt {
|
|
903
|
+
constructor(e, t) {
|
|
904
|
+
n(this, "formatter");
|
|
905
|
+
this.formatter = new Intl.NumberFormat(e, t);
|
|
906
|
+
}
|
|
907
|
+
render(e, t, s) {
|
|
908
|
+
if ((t == null ? void 0 : t.value) == null || t.value === "") {
|
|
909
|
+
e.textContent = "";
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
const i = Number(t.value);
|
|
913
|
+
if (isNaN(i)) {
|
|
914
|
+
e.textContent = String(t.value);
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
e.textContent = this.formatter.format(i), e.style.textAlign = "right";
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
class at {
|
|
921
|
+
render(e, t, s) {
|
|
922
|
+
if ((t == null ? void 0 : t.value) == null) {
|
|
923
|
+
e.textContent = "";
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
const i = Math.max(0, Math.min(100, Number(t.value)));
|
|
927
|
+
if (isNaN(i)) {
|
|
928
|
+
e.textContent = "";
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
const o = i >= 80 ? "#22c55e" : i >= 50 ? "#f59e0b" : i >= 25 ? "#f97316" : "#ef4444";
|
|
932
|
+
e.innerHTML = `<div class="wt-progress">
|
|
933
|
+
<div class="wt-progress-bar" style="width:${i}%;background:${o}"></div>
|
|
934
|
+
<span class="wt-progress-label">${Math.round(i)}%</span>
|
|
935
|
+
</div>`;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
class ht {
|
|
939
|
+
render(e, t, s) {
|
|
940
|
+
e.textContent = "";
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
class ct {
|
|
944
|
+
constructor() {
|
|
945
|
+
n(this, "renderers", /* @__PURE__ */ new Map());
|
|
946
|
+
n(this, "defaultRenderer");
|
|
947
|
+
this.defaultRenderer = new ot(), this.renderers.set("text", this.defaultRenderer), this.renderers.set("blank", new ht()), this.renderers.set("checkbox", new nt()), this.renderers.set("badge", new lt()), this.renderers.set("number", new rt()), this.renderers.set("progress", new at());
|
|
948
|
+
}
|
|
949
|
+
register(e, t) {
|
|
950
|
+
this.renderers.set(e, t);
|
|
951
|
+
}
|
|
952
|
+
get(e) {
|
|
953
|
+
return this.renderers.get(e);
|
|
954
|
+
}
|
|
955
|
+
getAll() {
|
|
956
|
+
return this.renderers;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
class dt {
|
|
960
|
+
constructor(e) {
|
|
961
|
+
n(this, "editors", /* @__PURE__ */ new Map());
|
|
962
|
+
n(this, "activeEditor", null);
|
|
963
|
+
n(this, "activeEditorEl", null);
|
|
964
|
+
n(this, "activeRow", -1);
|
|
965
|
+
n(this, "activeCol", -1);
|
|
966
|
+
n(this, "overlayEl");
|
|
967
|
+
n(this, "onClose", null);
|
|
968
|
+
n(this, "handleEditorKey", (e) => {
|
|
969
|
+
switch (e.key) {
|
|
970
|
+
case "Enter":
|
|
971
|
+
e.shiftKey || (e.preventDefault(), e.stopPropagation(), this.close(!0));
|
|
972
|
+
break;
|
|
973
|
+
case "Escape":
|
|
974
|
+
e.preventDefault(), e.stopPropagation(), this.close(!1);
|
|
975
|
+
break;
|
|
976
|
+
case "Tab":
|
|
977
|
+
e.preventDefault(), e.stopPropagation(), this.close(!0);
|
|
978
|
+
break;
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
this.overlayEl = document.createElement("div"), this.overlayEl.className = "wt-editor-overlay", this.overlayEl.style.display = "none", e.appendChild(this.overlayEl), this.register("text", () => new ut()), this.register("blank", () => new gt());
|
|
982
|
+
}
|
|
983
|
+
register(e, t) {
|
|
984
|
+
this.editors.set(e, t);
|
|
985
|
+
}
|
|
986
|
+
get isEditing() {
|
|
987
|
+
return this.activeEditor !== null;
|
|
988
|
+
}
|
|
989
|
+
get editingCell() {
|
|
990
|
+
return this.activeEditor ? { row: this.activeRow, col: this.activeCol } : null;
|
|
991
|
+
}
|
|
992
|
+
open(e, t, s, i, o, l, r) {
|
|
993
|
+
this.close(!1);
|
|
994
|
+
const c = this.editors.get(s);
|
|
995
|
+
if (!c) return;
|
|
996
|
+
this.activeRow = e, this.activeCol = t, this.activeEditor = c(), this.overlayEl.style.display = "", this.overlayEl.style.left = `${o.x}px`, this.overlayEl.style.top = `${o.y}px`, this.overlayEl.style.width = `${o.width}px`, this.overlayEl.style.height = `${o.height}px`, this.activeEditorEl = this.activeEditor.createElement(this.overlayEl);
|
|
997
|
+
const h = r !== void 0 ? r : i;
|
|
998
|
+
this.activeEditor.open(h, o, l), this.activeEditorEl.addEventListener("keydown", this.handleEditorKey);
|
|
999
|
+
}
|
|
1000
|
+
close(e) {
|
|
1001
|
+
var l;
|
|
1002
|
+
if (!this.activeEditor) return;
|
|
1003
|
+
const t = this.activeEditor, s = this.activeRow, i = this.activeCol;
|
|
1004
|
+
let o;
|
|
1005
|
+
e && (o = t.getValue(), t.validate && t.validate(o) !== !0) || (this.activeEditorEl && (this.activeEditorEl.removeEventListener("keydown", this.handleEditorKey), this.activeEditorEl = null), t.close(), this.overlayEl.innerHTML = "", this.overlayEl.style.display = "none", this.activeEditor = null, this.activeRow = -1, this.activeCol = -1, (l = this.onClose) == null || l.call(this, s, i, e ? o : void 0, !e));
|
|
1006
|
+
}
|
|
1007
|
+
destroy() {
|
|
1008
|
+
this.close(!1), this.overlayEl.remove();
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
class ut {
|
|
1012
|
+
constructor() {
|
|
1013
|
+
n(this, "input");
|
|
1014
|
+
}
|
|
1015
|
+
createElement(e) {
|
|
1016
|
+
return this.input = document.createElement("input"), this.input.type = "text", this.input.className = "wt-editor-input", e.appendChild(this.input), this.input;
|
|
1017
|
+
}
|
|
1018
|
+
open(e, t, s) {
|
|
1019
|
+
this.input.value = e != null ? String(e) : "", requestAnimationFrame(() => {
|
|
1020
|
+
this.input.focus(), this.input.select();
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
getValue() {
|
|
1024
|
+
return this.input.value;
|
|
1025
|
+
}
|
|
1026
|
+
close() {
|
|
1027
|
+
this.input.remove();
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
class gt {
|
|
1031
|
+
constructor() {
|
|
1032
|
+
n(this, "el");
|
|
1033
|
+
}
|
|
1034
|
+
createElement(e) {
|
|
1035
|
+
return this.el = document.createElement("div"), e.appendChild(this.el), this.el;
|
|
1036
|
+
}
|
|
1037
|
+
open() {
|
|
1038
|
+
}
|
|
1039
|
+
getValue() {
|
|
1040
|
+
}
|
|
1041
|
+
close() {
|
|
1042
|
+
var e;
|
|
1043
|
+
(e = this.el) == null || e.remove();
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
class pt {
|
|
1047
|
+
constructor(e, t) {
|
|
1048
|
+
n(this, "selection");
|
|
1049
|
+
n(this, "callbacks");
|
|
1050
|
+
this.selection = e, this.callbacks = t;
|
|
1051
|
+
}
|
|
1052
|
+
handleKeyDown(e) {
|
|
1053
|
+
const t = e.ctrlKey || e.metaKey, s = e.shiftKey, i = this.selection.focus;
|
|
1054
|
+
switch (e.key) {
|
|
1055
|
+
case "ArrowUp":
|
|
1056
|
+
e.preventDefault(), this.selection.move(-1, 0, s), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1057
|
+
break;
|
|
1058
|
+
case "ArrowDown":
|
|
1059
|
+
e.preventDefault(), this.selection.move(1, 0, s), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1060
|
+
break;
|
|
1061
|
+
case "ArrowLeft":
|
|
1062
|
+
e.preventDefault(), this.selection.move(0, -1, s), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1063
|
+
break;
|
|
1064
|
+
case "ArrowRight":
|
|
1065
|
+
e.preventDefault(), this.selection.move(0, 1, s), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1066
|
+
break;
|
|
1067
|
+
case "Tab":
|
|
1068
|
+
e.preventDefault(), this.selection.move(0, s ? -1 : 1, !1), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1069
|
+
break;
|
|
1070
|
+
case "Enter":
|
|
1071
|
+
e.preventDefault(), i && this.callbacks.onStartEdit(i.row, i.col);
|
|
1072
|
+
break;
|
|
1073
|
+
case "F2":
|
|
1074
|
+
e.preventDefault(), i && this.callbacks.onStartEdit(i.row, i.col);
|
|
1075
|
+
break;
|
|
1076
|
+
case "Delete":
|
|
1077
|
+
case "Backspace":
|
|
1078
|
+
e.preventDefault(), this.callbacks.onDelete();
|
|
1079
|
+
break;
|
|
1080
|
+
case "Escape":
|
|
1081
|
+
e.preventDefault(), this.selection.clear();
|
|
1082
|
+
break;
|
|
1083
|
+
case "Home":
|
|
1084
|
+
e.preventDefault(), t ? this.selection.focusCell(0, 0) : i && this.selection.focusCell(i.row, 0), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1085
|
+
break;
|
|
1086
|
+
case "End":
|
|
1087
|
+
e.preventDefault(), this.selection.focus && this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);
|
|
1088
|
+
break;
|
|
1089
|
+
case "a":
|
|
1090
|
+
t ? (e.preventDefault(), this.selection.selectAll()) : this.handleCharInput(e);
|
|
1091
|
+
break;
|
|
1092
|
+
case "c":
|
|
1093
|
+
t ? (e.preventDefault(), this.callbacks.onCopy()) : this.handleCharInput(e);
|
|
1094
|
+
break;
|
|
1095
|
+
case "v":
|
|
1096
|
+
t ? (e.preventDefault(), this.callbacks.onPaste()) : this.handleCharInput(e);
|
|
1097
|
+
break;
|
|
1098
|
+
case "x":
|
|
1099
|
+
t ? (e.preventDefault(), this.callbacks.onCut()) : this.handleCharInput(e);
|
|
1100
|
+
break;
|
|
1101
|
+
case "z":
|
|
1102
|
+
t ? (e.preventDefault(), s ? this.callbacks.onRedo() : this.callbacks.onUndo()) : this.handleCharInput(e);
|
|
1103
|
+
break;
|
|
1104
|
+
case "y":
|
|
1105
|
+
t ? (e.preventDefault(), this.callbacks.onRedo()) : this.handleCharInput(e);
|
|
1106
|
+
break;
|
|
1107
|
+
default:
|
|
1108
|
+
!t && !e.altKey && e.key.length === 1 && this.handleCharInput(e);
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
handleCharInput(e) {
|
|
1113
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
1114
|
+
const t = this.selection.focus;
|
|
1115
|
+
t && (e.preventDefault(), this.callbacks.onStartEdit(t.row, t.col, e.key));
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
class ft {
|
|
1119
|
+
constructor(e, t) {
|
|
1120
|
+
n(this, "data");
|
|
1121
|
+
n(this, "selection");
|
|
1122
|
+
n(this, "onChange", null);
|
|
1123
|
+
this.data = e, this.selection = t;
|
|
1124
|
+
}
|
|
1125
|
+
async copy() {
|
|
1126
|
+
const e = this.selectionToTSV();
|
|
1127
|
+
if (e)
|
|
1128
|
+
try {
|
|
1129
|
+
await navigator.clipboard.writeText(e);
|
|
1130
|
+
} catch {
|
|
1131
|
+
this.fallbackCopy(e);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
async cut() {
|
|
1135
|
+
await this.copy(), this.deleteSelected();
|
|
1136
|
+
}
|
|
1137
|
+
async paste() {
|
|
1138
|
+
var l;
|
|
1139
|
+
const e = this.selection.focus;
|
|
1140
|
+
if (!e) return;
|
|
1141
|
+
let t;
|
|
1142
|
+
try {
|
|
1143
|
+
t = await navigator.clipboard.readText();
|
|
1144
|
+
} catch {
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
const s = this.parseTSV(t);
|
|
1148
|
+
if (s.length === 0) return;
|
|
1149
|
+
const i = s.length === 1 && s[0].length === 1, o = [];
|
|
1150
|
+
if (i && !this.isFullRowOrColSelected()) {
|
|
1151
|
+
const r = s[0][0];
|
|
1152
|
+
this.selection.forEachSelected((c, h) => {
|
|
1153
|
+
c < this.data.rowCount && h < this.data.colCount && o.push({ row: c, col: h, data: { value: r } });
|
|
1154
|
+
});
|
|
1155
|
+
} else
|
|
1156
|
+
for (let r = 0; r < s.length; r++)
|
|
1157
|
+
for (let c = 0; c < s[r].length; c++) {
|
|
1158
|
+
const h = e.row + r, d = e.col + c;
|
|
1159
|
+
h >= this.data.rowCount || d >= this.data.colCount || o.push({
|
|
1160
|
+
row: h,
|
|
1161
|
+
col: d,
|
|
1162
|
+
data: { value: s[r][c] }
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
o.length > 0 && (this.data.applyPatch(o), (l = this.onChange) == null || l.call(this, o));
|
|
1166
|
+
}
|
|
1167
|
+
/** Check if current selection spans an entire row or column */
|
|
1168
|
+
isFullRowOrColSelected() {
|
|
1169
|
+
const e = this.selection.getBounds();
|
|
1170
|
+
if (!e) return !1;
|
|
1171
|
+
const t = e.c1 === 0 && e.c2 === this.data.colCount - 1, s = e.r1 === 0 && e.r2 === this.data.rowCount - 1;
|
|
1172
|
+
return t || s;
|
|
1173
|
+
}
|
|
1174
|
+
deleteSelected() {
|
|
1175
|
+
var t;
|
|
1176
|
+
const e = [];
|
|
1177
|
+
this.selection.forEachSelected((s, i) => {
|
|
1178
|
+
this.data.hasCell(s, i) && e.push({ row: s, col: i, data: { value: void 0 } });
|
|
1179
|
+
}), e.length > 0 && (this.data.applyPatch(e), (t = this.onChange) == null || t.call(this, e));
|
|
1180
|
+
}
|
|
1181
|
+
selectionToTSV() {
|
|
1182
|
+
const e = this.selection.getBounds();
|
|
1183
|
+
if (!e) return null;
|
|
1184
|
+
const t = [];
|
|
1185
|
+
for (let s = e.r1; s <= e.r2; s++) {
|
|
1186
|
+
const i = [];
|
|
1187
|
+
for (let o = e.c1; o <= e.c2; o++) {
|
|
1188
|
+
const l = this.data.getCell(s, o), r = l == null ? void 0 : l.value;
|
|
1189
|
+
i.push(r != null ? String(r) : "");
|
|
1190
|
+
}
|
|
1191
|
+
t.push(i.join(" "));
|
|
1192
|
+
}
|
|
1193
|
+
return t.join(`
|
|
1194
|
+
`);
|
|
1195
|
+
}
|
|
1196
|
+
parseTSV(e) {
|
|
1197
|
+
return e.split(`
|
|
1198
|
+
`).map((t) => t.split(" "));
|
|
1199
|
+
}
|
|
1200
|
+
fallbackCopy(e) {
|
|
1201
|
+
const t = document.createElement("textarea");
|
|
1202
|
+
t.value = e, t.style.position = "fixed", t.style.left = "-9999px", document.body.appendChild(t), t.select(), document.execCommand("copy"), t.remove();
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
class wt {
|
|
1206
|
+
constructor(e) {
|
|
1207
|
+
n(this, "columns");
|
|
1208
|
+
n(this, "resizing", !1);
|
|
1209
|
+
n(this, "resizeCol", -1);
|
|
1210
|
+
n(this, "startX", 0);
|
|
1211
|
+
n(this, "startWidth", 0);
|
|
1212
|
+
n(this, "onResize", null);
|
|
1213
|
+
n(this, "handleMove", (e) => {
|
|
1214
|
+
var i;
|
|
1215
|
+
if (!this.resizing) return;
|
|
1216
|
+
const t = e.clientX - this.startX, s = Math.max(30, this.startWidth + t);
|
|
1217
|
+
this.columns.setWidth(this.resizeCol, s), (i = this.onResize) == null || i.call(this, this.resizeCol, s);
|
|
1218
|
+
});
|
|
1219
|
+
n(this, "handleUp", () => {
|
|
1220
|
+
this.resizing = !1, document.removeEventListener("mousemove", this.handleMove), document.removeEventListener("mouseup", this.handleUp), document.body.style.cursor = "", document.body.style.userSelect = "";
|
|
1221
|
+
});
|
|
1222
|
+
this.columns = e;
|
|
1223
|
+
}
|
|
1224
|
+
start(e, t) {
|
|
1225
|
+
e < 0 || e >= this.columns.count || (this.resizing = !0, this.resizeCol = e, this.startX = t, this.startWidth = this.columns.getWidth(e), document.addEventListener("mousemove", this.handleMove), document.addEventListener("mouseup", this.handleUp), document.body.style.cursor = "col-resize", document.body.style.userSelect = "none");
|
|
1226
|
+
}
|
|
1227
|
+
destroy() {
|
|
1228
|
+
document.removeEventListener("mousemove", this.handleMove), document.removeEventListener("mouseup", this.handleUp);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
class mt {
|
|
1232
|
+
constructor(e) {
|
|
1233
|
+
n(this, "rows");
|
|
1234
|
+
n(this, "resizing", !1);
|
|
1235
|
+
n(this, "resizeRow", -1);
|
|
1236
|
+
n(this, "startY", 0);
|
|
1237
|
+
n(this, "startHeight", 0);
|
|
1238
|
+
n(this, "onResize", null);
|
|
1239
|
+
n(this, "handleMove", (e) => {
|
|
1240
|
+
var i;
|
|
1241
|
+
if (!this.resizing) return;
|
|
1242
|
+
const t = e.clientY - this.startY, s = Math.max(20, this.startHeight + t);
|
|
1243
|
+
this.rows.setHeight(this.resizeRow, s), (i = this.onResize) == null || i.call(this, this.resizeRow, s);
|
|
1244
|
+
});
|
|
1245
|
+
n(this, "handleUp", () => {
|
|
1246
|
+
this.resizing = !1, document.removeEventListener("mousemove", this.handleMove), document.removeEventListener("mouseup", this.handleUp), document.body.style.cursor = "", document.body.style.userSelect = "";
|
|
1247
|
+
});
|
|
1248
|
+
this.rows = e;
|
|
1249
|
+
}
|
|
1250
|
+
start(e, t) {
|
|
1251
|
+
this.resizing = !0, this.resizeRow = e, this.startY = t, this.startHeight = this.rows.getHeight(e), document.addEventListener("mousemove", this.handleMove), document.addEventListener("mouseup", this.handleUp), document.body.style.cursor = "row-resize", document.body.style.userSelect = "none";
|
|
1252
|
+
}
|
|
1253
|
+
destroy() {
|
|
1254
|
+
document.removeEventListener("mousemove", this.handleMove), document.removeEventListener("mouseup", this.handleUp);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
class Ct {
|
|
1258
|
+
constructor() {
|
|
1259
|
+
n(this, "el", null);
|
|
1260
|
+
n(this, "closeHandler", (e) => {
|
|
1261
|
+
this.el && !this.el.contains(e.target) && this.close();
|
|
1262
|
+
});
|
|
1263
|
+
n(this, "keyHandler", (e) => {
|
|
1264
|
+
e.key === "Escape" && this.close();
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
open(e, t, s, i) {
|
|
1268
|
+
this.close(), this.el = document.createElement("div"), this.el.className = "wt-context-menu";
|
|
1269
|
+
for (const l of s) {
|
|
1270
|
+
if (!(typeof l.visible == "function" ? l.visible(i) : l.visible ?? !0)) continue;
|
|
1271
|
+
if (l.separator) {
|
|
1272
|
+
const a = document.createElement("div");
|
|
1273
|
+
a.className = "wt-context-menu-separator", this.el.appendChild(a);
|
|
1274
|
+
continue;
|
|
1275
|
+
}
|
|
1276
|
+
const c = typeof l.disabled == "function" ? l.disabled(i) : l.disabled ?? !1, h = document.createElement("div");
|
|
1277
|
+
h.className = "wt-context-menu-item", c && h.classList.add("wt-context-menu-item--disabled");
|
|
1278
|
+
const d = document.createElement("span");
|
|
1279
|
+
if (d.textContent = l.label, h.appendChild(d), l.shortcut) {
|
|
1280
|
+
const a = document.createElement("span");
|
|
1281
|
+
a.className = "wt-context-menu-shortcut", a.textContent = l.shortcut, h.appendChild(a);
|
|
1282
|
+
}
|
|
1283
|
+
if (!c && l.action) {
|
|
1284
|
+
const a = l.action;
|
|
1285
|
+
h.addEventListener("click", (g) => {
|
|
1286
|
+
g.stopPropagation(), this.close(), a(i);
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
this.el.appendChild(h);
|
|
1290
|
+
}
|
|
1291
|
+
document.body.appendChild(this.el);
|
|
1292
|
+
const o = this.el.getBoundingClientRect();
|
|
1293
|
+
e + o.width > window.innerWidth && (e = window.innerWidth - o.width - 4), t + o.height > window.innerHeight && (t = window.innerHeight - o.height - 4), this.el.style.left = `${Math.max(0, e)}px`, this.el.style.top = `${Math.max(0, t)}px`, requestAnimationFrame(() => {
|
|
1294
|
+
document.addEventListener("mousedown", this.closeHandler), document.addEventListener("keydown", this.keyHandler);
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
close() {
|
|
1298
|
+
this.el && (this.el.remove(), this.el = null), document.removeEventListener("mousedown", this.closeHandler), document.removeEventListener("keydown", this.keyHandler);
|
|
1299
|
+
}
|
|
1300
|
+
get isOpen() {
|
|
1301
|
+
return this.el !== null;
|
|
1302
|
+
}
|
|
1303
|
+
destroy() {
|
|
1304
|
+
this.close();
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
class yt {
|
|
1308
|
+
constructor(e, t, s, i, o) {
|
|
1309
|
+
n(this, "handleEl");
|
|
1310
|
+
n(this, "shadowEl");
|
|
1311
|
+
n(this, "dragging", !1);
|
|
1312
|
+
n(this, "currentRow", -1);
|
|
1313
|
+
n(this, "currentCol", -1);
|
|
1314
|
+
n(this, "data");
|
|
1315
|
+
n(this, "selection");
|
|
1316
|
+
n(this, "getCellAtPoint", null);
|
|
1317
|
+
n(this, "getCellBounds", null);
|
|
1318
|
+
n(this, "onFill", null);
|
|
1319
|
+
n(this, "onFillCallback", null);
|
|
1320
|
+
n(this, "enabled", !0);
|
|
1321
|
+
n(this, "onMouseDown", (e) => {
|
|
1322
|
+
e.preventDefault(), e.stopPropagation();
|
|
1323
|
+
const t = this.selection.getBounds();
|
|
1324
|
+
t && (this.dragging = !0, this.currentRow = t.r2, this.currentCol = t.c2, document.addEventListener("mousemove", this.onMouseMove), document.addEventListener("mouseup", this.onMouseUp), document.body.style.cursor = "crosshair", document.body.style.userSelect = "none");
|
|
1325
|
+
});
|
|
1326
|
+
n(this, "onMouseMove", (e) => {
|
|
1327
|
+
if (!this.dragging || !this.getCellAtPoint) return;
|
|
1328
|
+
const t = this.getCellAtPoint(e.clientX, e.clientY);
|
|
1329
|
+
t && (this.currentRow = t.row, this.currentCol = t.col, this.updateShadow());
|
|
1330
|
+
});
|
|
1331
|
+
n(this, "onMouseUp", () => {
|
|
1332
|
+
this.dragging && (this.dragging = !1, document.removeEventListener("mousemove", this.onMouseMove), document.removeEventListener("mouseup", this.onMouseUp), document.body.style.cursor = "", document.body.style.userSelect = "", this.shadowEl.style.display = "none", this.executeFill(), this.updatePosition());
|
|
1333
|
+
});
|
|
1334
|
+
this.data = t, this.selection = s, this.handleEl = document.createElement("div"), this.handleEl.className = "wt-fill-handle", this.handleEl.style.display = "none", e.appendChild(this.handleEl), this.shadowEl = document.createElement("div"), this.shadowEl.className = "wt-fill-shadow", this.shadowEl.style.display = "none", e.appendChild(this.shadowEl), this.handleEl.addEventListener("mousedown", this.onMouseDown);
|
|
1335
|
+
}
|
|
1336
|
+
updatePosition() {
|
|
1337
|
+
const e = this.selection.getBounds();
|
|
1338
|
+
if (!this.enabled || !e || !this.getCellBounds) {
|
|
1339
|
+
this.handleEl.style.display = "none";
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
const t = this.getCellBounds(e.r2, e.c2);
|
|
1343
|
+
this.handleEl.style.display = "", this.handleEl.style.left = `${t.x + t.width - 4}px`, this.handleEl.style.top = `${t.y + t.height - 4}px`;
|
|
1344
|
+
}
|
|
1345
|
+
updateShadow() {
|
|
1346
|
+
const e = this.selection.getBounds();
|
|
1347
|
+
if (!e || !this.getCellBounds) {
|
|
1348
|
+
this.shadowEl.style.display = "none";
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
const { r1: t, c1: s, r2: i, c2: o } = e, l = this.currentRow, r = this.currentCol;
|
|
1352
|
+
if (l >= t && l <= i && r >= s && r <= o) {
|
|
1353
|
+
this.shadowEl.style.display = "none", this.updatePosition();
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
const c = Math.min(t, l), h = Math.max(i, l), d = Math.min(s, r), a = Math.max(o, r), g = this.getCellBounds(c, d), p = this.getCellBounds(h, a), w = g.x, C = g.y, E = p.x + p.width - w, b = p.y + p.height - C;
|
|
1357
|
+
this.shadowEl.style.display = "", this.shadowEl.style.left = `${w}px`, this.shadowEl.style.top = `${C}px`, this.shadowEl.style.width = `${E}px`, this.shadowEl.style.height = `${b}px`;
|
|
1358
|
+
const v = this.getCellBounds(l, r);
|
|
1359
|
+
this.handleEl.style.left = `${v.x + v.width - 4}px`, this.handleEl.style.top = `${v.y + v.height - 4}px`;
|
|
1360
|
+
}
|
|
1361
|
+
executeFill() {
|
|
1362
|
+
var w, C;
|
|
1363
|
+
const e = this.selection.getBounds();
|
|
1364
|
+
if (!e) return;
|
|
1365
|
+
const { r1: t, c1: s, r2: i, c2: o } = e, l = this.currentRow, r = this.currentCol;
|
|
1366
|
+
if (l >= t && l <= i && r >= s && r <= o) return;
|
|
1367
|
+
const c = l > i ? l - i : l < t ? t - l : 0, h = r > o ? r - o : r < s ? s - r : 0;
|
|
1368
|
+
let d, a;
|
|
1369
|
+
c > 0 && h > 0 ? (d = "diagonal", a = {
|
|
1370
|
+
startRow: Math.min(t, l),
|
|
1371
|
+
startCol: Math.min(s, r),
|
|
1372
|
+
endRow: Math.max(i, l),
|
|
1373
|
+
endCol: Math.max(o, r)
|
|
1374
|
+
}) : c > 0 && h === 0 ? l > i ? (d = "down", a = { startRow: i + 1, startCol: s, endRow: l, endCol: o }) : (d = "up", a = { startRow: l, startCol: s, endRow: t - 1, endCol: o }) : h > 0 && c === 0 ? r > o ? (d = "right", a = { startRow: t, startCol: o + 1, endRow: i, endCol: r }) : (d = "left", a = { startRow: t, startCol: r, endRow: i, endCol: s - 1 }) : (d = "diagonal", a = {
|
|
1375
|
+
startRow: Math.min(t, l),
|
|
1376
|
+
startCol: Math.min(s, r),
|
|
1377
|
+
endRow: Math.max(i, l),
|
|
1378
|
+
endCol: Math.max(o, r)
|
|
1379
|
+
});
|
|
1380
|
+
const g = { startRow: t, startCol: s, endRow: i, endCol: o };
|
|
1381
|
+
if (this.onFillCallback) {
|
|
1382
|
+
const E = this.onFillCallback(g, a, d);
|
|
1383
|
+
if (E === !0) return;
|
|
1384
|
+
if (Array.isArray(E)) {
|
|
1385
|
+
(w = this.onFill) == null || w.call(this, E, g, a, d);
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
const p = this.defaultFill(g, a, d);
|
|
1390
|
+
(C = this.onFill) == null || C.call(this, p, g, a, d);
|
|
1391
|
+
}
|
|
1392
|
+
defaultFill(e, t, s) {
|
|
1393
|
+
const i = [], o = e.endRow - e.startRow + 1, l = e.endCol - e.startCol + 1;
|
|
1394
|
+
for (let r = t.startRow; r <= t.endRow; r++)
|
|
1395
|
+
for (let c = t.startCol; c <= t.endCol; c++) {
|
|
1396
|
+
if (r >= e.startRow && r <= e.endRow && c >= e.startCol && c <= e.endCol)
|
|
1397
|
+
continue;
|
|
1398
|
+
const h = e.startRow + ((r - e.startRow) % o + o) % o, d = e.startCol + ((c - e.startCol) % l + l) % l, a = this.data.getCell(h, d);
|
|
1399
|
+
i.push({
|
|
1400
|
+
row: r,
|
|
1401
|
+
col: c,
|
|
1402
|
+
data: { value: a == null ? void 0 : a.value }
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
return i;
|
|
1406
|
+
}
|
|
1407
|
+
destroy() {
|
|
1408
|
+
this.handleEl.remove(), this.shadowEl.remove(), document.removeEventListener("mousemove", this.onMouseMove), document.removeEventListener("mouseup", this.onMouseUp);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
class vt {
|
|
1412
|
+
constructor(e) {
|
|
1413
|
+
n(this, "columns");
|
|
1414
|
+
n(this, "dragging", !1);
|
|
1415
|
+
n(this, "sourceCol", -1);
|
|
1416
|
+
n(this, "targetCol", -1);
|
|
1417
|
+
n(this, "ghostEl", null);
|
|
1418
|
+
n(this, "indicatorEl", null);
|
|
1419
|
+
n(this, "onReorder", null);
|
|
1420
|
+
/** Resolve column index from screen X */
|
|
1421
|
+
n(this, "getColAtX", null);
|
|
1422
|
+
/** Get column header label */
|
|
1423
|
+
n(this, "getColLabel", null);
|
|
1424
|
+
n(this, "onMouseMove", (e) => {
|
|
1425
|
+
if (this.dragging && (this.ghostEl && (this.ghostEl.style.left = `${e.clientX}px`, this.ghostEl.style.top = `${e.clientY - 14}px`), this.getColAtX && (this.targetCol = this.getColAtX(e.clientX)), this.indicatorEl && this.targetCol >= 0)) {
|
|
1426
|
+
const t = this.columns.getX(this.targetCol);
|
|
1427
|
+
this.indicatorEl.style.display = "", this.indicatorEl.style.left = `${t}px`;
|
|
1428
|
+
}
|
|
1429
|
+
});
|
|
1430
|
+
n(this, "onMouseUp", () => {
|
|
1431
|
+
var e, t, s;
|
|
1432
|
+
this.dragging && (this.dragging = !1, document.removeEventListener("mousemove", this.onMouseMove), document.removeEventListener("mouseup", this.onMouseUp), document.body.style.cursor = "", document.body.style.userSelect = "", (e = this.ghostEl) == null || e.remove(), this.ghostEl = null, (t = this.indicatorEl) == null || t.remove(), this.indicatorEl = null, this.sourceCol !== this.targetCol && this.targetCol >= 0 && ((s = this.onReorder) == null || s.call(this, this.sourceCol, this.targetCol)));
|
|
1433
|
+
});
|
|
1434
|
+
this.columns = e;
|
|
1435
|
+
}
|
|
1436
|
+
start(e, t, s) {
|
|
1437
|
+
var i;
|
|
1438
|
+
this.dragging = !0, this.sourceCol = e, this.targetCol = e, this.ghostEl = document.createElement("div"), this.ghostEl.className = "wt-reorder-ghost", this.ghostEl.textContent = ((i = this.getColLabel) == null ? void 0 : i.call(this, e)) ?? String(e), this.ghostEl.style.left = `${t.clientX}px`, this.ghostEl.style.top = `${t.clientY - 14}px`, document.body.appendChild(this.ghostEl), this.indicatorEl = document.createElement("div"), this.indicatorEl.className = "wt-reorder-indicator", this.indicatorEl.style.display = "none", s.appendChild(this.indicatorEl), document.addEventListener("mousemove", this.onMouseMove), document.addEventListener("mouseup", this.onMouseUp), document.body.style.cursor = "grabbing", document.body.style.userSelect = "none";
|
|
1439
|
+
}
|
|
1440
|
+
destroy() {
|
|
1441
|
+
var e, t;
|
|
1442
|
+
(e = this.ghostEl) == null || e.remove(), (t = this.indicatorEl) == null || t.remove(), document.removeEventListener("mousemove", this.onMouseMove), document.removeEventListener("mouseup", this.onMouseUp);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
class Et {
|
|
1446
|
+
constructor(e) {
|
|
1447
|
+
n(this, "groups", []);
|
|
1448
|
+
n(this, "hiddenRows", /* @__PURE__ */ new Set());
|
|
1449
|
+
n(this, "onChange", null);
|
|
1450
|
+
e && (this.groups = e.map((t) => ({ ...t })), this.rebuildHidden());
|
|
1451
|
+
}
|
|
1452
|
+
addGroup(e) {
|
|
1453
|
+
var t;
|
|
1454
|
+
this.groups.push({ ...e }), this.rebuildHidden(), (t = this.onChange) == null || t.call(this);
|
|
1455
|
+
}
|
|
1456
|
+
removeGroup(e) {
|
|
1457
|
+
var t;
|
|
1458
|
+
this.groups = this.groups.filter((s) => s.startRow !== e), this.rebuildHidden(), (t = this.onChange) == null || t.call(this);
|
|
1459
|
+
}
|
|
1460
|
+
toggleGroup(e) {
|
|
1461
|
+
var s;
|
|
1462
|
+
const t = this.groups.find((i) => i.startRow === e);
|
|
1463
|
+
t && (t.expanded = !t.expanded, this.rebuildHidden(), (s = this.onChange) == null || s.call(this));
|
|
1464
|
+
}
|
|
1465
|
+
expandAll() {
|
|
1466
|
+
var e;
|
|
1467
|
+
for (const t of this.groups) t.expanded = !0;
|
|
1468
|
+
this.rebuildHidden(), (e = this.onChange) == null || e.call(this);
|
|
1469
|
+
}
|
|
1470
|
+
collapseAll() {
|
|
1471
|
+
var e;
|
|
1472
|
+
for (const t of this.groups) t.expanded = !1;
|
|
1473
|
+
this.rebuildHidden(), (e = this.onChange) == null || e.call(this);
|
|
1474
|
+
}
|
|
1475
|
+
isGroupHeader(e) {
|
|
1476
|
+
return this.groups.find((t) => t.startRow === e) ?? null;
|
|
1477
|
+
}
|
|
1478
|
+
isHidden(e) {
|
|
1479
|
+
return this.hiddenRows.has(e);
|
|
1480
|
+
}
|
|
1481
|
+
getGroups() {
|
|
1482
|
+
return [...this.groups];
|
|
1483
|
+
}
|
|
1484
|
+
/** Build the set of hidden rows based on collapsed groups */
|
|
1485
|
+
rebuildHidden() {
|
|
1486
|
+
this.hiddenRows.clear();
|
|
1487
|
+
for (const e of this.groups)
|
|
1488
|
+
if (!e.expanded)
|
|
1489
|
+
for (let t = 1; t <= e.count; t++)
|
|
1490
|
+
this.hiddenRows.add(e.startRow + t);
|
|
1491
|
+
}
|
|
1492
|
+
/** Get a filter function compatible with ViewMapping */
|
|
1493
|
+
getFilter() {
|
|
1494
|
+
return (e) => !this.hiddenRows.has(e);
|
|
1495
|
+
}
|
|
1496
|
+
clear() {
|
|
1497
|
+
var e;
|
|
1498
|
+
this.groups = [], this.hiddenRows.clear(), (e = this.onChange) == null || e.call(this);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
class bt {
|
|
1502
|
+
constructor(e) {
|
|
1503
|
+
/** visualIndex -> dataIndex */
|
|
1504
|
+
n(this, "mapping", []);
|
|
1505
|
+
n(this, "identity", !0);
|
|
1506
|
+
n(this, "sortState", null);
|
|
1507
|
+
n(this, "filters", /* @__PURE__ */ new Map());
|
|
1508
|
+
n(this, "data");
|
|
1509
|
+
n(this, "onChange", null);
|
|
1510
|
+
this.data = e, this.rebuild();
|
|
1511
|
+
}
|
|
1512
|
+
/** Total visible row count after filtering */
|
|
1513
|
+
get visibleRowCount() {
|
|
1514
|
+
return this.identity ? this.data.rowCount : this.mapping.length;
|
|
1515
|
+
}
|
|
1516
|
+
/** Translate visual row to data row */
|
|
1517
|
+
toDataRow(e) {
|
|
1518
|
+
return this.identity ? e : this.mapping[e] ?? e;
|
|
1519
|
+
}
|
|
1520
|
+
/** Translate data row to visual row (or -1 if filtered out) */
|
|
1521
|
+
toVisualRow(e) {
|
|
1522
|
+
return this.identity ? e : this.mapping.indexOf(e);
|
|
1523
|
+
}
|
|
1524
|
+
// ── Sorting ──
|
|
1525
|
+
sort(e, t, s) {
|
|
1526
|
+
var i;
|
|
1527
|
+
t === null ? this.sortState = null : this.sortState = { col: e, direction: t, compareFn: s }, this.rebuild(), (i = this.onChange) == null || i.call(this);
|
|
1528
|
+
}
|
|
1529
|
+
getSortState() {
|
|
1530
|
+
return this.sortState;
|
|
1531
|
+
}
|
|
1532
|
+
clearSort() {
|
|
1533
|
+
var e;
|
|
1534
|
+
this.sortState = null, this.rebuild(), (e = this.onChange) == null || e.call(this);
|
|
1535
|
+
}
|
|
1536
|
+
// ── Filtering ──
|
|
1537
|
+
setFilter(e, t) {
|
|
1538
|
+
var s;
|
|
1539
|
+
this.filters.set(e, t), this.rebuild(), (s = this.onChange) == null || s.call(this);
|
|
1540
|
+
}
|
|
1541
|
+
removeFilter(e) {
|
|
1542
|
+
var t;
|
|
1543
|
+
this.filters.delete(e), this.rebuild(), (t = this.onChange) == null || t.call(this);
|
|
1544
|
+
}
|
|
1545
|
+
clearFilters() {
|
|
1546
|
+
var e;
|
|
1547
|
+
this.filters.clear(), this.rebuild(), (e = this.onChange) == null || e.call(this);
|
|
1548
|
+
}
|
|
1549
|
+
getActiveFilters() {
|
|
1550
|
+
return Array.from(this.filters.keys());
|
|
1551
|
+
}
|
|
1552
|
+
// ── Rebuild ──
|
|
1553
|
+
rebuild() {
|
|
1554
|
+
const e = this.sortState !== null, t = this.filters.size > 0;
|
|
1555
|
+
if (!e && !t) {
|
|
1556
|
+
this.identity = !0, this.mapping = [];
|
|
1557
|
+
return;
|
|
1558
|
+
}
|
|
1559
|
+
this.identity = !1;
|
|
1560
|
+
let s = [];
|
|
1561
|
+
for (let i = 0; i < this.data.rowCount; i++)
|
|
1562
|
+
s.push(i);
|
|
1563
|
+
if (t && (s = s.filter((i) => {
|
|
1564
|
+
for (const o of this.filters.values())
|
|
1565
|
+
if (!o(i, this.data)) return !1;
|
|
1566
|
+
return !0;
|
|
1567
|
+
})), e && this.sortState) {
|
|
1568
|
+
const { col: i, direction: o, compareFn: l } = this.sortState, r = o === "desc" ? -1 : 1;
|
|
1569
|
+
s.sort((c, h) => {
|
|
1570
|
+
var g, p;
|
|
1571
|
+
const d = (g = this.data.getCell(c, i)) == null ? void 0 : g.value, a = (p = this.data.getCell(h, i)) == null ? void 0 : p.value;
|
|
1572
|
+
return l ? l(d, a) * r : xt(d, a) * r;
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1575
|
+
this.mapping = s;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
function xt(u, e) {
|
|
1579
|
+
return u == null && e == null ? 0 : u == null ? 1 : e == null ? -1 : typeof u == "number" && typeof e == "number" ? u - e : typeof u == "boolean" && typeof e == "boolean" ? u === e ? 0 : u ? -1 : 1 : String(u).localeCompare(String(e), void 0, { numeric: !0, sensitivity: "base" });
|
|
1580
|
+
}
|
|
1581
|
+
class Rt {
|
|
1582
|
+
constructor(e) {
|
|
1583
|
+
/** All active merges */
|
|
1584
|
+
n(this, "merges", []);
|
|
1585
|
+
/** Quick lookup: "row:col" -> merge that covers this cell */
|
|
1586
|
+
n(this, "coverMap", /* @__PURE__ */ new Map());
|
|
1587
|
+
n(this, "onChange", null);
|
|
1588
|
+
if (e)
|
|
1589
|
+
for (const t of e)
|
|
1590
|
+
this.addMerge(t, !1);
|
|
1591
|
+
}
|
|
1592
|
+
key(e, t) {
|
|
1593
|
+
return `${e}:${t}`;
|
|
1594
|
+
}
|
|
1595
|
+
/** Add a merge. The anchor is (row, col). */
|
|
1596
|
+
addMerge(e, t = !0) {
|
|
1597
|
+
var s;
|
|
1598
|
+
if (!(e.rowSpan < 1 || e.colSpan < 1) && !(e.rowSpan === 1 && e.colSpan === 1)) {
|
|
1599
|
+
for (let i = e.row; i < e.row + e.rowSpan; i++)
|
|
1600
|
+
for (let o = e.col; o < e.col + e.colSpan; o++)
|
|
1601
|
+
if (this.coverMap.has(this.key(i, o))) {
|
|
1602
|
+
const l = this.coverMap.get(this.key(i, o));
|
|
1603
|
+
this.removeMerge(l.row, l.col, !1);
|
|
1604
|
+
}
|
|
1605
|
+
this.merges.push(e);
|
|
1606
|
+
for (let i = e.row; i < e.row + e.rowSpan; i++)
|
|
1607
|
+
for (let o = e.col; o < e.col + e.colSpan; o++)
|
|
1608
|
+
this.coverMap.set(this.key(i, o), e);
|
|
1609
|
+
t && ((s = this.onChange) == null || s.call(this));
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
/** Remove the merge anchored at (row, col) */
|
|
1613
|
+
removeMerge(e, t, s = !0) {
|
|
1614
|
+
var l;
|
|
1615
|
+
const i = this.merges.findIndex((r) => r.row === e && r.col === t);
|
|
1616
|
+
if (i === -1) return !1;
|
|
1617
|
+
const o = this.merges[i];
|
|
1618
|
+
this.merges.splice(i, 1);
|
|
1619
|
+
for (let r = o.row; r < o.row + o.rowSpan; r++)
|
|
1620
|
+
for (let c = o.col; c < o.col + o.colSpan; c++)
|
|
1621
|
+
this.coverMap.delete(this.key(r, c));
|
|
1622
|
+
return s && ((l = this.onChange) == null || l.call(this)), !0;
|
|
1623
|
+
}
|
|
1624
|
+
/** Get the merge that covers (row, col), or null */
|
|
1625
|
+
getMerge(e, t) {
|
|
1626
|
+
return this.coverMap.get(this.key(e, t)) ?? null;
|
|
1627
|
+
}
|
|
1628
|
+
/** Is this cell the anchor (top-left) of a merge? */
|
|
1629
|
+
isAnchor(e, t) {
|
|
1630
|
+
const s = this.coverMap.get(this.key(e, t));
|
|
1631
|
+
return s !== void 0 && s.row === e && s.col === t;
|
|
1632
|
+
}
|
|
1633
|
+
/** Is this cell hidden by a merge (i.e. not the anchor)? */
|
|
1634
|
+
isHidden(e, t) {
|
|
1635
|
+
const s = this.coverMap.get(this.key(e, t));
|
|
1636
|
+
return s !== void 0 && (s.row !== e || s.col !== t);
|
|
1637
|
+
}
|
|
1638
|
+
/** Get all merges */
|
|
1639
|
+
getAll() {
|
|
1640
|
+
return [...this.merges];
|
|
1641
|
+
}
|
|
1642
|
+
/** Clear all merges */
|
|
1643
|
+
clear() {
|
|
1644
|
+
var e;
|
|
1645
|
+
this.merges.length = 0, this.coverMap.clear(), (e = this.onChange) == null || e.call(this);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
class St {
|
|
1649
|
+
constructor(e) {
|
|
1650
|
+
n(this, "_page");
|
|
1651
|
+
n(this, "_pageSize");
|
|
1652
|
+
n(this, "_totalRows");
|
|
1653
|
+
n(this, "enabled");
|
|
1654
|
+
n(this, "onChange", null);
|
|
1655
|
+
this.enabled = (e == null ? void 0 : e.enabled) ?? !1, this._pageSize = (e == null ? void 0 : e.pageSize) ?? 50, this._page = (e == null ? void 0 : e.page) ?? 0, this._totalRows = (e == null ? void 0 : e.totalRows) ?? 0;
|
|
1656
|
+
}
|
|
1657
|
+
get page() {
|
|
1658
|
+
return this._page;
|
|
1659
|
+
}
|
|
1660
|
+
get pageSize() {
|
|
1661
|
+
return this._pageSize;
|
|
1662
|
+
}
|
|
1663
|
+
get totalRows() {
|
|
1664
|
+
return this._totalRows;
|
|
1665
|
+
}
|
|
1666
|
+
get totalPages() {
|
|
1667
|
+
return this._totalRows === 0 ? 0 : Math.ceil(this._totalRows / this._pageSize);
|
|
1668
|
+
}
|
|
1669
|
+
get startRow() {
|
|
1670
|
+
return this._page * this._pageSize;
|
|
1671
|
+
}
|
|
1672
|
+
get endRow() {
|
|
1673
|
+
return Math.min(this.startRow + this._pageSize, this._totalRows);
|
|
1674
|
+
}
|
|
1675
|
+
getState() {
|
|
1676
|
+
return {
|
|
1677
|
+
page: this._page,
|
|
1678
|
+
pageSize: this._pageSize,
|
|
1679
|
+
totalRows: this._totalRows,
|
|
1680
|
+
totalPages: this.totalPages,
|
|
1681
|
+
startRow: this.startRow,
|
|
1682
|
+
endRow: this.endRow
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
setPage(e) {
|
|
1686
|
+
var s;
|
|
1687
|
+
const t = Math.max(0, Math.min(e, this.totalPages - 1));
|
|
1688
|
+
t !== this._page && (this._page = t, (s = this.onChange) == null || s.call(this, this.getState()));
|
|
1689
|
+
}
|
|
1690
|
+
setPageSize(e) {
|
|
1691
|
+
var t;
|
|
1692
|
+
this._pageSize = Math.max(1, e), this._page = Math.min(this._page, this.totalPages - 1), this._page < 0 && (this._page = 0), (t = this.onChange) == null || t.call(this, this.getState());
|
|
1693
|
+
}
|
|
1694
|
+
setTotalRows(e) {
|
|
1695
|
+
var t;
|
|
1696
|
+
this._totalRows = e, this._page >= this.totalPages && (this._page = Math.max(0, this.totalPages - 1)), (t = this.onChange) == null || t.call(this, this.getState());
|
|
1697
|
+
}
|
|
1698
|
+
nextPage() {
|
|
1699
|
+
this.setPage(this._page + 1);
|
|
1700
|
+
}
|
|
1701
|
+
prevPage() {
|
|
1702
|
+
this.setPage(this._page - 1);
|
|
1703
|
+
}
|
|
1704
|
+
firstPage() {
|
|
1705
|
+
this.setPage(0);
|
|
1706
|
+
}
|
|
1707
|
+
lastPage() {
|
|
1708
|
+
this.setPage(this.totalPages - 1);
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
function D(u) {
|
|
1712
|
+
const e = [], t = O(u), s = [];
|
|
1713
|
+
for (let i = 0; i < t; i++)
|
|
1714
|
+
s.push([]);
|
|
1715
|
+
return V(u, 0, e, s, t), { flatColumns: e, headerRows: s, maxDepth: t };
|
|
1716
|
+
}
|
|
1717
|
+
function O(u) {
|
|
1718
|
+
let e = 1;
|
|
1719
|
+
for (const t of u)
|
|
1720
|
+
t.children && t.children.length > 0 && (e = Math.max(e, 1 + O(t.children)));
|
|
1721
|
+
return e;
|
|
1722
|
+
}
|
|
1723
|
+
function V(u, e, t, s, i) {
|
|
1724
|
+
for (const o of u)
|
|
1725
|
+
if (o.children && o.children.length > 0) {
|
|
1726
|
+
const l = t.length;
|
|
1727
|
+
V(o.children, e + 1, t, s, i);
|
|
1728
|
+
const r = t.length - l;
|
|
1729
|
+
s[e].push({
|
|
1730
|
+
label: o.label ?? "",
|
|
1731
|
+
colSpan: r,
|
|
1732
|
+
rowSpan: 1,
|
|
1733
|
+
col: l,
|
|
1734
|
+
level: e,
|
|
1735
|
+
config: o
|
|
1736
|
+
});
|
|
1737
|
+
} else {
|
|
1738
|
+
const l = t.length;
|
|
1739
|
+
t.push(o);
|
|
1740
|
+
const r = i - e;
|
|
1741
|
+
s[e].push({
|
|
1742
|
+
label: o.label ?? "",
|
|
1743
|
+
colSpan: 1,
|
|
1744
|
+
rowSpan: r,
|
|
1745
|
+
col: l,
|
|
1746
|
+
level: e,
|
|
1747
|
+
config: o
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
class Mt {
|
|
1752
|
+
constructor(e) {
|
|
1753
|
+
n(this, "el");
|
|
1754
|
+
n(this, "infoEl");
|
|
1755
|
+
n(this, "prevBtn");
|
|
1756
|
+
n(this, "nextBtn");
|
|
1757
|
+
n(this, "firstBtn");
|
|
1758
|
+
n(this, "lastBtn");
|
|
1759
|
+
n(this, "pageInput");
|
|
1760
|
+
n(this, "clickHandler");
|
|
1761
|
+
n(this, "changeHandler");
|
|
1762
|
+
n(this, "onPageChange", null);
|
|
1763
|
+
this.el = document.createElement("div"), this.el.className = "wt-pagination", this.infoEl = document.createElement("span"), this.infoEl.className = "wt-pagination-info", this.firstBtn = this.createBtn("first", "«"), this.prevBtn = this.createBtn("prev", "‹"), this.pageInput = document.createElement("input"), this.pageInput.type = "number", this.pageInput.className = "wt-pagination-input", this.pageInput.min = "1", this.nextBtn = this.createBtn("next", "›"), this.lastBtn = this.createBtn("last", "»"), this.el.appendChild(this.infoEl), this.el.appendChild(this.firstBtn), this.el.appendChild(this.prevBtn), this.el.appendChild(this.pageInput), this.el.appendChild(this.nextBtn), this.el.appendChild(this.lastBtn), this.clickHandler = (t) => {
|
|
1764
|
+
var o, l, r, c;
|
|
1765
|
+
const s = t.target.closest(".wt-pagination-btn");
|
|
1766
|
+
if (!s) return;
|
|
1767
|
+
const i = s.dataset.action;
|
|
1768
|
+
i === "first" ? (o = this.onPageChange) == null || o.call(this, 0) : i === "prev" ? (l = this.onPageChange) == null || l.call(this, -1) : i === "next" ? (r = this.onPageChange) == null || r.call(this, -2) : i === "last" && ((c = this.onPageChange) == null || c.call(this, -3));
|
|
1769
|
+
}, this.el.addEventListener("click", this.clickHandler), this.changeHandler = () => {
|
|
1770
|
+
var s;
|
|
1771
|
+
const t = parseInt(this.pageInput.value, 10) - 1;
|
|
1772
|
+
isNaN(t) || (s = this.onPageChange) == null || s.call(this, t);
|
|
1773
|
+
}, this.pageInput.addEventListener("change", this.changeHandler), e.appendChild(this.el);
|
|
1774
|
+
}
|
|
1775
|
+
update(e) {
|
|
1776
|
+
this.infoEl.textContent = `${e.startRow + 1}-${e.endRow} of ${e.totalRows}`, this.pageInput.value = String(e.page + 1), this.pageInput.max = String(e.totalPages), this.prevBtn.disabled = e.page <= 0, this.firstBtn.disabled = e.page <= 0, this.nextBtn.disabled = e.page >= e.totalPages - 1, this.lastBtn.disabled = e.page >= e.totalPages - 1;
|
|
1777
|
+
}
|
|
1778
|
+
show() {
|
|
1779
|
+
this.el.style.display = "";
|
|
1780
|
+
}
|
|
1781
|
+
hide() {
|
|
1782
|
+
this.el.style.display = "none";
|
|
1783
|
+
}
|
|
1784
|
+
destroy() {
|
|
1785
|
+
this.el.removeEventListener("click", this.clickHandler), this.pageInput.removeEventListener("change", this.changeHandler), this.el.remove();
|
|
1786
|
+
}
|
|
1787
|
+
createBtn(e, t) {
|
|
1788
|
+
const s = document.createElement("button");
|
|
1789
|
+
return s.className = "wt-pagination-btn", s.dataset.action = e, s.textContent = t, s;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
class Ht {
|
|
1793
|
+
constructor(e) {
|
|
1794
|
+
n(this, "el");
|
|
1795
|
+
this.el = document.createElement("div"), this.el.className = "wt-loading-overlay", this.el.innerHTML = '<div class="wt-loading-spinner"></div>', this.el.style.display = "none", e.appendChild(this.el);
|
|
1796
|
+
}
|
|
1797
|
+
show() {
|
|
1798
|
+
this.el.style.display = "";
|
|
1799
|
+
}
|
|
1800
|
+
hide() {
|
|
1801
|
+
this.el.style.display = "none";
|
|
1802
|
+
}
|
|
1803
|
+
get isVisible() {
|
|
1804
|
+
return this.el.style.display !== "none";
|
|
1805
|
+
}
|
|
1806
|
+
destroy() {
|
|
1807
|
+
this.el.remove();
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
function kt(u, e, t = {}) {
|
|
1811
|
+
const {
|
|
1812
|
+
visibleOnly: s = !0,
|
|
1813
|
+
columns: i,
|
|
1814
|
+
includeHeaders: o = !0,
|
|
1815
|
+
headers: l
|
|
1816
|
+
} = t, r = i ?? Array.from({ length: u.colCount }, (d, a) => a), c = [];
|
|
1817
|
+
if (o) {
|
|
1818
|
+
const d = r.map((a, g) => {
|
|
1819
|
+
const p = (l == null ? void 0 : l[g]) ?? z(a);
|
|
1820
|
+
return W(p);
|
|
1821
|
+
});
|
|
1822
|
+
c.push(d.join(","));
|
|
1823
|
+
}
|
|
1824
|
+
const h = s ? e.visibleRowCount : u.rowCount;
|
|
1825
|
+
for (let d = 0; d < h; d++) {
|
|
1826
|
+
const a = s ? e.toDataRow(d) : d, g = r.map((p) => {
|
|
1827
|
+
const w = u.getCell(a, p), C = w == null ? void 0 : w.value;
|
|
1828
|
+
return W(C != null ? String(C) : "");
|
|
1829
|
+
});
|
|
1830
|
+
c.push(g.join(","));
|
|
1831
|
+
}
|
|
1832
|
+
return c.join(`
|
|
1833
|
+
`);
|
|
1834
|
+
}
|
|
1835
|
+
function Lt(u, e, t = {}) {
|
|
1836
|
+
const {
|
|
1837
|
+
visibleOnly: s = !0,
|
|
1838
|
+
columns: i,
|
|
1839
|
+
headers: o
|
|
1840
|
+
} = t, l = i ?? Array.from({ length: u.colCount }, (h, d) => d), r = s ? e.visibleRowCount : u.rowCount, c = [];
|
|
1841
|
+
for (let h = 0; h < r; h++) {
|
|
1842
|
+
const d = s ? e.toDataRow(h) : h, a = {};
|
|
1843
|
+
for (let g = 0; g < l.length; g++) {
|
|
1844
|
+
const p = l[g], w = (o == null ? void 0 : o[g]) ?? z(p), C = u.getCell(d, p);
|
|
1845
|
+
a[w] = (C == null ? void 0 : C.value) ?? null;
|
|
1846
|
+
}
|
|
1847
|
+
c.push(a);
|
|
1848
|
+
}
|
|
1849
|
+
return c;
|
|
1850
|
+
}
|
|
1851
|
+
function N(u, e, t) {
|
|
1852
|
+
const s = new Blob([u], { type: t }), i = URL.createObjectURL(s), o = document.createElement("a");
|
|
1853
|
+
o.href = i, o.download = e, o.click(), URL.revokeObjectURL(i);
|
|
1854
|
+
}
|
|
1855
|
+
function W(u) {
|
|
1856
|
+
return u.includes(",") || u.includes('"') || u.includes(`
|
|
1857
|
+
`) ? `"${u.replace(/"/g, '""')}"` : u;
|
|
1858
|
+
}
|
|
1859
|
+
class It extends q {
|
|
1860
|
+
constructor(t, s = {}) {
|
|
1861
|
+
var h, d;
|
|
1862
|
+
super();
|
|
1863
|
+
n(this, "data");
|
|
1864
|
+
n(this, "selection");
|
|
1865
|
+
n(this, "columns");
|
|
1866
|
+
n(this, "rows");
|
|
1867
|
+
n(this, "commands");
|
|
1868
|
+
n(this, "viewMapping");
|
|
1869
|
+
n(this, "merges");
|
|
1870
|
+
n(this, "pagination");
|
|
1871
|
+
n(this, "rowGroups");
|
|
1872
|
+
n(this, "renderer");
|
|
1873
|
+
n(this, "rendererRegistry");
|
|
1874
|
+
n(this, "editorManager");
|
|
1875
|
+
n(this, "keyboard");
|
|
1876
|
+
n(this, "clipboard");
|
|
1877
|
+
n(this, "columnResize");
|
|
1878
|
+
n(this, "rowResize");
|
|
1879
|
+
n(this, "contextMenu");
|
|
1880
|
+
n(this, "autoFit");
|
|
1881
|
+
n(this, "paginationBar", null);
|
|
1882
|
+
n(this, "loadingOverlay");
|
|
1883
|
+
n(this, "fillHandle");
|
|
1884
|
+
n(this, "columnReorder");
|
|
1885
|
+
n(this, "headerRows", []);
|
|
1886
|
+
n(this, "theme");
|
|
1887
|
+
n(this, "options");
|
|
1888
|
+
// Drag selection state
|
|
1889
|
+
n(this, "isDragging", !1);
|
|
1890
|
+
n(this, "_infiniteScrollHandler", null);
|
|
1891
|
+
n(this, "_lazyLoadHandler", null);
|
|
1892
|
+
n(this, "_keydownHandler", null);
|
|
1893
|
+
// ── Context Menu ──
|
|
1894
|
+
/** Override this to customize context menu items */
|
|
1895
|
+
n(this, "contextMenuItems", [
|
|
1896
|
+
// ── Cell items ──
|
|
1897
|
+
{ label: "Copy", shortcut: "Ctrl+C", visible: (t) => t.target === "cell", action: () => this.clipboard.copy() },
|
|
1898
|
+
{
|
|
1899
|
+
label: "Paste",
|
|
1900
|
+
shortcut: "Ctrl+V",
|
|
1901
|
+
visible: (t) => t.target === "cell",
|
|
1902
|
+
disabled: (t) => t.readOnly,
|
|
1903
|
+
action: () => this.pasteWithUndo()
|
|
1904
|
+
},
|
|
1905
|
+
{
|
|
1906
|
+
label: "Cut",
|
|
1907
|
+
shortcut: "Ctrl+X",
|
|
1908
|
+
visible: (t) => t.target === "cell",
|
|
1909
|
+
disabled: (t) => t.readOnly,
|
|
1910
|
+
action: () => this.cutWithUndo()
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
label: "",
|
|
1914
|
+
separator: !0,
|
|
1915
|
+
visible: (t) => t.target === "cell"
|
|
1916
|
+
},
|
|
1917
|
+
{
|
|
1918
|
+
label: "Delete content",
|
|
1919
|
+
shortcut: "Del",
|
|
1920
|
+
visible: (t) => t.target === "cell" && t.selectedCount > 0,
|
|
1921
|
+
disabled: (t) => t.readOnly,
|
|
1922
|
+
action: () => this.deleteSelected()
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
label: "",
|
|
1926
|
+
separator: !0,
|
|
1927
|
+
visible: (t) => t.target === "cell"
|
|
1928
|
+
},
|
|
1929
|
+
{
|
|
1930
|
+
label: "Insert row above",
|
|
1931
|
+
visible: (t) => t.target === "cell" || t.target === "row-header",
|
|
1932
|
+
disabled: (t) => t.readOnly,
|
|
1933
|
+
action: (t) => this.insertRow(t.row)
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
label: "Insert row below",
|
|
1937
|
+
visible: (t) => t.target === "cell" || t.target === "row-header",
|
|
1938
|
+
disabled: (t) => t.readOnly,
|
|
1939
|
+
action: (t) => this.insertRow(t.row + 1)
|
|
1940
|
+
},
|
|
1941
|
+
{
|
|
1942
|
+
label: "Insert column left",
|
|
1943
|
+
visible: (t) => t.target === "cell" && !t.isMultiSelect || t.target === "column-header",
|
|
1944
|
+
disabled: (t) => t.readOnly,
|
|
1945
|
+
action: (t) => this.insertColumn(t.col)
|
|
1946
|
+
},
|
|
1947
|
+
{
|
|
1948
|
+
label: "Insert column right",
|
|
1949
|
+
visible: (t) => t.target === "cell" && !t.isMultiSelect || t.target === "column-header",
|
|
1950
|
+
disabled: (t) => t.readOnly,
|
|
1951
|
+
action: (t) => this.insertColumn(t.col + 1)
|
|
1952
|
+
},
|
|
1953
|
+
// ── Column header items ──
|
|
1954
|
+
{
|
|
1955
|
+
label: "",
|
|
1956
|
+
separator: !0,
|
|
1957
|
+
visible: (t) => t.target === "column-header"
|
|
1958
|
+
},
|
|
1959
|
+
{
|
|
1960
|
+
label: "Sort ascending",
|
|
1961
|
+
visible: (t) => t.target === "column-header",
|
|
1962
|
+
action: (t) => this.sort(t.col, "asc")
|
|
1963
|
+
},
|
|
1964
|
+
{
|
|
1965
|
+
label: "Sort descending",
|
|
1966
|
+
visible: (t) => t.target === "column-header",
|
|
1967
|
+
action: (t) => this.sort(t.col, "desc")
|
|
1968
|
+
},
|
|
1969
|
+
{
|
|
1970
|
+
label: "Clear sort",
|
|
1971
|
+
visible: (t) => t.target === "column-header" && this.viewMapping.getSortState() !== null,
|
|
1972
|
+
action: () => this.clearSort()
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
label: "",
|
|
1976
|
+
separator: !0,
|
|
1977
|
+
visible: (t) => t.target === "column-header"
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
label: "Auto-fit column width",
|
|
1981
|
+
visible: (t) => t.target === "column-header" || t.target === "cell",
|
|
1982
|
+
action: (t) => this.autoFitColumn(t.col >= 0 ? t.col : 0)
|
|
1983
|
+
},
|
|
1984
|
+
// ── Row header items ──
|
|
1985
|
+
{
|
|
1986
|
+
label: "",
|
|
1987
|
+
separator: !0,
|
|
1988
|
+
visible: (t) => t.target === "row-header"
|
|
1989
|
+
},
|
|
1990
|
+
{
|
|
1991
|
+
label: "Select row",
|
|
1992
|
+
visible: (t) => t.target === "row-header",
|
|
1993
|
+
action: (t) => this.selection.selectRow(t.row)
|
|
1994
|
+
},
|
|
1995
|
+
// ── Common items ──
|
|
1996
|
+
{ label: "", separator: !0 },
|
|
1997
|
+
{
|
|
1998
|
+
label: "Undo",
|
|
1999
|
+
shortcut: "Ctrl+Z",
|
|
2000
|
+
disabled: (t) => !t.canUndo,
|
|
2001
|
+
action: () => this.undo()
|
|
2002
|
+
},
|
|
2003
|
+
{
|
|
2004
|
+
label: "Redo",
|
|
2005
|
+
shortcut: "Ctrl+Y",
|
|
2006
|
+
disabled: (t) => !t.canRedo,
|
|
2007
|
+
action: () => this.redo()
|
|
2008
|
+
}
|
|
2009
|
+
]);
|
|
2010
|
+
this.options = s;
|
|
2011
|
+
const i = s.defaultRowHeight ?? 28, o = s.defaultColWidth ?? 100;
|
|
2012
|
+
let l = s.columns ?? [];
|
|
2013
|
+
if (l.some((a) => a.children && a.children.length > 0)) {
|
|
2014
|
+
const a = D(l);
|
|
2015
|
+
l = a.flatColumns, this.headerRows = a.headerRows;
|
|
2016
|
+
}
|
|
2017
|
+
const r = s.colCount ?? (l.length || 26);
|
|
2018
|
+
let c;
|
|
2019
|
+
if (s.mode === "table" && s.tableData ? c = s.tableData.length : c = s.rowCount ?? 100, this.theme = { ...K, ...s.theme }, this.data = new j(c, r), this.selection = new J(c, r), s.infinite && (this.selection.infinite = !0), this.columns = new P(r, o, l), this.rows = new tt(c, i), this.commands = new Z(s.undoLimit ?? 100), this.viewMapping = new bt(this.data), this.merges = new Rt(), this.pagination = new St(s.pagination), this.rowGroups = new Et(
|
|
2020
|
+
(h = s.rowGroups) == null ? void 0 : h.map((a) => ({
|
|
2021
|
+
...a,
|
|
2022
|
+
expanded: a.expanded ?? !0,
|
|
2023
|
+
depth: a.depth ?? 0
|
|
2024
|
+
}))
|
|
2025
|
+
), this.rendererRegistry = new ct(), this.renderer = new et(t), this.editorManager = new dt(this.renderer.getScrollContainer()), this.columnResize = new wt(this.columns), this.columnReorder = new vt(this.columns), this.rowResize = new mt(this.rows), this.contextMenu = new Ct(), this.clipboard = new ft(this.data, this.selection), this.fillHandle = new yt(
|
|
2026
|
+
this.renderer.getViewportEl(),
|
|
2027
|
+
this.data,
|
|
2028
|
+
this.selection,
|
|
2029
|
+
this.columns,
|
|
2030
|
+
this.rows
|
|
2031
|
+
), this.keyboard = new pt(this.selection, {
|
|
2032
|
+
onStartEdit: (a, g, p) => {
|
|
2033
|
+
this.options.allowEditing !== !1 && this.startEditing(a, g, p);
|
|
2034
|
+
},
|
|
2035
|
+
onDelete: () => this.deleteSelected(),
|
|
2036
|
+
onCopy: () => {
|
|
2037
|
+
this.options.allowClipboard !== !1 && this.clipboard.copy();
|
|
2038
|
+
},
|
|
2039
|
+
onPaste: () => {
|
|
2040
|
+
this.options.allowClipboard !== !1 && this.pasteWithUndo();
|
|
2041
|
+
},
|
|
2042
|
+
onCut: () => {
|
|
2043
|
+
this.options.allowClipboard !== !1 && this.cutWithUndo();
|
|
2044
|
+
},
|
|
2045
|
+
onUndo: () => {
|
|
2046
|
+
this.options.allowUndoRedo !== !1 && this.undo();
|
|
2047
|
+
},
|
|
2048
|
+
onRedo: () => {
|
|
2049
|
+
this.options.allowUndoRedo !== !1 && this.redo();
|
|
2050
|
+
},
|
|
2051
|
+
onScrollTo: (a, g) => this.renderer.scrollToCell(a, g)
|
|
2052
|
+
}), this.wireCallbacks(), this.renderer.init({
|
|
2053
|
+
data: this.data,
|
|
2054
|
+
columns: this.columns,
|
|
2055
|
+
rows: this.rows,
|
|
2056
|
+
selection: this.selection,
|
|
2057
|
+
viewMapping: this.viewMapping,
|
|
2058
|
+
merges: this.merges,
|
|
2059
|
+
theme: this.theme,
|
|
2060
|
+
renderers: this.rendererRegistry.getAll(),
|
|
2061
|
+
defaultRenderer: this.rendererRegistry.defaultRenderer,
|
|
2062
|
+
defaultCellType: s.defaultCellType ?? "text",
|
|
2063
|
+
showRowHeaders: s.showRowHeaders ?? !0,
|
|
2064
|
+
showColHeaders: s.showColHeaders ?? !0,
|
|
2065
|
+
frozenRows: s.frozenRows ?? 0,
|
|
2066
|
+
frozenCols: s.frozenCols ?? 0,
|
|
2067
|
+
autoRowHeight: s.autoRowHeight ?? !1,
|
|
2068
|
+
showGridLines: s.showGridLines ?? !0,
|
|
2069
|
+
showBorder: s.showBorder ?? !0,
|
|
2070
|
+
layout: s.layout ?? "scroll",
|
|
2071
|
+
headerRows: this.headerRows.length > 0 ? this.headerRows : void 0
|
|
2072
|
+
}), this.autoFit = new it(
|
|
2073
|
+
t,
|
|
2074
|
+
this.data,
|
|
2075
|
+
this.columns,
|
|
2076
|
+
this.rows,
|
|
2077
|
+
this.rendererRegistry.getAll(),
|
|
2078
|
+
this.rendererRegistry.defaultRenderer
|
|
2079
|
+
), this.fillHandle.getCellBounds = (a, g) => ({
|
|
2080
|
+
x: this.columns.getX(g),
|
|
2081
|
+
y: this.rows.getY(a),
|
|
2082
|
+
width: this.columns.getWidth(g),
|
|
2083
|
+
height: this.rows.getHeight(a)
|
|
2084
|
+
}), this.fillHandle.getCellAtPoint = (a, g) => {
|
|
2085
|
+
const p = this.renderer.getScrollContainer(), w = p.getBoundingClientRect(), C = p.scrollLeft, E = p.scrollTop, b = a - w.left + C, v = g - w.top + E, _ = this.rows.getRowAtY(v), T = this.columns.getColAtX(b);
|
|
2086
|
+
return _ >= 0 && T >= 0 ? { row: _, col: T } : null;
|
|
2087
|
+
}, this.fillHandle.enabled = s.allowFillHandle !== !1, this.fillHandle.onFillCallback = s.onFill ?? null, this.fillHandle.onFill = (a, g, p) => {
|
|
2088
|
+
if (a.length > 0) {
|
|
2089
|
+
const w = new F(this.data, a);
|
|
2090
|
+
this.execCommand(w), this.emit("data:patch", { patches: a });
|
|
2091
|
+
}
|
|
2092
|
+
this.selection.extendTo(p.endRow, p.endCol);
|
|
2093
|
+
}, this.loadingOverlay = new Ht(t), s.loading && this.loadingOverlay.show(), (d = s.pagination) != null && d.enabled && (this.paginationBar = new Mt(t), this.pagination.setTotalRows(s.pagination.totalRows ?? c), this.paginationBar.update(this.pagination.getState()), this.paginationBar.onPageChange = (a) => {
|
|
2094
|
+
a === -1 ? this.pagination.prevPage() : a === -2 ? this.pagination.nextPage() : a === -3 ? this.pagination.lastPage() : this.pagination.setPage(a);
|
|
2095
|
+
}, this.pagination.onChange = (a) => {
|
|
2096
|
+
var g, p, w;
|
|
2097
|
+
(g = this.paginationBar) == null || g.update(a), (w = (p = this.options).onPageChange) == null || w.call(p, a.page, a.pageSize), this.renderer.scheduleRender();
|
|
2098
|
+
}), s.mode === "table" && s.tableData ? this.loadTableData(s.tableData, l) : s.data && this.data.applyPatch(s.data), s.merges)
|
|
2099
|
+
for (const a of s.merges)
|
|
2100
|
+
this.merges.addMerge(a, !1);
|
|
2101
|
+
if (s.sort && this.viewMapping.sort(s.sort.col, s.sort.direction), s.filters)
|
|
2102
|
+
for (const [a, g] of Object.entries(s.filters))
|
|
2103
|
+
this.viewMapping.setFilter(Number(a), g);
|
|
2104
|
+
if (this.merges.onChange = () => {
|
|
2105
|
+
this.renderer.scheduleRender();
|
|
2106
|
+
}, this.viewMapping.onChange = () => {
|
|
2107
|
+
this.renderer.updateLayout(), this.renderer.scheduleRender();
|
|
2108
|
+
}, s.infinite)
|
|
2109
|
+
if (s.layout === "auto")
|
|
2110
|
+
this._infiniteScrollHandler = () => {
|
|
2111
|
+
let p = !1;
|
|
2112
|
+
const w = document.documentElement.scrollHeight, C = document.documentElement.scrollWidth, E = window.scrollY + window.innerHeight, b = window.scrollX + window.innerWidth;
|
|
2113
|
+
w - E < 200 && (this.data.rowCount += 20, this.rows.setCount(this.data.rowCount), this.viewMapping.rebuild(), p = !0), C - b < 200 && (this.data.colCount += 20, this.columns.setCount(this.data.colCount), p = !0), p && (this.selection.setDimensions(this.data.rowCount, this.data.colCount), this.refresh());
|
|
2114
|
+
}, window.addEventListener("scroll", this._infiniteScrollHandler, { passive: !0 });
|
|
2115
|
+
else {
|
|
2116
|
+
const p = this.renderer.getScrollContainer();
|
|
2117
|
+
this._infiniteScrollHandler = () => {
|
|
2118
|
+
p.scrollTop + p.clientHeight >= p.scrollHeight - 200 && (this.data.rowCount += 20, this.rows.setCount(this.data.rowCount), this.selection.setDimensions(this.data.rowCount, this.data.colCount), this.viewMapping.rebuild(), this.refresh()), p.scrollLeft + p.clientWidth >= p.scrollWidth - 200 && (this.data.colCount += 20, this.columns.setCount(this.data.colCount), this.selection.setDimensions(this.data.rowCount, this.data.colCount), this.refresh());
|
|
2119
|
+
}, p.addEventListener("scroll", this._infiniteScrollHandler, { passive: !0 });
|
|
2120
|
+
}
|
|
2121
|
+
this.renderer.getContainer().focus();
|
|
2122
|
+
}
|
|
2123
|
+
wireCallbacks() {
|
|
2124
|
+
if (this.data.onChange = () => {
|
|
2125
|
+
this.renderer.scheduleRender();
|
|
2126
|
+
}, this.selection.onChange = () => {
|
|
2127
|
+
var t, s;
|
|
2128
|
+
this.options.infinite && this.selection.focus && this.expandIfNeeded(this.selection.focus.row, this.selection.focus.col), this.renderer.scheduleRender(), this.fillHandle.updatePosition(), this.emit("selection:change", { ranges: this.selection.ranges }), (s = (t = this.options).onSelectionChange) == null || s.call(t, this.selection.ranges);
|
|
2129
|
+
}, this.renderer.onCellClick = (t, s, i) => {
|
|
2130
|
+
this.contextMenu.isOpen && this.contextMenu.close(), this.editorManager.isEditing && this.editorManager.close(!0);
|
|
2131
|
+
const o = this.data.getCell(t, s), l = this.columns.getConfig(s), r = this.options.defaultCellType ?? "text";
|
|
2132
|
+
if (((o == null ? void 0 : o.type) ?? (l == null ? void 0 : l.type) ?? r) === "checkbox" && !this.options.readOnly && this.options.allowEditing !== !1 && !(l != null && l.readOnly) && !(o != null && o.readOnly)) {
|
|
2133
|
+
const h = !!(o != null && o.value);
|
|
2134
|
+
this.setCellValue(t, s, !h), this.options.allowSelection !== !1 && this.selection.focusCell(t, s), this.emit("cell:click", { row: t, col: s, event: i });
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (this.options.allowSelection !== !1 && (i.shiftKey && this.options.allowRangeSelection !== !1 ? this.selection.extendTo(t, s) : (i.ctrlKey || i.metaKey) && this.options.allowRangeSelection !== !1 ? this.selection.addRange({ startRow: t, startCol: s, endRow: t, endCol: s }) : this.selection.focusCell(t, s)), this.emit("cell:click", { row: t, col: s, event: i }), this.options.allowRangeSelection !== !1 && this.options.allowSelection !== !1) {
|
|
2138
|
+
this.isDragging = !0;
|
|
2139
|
+
const h = (a) => {
|
|
2140
|
+
if (!this.isDragging) return;
|
|
2141
|
+
const g = this.renderer.getCellFromEvent(a);
|
|
2142
|
+
g && this.selection.extendTo(g.row, g.col);
|
|
2143
|
+
}, d = () => {
|
|
2144
|
+
this.isDragging = !1, document.removeEventListener("mousemove", h), document.removeEventListener("mouseup", d);
|
|
2145
|
+
};
|
|
2146
|
+
document.addEventListener("mousemove", h), document.addEventListener("mouseup", d);
|
|
2147
|
+
}
|
|
2148
|
+
}, this.renderer.onCellDblClick = (t, s, i) => {
|
|
2149
|
+
this.emit("cell:dblclick", { row: t, col: s, event: i }), !this.options.readOnly && this.options.allowEditing !== !1 && this.startEditing(t, s);
|
|
2150
|
+
}, this.renderer.onCellContextMenu = (t, s, i) => {
|
|
2151
|
+
i.preventDefault(), this.emit("cell:contextmenu", { row: t, col: s, event: i }), this.options.allowContextMenu !== !1 && (this.options.allowSelection !== !1 && !this.selection.isSelected(t, s) && this.selection.focusCell(t, s), this.openContextMenu(i.clientX, i.clientY, t, s));
|
|
2152
|
+
}, this.renderer.onHeaderClick = (t, s, i) => {
|
|
2153
|
+
if (t === "col")
|
|
2154
|
+
this.options.allowColReorder ? this.columnReorder.start(s, i, this.renderer.getContainer()) : this.selection.selectColumn(s);
|
|
2155
|
+
else if (t === "row") {
|
|
2156
|
+
const o = i.target.closest(".wt-row-header-cell");
|
|
2157
|
+
if (o) {
|
|
2158
|
+
const l = o.getBoundingClientRect();
|
|
2159
|
+
if (i.clientY > l.bottom - 4 && this.options.allowRowResize !== !1) {
|
|
2160
|
+
this.rowResize.start(s, i.clientY);
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
this.selection.selectRow(s);
|
|
2165
|
+
} else t === "corner" && this.selection.selectAll();
|
|
2166
|
+
}, this.renderer.onColumnResizeStart = (t, s) => {
|
|
2167
|
+
this.options.allowColResize !== !1 && this.columnResize.start(t, s);
|
|
2168
|
+
}, this.columnResize.onResize = (t, s) => {
|
|
2169
|
+
this.renderer.updateLayout(), this.renderer.scheduleRender(), this.emit("column:resize", { col: t, width: s });
|
|
2170
|
+
}, this.rowResize.onResize = (t, s) => {
|
|
2171
|
+
this.renderer.updateLayout(), this.renderer.scheduleRender(), this.emit("row:resize", { row: t, height: s });
|
|
2172
|
+
}, this.renderer.onScroll = (t) => {
|
|
2173
|
+
var s, i;
|
|
2174
|
+
this.emit("scroll", { viewport: t }), (i = (s = this.options).onScroll) == null || i.call(s, t);
|
|
2175
|
+
}, this.editorManager.onClose = (t, s, i, o) => {
|
|
2176
|
+
var l, r, c;
|
|
2177
|
+
if (!o && i !== void 0) {
|
|
2178
|
+
const h = (l = this.data.getCell(t, s)) == null ? void 0 : l.value, d = new $(this.data, t, s, i);
|
|
2179
|
+
this.execCommand(d), this.emit("cell:change", { row: t, col: s, oldValue: h, newValue: i }), (c = (r = this.options).onCellChange) == null || c.call(r, t, s, h, i);
|
|
2180
|
+
}
|
|
2181
|
+
this.emit("editor:close", { row: t, col: s, value: i, cancelled: o }), this.renderer.getContainer().focus();
|
|
2182
|
+
}, this._keydownHandler = (t) => {
|
|
2183
|
+
this.options.allowKeyboardNav !== !1 && (this.editorManager.isEditing || this.keyboard.handleKeyDown(t));
|
|
2184
|
+
}, this.renderer.getContainer().addEventListener("keydown", this._keydownHandler), this.renderer.onHeaderContextMenu = (t, s, i) => {
|
|
2185
|
+
const o = t === "col" ? "column-header" : "row-header", l = t === "row" ? s : -1, r = t === "col" ? s : -1, c = this.buildMenuContext(l, r, o);
|
|
2186
|
+
this.contextMenu.open(i.clientX, i.clientY, this.contextMenuItems, c);
|
|
2187
|
+
}, this.clipboard.onChange = (t) => {
|
|
2188
|
+
this.emit("data:patch", { patches: t });
|
|
2189
|
+
}, this.columnReorder.getColAtX = (t) => {
|
|
2190
|
+
const s = this.renderer.getScrollContainer(), i = s.getBoundingClientRect();
|
|
2191
|
+
return this.columns.getColAtX(t - i.left + s.scrollLeft);
|
|
2192
|
+
}, this.columnReorder.getColLabel = (t) => {
|
|
2193
|
+
var s;
|
|
2194
|
+
return ((s = this.columns.getConfig(t)) == null ? void 0 : s.label) ?? P.columnLabel(t);
|
|
2195
|
+
}, this.columnReorder.onReorder = (t, s) => {
|
|
2196
|
+
this.reorderColumn(t, s);
|
|
2197
|
+
}, this.rowGroups.onChange = () => {
|
|
2198
|
+
const t = this.rowGroups.getFilter();
|
|
2199
|
+
this.viewMapping.setFilter(-1, (s) => t(s));
|
|
2200
|
+
}, this.options.rowGroups && this.options.rowGroups.length > 0) {
|
|
2201
|
+
const t = this.rowGroups.getFilter();
|
|
2202
|
+
this.viewMapping.setFilter(-1, (s) => t(s));
|
|
2203
|
+
}
|
|
2204
|
+
if (this.options.onLoadMore) {
|
|
2205
|
+
const t = this.options.onLoadMore, s = 200;
|
|
2206
|
+
if (this.options.layout === "auto")
|
|
2207
|
+
this._lazyLoadHandler = () => {
|
|
2208
|
+
const i = document.documentElement.scrollHeight, o = window.scrollY + window.innerHeight;
|
|
2209
|
+
i - o < s && t("down");
|
|
2210
|
+
}, window.addEventListener("scroll", this._lazyLoadHandler, { passive: !0 });
|
|
2211
|
+
else {
|
|
2212
|
+
const i = this.renderer.getScrollContainer();
|
|
2213
|
+
this._lazyLoadHandler = () => {
|
|
2214
|
+
i.scrollTop + i.clientHeight >= i.scrollHeight - s && t("down"), i.scrollLeft + i.clientWidth >= i.scrollWidth - s && t("right");
|
|
2215
|
+
}, i.addEventListener("scroll", this._lazyLoadHandler, { passive: !0 });
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
buildMenuContext(t, s, i = "cell") {
|
|
2220
|
+
const o = this.selection.getBounds();
|
|
2221
|
+
let l = 0;
|
|
2222
|
+
return this.selection.forEachSelected(() => {
|
|
2223
|
+
l++;
|
|
2224
|
+
}), {
|
|
2225
|
+
target: i,
|
|
2226
|
+
row: t,
|
|
2227
|
+
col: s,
|
|
2228
|
+
selectedCount: l,
|
|
2229
|
+
isMultiSelect: l > 1,
|
|
2230
|
+
isFullRow: o ? o.c1 === 0 && o.c2 === this.data.colCount - 1 : !1,
|
|
2231
|
+
isFullCol: o ? o.r1 === 0 && o.r2 === this.data.rowCount - 1 : !1,
|
|
2232
|
+
readOnly: !!this.options.readOnly,
|
|
2233
|
+
canUndo: this.commands.canUndo,
|
|
2234
|
+
canRedo: this.commands.canRedo
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
openContextMenu(t, s, i, o) {
|
|
2238
|
+
const l = this.buildMenuContext(i, o);
|
|
2239
|
+
this.contextMenu.open(t, s, this.contextMenuItems, l);
|
|
2240
|
+
}
|
|
2241
|
+
// ── Public API ──
|
|
2242
|
+
setCell(t, s, i) {
|
|
2243
|
+
this.data.setCell(t, s, i);
|
|
2244
|
+
}
|
|
2245
|
+
getCell(t, s) {
|
|
2246
|
+
return this.data.getCell(t, s);
|
|
2247
|
+
}
|
|
2248
|
+
setCellValue(t, s, i) {
|
|
2249
|
+
var r;
|
|
2250
|
+
const o = (r = this.data.getCell(t, s)) == null ? void 0 : r.value, l = new $(this.data, t, s, i);
|
|
2251
|
+
this.execCommand(l), this.emit("cell:change", { row: t, col: s, oldValue: o, newValue: i });
|
|
2252
|
+
}
|
|
2253
|
+
deleteCell(t, s) {
|
|
2254
|
+
this.data.deleteCell(t, s);
|
|
2255
|
+
}
|
|
2256
|
+
applyPatch(t) {
|
|
2257
|
+
const s = new F(this.data, t);
|
|
2258
|
+
this.execCommand(s), this.emit("data:patch", { patches: t });
|
|
2259
|
+
}
|
|
2260
|
+
transaction(t) {
|
|
2261
|
+
this.data.transaction(t);
|
|
2262
|
+
}
|
|
2263
|
+
undo() {
|
|
2264
|
+
const t = this.commands.undo();
|
|
2265
|
+
if (t) {
|
|
2266
|
+
const s = t.getChanges().map((i) => ({
|
|
2267
|
+
row: i.row,
|
|
2268
|
+
col: i.col,
|
|
2269
|
+
oldValue: i.newValue,
|
|
2270
|
+
newValue: i.oldValue
|
|
2271
|
+
}));
|
|
2272
|
+
this.emit("command:undo", { changes: s });
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
redo() {
|
|
2276
|
+
const t = this.commands.redo();
|
|
2277
|
+
t && this.emit("command:redo", { changes: t.getChanges() });
|
|
2278
|
+
}
|
|
2279
|
+
getSelection() {
|
|
2280
|
+
return [...this.selection.ranges];
|
|
2281
|
+
}
|
|
2282
|
+
getSelectionInfo() {
|
|
2283
|
+
return this.selection.getInfo();
|
|
2284
|
+
}
|
|
2285
|
+
setSelection(t) {
|
|
2286
|
+
if (t.length > 0) {
|
|
2287
|
+
this.selection.focusCell(t[0].startRow, t[0].startCol);
|
|
2288
|
+
for (let s = 1; s < t.length; s++)
|
|
2289
|
+
this.selection.addRange(t[s]);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
scrollTo(t, s) {
|
|
2293
|
+
this.renderer.scrollToCell(t, s);
|
|
2294
|
+
}
|
|
2295
|
+
registerRenderer(t, s) {
|
|
2296
|
+
this.rendererRegistry.register(t, s);
|
|
2297
|
+
}
|
|
2298
|
+
registerEditor(t, s) {
|
|
2299
|
+
this.editorManager.register(t, s);
|
|
2300
|
+
}
|
|
2301
|
+
setColumnWidth(t, s) {
|
|
2302
|
+
this.columns.setWidth(t, s), this.renderer.updateLayout(), this.renderer.scheduleRender();
|
|
2303
|
+
}
|
|
2304
|
+
setRowHeight(t, s) {
|
|
2305
|
+
this.rows.setHeight(t, s), this.renderer.updateLayout(), this.renderer.scheduleRender();
|
|
2306
|
+
}
|
|
2307
|
+
autoFitColumn(t) {
|
|
2308
|
+
const s = this.autoFit.autoFitColumn(t);
|
|
2309
|
+
this.columns.setWidth(t, s), this.renderer.updateLayout(), this.renderer.scheduleRender(), this.emit("column:resize", { col: t, width: s });
|
|
2310
|
+
}
|
|
2311
|
+
autoFitRow(t) {
|
|
2312
|
+
const s = this.autoFit.autoFitRow(t);
|
|
2313
|
+
this.rows.setHeight(t, s), this.renderer.updateLayout(), this.renderer.scheduleRender(), this.emit("row:resize", { row: t, height: s });
|
|
2314
|
+
}
|
|
2315
|
+
insertRow(t) {
|
|
2316
|
+
this.data.rowCount += 1, this.rows.setCount(this.data.rowCount), this.selection.setDimensions(this.data.rowCount, this.data.colCount), this.data.transaction(() => {
|
|
2317
|
+
for (let s = this.data.rowCount - 1; s > t; s--)
|
|
2318
|
+
for (let i = 0; i < this.data.colCount; i++) {
|
|
2319
|
+
const o = this.data.getCell(s - 1, i);
|
|
2320
|
+
o ? this.data.setCell(s, i, { ...o }) : this.data.deleteCell(s, i);
|
|
2321
|
+
}
|
|
2322
|
+
for (let s = 0; s < this.data.colCount; s++)
|
|
2323
|
+
this.data.deleteCell(t, s);
|
|
2324
|
+
}), this.renderer.updateLayout(), this.renderer.scheduleRender();
|
|
2325
|
+
}
|
|
2326
|
+
insertColumn(t) {
|
|
2327
|
+
this.data.colCount += 1, this.columns.setCount(this.data.colCount), this.selection.setDimensions(this.data.rowCount, this.data.colCount), this.data.transaction(() => {
|
|
2328
|
+
for (let s = 0; s < this.data.rowCount; s++) {
|
|
2329
|
+
for (let i = this.data.colCount - 1; i > t; i--) {
|
|
2330
|
+
const o = this.data.getCell(s, i - 1);
|
|
2331
|
+
o ? this.data.setCell(s, i, { ...o }) : this.data.deleteCell(s, i);
|
|
2332
|
+
}
|
|
2333
|
+
this.data.deleteCell(s, t);
|
|
2334
|
+
}
|
|
2335
|
+
}), this.renderer.updateLayout(), this.renderer.scheduleRender();
|
|
2336
|
+
}
|
|
2337
|
+
// ── Sort & Filter ──
|
|
2338
|
+
sort(t, s, i) {
|
|
2339
|
+
var o;
|
|
2340
|
+
if (this.options.onSort) {
|
|
2341
|
+
const l = (o = this.columns.getConfig(t)) == null ? void 0 : o.key;
|
|
2342
|
+
if (this.options.onSort(t, s, l) === !0) return;
|
|
2343
|
+
}
|
|
2344
|
+
this.viewMapping.sort(t, s, i);
|
|
2345
|
+
}
|
|
2346
|
+
clearSort() {
|
|
2347
|
+
this.options.onSort && this.options.onSort(-1, null) === !0 || this.viewMapping.clearSort();
|
|
2348
|
+
}
|
|
2349
|
+
getSortState() {
|
|
2350
|
+
return this.viewMapping.getSortState();
|
|
2351
|
+
}
|
|
2352
|
+
setFilter(t, s) {
|
|
2353
|
+
var i;
|
|
2354
|
+
if (this.options.onFilter) {
|
|
2355
|
+
const o = (i = this.columns.getConfig(t)) == null ? void 0 : i.key;
|
|
2356
|
+
if (this.options.onFilter(t, o, !0) === !0) return;
|
|
2357
|
+
}
|
|
2358
|
+
this.viewMapping.setFilter(t, s);
|
|
2359
|
+
}
|
|
2360
|
+
removeFilter(t) {
|
|
2361
|
+
var s;
|
|
2362
|
+
if (this.options.onFilter) {
|
|
2363
|
+
const i = (s = this.columns.getConfig(t)) == null ? void 0 : s.key;
|
|
2364
|
+
if (this.options.onFilter(t, i, !1) === !0) return;
|
|
2365
|
+
}
|
|
2366
|
+
this.viewMapping.removeFilter(t);
|
|
2367
|
+
}
|
|
2368
|
+
clearFilters() {
|
|
2369
|
+
this.viewMapping.clearFilters();
|
|
2370
|
+
}
|
|
2371
|
+
getActiveFilters() {
|
|
2372
|
+
return this.viewMapping.getActiveFilters();
|
|
2373
|
+
}
|
|
2374
|
+
// ── Merge ──
|
|
2375
|
+
mergeCells(t, s, i, o) {
|
|
2376
|
+
this.merges.addMerge({ row: t, col: s, rowSpan: i, colSpan: o }), this.renderer.scheduleRender();
|
|
2377
|
+
}
|
|
2378
|
+
unmergeCells(t, s) {
|
|
2379
|
+
this.merges.removeMerge(t, s), this.renderer.scheduleRender();
|
|
2380
|
+
}
|
|
2381
|
+
getMerge(t, s) {
|
|
2382
|
+
return this.merges.getMerge(t, s);
|
|
2383
|
+
}
|
|
2384
|
+
clearMerges() {
|
|
2385
|
+
this.merges.clear(), this.renderer.scheduleRender();
|
|
2386
|
+
}
|
|
2387
|
+
// ── Row Groups ──
|
|
2388
|
+
addRowGroup(t, s, i, o = !0) {
|
|
2389
|
+
this.rowGroups.addGroup({ startRow: t, count: s, label: i, expanded: o, depth: 0 });
|
|
2390
|
+
}
|
|
2391
|
+
removeRowGroup(t) {
|
|
2392
|
+
this.rowGroups.removeGroup(t);
|
|
2393
|
+
}
|
|
2394
|
+
toggleRowGroup(t) {
|
|
2395
|
+
this.rowGroups.toggleGroup(t);
|
|
2396
|
+
}
|
|
2397
|
+
expandAllGroups() {
|
|
2398
|
+
this.rowGroups.expandAll();
|
|
2399
|
+
}
|
|
2400
|
+
collapseAllGroups() {
|
|
2401
|
+
this.rowGroups.collapseAll();
|
|
2402
|
+
}
|
|
2403
|
+
// ── Export ──
|
|
2404
|
+
exportCSV(t) {
|
|
2405
|
+
return kt(this.data, this.viewMapping, t);
|
|
2406
|
+
}
|
|
2407
|
+
exportJSON(t) {
|
|
2408
|
+
return Lt(this.data, this.viewMapping, t);
|
|
2409
|
+
}
|
|
2410
|
+
downloadCSV(t = "export.csv", s) {
|
|
2411
|
+
const i = this.exportCSV(s);
|
|
2412
|
+
N(i, t, "text/csv;charset=utf-8");
|
|
2413
|
+
}
|
|
2414
|
+
downloadJSON(t = "export.json", s) {
|
|
2415
|
+
const i = JSON.stringify(this.exportJSON(s), null, 2);
|
|
2416
|
+
N(i, t, "application/json");
|
|
2417
|
+
}
|
|
2418
|
+
getViewport() {
|
|
2419
|
+
return this.renderer.getViewport();
|
|
2420
|
+
}
|
|
2421
|
+
refresh() {
|
|
2422
|
+
this.renderer.updateLayout(), this.renderer.scheduleRender();
|
|
2423
|
+
}
|
|
2424
|
+
destroy() {
|
|
2425
|
+
var t;
|
|
2426
|
+
this._keydownHandler && this.renderer.getContainer().removeEventListener("keydown", this._keydownHandler), this._infiniteScrollHandler && (window.removeEventListener("scroll", this._infiniteScrollHandler), this.renderer.getScrollContainer().removeEventListener("scroll", this._infiniteScrollHandler)), this._lazyLoadHandler && (window.removeEventListener("scroll", this._lazyLoadHandler), this.renderer.getScrollContainer().removeEventListener("scroll", this._lazyLoadHandler)), this.fillHandle.destroy(), this.columnReorder.destroy(), this.editorManager.destroy(), this.columnResize.destroy(), this.rowResize.destroy(), this.contextMenu.destroy(), this.autoFit.destroy(), this.loadingOverlay.destroy(), (t = this.paginationBar) == null || t.destroy(), this.renderer.destroy(), this.removeAllListeners();
|
|
2427
|
+
}
|
|
2428
|
+
// ── Private ──
|
|
2429
|
+
startEditing(t, s, i) {
|
|
2430
|
+
if (this.options.readOnly) return;
|
|
2431
|
+
const o = this.columns.getConfig(s), l = this.data.getCell(t, s);
|
|
2432
|
+
if (o != null && o.readOnly || l != null && l.readOnly) return;
|
|
2433
|
+
const r = this.options.defaultCellType ?? "text", c = (l == null ? void 0 : l.type) ?? (o == null ? void 0 : o.type) ?? r, h = (o == null ? void 0 : o.editor) ?? c;
|
|
2434
|
+
if (h === "blank") {
|
|
2435
|
+
this.emit("editor:open", { row: t, col: s }), this.emit("editor:close", { row: t, col: s, value: void 0, cancelled: !0 });
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
const d = this.renderer.getCellBounds(t, s), a = l == null ? void 0 : l.value;
|
|
2439
|
+
this.emit("editor:open", { row: t, col: s }), this.editorManager.open(t, s, h, a, d, l, i);
|
|
2440
|
+
}
|
|
2441
|
+
deleteSelected() {
|
|
2442
|
+
if (this.options.readOnly) return;
|
|
2443
|
+
const t = [];
|
|
2444
|
+
if (this.selection.forEachSelected((s, i) => {
|
|
2445
|
+
this.data.hasCell(s, i) && t.push({ row: s, col: i });
|
|
2446
|
+
}), t.length > 0) {
|
|
2447
|
+
const s = new Q(this.data, t);
|
|
2448
|
+
this.execCommand(s);
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
async pasteWithUndo() {
|
|
2452
|
+
const t = this.selection.focus;
|
|
2453
|
+
if (!t) return;
|
|
2454
|
+
let s;
|
|
2455
|
+
try {
|
|
2456
|
+
s = await navigator.clipboard.readText();
|
|
2457
|
+
} catch {
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
const i = s.split(`
|
|
2461
|
+
`).map((r) => r.split(" "));
|
|
2462
|
+
if (i.length === 0) return;
|
|
2463
|
+
const o = i.length === 1 && i[0].length === 1, l = [];
|
|
2464
|
+
if (o && !this.isFullRowOrColSelected()) {
|
|
2465
|
+
const r = i[0][0];
|
|
2466
|
+
this.selection.forEachSelected((c, h) => {
|
|
2467
|
+
c < this.data.rowCount && h < this.data.colCount && l.push({ row: c, col: h, data: { value: r } });
|
|
2468
|
+
});
|
|
2469
|
+
} else
|
|
2470
|
+
for (let r = 0; r < i.length; r++)
|
|
2471
|
+
for (let c = 0; c < i[r].length; c++) {
|
|
2472
|
+
const h = t.row + r, d = t.col + c;
|
|
2473
|
+
h >= this.data.rowCount || d >= this.data.colCount || l.push({ row: h, col: d, data: { value: i[r][c] } });
|
|
2474
|
+
}
|
|
2475
|
+
if (l.length > 0) {
|
|
2476
|
+
const r = new F(this.data, l);
|
|
2477
|
+
this.execCommand(r), this.emit("data:patch", { patches: l });
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
async cutWithUndo() {
|
|
2481
|
+
await this.clipboard.copy(), this.deleteSelected();
|
|
2482
|
+
}
|
|
2483
|
+
execCommand(t) {
|
|
2484
|
+
this.commands.execute(t), this.emit("command:execute", { changes: t.getChanges() });
|
|
2485
|
+
}
|
|
2486
|
+
/** Move a column from one index to another, shifting data */
|
|
2487
|
+
reorderColumn(t, s) {
|
|
2488
|
+
if (t === s) return;
|
|
2489
|
+
this.data.transaction(() => {
|
|
2490
|
+
for (let l = 0; l < this.data.rowCount; l++) {
|
|
2491
|
+
const r = [];
|
|
2492
|
+
for (let h = 0; h < this.data.colCount; h++)
|
|
2493
|
+
r.push(this.data.getCell(l, h));
|
|
2494
|
+
const c = r.splice(t, 1)[0];
|
|
2495
|
+
r.splice(s, 0, c);
|
|
2496
|
+
for (let h = 0; h < r.length; h++)
|
|
2497
|
+
r[h] ? this.data.setCell(l, h, r[h]) : this.data.deleteCell(l, h);
|
|
2498
|
+
}
|
|
2499
|
+
});
|
|
2500
|
+
const i = [];
|
|
2501
|
+
for (let l = 0; l < this.columns.count; l++)
|
|
2502
|
+
i.push(this.columns.getWidth(l));
|
|
2503
|
+
const o = i.splice(t, 1)[0];
|
|
2504
|
+
i.splice(s, 0, o);
|
|
2505
|
+
for (let l = 0; l < i.length; l++)
|
|
2506
|
+
this.columns.setWidth(l, i[l]);
|
|
2507
|
+
this.refresh();
|
|
2508
|
+
}
|
|
2509
|
+
expandIfNeeded(t, s) {
|
|
2510
|
+
let i = !1;
|
|
2511
|
+
if (t >= this.data.rowCount) {
|
|
2512
|
+
const o = t + 2;
|
|
2513
|
+
this.data.rowCount = o, this.rows.setCount(o), this.viewMapping.rebuild(), i = !0;
|
|
2514
|
+
}
|
|
2515
|
+
if (s >= this.data.colCount) {
|
|
2516
|
+
const o = s + 2;
|
|
2517
|
+
this.data.colCount = o, this.columns.setCount(o), i = !0;
|
|
2518
|
+
}
|
|
2519
|
+
i && (this.selection.setDimensions(this.data.rowCount, this.data.colCount), this.refresh());
|
|
2520
|
+
}
|
|
2521
|
+
isFullRowOrColSelected() {
|
|
2522
|
+
const t = this.selection.getBounds();
|
|
2523
|
+
return t ? t.c1 === 0 && t.c2 === this.data.colCount - 1 || t.r1 === 0 && t.r2 === this.data.rowCount - 1 : !1;
|
|
2524
|
+
}
|
|
2525
|
+
/** Load row objects into the sparse DataModel using column keys */
|
|
2526
|
+
loadTableData(t, s) {
|
|
2527
|
+
const i = /* @__PURE__ */ new Map();
|
|
2528
|
+
s.forEach((o, l) => {
|
|
2529
|
+
o.key && i.set(o.key, l);
|
|
2530
|
+
}), this.data.transaction(() => {
|
|
2531
|
+
for (let o = 0; o < t.length; o++) {
|
|
2532
|
+
const l = t[o];
|
|
2533
|
+
for (const [r, c] of Object.entries(l)) {
|
|
2534
|
+
const h = i.get(r);
|
|
2535
|
+
h !== void 0 && this.data.setCell(o, h, { value: c });
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
// ── Table Mode API ──
|
|
2541
|
+
/** Replace all table data (table mode) */
|
|
2542
|
+
setTableData(t) {
|
|
2543
|
+
const s = this.options.columns ?? [];
|
|
2544
|
+
let i = s;
|
|
2545
|
+
s.some((o) => o.children && o.children.length > 0) && (i = D(s).flatColumns), this.data.clear(), this.data.rowCount = t.length, this.rows.setCount(t.length), this.selection.setDimensions(t.length, this.data.colCount), this.loadTableData(t, i), this.pagination.enabled && this.pagination.setTotalRows(t.length), this.viewMapping.rebuild(), this.refresh();
|
|
2546
|
+
}
|
|
2547
|
+
// ── Loading ──
|
|
2548
|
+
setLoading(t) {
|
|
2549
|
+
t ? this.loadingOverlay.show() : this.loadingOverlay.hide();
|
|
2550
|
+
}
|
|
2551
|
+
get isLoading() {
|
|
2552
|
+
return this.loadingOverlay.isVisible;
|
|
2553
|
+
}
|
|
2554
|
+
// ── Pagination API ──
|
|
2555
|
+
setPage(t) {
|
|
2556
|
+
this.pagination.setPage(t);
|
|
2557
|
+
}
|
|
2558
|
+
setPageSize(t) {
|
|
2559
|
+
this.pagination.setPageSize(t);
|
|
2560
|
+
}
|
|
2561
|
+
getPaginationState() {
|
|
2562
|
+
return this.pagination.getState();
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
class Bt {
|
|
2566
|
+
constructor(e) {
|
|
2567
|
+
n(this, "config");
|
|
2568
|
+
n(this, "container");
|
|
2569
|
+
n(this, "listEl");
|
|
2570
|
+
n(this, "searchInput", null);
|
|
2571
|
+
n(this, "selected", /* @__PURE__ */ new Set());
|
|
2572
|
+
n(this, "options", []);
|
|
2573
|
+
n(this, "highlightIndex", -1);
|
|
2574
|
+
n(this, "searchInputHandler", null);
|
|
2575
|
+
n(this, "handleItemClick", (e) => {
|
|
2576
|
+
const t = e.target.closest(".wt-dropdown-item");
|
|
2577
|
+
if (!t) return;
|
|
2578
|
+
e.stopPropagation();
|
|
2579
|
+
const s = parseInt(t.dataset.index ?? "", 10);
|
|
2580
|
+
if (isNaN(s) || s < 0 || s >= this.options.length) return;
|
|
2581
|
+
const i = this.options[s];
|
|
2582
|
+
i.disabled || this.selectOption(i);
|
|
2583
|
+
});
|
|
2584
|
+
n(this, "handleKey", (e) => {
|
|
2585
|
+
const t = this.listEl.children;
|
|
2586
|
+
switch (e.key) {
|
|
2587
|
+
case "ArrowDown":
|
|
2588
|
+
e.preventDefault(), this.highlightIndex = Math.min(this.highlightIndex + 1, t.length - 1), this.updateHighlight();
|
|
2589
|
+
break;
|
|
2590
|
+
case "ArrowUp":
|
|
2591
|
+
e.preventDefault(), this.highlightIndex = Math.max(this.highlightIndex - 1, 0), this.updateHighlight();
|
|
2592
|
+
break;
|
|
2593
|
+
case "Enter":
|
|
2594
|
+
e.preventDefault(), this.highlightIndex >= 0 && this.highlightIndex < this.options.length && this.selectOption(this.options[this.highlightIndex]);
|
|
2595
|
+
break;
|
|
2596
|
+
}
|
|
2597
|
+
});
|
|
2598
|
+
this.config = e;
|
|
2599
|
+
}
|
|
2600
|
+
createElement(e) {
|
|
2601
|
+
return this.container = document.createElement("div"), this.container.className = "wt-dropdown", this.config.searchable && (this.searchInput = document.createElement("input"), this.searchInput.type = "text", this.searchInput.className = "wt-dropdown-search", this.searchInput.placeholder = this.config.placeholder ?? "Search...", this.container.appendChild(this.searchInput), this.searchInputHandler = () => {
|
|
2602
|
+
this.loadOptions(this.searchInput.value);
|
|
2603
|
+
}, this.searchInput.addEventListener("input", this.searchInputHandler)), this.listEl = document.createElement("div"), this.listEl.className = "wt-dropdown-list", this.container.appendChild(this.listEl), this.listEl.addEventListener("click", this.handleItemClick), e.appendChild(this.container), this.container.addEventListener("keydown", this.handleKey), this.container;
|
|
2604
|
+
}
|
|
2605
|
+
open(e, t, s) {
|
|
2606
|
+
this.config.multiple && Array.isArray(e) ? this.selected = new Set(e) : e != null && (this.selected = /* @__PURE__ */ new Set([e])), this.loadOptions(""), requestAnimationFrame(() => {
|
|
2607
|
+
this.searchInput ? this.searchInput.focus() : this.container.focus();
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
getValue() {
|
|
2611
|
+
return this.config.multiple ? Array.from(this.selected) : this.selected.size > 0 ? this.selected.values().next().value : null;
|
|
2612
|
+
}
|
|
2613
|
+
close() {
|
|
2614
|
+
this.searchInput && this.searchInputHandler && this.searchInput.removeEventListener("input", this.searchInputHandler), this.listEl.removeEventListener("click", this.handleItemClick), this.container.removeEventListener("keydown", this.handleKey), this.container.remove();
|
|
2615
|
+
}
|
|
2616
|
+
async loadOptions(e) {
|
|
2617
|
+
if (this.config.source)
|
|
2618
|
+
this.options = await this.config.source(e, 0, 0);
|
|
2619
|
+
else if (this.config.options) {
|
|
2620
|
+
const t = e.toLowerCase();
|
|
2621
|
+
this.options = t ? this.config.options.filter((s) => s.label.toLowerCase().includes(t)) : this.config.options;
|
|
2622
|
+
}
|
|
2623
|
+
this.renderOptions();
|
|
2624
|
+
}
|
|
2625
|
+
renderOptions() {
|
|
2626
|
+
this.listEl.innerHTML = "", this.highlightIndex = -1;
|
|
2627
|
+
for (let e = 0; e < this.options.length; e++) {
|
|
2628
|
+
const t = this.options[e], s = document.createElement("div");
|
|
2629
|
+
if (s.className = "wt-dropdown-item", s.dataset.index = String(e), this.selected.has(t.value) && s.classList.add("wt-dropdown-item--selected"), t.disabled && s.classList.add("wt-dropdown-item--disabled"), this.config.renderOption)
|
|
2630
|
+
this.config.renderOption(t, s);
|
|
2631
|
+
else if (s.textContent = t.label, t.icon) {
|
|
2632
|
+
const i = document.createElement("span");
|
|
2633
|
+
i.className = "wt-dropdown-icon", i.textContent = t.icon, s.prepend(i);
|
|
2634
|
+
}
|
|
2635
|
+
this.listEl.appendChild(s);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
selectOption(e) {
|
|
2639
|
+
this.config.multiple ? (this.selected.has(e.value) ? this.selected.delete(e.value) : this.selected.add(e.value), this.renderOptions()) : (this.selected.clear(), this.selected.add(e.value));
|
|
2640
|
+
}
|
|
2641
|
+
updateHighlight() {
|
|
2642
|
+
var t;
|
|
2643
|
+
const e = this.listEl.children;
|
|
2644
|
+
for (let s = 0; s < e.length; s++)
|
|
2645
|
+
e[s].classList.toggle("wt-dropdown-item--highlight", s === this.highlightIndex);
|
|
2646
|
+
(t = e[this.highlightIndex]) == null || t.scrollIntoView({ block: "nearest" });
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
class zt {
|
|
2650
|
+
constructor(e) {
|
|
2651
|
+
n(this, "el");
|
|
2652
|
+
n(this, "onAttempt");
|
|
2653
|
+
n(this, "row", -1);
|
|
2654
|
+
n(this, "col", -1);
|
|
2655
|
+
this.onAttempt = e ?? null;
|
|
2656
|
+
}
|
|
2657
|
+
createElement(e) {
|
|
2658
|
+
return this.el = document.createElement("div"), e.appendChild(this.el), this.el;
|
|
2659
|
+
}
|
|
2660
|
+
open(e, t, s) {
|
|
2661
|
+
this.onAttempt && this.onAttempt(this.row, this.col);
|
|
2662
|
+
}
|
|
2663
|
+
/** Called by EditorManager before open() to pass row/col */
|
|
2664
|
+
setPosition(e, t) {
|
|
2665
|
+
this.row = e, this.col = t;
|
|
2666
|
+
}
|
|
2667
|
+
getValue() {
|
|
2668
|
+
}
|
|
2669
|
+
close() {
|
|
2670
|
+
var e;
|
|
2671
|
+
(e = this.el) == null || e.remove();
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
const Ft = {
|
|
2675
|
+
bgColor: "#ffffff",
|
|
2676
|
+
cellBgColor: "#ffffff",
|
|
2677
|
+
cellTextColor: "#1e293b",
|
|
2678
|
+
headerBgColor: "#f8fafc",
|
|
2679
|
+
headerTextColor: "#475569",
|
|
2680
|
+
gridLineColor: "#e2e8f0",
|
|
2681
|
+
selectionBgColor: "rgba(59, 130, 246, 0.08)",
|
|
2682
|
+
selectionBorderColor: "#3b82f6",
|
|
2683
|
+
focusBorderColor: "#3b82f6",
|
|
2684
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
2685
|
+
fontSize: 13,
|
|
2686
|
+
headerFontSize: 12,
|
|
2687
|
+
cellPadding: 8,
|
|
2688
|
+
headerHeight: 28,
|
|
2689
|
+
rowHeaderWidth: 50
|
|
2690
|
+
}, Pt = {
|
|
2691
|
+
bgColor: "#0f172a",
|
|
2692
|
+
cellBgColor: "#1e293b",
|
|
2693
|
+
cellTextColor: "#e2e8f0",
|
|
2694
|
+
headerBgColor: "#0f172a",
|
|
2695
|
+
headerTextColor: "#94a3b8",
|
|
2696
|
+
gridLineColor: "#334155",
|
|
2697
|
+
selectionBgColor: "rgba(59, 130, 246, 0.15)",
|
|
2698
|
+
selectionBorderColor: "#3b82f6",
|
|
2699
|
+
focusBorderColor: "#60a5fa",
|
|
2700
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
2701
|
+
fontSize: 13,
|
|
2702
|
+
headerFontSize: 12,
|
|
2703
|
+
cellPadding: 8,
|
|
2704
|
+
headerHeight: 28,
|
|
2705
|
+
rowHeaderWidth: 50
|
|
2706
|
+
}, $t = {
|
|
2707
|
+
bgColor: "#ffffff",
|
|
2708
|
+
cellBgColor: "#ffffff",
|
|
2709
|
+
cellTextColor: "#111827",
|
|
2710
|
+
headerBgColor: "#ffffff",
|
|
2711
|
+
headerTextColor: "#9ca3af",
|
|
2712
|
+
gridLineColor: "#f3f4f6",
|
|
2713
|
+
selectionBgColor: "rgba(99, 102, 241, 0.06)",
|
|
2714
|
+
selectionBorderColor: "#6366f1",
|
|
2715
|
+
focusBorderColor: "#6366f1",
|
|
2716
|
+
fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, sans-serif',
|
|
2717
|
+
fontSize: 13,
|
|
2718
|
+
headerFontSize: 11,
|
|
2719
|
+
cellPadding: 10,
|
|
2720
|
+
headerHeight: 32,
|
|
2721
|
+
rowHeaderWidth: 44
|
|
2722
|
+
};
|
|
2723
|
+
export {
|
|
2724
|
+
lt as BadgeRenderer,
|
|
2725
|
+
zt as BlankEditor,
|
|
2726
|
+
ht as BlankRenderer,
|
|
2727
|
+
nt as CheckboxRenderer,
|
|
2728
|
+
P as ColumnModel,
|
|
2729
|
+
Z as CommandBus,
|
|
2730
|
+
Ct as ContextMenu,
|
|
2731
|
+
j as DataModel,
|
|
2732
|
+
Q as DeleteCellsCommand,
|
|
2733
|
+
Bt as DropdownEditor,
|
|
2734
|
+
q as EventEmitter,
|
|
2735
|
+
Rt as MergeModel,
|
|
2736
|
+
rt as NumberRenderer,
|
|
2737
|
+
St as PaginationModel,
|
|
2738
|
+
F as PatchCommand,
|
|
2739
|
+
at as ProgressRenderer,
|
|
2740
|
+
ct as RendererRegistry,
|
|
2741
|
+
Et as RowGroupModel,
|
|
2742
|
+
tt as RowModel,
|
|
2743
|
+
J as SelectionModel,
|
|
2744
|
+
$ as SetCellValueCommand,
|
|
2745
|
+
Pt as THEME_DARK,
|
|
2746
|
+
Ft as THEME_LIGHT,
|
|
2747
|
+
$t as THEME_MINIMAL,
|
|
2748
|
+
ot as TextRenderer,
|
|
2749
|
+
bt as ViewMapping,
|
|
2750
|
+
It as WanderTable,
|
|
2751
|
+
z as columnLabel,
|
|
2752
|
+
N as downloadFile,
|
|
2753
|
+
kt as exportCSV,
|
|
2754
|
+
Lt as exportJSON,
|
|
2755
|
+
D as flattenColumns
|
|
2756
|
+
};
|
|
2757
|
+
//# sourceMappingURL=wandertable.js.map
|