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.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +505 -0
  3. package/dist/style.css +1 -0
  4. package/dist/types/WanderTable.d.ts +112 -0
  5. package/dist/types/WanderTable.d.ts.map +1 -0
  6. package/dist/types/__tests__/ColumnModel.test.d.ts +2 -0
  7. package/dist/types/__tests__/ColumnModel.test.d.ts.map +1 -0
  8. package/dist/types/__tests__/CommandBus.test.d.ts +2 -0
  9. package/dist/types/__tests__/CommandBus.test.d.ts.map +1 -0
  10. package/dist/types/__tests__/DataModel.test.d.ts +2 -0
  11. package/dist/types/__tests__/DataModel.test.d.ts.map +1 -0
  12. package/dist/types/__tests__/Export.test.d.ts +2 -0
  13. package/dist/types/__tests__/Export.test.d.ts.map +1 -0
  14. package/dist/types/__tests__/GroupedHeaders.test.d.ts +2 -0
  15. package/dist/types/__tests__/GroupedHeaders.test.d.ts.map +1 -0
  16. package/dist/types/__tests__/MergeModel.test.d.ts +2 -0
  17. package/dist/types/__tests__/MergeModel.test.d.ts.map +1 -0
  18. package/dist/types/__tests__/SelectionModel.test.d.ts +2 -0
  19. package/dist/types/__tests__/SelectionModel.test.d.ts.map +1 -0
  20. package/dist/types/__tests__/ViewMapping.test.d.ts +2 -0
  21. package/dist/types/__tests__/ViewMapping.test.d.ts.map +1 -0
  22. package/dist/types/columns/ColumnModel.d.ts +25 -0
  23. package/dist/types/columns/ColumnModel.d.ts.map +1 -0
  24. package/dist/types/columns/GroupedHeaders.d.ts +20 -0
  25. package/dist/types/columns/GroupedHeaders.d.ts.map +1 -0
  26. package/dist/types/core/CommandBus.d.ts +63 -0
  27. package/dist/types/core/CommandBus.d.ts.map +1 -0
  28. package/dist/types/core/DataModel.d.ts +27 -0
  29. package/dist/types/core/DataModel.d.ts.map +1 -0
  30. package/dist/types/core/EventEmitter.d.ts +10 -0
  31. package/dist/types/core/EventEmitter.d.ts.map +1 -0
  32. package/dist/types/core/MergeModel.d.ts +35 -0
  33. package/dist/types/core/MergeModel.d.ts.map +1 -0
  34. package/dist/types/core/PaginationModel.d.ts +24 -0
  35. package/dist/types/core/PaginationModel.d.ts.map +1 -0
  36. package/dist/types/core/RowGroupModel.d.ts +36 -0
  37. package/dist/types/core/RowGroupModel.d.ts.map +1 -0
  38. package/dist/types/core/SelectionModel.d.ts +47 -0
  39. package/dist/types/core/SelectionModel.d.ts.map +1 -0
  40. package/dist/types/core/ViewMapping.d.ts +37 -0
  41. package/dist/types/core/ViewMapping.d.ts.map +1 -0
  42. package/dist/types/core/ViewportModel.d.ts +9 -0
  43. package/dist/types/core/ViewportModel.d.ts.map +1 -0
  44. package/dist/types/editors/BlankEditor.d.ts +20 -0
  45. package/dist/types/editors/BlankEditor.d.ts.map +1 -0
  46. package/dist/types/editors/DropdownEditor.d.ts +23 -0
  47. package/dist/types/editors/DropdownEditor.d.ts.map +1 -0
  48. package/dist/types/editors/EditorManager.d.ts +22 -0
  49. package/dist/types/editors/EditorManager.d.ts.map +1 -0
  50. package/dist/types/index.d.ts +35 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/interaction/ClipboardManager.d.ts +19 -0
  53. package/dist/types/interaction/ClipboardManager.d.ts.map +1 -0
  54. package/dist/types/interaction/ColumnReorder.d.ts +20 -0
  55. package/dist/types/interaction/ColumnReorder.d.ts.map +1 -0
  56. package/dist/types/interaction/ColumnResize.d.ts +15 -0
  57. package/dist/types/interaction/ColumnResize.d.ts.map +1 -0
  58. package/dist/types/interaction/FillHandle.d.ts +39 -0
  59. package/dist/types/interaction/FillHandle.d.ts.map +1 -0
  60. package/dist/types/interaction/KeyboardNav.d.ts +19 -0
  61. package/dist/types/interaction/KeyboardNav.d.ts.map +1 -0
  62. package/dist/types/interaction/RowResize.d.ts +15 -0
  63. package/dist/types/interaction/RowResize.d.ts.map +1 -0
  64. package/dist/types/plugins/ContextMenu.d.ts +44 -0
  65. package/dist/types/plugins/ContextMenu.d.ts.map +1 -0
  66. package/dist/types/plugins/Export.d.ts +16 -0
  67. package/dist/types/plugins/Export.d.ts.map +1 -0
  68. package/dist/types/render/AutoFit.d.ts +23 -0
  69. package/dist/types/render/AutoFit.d.ts.map +1 -0
  70. package/dist/types/render/DOMRenderer.d.ts +91 -0
  71. package/dist/types/render/DOMRenderer.d.ts.map +1 -0
  72. package/dist/types/render/LoadingOverlay.d.ts +9 -0
  73. package/dist/types/render/LoadingOverlay.d.ts.map +1 -0
  74. package/dist/types/render/PaginationBar.d.ts +20 -0
  75. package/dist/types/render/PaginationBar.d.ts.map +1 -0
  76. package/dist/types/renderers/BadgeRenderer.d.ts +5 -0
  77. package/dist/types/renderers/BadgeRenderer.d.ts.map +1 -0
  78. package/dist/types/renderers/BlankRenderer.d.ts +9 -0
  79. package/dist/types/renderers/BlankRenderer.d.ts.map +1 -0
  80. package/dist/types/renderers/CheckboxRenderer.d.ts +5 -0
  81. package/dist/types/renderers/CheckboxRenderer.d.ts.map +1 -0
  82. package/dist/types/renderers/NumberRenderer.d.ts +7 -0
  83. package/dist/types/renderers/NumberRenderer.d.ts.map +1 -0
  84. package/dist/types/renderers/ProgressRenderer.d.ts +5 -0
  85. package/dist/types/renderers/ProgressRenderer.d.ts.map +1 -0
  86. package/dist/types/renderers/RendererRegistry.d.ts +10 -0
  87. package/dist/types/renderers/RendererRegistry.d.ts.map +1 -0
  88. package/dist/types/renderers/TextRenderer.d.ts +5 -0
  89. package/dist/types/renderers/TextRenderer.d.ts.map +1 -0
  90. package/dist/types/rows/RowModel.d.ts +20 -0
  91. package/dist/types/rows/RowModel.d.ts.map +1 -0
  92. package/dist/types/themes.d.ts +5 -0
  93. package/dist/types/themes.d.ts.map +1 -0
  94. package/dist/types/types/index.d.ts +348 -0
  95. package/dist/types/types/index.d.ts.map +1 -0
  96. package/dist/wandertable.cjs +14 -0
  97. package/dist/wandertable.cjs.map +1 -0
  98. package/dist/wandertable.global.js +14 -0
  99. package/dist/wandertable.global.js.map +1 -0
  100. package/dist/wandertable.js +2757 -0
  101. package/dist/wandertable.js.map +1 -0
  102. package/dist/wandertable.umd.js +14 -0
  103. package/dist/wandertable.umd.js.map +1 -0
  104. 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