cellux 0.0.1 → 0.1.5

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 (76) hide show
  1. package/dist/TyeaheadEditor.d.ts +36 -0
  2. package/dist/TyeaheadEditor.d.ts.map +1 -0
  3. package/dist/asserts.d.ts +16 -0
  4. package/dist/asserts.d.ts.map +1 -0
  5. package/dist/cellux.css +1 -0
  6. package/dist/cellux.js +2703 -0
  7. package/dist/cellux.umd.cjs +134 -0
  8. package/dist/column-state.d.ts +9 -0
  9. package/dist/column-state.d.ts.map +1 -0
  10. package/dist/column-tab-builder.d.ts +17 -0
  11. package/dist/column-tab-builder.d.ts.map +1 -0
  12. package/dist/column-tab-container.d.ts +13 -0
  13. package/dist/column-tab-container.d.ts.map +1 -0
  14. package/dist/column.d.ts +81 -0
  15. package/dist/column.d.ts.map +1 -0
  16. package/dist/console-log.d.ts +12 -0
  17. package/dist/console-log.d.ts.map +1 -0
  18. package/dist/context-menu.d.ts +11 -0
  19. package/dist/context-menu.d.ts.map +1 -0
  20. package/dist/data-dash.d.ts +8 -0
  21. package/dist/data-dash.d.ts.map +1 -0
  22. package/dist/date-time-picker.d.ts +17 -0
  23. package/dist/date-time-picker.d.ts.map +1 -0
  24. package/dist/debug-overlay/debug-overlay.d.ts +24 -0
  25. package/dist/debug-overlay/debug-overlay.d.ts.map +1 -0
  26. package/dist/enums.d.ts +6 -0
  27. package/dist/enums.d.ts.map +1 -0
  28. package/dist/event-maps.d.ts +24 -0
  29. package/dist/event-maps.d.ts.map +1 -0
  30. package/dist/events.d.ts +40 -0
  31. package/dist/events.d.ts.map +1 -0
  32. package/dist/filter.d.ts +17 -0
  33. package/dist/filter.d.ts.map +1 -0
  34. package/dist/grid-api.d.ts +28 -0
  35. package/dist/grid-api.d.ts.map +1 -0
  36. package/dist/grid-assertions.d.ts +33 -0
  37. package/dist/grid-assertions.d.ts.map +1 -0
  38. package/dist/grid-assertions.test.d.ts +1 -0
  39. package/dist/grid-assertions.test.d.ts.map +1 -0
  40. package/dist/grid-class-name.d.ts +32 -0
  41. package/dist/grid-class-name.d.ts.map +1 -0
  42. package/dist/grid-options.d.ts +25 -0
  43. package/dist/grid-options.d.ts.map +1 -0
  44. package/dist/grid-row-ref.d.ts +12 -0
  45. package/dist/grid-row-ref.d.ts.map +1 -0
  46. package/dist/grid.d.ts +159 -0
  47. package/dist/grid.d.ts.map +1 -0
  48. package/dist/index.d.ts +7 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/interfaces.d.ts +105 -0
  51. package/dist/interfaces.d.ts.map +1 -0
  52. package/dist/quick-filter.d.ts +12 -0
  53. package/dist/quick-filter.d.ts.map +1 -0
  54. package/dist/renderer.d.ts +83 -0
  55. package/dist/renderer.d.ts.map +1 -0
  56. package/dist/select-editor-custom.d.ts +26 -0
  57. package/dist/select-editor-custom.d.ts.map +1 -0
  58. package/dist/select-editor.d.ts +11 -0
  59. package/dist/select-editor.d.ts.map +1 -0
  60. package/dist/sorting.d.ts +19 -0
  61. package/dist/sorting.d.ts.map +1 -0
  62. package/dist/status-bar.d.ts +11 -0
  63. package/dist/status-bar.d.ts.map +1 -0
  64. package/dist/text-editor.d.ts +13 -0
  65. package/dist/text-editor.d.ts.map +1 -0
  66. package/dist/types.d.ts +30 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/utilities/formatter.d.ts +4 -0
  69. package/dist/utilities/formatter.d.ts.map +1 -0
  70. package/dist/utilities/utilities.d.ts +241 -0
  71. package/dist/utilities/utilities.d.ts.map +1 -0
  72. package/package.json +32 -18
  73. package/README.md +0 -11
  74. package/files.zip +0 -0
  75. package/index.d.ts +0 -4
  76. package/index.js +0 -4
package/dist/cellux.js ADDED
@@ -0,0 +1,2703 @@
1
+ const Z = {
2
+ click: "onCellClicked",
3
+ dblclick: "onCellDoubleClicked",
4
+ contextmenu: "onContextMenu",
5
+ mousedown: "onCellMouseDown",
6
+ mouseup: "onCellMouseUp",
7
+ mousemove: "onCellMouseMove",
8
+ mouseenter: "onCellMouseEnter",
9
+ mouseleave: "onCellMouseLeave",
10
+ mouseover: "onCellMouseOver",
11
+ mouseout: "onCellMouseOut"
12
+ }, J = {
13
+ click: "onRowClicked",
14
+ dblclick: "onRowDoubleClicked",
15
+ mouseover: "onRowMouseOver",
16
+ mouseout: "onRowMouseOut"
17
+ }, C = {
18
+ dataField: "data-field",
19
+ dataColIndex: "data-col-index",
20
+ dataResizeIndex: "data-resize-index"
21
+ }, g = {
22
+ cx_grid_container: "cellux-grid-container",
23
+ grid_viewport: "grid-viewport",
24
+ left_panel: "left-panel",
25
+ center_panel: "center-panel",
26
+ header: "header",
27
+ header_center: "header-center",
28
+ header_left: "header-left",
29
+ header_label: "header-label",
30
+ header_cell: "header-cell",
31
+ col_resizer: "col-resizer",
32
+ grid_body: "grid-body",
33
+ grid_body_left: "grid-body-left",
34
+ grid_body_center: "grid-body-center",
35
+ rows_container: "rows-container",
36
+ rows_container_center: "rows-container-center",
37
+ rows_container_left: "rows-container-left",
38
+ row: "cellux-row",
39
+ cell: "cell",
40
+ cell_editing: "cell-editing",
41
+ visual_cell: "visual-cell",
42
+ select_all_checkbox: "select-all-checkbox",
43
+ active_row: "active-row",
44
+ // fn_grid_header_cell: 'header-cell',
45
+ header_menu_icon: "header-menu-icon",
46
+ // fn_grid_header_center: 'header-center',
47
+ header_inner: "header-inner",
48
+ status_bar: "status-bar",
49
+ // Column Menu Items
50
+ fn_filter_item: "fn-filter-item",
51
+ fn_filter_list: "fn-filter-list",
52
+ // State classes (no CSS rules - JS only)
53
+ active_cell: "active-cell",
54
+ panel_1: "fn-panel-1"
55
+ };
56
+ function Y(h) {
57
+ return typeof h == "function";
58
+ }
59
+ function O(h, t) {
60
+ const e = t.length;
61
+ if (e === 0)
62
+ return {
63
+ firstRenderedRowIndex: 0,
64
+ lastRenderedRowIndex: -1,
65
+ firstVisibleRowIndex: 0,
66
+ lastVisibleRowIndex: -1,
67
+ renderedRowCount: 0
68
+ };
69
+ const { rowHeight: r, viewportHeight: n, scrollTop: i, rowBuffer: s } = h, l = Math.max(0, s), a = Math.max(0, Math.floor(i / r)), o = Math.max(1, Math.ceil(n / r)), d = Math.min(e - 1, a + o - 1), u = Math.min(e, o + 2 * l);
70
+ let c = Math.max(0, a - l), f = c + u - 1;
71
+ return f > e - 1 && (f = e - 1, c = Math.max(0, f - u + 1)), {
72
+ firstRenderedRowIndex: c,
73
+ lastRenderedRowIndex: f,
74
+ firstVisibleRowIndex: a,
75
+ lastVisibleRowIndex: d,
76
+ renderedRowCount: f - c + 1
77
+ };
78
+ }
79
+ function ee(h) {
80
+ return h.map((t, e) => {
81
+ if (typeof t == "number") {
82
+ if (!Number.isFinite(t) || t < 0)
83
+ throw new Error(`convertWidthArray: invalid numeric width at index ${e}: ${t}`);
84
+ return `${t}px`;
85
+ }
86
+ const r = t.trim();
87
+ if (!r)
88
+ throw new Error(`convertWidthArray: empty width token at index ${e}`);
89
+ if (/\s/.test(r))
90
+ throw new Error(`convertWidthArray: width token contains whitespace at index ${e}: "${t}"`);
91
+ return r;
92
+ }).join(" ");
93
+ }
94
+ function te(h) {
95
+ const t = h?.closest(`.${g.cell}`);
96
+ if (!t?.parentElement) return null;
97
+ const e = Array.from(t.parentElement.children).indexOf(t);
98
+ return e === -1 ? null : e;
99
+ }
100
+ function V(h) {
101
+ if (!h) return null;
102
+ const t = h.closest(".cellux-row");
103
+ if (!t) return null;
104
+ const e = Number(t.dataset.arrayIndex);
105
+ return isNaN(e) ? null : e;
106
+ }
107
+ function re(h, t) {
108
+ const e = V(h);
109
+ if (e === null) throw new Error("getRowData: element is not within a grid row");
110
+ const r = t[e];
111
+ if (!r) throw new Error(`getRowData: rowData undefined at index ${e}`);
112
+ return r;
113
+ }
114
+ function ne(h, t, e, r) {
115
+ if (!t) throw new Error("getColumnCallbackPayload: cellEl is null");
116
+ const n = t.closest(".cellux-row");
117
+ if (!n) throw new Error("getColumnCallbackPayload: cellEl.closest('.cellux-row') returned null");
118
+ const i = Array.from(n.children).indexOf(t);
119
+ if (i < 0) throw new Error("getColumnCallbackPayload: cell not found in row children");
120
+ const s = e[i];
121
+ if (!s) throw new Error(`getColumnCallbackPayload: column undefined at index ${i}`);
122
+ const l = Number(n.dataset.arrayIndex), a = Number(n.dataset.gridIndex), o = r[l];
123
+ if (!o) throw new Error(`getColumnCallbackPayload: rowData undefined at arrayIndex ${l}`);
124
+ const d = o[s.field];
125
+ return {
126
+ data: o,
127
+ rowIndex: a,
128
+ arrayIndex: l,
129
+ colDef: s,
130
+ value: d,
131
+ cellElement: t
132
+ };
133
+ }
134
+ function z(h) {
135
+ return (h == null ? "" : String(h)).replace(/\u00A0/g, " ").replace(/[\u200B-\u200D\uFEFF]/g, "").replace(/[\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g, "").replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, "").trim();
136
+ }
137
+ function ie(h) {
138
+ return z(h).replace(/\s+/g, " ").trim();
139
+ }
140
+ function G() {
141
+ if (!document.querySelector(".cellux-grid-container")) throw new Error("getContainer came up empty");
142
+ return document.querySelector(".cellux-grid-container");
143
+ }
144
+ function j() {
145
+ const h = G();
146
+ if (!h) return null;
147
+ const t = h.querySelector(".header");
148
+ if (!t) throw new Error("getHeaderEl came up empty");
149
+ return t;
150
+ }
151
+ function L() {
152
+ const h = j();
153
+ if (!h) return null;
154
+ const t = h.querySelector(".header-inner");
155
+ if (!t) throw new Error("getHeaderInnerEl came up empty");
156
+ return t;
157
+ }
158
+ function se() {
159
+ const h = L();
160
+ Array.from(h.children).forEach((t) => {
161
+ const e = t.querySelector(".header-label");
162
+ console.log(e?.textContent);
163
+ });
164
+ }
165
+ function le(h, t) {
166
+ const n = (t._leftColDefs.some((i) => i.field === h) ? t._leftColDefs : t._centerColDefs).findIndex((i) => i.field === h);
167
+ if (n === -1) throw new Error(`autoSizeColumn: field ${h} not found`);
168
+ return n;
169
+ }
170
+ function K(h, t) {
171
+ const e = t._leftColDefs.some((i) => i.field === h), n = (e ? t._leftColDefs : t._centerColDefs).findIndex((i) => i.field === h);
172
+ if (n === -1) throw new Error(`autoSizeColumn: field ${h} not found`);
173
+ return { colIndex: n, isLeft: e };
174
+ }
175
+ function X(h) {
176
+ h._visibleColDefs = h._allColDefs.filter((t) => !t.hide), h._leftColDefs = h._visibleColDefs.filter((t) => t.pinned === "left"), h._centerColDefs = h._visibleColDefs.filter((t) => t.pinned !== "left");
177
+ }
178
+ function T(h) {
179
+ return h.getAttribute(C.dataField);
180
+ }
181
+ function H(h) {
182
+ const t = h.getAttribute(C.dataColIndex);
183
+ if (t === null) return null;
184
+ const e = Number(t);
185
+ return Number.isInteger(e) ? e : null;
186
+ }
187
+ function P(h, t) {
188
+ const e = h.getAttribute(C.dataField);
189
+ if (!e) throw new Error("field undefined in getColumnFromHeaderCell");
190
+ return t._renderer._visibleColDefs.find((n) => n.field === e) ?? null;
191
+ }
192
+ function I(h) {
193
+ return h.closest(".cellux-row");
194
+ }
195
+ function $(h) {
196
+ const t = Number(h.dataset.arrayIndex);
197
+ return Number.isInteger(t) ? t : null;
198
+ }
199
+ function x(h) {
200
+ const t = Number(h.dataset.rowIndex);
201
+ return Number.isInteger(t) ? t : null;
202
+ }
203
+ function S(h, t) {
204
+ const e = Array.from(t.children).indexOf(h);
205
+ return e >= 0 ? e : null;
206
+ }
207
+ function U(h, t) {
208
+ const e = I(h);
209
+ if (!e) return null;
210
+ const r = S(h, e);
211
+ return r === null ? null : t._renderer._centerColDefs[r] ?? null;
212
+ }
213
+ function W(h) {
214
+ const t = I(h);
215
+ if (!t) return null;
216
+ const e = x(t), r = $(t);
217
+ return e === null || r === null ? null : { rowEl: t, rowIndex: e, arrayIndex: r };
218
+ }
219
+ function Q(h, t) {
220
+ const e = W(h);
221
+ if (!e) return null;
222
+ const r = U(h, t);
223
+ return r ? { colDef: r, ...e } : null;
224
+ }
225
+ const N = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
226
+ __proto__: null,
227
+ computeRenderedRowCount: O,
228
+ convertWidthArrayToString: ee,
229
+ getArrayIndex: V,
230
+ getArrayIndexFromRow: $,
231
+ getCellColIndex: S,
232
+ getCellContext: Q,
233
+ getColDefFromCell: U,
234
+ getColIndexFromHeaderCell: H,
235
+ getColumnCallbackPayload: ne,
236
+ getColumnFromHeaderCell: P,
237
+ getColumnIndex: te,
238
+ getColumnIndexFromFieldName: K,
239
+ getColumnIndexOnlyFromFieldName: le,
240
+ getContainerEl: G,
241
+ getFieldFromHeaderCell: T,
242
+ getHeaderEl: j,
243
+ getHeaderInnerEl: L,
244
+ getRowAndArrayIndex: W,
245
+ getRowData: re,
246
+ getRowFromCell: I,
247
+ getRowIndexFromRow: x,
248
+ isFunction: Y,
249
+ normalizeTextHard: ie,
250
+ normalizeTextSoft: z,
251
+ printHeaderDom: se,
252
+ reComputeColDefs: X
253
+ }, Symbol.toStringTag, { value: "Module" }));
254
+ class oe {
255
+ constructor(t, e) {
256
+ this._grid = t, this._renderer = e, this.className = "grid-debug-overlay2", this._showOverlay = !0, this._showLists = !1, this._showFilters = !1, this._panel1El = null, this._panel2El = null, this._panelFilters = null;
257
+ }
258
+ //currentState: GridState,
259
+ updateDebugOverlay() {
260
+ if (!this._grid.showDebugOverlay || !this._showOverlay) return;
261
+ const t = N, e = g, r = this._grid.currentState, n = this._grid.derivedIndices;
262
+ this._panel1El || this.createDebugOverlay();
263
+ const { firstVisibleRowIndex: i, lastRenderedRowIndex: s, firstRenderedRowIndex: l, lastVisibleRowIndex: a, renderedRowCount: o } = t.computeRenderedRowCount(r, n);
264
+ r.totalRows ?? this._grid.options.rowData?.length;
265
+ const d = this._grid._renderer._visibleColDefs?.length ?? 0, u = this._grid._renderer._centerBodyEl?.scrollTop ?? 0, c = this._grid._renderer._centerBodyEl.querySelector(`.${e.active_cell}`), f = this._grid.currentState.viewportHeight, _ = this._renderer.renderedRowDivs.length;
266
+ let p = [
267
+ `rowBuffer: ${this._grid.currentState.rowBuffer}`,
268
+ `_centerRenderedRowDivs.length: ${_}`,
269
+ `Visible Row Count: ${a - i + 1}`,
270
+ // `renderedRowDivs[0].rowId: ${rowZero}`,
271
+ // `renderedRowDivs[${length - 1}].rowId: ${lastRenderedRowId}`,
272
+ `firstRenderedRowIndex: ${l}`,
273
+ `lastRenderedRowIndex: ${s}`,
274
+ `viewPortHeight: ${f}`,
275
+ `rowHeight: ${this._grid.currentState.rowHeight}`,
276
+ `firstVisibleRowIndex: ${i}`,
277
+ `lastVisibleRowIndex: ${a}`,
278
+ `scrollTop: ${u}`,
279
+ `renderedRowCount: ${o}`,
280
+ `columnCount: ${d}`,
281
+ `activeCell.textContent: ${c?.textContent}`,
282
+ // `activeCell.outerHTML: ${activeCell? activeCell.outerHTML: null}`,
283
+ `activeRowIndex: ${this._grid.activeRowIndex}`
284
+ ].join(" | ");
285
+ this._panel1El.style.minHeight = "80px", this._panel1El.textContent = p, this._showLists && (this._panel2El.style.minHeight = "80px", this.buildLists()), this._showFilters && (this._panelFilters.style.minHeight = "200px", this.buildFiltersPanel());
286
+ }
287
+ buildFiltersPanel() {
288
+ const t = this._grid._filter._columnFiltersMap, e = [];
289
+ for (const [r, n] of t) {
290
+ const i = Array.from(n).sort(
291
+ (s, l) => String(s).localeCompare(String(l))
292
+ );
293
+ e.push(`${r} (${i.length}): [${i.join(", ")}]`);
294
+ }
295
+ this._panelFilters.textContent = e.join(`
296
+ `);
297
+ }
298
+ getVisibleColumns() {
299
+ return this._renderer._visibleColDefs.map((e, r) => `${r}/${e.field}`);
300
+ }
301
+ getAllColDefs() {
302
+ return this._renderer._allColDefs.map((e, r) => `${r}/${e.field}`);
303
+ }
304
+ createDebugOverlay() {
305
+ if (!this._showOverlay) return;
306
+ const t = document.createElement("div");
307
+ if (t.className = this.className, t.style.pointerEvents = "none", t.textContent = "debug...", this._panel1El = t, this._grid._renderer._gridContainerEl.parentElement?.insertBefore(
308
+ this._panel1El,
309
+ this._grid._renderer._gridContainerEl
310
+ ), this._showLists) {
311
+ const e = document.createElement("div");
312
+ e.className = this.className, e.style.pointerEvents = "none", this._panel2El = e, this._grid._renderer._gridContainerEl.parentElement?.insertBefore(
313
+ this._panel2El,
314
+ this._grid._renderer._gridContainerEl
315
+ );
316
+ }
317
+ if (this._showFilters) {
318
+ const e = document.createElement("div");
319
+ e.className = this.className, e.style.pointerEvents = "none", this._panelFilters = e, this._grid._renderer._gridContainerEl.parentElement?.insertBefore(
320
+ this._panelFilters,
321
+ this._grid._renderer._gridContainerEl
322
+ );
323
+ }
324
+ }
325
+ buildLists() {
326
+ let t = this._panel2El;
327
+ if (!t) return;
328
+ t.style.display = "flex", t.style.gap = "20px", t.style.alignItems = "flex-start", t.textContent = null;
329
+ let e;
330
+ e = this.buildList("_leftColDefs[]", this._renderer._leftColDefs, this._renderer._leftColumnWidths), e && t.appendChild(e), e = this.buildList("_centerColDefs[]", this._renderer._centerColDefs, this._renderer._centerColumnWidths), e && t.appendChild(e), e = this.buildList("_allColDefs[]", this._renderer._allColDefs, this._renderer._centerColumnWidths), e && t.appendChild(e), e = this.buildList(
331
+ "options colDef array",
332
+ this._grid.options?.columnDefs,
333
+ this._grid.options?.columnDefs.map((r) => r.width)
334
+ ), e && t.appendChild(e);
335
+ }
336
+ buildList(t, e, r) {
337
+ const n = e.map((a, o) => {
338
+ const d = a.hide ?? !1, u = r[o] ?? a.width, c = a.pinned ? "left" : "";
339
+ return `${o}/${a.field}/${d}/${u} ${c}`;
340
+ }), i = document.createElement("div"), s = document.createElement("h4");
341
+ s.textContent = t + ` (${n.length})`, i.appendChild(s);
342
+ const l = document.createElement("ul");
343
+ return n.forEach((a) => {
344
+ const o = document.createElement("li");
345
+ o.textContent = a, l.appendChild(o);
346
+ }), l.style.listStylePosition = "inside", i.appendChild(l), i;
347
+ }
348
+ }
349
+ class de {
350
+ constructor(t) {
351
+ this._grid = t, this._quickFilterText = "";
352
+ }
353
+ clearQuickFilter() {
354
+ this._quickFilterText = "", this.applyQuickFilter();
355
+ }
356
+ getQuickFilter() {
357
+ return this._quickFilterText;
358
+ }
359
+ applyQuickFilter() {
360
+ if (!this._quickFilterText)
361
+ this._grid._filter.filteredIndices = [...Array(this._grid.getRowData().length).keys()];
362
+ else {
363
+ const t = this._quickFilterText.toLowerCase();
364
+ this._grid._filter.filteredIndices = Array.from(Array(this._grid.getRowData().length).keys()).filter((e) => {
365
+ const r = this._grid.getRowData()[e];
366
+ return this._grid._renderer._allColDefs.filter((n) => !n.hide).some((n) => {
367
+ const i = r[n.field];
368
+ return i == null ? !1 : String(i).toLowerCase().includes(t);
369
+ });
370
+ });
371
+ }
372
+ this._grid._sort.applySort(), this._grid.updateTotalRowsDisplay(), this._grid.refreshGrid();
373
+ }
374
+ // public applyQuickFilter(): void {
375
+ // if (!this._quickFilterText) {
376
+ // // No filter - use all rows
377
+ // this._grid._filter.filteredIndices = [...Array(this._grid.getRowData().length).keys()];
378
+ // } else {
379
+ // // Filter the indices based on search text
380
+ // const filterText = this._quickFilterText;
381
+ // this._grid._filter.filteredIndices = Array.from(Array(this._grid.getRowData().length).keys())
382
+ // .filter(arrayIndex => {
383
+ // const row = this._grid.getRowData()[arrayIndex];
384
+ // // Search across all columns
385
+ // return this._grid._renderer._visibleColDefs.some(col => {
386
+ // const value = row[col.field];
387
+ // if (value == null) return false;
388
+ // const stringValue = String(value).toLowerCase();
389
+ // return stringValue.includes(filterText);
390
+ // });
391
+ // });
392
+ // }
393
+ // // Now apply sort to the filtered indices
394
+ // this._grid._sort.applySort();
395
+ // this._grid.updateTotalRowsDisplay();
396
+ // this._grid.refreshGrid();
397
+ // }
398
+ get quickFilterText() {
399
+ return this._quickFilterText;
400
+ }
401
+ set quickFilterText(t) {
402
+ this._quickFilterText = t.toLowerCase().trim(), this.applyQuickFilter();
403
+ }
404
+ }
405
+ class ae {
406
+ constructor(t, e) {
407
+ this._grid = t, this.rootEl = e, this._statusBarEl = null;
408
+ }
409
+ destroy() {
410
+ this._statusBarEl = null;
411
+ }
412
+ updateRowsPanel() {
413
+ if (this._statusBarEl || (this._statusBarEl = this.rootEl.querySelector(".status-bar")), this._statusBarEl) {
414
+ const t = this._grid._filter.filteredIndices.length, e = this._grid.options.rowData.length;
415
+ t < e ? this._statusBarEl.textContent = `${t} of ${e} rows (filtered)` : this._statusBarEl.textContent = `${e} rows`;
416
+ }
417
+ }
418
+ get statusBarEl() {
419
+ return this._statusBarEl;
420
+ }
421
+ }
422
+ class ce {
423
+ constructor(t) {
424
+ this._grid = t;
425
+ }
426
+ onContextMenu(t) {
427
+ t.preventDefault(), t.stopPropagation();
428
+ const e = this._grid.getCellEventParams(t.target, t);
429
+ if (!e) return;
430
+ this.removeContextMenu();
431
+ const r = {
432
+ data: e.data,
433
+ rowIndex: e.rowIndex,
434
+ arrayIndex: e.arrayIndex,
435
+ colDef: e.colDef,
436
+ value: e.value,
437
+ event: t,
438
+ grid: this._grid
439
+ };
440
+ let n;
441
+ this._grid.options.getContextMenuItems ? n = this._grid.options.getContextMenuItems(r) : n = this.getDefaultContextMenuItems(), this.renderContextMenu(t.clientX, t.clientY, n, r);
442
+ }
443
+ getDefaultContextMenuItems() {
444
+ return ["copy", "separator", "autoSizeAll", "separator", "exportCsv"];
445
+ }
446
+ renderContextMenu(t, e, r, n) {
447
+ const i = document.createElement("div");
448
+ i.className = "fn-context-menu", r.forEach((s) => {
449
+ if (s === "separator") {
450
+ const d = document.createElement("div");
451
+ d.className = "fn-context-menu-separator", i.appendChild(d);
452
+ return;
453
+ }
454
+ if (typeof s == "string") {
455
+ const d = this.createBuiltInMenuItem(s, n);
456
+ d && i.appendChild(d);
457
+ return;
458
+ }
459
+ const l = document.createElement("div");
460
+ l.className = "fn-context-menu-item";
461
+ const a = typeof s.disabled == "function" ? s.disabled() : s.disabled;
462
+ a && l.classList.add("disabled");
463
+ let o = "";
464
+ s.icon && (o += `<span class="fn-context-menu-icon">${s.icon}</span>`), o += `<span class="fn-context-menu-label">${s.name}</span>`, l.innerHTML = o, a || l.addEventListener("click", (d) => {
465
+ d.stopPropagation(), s.action(), this.removeContextMenu();
466
+ }), i.appendChild(l);
467
+ }), i.style.left = `${t}px`, i.style.top = `${e}px`, requestAnimationFrame(() => {
468
+ const s = i.getBoundingClientRect();
469
+ s.right > window.innerWidth && (i.style.left = `${t - s.width}px`), s.bottom > window.innerHeight && (i.style.top = `${e - s.height}px`);
470
+ }), document.body.appendChild(i), this._grid.contextMenuEl = i, setTimeout(() => {
471
+ document.addEventListener("click", () => this.removeContextMenu(), { once: !0 }), document.addEventListener("contextmenu", () => this.removeContextMenu(), { once: !0 });
472
+ }, 0), this._grid._renderer._centerBodyEl?.addEventListener("scroll", () => this.removeContextMenu(), { once: !0 });
473
+ }
474
+ createBuiltInMenuItem(t, e) {
475
+ const r = document.createElement("div");
476
+ r.className = "fn-context-menu-item";
477
+ let n = "", i;
478
+ switch (t) {
479
+ case "copy":
480
+ n = "Copy", i = () => {
481
+ const l = String(e.value ?? "");
482
+ navigator.clipboard.writeText(l);
483
+ const o = e.event.target.closest(".cell");
484
+ o && (o.classList.add("fn-cell-copying"), setTimeout(() => {
485
+ o.classList.remove("fn-cell-copying");
486
+ }, 300));
487
+ };
488
+ break;
489
+ case "autoSizeAll":
490
+ n = "Auto-size All Columns", i = () => {
491
+ this._grid.autoSizeAllColumns(), this._grid._colStateMgr.saveColumnState();
492
+ };
493
+ break;
494
+ case "exportCsv":
495
+ n = "Export to CSV", i = () => {
496
+ this._grid.exportToCsv();
497
+ };
498
+ break;
499
+ default:
500
+ return null;
501
+ }
502
+ const s = document.createElement("span");
503
+ return s.className = "fn-context-menu-label", s.textContent = n, r.appendChild(s), r.addEventListener("click", (l) => {
504
+ l.stopPropagation(), i(), this.removeContextMenu();
505
+ }), r;
506
+ }
507
+ removeContextMenu() {
508
+ this._grid.contextMenuEl && document.body.contains(this._grid.contextMenuEl) && document.body.removeChild(this._grid.contextMenuEl), this._grid.contextMenuEl = null;
509
+ }
510
+ }
511
+ class he {
512
+ constructor(t) {
513
+ this._grid = t;
514
+ }
515
+ print(t, e = !1, r = "log") {
516
+ !this._grid.consoleLog || !e || console[r](t);
517
+ }
518
+ }
519
+ class ue {
520
+ constructor(t, e, r = !1, n = !1) {
521
+ this._grid = t, this._renderer = e, this._dev = r, this._consoleLog = n, this.skip = !1, this._dev = !0, this._consoleLog = !1;
522
+ }
523
+ // Fire only if dev
524
+ check(t) {
525
+ this._dev && t();
526
+ }
527
+ assertAll(t) {
528
+ const e = this._consoleLog;
529
+ this._consoleLog = t, this.assertDomWired(), this.assertHeaderCountMatchesColumnCount(), this.assertCssColumnsMatchColumns(), this.assertColumnWidthsLengthMatchColumnsLength(), this.assertColumnSync(), this.assertVisibleColOrder(), this.assertCenterColDefsSync(), this.assertPanelColDefsMatchVisible(), this.assertHeaderDomMatchesPanelColDefs(), this.assertNoDuplicateFields(), this.assertHiddenColsNotVisible(), this._consoleLog = e;
530
+ }
531
+ element(t, e) {
532
+ if (this.skip) return;
533
+ let r = `assert.element: required element with class name "${e}" not found.`;
534
+ if (r += " Did you hear what I said man?! NOT FOUND!!", !t) throw new Error(r);
535
+ }
536
+ assertDomWired() {
537
+ this.check(() => {
538
+ this.element(this._grid._renderer._gridContainerEl, "cellux-grid-container"), this.element(this._grid._renderer._centerHeaderEl, "header"), this.element(this._grid._renderer._centerHeaderInnerEl, "header-inner"), this.element(this._grid._renderer._centerBodyEl, "grid-body-center"), this.element(this._grid._renderer._centerRowsContainerEl, "rows-container-center"), this.print("assertDomWired");
539
+ });
540
+ }
541
+ assertColumnWidthsSync() {
542
+ this.check(() => {
543
+ const t = this._renderer._visibleColDefs.filter((e) => e.pinned !== "left").length;
544
+ if (this._renderer._centerColumnWidths.length !== t)
545
+ throw new Error(
546
+ `_centerColumnWidths out of sync: ${this._renderer._centerColumnWidths.length} widths, ${t} center cols`
547
+ );
548
+ });
549
+ }
550
+ assertHeaderCountMatchesColumnCount() {
551
+ }
552
+ // DEV: CSS --grid-columns token count should match column count (best-effort)
553
+ assertCssColumnsMatchColumns() {
554
+ this.check(() => {
555
+ const t = this._grid._renderer._gridContainerEl.style.getPropertyValue("--grid-columns").trim();
556
+ if (!t) return;
557
+ const e = t.split(/\s+/).filter(Boolean);
558
+ if (e.length !== this._renderer._visibleColDefs.length)
559
+ throw new Error(
560
+ `CSS columns mismatch: tokens=${e.length}, columns=${this._renderer._visibleColDefs.length}, value="${t}"`
561
+ );
562
+ this.print(`assertCssColumnsMatchColumns: tokens.length===this._grid.columns.length===${this._renderer._visibleColDefs.length}`);
563
+ });
564
+ }
565
+ // DEV: each rendered row must have correct cell count and valid dataset indices
566
+ assertRenderedRowsValid(t, e) {
567
+ this.check(() => {
568
+ const r = this._renderer._visibleColDefs.filter((n) => n.pinned !== "left");
569
+ for (let n = 0; n < t; n++) {
570
+ const i = this._renderer.renderedRowDivs[n];
571
+ if (!i) throw new Error(`Missing rowDiv at rendered index ${n}`);
572
+ if (i.children.length !== r.length)
573
+ throw new Error(
574
+ `Row cell count mismatch: rowChildren=${i.children.length}, centerCols=${r.length}`
575
+ );
576
+ const s = Number(i.dataset.rowIndex), l = Number(i.dataset.arrayIndex), a = i.dataset.rowIndex !== void 0, o = i.dataset.arrayIndex !== void 0;
577
+ if (a && !Number.isInteger(s))
578
+ throw new Error(`Invalid row.dataset.rowIndex="${i.dataset.rowIndex}"`);
579
+ if (o && !Number.isInteger(l))
580
+ throw new Error(`Invalid row.dataset.arrayIndex="${i.dataset.arrayIndex}"`);
581
+ if (a && s !== e + n)
582
+ throw new Error(
583
+ `rowIndex drift: expected=${e + n}, actual=${s}`
584
+ );
585
+ }
586
+ });
587
+ }
588
+ assertColumnWidthsLengthMatchColumnsLength() {
589
+ this.check(() => {
590
+ const t = this._renderer._visibleColDefs.filter((r) => r.pinned === "left"), e = this._renderer._visibleColDefs.filter((r) => r.pinned !== "left");
591
+ if (this._renderer._centerColumnWidths.length !== e.length)
592
+ throw new Error(
593
+ `_centerColumnWidths/centerCols mismatch: widths=${this._renderer._centerColumnWidths.length}, centerCols=${e.length}`
594
+ );
595
+ if (this._renderer._leftColumnWidths.length !== t.length)
596
+ throw new Error(
597
+ `_leftColumnWidths/leftCols mismatch: widths=${this._renderer._leftColumnWidths.length}, leftCols=${t.length}`
598
+ );
599
+ this.print("assertWidthsMatchColumns");
600
+ });
601
+ }
602
+ assertPopulateRowsPreCheck(t, e) {
603
+ this.check(() => {
604
+ if (!this._grid._renderer._centerBodyEl) throw new Error("populateRows: _centerBodyEl is null");
605
+ if (!this._grid._renderer._centerRowsContainerEl) throw new Error("populateRows: _rowsContainer is null");
606
+ if (!this._grid._renderer._gridContainerEl) throw new Error("populateRows: _gridContainer is null");
607
+ if (!Number.isInteger(t) || t < 0)
608
+ throw new Error(`populateRows: invalid rowCount=${t}`);
609
+ if (!Number.isInteger(e) || e < 0)
610
+ throw new Error(`populateRows: invalid firstRenderedRowIndex=${e}`);
611
+ if (t > this._renderer.renderedRowDivs.length)
612
+ throw new Error(
613
+ `populateRows: rowCount (${t}) exceeds rendered row pool (${this._renderer.renderedRowDivs.length}). Did createEmptyRows() run with the right count?`
614
+ );
615
+ const r = this._renderer._visibleColDefs.filter((i) => i.pinned === "left"), n = this._renderer._visibleColDefs.filter((i) => i.pinned !== "left");
616
+ if (this._renderer._centerColumnWidths.length !== n.length)
617
+ throw new Error(
618
+ `populateRows: centerCols/widths mismatch: cols=${n.length}, widths=${this._renderer._centerColumnWidths.length}`
619
+ );
620
+ if (this._renderer._leftColumnWidths.length !== r.length)
621
+ throw new Error(
622
+ `populateRows: leftCols/widths mismatch: cols=${r.length}, widths=${this._renderer._leftColumnWidths.length}`
623
+ );
624
+ this.print(`assertPopulateRowsPreCheck: rowCount===${t}; firstRenderedRowIndex===${e}`);
625
+ });
626
+ }
627
+ assertWidthsMatch() {
628
+ this.check(() => {
629
+ const t = this._renderer._visibleColDefs.filter((r) => r.pinned === "left"), e = this._renderer._visibleColDefs.filter((r) => r.pinned !== "left");
630
+ if (this._renderer._centerColumnWidths.length !== e.length)
631
+ throw new Error(
632
+ `assertWidthsMatch: centerCols/widths mismatch: cols=${e.length}, widths=${this._renderer._centerColumnWidths.length}`
633
+ );
634
+ if (this._renderer._leftColumnWidths.length !== t.length)
635
+ throw new Error(
636
+ `assertWidthsMatch: leftCols/widths mismatch: cols=${t.length}, widths=${this._renderer._leftColumnWidths.length}`
637
+ );
638
+ });
639
+ }
640
+ assertPopulateRowsPostCheck(t, e) {
641
+ this.check(() => {
642
+ if (this._grid.activeRowIndex == null || !this._grid.activeColField) return;
643
+ const r = e, n = t > 0 ? e + t - 1 : e - 1, i = this._grid.activeRowIndex >= r && this._grid.activeRowIndex <= n, s = this._grid._renderer._centerBodyEl.querySelector(`.${g.active_cell}`);
644
+ if (!i) {
645
+ if (s) {
646
+ const u = s.closest(".cellux-row");
647
+ throw new Error(
648
+ `populateRows: found an active cell in DOM even though active row is not rendered. activeRow=${this._grid.activeRowIndex}, renderedRange=${r}-${n}, staleDomRowIndex=${u?.dataset.rowIndex}, staleArrayIndex=${u?.dataset.arrayIndex}, staleText=${s.textContent}`
649
+ );
650
+ }
651
+ return;
652
+ }
653
+ if (!i) {
654
+ if (s)
655
+ throw new Error(
656
+ `populateRows: found an active cell in DOM even though active row is not rendered. activeRow=${this._grid.activeRowIndex}, renderedRange=${r}-${n}`
657
+ );
658
+ return;
659
+ }
660
+ if (!s)
661
+ throw new Error(
662
+ `populateRows: active row is rendered but no active cell in DOM. activeRow=${this._grid.activeRowIndex}, field=${this._grid.activeColField}, renderedRange=${r}-${n}`
663
+ );
664
+ s && i && this._consoleLog && this.print(`Active Cell Content: ${s.textContent}`);
665
+ const l = s.closest(".cellux-row");
666
+ if (!l) throw new Error("populateRows: active cell exists but no row parent");
667
+ const a = Number(l.dataset.rowIndex), o = Array.from(l.children).indexOf(s), d = this._renderer._visibleColDefs[o]?.field ?? null;
668
+ if (a !== this._grid.activeRowIndex || d !== this._grid.activeColField)
669
+ throw new Error(
670
+ `populateRows: active mismatch. expected gi=${this._grid.activeRowIndex} field=${this._grid.activeColField} but DOM has gi=${a} field=${d}`
671
+ );
672
+ this.print("assertPopulateRowsPostCheck");
673
+ });
674
+ }
675
+ assertColumnSync() {
676
+ }
677
+ assertVisibleColOrder() {
678
+ this.check(() => {
679
+ const t = this._renderer._allColDefs.filter((r) => !r.hide), e = this._renderer._visibleColDefs;
680
+ if (t.length !== e.length)
681
+ throw new Error(
682
+ `assertVisibleColOrder: length mismatch — _allColDefs yields ${t.length} visible, _visibleColDefs has ${e.length}`
683
+ );
684
+ t.forEach((r, n) => {
685
+ if (r.field !== e[n].field)
686
+ throw new Error(
687
+ `assertVisibleColOrder: mismatch at index ${n} — _allColDefs says "${r.field}", _visibleColDefs says "${e[n].field}"`
688
+ );
689
+ }), this.print(t), this.print(e);
690
+ });
691
+ }
692
+ assertCenterColDefsSync() {
693
+ this.check(() => {
694
+ if (this._renderer._centerColDefs.length !== this._renderer._centerColumnWidths.length)
695
+ throw new Error(
696
+ `_centerColDefs/widths mismatch: colDefs=${this._renderer._centerColDefs.length}, widths=${this._renderer._centerColumnWidths.length}`
697
+ );
698
+ if (this._renderer._leftColDefs.length !== this._renderer._leftColumnWidths.length)
699
+ throw new Error(
700
+ `_leftColDefs/widths mismatch: colDefs=${this._renderer._leftColDefs.length}, widths=${this._renderer._leftColumnWidths.length}`
701
+ );
702
+ });
703
+ }
704
+ assertPanelColDefsMatchVisible() {
705
+ this.check(() => {
706
+ const t = this._renderer._visibleColDefs.filter((r) => r.pinned === "left"), e = this._renderer._visibleColDefs.filter((r) => r.pinned !== "left");
707
+ if (this._renderer._leftColDefs.length !== t.length)
708
+ throw new Error(
709
+ `_leftColDefs out of sync with _visibleColDefs: leftColDefs=${this._renderer._leftColDefs.length}, expected=${t.length}`
710
+ );
711
+ if (this._renderer._centerColDefs.length !== e.length)
712
+ throw new Error(
713
+ `_centerColDefs out of sync with _visibleColDefs: centerColDefs=${this._renderer._centerColDefs.length}, expected=${e.length}`
714
+ );
715
+ t.forEach((r, n) => {
716
+ if (this._renderer._leftColDefs[n]?.field !== r.field)
717
+ throw new Error(
718
+ `_leftColDefs field mismatch at ${n}: expected="${r.field}", got="${this._renderer._leftColDefs[n]?.field}"`
719
+ );
720
+ }), e.forEach((r, n) => {
721
+ if (this._renderer._centerColDefs[n]?.field !== r.field)
722
+ throw new Error(
723
+ `_centerColDefs field mismatch at ${n}: expected="${r.field}", got="${this._renderer._centerColDefs[n]?.field}"`
724
+ );
725
+ });
726
+ });
727
+ }
728
+ assertHeaderDomMatchesPanelColDefs() {
729
+ this.check(() => {
730
+ const t = this._renderer._centerHeaderInnerEl.querySelectorAll(".header-cell");
731
+ if (t.length !== this._renderer._centerColDefs.length)
732
+ throw new Error(
733
+ `Center header DOM/colDefs mismatch: DOM=${t.length}, _centerColDefs=${this._renderer._centerColDefs.length}`
734
+ );
735
+ const e = this._renderer._leftHeaderInnerEl.querySelectorAll(".header-cell");
736
+ if (e.length !== this._renderer._leftColDefs.length)
737
+ throw new Error(
738
+ `Left header DOM/colDefs mismatch: DOM=${e.length}, _leftColDefs=${this._renderer._leftColDefs.length}`
739
+ );
740
+ });
741
+ }
742
+ assertNoDuplicateFields() {
743
+ this.check(() => {
744
+ const t = this._renderer._allColDefs.map((r) => r.field);
745
+ if (new Set(t).size !== t.length) {
746
+ const r = t.filter((n, i) => t.indexOf(n) !== i);
747
+ throw new Error(`Duplicate fields in _allColDefs: ${r.join(", ")}`);
748
+ }
749
+ });
750
+ }
751
+ assertHiddenColsNotVisible() {
752
+ this.check(() => {
753
+ const t = this._renderer._allColDefs.filter((e) => e.hide);
754
+ for (const e of t)
755
+ if (this._renderer._visibleColDefs.find((r) => r.field === e.field))
756
+ throw new Error(
757
+ `Hidden column "${e.field}" found in _visibleColDefs`
758
+ );
759
+ });
760
+ }
761
+ assertPanelCellCountMatchesColDefs() {
762
+ this.check(() => {
763
+ const t = this._renderer._centerColDefs.length;
764
+ this._renderer._centerRenderedRowDivs.forEach((r, n) => {
765
+ const i = r.children.length;
766
+ if (i !== t)
767
+ throw new Error(
768
+ `Center row ${n} has ${i} cells but _centerColDefs has ${t} columns`
769
+ );
770
+ });
771
+ const e = this._renderer._leftColDefs.length;
772
+ this._renderer._leftRenderedRowDivs.forEach((r, n) => {
773
+ const i = r.children.length;
774
+ if (i !== e)
775
+ throw new Error(
776
+ `Left row ${n} has ${i} cells but _leftColDefs has ${e} columns`
777
+ );
778
+ });
779
+ });
780
+ }
781
+ assertHeaderCellCountMatchesColDefs() {
782
+ this.check(() => {
783
+ const t = this._renderer._centerHeaderInnerEl?.children.length ?? 0;
784
+ if (t !== this._renderer._centerColDefs.length)
785
+ throw new Error(
786
+ `Center header has ${t} cells but _centerColDefs has ${this._renderer._centerColDefs.length}`
787
+ );
788
+ const e = this._renderer._leftHeaderInnerEl?.children.length ?? 0;
789
+ if (e !== this._renderer._leftColDefs.length)
790
+ throw new Error(
791
+ `Left header has ${e} cells but _leftColDefs has ${this._renderer._leftColDefs.length}`
792
+ );
793
+ });
794
+ }
795
+ print(t) {
796
+ this._consoleLog && console.log(t);
797
+ }
798
+ }
799
+ class fe {
800
+ constructor(t) {
801
+ if (this._grid = t, this._centerColumnWidths = [], this._leftColumnWidths = [], this._leftRenderedRowDivs = [], this._centerRenderedRowDivs = [], this._visibleColDefs = [], this._allColDefs = [], this._leftColDefs = [], this._centerColDefs = [], this._firstDataRendered = !1, this.buildGridSkeleton = () => {
802
+ const e = g;
803
+ this._rootEl.innerHTML = `
804
+ <div class="${e.cx_grid_container}" data-grid tabindex="0">
805
+
806
+ <div class="${e.grid_viewport}">
807
+
808
+ <!-- Left Pinned Zone -->
809
+ <!-- I set --grid-columns in updateGridTemplateColumns-->
810
+ <div class="${e.left_panel}" >
811
+ <div class="${e.header} ${e.header_left}">
812
+ <div class="${e.header_inner}">
813
+ ${this._leftColDefs.map((r, n) => `
814
+ <div class="${e.header_cell}"
815
+ ${C.dataColIndex}="${n}"
816
+ ${C.dataField}="${r.field}"
817
+ draggable="true">
818
+ <span class="${e.header_label}" style="${r.sortable !== !1 ? "cursor:pointer" : ""}">
819
+ ${r.headerName}
820
+ </span>
821
+ <span class="${e.header_menu_icon}" ${C.dataColIndex}="${n}" ${C.dataField}="${r.field}">☰</span>
822
+ <span class="${e.col_resizer}" aria-hidden="true"></span>
823
+ </div>`).join("")}
824
+ </div>
825
+ </div>
826
+ <div class="${e.grid_body} ${e.grid_body_left} ">
827
+ <div class="${e.rows_container} ${e.rows_container_left} "></div>
828
+ </div>
829
+ </div>
830
+
831
+ <!-- Center Zone -->
832
+ <!-- I set --grid-columns in updateGridTemplateColumns-->
833
+ <div class="${e.center_panel}">
834
+ <div class="${e.header} ${e.header_center}">
835
+ <div class="${e.header_inner}">
836
+ ${this._centerColDefs.map((r, n) => `
837
+ <div class="${e.header_cell}"
838
+ ${C.dataColIndex}="${n}"
839
+ ${C.dataField}="${r.field}"
840
+ draggable="true">
841
+ <span class="${e.header_label}" style="${r.sortable !== !1 ? "cursor:pointer" : ""}">
842
+ ${r.headerName}
843
+ </span>
844
+ <span class="${e.header_menu_icon}"
845
+ ${C.dataColIndex}="${n}"
846
+ ${C.dataField}="${r.field}">☰</span>
847
+ <span class="${e.col_resizer}" aria-hidden="true"></span>
848
+ </div>`).join("")}
849
+ </div>
850
+ </div>
851
+ <div class="${e.grid_body} ${e.grid_body_center}">
852
+ <div class="${e.rows_container} ${e.rows_container_center}"></div>
853
+ </div>
854
+ </div>
855
+
856
+ </div>
857
+
858
+ <div class="${e.status_bar}">
859
+ <!--Nothing for now -->
860
+ <span></span>
861
+ </div>
862
+
863
+ </div>`, this.cacheDOMElements(), this._assertions.assertDomWired(), this.updateGridTemplateColumns(), this.updateLeftZoneWidth();
864
+ }, !this._grid.rootEl) throw new Error("rootEl undefined in Renderer ctor");
865
+ if (!this._grid.options) throw new Error("options undefined in Renderer ctor");
866
+ this._rootEl = this._grid.rootEl, this._options = this._grid.options, this._allColDefs = this._options.columnDefs.map((e) => this._grid.resolveColDef(e)), this.recomputeColDefsAndWidths(), this._assertions = new ue(this._grid, this);
867
+ }
868
+ /**
869
+ * Measure the visible height of the scrollable grid body and publish it to state.
870
+ * Used during initial setup to give the virtualizer a real viewport height so it
871
+ * can compute how many rows to render. Safely no-ops if the body isn’t laid out yet
872
+ * (clientHeight === 0). On a successful read, flips `viewportMeasured` so the initial
873
+ * render path can skip re-measuring; later size changes are handled by the ResizeObserver.
874
+ * If there are any that is.
875
+ */
876
+ measureViewportHeight() {
877
+ const t = this._rootEl.querySelector(`.${g.grid_body_center}`);
878
+ t && t.clientHeight > 0 && (this._grid.currentState.viewportHeight = t.clientHeight);
879
+ }
880
+ // public updateGridTemplateColumns(): void {
881
+ // const u = util;
882
+ // // Center zone
883
+ // const centerEl = this._rootEl.querySelector<HTMLElement>('.center-panel');
884
+ // if (centerEl) {
885
+ // const centerTemplate = u.convertWidthArrayToString(this._centerColumnWidths);
886
+ // centerEl.style.setProperty('--grid-columns', centerTemplate);
887
+ // } else {
888
+ // }
889
+ // // Left zone
890
+ // const leftEl = this._leftEl;
891
+ // if (leftEl) {
892
+ // const leftTemplate = u.convertWidthArrayToString(this._leftColumnWidths);
893
+ // leftEl.style.setProperty('--grid-columns', leftTemplate);
894
+ // } else {
895
+ // }
896
+ // }
897
+ updateGridTemplateColumns() {
898
+ const t = N;
899
+ if (this._centerPanelEl) {
900
+ const e = this._centerColumnWidths.length > 0 ? t.convertWidthArrayToString(this._centerColumnWidths) : "0px";
901
+ this._centerPanelEl.style.setProperty("--grid-columns", e);
902
+ }
903
+ if (this._leftPanelEl) {
904
+ const e = this._leftColumnWidths.length > 0 ? t.convertWidthArrayToString(this._leftColumnWidths) : "0px";
905
+ this._leftPanelEl.style.setProperty("--grid-columns", e);
906
+ }
907
+ }
908
+ resetRowPool() {
909
+ this._centerRenderedRowDivs = [], this._leftRenderedRowDivs = [];
910
+ }
911
+ /**
912
+ * Initializes the recycled DOM pool with `n` empty row divs.
913
+ *
914
+ * Creates row container divs with pre-structured cell children, one cell per column.
915
+ * These rows form a reusable pool for virtual scrolling - as the user scrolls, these
916
+ * same DOM elements are repositioned and repopulated with different data rather than
917
+ * creating/destroying elements continuously.
918
+ *
919
+ * Called once during grid initialization. If the pool already has `n` or more rows,
920
+ * no new elements are created (idempotent).
921
+ *
922
+ * @param n - Number of row divs to ensure exist in the pool
923
+ */
924
+ initializePool(t, e, r, n) {
925
+ const i = g;
926
+ for (; r.length < t; ) {
927
+ const s = document.createElement("div");
928
+ s.className = i.row, s.setAttribute("role", "row"), e.forEach(() => {
929
+ const l = document.createElement("div");
930
+ l.className = i.cell, l.setAttribute("role", "grid_cell"), s.appendChild(l);
931
+ }), n.appendChild(s), r.push(s);
932
+ }
933
+ }
934
+ initializeRowPool(t) {
935
+ this.initializePool(
936
+ t,
937
+ this._centerColDefs,
938
+ this._centerRenderedRowDivs,
939
+ this._centerRowsContainerEl
940
+ ), this._assertions.assertColumnWidthsLengthMatchColumnsLength(), this._assertions.assertHeaderCountMatchesColumnCount();
941
+ }
942
+ initializeLeftRowPool(t) {
943
+ this.initializePool(
944
+ t,
945
+ this._leftColDefs,
946
+ this._leftRenderedRowDivs,
947
+ this._leftRowsContainerEl
948
+ );
949
+ }
950
+ populatePanel(t, e, r, n, i) {
951
+ const s = g;
952
+ if (this._options.rowData) {
953
+ for (let l = 0; l < t; l++) {
954
+ const a = this._grid._filteredAndSortedIndices[e + l];
955
+ if (a === void 0) {
956
+ if (!i) throw new Error("populatePanel: arrayIndex is undefined.");
957
+ return;
958
+ }
959
+ const o = Math.round((e + l) * this._grid.currentState.rowHeight), d = n[l];
960
+ if (!d) throw new Error(`populatePanel: rowDiv at index ${l} is undefined.`);
961
+ const u = this._options.rowData[a];
962
+ if (!u) {
963
+ d.classList.remove(s.active_row), d.dataset.arrayIndex = "", d.dataset.rowIndex = "", d.dataset.yPos = "";
964
+ for (let c = 0; c < d.children.length; c++) {
965
+ const f = d.children[c];
966
+ f.classList.remove(s.active_cell), f.classList.remove(s.visual_cell);
967
+ }
968
+ continue;
969
+ }
970
+ d.style.transform = `translate3d(0, ${o}px, 0)`, d.dataset.arrayIndex = String(a), d.dataset.rowIndex = String(e + l), d.dataset.yPos = o.toString(), i || (a === this._grid.activeArrayIndex ? d.classList.add(s.active_row) : d.classList.remove(s.active_row)), r.forEach((c, f) => {
971
+ const _ = d.children[f];
972
+ if (!_) {
973
+ if (!i) throw new Error(`populatePanel: missing cell at colIndex ${f}.`);
974
+ return;
975
+ }
976
+ this.populateCell(_, c, u, a, e + l);
977
+ const p = this._grid.activeRowIndex === e + l && this._grid.activeColField === c.field;
978
+ _.classList.toggle(s.active_cell, p), _.classList.toggle(s.visual_cell, p);
979
+ });
980
+ }
981
+ for (let l = t; l < n.length; l++) {
982
+ const a = n[l];
983
+ if (a) {
984
+ a.classList.remove(s.active_row), a.dataset.arrayIndex = "", a.dataset.rowIndex = "", a.dataset.yPos = "", i && (a.style.display = "none");
985
+ for (let o = 0; o < a.children.length; o++) {
986
+ const d = a.children[o];
987
+ d.classList.remove(s.active_cell), d.classList.remove(s.visual_cell);
988
+ }
989
+ }
990
+ }
991
+ }
992
+ }
993
+ populateCenterRows(t, e) {
994
+ this._options.rowData && (this._assertions.assertPopulateRowsPreCheck(t, e), this.populatePanel(
995
+ t,
996
+ e,
997
+ this._centerColDefs,
998
+ this._centerRenderedRowDivs,
999
+ !1
1000
+ ), !this._firstDataRendered && t > 0 && (this._firstDataRendered = !0, this._options.onFirstDataRendered?.({
1001
+ api: this._grid,
1002
+ rowCount: this._options.rowData.length
1003
+ })), this._assertions.assertRenderedRowsValid(t, e), this._assertions.assertColumnSync(), this._grid.updateDebugOverlay());
1004
+ }
1005
+ populateLeftRows(t, e) {
1006
+ this._options.rowData && this._leftColDefs.length !== 0 && this.populatePanel(
1007
+ t,
1008
+ e,
1009
+ this._leftColDefs,
1010
+ this._leftRenderedRowDivs,
1011
+ !0
1012
+ );
1013
+ }
1014
+ updateLeftZoneWidth() {
1015
+ if (!this._leftPanelEl) return;
1016
+ const t = this._leftColumnWidths.reduce((e, r) => e + r, 0);
1017
+ this._leftPanelEl.style.width = `${t}px`;
1018
+ }
1019
+ cacheDOMElements() {
1020
+ const t = g;
1021
+ this._gridContainerEl = this._rootEl.querySelector(`.${t.cx_grid_container}`), this.cacheCheck(this._gridContainerEl, `${t.cx_grid_container}`), this._centerHeaderEl = this._rootEl.querySelector(`.${t.header_center}`), this.cacheCheck(this._centerHeaderEl, `.${t.header_center}`), this._leftHeaderEl = this._rootEl.querySelector(`.${t.header_left}`), this.cacheCheck(this._leftHeaderEl, `.${t.header_left}`), this._centerHeaderInnerEl = this._rootEl.querySelector(`.${t.header_center} .${t.header_inner}`), this.cacheCheck(this._centerHeaderInnerEl, `.${t.header_center} .${t.header_inner}`), this._centerBodyEl = this._rootEl.querySelector(`.${t.grid_body_center}`), this.cacheCheck(this._centerBodyEl, `.${t.grid_body_center}`), this._centerRowsContainerEl = this._rootEl.querySelector(`.${t.rows_container_center}`), this.cacheCheck(this._centerRowsContainerEl, `.${t.rows_container_center}`), this._centerPanelEl = this._rootEl.querySelector(`.${t.center_panel}`), this.cacheCheck(this._centerPanelEl, `.${t.center_panel}`), this._leftPanelEl = this._rootEl.querySelector(`.${t.left_panel}`), this.cacheCheck(this._leftPanelEl, `.${t.left_panel}`), this._leftHeaderInnerEl = this._rootEl.querySelector(`.${t.header_left} .${t.header_inner}`), this.cacheCheck(this._leftHeaderInnerEl, `.${t.header_left} .${t.header_inner}`), this._leftBodyEl = this._rootEl.querySelector(".grid-body-left"), this.cacheCheck(this._leftBodyEl), this._leftRowsContainerEl = this._rootEl.querySelector(`.${t.rows_container_left}`), this.cacheCheck(this._leftRowsContainerEl, `.${t.rows_container_left}`);
1022
+ }
1023
+ cacheCheck(t, e = "MISSING") {
1024
+ const r = `Check Renderer::cacheDOMElements!! classList: ${e}`;
1025
+ if (!t) throw new Error(r);
1026
+ }
1027
+ headerCallbacks() {
1028
+ Array.from(L().children), this._visibleColDefs.forEach((t, e) => {
1029
+ });
1030
+ }
1031
+ // On Renderer
1032
+ syncRowVisibility(t) {
1033
+ for (let e = 0; e < this._centerRenderedRowDivs.length; e++) {
1034
+ const r = this._centerRenderedRowDivs[e];
1035
+ if (!r) throw new Error(`syncRowVisibility: center rowDiv at index ${e} is undefined`);
1036
+ r.style.display = e < t ? "" : "none";
1037
+ }
1038
+ for (let e = 0; e < this._leftRenderedRowDivs.length; e++) {
1039
+ const r = this._leftRenderedRowDivs[e];
1040
+ if (!r) throw new Error(`syncRowVisibility: left rowDiv at index ${e} is undefined`);
1041
+ r.style.display = e < t ? "" : "none";
1042
+ }
1043
+ }
1044
+ syncHorizontalHeaderScroll(t) {
1045
+ if (!this._centerHeaderInnerEl)
1046
+ throw new Error("_centerHeaderInnerEl undefined in syncHeaderScroll");
1047
+ this._centerHeaderInnerEl.style.transform = `translateX(${-t}px)`;
1048
+ }
1049
+ destroy() {
1050
+ this._centerRenderedRowDivs = [];
1051
+ }
1052
+ test() {
1053
+ return this._centerRenderedRowDivs;
1054
+ }
1055
+ prepareCellForRender(t) {
1056
+ t.className = g.cell, t.removeAttribute("style");
1057
+ }
1058
+ // ~mdev
1059
+ populateCell(t, e, r, n, i) {
1060
+ this._assertions.check(() => {
1061
+ if (!e?.field) throw new Error("updateCell: col is missing field");
1062
+ }), this.prepareCellForRender(t);
1063
+ const s = {
1064
+ data: r,
1065
+ rowIndex: i,
1066
+ arrayIndex: n,
1067
+ colDef: e,
1068
+ api: this._grid.api,
1069
+ value: r?.[e.field],
1070
+ cellElement: t
1071
+ }, l = e.valueGetter ? e.valueGetter({ cellElement: t, data: r, rowIndex: i, arrayIndex: n, colDef: e, api: this._grid.api, value: r?.[e.field] }) : r?.[e.field];
1072
+ s.value = l;
1073
+ const a = e.valueFormatter ? e.valueFormatter(s) : l;
1074
+ if (e.cellStyle && this.applyCellStyle(t, e.cellStyle, s), e.cellClass && this.applyCellClass(t, e.cellClass, s), e.cellRenderer) {
1075
+ const o = e.cellRenderer(s);
1076
+ t.innerHTML = "", typeof o == "string" ? t.innerHTML = o : t.appendChild(o);
1077
+ } else
1078
+ t.textContent = String(a ?? "");
1079
+ }
1080
+ applyCellClass(t, e, r) {
1081
+ if (!e) return;
1082
+ const n = typeof e == "function" ? e(r) : e;
1083
+ Array.isArray(n) ? t.classList.add(...n) : n && t.classList.add(n);
1084
+ }
1085
+ applyCellStyle(t, e, r) {
1086
+ if (!e) return;
1087
+ const n = typeof e == "function" ? e(r) : e;
1088
+ if (e) {
1089
+ const i = { ...n };
1090
+ if (i.textAlign && !i.justifyContent) {
1091
+ const s = String(i.textAlign), l = {
1092
+ left: "flex-start",
1093
+ right: "flex-end",
1094
+ center: "center",
1095
+ justify: "space-between"
1096
+ // bonus: makes justify work too
1097
+ };
1098
+ l[s] && (i.justifyContent = l[s], delete i.textAlign);
1099
+ }
1100
+ Object.assign(t.style, i);
1101
+ }
1102
+ }
1103
+ recomputeColDefsAndWidths() {
1104
+ this._visibleColDefs = this._allColDefs.filter((t) => !t.hide), this._leftColDefs = this._visibleColDefs.filter((t) => t.pinned === "left"), this._centerColDefs = this._visibleColDefs.filter((t) => t.pinned !== "left"), this._leftColumnWidths = this._leftColDefs.map((t) => t.width ?? 100), this._centerColumnWidths = this._centerColDefs.map((t) => t.width ?? 100);
1105
+ }
1106
+ recomputeRowDivs() {
1107
+ const { firstRenderedRowIndex: t, renderedRowCount: e } = this._grid.computeRenderedRowCount();
1108
+ this.resetRowPool(), this.initializeRowPool(e), this.initializeLeftRowPool(e);
1109
+ }
1110
+ buildHeaderCell(t, e) {
1111
+ const r = document.createElement("div");
1112
+ return r.className = g.header_cell, r.setAttribute(`${C.dataField}`, t.field), r.setAttribute(`${C.dataColIndex}`, String(e)), r.draggable = !0, r.innerHTML = `
1113
+ <span class="${g.header_label}" style="${t.sortable !== !1 ? "cursor:pointer" : ""}">
1114
+ ${t.headerName}
1115
+ </span>
1116
+ <span class="${g.header_menu_icon}" ${C.dataColIndex}="${e}" ${C.dataField}="${t.field}">☰</span>
1117
+ <span class="${g.col_resizer}" ${C.dataResizeIndex}="${e}" aria-hidden="true"></span>
1118
+ `, r;
1119
+ }
1120
+ get renderedRowDivs() {
1121
+ return this._centerRenderedRowDivs;
1122
+ }
1123
+ get firstDataRendered() {
1124
+ return this._firstDataRendered;
1125
+ }
1126
+ get rootEl() {
1127
+ return this._rootEl;
1128
+ }
1129
+ get bodyEl() {
1130
+ return this._centerBodyEl;
1131
+ }
1132
+ get headerInnerEl() {
1133
+ return this._centerHeaderInnerEl;
1134
+ }
1135
+ }
1136
+ class _e {
1137
+ constructor(t) {
1138
+ if (this._grid = t, this._columnFiltersMap = /* @__PURE__ */ new Map(), this._filteredIndices = [], !this._grid.options)
1139
+ throw new Error("options undefined in Filter constructor");
1140
+ this._grid.options.rowData && (this._filteredIndices = [...Array(this._grid.options.rowData.length).keys()]);
1141
+ }
1142
+ loadFilterState() {
1143
+ if (!this._grid.options) return;
1144
+ const t = this._grid.options;
1145
+ if (!t.filterStateKey) return;
1146
+ const e = localStorage.getItem(t.filterStateKey);
1147
+ if (e)
1148
+ try {
1149
+ const r = JSON.parse(e);
1150
+ this._columnFiltersMap.clear(), r.forEach((n) => {
1151
+ t.columnDefs.some((s) => s.field === n.field) && n.filterValues && n.filterValues.length > 0 && this._columnFiltersMap.set(n.field, new Set(n.filterValues));
1152
+ });
1153
+ } catch (r) {
1154
+ console.warn("Failed to load filter state. Not necessarily a bad thing.", r), localStorage.removeItem(t.filterStateKey);
1155
+ }
1156
+ }
1157
+ saveFilterState() {
1158
+ if (!this._grid.options || !this._grid.options.filterStateKey) return;
1159
+ const t = [];
1160
+ this._columnFiltersMap.forEach((e, r) => {
1161
+ t.push({
1162
+ field: r,
1163
+ filterValues: Array.from(e)
1164
+ });
1165
+ }), localStorage.setItem(
1166
+ this._grid.options.filterStateKey,
1167
+ JSON.stringify(t)
1168
+ );
1169
+ }
1170
+ applyColumnFilters() {
1171
+ if (!this._grid.options)
1172
+ return;
1173
+ if (this._columnFiltersMap.size === 0) {
1174
+ this._filteredIndices = [...Array(this._grid.options.rowData.length).keys()], this._grid.onFilterChanged(), this.saveFilterState();
1175
+ return;
1176
+ }
1177
+ const e = [...Array(this._grid.options.rowData.length).keys()].filter((r) => {
1178
+ const n = this._grid.options.rowData[r];
1179
+ if (!n) throw new Error("row undefined in applyColumnFilters");
1180
+ for (const [i, s] of this._columnFiltersMap) {
1181
+ const l = n[i];
1182
+ if (!s.has(l))
1183
+ return !1;
1184
+ }
1185
+ return !0;
1186
+ });
1187
+ this._filteredIndices = [...e], this._grid.onFilterChanged(), this.saveFilterState();
1188
+ }
1189
+ getDistinctValuesByField(t) {
1190
+ if (!this._grid.options) return [];
1191
+ const e = /* @__PURE__ */ new Set();
1192
+ return this._grid.options.rowData.forEach((r) => {
1193
+ const n = r[t];
1194
+ e.add(n);
1195
+ }), Array.from(e).sort((r, n) => r == null && n == null ? 0 : r == null ? 1 : n == null ? -1 : this._grid.collator.compare(String(r), String(n)));
1196
+ }
1197
+ clearColumnFilter(t) {
1198
+ this._columnFiltersMap.has(t) && (this._columnFiltersMap.delete(t), this.applyColumnFilters());
1199
+ }
1200
+ clearColumnFilters() {
1201
+ this._columnFiltersMap.clear();
1202
+ const t = this._grid.options;
1203
+ t && (this._filteredIndices = [...Array(t.rowData.length).keys()], this._grid._sort.applySort(), this._grid.updateTotalRowsDisplay(), this._grid.refreshGrid(), this._grid._tabBuilder.updateFilterIcons(), this.saveFilterState());
1204
+ }
1205
+ get filteredIndices() {
1206
+ return this._filteredIndices;
1207
+ }
1208
+ set filteredIndices(t) {
1209
+ this._filteredIndices = [...t];
1210
+ }
1211
+ }
1212
+ class pe {
1213
+ constructor(t) {
1214
+ if (this._grid = t, this.sortModelArray = [], this.updateSortModel = (e, r = !1) => {
1215
+ if (!this._grid.options) return;
1216
+ let n = Array.isArray(this.sortModelArray) ? [...this.sortModelArray] : [];
1217
+ if (r) {
1218
+ const i = n.find((s) => s.field === e);
1219
+ i ? i.dir === "asc" ? i.dir = "desc" : n = n.filter((s) => s.field !== e) : n.push({ field: e, dir: "asc" });
1220
+ } else {
1221
+ const i = n.find((s) => s.field === e);
1222
+ i ? i.dir === "asc" ? n = [{ field: e, dir: "desc" }] : n = [] : n = [{ field: e, dir: "asc" }];
1223
+ }
1224
+ this.sortModelArray = [...n], this.onSortChanged(this.sortModelArray);
1225
+ }, this.compare = (e, r, n) => {
1226
+ const i = e == null, s = r == null;
1227
+ if (i || s) return i === s ? 0 : (i ? 1 : -1) * (n === "asc" ? 1 : -1);
1228
+ if (typeof e == "number" && typeof r == "number")
1229
+ return (e < r ? -1 : e > r ? 1 : 0) * (n === "asc" ? 1 : -1);
1230
+ if (e instanceof Date && r instanceof Date) {
1231
+ const a = e.getTime() - r.getTime();
1232
+ return (a === 0 ? 0 : a < 0 ? -1 : 1) * (n === "asc" ? 1 : -1);
1233
+ }
1234
+ return this._grid.collator.compare(String(e), String(r)) * (n === "asc" ? 1 : -1);
1235
+ }, !this._grid.options)
1236
+ throw new Error("options undefined in Filter constructor");
1237
+ this._grid.options.rowData && (this._grid._filter.filteredIndices = [...Array(this._grid.options.rowData.length).keys()]);
1238
+ }
1239
+ onSortChanged(t) {
1240
+ this._grid.options && (this._grid._colStateMgr.saveColumnState(), this.applySort(), this.updateHeaderSortIndicators(), this._grid.options.onSortChanged?.(this.sortModelArray));
1241
+ }
1242
+ applySort() {
1243
+ this.prepareFilteredSort();
1244
+ const { firstRenderedRowIndex: t, renderedRowCount: e } = this._grid.computeRenderedRowCount();
1245
+ this._grid._renderer.populateCenterRows(e, t), this._grid._renderer.populateLeftRows(e, t);
1246
+ }
1247
+ // Check to see if we're sorting filtered data. IF SO,
1248
+ // spread from this._filter.filteredIndices.
1249
+ prepareFilteredSort() {
1250
+ const t = [...this._grid._filter.filteredIndices];
1251
+ this.sortModelArray.length > 0 && this.sortRows(t), this._grid._filteredAndSortedIndices = t;
1252
+ }
1253
+ // indices -> mutate in place.
1254
+ sortRows(t) {
1255
+ const e = this._grid.options;
1256
+ e && t.sort((r, n) => {
1257
+ const i = e.rowData[r], s = e.rowData[n];
1258
+ if (!i || !s)
1259
+ throw new Error(`sortRows: rowData undefined at index ${r} or ${n}`);
1260
+ for (const { field: l, dir: a } of this.sortModelArray) {
1261
+ const o = this.compare(i[l], s[l], a);
1262
+ if (o !== 0) return o;
1263
+ }
1264
+ return 0;
1265
+ });
1266
+ }
1267
+ updateHeaderSortIndicators() {
1268
+ const t = this._grid._renderer._centerHeaderEl.querySelectorAll(`[${C.dataField}]`), e = this._grid._renderer._leftHeaderEl.querySelectorAll(`[${C.dataField}]`);
1269
+ this._updateHeaderSortIndicators(t), this._updateHeaderSortIndicators(e);
1270
+ }
1271
+ _updateHeaderSortIndicators(t) {
1272
+ const e = g;
1273
+ t.forEach((r) => {
1274
+ const n = r.getAttribute(C.dataField), i = P(r, this._grid);
1275
+ if (!i) return;
1276
+ const s = i.headerValueGetter ? i.headerValueGetter(i) : i.headerName, l = r.querySelector(`.${e.header_label}`);
1277
+ if (!l) return;
1278
+ const a = this.sortModelArray.findIndex((f) => f.field === n);
1279
+ if (a === -1) {
1280
+ l.textContent = s;
1281
+ return;
1282
+ }
1283
+ const u = this.sortModelArray[a].dir === "asc" ? " ▲" : " ▼", c = this.sortModelArray.length > 1 ? ` ${a + 1}` : "";
1284
+ l.textContent = s + u + c;
1285
+ });
1286
+ }
1287
+ getNodeList() {
1288
+ return this._grid._renderer._centerHeaderEl.querySelectorAll(`[${C.dataField}]`);
1289
+ }
1290
+ }
1291
+ class ge {
1292
+ constructor(t) {
1293
+ this._grid = t, this._activeTab = "filter", this._containerEl = document.createElement("div"), this._containerEl.className = "fn-column-menu";
1294
+ }
1295
+ build(t, e, r) {
1296
+ return this._containerEl.innerHTML = `
1297
+ <div class="fn-column-menu-tabs">
1298
+ <div class="fn-tab fn-tab-active" data-tab="filter">Filter</div>
1299
+ <div class="fn-tab" data-tab="columns">Columns</div>
1300
+ <div class="fn-tab" data-tab="general">General</div>
1301
+ <div class="fn-tab fn-tab-close" data-tab="close">&times;</div>
1302
+ </div>
1303
+ <div class="fn-column-menu-body"></div>
1304
+ `, this._tabDivs = { filter: t, columns: r, general: e }, this.wireTabs(), this.showTab(this._activeTab), this._containerEl;
1305
+ }
1306
+ wireTabs() {
1307
+ this._containerEl.querySelectorAll(".fn-tab").forEach((t) => {
1308
+ const e = t;
1309
+ e.dataset.tab === "close" ? e.addEventListener("click", () => this._containerEl.remove()) : e.addEventListener("click", () => {
1310
+ const r = e.dataset.tab;
1311
+ this.showTab(r);
1312
+ });
1313
+ });
1314
+ }
1315
+ showTab(t) {
1316
+ const e = this._containerEl.querySelector(".fn-column-menu-body");
1317
+ e.innerHTML = "", e.appendChild(this._tabDivs[t]), this._containerEl.querySelectorAll(".fn-tab").forEach((r) => {
1318
+ r.classList.toggle("fn-tab-active", r.dataset.tab === t);
1319
+ });
1320
+ }
1321
+ }
1322
+ class me {
1323
+ constructor(t) {
1324
+ if (this._grid = t, this.collator = new Intl.Collator(void 0, { numeric: !0, sensitivity: "base" }), this._tabContainerEl = null, !this._grid.options)
1325
+ throw new Error("options undefined in Filter constructor");
1326
+ this._grid.options.rowData;
1327
+ }
1328
+ updateFilterIcons() {
1329
+ const t = g, e = this._grid._renderer._centerHeaderEl.querySelectorAll(`.${t.header_cell}`);
1330
+ if (!e) {
1331
+ console.error("updateFilterIcons: headerCells div undefined");
1332
+ return;
1333
+ }
1334
+ e.forEach((r) => {
1335
+ const n = r.dataset.field;
1336
+ if (!n) {
1337
+ console.error("updateFilterIcons: field attribute undefined");
1338
+ return;
1339
+ }
1340
+ const i = r.querySelector(`.${t.header_menu_icon}`);
1341
+ if (!i) {
1342
+ console.error("updateFilterIcons: icon div undefined");
1343
+ return;
1344
+ }
1345
+ n && this.isColumnFiltered(n) ? (i.classList.add("filtered"), i.textContent = "⚑") : (i.classList.remove("filtered"), i.textContent = "☰");
1346
+ });
1347
+ }
1348
+ isColumnFiltered(t) {
1349
+ return this._grid._filter._columnFiltersMap.has(t);
1350
+ }
1351
+ buildTabContainer(t, e) {
1352
+ if (!this._grid.options) return;
1353
+ const r = e.dataset.field, n = document.querySelector(".fn-filter-dropdown");
1354
+ if (n) {
1355
+ n.remove();
1356
+ return;
1357
+ }
1358
+ const i = new ge(this._grid);
1359
+ let s = null, l = null, a = null;
1360
+ this._grid.options.onBuildFilterTab && (s = this._grid.options.onBuildFilterTab(r, this._grid)), s || (s = this.buildFilterTab(t, e)), this._grid.options.onBuildFieldListTab && (l = this._grid.options.onBuildFieldListTab(r, this._grid)), l || (l = this.buildFieldListTab(t, e)), this._grid.options.onBuildGeneralTab && (a = this._grid.options.onBuildGeneralTab(r, this._grid)), a || (a = this.buildGeneralTab(t, e)), this._tabContainerEl = i.build(s, a, l), this._tabContainerEl.classList.add("fn-filter-dropdown");
1361
+ const o = e.getBoundingClientRect();
1362
+ this._tabContainerEl.style.left = `${o.left}px`, this._tabContainerEl.style.top = `${o.bottom + 4}px`, this._tabContainerEl.addEventListener("click", (c) => {
1363
+ c.stopPropagation();
1364
+ });
1365
+ const d = () => {
1366
+ console.log("closeMenu"), this._tabContainerEl.remove(), u.removeEventListener("scroll", d), window.removeEventListener("scroll", d);
1367
+ }, u = this._grid._renderer._centerBodyEl;
1368
+ u.addEventListener("scroll", d, { once: !0 }), window.addEventListener("scroll", d, { once: !0 }), setTimeout(() => {
1369
+ document.addEventListener("click", d, { once: !0 });
1370
+ }, 0), document.body.appendChild(this._tabContainerEl);
1371
+ }
1372
+ buildFilterTab(t, e) {
1373
+ const r = g, n = document.createElement("div");
1374
+ if (n.textContent = "ERROR MISSING", !this._grid.options) return n;
1375
+ const i = e.closest(`.${r.header_cell}`);
1376
+ if (!i)
1377
+ return console.warn("headerEl undefined in buildFilterTab"), n;
1378
+ const s = i.dataset.field, l = this._grid.options.columnDefs.find((m) => m.field === s);
1379
+ if (!l) return n;
1380
+ const a = this._grid._filter.getDistinctValuesByField(s), o = this._grid._filter._columnFiltersMap.get(s), d = o !== void 0, u = document.createElement("div");
1381
+ u.className = "fn-filter-tab-content", u.innerHTML = `
1382
+ <div class="fn-filter-dropdown-header">
1383
+ Filter: ${l.headerName}
1384
+ </div>
1385
+ <div class="fn-filter-search-box">
1386
+ <input type="text" placeholder="Search..." class="fn-filter-search-input" />
1387
+ </div>
1388
+ <div class="fn-filter-item fn-filter-select-all">
1389
+ <label>
1390
+ <input type="checkbox" ${d ? "" : "checked"} class="select-all-checkbox" />
1391
+ <span>(Select All)</span>
1392
+ </label>
1393
+ </div>
1394
+ <div class="fn-filter-dropdown-list">
1395
+ ${a.map((m) => {
1396
+ const y = !d || o.has(m);
1397
+ return `
1398
+ <div class="fn-filter-item" data-filter-value="${m ?? ""}">
1399
+ <label>
1400
+ <input type="checkbox" ${y ? "checked" : ""} class="value-checkbox" data-value="${m ?? ""}" />
1401
+ <span>${m ?? "(blank)"}</span>
1402
+ </label>
1403
+ </div>
1404
+ `;
1405
+ }).join("")}
1406
+ </div>
1407
+ `;
1408
+ const c = u.querySelector(".fn-filter-search-input"), f = u.querySelectorAll(".fn-filter-item:not(.fn-filter-select-all)");
1409
+ c.addEventListener("input", () => {
1410
+ const m = c.value.toLowerCase();
1411
+ f.forEach((y) => {
1412
+ const w = y.dataset.filterValue || "", v = String(w).toLowerCase();
1413
+ y.style.display = v.includes(m) ? "" : "none";
1414
+ });
1415
+ }), requestAnimationFrame(() => c.focus());
1416
+ const _ = u.querySelector(`.${g.select_all_checkbox}`), p = u.querySelectorAll(".value-checkbox"), R = Array.from(p).every((m) => m.checked), b = Array.from(p).every((m) => !m.checked);
1417
+ return _.indeterminate = !R && !b, _.addEventListener("change", () => {
1418
+ p.forEach((m) => m.checked = _.checked), _.indeterminate = !1, this.updateColumnFilterByField(s, p);
1419
+ }), p.forEach((m) => {
1420
+ m.addEventListener("change", () => {
1421
+ const y = Array.from(p).every((v) => v.checked), w = Array.from(p).every((v) => !v.checked);
1422
+ _.checked = y, _.indeterminate = !y && !w, this.updateColumnFilterByField(s, p);
1423
+ });
1424
+ }), u;
1425
+ }
1426
+ buildFieldListTab(t, e) {
1427
+ const n = this._grid.api.getAllColumns().map((o) => ({ field: o.field, headerName: o.headerName, hide: o.hide ?? !1 })).sort((o, d) => o.headerName.toLowerCase().localeCompare(d.headerName.toLowerCase())), i = document.createElement("div");
1428
+ i.className = "fn-filter-list", i.innerHTML = `<div class="fn-filter-search-box">
1429
+ <input type="text" placeholder="Search..." class="fn-filter-search-input" />
1430
+ </div>`, n.forEach((o) => {
1431
+ const d = document.createElement("div");
1432
+ d.className = "fn-filter-item", d.setAttribute("data-filter-value", o.field), d.innerHTML = `
1433
+ <label>
1434
+ <input type="checkbox" ${o.hide ? "" : "checked"} class="field-checkbox" data-value="${o.field}" />
1435
+ <span>${o.headerName} (${o.field})</span>
1436
+ </label>
1437
+ `, i.appendChild(d);
1438
+ });
1439
+ const s = i.querySelector(".fn-filter-search-input"), l = i.querySelectorAll(".fn-filter-item");
1440
+ return s.addEventListener("input", () => {
1441
+ const o = s.value.toLowerCase();
1442
+ l.forEach((d) => {
1443
+ const u = d.dataset.filterValue || "", c = String(u).toLowerCase();
1444
+ d.style.display = c.includes(o) ? "" : "none";
1445
+ });
1446
+ }), i.querySelectorAll(".field-checkbox").forEach((o) => {
1447
+ o.addEventListener("change", () => {
1448
+ const d = o.getAttribute("data-value"), u = o.checked;
1449
+ this.showHideFields(d, u);
1450
+ });
1451
+ }), i;
1452
+ }
1453
+ buildGeneralTab(t, e) {
1454
+ this._grid;
1455
+ const r = g, n = document.createElement("div");
1456
+ if (n.textContent = "ERROR in buildGeneralTab", !this._grid.options || !this._grid.options.columnDefs) return n;
1457
+ const i = document.createElement("div"), l = e.closest(`.${r.header_cell}`).dataset.field, a = this._grid._renderer._visibleColDefs.find((p) => p.field === l), o = a?.pinned === "left";
1458
+ let d = document.createElement("div");
1459
+ d.innerHTML = `
1460
+ <label>
1461
+ <input type="checkbox" ${o ? "checked" : ""} class="pinned-checkbox" />
1462
+ <span>Pin Column Left</span>
1463
+ </label>`, d.className = r.fn_filter_item;
1464
+ const u = d.querySelector(".pinned-checkbox");
1465
+ u && u.addEventListener("change", () => {
1466
+ this._grid.pinColumn(a, u.checked);
1467
+ }), i.append(d);
1468
+ let c = document.createElement("div");
1469
+ c.textContent = "Autosize This Column", c.addEventListener("click", (p) => {
1470
+ console.log("itemAutosizeColumnEl", p), a && l && (this._grid.autoSizeColumn(l), this._tabContainerEl.remove());
1471
+ }, { once: !1 }), c.className = r.fn_filter_item, i.append(c);
1472
+ const f = document.createElement("div");
1473
+ f.textContent = "Autosize All Columns", f.className = r.fn_filter_item, f.addEventListener("click", (p) => {
1474
+ this._grid.autoSizeAllColumns(), this._tabContainerEl.remove();
1475
+ }, { once: !1 }), i.append(f);
1476
+ const _ = document.createElement("div");
1477
+ return _.textContent = "Reset Columns", _.className = r.fn_filter_item, _.addEventListener("click", (p) => {
1478
+ a && l && (this._grid.resetAllColumns(), this._tabContainerEl.remove());
1479
+ }, { once: !1 }), i.append(_), i.className = r.fn_filter_list, i;
1480
+ }
1481
+ showHideFields(t, e) {
1482
+ this._grid.api.setColumnVisible(t, e);
1483
+ }
1484
+ updateColumnFilterByField(t, e) {
1485
+ const r = /* @__PURE__ */ new Set();
1486
+ e.forEach((i) => {
1487
+ if (i.checked) {
1488
+ const s = i.dataset.value;
1489
+ let l;
1490
+ if (s === "")
1491
+ l = null;
1492
+ else {
1493
+ const a = Number(s);
1494
+ !isNaN(a) && s.trim() !== "" ? l = a : l = s;
1495
+ }
1496
+ r.add(l);
1497
+ }
1498
+ });
1499
+ const n = this._grid._filter.getDistinctValuesByField(t);
1500
+ console.log("All distinct values:", n.length), r.size === n.length ? (this._grid._filter._columnFiltersMap.delete(t), console.log("Removed filter - all checked")) : (this._grid._filter._columnFiltersMap.set(t, r), console.log("Set filter with", r.size, "values")), this._grid._filter.applyColumnFilters(), this.updateFilterIcons();
1501
+ }
1502
+ }
1503
+ class Ce {
1504
+ constructor(t) {
1505
+ this._grid = t, this.cn = g, this.onGridMouseEvent = (e) => {
1506
+ const r = e.target, n = g;
1507
+ if (!(r instanceof HTMLElement) || e.type === "mouseover" || e.type === "mouseenter" || e.type === "mousemove" || e.type === "mouseout")
1508
+ return;
1509
+ if (e.type === "click" && r.classList.contains(n.header_menu_icon)) {
1510
+ e.stopPropagation(), e.preventDefault(), this._grid._tabBuilder.buildTabContainer(e, r);
1511
+ return;
1512
+ }
1513
+ if (e.type === "click" && r.closest(`.${n.header_cell}`)) {
1514
+ this._grid.onColumnSort(e);
1515
+ return;
1516
+ }
1517
+ if (e.type === "click" && this._grid.updateDebugOverlay(), e.type === "dblclick" && r.closest(`.${n.cell}`) && e.preventDefault(), e.type === "mousedown" && r.classList.contains(n.col_resizer)) {
1518
+ this._grid.onResizerMouseDown(e);
1519
+ return;
1520
+ }
1521
+ if (e.type === "dblclick" && r.classList.contains(n.col_resizer)) {
1522
+ this._grid.onAutoResizeColumn(e);
1523
+ return;
1524
+ }
1525
+ const i = r.closest(`.${n.cell}`);
1526
+ if (!i) return;
1527
+ const s = I(i);
1528
+ if (!s) {
1529
+ console.error("getRowFromCell failed in onGridMouseEvent");
1530
+ return;
1531
+ }
1532
+ if (s.closest(`.${this.cn.rows_container_left}`), s.closest(`.${this.cn.rows_container_center}`), e.type === "contextmenu") {
1533
+ if (e.shiftKey || e.ctrlKey)
1534
+ return;
1535
+ const d = $(s);
1536
+ if (d === null) return;
1537
+ this._grid._activeArrayIndex = d, this._grid._activeRowElement = s, localStorage.setItem("activeRowArrayIndex", String(d)), this._grid.setActiveRow(s), this._grid.setActiveCell(i), this._grid.updateDebugOverlay(), this._grid._contextMenu.onContextMenu(e);
1538
+ return;
1539
+ }
1540
+ if (e.type === "click") {
1541
+ const d = $(s);
1542
+ if (d === null) return;
1543
+ this._grid._activeArrayIndex = d, this._grid._activeRowElement = s, localStorage.setItem("activeRowArrayIndex", String(d)), this._grid.setActiveRow(s), this._grid.setActiveCell(i), this._grid.updateDebugOverlay();
1544
+ }
1545
+ const l = this._grid.getCellEventParams(i, e);
1546
+ if (e.type === "dblclick" && l?.colDef?.editable === !0) {
1547
+ this._grid.startCellEditing(e, i);
1548
+ return;
1549
+ }
1550
+ const a = this._grid._rowEventMap[e.type];
1551
+ if (a && this._grid._options[a]) {
1552
+ const d = this._grid.getRowEventParams(e);
1553
+ if (d === null) {
1554
+ console.error("Grid rowEvent null");
1555
+ return;
1556
+ }
1557
+ this._grid._options[a](d);
1558
+ }
1559
+ const o = this._grid._cellEventMap[e.type];
1560
+ if (o && l.colDef[o]) {
1561
+ if (l === null) {
1562
+ console.error("Grid cellEvent null");
1563
+ return;
1564
+ }
1565
+ l.colDef[o](l);
1566
+ }
1567
+ }, this.onGridKeyDown = (e) => {
1568
+ if (e.key === "Tab") {
1569
+ this._grid.handleTabNavigation(e);
1570
+ return;
1571
+ }
1572
+ if (!this._grid._renderer._centerBodyEl) throw new Error("_centerBodyEl undefined in onGridKeyDown");
1573
+ const r = this._grid._renderer._centerBodyEl.querySelector(`.${this.cn.active_cell}`) ?? this._grid._renderer._leftBodyEl?.querySelector(`.${this.cn.active_cell}`);
1574
+ if (!r) {
1575
+ this._grid.focusCell(0, 0);
1576
+ return;
1577
+ }
1578
+ if (!(r.querySelector("input") !== null) && e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
1579
+ e.preventDefault(), this._grid.startCellEditing(e, r, e.key);
1580
+ return;
1581
+ }
1582
+ if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "PageUp", "PageDown", "Home", "End"].includes(e.key))
1583
+ return;
1584
+ e.preventDefault(), e.stopPropagation();
1585
+ const i = I(r);
1586
+ if (!i) return;
1587
+ const s = S(r, i);
1588
+ if (s === null) return;
1589
+ const l = x(i);
1590
+ if (l === null) return;
1591
+ const a = this._grid._getPinnedCount(), u = (!!i.closest(`.${this.cn.rows_container_left}`) ? 0 : a) + s;
1592
+ let c = l, f = u;
1593
+ const _ = this._grid._renderer._visibleColDefs.length, p = Math.floor(this._grid.currentState.viewportHeight / this._grid.currentState.rowHeight);
1594
+ switch (e.key) {
1595
+ case "ArrowUp":
1596
+ c = Math.max(0, l - 1);
1597
+ break;
1598
+ case "ArrowDown":
1599
+ c = Math.min(this._grid._filteredAndSortedIndices.length - 1, l + 1);
1600
+ break;
1601
+ case "ArrowLeft":
1602
+ f = Math.max(0, u - 1);
1603
+ break;
1604
+ case "ArrowRight":
1605
+ f = Math.min(_ - 1, u + 1);
1606
+ break;
1607
+ case "PageUp":
1608
+ c = Math.max(0, l - p);
1609
+ break;
1610
+ case "PageDown":
1611
+ c = Math.min(this._grid._filteredAndSortedIndices.length - 1, l + p);
1612
+ break;
1613
+ case "Home":
1614
+ e.ctrlKey && (c = 0), f = 0;
1615
+ break;
1616
+ case "End":
1617
+ e.ctrlKey && (c = this._grid._filteredAndSortedIndices.length - 1), f = _ - 1;
1618
+ break;
1619
+ }
1620
+ if (c === l && f === u) {
1621
+ this._grid._console.print("no movement");
1622
+ return;
1623
+ }
1624
+ this._grid.focusCell(c, f);
1625
+ };
1626
+ }
1627
+ }
1628
+ class we {
1629
+ constructor(t) {
1630
+ this._grid = t, this.loadColumnState = () => {
1631
+ if (!this._grid._options.columnStateKey) return;
1632
+ const e = localStorage.getItem(this._grid._options.columnStateKey);
1633
+ if (!e) return;
1634
+ const r = JSON.parse(e), n = new Map(r.map((o) => [o.field, o]));
1635
+ for (const o of this._grid._renderer._allColDefs) {
1636
+ const d = n.get(o.field);
1637
+ d && (o.pinned = d.pinned === "left" ? "left" : void 0, o.width = d.columnWidth, o.hide = d.hide ?? !1);
1638
+ }
1639
+ this._grid._renderer.recomputeColDefsAndWidths();
1640
+ const i = (o, d) => {
1641
+ const u = new Map(d.map((_) => [_.field, _])), c = [], f = [];
1642
+ for (const _ of o) {
1643
+ const p = u.get(_.field);
1644
+ p ? c.push({ col: _, state: p }) : f.push(_);
1645
+ }
1646
+ return [
1647
+ ...c.sort((_, p) => _.state.columnOrder - p.state.columnOrder).map((_) => _.col),
1648
+ ...f
1649
+ ];
1650
+ }, s = r.filter((o) => o.pinned === "left" && !o.hide), l = r.filter((o) => o.pinned !== "left" && !o.hide);
1651
+ this._grid._renderer._leftColDefs = i(this._grid._renderer._leftColDefs, s), this._grid._renderer._centerColDefs = i(this._grid._renderer._centerColDefs, l), this._grid._renderer._leftColumnWidths = this._grid._renderer._leftColDefs.map((o) => n.get(o.field)?.columnWidth ?? o.width ?? 100), this._grid._renderer._centerColumnWidths = this._grid._renderer._centerColDefs.map((o) => n.get(o.field)?.columnWidth ?? o.width ?? 100), this._grid._renderer._visibleColDefs = [
1652
+ ...this._grid._renderer._leftColDefs,
1653
+ ...this._grid._renderer._centerColDefs
1654
+ ];
1655
+ const a = this._grid._renderer._allColDefs.filter((o) => o.hide);
1656
+ this._grid._renderer._allColDefs = [...this._grid._renderer._visibleColDefs, ...a], this._grid._sort.sortModelArray = r.filter((o) => o.sortDir && o.sortDir !== "none" && o.sortPriority !== void 0).sort((o, d) => o.sortPriority - d.sortPriority).map((o) => ({ field: o.field, dir: o.sortDir }));
1657
+ };
1658
+ }
1659
+ saveColumnState() {
1660
+ if (!this._grid._options.columnStateKey) return;
1661
+ const t = this._grid._renderer._leftColDefs.map((i, s) => {
1662
+ const l = this._grid._sort.sortModelArray.findIndex((d) => d.field === i.field), a = l >= 0 ? this._grid._sort.sortModelArray[l] : void 0, o = this._grid._renderer._leftColumnWidths[s];
1663
+ if (o === void 0) throw new Error(`saveColumnState: left width undefined at index ${s}`);
1664
+ return {
1665
+ columnOrder: s,
1666
+ field: i.field,
1667
+ columnWidth: o,
1668
+ pinned: "left",
1669
+ hide: !1,
1670
+ sortDir: a?.dir ?? "none",
1671
+ sortPriority: l >= 0 ? l : void 0
1672
+ };
1673
+ }), e = this._grid._renderer._centerColDefs.map((i, s) => {
1674
+ const l = this._grid._sort.sortModelArray.findIndex((d) => d.field === i.field), a = l >= 0 ? this._grid._sort.sortModelArray[l] : void 0, o = this._grid._renderer._centerColumnWidths[s];
1675
+ if (o === void 0) throw new Error(`saveColumnState: center width undefined at index ${s}`);
1676
+ return {
1677
+ columnOrder: s,
1678
+ field: i.field,
1679
+ columnWidth: o,
1680
+ pinned: null,
1681
+ hide: !1,
1682
+ sortDir: a?.dir ?? "none",
1683
+ sortPriority: l >= 0 ? l : void 0
1684
+ };
1685
+ }), r = this._grid._renderer._allColDefs.filter((i) => i.hide).map((i, s) => ({
1686
+ columnOrder: t.length + e.length + s,
1687
+ field: i.field,
1688
+ columnWidth: i.width ?? 100,
1689
+ pinned: null,
1690
+ hide: !0,
1691
+ sortDir: "none",
1692
+ sortPriority: void 0
1693
+ })), n = [...t, ...e, ...r];
1694
+ localStorage.setItem(
1695
+ this._grid._options.columnStateKey,
1696
+ JSON.stringify(n)
1697
+ );
1698
+ }
1699
+ }
1700
+ class ve {
1701
+ // #endregion decl
1702
+ constructor(t, e) {
1703
+ this._rootEl = t, this._options = e, this._debug = !1, this._consoleLog = !0, this._showDebugOverlay = !0, this.cn = g, this._api = null, this._quickFilterText = "", this.MIN_COLUMN_WIDTH = 50, this.MAX_COLUMN_WIDTH = 800, this.gu = N, this._scrollRafId = null, this._pendingScrollTop = 0, this._editInput = null, this._debugEnabled = !0, this._debugEl = null, this._activeArrayIndex = null, this._contextMenuEl = null, this._activeRowIndex = null, this._activeColField = null, this._filteredAndSortedIndices = [], this.collator = new Intl.Collator(void 0, { numeric: !0, sensitivity: "base" }), this._cellEventMap = Z, this._rowEventMap = J, this.currentState = {
1704
+ /**
1705
+ * Current vertical scroll position in pixels, measured from the top of the scrollable content.
1706
+ *
1707
+ * Starts at 0 when scrolled to the top. Increases as the user scrolls down.
1708
+ * Used to calculate which rows are currently visible in the viewport and need to be rendered.
1709
+ * Updated continuously during scroll events.
1710
+ *
1711
+ * Example: If scrollTop is 320px and rowHeight is 32px, the first visible row is at index 10.
1712
+ */
1713
+ scrollTop: 0,
1714
+ /**
1715
+ * The visible height of the scrollable grid body in pixels.
1716
+ *
1717
+ * Used to calculate how many rows can fit in the visible area, which determines
1718
+ * the size of the recycled DOM pool for virtual scrolling. Measured once during
1719
+ * grid initialization from the actual rendered height of the body element.
1720
+ */
1721
+ viewportHeight: 0,
1722
+ // Row height in pixels
1723
+ rowHeight: 0,
1724
+ // this is set in options and copied over.
1725
+ /**
1726
+ * Number of extra rows to render above/below the visible viewport.
1727
+ * Reduces flashing during scroll by pre-rendering rows just outside view.
1728
+ */
1729
+ rowBuffer: 3,
1730
+ totalRows: 0
1731
+ }, this.onResizerMouseDown = (r) => {
1732
+ const n = g, i = r.target.closest(`.${n.header_cell}`);
1733
+ if (!i) return;
1734
+ r.preventDefault(), r.stopPropagation();
1735
+ const s = H(i);
1736
+ if (s === null || !Number.isInteger(s)) return;
1737
+ const l = !!i.closest(`.${n.header_left}`), a = r.clientX, o = l ? this._renderer._leftColumnWidths[s] : this.getColumnWidthInPixels(s), d = (c) => {
1738
+ const f = c.clientX - a, _ = Math.max(50, o + f);
1739
+ l ? (this._renderer._leftColumnWidths[s] = _, this._renderer.updateGridTemplateColumns(), this._renderer.updateLeftZoneWidth()) : this.resizeColumnWidth(s, _);
1740
+ }, u = () => {
1741
+ this._colStateMgr.saveColumnState(), document.removeEventListener("mousemove", d), document.removeEventListener("mouseup", u);
1742
+ };
1743
+ document.addEventListener("mousemove", d), document.addEventListener("mouseup", u);
1744
+ }, this.onScroll = () => {
1745
+ const r = this._renderer._centerBodyEl?.scrollTop ?? 0, n = this._renderer._centerBodyEl?.scrollLeft ?? 0, i = r !== this.currentState.scrollTop;
1746
+ this._pendingScrollTop = r, this._renderer._leftBodyEl.scrollTop = r, this._renderer.syncHorizontalHeaderScroll(n), this._scrollRafId === null && (this._scrollRafId = requestAnimationFrame(() => {
1747
+ this._scrollRafId = null, this.currentState.scrollTop = this._pendingScrollTop;
1748
+ const { firstRenderedRowIndex: s, renderedRowCount: l } = this.computeRenderedRowCount();
1749
+ this._renderer.populateCenterRows(l, s), i && this._renderer.populateLeftRows(l, s);
1750
+ }));
1751
+ }, this.onColumnSort = (r) => {
1752
+ const n = r.target;
1753
+ if (n.classList.contains(g.col_resizer)) return;
1754
+ const i = n.closest(`[${C.dataField}]`);
1755
+ if (!i) return;
1756
+ const s = T(i);
1757
+ if (!s) return;
1758
+ const l = this.getColDef(s);
1759
+ l && l.sortable !== !1 && this._sort.updateSortModel(s, r.shiftKey);
1760
+ }, this.commitCellEdit = () => {
1761
+ const r = this._editingCell;
1762
+ if (!r) return;
1763
+ const { cell: n, colDef: i, rowData: s, arrayIndex: l, rowIndex: a, originalValue: o, customEditor: d } = r, u = i.field;
1764
+ n.classList.remove(this.cn.cell_editing);
1765
+ const c = this._editInput, f = d;
1766
+ this._editingCell = null, this._editInput = null;
1767
+ let _;
1768
+ if (f)
1769
+ _ = f.getValue(), f.destroy?.();
1770
+ else if (c)
1771
+ _ = c.value, c.isConnected && c.remove();
1772
+ else
1773
+ return;
1774
+ const p = o, R = {
1775
+ data: s,
1776
+ rowIndex: a,
1777
+ arrayIndex: l,
1778
+ colDef: i,
1779
+ cellElement: n,
1780
+ oldValue: p,
1781
+ newValue: _,
1782
+ value: p,
1783
+ api: this.api
1784
+ };
1785
+ if (i.valueSetter) {
1786
+ if (!i.valueSetter(R)) {
1787
+ this._renderer.populateCell(n, i, s, l, a), i.onCellEditingStopped && i.onCellEditingStopped({
1788
+ data: s,
1789
+ rowIndex: a,
1790
+ arrayIndex: l,
1791
+ colDef: i,
1792
+ // value: rowData[column.field],
1793
+ value: s[u],
1794
+ cellElement: n
1795
+ }), this.setActiveCell(n);
1796
+ return;
1797
+ }
1798
+ } else
1799
+ s[u] = _;
1800
+ const b = s[u];
1801
+ if (i.onCellValueChanged) {
1802
+ const m = (v) => typeof v == "string" ? this.gu.normalizeTextSoft(v) : v, y = m(p);
1803
+ if (m(b) !== y) {
1804
+ const v = {
1805
+ data: s,
1806
+ rowIndex: a,
1807
+ arrayIndex: l,
1808
+ colDef: i,
1809
+ cellElement: n,
1810
+ oldValue: p,
1811
+ value: b,
1812
+ newValue: b,
1813
+ // Use the actual applied value
1814
+ api: this.api
1815
+ };
1816
+ i.onCellValueChanged(v);
1817
+ }
1818
+ }
1819
+ i.onCellEditingStopped && i.onCellEditingStopped({
1820
+ data: s,
1821
+ rowIndex: a,
1822
+ arrayIndex: l,
1823
+ colDef: i,
1824
+ value: b,
1825
+ cellElement: n
1826
+ // ~AS
1827
+ }), this._renderer.populateCell(n, i, s, l, a), this.setActiveCell(n), this._renderer._gridContainerEl?.focus({ preventScroll: !0 });
1828
+ }, this.cancelCellEdit = (r = !1) => {
1829
+ const n = this._editingCell, i = this._editInput;
1830
+ if (!n) return;
1831
+ this._editingCell = null, this._editInput = null, i?.isConnected && i.remove();
1832
+ const { cell: s, colDef: l, rowData: a, arrayIndex: o, rowIndex: d } = n;
1833
+ this._renderer.populateCell(s, l, a, o, d), l.onCellEditingStopped && l.onCellEditingStopped({
1834
+ data: a,
1835
+ rowIndex: d,
1836
+ arrayIndex: o,
1837
+ colDef: l,
1838
+ value: a[l.field],
1839
+ cellElement: s
1840
+ // ~AS
1841
+ }), r || this.setActiveCell(s);
1842
+ }, this.getColDef = (r) => ((this._renderer._allColDefs.find((i) => i.field === r) ?? null) || console.warn(`Field param ${r} not found`), this._renderer._allColDefs.find((i) => i.field === r) ?? null), this.setRowData = (r) => {
1843
+ this._options.rowData = r, this._filteredAndSortedIndices = [...Array(r.length).keys()], this._filter.clearColumnFilters(), this._sort.prepareFilteredSort(), this._activeArrayIndex = null, this._activeRowIndex = null, this._activeColField = null, this.refreshGrid();
1844
+ }, this._quickFilter = new de(this), this._statusBar = new ae(this, t), this._contextMenu = new ce(this), this._console = new he(this), this._renderer = new fe(this), this._filter = new _e(this), this._tabBuilder = new me(this), this._sort = new pe(this), this._gridEvents = new Ce(this), this._colStateMgr = new we(this), this.currentState.rowHeight = e.rowHeight ? e.rowHeight : 32, this._debugOverlay = new oe(this, this._renderer), this._options?.rowData && (this._filteredAndSortedIndices = [...Array(this._options.rowData.length).keys()]), this._filter.loadFilterState(), this._colStateMgr.loadColumnState();
1845
+ }
1846
+ resolveColDef(t) {
1847
+ return { ...this._options.defaultColDef ?? {}, ...t };
1848
+ }
1849
+ //************************************************************************************* */
1850
+ //************************************************************************************* */
1851
+ //********************************** LIFE CYCLE *************************************** */
1852
+ //************************************************************************************* */
1853
+ //************************************************************************************* */
1854
+ //#region LIFE CYCLE
1855
+ create() {
1856
+ const t = this._filteredAndSortedIndices.length;
1857
+ this._renderer.buildGridSkeleton(), this.applyRowHeight(this.currentState.rowHeight), this._renderer.resetRowPool(), this._renderer.updateLeftZoneWidth(), this._renderer._centerBodyEl.getBoundingClientRect(), this._renderer.measureViewportHeight(), this._statusBar.updateRowsPanel(), this._renderer._centerRowsContainerEl.style.height = `${t * this.currentState.rowHeight}px`, this._renderer._leftRowsContainerEl.style.height = `${t * this.currentState.rowHeight}px`, this._renderer._centerBodyEl.addEventListener("scroll", this.onScroll);
1858
+ const { firstRenderedRowIndex: e, renderedRowCount: r } = this.computeRenderedRowCount();
1859
+ this._options && (this._sort.prepareFilteredSort(), this._renderer.initializeRowPool(r), this._renderer.initializeLeftRowPool(r), this._renderer.populateCenterRows(r, e), this._renderer.populateLeftRows(r, e), this._sort.updateHeaderSortIndicators(), this.attachEvents(), this._filter._columnFiltersMap.size > 0 && (this._filter.applyColumnFilters(), this._tabBuilder.updateFilterIcons()), this._renderer.headerCallbacks(), this._options?.onGridReady?.({ api: this }));
1860
+ }
1861
+ applyRowHeight(t) {
1862
+ document.documentElement.style.setProperty("--cellux-grid-row-height", `${t}px`);
1863
+ }
1864
+ destroy() {
1865
+ this._renderer._centerBodyEl?.removeEventListener("scroll", this.onScroll), this.detachEvents(), this._renderer._centerRowsContainerEl = null, this._renderer._centerBodyEl = null, this._renderer._centerHeaderEl = null, this._renderer._gridContainerEl = null, this._statusBar.destroy(), this._renderer.destroy();
1866
+ }
1867
+ //#endregion LIFE CYCLE
1868
+ computeRenderedRowCount() {
1869
+ return O(this.currentState, this._filteredAndSortedIndices);
1870
+ }
1871
+ // #endregion
1872
+ //************************************************************************************* */
1873
+ //************************************************************************************* */
1874
+ //********************************* AUTO RESIZE *************************************** */
1875
+ //************************************************************************************* */
1876
+ //************************************************************************************* */
1877
+ //#region auto-resize
1878
+ onAutoResizeColumn(t) {
1879
+ if (t.shiftKey) {
1880
+ this.autoSizeAllColumns(), this._colStateMgr.saveColumnState();
1881
+ return;
1882
+ }
1883
+ const e = t.target.closest(`[${C.dataColIndex}]`);
1884
+ if (!e) {
1885
+ console.error("onAutoResizeColumn: error getting variable handle.");
1886
+ return;
1887
+ }
1888
+ const r = T(e);
1889
+ if (!r) {
1890
+ console.error("onAutoResizeColumn: error getting variable field.");
1891
+ return;
1892
+ }
1893
+ this.autoSizeColumn(r), this._colStateMgr.saveColumnState();
1894
+ }
1895
+ autoSizeColumn(t) {
1896
+ const { colIndex: e, isLeft: r } = K(t, this._renderer), n = r ? this._renderer._leftColDefs : this._renderer._centerColDefs;
1897
+ if (e === null) return;
1898
+ const i = n[e], s = document.createElement("div");
1899
+ s.style.visibility = "hidden", s.style.position = "absolute", s.style.whiteSpace = "nowrap", s.classList.add(g.cell), document.body.appendChild(s);
1900
+ let l = 0;
1901
+ s.textContent = i.headerName, l = Math.max(l, s.offsetWidth), (r ? this._renderer._leftRenderedRowDivs : this._renderer._centerRenderedRowDivs).forEach((o) => {
1902
+ if (o.style.display !== "none") {
1903
+ const d = o.children[e];
1904
+ d && (s.textContent = d.textContent || "", l = Math.max(l, s.offsetWidth));
1905
+ }
1906
+ }), document.body.removeChild(s), r ? this._renderer._leftColumnWidths[e] = Math.max(this.MIN_COLUMN_WIDTH, Math.min(this.MAX_COLUMN_WIDTH, l + 20)) : this._renderer._centerColumnWidths[e] = Math.max(this.MIN_COLUMN_WIDTH, Math.min(this.MAX_COLUMN_WIDTH, l + 20)), this._renderer.updateGridTemplateColumns();
1907
+ }
1908
+ // ~autoSizeAllColumns
1909
+ autoSizeAllColumns() {
1910
+ const t = document.createElement("div");
1911
+ t.style.visibility = "hidden", t.style.position = "absolute", t.style.whiteSpace = "nowrap", t.classList.add(g.cell), document.body.appendChild(t);
1912
+ const e = document.createElement("div");
1913
+ e.style.visibility = "hidden", e.style.position = "absolute", e.style.whiteSpace = "nowrap", e.style.display = "flex", e.style.alignItems = "center", e.style.gap = "4px", e.classList.add(g.header_cell), document.body.appendChild(e);
1914
+ const r = (n, i, s, l) => {
1915
+ n.forEach((a, o) => {
1916
+ let d = 0;
1917
+ const u = i.children[o];
1918
+ u && (e.innerHTML = u.innerHTML, d = Math.max(d, e.offsetWidth)), s.forEach((c) => {
1919
+ if (c.style.display !== "none") {
1920
+ const f = c.children[o];
1921
+ f && (t.textContent = f.textContent || "", d = Math.max(d, t.offsetWidth));
1922
+ }
1923
+ }), l[o] = Math.max(this.MIN_COLUMN_WIDTH, Math.min(this.MAX_COLUMN_WIDTH, d + 20));
1924
+ });
1925
+ };
1926
+ this._renderer._leftColDefs.length > 0 && r(
1927
+ this._renderer._leftColDefs,
1928
+ this._renderer._leftHeaderInnerEl,
1929
+ this._renderer._leftRenderedRowDivs,
1930
+ this._renderer._leftColumnWidths
1931
+ ), r(
1932
+ this._renderer._centerColDefs,
1933
+ this._renderer._centerHeaderInnerEl,
1934
+ this._renderer._centerRenderedRowDivs,
1935
+ this._renderer._centerColumnWidths
1936
+ ), document.body.removeChild(t), document.body.removeChild(e), this._renderer.updateGridTemplateColumns(), this._renderer.updateLeftZoneWidth();
1937
+ }
1938
+ //#endregion
1939
+ //************************************************************************************* */
1940
+ //************************************************************************************* */
1941
+ //************************************** EVENTS *************************************** */
1942
+ //************************************************************************************* */
1943
+ //************************************************************************************* */
1944
+ //#region Events
1945
+ attachEvents() {
1946
+ this.detachEvents();
1947
+ const t = this._renderer._gridContainerEl;
1948
+ this.eventAbortController = new AbortController(), Object.keys(this._cellEventMap).forEach((r) => {
1949
+ t?.addEventListener(r, this._gridEvents.onGridMouseEvent, {
1950
+ signal: this.eventAbortController.signal
1951
+ });
1952
+ }), this._renderer._gridContainerEl?.addEventListener("keydown", this._gridEvents.onGridKeyDown, {
1953
+ signal: this.eventAbortController.signal
1954
+ }), this.attachColumnReorderListeners();
1955
+ }
1956
+ setActiveCellCSS(t, e) {
1957
+ e ? (t.classList.add(g.active_cell), t.classList.add(g.visual_cell)) : (t.classList.remove(g.active_cell), t.classList.remove(g.visual_cell));
1958
+ }
1959
+ setActiveCell(t) {
1960
+ const e = this._renderer._centerBodyEl.querySelector(`.${this.cn.active_cell}`) ?? this._renderer._leftBodyEl?.querySelector(`.${this.cn.active_cell}`);
1961
+ e && this.setActiveCellCSS(e, !1), this.setActiveCellCSS(t, !0);
1962
+ const r = I(t);
1963
+ if (r) {
1964
+ this._activeRowIndex = x(r);
1965
+ const n = S(t, r), s = !!r.closest(`.${this.cn.rows_container_left}`) ? this._renderer._leftColDefs : this._renderer._centerColDefs;
1966
+ this._activeColField = n !== null ? s[n]?.field ?? null : null;
1967
+ }
1968
+ this._activeRowIndex !== null && this.ensureRowVisible(this._activeRowIndex), this._debugOverlay.updateDebugOverlay();
1969
+ }
1970
+ // public focusCell(rowIndex: number, colIndexGlobal: number): void {
1971
+ // this.ensureRowVisible(rowIndex);
1972
+ // const { firstRenderedRowIndex, renderedRowCount } = this.computeRenderedRowCount();
1973
+ // this._renderer.populateCenterRows(renderedRowCount, firstRenderedRowIndex);
1974
+ // this._renderer.populateLeftRows(renderedRowCount, firstRenderedRowIndex);
1975
+ // requestAnimationFrame(() => {
1976
+ // const pinnedCount = this._getPinnedCount();
1977
+ // const isLeft = colIndexGlobal < pinnedCount;
1978
+ // const panelColIndex = isLeft ? colIndexGlobal : colIndexGlobal - pinnedCount;
1979
+ // const rowDivs = isLeft
1980
+ // ? this._renderer._leftRenderedRowDivs
1981
+ // : this._renderer._centerRenderedRowDivs;
1982
+ // console.log('looking for rowIndex:', rowIndex);
1983
+ // console.log('leftRowDivs:', this._renderer._leftRenderedRowDivs.map(r => util.getRowIndexFromRow(r)));
1984
+ // const targetRowEl = rowDivs.find(row => util.getRowIndexFromRow(row) === rowIndex);
1985
+ // if (!targetRowEl) return;
1986
+ // // Debug
1987
+ // // console.log('isLeft:', isLeft, 'colIndexGlobal:', colIndexGlobal, 'pinnedCount:', pinnedCount);
1988
+ // // console.log('leftRowDivs:', this._renderer._leftRenderedRowDivs.map(r => util.getRowIndexFromRow(r)));
1989
+ // // console.log('targetRowEl:', targetRowEl);
1990
+ // const targetCellEl = targetRowEl.children[panelColIndex] as HTMLElement;
1991
+ // if (targetCellEl) {
1992
+ // this.setActiveCell(targetCellEl);
1993
+ // }
1994
+ // });
1995
+ // }
1996
+ focusCell(t, e) {
1997
+ const r = this._getPinnedCount(), n = e < r, i = n ? e : e - r, s = n ? this._renderer._leftColDefs : this._renderer._centerColDefs;
1998
+ this._activeRowIndex = t, this._activeColField = s[i]?.field ?? null, this.ensureRowVisible(t);
1999
+ const { firstRenderedRowIndex: l, renderedRowCount: a } = this.computeRenderedRowCount();
2000
+ this._renderer.populateCenterRows(a, l), this._renderer.populateLeftRows(a, l), requestAnimationFrame(() => {
2001
+ const d = (n ? this._renderer._leftRenderedRowDivs : this._renderer._centerRenderedRowDivs).find((c) => x(c) === t);
2002
+ if (!d) return;
2003
+ const u = d.children[i];
2004
+ u && this.setActiveCell(u);
2005
+ });
2006
+ }
2007
+ _getPinnedCount() {
2008
+ return this._renderer._leftColDefs?.length ?? 0;
2009
+ }
2010
+ handleTabNavigation(t) {
2011
+ t.preventDefault();
2012
+ const e = this._getPinnedCount(), r = this._renderer._leftBodyEl?.querySelector(`.${this.cn.active_cell}`), n = this._renderer._centerBodyEl?.querySelector(`.${this.cn.active_cell}`), i = r ?? n;
2013
+ if (!i) {
2014
+ this.focusCell(0, 0);
2015
+ return;
2016
+ }
2017
+ const s = I(i);
2018
+ if (!s) return;
2019
+ const l = S(i, s);
2020
+ if (l === null) return;
2021
+ const a = x(s);
2022
+ if (a === null) return;
2023
+ const d = (r ? 0 : e) + l, u = this._renderer._visibleColDefs.length;
2024
+ let c = a, f = d;
2025
+ t.shiftKey ? (f--, f < 0 && (c--, f = u - 1)) : (f++, f >= u && (c++, f = 0)), !(c < 0 || c >= this._filteredAndSortedIndices.length) && this.focusCell(c, f);
2026
+ }
2027
+ ensureRowVisible(t) {
2028
+ const e = t * this.currentState.rowHeight, r = e + this.currentState.rowHeight, n = this._renderer._centerBodyEl.scrollTop, i = n + this.currentState.viewportHeight;
2029
+ if (this._debug) {
2030
+ const s = `ensureRowVisible rowIndex: ${t}; viewportTop: ${n}; viewportBottom: ${i}; rowTop: ${e}; rowBottom: ${r};`;
2031
+ this._console.print(s);
2032
+ }
2033
+ if (e >= n && r <= i) {
2034
+ this._console.print("Row already visible, no scroll");
2035
+ return;
2036
+ }
2037
+ if (e < n) {
2038
+ this._console.print(`Scrolling UP to: ${e}`), this._renderer._centerBodyEl.scrollTop = e;
2039
+ return;
2040
+ }
2041
+ if (r > i) {
2042
+ const s = r - this.currentState.viewportHeight;
2043
+ this._console.print(`Scrolling DOWN to: ${s}`), this._renderer._centerBodyEl.scrollTop = s;
2044
+ return;
2045
+ }
2046
+ }
2047
+ // private createDragElement(headerCell: HTMLElement, isLeft: boolean = false): HTMLElement {
2048
+ // const colIndex = Number(headerCell.dataset.colIndex);
2049
+ // const colDefs = isLeft ? this._renderer._leftColDefs : this._renderer._centerColDefs;
2050
+ // const column = colDefs[colIndex];
2051
+ // if (!column) throw new Error(`column undefined in createDragElement`);
2052
+ // const dragEl = document.createElement('div');
2053
+ // dragEl.innerHTML = `
2054
+ // <span style="margin-right: 6px; opacity: 0.8;">⋮⋮</span>
2055
+ // <span>${column.headerName}</span>`;
2056
+ // dragEl.style.cssText = `
2057
+ // position: fixed;
2058
+ // padding: 8px 16px;
2059
+ // background: rgba(255, 255, 255, 0.95);
2060
+ // border: 1px solid #d0d0d0;
2061
+ // border-radius: 4px;
2062
+ // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
2063
+ // font-size: 13px;
2064
+ // font-weight: 500;
2065
+ // color: #333;
2066
+ // white-space: nowrap;
2067
+ // pointer-events: none;
2068
+ // z-index: 10000;
2069
+ // display: flex;
2070
+ // align-items: center;
2071
+ // `;
2072
+ // return dragEl;
2073
+ // }
2074
+ createDragElement(t, e = !1) {
2075
+ const r = t.dataset.field, i = (e ? this._renderer._leftColDefs : this._renderer._centerColDefs).find((l) => l.field === r);
2076
+ if (!i) throw new Error("column undefined in createDragElement");
2077
+ const s = document.createElement("div");
2078
+ return s.innerHTML = `
2079
+ <span style="margin-right: 6px; opacity: 0.8;">⋮⋮</span>
2080
+ <span>${i.headerName}</span>`, s.style.cssText = `
2081
+ position: fixed;
2082
+ padding: 8px 16px;
2083
+ background: rgba(255, 255, 255, 0.95);
2084
+ border: 1px solid #d0d0d0;
2085
+ border-radius: 4px;
2086
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
2087
+ font-size: 13px;
2088
+ font-weight: 500;
2089
+ color: #333;
2090
+ white-space: nowrap;
2091
+ pointer-events: none;
2092
+ z-index: 10000;
2093
+ display: flex;
2094
+ align-items: center;
2095
+ `, s;
2096
+ }
2097
+ resizeColumnWidth(t, e) {
2098
+ this._renderer._centerColumnWidths[t] = e, this._renderer.updateGridTemplateColumns(), this.updateDebugOverlay();
2099
+ }
2100
+ getColumnWidthInPixels(t) {
2101
+ return this._renderer._centerHeaderEl?.querySelector(".header-inner")?.children[t]?.offsetWidth ?? 100;
2102
+ }
2103
+ detachEvents() {
2104
+ this.eventAbortController?.abort(), this.eventAbortController = void 0;
2105
+ }
2106
+ setActiveRow(t) {
2107
+ this._renderer.renderedRowDivs.forEach((e) => e.classList.remove(g.active_row)), t.classList.add(g.active_row);
2108
+ }
2109
+ // getCellContextParams(cellEl: HTMLElement): CellContext<T> | null {
2110
+ // const c = GridClassName;
2111
+ // // const cellEl = (e.target as HTMLElement).closest(`.${c.cell}`) as HTMLElement;
2112
+ // // if (!cellEl) return null;
2113
+ // const rowEl = cellEl.closest('.cellux-row') as HTMLElement;
2114
+ // if (!rowEl) return null;
2115
+ // // use Array's indexOf method to get the column index of cellEl
2116
+ // const columnIndex = Array.from(rowEl.children).indexOf(cellEl);
2117
+ // // index is -1? element not found so exit.
2118
+ // if (columnIndex < 0) {
2119
+ // console.warn('Cell not found in row');
2120
+ // return null;
2121
+ // }
2122
+ // // Get my data-* property values.
2123
+ // const arrayIndex = Number(rowEl.dataset.arrayIndex);
2124
+ // const rowIndex = Number(rowEl.dataset.rowIndex);
2125
+ // // Should be impossible
2126
+ // if (!Number.isInteger(arrayIndex) || !Number.isInteger(rowIndex)) return null;
2127
+ // const cols = this._renderer._centerColDefs;
2128
+ // if (!cols) throw new Error('getCellEventPayload: columnDefs is undefined');
2129
+ // const colDef: ColumnDef<T> | undefined = cols[columnIndex];
2130
+ // if (!colDef) throw new Error(`getCellEventPayload: column undefined at index ${columnIndex}`);
2131
+ // if (!colDef) return null;
2132
+ // const data = this._options.rowData![arrayIndex];
2133
+ // if (!data) return null;
2134
+ // // const value = data?.[colDef.field];
2135
+ // const value = colDef.valueGetter
2136
+ // ? colDef.valueGetter({ cellElement: cellEl, data: data, rowIndex, arrayIndex, colDef: colDef, api: this.api, value: data?.[colDef.field] })
2137
+ // : data?.[colDef.field];
2138
+ // const cellContext: CellContext<T> = {
2139
+ // value,
2140
+ // colDef,
2141
+ // data,
2142
+ // rowIndex: rowIndex,
2143
+ // arrayIndex: arrayIndex,
2144
+ // // grid: this,
2145
+ // api: this.api,
2146
+ // cellElement: cellEl
2147
+ // };
2148
+ // return cellContext;
2149
+ // }
2150
+ getCellContextParams(t) {
2151
+ const e = Q(t, this);
2152
+ if (!e) return null;
2153
+ const { colDef: r, rowIndex: n, arrayIndex: i } = e, s = this._options.rowData[i];
2154
+ return s ? { value: r.valueGetter ? r.valueGetter({ cellElement: t, data: s, rowIndex: n, arrayIndex: i, colDef: r, api: this.api, value: s?.[r.field] }) : s?.[r.field], colDef: r, data: s, rowIndex: n, arrayIndex: i, api: this.api, cellElement: t } : null;
2155
+ }
2156
+ getCellEventParams(t, e) {
2157
+ const r = this.getCellContextParams(t);
2158
+ return r ? {
2159
+ value: r.value,
2160
+ colDef: r.colDef,
2161
+ data: r.data,
2162
+ rowIndex: r.rowIndex,
2163
+ arrayIndex: r.arrayIndex,
2164
+ cellElement: t,
2165
+ grid: this,
2166
+ event: e,
2167
+ api: this.api
2168
+ } : null;
2169
+ }
2170
+ // getCellEventParams(cellEl: HTMLElement, e: Event): CellEvent<T> | null {
2171
+ // const c = GridClassName;
2172
+ // const cellContext = this.getCellContextParams(cellEl);
2173
+ // const cellEvent: CellEvent<T> = {
2174
+ // value: cellContext?.value,
2175
+ // colDef: cellContext?.colDef!,
2176
+ // data: cellContext?.data!,
2177
+ // rowIndex: cellContext?.rowIndex!,
2178
+ // arrayIndex: cellContext?.arrayIndex!,
2179
+ // cellElement: cellEl,
2180
+ // grid: this,
2181
+ // event: e,
2182
+ // api: this.api
2183
+ // };
2184
+ // return cellEvent;
2185
+ // }
2186
+ // getRowEventParams(e: MouseEvent): RowEvent<T> | null {
2187
+ // const cellEl = (e.target as HTMLElement).closest('.cell') as HTMLElement;
2188
+ // if (!cellEl) return null;
2189
+ // const rowEl = cellEl.closest('.cellux-row') as HTMLElement;
2190
+ // if (!rowEl) return null;
2191
+ // // use Array's indexOf method to get the column index of cellEl
2192
+ // const columnIndex = Array.from(rowEl.children).indexOf(cellEl);
2193
+ // // index is -1? element not found so exit.
2194
+ // if (columnIndex < 0) {
2195
+ // console.warn('Cell not found in row');
2196
+ // return null;
2197
+ // }
2198
+ // // Get my data-* property values.
2199
+ // const arrayIndex = Number(rowEl.dataset.arrayIndex);
2200
+ // const rowIndex = Number(rowEl.dataset.rowIndex);
2201
+ // // Should be impossible
2202
+ // if (!Number.isInteger(arrayIndex) || !Number.isInteger(rowIndex)) return null;
2203
+ // const cols = this._renderer._centerColDefs;
2204
+ // if (!cols) throw new Error('getColumnCallbackPayload: columnDefs is undefined');
2205
+ // const colDef: ColumnDef<T> | undefined = cols[columnIndex];
2206
+ // if (!colDef) throw new Error(`getColumnCallbackPayload: column undefined at index ${columnIndex}`);
2207
+ // if (!colDef) return null;
2208
+ // const data = this._options.rowData![arrayIndex];
2209
+ // if (!data) return null;
2210
+ // const rowEvent: RowEvent<T> = {
2211
+ // data,
2212
+ // rowIndex,
2213
+ // arrayIndex,
2214
+ // event: e,
2215
+ // grid: this,
2216
+ // api: this.api
2217
+ // };
2218
+ // return rowEvent;
2219
+ // }
2220
+ getRowEventParams(t) {
2221
+ const e = t.target.closest(".cell");
2222
+ if (!e) return null;
2223
+ const r = W(e);
2224
+ if (!r) return null;
2225
+ const n = this._options.rowData[r.arrayIndex];
2226
+ return n ? {
2227
+ data: n,
2228
+ rowIndex: r.rowIndex,
2229
+ arrayIndex: r.arrayIndex,
2230
+ event: t,
2231
+ grid: this,
2232
+ api: this.api
2233
+ } : null;
2234
+ }
2235
+ getMouseEventData(t, e) {
2236
+ const r = S(e, t);
2237
+ if (r === null) return null;
2238
+ const n = x(t), i = $(t);
2239
+ return n === null || i === null ? null : { columnIndex: r, arrayIndex: i, rowIndex: n };
2240
+ }
2241
+ // #endregion
2242
+ //************************************************************************************* */
2243
+ //************************************************************************************* */
2244
+ //****************************** DRAG AND DROP COLUMNS ******************************** */
2245
+ //************************************************************************************* */
2246
+ //************************************************************************************* */
2247
+ //#region Drag and Drop
2248
+ // ~attachColumnReorderListeners
2249
+ attachColumnReorderListeners() {
2250
+ this.attachReorderListenersForPanel(this._renderer._centerHeaderEl, !1), this._renderer._leftHeaderInnerEl && this._renderer._leftColDefs.length > 1 && this.attachReorderListenersForPanel(this._renderer._leftPanelEl, !0);
2251
+ }
2252
+ attachReorderListenersForPanel(t, e) {
2253
+ if (!t) return;
2254
+ this.eventAbortController || (this.eventAbortController = new AbortController());
2255
+ let r = !1, n = null, i = 0, s = null, l = 0, a = -1, o = 0, d = !0;
2256
+ const u = 10;
2257
+ e ? this._renderer._leftColDefs : this._renderer._centerColDefs, e ? this._renderer._leftColumnWidths : this._renderer._centerColumnWidths;
2258
+ const c = e ? ".header-left .header-cell" : ".header-center .header-cell";
2259
+ t.addEventListener("mousedown", (f) => {
2260
+ if (f.button !== 0) return;
2261
+ const _ = f.target?.closest(c);
2262
+ if (!_ || f.target.closest(".col-resizer")) return;
2263
+ i = f.clientX, l = i, o = i;
2264
+ const p = _.getBoundingClientRect();
2265
+ let R = { x: f.clientX - p.left, y: f.clientY - p.top };
2266
+ if (s = H(_), s === null) return;
2267
+ const b = P(_, this);
2268
+ if (!b || b.moveable === !1) return;
2269
+ a = -1, f.preventDefault();
2270
+ const m = (w) => {
2271
+ if (s !== null) {
2272
+ if (!r && Math.abs(w.clientX - i) > 5) {
2273
+ r = !0, _.classList.add("dragging"), n = this.createDragElement(_, e), document.body.appendChild(n), document.body.style.cursor = "grabbing", document.body.style.userSelect = "none";
2274
+ const v = n.getBoundingClientRect();
2275
+ R = { x: v.width / 2, y: v.height / 2 };
2276
+ }
2277
+ if (r && n) {
2278
+ const v = w.clientX > o;
2279
+ v !== d && (a = -1, d = v), o = w.clientX, n.style.left = w.clientX - R.x + "px", n.style.top = w.clientY - R.y + "px";
2280
+ const B = Array.from(t.querySelectorAll(c));
2281
+ let M = -1;
2282
+ for (let E = 0; E < B.length; E++) {
2283
+ if (E === s) continue;
2284
+ const D = B[E].getBoundingClientRect(), k = Math.min(8, D.width * 0.3);
2285
+ if (w.clientX >= D.left + k && w.clientX <= D.right - k) {
2286
+ M = E;
2287
+ break;
2288
+ }
2289
+ }
2290
+ M !== -1 && M !== a && Math.abs(w.clientX - l) > u && (this.reorderColumnInPanel(s, M, e), this._sort.updateHeaderSortIndicators(), a = s, s = M, l = w.clientX), requestAnimationFrame(() => {
2291
+ const E = Array.from(t.querySelectorAll(c));
2292
+ let A = -1;
2293
+ for (let D = 0; D < E.length; D++) {
2294
+ if (D === s) continue;
2295
+ const F = E[D].getBoundingClientRect(), q = Math.min(8, F.width * 0.3);
2296
+ if (w.clientX >= F.left + q && w.clientX <= F.right - q) {
2297
+ A = D;
2298
+ break;
2299
+ }
2300
+ }
2301
+ A !== -1 && (E.forEach((D) => D.classList.remove("drop-target")), E[A]?.classList.add("drop-target")), s !== null && E[s]?.classList.add("dragging");
2302
+ });
2303
+ }
2304
+ }
2305
+ }, y = () => {
2306
+ document.removeEventListener("mousemove", m), document.removeEventListener("mouseup", y), r && (r = !1, t.querySelectorAll(c).forEach((w) => {
2307
+ w.classList.remove("dragging", "drop-target");
2308
+ }), n && document.body.contains(n) && document.body.removeChild(n), document.body.style.cursor = "", document.body.style.userSelect = "", this._colStateMgr.saveColumnState(), this._sort.updateHeaderSortIndicators()), n = null, s = null, a = -1;
2309
+ };
2310
+ document.addEventListener("mousemove", m), document.addEventListener("mouseup", y);
2311
+ }, { signal: this.eventAbortController.signal });
2312
+ }
2313
+ reorderColumnInPanel(t, e, r) {
2314
+ if (t === e) return;
2315
+ const n = r ? this._renderer._leftColDefs : this._renderer._centerColDefs, i = r ? this._renderer._leftColumnWidths : this._renderer._centerColumnWidths, s = r ? this._renderer._leftPanelEl : this._renderer._centerHeaderEl;
2316
+ this._renderer._assertions.assertColumnWidthsSync();
2317
+ const [l] = n.splice(t, 1);
2318
+ if (!l) throw new Error("movedColumn undefined in reorderColumnInPanel");
2319
+ const [a] = i.splice(t, 1);
2320
+ if (!a) throw new Error("movedWidth undefined in reorderColumnInPanel");
2321
+ n.splice(e, 0, l), i.splice(e, 0, a), this._renderer._visibleColDefs = [
2322
+ ...this._renderer._leftColDefs,
2323
+ ...this._renderer._centerColDefs
2324
+ ];
2325
+ const o = this._renderer._allColDefs.filter((_) => _.hide);
2326
+ this._renderer._allColDefs = [...this._renderer._visibleColDefs, ...o];
2327
+ const d = s.querySelector(".header-inner"), u = Array.from(d.children), c = u[t], f = u[e];
2328
+ if (c && f && (t < e ? d.insertBefore(c, f.nextSibling) : d.insertBefore(c, f)), Array.from(d.querySelectorAll(".header-cell")).forEach((_, p) => _.dataset.colIndex = String(p)), this._renderer.updateGridTemplateColumns(), r) {
2329
+ const { firstRenderedRowIndex: _, renderedRowCount: p } = this.computeRenderedRowCount();
2330
+ this._renderer.populateLeftRows(p, _);
2331
+ } else
2332
+ this.refreshVisibleRows();
2333
+ }
2334
+ // PATCH: after DOM reorder, keep indices consistent for resize + drag logic
2335
+ reindexHeaderCells() {
2336
+ const t = `.${g.header_cell}`;
2337
+ Array.from(
2338
+ this._renderer._centerHeaderInnerEl.querySelectorAll(t)
2339
+ ).forEach((n, i) => {
2340
+ n.dataset.colIndex = String(i);
2341
+ }), Array.from(
2342
+ this._renderer._leftHeaderInnerEl.querySelectorAll(t)
2343
+ ).forEach((n, i) => {
2344
+ n.dataset.colIndex = String(i);
2345
+ });
2346
+ }
2347
+ // PATCH: refresh currently-visible rows only (keeps virtualization logic centralized)
2348
+ refreshVisibleRows() {
2349
+ const { firstRenderedRowIndex: t, renderedRowCount: e } = this.computeRenderedRowCount();
2350
+ this._renderer.populateCenterRows(e, t);
2351
+ }
2352
+ // #endregion
2353
+ //************************************************************************************* */
2354
+ //************************************************************************************* */
2355
+ //************************************ EDITING **************************************** */
2356
+ //************************************************************************************* */
2357
+ //************************************************************************************* */
2358
+ // #region editing
2359
+ currentlyEditing() {
2360
+ return !!this._editInput || !!this._editingCell;
2361
+ }
2362
+ startCellEditing(t, e, r) {
2363
+ if (this.currentlyEditing())
2364
+ return;
2365
+ const n = this.getCellContextParams(e);
2366
+ if (!n) {
2367
+ console.error("getCellContextParams returned null/undefined in startCellEditing");
2368
+ return;
2369
+ }
2370
+ t instanceof MouseEvent && t.type === "dblclick" && n.colDef.cellEditor && t.preventDefault();
2371
+ const i = this._options.rowData[n.arrayIndex];
2372
+ if (!i) throw new Error("rowData object undefined in startCellEditing");
2373
+ if (this._editingCell = {
2374
+ cell: e,
2375
+ colDef: n.colDef,
2376
+ rowData: n.data,
2377
+ arrayIndex: n.arrayIndex,
2378
+ rowIndex: n.rowIndex,
2379
+ originalValue: n.value,
2380
+ customEditor: null
2381
+ }, typeof n.colDef?.onCellEditingStarted == "function" && n.colDef.onCellEditingStarted(n), n.colDef.cellEditor) {
2382
+ e.classList.remove(g.visual_cell), e.innerHTML = "";
2383
+ let u;
2384
+ if (typeof n.colDef.cellEditor == "string")
2385
+ throw new Error(`String editor types not yet implemented: ${n.colDef.cellEditor}`);
2386
+ u = new n.colDef.cellEditor();
2387
+ const c = {
2388
+ value: n.value,
2389
+ data: i,
2390
+ colDef: n.colDef,
2391
+ rowIndex: n.rowIndex,
2392
+ arrayIndex: n.arrayIndex,
2393
+ cellElement: e,
2394
+ cellEditorParams: n.colDef.cellEditorParams,
2395
+ stopEditing: () => this.commitCellEdit()
2396
+ }, f = u.init(c);
2397
+ e.appendChild(f), this._editingCell.customEditor = u;
2398
+ return;
2399
+ }
2400
+ const s = document.createElement("input");
2401
+ s.type = "text", s.value = r ?? String(n.value ?? "");
2402
+ const l = window.getComputedStyle(e), a = l.justifyContent, d = {
2403
+ "flex-start": "left",
2404
+ "flex-end": "right",
2405
+ center: "center",
2406
+ "space-between": "justify"
2407
+ }[a] || "left";
2408
+ s.style.cssText = `
2409
+ text-align: ${d};
2410
+ font-family: ${l.fontFamily};
2411
+ color: ${l.color};
2412
+ background: ${l.background};
2413
+ `, s.classList.add("cell-edit"), e.classList.add("cell-editing"), e.classList.remove(g.visual_cell), e.innerHTML = "", e.appendChild(s), s.focus(), this._editInput = s, r !== void 0 ? s.setSelectionRange(s.value.length, s.value.length) : setTimeout(() => s.select(), 0), s.addEventListener("blur", this.commitCellEdit, { once: !0 }), s.addEventListener("keydown", (u) => {
2414
+ u.key === "Enter" ? (u.preventDefault(), this.commitCellEdit()) : u.key === "Escape" ? (u.preventDefault(), this.cancelCellEdit()) : u.key === "Tab" && (u.preventDefault(), this.commitCellEdit());
2415
+ });
2416
+ }
2417
+ // #endregion
2418
+ //************************************************************************************* */
2419
+ //************************************************************************************* */
2420
+ //********************************** EXPORT DATA ************************************** */
2421
+ //************************************************************************************* */
2422
+ //************************************************************************************* */
2423
+ // #region Export
2424
+ // At the top with your other methods in the API section
2425
+ exportToCsv(t) {
2426
+ const e = t?.fileName || "export.csv", r = t?.columnKeys ? t.columnKeys.map((l) => this._renderer._visibleColDefs.find((a) => a.field === l)).filter((l) => l !== void 0) : this._renderer._visibleColDefs, n = r.map(
2427
+ (l) => this.escapeCsvValue(l.headerName)
2428
+ ), i = this._filteredAndSortedIndices.map((l) => {
2429
+ const a = this._options.rowData[l];
2430
+ if (!a) throw new Error("rowData undefined in exportToCsv");
2431
+ return r.map((o) => {
2432
+ const d = a[o.field], u = t?.processCellCallback ? t.processCellCallback({
2433
+ colDef: o,
2434
+ value: d,
2435
+ data: a
2436
+ }) : d;
2437
+ return this.escapeCsvValue(u);
2438
+ });
2439
+ }), s = [
2440
+ n.join(","),
2441
+ ...i.map((l) => l.join(","))
2442
+ ].join(`
2443
+ `);
2444
+ this.downloadCsv(s, e);
2445
+ }
2446
+ // escapeCsvValue and downloadCsv stay the same
2447
+ // NEW METHOD - add this
2448
+ escapeCsvValue(t) {
2449
+ if (t == null) return "";
2450
+ const e = String(t);
2451
+ return e.includes(",") || e.includes('"') || e.includes(`
2452
+ `) ? `"${e.replace(/"/g, '""')}"` : e;
2453
+ }
2454
+ // downloadCsv stays the same
2455
+ downloadCsv(t, e) {
2456
+ const r = new Blob([t], { type: "text/csv;charset=utf-8;" }), n = document.createElement("a"), i = URL.createObjectURL(r);
2457
+ n.setAttribute("href", i), n.setAttribute("download", e), n.style.visibility = "hidden", document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(i);
2458
+ }
2459
+ // #endregion
2460
+ // rowCount: number, firstRenderedRowIndex: number
2461
+ updateDebugOverlay() {
2462
+ this._debugOverlay.updateDebugOverlay();
2463
+ }
2464
+ // #endregion asserts/debug
2465
+ onFilterChanged() {
2466
+ this._sort.applySort(), this.updateTotalRowsDisplay(), this.refreshGrid(), this.options?.onFilterChanged?.();
2467
+ }
2468
+ //************************************************************************************* */
2469
+ //************************************************************************************* */
2470
+ //********************************** QUICK FILTER ************************************* */
2471
+ //************************************************************************************* */
2472
+ //************************************************************************************* */
2473
+ //#region Quick Filter
2474
+ clearQuickFilter() {
2475
+ this._quickFilter.quickFilterText = "", this._quickFilter.applyQuickFilter();
2476
+ }
2477
+ getQuickFilterText() {
2478
+ return this._quickFilter.quickFilterText;
2479
+ }
2480
+ updateTotalRowsDisplay() {
2481
+ this._statusBar.updateRowsPanel();
2482
+ }
2483
+ refreshGrid() {
2484
+ const t = this._filteredAndSortedIndices.length;
2485
+ this._renderer._centerRowsContainerEl.style.height = `${t * this.currentState.rowHeight}px`, this._renderer._leftRowsContainerEl.style.height = `${t * this.currentState.rowHeight}px`, this._renderer._centerBodyEl && (this._renderer._centerBodyEl.scrollTop = 0, this.currentState.scrollTop = 0);
2486
+ const { firstRenderedRowIndex: e, renderedRowCount: r } = this.computeRenderedRowCount();
2487
+ this._renderer.syncRowVisibility(r), this._renderer.populateCenterRows(r, e), this._renderer.populateLeftRows(r, e);
2488
+ }
2489
+ invalidateArrayIndex(t) {
2490
+ const e = this._renderer.renderedRowDivs.find(
2491
+ (i) => $(i) === t
2492
+ );
2493
+ if (!e) return;
2494
+ const r = x(e);
2495
+ if (r === null) return;
2496
+ const n = this._options.rowData?.[t];
2497
+ n && this._renderer._centerColDefs.forEach((i, s) => {
2498
+ const l = e.children[s];
2499
+ l && this._renderer.populateCell(l, i, n, t, r);
2500
+ });
2501
+ }
2502
+ invalidateRow(t) {
2503
+ const e = this._filteredAndSortedIndices[t];
2504
+ Number.isInteger(e) && this.invalidateArrayIndex(e);
2505
+ }
2506
+ getRowIndexFromArrayIndex(t) {
2507
+ const e = this._filteredAndSortedIndices.indexOf(t);
2508
+ return e >= 0 ? e : null;
2509
+ }
2510
+ updateCellValue(t, e, r) {
2511
+ const n = this._options.rowData?.[t];
2512
+ n && (n[e] = r, this.invalidateArrayIndex(t));
2513
+ }
2514
+ // This is kind of like ag-grids rowNode.updateData where they
2515
+ // update the entire row.
2516
+ updateRow(t, e) {
2517
+ const r = this._options.rowData?.[t];
2518
+ if (!r) return;
2519
+ let n = !1;
2520
+ for (const i of Object.keys(e))
2521
+ r[i] !== e[i] && (r[i] = e[i], n = !0);
2522
+ n && this.invalidateArrayIndex(t);
2523
+ }
2524
+ getDistinctValuesByField(t) {
2525
+ return this._filter.getDistinctValuesByField(t);
2526
+ }
2527
+ isCellEditable(t, e) {
2528
+ const r = t.editable ?? !0;
2529
+ return typeof r == "function" ? r(e) : r;
2530
+ }
2531
+ pinColumn(t, e) {
2532
+ const r = this._renderer._allColDefs.find((a) => a.field === t.field);
2533
+ if (!r) return;
2534
+ r.pinned = e ? "left" : void 0, this._renderer.recomputeColDefsAndWidths();
2535
+ const n = this._renderer._leftHeaderInnerEl, i = this._renderer._centerHeaderInnerEl;
2536
+ n.innerHTML = this._renderer._leftColDefs.map((a, o) => this._renderer.buildHeaderCell(a, o).outerHTML).join(""), i.innerHTML = this._renderer._centerColDefs.map((a, o) => this._renderer.buildHeaderCell(a, o).outerHTML).join(""), this._renderer._centerRowsContainerEl.innerHTML = "", this._renderer._leftRowsContainerEl.innerHTML = "", this._renderer.resetRowPool(), this._renderer.updateLeftZoneWidth(), this._renderer.updateGridTemplateColumns();
2537
+ const { firstRenderedRowIndex: s, renderedRowCount: l } = this.computeRenderedRowCount();
2538
+ this._renderer.initializeRowPool(l), this._renderer.initializeLeftRowPool(l), this._sort.updateHeaderSortIndicators(), this._renderer.headerCallbacks(), this.detachEvents(), this.attachEvents(), this.refreshGrid(), this._colStateMgr.saveColumnState(), this.updateDebugOverlay();
2539
+ }
2540
+ deleteColumnState() {
2541
+ }
2542
+ //************************************************************************************* */
2543
+ //************************************************************************************* */
2544
+ //*********************************** API ********************************************* */
2545
+ //************************************************************************************* */
2546
+ //************************************************************************************* */
2547
+ // #region API
2548
+ // Properties
2549
+ get Grid() {
2550
+ return this;
2551
+ }
2552
+ getRowData() {
2553
+ return this._options.rowData;
2554
+ }
2555
+ get activeRowIndex() {
2556
+ return this._activeRowIndex;
2557
+ }
2558
+ get activeArrayIndex() {
2559
+ return this._activeArrayIndex;
2560
+ }
2561
+ get activeColField() {
2562
+ return this._activeColField;
2563
+ }
2564
+ get quickFilterText() {
2565
+ return this._quickFilter.quickFilterText;
2566
+ }
2567
+ set quickFilterText(t) {
2568
+ this._quickFilter.quickFilterText = t;
2569
+ }
2570
+ get rootEl() {
2571
+ return this._rootEl;
2572
+ }
2573
+ get options() {
2574
+ return this._options;
2575
+ }
2576
+ get contextMenuEl() {
2577
+ return this._contextMenuEl;
2578
+ }
2579
+ set contextMenuEl(t) {
2580
+ this._contextMenuEl = t;
2581
+ }
2582
+ get derivedIndices() {
2583
+ return this._filteredAndSortedIndices;
2584
+ }
2585
+ get debug() {
2586
+ return this._debug;
2587
+ }
2588
+ get showDebugOverlay() {
2589
+ return this._showDebugOverlay;
2590
+ }
2591
+ get consoleLog() {
2592
+ return this._consoleLog;
2593
+ }
2594
+ get activeRowElement() {
2595
+ return this._activeRowElement;
2596
+ }
2597
+ set activeRowElement(t) {
2598
+ this._activeRowElement = t;
2599
+ }
2600
+ setColumnVisible(t, e) {
2601
+ const r = this._renderer._allColDefs.findIndex((c) => c.field === t);
2602
+ if (r === -1) {
2603
+ console.warn(`setColumnVisible: Column with field '${t}' not found.`);
2604
+ return;
2605
+ }
2606
+ const n = this._renderer._allColDefs[r];
2607
+ if (n.hide === !0 && e === !1) {
2608
+ console.warn(`Field ${t} is already hidden`);
2609
+ return;
2610
+ }
2611
+ if (n.hide === !1 && e === !0) {
2612
+ console.warn(`Field ${t} is already visible`);
2613
+ return;
2614
+ }
2615
+ const i = n.pinned === "left", s = this._renderer._allColDefs.slice(0, r).filter((c) => !c.hide && (i ? c.pinned === "left" : c.pinned !== "left")).length;
2616
+ n.hide = !e, X(this._renderer);
2617
+ const l = i ? this._renderer._leftHeaderInnerEl : this._renderer._centerHeaderInnerEl, a = i ? this._renderer._leftColumnWidths : this._renderer._centerColumnWidths, o = i ? this._renderer._leftRenderedRowDivs : this._renderer._centerRenderedRowDivs;
2618
+ if (e) {
2619
+ a.splice(s, 0, n.width ?? 100);
2620
+ const c = this._renderer.buildHeaderCell(n, s);
2621
+ l.insertBefore(c, l.children[s] ?? null), o.forEach((f) => {
2622
+ const _ = document.createElement("div");
2623
+ _.className = g.cell, _.setAttribute("role", "grid_cell"), f.insertBefore(_, f.children[s] ?? null);
2624
+ });
2625
+ } else
2626
+ a.splice(s, 1), l.children[s]?.remove(), o.forEach((c) => {
2627
+ c.children[s]?.remove();
2628
+ });
2629
+ this.reindexHeaderCells(), this._renderer.updateGridTemplateColumns(), this._renderer.updateLeftZoneWidth(), this._sort.updateHeaderSortIndicators();
2630
+ const { firstRenderedRowIndex: d, renderedRowCount: u } = this.computeRenderedRowCount();
2631
+ i ? this._renderer.populateLeftRows(u, d) : this._renderer.populateCenterRows(u, d), this._renderer._assertions.assertCenterColDefsSync(), this._renderer._assertions.assertPanelColDefsMatchVisible(), this._renderer._assertions.assertPanelCellCountMatchesColDefs(), this._renderer._assertions.assertHeaderCellCountMatchesColDefs(), this._colStateMgr.saveColumnState();
2632
+ }
2633
+ getActiveCell() {
2634
+ return this._renderer._centerBodyEl.querySelector(`.${this.cn.active_cell}`);
2635
+ }
2636
+ scroll(t) {
2637
+ const e = this._renderer._centerBodyEl;
2638
+ e && (this.debug, e.scrollTop += t);
2639
+ }
2640
+ scrollToAndActivateRowByArrayIndex(t) {
2641
+ const e = this._filteredAndSortedIndices.indexOf(t);
2642
+ if (e === -1) {
2643
+ localStorage.removeItem("activeRowArrayIndex");
2644
+ return;
2645
+ }
2646
+ this._activeArrayIndex = t, this.ensureRowVisible(e);
2647
+ const { firstRenderedRowIndex: r, renderedRowCount: n } = this.computeRenderedRowCount();
2648
+ this._renderer.populateCenterRows(n, r);
2649
+ }
2650
+ resetAllColumns() {
2651
+ this._renderer._allColDefs = this._options.columnDefs.map((t) => this.resolveColDef(t)), this._renderer.recomputeColDefsAndWidths(), this._renderer.recomputeRowDivs(), this._renderer._leftHeaderInnerEl.innerHTML = this._renderer._leftColDefs.map((t, e) => this._renderer.buildHeaderCell(t, e).outerHTML).join(""), this._renderer._centerHeaderInnerEl.innerHTML = this._renderer._centerColDefs.map((t, e) => this._renderer.buildHeaderCell(t, e).outerHTML).join(""), this._renderer.updateGridTemplateColumns(), this._renderer.updateLeftZoneWidth(), this.detachEvents(), this.attachEvents(), this._sort.updateHeaderSortIndicators(), this.refreshGrid(), this._colStateMgr.saveColumnState();
2652
+ }
2653
+ debugApi() {
2654
+ return {
2655
+ getrenderedRowDivs: () => this._renderer.renderedRowDivs
2656
+ };
2657
+ }
2658
+ _getGrid() {
2659
+ return this;
2660
+ }
2661
+ // ===============================================================================
2662
+ // ===============================================================================
2663
+ // Public API
2664
+ // ===============================================================================
2665
+ // ===============================================================================
2666
+ // exportToCsv?: (options?: CsvExportOptions<T>) => void;
2667
+ get api() {
2668
+ return this._api || (this._api = {
2669
+ version: ".01",
2670
+ exportToCsv: (t) => this.exportToCsv(t),
2671
+ setRowData: (t) => this.setRowData(t),
2672
+ getColumnState: () => {
2673
+ throw new Error("getColumnState not yet implemented");
2674
+ },
2675
+ clearColumnFilters: () => this._filter.clearColumnFilters(),
2676
+ clearColumnFilter: (t) => this._filter.clearColumnFilter(t),
2677
+ scroll: (t) => this.scroll(t),
2678
+ getColumnWidths: () => this._renderer._centerColumnWidths,
2679
+ destroy: () => this.destroy(),
2680
+ getColDef: (t) => this.getColDef(t),
2681
+ getAllColumns: () => this._renderer._allColDefs,
2682
+ getVisibleColumns: () => this._renderer._visibleColDefs,
2683
+ setQuickFilterText: (t) => this._quickFilter.quickFilterText = t,
2684
+ // dump: () => this._renderer.dump(),
2685
+ setColumnVisible: (t, e) => this.setColumnVisible(t, e),
2686
+ /* Called like so: api.updateRow!(20, { age: 100,
2687
+ city: 'Palo Alto',
2688
+ county: 'Santa Clara'
2689
+ });*/
2690
+ updateRow: (t, e) => this.updateRow(t, e),
2691
+ updateCellValue: (t, e, r) => this.updateCellValue(t, e, r),
2692
+ /** Debug helpers. Not part of the stable public API. */
2693
+ debug: {
2694
+ getRenderedRowDivs: () => this._renderer.renderedRowDivs,
2695
+ getGrid: () => this._getGrid()
2696
+ }
2697
+ }), this._api;
2698
+ }
2699
+ // #endregion API
2700
+ }
2701
+ export {
2702
+ ve as Grid
2703
+ };