@rozie-ui/data-table-lit 0.2.7 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -7,6 +7,196 @@ import { repeat } from "lit/directives/repeat.js";
7
7
  import "@rozie-ui/popover-lit";
8
8
  import { createTable, getCoreRowModel, getExpandedRowModel, getFacetedMinMaxValues, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getGroupedRowModel, getPaginationRowModel, getSortedRowModel } from "@tanstack/table-core";
9
9
  import { Virtualizer, elementScroll, measureElement, observeElementOffset, observeElementRect } from "@tanstack/virtual-core";
10
+ //#region src/helpers/columnDefUtils.ts
11
+ const isSafeKey = (k) => k !== "__proto__" && k !== "constructor" && k !== "prototype";
12
+ const wrapAggregationFn = (fn) => {
13
+ if (typeof fn === "string") return fn;
14
+ if (typeof fn !== "function") return void 0;
15
+ return (columnId, leafRows, childRows) => {
16
+ try {
17
+ return fn(columnId, leafRows, childRows);
18
+ } catch (err) {
19
+ return;
20
+ }
21
+ };
22
+ };
23
+ const collectNestedDefs = (list, out) => {
24
+ if (!Array.isArray(list)) return;
25
+ for (const d of list) {
26
+ if (!d || d.id == null) continue;
27
+ const id = String(d.id);
28
+ if (!(id in out)) out[id] = d;
29
+ if (Array.isArray(d.columns)) collectNestedDefs(d.columns, out);
30
+ }
31
+ };
32
+ const indexDefsById = (defs) => {
33
+ const out = Object.create(null);
34
+ if (!Array.isArray(defs)) return out;
35
+ for (const d of defs) {
36
+ if (!d || d.id == null) continue;
37
+ out[String(d.id)] = d;
38
+ }
39
+ for (const d of defs) if (d && Array.isArray(d.columns)) collectNestedDefs(d.columns, out);
40
+ return out;
41
+ };
42
+ const collectGroupableLeafDefs = (defs) => {
43
+ const out = [];
44
+ if (!Array.isArray(defs)) return out;
45
+ for (const d of defs) {
46
+ if (!d) continue;
47
+ if (Array.isArray(d.columns)) {
48
+ out.push(...collectGroupableLeafDefs(d.columns));
49
+ continue;
50
+ }
51
+ if (d.groupable === false) continue;
52
+ out.push(d);
53
+ }
54
+ return out;
55
+ };
56
+ //#endregion
57
+ //#region src/helpers/indexMath.ts
58
+ const clamp = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
59
+ const focusables = (cellEl) => {
60
+ if (!cellEl || !cellEl.querySelectorAll) return [];
61
+ return Array.prototype.slice.call(cellEl.querySelectorAll("button,[href],input,select,textarea,[tabindex]:not([tabindex=\"-1\"])")).filter((n) => !n.disabled);
62
+ };
63
+ const applyUpdater = (updater, current) => typeof updater === "function" ? updater(current) : updater;
64
+ //#endregion
65
+ //#region src/helpers/tsvGrid.ts
66
+ const escapeTsvField = (s) => {
67
+ if (s.indexOf(" ") >= 0 || s.indexOf("\n") >= 0 || s.indexOf("\r") >= 0 || s.indexOf("\"") >= 0) return "\"" + s.replace(/"/g, "\"\"") + "\"";
68
+ return s;
69
+ };
70
+ const parseTsv = (text) => {
71
+ const str = text != null ? String(text) : "";
72
+ if (str === "" || str.length > 2e6) return [];
73
+ const rows = [];
74
+ let row = [];
75
+ let field = "";
76
+ let inQuotes = false;
77
+ let i = 0;
78
+ const n = str.length;
79
+ while (i < n) {
80
+ const ch = str[i];
81
+ if (inQuotes) {
82
+ if (ch === "\"") {
83
+ if (i + 1 < n && str[i + 1] === "\"") {
84
+ field = field + "\"";
85
+ i = i + 2;
86
+ continue;
87
+ }
88
+ inQuotes = false;
89
+ i = i + 1;
90
+ continue;
91
+ }
92
+ field = field + ch;
93
+ i = i + 1;
94
+ continue;
95
+ }
96
+ if (ch === "\"" && field === "") {
97
+ inQuotes = true;
98
+ i = i + 1;
99
+ continue;
100
+ }
101
+ if (ch === " ") {
102
+ row.push(field);
103
+ field = "";
104
+ i = i + 1;
105
+ continue;
106
+ }
107
+ if (ch === "\r") {
108
+ if (i + 1 < n && str[i + 1] === "\n") i = i + 1;
109
+ row.push(field);
110
+ field = "";
111
+ rows.push(row);
112
+ row = [];
113
+ i = i + 1;
114
+ continue;
115
+ }
116
+ if (ch === "\n") {
117
+ row.push(field);
118
+ field = "";
119
+ rows.push(row);
120
+ row = [];
121
+ i = i + 1;
122
+ continue;
123
+ }
124
+ field = field + ch;
125
+ i = i + 1;
126
+ }
127
+ row.push(field);
128
+ rows.push(row);
129
+ if (rows.length > 1) {
130
+ const last = rows[rows.length - 1];
131
+ if (last.length === 1 && last[0] === "") rows.pop();
132
+ }
133
+ return rows;
134
+ };
135
+ const tileGridToBox = (grid, box) => {
136
+ const srcRows = grid.length;
137
+ let srcCols = 0;
138
+ for (let i = 0; i < srcRows; i++) {
139
+ const w = grid[i] && grid[i].length ? grid[i].length : 0;
140
+ if (w > srcCols) srcCols = w;
141
+ }
142
+ if (srcRows <= 0 || srcCols <= 0) return grid;
143
+ const boxRows = box.r1 - box.r0 + 1;
144
+ const boxCols = box.c1 - box.c0 + 1;
145
+ const rows = boxRows > srcRows ? boxRows : srcRows;
146
+ const cols = boxCols > srcCols ? boxCols : srcCols;
147
+ const out = [];
148
+ for (let r = 0; r < rows; r++) {
149
+ const srcLine = grid[r % srcRows] || [];
150
+ const line = [];
151
+ for (let c = 0; c < cols; c++) {
152
+ const v = srcLine[c % srcCols];
153
+ line.push(v != null ? v : "");
154
+ }
155
+ out.push(line);
156
+ }
157
+ return out;
158
+ };
159
+ const tileIndex = (i, lo, hi) => {
160
+ const span = hi - lo + 1;
161
+ if (span <= 1) return lo;
162
+ let k = (i - lo) % span;
163
+ if (k < 0) k = k + span;
164
+ return lo + k;
165
+ };
166
+ //#endregion
167
+ //#region src/helpers/rowValueUtils.ts
168
+ const replaceRowValue = (rows, rowIndex, field, value) => {
169
+ const src = rows || [];
170
+ const out = [];
171
+ for (let i = 0; i < src.length; i++) if (i === rowIndex) out.push({
172
+ ...src[i] || {},
173
+ [field]: value
174
+ });
175
+ else out.push(src[i]);
176
+ return out;
177
+ };
178
+ const replaceRowValues = (rows, rowIndex, fieldValues) => {
179
+ const src = rows || [];
180
+ const fv = fieldValues || {};
181
+ const out = [];
182
+ for (let i = 0; i < src.length; i++) if (i === rowIndex) out.push({
183
+ ...src[i] || {},
184
+ ...fv
185
+ });
186
+ else out.push(src[i]);
187
+ return out;
188
+ };
189
+ const indexOfRowIn = (rows, rowOriginal, rowId) => {
190
+ const list = rows || [];
191
+ for (let i = 0; i < list.length; i++) {
192
+ const r = list[i];
193
+ if (!r) continue;
194
+ if (rowId != null && r.id === rowId) return i;
195
+ if (rowOriginal != null && r.original === rowOriginal) return i;
196
+ }
197
+ return -1;
198
+ };
199
+ //#endregion
10
200
  //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
11
201
  function __decorate(decorators, target, key, desc) {
12
202
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -130,6 +320,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
130
320
  this.undoLimit = 100;
131
321
  this.virtual = false;
132
322
  this.estimateRowHeight = 40;
323
+ this.autoMeasure = false;
133
324
  this.maxHeight = "";
134
325
  this._dataDefault = signal([]);
135
326
  this._sortingDefault = signal([]);
@@ -217,7 +408,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
217
408
  this.virtualizer = null;
218
409
  this.virtualizerCleanup = null;
219
410
  this.gridScrollEl = null;
411
+ this.colVirtualizer = null;
412
+ this.colVirtualizerCleanup = null;
220
413
  this.remeasurePending = false;
414
+ this.remeasureRaf = null;
415
+ this.remeasureDisposed = false;
221
416
  this.GRID_PAGE_STEP = 10;
222
417
  this.gridRoot = null;
223
418
  this.programmatic = 0;
@@ -255,18 +450,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
255
450
  columnSizingInfo: this._columnSizingInfo.value
256
451
  });
257
452
  this.currentData = () => this.data != null ? this.data : this._dataDefault.value;
258
- this.isSafeKey = (k) => k !== "__proto__" && k !== "constructor" && k !== "prototype";
259
- this.wrapAggregationFn = (fn) => {
260
- if (typeof fn === "string") return fn;
261
- if (typeof fn !== "function") return void 0;
262
- return (columnId, leafRows, childRows) => {
263
- try {
264
- return fn(columnId, leafRows, childRows);
265
- } catch (err) {
266
- return;
267
- }
268
- };
269
- };
270
453
  this.buildConfigDef = (c) => {
271
454
  if (!c) return null;
272
455
  if (Array.isArray(c.columns)) {
@@ -280,7 +463,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
280
463
  if (gid == null) gid = c.header != null ? "__grp_" + kids.map((k) => k.id).join("_") : null;
281
464
  if (gid == null) return null;
282
465
  const id = String(gid);
283
- if (!this.isSafeKey(id)) return null;
466
+ if (!isSafeKey(id)) return null;
284
467
  return {
285
468
  id,
286
469
  header: c.header != null ? c.header : id,
@@ -290,7 +473,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
290
473
  const rawId = c.id != null ? c.id : c.field;
291
474
  if (rawId == null) return null;
292
475
  const id = String(rawId);
293
- if (!this.isSafeKey(id)) return null;
476
+ if (!isSafeKey(id)) return null;
294
477
  return {
295
478
  id,
296
479
  accessorKey: c.field != null ? c.field : id,
@@ -300,7 +483,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
300
483
  filterable: c.filterable === true,
301
484
  expandable: c.expandable === true,
302
485
  groupable: c.groupable !== false,
303
- aggregationFn: this.wrapAggregationFn(c.aggregationFn),
486
+ aggregationFn: wrapAggregationFn(c.aggregationFn),
304
487
  pinned: c.pinned != null ? c.pinned : "",
305
488
  width: c.width != null ? c.width : "",
306
489
  meta: {
@@ -311,10 +494,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
311
494
  }
312
495
  };
313
496
  };
497
+ this.columnDefsCache = null;
498
+ this.columnDefsCacheColumnsRef = void 0;
499
+ this.columnDefsCacheColRegRef = void 0;
500
+ this.columnDefsIndexCache = null;
314
501
  this.columnDefs = () => {
502
+ const cfg = this.columns || [];
503
+ const reg = this._colReg.value || {};
504
+ if (this.columnDefsCache && this.columns === this.columnDefsCacheColumnsRef && this._colReg.value === this.columnDefsCacheColRegRef) return this.columnDefsCache;
315
505
  const byId = Object.create(null);
316
506
  const order = [];
317
- const cfg = this.columns || [];
318
507
  for (const c of cfg) {
319
508
  const def = this.buildConfigDef(c);
320
509
  if (!def) continue;
@@ -322,9 +511,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
322
511
  if (!(id in byId)) order.push(id);
323
512
  byId[id] = def;
324
513
  }
325
- const reg = this._colReg.value || {};
326
514
  for (const id in reg) {
327
- if (!this.isSafeKey(id)) continue;
515
+ if (!isSafeKey(id)) continue;
328
516
  const spec = reg[id];
329
517
  if (!spec) continue;
330
518
  if (!(id in byId)) order.push(id);
@@ -337,7 +525,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
337
525
  filterable: spec.filterable === true,
338
526
  expandable: spec.expandable === true,
339
527
  groupable: spec.groupable !== false,
340
- aggregationFn: this.wrapAggregationFn(spec.aggregationFn),
528
+ aggregationFn: wrapAggregationFn(spec.aggregationFn),
341
529
  pinned: spec.pinned != null ? spec.pinned : "",
342
530
  width: spec.width != null ? spec.width : "",
343
531
  meta: {
@@ -350,8 +538,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
350
538
  }
351
539
  const out = [];
352
540
  for (const id of order) if (byId[id]) out.push(byId[id]);
541
+ this.columnDefsCache = out;
542
+ this.columnDefsCacheColumnsRef = this.columns;
543
+ this.columnDefsCacheColRegRef = this._colReg.value;
544
+ this.columnDefsIndexCache = indexDefsById(out);
353
545
  return out;
354
546
  };
547
+ this.defIndex = () => {
548
+ this.columnDefs();
549
+ return this.columnDefsIndexCache || Object.create(null);
550
+ };
355
551
  this.SELECT_COL_ID = "__rdt_select";
356
552
  this.EXPANDER_COL_ID = "__rdt_expander";
357
553
  this.selectionEnabled = () => this.selectionMode === "single" || this.selectionMode === "multiple";
@@ -392,7 +588,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
392
588
  }));
393
589
  this.programmatic--;
394
590
  };
395
- this.applyUpdater = (updater, current) => typeof updater === "function" ? updater(current) : updater;
396
591
  this.writeExpanded = (next) => {
397
592
  if (this.programmatic) return;
398
593
  this.programmatic++;
@@ -604,48 +799,101 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
604
799
  };
605
800
  this.refreshRowModel = null;
606
801
  this.onSortingChangeCb = (updater) => {
607
- this.writeSorting(this.applyUpdater(updater, this.currentState().sorting));
802
+ this.writeSorting(applyUpdater(updater, this.currentState().sorting));
608
803
  };
609
804
  this.onExpandedChangeCb = (updater) => {
610
- this.writeExpanded(this.applyUpdater(updater, this.currentState().expanded));
805
+ this.writeExpanded(applyUpdater(updater, this.currentState().expanded));
611
806
  };
612
807
  this.onGroupingChangeCb = (updater) => {
613
- this.writeGrouping(this.applyUpdater(updater, this.currentState().grouping));
808
+ this.writeGrouping(applyUpdater(updater, this.currentState().grouping));
614
809
  };
615
810
  this.onGlobalFilterChangeCb = (updater) => {
616
- this.writeGlobalFilter(this.applyUpdater(updater, this.currentState().globalFilter));
811
+ this.writeGlobalFilter(applyUpdater(updater, this.currentState().globalFilter));
617
812
  };
618
813
  this.onColumnFiltersChangeCb = (updater) => {
619
- this.writeColumnFilters(this.applyUpdater(updater, this.currentState().columnFilters));
814
+ this.writeColumnFilters(applyUpdater(updater, this.currentState().columnFilters));
620
815
  };
621
816
  this.onPaginationChangeCb = (updater) => {
622
- this.writePagination(this.applyUpdater(updater, this.currentState().pagination));
817
+ this.writePagination(applyUpdater(updater, this.currentState().pagination));
623
818
  };
624
819
  this.onRowSelectionChangeCb = (updater) => {
625
- this.writeRowSelection(this.applyUpdater(updater, this.currentState().rowSelection));
820
+ this.writeRowSelection(applyUpdater(updater, this.currentState().rowSelection));
626
821
  };
627
822
  this.onColumnVisibilityChangeCb = (updater) => {
628
- this.writeColumnVisibility(this.applyUpdater(updater, this.currentState().columnVisibility));
823
+ this.writeColumnVisibility(applyUpdater(updater, this.currentState().columnVisibility));
629
824
  };
630
825
  this.onColumnSizingChangeCb = (updater) => {
631
- this.writeColumnSizing(this.applyUpdater(updater, this.currentState().columnSizing));
826
+ this.writeColumnSizing(applyUpdater(updater, this.currentState().columnSizing));
632
827
  };
633
828
  this.onColumnOrderChangeCb = (updater) => {
634
- this.writeColumnOrder(this.applyUpdater(updater, this.currentState().columnOrder));
829
+ this.writeColumnOrder(applyUpdater(updater, this.currentState().columnOrder));
635
830
  };
636
831
  this.onColumnPinningChangeCb = (updater) => {
637
- this.writeColumnPinning(this.applyUpdater(updater, this.currentState().columnPinning));
832
+ this.writeColumnPinning(applyUpdater(updater, this.currentState().columnPinning));
638
833
  };
639
834
  this.onColumnSizingInfoChangeCb = (updater) => {
640
- const next = this.applyUpdater(updater, this._columnSizingInfo.value);
835
+ const next = applyUpdater(updater, this._columnSizingInfo.value);
641
836
  this._columnSizingInfo.value = next != null ? next : this._columnSizingInfo.value;
642
837
  };
838
+ this.resolveVirtual = () => {
839
+ const v = this.virtual;
840
+ if (typeof v === "string") {
841
+ if (v === "rows") return "rows";
842
+ if (v === "columns") return "columns";
843
+ if (v === "both") return "both";
844
+ return "off";
845
+ }
846
+ return v === true ? "rows" : "off";
847
+ };
848
+ this.rowsWindowed = () => {
849
+ const s = this.resolveVirtual();
850
+ return s === "rows" || s === "both";
851
+ };
852
+ this.colsWindowed = () => {
853
+ const s = this.resolveVirtual();
854
+ return s === "columns" || s === "both";
855
+ };
856
+ this.isWindowed = () => this.rowsWindowed() || this.colsWindowed();
857
+ this.autoMeasureOn = () => this.autoMeasure === true;
858
+ this.columnCount = () => this.visibleColCount();
859
+ this.columnSize = (i) => {
860
+ if (!this.table || !this.table.getVisibleLeafColumns) return 150;
861
+ const c = this.table.getVisibleLeafColumns()[i];
862
+ return c && typeof c.getSize === "function" ? c.getSize() : 150;
863
+ };
864
+ this.forcedColumns = () => {
865
+ if (!this.colsWindowed()) return [];
866
+ const out = [];
867
+ if (this.table && this.table.getVisibleLeafColumns) {
868
+ const cols = this.table.getVisibleLeafColumns();
869
+ for (let i = 0; i < cols.length; i++) {
870
+ const c = cols[i];
871
+ if (c && c.getIsPinned && c.getIsPinned()) out.push(i);
872
+ }
873
+ }
874
+ if (!this._activeIsHeader.value && this._activeColIndex.value >= 0 && out.indexOf(this._activeColIndex.value) === -1) out.push(this._activeColIndex.value);
875
+ if (this._editingRow.value >= 0 && this._editingCol.value >= 0 && out.indexOf(this._editingCol.value) === -1) out.push(this._editingCol.value);
876
+ return out;
877
+ };
878
+ this.windowedCells = (row) => {
879
+ this._windowVer.value;
880
+ const cells = this.visibleCellsFor(row);
881
+ if (!this.colsWindowed()) return cells;
882
+ const idx = this.windowedColIndices();
883
+ const out = [];
884
+ for (let i = 0; i < idx.length; i++) {
885
+ const cell = cells[idx[i]];
886
+ if (cell) out.push(cell);
887
+ }
888
+ return out;
889
+ };
643
890
  this.windowSource = () => {
644
891
  if (!this.table) return [];
645
- if (this.virtual) return this.table.getPrePaginationRowModel().rows;
892
+ if (this.rowsWindowed()) return this.table.getPrePaginationRowModel().rows;
646
893
  return this.table.getRowModel().rows;
647
894
  };
648
895
  this.scheduleRemeasure = () => {
896
+ if (this.remeasureDisposed) return;
649
897
  if (this.remeasurePending) return;
650
898
  this.remeasurePending = true;
651
899
  let ranMicro = false;
@@ -653,6 +901,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
653
901
  this.remeasureWindow();
654
902
  };
655
903
  const rafPass = () => {
904
+ this.remeasureRaf = null;
656
905
  this.remeasurePending = false;
657
906
  this.remeasureWindow();
658
907
  };
@@ -660,9 +909,18 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
660
909
  ranMicro = true;
661
910
  queueMicrotask(microPass);
662
911
  }
663
- if (typeof requestAnimationFrame === "function") requestAnimationFrame(rafPass);
912
+ if (typeof requestAnimationFrame === "function") this.remeasureRaf = requestAnimationFrame(rafPass);
664
913
  else if (ranMicro) this.remeasurePending = false;
665
- else setTimeout(rafPass, 0);
914
+ else this.remeasureRaf = setTimeout(rafPass, 0);
915
+ };
916
+ this.teardownRemeasure = () => {
917
+ this.remeasureDisposed = true;
918
+ if (this.remeasureRaf != null) {
919
+ if (typeof requestAnimationFrame === "function") cancelAnimationFrame(this.remeasureRaf);
920
+ else clearTimeout(this.remeasureRaf);
921
+ this.remeasureRaf = null;
922
+ }
923
+ this.remeasurePending = false;
666
924
  };
667
925
  this.pinnedEditIndex = () => {
668
926
  if (this._editingRow.value >= 0) return this._editingRow.value;
@@ -675,19 +933,123 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
675
933
  return ms && ms[pin] ? ms[pin] : null;
676
934
  };
677
935
  this.remeasureWindow = () => {
936
+ if (this.remeasureDisposed) return;
678
937
  if (!this.virtualizer || !this.gridRoot) return;
679
938
  if (this.virtualizer.scrollState) return;
680
939
  const trs = this.gridRoot.querySelectorAll("tbody.rdt-tbody > tr[data-index]");
681
940
  for (const tr of trs) this.virtualizer.measureElement(tr);
941
+ if (this.afterRowRemeasure) this.afterRowRemeasure();
682
942
  };
683
943
  this.virtualItemKey = (i) => {
684
944
  const src = this.windowSource();
685
945
  return src && src[i] ? src[i].id : void 0;
686
946
  };
947
+ this.COL_OVERSCAN = 3;
948
+ this.colRtlObserver = null;
949
+ this.colRtlObserverEl = null;
950
+ this.isColRtl = () => {
951
+ if (!this.gridScrollEl || typeof getComputedStyle !== "function") return false;
952
+ return getComputedStyle(this.gridScrollEl).direction === "rtl";
953
+ };
954
+ this.ensureColRtlWatch = () => {
955
+ if (!this.gridScrollEl || this.colRtlObserverEl === this.gridScrollEl || typeof MutationObserver !== "function") return;
956
+ if (this.colRtlObserver) this.colRtlObserver.disconnect();
957
+ this.colRtlObserver = new MutationObserver(() => {
958
+ if (this.colVirtualizer) this.colVirtualizer.setOptions({
959
+ ...this.colVirtualizer.options,
960
+ isRtl: this.isColRtl()
961
+ });
962
+ });
963
+ this.colRtlObserver.observe(this.gridScrollEl, {
964
+ attributes: true,
965
+ attributeFilter: ["dir"]
966
+ });
967
+ this.colRtlObserverEl = this.gridScrollEl;
968
+ };
969
+ this.teardownColRtlWatch = () => {
970
+ if (this.colRtlObserver) this.colRtlObserver.disconnect();
971
+ this.colRtlObserver = null;
972
+ this.colRtlObserverEl = null;
973
+ };
974
+ this.columnVirtualizerOptions = () => {
975
+ this.ensureColRtlWatch();
976
+ return {
977
+ count: this.columnCount(),
978
+ getScrollElement: () => this.gridScrollEl,
979
+ estimateSize: (i) => this.columnSize(i),
980
+ horizontal: true,
981
+ isRtl: this.isColRtl(),
982
+ observeElementRect,
983
+ observeElementOffset,
984
+ scrollToFn: elementScroll,
985
+ measureElement,
986
+ overscan: this.COL_OVERSCAN,
987
+ onChange: () => {
988
+ this._windowVer.value = this._windowVer.value + 1;
989
+ }
990
+ };
991
+ };
992
+ this.measuredRowTotal = 0;
993
+ this.measuredRowCount = 0;
994
+ this.lastFedRowEstimate = 0;
995
+ this.foldedRowHeights = {};
996
+ this.windowVerBumpPending = false;
997
+ this.bumpWindowVer = () => {
998
+ if (this.windowVerBumpPending) return;
999
+ this.windowVerBumpPending = true;
1000
+ const flush = () => {
1001
+ this.windowVerBumpPending = false;
1002
+ this._windowVer.value = this._windowVer.value + 1;
1003
+ };
1004
+ if (typeof queueMicrotask !== "undefined") queueMicrotask(flush);
1005
+ else setTimeout(flush, 0);
1006
+ };
1007
+ this.ESTIMATE_REFEED_DELTA_PX = 4;
1008
+ this.estimateRowSize = (i) => {
1009
+ if (!this.autoMeasureOn()) return this.estimateRowHeight;
1010
+ if (this.measuredRowCount === 0) return this.estimateRowHeight;
1011
+ return Math.round(this.measuredRowTotal / this.measuredRowCount);
1012
+ };
1013
+ this.foldMeasuredRow = (index, height) => {
1014
+ const prev = this.foldedRowHeights[index];
1015
+ if (prev === height) return;
1016
+ if (prev == null) {
1017
+ this.measuredRowTotal = this.measuredRowTotal + height;
1018
+ this.measuredRowCount = this.measuredRowCount + 1;
1019
+ } else this.measuredRowTotal = this.measuredRowTotal - prev + height;
1020
+ this.foldedRowHeights[index] = height;
1021
+ };
1022
+ this.refineRowEstimate = () => {
1023
+ if (!this.autoMeasureOn() || !this.virtualizer) return;
1024
+ const items = this.virtualizer.getVirtualItems();
1025
+ const measurements = this.virtualizer.getMeasurements();
1026
+ for (let i = 0; i < items.length; i++) {
1027
+ const idx = items[i].index;
1028
+ const m = measurements && measurements[idx];
1029
+ if (m) this.foldMeasuredRow(idx, m.size);
1030
+ }
1031
+ if (this.virtualizer.scrollState) return;
1032
+ const est = this.estimateRowSize(0);
1033
+ if (Math.abs(est - this.lastFedRowEstimate) < this.ESTIMATE_REFEED_DELTA_PX) return;
1034
+ const anchorIndex = items.length ? items[0].index : -1;
1035
+ const anchorStart = items.length ? items[0].start : 0;
1036
+ this.virtualizer.setOptions(this.virtualizerOptions());
1037
+ this.virtualizer._willUpdate();
1038
+ this.lastFedRowEstimate = est;
1039
+ if (anchorIndex >= 0 && this.gridScrollEl) {
1040
+ const freshMeasurements = this.virtualizer.getMeasurements();
1041
+ const fresh = freshMeasurements && freshMeasurements[anchorIndex];
1042
+ if (fresh) {
1043
+ const delta = fresh.start - anchorStart;
1044
+ if (delta !== 0) this.gridScrollEl.scrollTop = this.gridScrollEl.scrollTop + delta;
1045
+ }
1046
+ }
1047
+ this.bumpWindowVer();
1048
+ };
687
1049
  this.virtualizerOptions = () => ({
688
1050
  count: this.windowSource().length,
689
1051
  getScrollElement: () => this.gridScrollEl,
690
- estimateSize: () => this.estimateRowHeight,
1052
+ estimateSize: (i) => this.estimateRowSize(i),
691
1053
  observeElementRect,
692
1054
  observeElementOffset,
693
1055
  scrollToFn: elementScroll,
@@ -695,7 +1057,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
695
1057
  overscan: 8,
696
1058
  getItemKey: this.virtualItemKey,
697
1059
  onChange: () => {
698
- this._windowVer.value = this._windowVer.value + 1;
1060
+ this.bumpWindowVer();
699
1061
  this.scheduleRemeasure();
700
1062
  }
701
1063
  });
@@ -704,8 +1066,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
704
1066
  this._windowVer.value;
705
1067
  this._editVer.value;
706
1068
  if (!this.virtualizer) {
707
- if (!this.virtual) return (this._rows.value || []).map((r) => ({
708
- vi: null,
1069
+ if (!this.rowsWindowed()) return (this._rows.value || []).map((r, i) => ({
1070
+ vi: { index: i },
709
1071
  row: r
710
1072
  }));
711
1073
  return [];
@@ -741,7 +1103,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
741
1103
  this.padTop = () => {
742
1104
  this._windowVer.value;
743
1105
  this._editVer.value;
744
- if (!this.virtual || !this.virtualizer) return 0;
1106
+ if (!this.rowsWindowed() || !this.virtualizer) return 0;
745
1107
  const items = this.virtualizer.getVirtualItems();
746
1108
  let pad = items.length ? items[0].start : 0;
747
1109
  const pin = this.pinnedEditIndex();
@@ -755,7 +1117,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
755
1117
  this.padBottom = () => {
756
1118
  this._windowVer.value;
757
1119
  this._editVer.value;
758
- if (!this.virtual || !this.virtualizer) return 0;
1120
+ if (!this.rowsWindowed() || !this.virtualizer) return 0;
759
1121
  const items = this.virtualizer.getVirtualItems();
760
1122
  if (!items.length) return 0;
761
1123
  let pad = this.virtualizer.getTotalSize() - items[items.length - 1].end;
@@ -776,11 +1138,59 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
776
1138
  return false;
777
1139
  };
778
1140
  this.rowIsOutsideWindow = (r) => {
779
- if (!this.virtual || !this.virtualizer) return false;
1141
+ if (!this.rowsWindowed() || !this.virtualizer) return false;
780
1142
  const items = this.virtualizer.getVirtualItems();
781
1143
  for (const it of items) if (it.index === r) return false;
782
1144
  return true;
783
1145
  };
1146
+ this.windowedColIndices = () => {
1147
+ this._windowVer.value;
1148
+ this._editVer.value;
1149
+ if (!this.colsWindowed()) {
1150
+ const n = this.columnCount();
1151
+ const out = [];
1152
+ for (let i = 0; i < n; i++) out.push(i);
1153
+ return out;
1154
+ }
1155
+ if (!this.colVirtualizer) return [];
1156
+ const idx = this.colVirtualizer.getVirtualItems().map((it) => it.index);
1157
+ const forced = this.forcedColumns();
1158
+ for (let i = 0; i < forced.length; i++) if (idx.indexOf(forced[i]) === -1) idx.push(forced[i]);
1159
+ idx.sort((a, b) => a - b);
1160
+ return idx;
1161
+ };
1162
+ this.colPadLeft = () => {
1163
+ this._windowVer.value;
1164
+ this._editVer.value;
1165
+ if (!this.colsWindowed() || !this.colVirtualizer) return 0;
1166
+ const items = this.colVirtualizer.getVirtualItems();
1167
+ let pad = items.length ? items[0].start : 0;
1168
+ if (items.length) {
1169
+ const firstIdx = items[0].index;
1170
+ const forced = this.forcedColumns();
1171
+ for (let i = 0; i < forced.length; i++) if (forced[i] < firstIdx) pad = pad - this.columnSize(forced[i]);
1172
+ }
1173
+ return pad < 0 ? 0 : pad;
1174
+ };
1175
+ this.colPadRight = () => {
1176
+ this._windowVer.value;
1177
+ this._editVer.value;
1178
+ if (!this.colsWindowed() || !this.colVirtualizer) return 0;
1179
+ const items = this.colVirtualizer.getVirtualItems();
1180
+ if (!items.length) return 0;
1181
+ let pad = this.colVirtualizer.getTotalSize() - items[items.length - 1].end;
1182
+ const lastIdx = items[items.length - 1].index;
1183
+ const forced = this.forcedColumns();
1184
+ for (let i = 0; i < forced.length; i++) if (forced[i] > lastIdx) pad = pad - this.columnSize(forced[i]);
1185
+ return pad < 0 ? 0 : pad;
1186
+ };
1187
+ this.colIsOutsideWindow = (c) => {
1188
+ if (!this.colsWindowed() || !this.colVirtualizer) return false;
1189
+ const items = this.colVirtualizer.getVirtualItems();
1190
+ for (const it of items) if (it.index === c) return false;
1191
+ return true;
1192
+ };
1193
+ this.afterRowRemeasure = this.refineRowEstimate;
784
1194
  this.announceState = {
785
1195
  sorting: null,
786
1196
  columnFilters: null,
@@ -879,9 +1289,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
879
1289
  return "";
880
1290
  };
881
1291
  this.defFor = (colId) => {
882
- const defs = this.columnDefs();
883
- for (const d of defs) if (d.id === colId) return d;
884
- return null;
1292
+ if (colId == null) return null;
1293
+ const d = this.defIndex()[String(colId)];
1294
+ return d != null ? d : null;
885
1295
  };
886
1296
  this.visibleCellsFor = (row) => this._rowModelVer.value >= 0 ? row.getVisibleCells() : [];
887
1297
  this.editMetaOf = (colId) => {
@@ -1058,22 +1468,56 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1058
1468
  return base;
1059
1469
  };
1060
1470
  this.rowIsGrouped = (row) => !!(this.tick() >= 0 && row && row.getIsGrouped && row.getIsGrouped());
1471
+ this.rowIndexIsGrouped = (rowIndex) => this.rowIsGrouped((this._rows.value || [])[rowIndex]);
1061
1472
  this.groupingActive = () => this.tick() >= 0 && (this.currentState().grouping || []).length > 0;
1062
1473
  this.cellIsGrouped = (cellCtx) => !!(this.tick() >= 0 && cellCtx && cellCtx.getIsGrouped && cellCtx.getIsGrouped());
1063
1474
  this.cellIsAggregated = (cellCtx) => !!(this.tick() >= 0 && cellCtx && cellCtx.getIsAggregated && cellCtx.getIsAggregated());
1064
1475
  this.cellIsPlaceholder = (cellCtx) => !!(this.tick() >= 0 && cellCtx && cellCtx.getIsPlaceholder && cellCtx.getIsPlaceholder());
1065
- this.groupSubRowCount = (row) => row && row.getLeafRows ? row.getLeafRows().length : row && row.subRows ? row.subRows.length : 0;
1476
+ this.groupSubRowCount = (row) => {
1477
+ if (row && row.getLeafRows) {
1478
+ const leaves = row.getLeafRows();
1479
+ let n = 0;
1480
+ for (let i = 0; i < leaves.length; i++) {
1481
+ const r = leaves[i];
1482
+ if (!(r && r.getIsGrouped && r.getIsGrouped())) n = n + 1;
1483
+ }
1484
+ return n;
1485
+ }
1486
+ return row && row.subRows ? row.subRows.length : 0;
1487
+ };
1488
+ this.groupRowDescriptorCache = null;
1489
+ this.groupRowDescriptorCacheVer = void 0;
1490
+ this.groupRowDescriptor = (row) => {
1491
+ const ver = this._rowModelVer.value;
1492
+ if (!this.groupRowDescriptorCache || this.groupRowDescriptorCacheVer !== ver) {
1493
+ this.groupRowDescriptorCache = Object.create(null);
1494
+ this.groupRowDescriptorCacheVer = ver;
1495
+ }
1496
+ const key = String(row.id);
1497
+ let d = this.groupRowDescriptorCache[key];
1498
+ if (!d) {
1499
+ const groupingColumnId = row.groupingColumnId != null ? row.groupingColumnId : "";
1500
+ const groupingValue = row.getGroupingValue ? row.getGroupingValue(groupingColumnId) : row.groupingValue;
1501
+ d = {
1502
+ isGroupRow: true,
1503
+ groupId: row.id,
1504
+ groupingColumnId,
1505
+ groupingValue,
1506
+ leafCount: this.groupSubRowCount(row)
1507
+ };
1508
+ this.groupRowDescriptorCache[key] = d;
1509
+ }
1510
+ return d;
1511
+ };
1512
+ this.cellSlotRow = (row) => this.rowIsGrouped(row) ? this.groupRowDescriptor(row) : row ? row.original : null;
1066
1513
  this.groupingKeys = () => this.currentState().grouping || [];
1067
1514
  this.groupableColumns = () => {
1068
1515
  const out = [];
1069
- const defs = this.columnDefs();
1070
- for (const d of defs) {
1071
- if (!d || d.groupable === false) continue;
1072
- out.push({
1073
- id: d.id,
1074
- label: d.header != null ? d.header : d.id
1075
- });
1076
- }
1516
+ const defs = collectGroupableLeafDefs(this.columnDefs());
1517
+ for (const d of defs) out.push({
1518
+ id: d.id,
1519
+ label: d.header != null ? d.header : d.id
1520
+ });
1077
1521
  return out;
1078
1522
  };
1079
1523
  this.stopEvent = (evt) => {
@@ -1153,7 +1597,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1153
1597
  };
1154
1598
  this.getRowIndexRelativeToPage = (absRow) => {
1155
1599
  const abs = absRow == null ? this.toAbsRow(this._activeRow.value) : Math.trunc(Number(absRow)) || 0;
1156
- if (this.virtual) return abs;
1600
+ if (this.rowsWindowed()) return abs;
1157
1601
  return abs - this.pageRowOffset();
1158
1602
  };
1159
1603
  this.cut = () => this.cutRange();
@@ -1164,12 +1608,12 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1164
1608
  this.colIndexOf = (row, cellCtx) => this.tick() >= 0 ? this.visibleCellsFor(row).indexOf(cellCtx) : -1;
1165
1609
  this.headerColIndexOf = (hg, header) => (hg && hg.headers ? hg.headers : []).indexOf(header);
1166
1610
  this.pageRowOffset = () => {
1167
- if (!this.isGrid() || this.virtual) return 0;
1611
+ if (!this.isGrid() || this.rowsWindowed()) return 0;
1168
1612
  return this.pageIndex() * this.pageSize();
1169
1613
  };
1170
1614
  this.toAbsRow = (localRow) => localRow + this.pageRowOffset();
1171
1615
  this.prePaginationRowCount = () => {
1172
- if (!this.table || this.virtual) return this.bodyRowCount();
1616
+ if (!this.table || this.rowsWindowed()) return this.bodyRowCount();
1173
1617
  const pm = this.table.getPrePaginationRowModel();
1174
1618
  return pm && pm.rows ? pm.rows.length : this.bodyRowCount();
1175
1619
  };
@@ -1204,8 +1648,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1204
1648
  const c = nextCol == null ? this._activeColIndex.value : nextCol;
1205
1649
  const lvl = nextLevel == null ? this._activeHeaderLevel.value : nextLevel;
1206
1650
  const header = nextIsHeader == null ? this._activeIsHeader.value : nextIsHeader;
1207
- if (this.virtual && this.virtualizer && !header && this.rowIsOutsideWindow(r)) {
1208
- this.virtualizer.scrollToIndex(r, { align: "center" });
1651
+ const rowOut = this.rowsWindowed() && this.virtualizer && this.rowIsOutsideWindow(r);
1652
+ const colOut = this.colsWindowed() && this.colVirtualizer && this.colIsOutsideWindow(c);
1653
+ if (!header && (rowOut || colOut)) {
1654
+ if (rowOut) this.virtualizer.scrollToIndex(r, { align: "center" });
1655
+ if (colOut) this.colVirtualizer.scrollToIndex(c, { align: "center" });
1209
1656
  let focusAttempts = 0;
1210
1657
  const myEpoch = this.focusIntentEpoch;
1211
1658
  const focusWhenReady = () => {
@@ -1244,7 +1691,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1244
1691
  return hg.length ? (hg[hg.length - 1].headers || []).length : 0;
1245
1692
  };
1246
1693
  this.bodyRowCount = () => (this._rows.value || []).length;
1247
- this.clamp = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
1248
1694
  this.headerLeafLevel = () => {
1249
1695
  const hg = this._headerGroups.value || [];
1250
1696
  return hg.length ? hg.length - 1 : 0;
@@ -1290,7 +1736,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1290
1736
  };
1291
1737
  this.moveCol = (delta) => {
1292
1738
  const max = (this._activeIsHeader.value ? this.headerCountAtLevel(this._activeHeaderLevel.value) : this.visibleColCount()) - 1;
1293
- const nextCol = this.clamp(this._activeColIndex.value + delta, 0, max < 0 ? 0 : max);
1739
+ const nextCol = clamp(this._activeColIndex.value + delta, 0, max < 0 ? 0 : max);
1294
1740
  this._activeColIndex.value = nextCol;
1295
1741
  return nextCol;
1296
1742
  };
@@ -1320,7 +1766,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1320
1766
  isHeader: true,
1321
1767
  level: this._activeHeaderLevel.value
1322
1768
  };
1323
- const landRow = this.clamp(delta - 1, 0, maxRow);
1769
+ const landRow = clamp(delta - 1, 0, maxRow);
1324
1770
  this._activeIsHeader.value = false;
1325
1771
  this._activeRow.value = landRow;
1326
1772
  return {
@@ -1359,7 +1805,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1359
1805
  level: leafLevel
1360
1806
  };
1361
1807
  }
1362
- const nextRow = this.clamp(this._activeRow.value + delta, 0, maxRow);
1808
+ const nextRow = clamp(this._activeRow.value + delta, 0, maxRow);
1363
1809
  this._activeRow.value = nextRow;
1364
1810
  this._activeIsHeader.value = false;
1365
1811
  return {
@@ -1408,19 +1854,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1408
1854
  const rowKey = this._activeIsHeader.value ? "__header" : String(this._activeRow.value);
1409
1855
  return this.resolveCellEl(rowKey, this._activeColIndex.value, this._activeIsHeader.value ? this._activeHeaderLevel.value : null);
1410
1856
  };
1411
- this.focusables = (cellEl) => {
1412
- if (!cellEl || !cellEl.querySelectorAll) return [];
1413
- return Array.prototype.slice.call(cellEl.querySelectorAll("button,[href],input,select,textarea,[tabindex]:not([tabindex=\"-1\"])")).filter((n) => !n.disabled);
1414
- };
1415
1857
  this.enterControl = () => {
1416
- const cellEl = this.currentCellEl();
1417
- const list = this.focusables(cellEl);
1858
+ const list = focusables(this.currentCellEl());
1418
1859
  if (!list.length) return;
1419
1860
  this._activeInControl.value = true;
1420
1861
  list[0].focus();
1421
1862
  };
1422
1863
  this.cycleWithinCell = (cellEl, forward) => {
1423
- const list = this.focusables(cellEl);
1864
+ const list = focusables(cellEl);
1424
1865
  if (!list.length) return;
1425
1866
  const active = this.gridRoot ? this.gridRoot.getRootNode().activeElement : null;
1426
1867
  const cur = list.indexOf(active);
@@ -1791,7 +2232,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1791
2232
  }
1792
2233
  }
1793
2234
  const maxCol = colN - 1;
1794
- const col = this.clamp(this._activeColIndex.value, 0, maxCol < 0 ? 0 : maxCol);
2235
+ const col = clamp(this._activeColIndex.value, 0, maxCol < 0 ? 0 : maxCol);
1795
2236
  if (col !== this._activeColIndex.value) this._activeColIndex.value = col;
1796
2237
  if (rowN <= 0) {
1797
2238
  this._activeIsHeader.value = true;
@@ -1809,16 +2250,48 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1809
2250
  if (!this._activeIsHeader.value) {
1810
2251
  const lastRow = rowN - 1;
1811
2252
  const maxRow = lastRow < 0 ? 0 : lastRow;
1812
- const row = this.clamp(this._activeRow.value, 0, maxRow);
2253
+ const row = clamp(this._activeRow.value, 0, maxRow);
1813
2254
  if (row !== this._activeRow.value) this._activeRow.value = row;
1814
2255
  }
1815
2256
  this.clampRange(rowN - 1, colN - 1);
1816
2257
  if (recoverFocus) {
1817
- const recRow = this.clamp(doomedRow, 0, rowN - 1);
1818
- const recCol = this.clamp(doomedCol, 0, maxCol < 0 ? 0 : maxCol);
2258
+ const recRow = clamp(doomedRow, 0, rowN - 1);
2259
+ const recCol = clamp(doomedCol, 0, maxCol < 0 ? 0 : maxCol);
1819
2260
  this.recoverGridFocus(String(recRow), recCol, null);
1820
2261
  }
1821
2262
  };
2263
+ this.windowedHeadersFor = (hg, hgLevel) => {
2264
+ const headers = hg && hg.headers || [];
2265
+ if (!this.colsWindowed()) return headers.map((h) => ({
2266
+ header: h,
2267
+ span: h && h.colSpan > 1 ? h.colSpan : 1
2268
+ }));
2269
+ const idx = this.windowedColIndices();
2270
+ const idxSet = {};
2271
+ for (let i = 0; i < idx.length; i++) idxSet[idx[i]] = true;
2272
+ let cursor = 0;
2273
+ const out = [];
2274
+ for (let i = 0; i < headers.length; i++) {
2275
+ const h = headers[i];
2276
+ const leafCount = h && h.colSpan ? h.colSpan : 1;
2277
+ const start = cursor;
2278
+ const end = cursor + leafCount;
2279
+ cursor = end;
2280
+ let span = 0;
2281
+ for (let c = start; c < end; c++) if (idxSet[c]) span = span + 1;
2282
+ if (span > 0) out.push({
2283
+ header: h,
2284
+ span
2285
+ });
2286
+ }
2287
+ return out;
2288
+ };
2289
+ this.windowedColSpan = () => this.colsWindowed() ? this.windowedColIndices().length + 2 : this.visibleColCount();
2290
+ this.remeasureColumnWindow = () => {
2291
+ if (!this.colsWindowed() || !this.colVirtualizer) return;
2292
+ this.colVirtualizer.setOptions(this.columnVirtualizerOptions());
2293
+ this.colVirtualizer._willUpdate();
2294
+ };
1822
2295
  this.gridEmptyFallback = false;
1823
2296
  this.rangeTransition = false;
1824
2297
  this.rangeClickPending = false;
@@ -1847,8 +2320,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1847
2320
  focus: null
1848
2321
  };
1849
2322
  const clampCorner = (c) => c == null ? null : {
1850
- rowIndex: this.clamp(c.rowIndex, 0, maxRow),
1851
- colIndex: this.clamp(c.colIndex, 0, maxCol)
2323
+ rowIndex: clamp(c.rowIndex, 0, maxRow),
2324
+ colIndex: clamp(c.colIndex, 0, maxCol)
1852
2325
  };
1853
2326
  return {
1854
2327
  anchor: clampCorner(a),
@@ -1891,8 +2364,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1891
2364
  colIndex: this._activeColIndex.value
1892
2365
  };
1893
2366
  }
1894
- const nextRow = this.clamp(focus.rowIndex + dRow, 0, maxRow);
1895
- const nextCol = this.clamp(focus.colIndex + dCol, 0, maxCol);
2367
+ const nextRow = clamp(focus.rowIndex + dRow, 0, maxRow);
2368
+ const nextCol = clamp(focus.colIndex + dCol, 0, maxCol);
1896
2369
  const nextFocus = {
1897
2370
  rowIndex: nextRow,
1898
2371
  colIndex: nextCol
@@ -1916,8 +2389,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1916
2389
  colIndex: this._activeColIndex.value
1917
2390
  };
1918
2391
  const nextFocus = {
1919
- rowIndex: this.clamp(Math.trunc(Number(rIdx)) || 0, 0, maxRow),
1920
- colIndex: this.clamp(Math.trunc(Number(cIdx)) || 0, 0, maxCol)
2392
+ rowIndex: clamp(Math.trunc(Number(rIdx)) || 0, 0, maxRow),
2393
+ colIndex: clamp(Math.trunc(Number(cIdx)) || 0, 0, maxCol)
1921
2394
  };
1922
2395
  this._rangeAnchor.value = anchor;
1923
2396
  this._rangeFocus.value = nextFocus;
@@ -1961,16 +2434,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1961
2434
  return;
1962
2435
  }
1963
2436
  if (a) {
1964
- const ar = this.clamp(a.rowIndex, 0, maxRow);
1965
- const ac = this.clamp(a.colIndex, 0, maxCol);
2437
+ const ar = clamp(a.rowIndex, 0, maxRow);
2438
+ const ac = clamp(a.colIndex, 0, maxCol);
1966
2439
  if (ar !== a.rowIndex || ac !== a.colIndex) this._rangeAnchor.value = {
1967
2440
  rowIndex: ar,
1968
2441
  colIndex: ac
1969
2442
  };
1970
2443
  }
1971
2444
  if (f) {
1972
- const fr = this.clamp(f.rowIndex, 0, maxRow);
1973
- const fc = this.clamp(f.colIndex, 0, maxCol);
2445
+ const fr = clamp(f.rowIndex, 0, maxRow);
2446
+ const fc = clamp(f.colIndex, 0, maxCol);
1974
2447
  if (fr !== f.rowIndex || fc !== f.colIndex) this._rangeFocus.value = {
1975
2448
  rowIndex: fr,
1976
2449
  colIndex: fc
@@ -1992,10 +2465,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1992
2465
  const maxRow = this.bodyRowCount() - 1;
1993
2466
  const maxCol = this.visibleColCount() - 1;
1994
2467
  if (maxRow < 0 || maxCol < 0) return null;
1995
- const ar = this.clamp(a.rowIndex, 0, maxRow);
1996
- const ac = this.clamp(a.colIndex, 0, maxCol);
1997
- const fr = this.clamp(f.rowIndex, 0, maxRow);
1998
- const fc = this.clamp(f.colIndex, 0, maxCol);
2468
+ const ar = clamp(a.rowIndex, 0, maxRow);
2469
+ const ac = clamp(a.colIndex, 0, maxCol);
2470
+ const fr = clamp(f.rowIndex, 0, maxRow);
2471
+ const fc = clamp(f.colIndex, 0, maxCol);
1999
2472
  return {
2000
2473
  r0: ar < fr ? ar : fr,
2001
2474
  r1: ar > fr ? ar : fr,
@@ -2003,10 +2476,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2003
2476
  c1: ac > fc ? ac : fc
2004
2477
  };
2005
2478
  };
2006
- this.escapeTsvField = (s) => {
2007
- if (s.indexOf(" ") >= 0 || s.indexOf("\n") >= 0 || s.indexOf("\r") >= 0 || s.indexOf("\"") >= 0) return "\"" + s.replace(/"/g, "\"\"") + "\"";
2008
- return s;
2009
- };
2010
2479
  this.rangeToTsv = () => {
2011
2480
  const box = this.normalizedRange();
2012
2481
  const r0 = box ? box.r0 : this._activeRow.value;
@@ -2018,77 +2487,12 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2018
2487
  const cells = [];
2019
2488
  for (let c = c0; c <= c1; c++) {
2020
2489
  const v = this.cellValueAt(r, c);
2021
- cells.push(this.escapeTsvField(v == null ? "" : String(v)));
2490
+ cells.push(escapeTsvField(v == null ? "" : String(v)));
2022
2491
  }
2023
2492
  lines.push(cells.join(" "));
2024
2493
  }
2025
2494
  return lines.join("\n");
2026
2495
  };
2027
- this.parseTsv = (text) => {
2028
- const str = text != null ? String(text) : "";
2029
- if (str === "" || str.length > 2e6) return [];
2030
- const rows = [];
2031
- let row = [];
2032
- let field = "";
2033
- let inQuotes = false;
2034
- let i = 0;
2035
- const n = str.length;
2036
- while (i < n) {
2037
- const ch = str[i];
2038
- if (inQuotes) {
2039
- if (ch === "\"") {
2040
- if (i + 1 < n && str[i + 1] === "\"") {
2041
- field = field + "\"";
2042
- i = i + 2;
2043
- continue;
2044
- }
2045
- inQuotes = false;
2046
- i = i + 1;
2047
- continue;
2048
- }
2049
- field = field + ch;
2050
- i = i + 1;
2051
- continue;
2052
- }
2053
- if (ch === "\"" && field === "") {
2054
- inQuotes = true;
2055
- i = i + 1;
2056
- continue;
2057
- }
2058
- if (ch === " ") {
2059
- row.push(field);
2060
- field = "";
2061
- i = i + 1;
2062
- continue;
2063
- }
2064
- if (ch === "\r") {
2065
- if (i + 1 < n && str[i + 1] === "\n") i = i + 1;
2066
- row.push(field);
2067
- field = "";
2068
- rows.push(row);
2069
- row = [];
2070
- i = i + 1;
2071
- continue;
2072
- }
2073
- if (ch === "\n") {
2074
- row.push(field);
2075
- field = "";
2076
- rows.push(row);
2077
- row = [];
2078
- i = i + 1;
2079
- continue;
2080
- }
2081
- field = field + ch;
2082
- i = i + 1;
2083
- }
2084
- row.push(field);
2085
- rows.push(row);
2086
- if (rows.length > 1) {
2087
- const last = rows[rows.length - 1];
2088
- if (last.length === 1 && last[0] === "") rows.pop();
2089
- }
2090
- return rows;
2091
- };
2092
2496
  this.copyRange = () => {
2093
2497
  if (!this.clipboardActiveAllowed()) return;
2094
2498
  if (typeof navigator === "undefined" || !navigator.clipboard || !navigator.clipboard.writeText) return;
@@ -2111,11 +2515,13 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2111
2515
  for (let gr = 0; gr < grid.length; gr++) {
2112
2516
  const r = originRow + gr;
2113
2517
  if (r > maxRow) break;
2518
+ const rowGrouped = this.rowIndexIsGrouped(r);
2114
2519
  const cols = grid[gr] || [];
2115
2520
  for (let gc = 0; gc < cols.length; gc++) {
2116
2521
  const c = originCol + gc;
2117
2522
  if (c > maxCol) break;
2118
2523
  total = total + 1;
2524
+ if (rowGrouped) continue;
2119
2525
  const colId = this.columnIdAt(r, c);
2120
2526
  if (colId == null || !this.columnEditable(colId)) continue;
2121
2527
  const rowObj = this.rowOriginalAt(r);
@@ -2124,7 +2530,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2124
2530
  const field = this.fieldOfColId(colId);
2125
2531
  const srcIndex = this.sourceIndexOfRow(r);
2126
2532
  const oldValue = rowObj ? rowObj[field] : null;
2127
- next = this.replaceRowValue(next, srcIndex, field, value);
2533
+ next = replaceRowValue(next, srcIndex, field, value);
2128
2534
  committed.push({
2129
2535
  rowId: this.rowIdAt(r),
2130
2536
  columnId: colId,
@@ -2159,30 +2565,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2159
2565
  const row = (this._rows.value || [])[rowIndex];
2160
2566
  return row ? row.id : null;
2161
2567
  };
2162
- this.tileGridToBox = (grid, box) => {
2163
- const srcRows = grid.length;
2164
- let srcCols = 0;
2165
- for (let i = 0; i < srcRows; i++) {
2166
- const w = grid[i] && grid[i].length ? grid[i].length : 0;
2167
- if (w > srcCols) srcCols = w;
2168
- }
2169
- if (srcRows <= 0 || srcCols <= 0) return grid;
2170
- const boxRows = box.r1 - box.r0 + 1;
2171
- const boxCols = box.c1 - box.c0 + 1;
2172
- const rows = boxRows > srcRows ? boxRows : srcRows;
2173
- const cols = boxCols > srcCols ? boxCols : srcCols;
2174
- const out = [];
2175
- for (let r = 0; r < rows; r++) {
2176
- const srcLine = grid[r % srcRows] || [];
2177
- const line = [];
2178
- for (let c = 0; c < cols; c++) {
2179
- const v = srcLine[c % srcCols];
2180
- line.push(v != null ? v : "");
2181
- }
2182
- out.push(line);
2183
- }
2184
- return out;
2185
- };
2186
2568
  this.pasteRange = () => {
2187
2569
  if (!this.clipboardActiveAllowed()) return;
2188
2570
  if (typeof navigator === "undefined" || !navigator.clipboard || !navigator.clipboard.readText) return;
@@ -2203,9 +2585,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2203
2585
  }
2204
2586
  if (!p || !p.then) return;
2205
2587
  p.then((text) => {
2206
- const grid = this.parseTsv(text);
2588
+ const grid = parseTsv(text);
2207
2589
  if (!grid.length) return;
2208
- const tiled = this.tileGridToBox(grid, destBox);
2590
+ const tiled = tileGridToBox(grid, destBox);
2209
2591
  this.applyGridToRange(tiled, anchorRow, anchorCol);
2210
2592
  }).catch(() => {});
2211
2593
  };
@@ -2243,13 +2625,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2243
2625
  }
2244
2626
  this.applyGridToRange(grid, r0, c0);
2245
2627
  };
2246
- this.tileIndex = (i, lo, hi) => {
2247
- const span = hi - lo + 1;
2248
- if (span <= 1) return lo;
2249
- let k = (i - lo) % span;
2250
- if (k < 0) k = k + span;
2251
- return lo + k;
2252
- };
2253
2628
  this.fillRange = (sourceBox, endCell) => {
2254
2629
  let box;
2255
2630
  if (sourceBox && sourceBox.r0 != null && endCell) {
@@ -2279,8 +2654,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2279
2654
  for (let r = box.r0; r <= box.r1; r++) {
2280
2655
  const cols = [];
2281
2656
  for (let c = box.c0; c <= box.c1; c++) {
2282
- const sr = this.tileIndex(r, src.r0, src.r1);
2283
- const sc = this.tileIndex(c, src.c0, src.c1);
2657
+ const sr = tileIndex(r, src.r0, src.r1);
2658
+ const sc = tileIndex(c, src.c0, src.c1);
2284
2659
  const v = this.cellValueAt(sr, sc);
2285
2660
  cols.push(v == null ? "" : String(v));
2286
2661
  }
@@ -2291,6 +2666,30 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2291
2666
  this.fillDragging = false;
2292
2667
  this.fillDragMove = null;
2293
2668
  this.fillDragUp = null;
2669
+ this.fillEdgeScrollRaf = null;
2670
+ this.FILL_EDGE_SCROLL_PX = 24;
2671
+ this.FILL_EDGE_SCROLL_STEP = 16;
2672
+ this.edgeDelta = (clientX, clientY) => {
2673
+ if (!this.gridScrollEl) return {
2674
+ dx: 0,
2675
+ dy: 0
2676
+ };
2677
+ const rect = this.gridScrollEl.getBoundingClientRect();
2678
+ let dx = 0;
2679
+ let dy = 0;
2680
+ if (this.colsWindowed()) {
2681
+ if (clientX - rect.left < this.FILL_EDGE_SCROLL_PX) dx = -this.FILL_EDGE_SCROLL_STEP;
2682
+ else if (rect.right - clientX < this.FILL_EDGE_SCROLL_PX) dx = this.FILL_EDGE_SCROLL_STEP;
2683
+ }
2684
+ if (this.rowsWindowed()) {
2685
+ if (clientY - rect.top < this.FILL_EDGE_SCROLL_PX) dy = -this.FILL_EDGE_SCROLL_STEP;
2686
+ else if (rect.bottom - clientY < this.FILL_EDGE_SCROLL_PX) dy = this.FILL_EDGE_SCROLL_STEP;
2687
+ }
2688
+ return {
2689
+ dx,
2690
+ dy
2691
+ };
2692
+ };
2294
2693
  this.teardownFillDrag = () => {
2295
2694
  if (typeof document !== "undefined") {
2296
2695
  if (this.fillDragMove) document.removeEventListener("pointermove", this.fillDragMove);
@@ -2299,6 +2698,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2299
2698
  this.fillDragMove = null;
2300
2699
  this.fillDragUp = null;
2301
2700
  this.fillDragging = false;
2701
+ if (this.fillEdgeScrollRaf != null) {
2702
+ if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.fillEdgeScrollRaf);
2703
+ this.fillEdgeScrollRaf = null;
2704
+ }
2302
2705
  };
2303
2706
  this.cellIndexFromPoint = (clientX, clientY) => {
2304
2707
  if (typeof document === "undefined" || !document.elementFromPoint) return null;
@@ -2333,14 +2736,42 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2333
2736
  r: sourceBox.r1,
2334
2737
  c: sourceBox.c1
2335
2738
  } : null;
2336
- const move = (ev) => {
2337
- if (!this.fillDragging) return;
2338
- const cell = this.cellIndexFromPoint(ev.clientX, ev.clientY);
2739
+ let lastClientX = 0;
2740
+ let lastClientY = 0;
2741
+ const applyPointAt = (clientX, clientY) => {
2742
+ const cell = this.cellIndexFromPoint(clientX, clientY);
2339
2743
  if (cell && (!lastCell || cell.r !== lastCell.r || cell.c !== lastCell.c)) {
2340
2744
  lastCell = cell;
2341
2745
  this.setRangeFocus(cell.r, cell.c);
2342
2746
  }
2343
2747
  };
2748
+ const scrollStep = () => {
2749
+ if (!this.fillDragging) {
2750
+ this.fillEdgeScrollRaf = null;
2751
+ return;
2752
+ }
2753
+ const d = this.edgeDelta(lastClientX, lastClientY);
2754
+ if (d.dx === 0 && d.dy === 0) {
2755
+ this.fillEdgeScrollRaf = null;
2756
+ return;
2757
+ }
2758
+ if (this.gridScrollEl) {
2759
+ if (d.dx !== 0) this.gridScrollEl.scrollLeft = this.gridScrollEl.scrollLeft + d.dx;
2760
+ if (d.dy !== 0) this.gridScrollEl.scrollTop = this.gridScrollEl.scrollTop + d.dy;
2761
+ }
2762
+ applyPointAt(lastClientX, lastClientY);
2763
+ this.fillEdgeScrollRaf = requestAnimationFrame(scrollStep);
2764
+ };
2765
+ const move = (ev) => {
2766
+ if (!this.fillDragging) return;
2767
+ lastClientX = ev.clientX;
2768
+ lastClientY = ev.clientY;
2769
+ applyPointAt(ev.clientX, ev.clientY);
2770
+ if (this.fillEdgeScrollRaf == null && typeof requestAnimationFrame === "function") {
2771
+ const d = this.edgeDelta(ev.clientX, ev.clientY);
2772
+ if (d.dx !== 0 || d.dy !== 0) this.fillEdgeScrollRaf = requestAnimationFrame(scrollStep);
2773
+ }
2774
+ };
2344
2775
  const up = () => {
2345
2776
  this.teardownFillDrag();
2346
2777
  if (lastCell && sourceBox && (lastCell.r !== sourceBox.r1 || lastCell.c !== sourceBox.c1)) this.fillRange(sourceBox, lastCell);
@@ -2400,11 +2831,13 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2400
2831
  return cell && cell.column ? cell.column.id : null;
2401
2832
  };
2402
2833
  this.isActiveCellEditable = () => {
2834
+ if (this.rowIndexIsGrouped(this._activeRow.value)) return false;
2403
2835
  const colId = this.activeCellColumnId();
2404
2836
  return colId != null && this.columnEditable(colId);
2405
2837
  };
2406
2838
  this.isEditing = (rowIndex, colIndex) => {
2407
2839
  if (this._editVer.value < 0) return false;
2840
+ if (this.rowIndexIsGrouped(rowIndex)) return false;
2408
2841
  if (this._editingRowIndex.value != null && this._editingRowIndex.value === rowIndex) {
2409
2842
  const colId = this.columnIdAt(rowIndex, colIndex);
2410
2843
  return colId != null && this.columnEditable(colId);
@@ -2429,16 +2862,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2429
2862
  this.setInvalid = (msg) => {
2430
2863
  this._invalidMsg.value = msg != null ? msg : "";
2431
2864
  };
2432
- this.replaceRowValue = (rows, rowIndex, field, value) => {
2433
- const src = rows || [];
2434
- const out = [];
2435
- for (let i = 0; i < src.length; i++) if (i === rowIndex) out.push({
2436
- ...src[i] || {},
2437
- [field]: value
2438
- });
2439
- else out.push(src[i]);
2440
- return out;
2441
- };
2442
2865
  this.sourceIndexOfRow = (visibleRowIndex) => {
2443
2866
  const row = (this._rows.value || [])[visibleRowIndex];
2444
2867
  if (!row) return visibleRowIndex;
@@ -2514,6 +2937,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2514
2937
  return cell ? cell.getValue() : null;
2515
2938
  };
2516
2939
  this.beginEdit = (rowIndex, colIndex, seed) => {
2940
+ if (this.rowIndexIsGrouped(rowIndex)) return;
2517
2941
  const colId = this.columnIdAt(rowIndex, colIndex);
2518
2942
  if (colId == null || !this.columnEditable(colId)) return;
2519
2943
  this.committedThisSession = false;
@@ -2545,16 +2969,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2545
2969
  if (typeof requestAnimationFrame === "function") requestAnimationFrame(tryFocus);
2546
2970
  else setTimeout(tryFocus, 0);
2547
2971
  };
2548
- this.indexOfRowIn = (rows, rowOriginal, rowId) => {
2549
- const list = rows || [];
2550
- for (let i = 0; i < list.length; i++) {
2551
- const r = list[i];
2552
- if (!r) continue;
2553
- if (rowId != null && r.id === rowId) return i;
2554
- if (rowOriginal != null && r.original === rowOriginal) return i;
2555
- }
2556
- return -1;
2557
- };
2558
2972
  this.endEdit = () => {
2559
2973
  this._editingRow.value = -1;
2560
2974
  this._editingCol.value = -1;
@@ -2616,7 +3030,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2616
3030
  this.committedThisSession = true;
2617
3031
  if (changed) {
2618
3032
  const srcIndex = this.sourceIndexOfRow(this._editingRow.value);
2619
- const next = this.replaceRowValue(this.currentData(), srcIndex, field, newValue);
3033
+ const next = replaceRowValue(this.currentData(), srcIndex, field, newValue);
2620
3034
  this.writeData(next);
2621
3035
  this.dispatchEvent(new CustomEvent("cell-edit-commit", {
2622
3036
  detail: {
@@ -2641,6 +3055,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2641
3055
  return true;
2642
3056
  };
2643
3057
  this.toggleActiveBooleanCell = () => {
3058
+ if (this.rowIndexIsGrouped(this._activeRow.value)) return;
2644
3059
  const colId = this.columnIdAt(this._activeRow.value, this._activeColIndex.value);
2645
3060
  if (colId == null || !this.columnEditable(colId)) return;
2646
3061
  const row = (this._rows.value || [])[this._activeRow.value];
@@ -2659,7 +3074,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2659
3074
  const field = def && def.accessorKey != null ? def.accessorKey : colId;
2660
3075
  const srcIndex = this.sourceIndexOfRow(this._activeRow.value);
2661
3076
  this.committedThisSession = true;
2662
- this.writeData(this.replaceRowValue(this.currentData(), srcIndex, field, newValue));
3077
+ this.writeData(replaceRowValue(this.currentData(), srcIndex, field, newValue));
2663
3078
  this.dispatchEvent(new CustomEvent("cell-edit-commit", {
2664
3079
  detail: {
2665
3080
  rowId,
@@ -2730,6 +3145,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2730
3145
  this.beginRowEdit = (row) => {
2731
3146
  const rowIndex = this.rowIndexOf(row);
2732
3147
  if (rowIndex < 0) return;
3148
+ if (this.rowIndexIsGrouped(rowIndex)) return;
2733
3149
  const editable = this.editableColumnsForRow(rowIndex);
2734
3150
  if (editable.length === 0) return;
2735
3151
  this.committedThisSession = false;
@@ -2794,7 +3210,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2794
3210
  this.editTransition = true;
2795
3211
  if (changed) {
2796
3212
  const srcIndex = this.sourceIndexOfRow(rowIndex);
2797
- const next = this.replaceRowValues(this.currentData(), srcIndex, fieldValues);
3213
+ const next = replaceRowValues(this.currentData(), srcIndex, fieldValues);
2798
3214
  this.writeData(next);
2799
3215
  this.dispatchEvent(new CustomEvent("row-edit-commit", {
2800
3216
  detail: {
@@ -2824,17 +3240,6 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2824
3240
  this.editTransition = false;
2825
3241
  this.focusCellWhenReady(focusRow, focusCol);
2826
3242
  };
2827
- this.replaceRowValues = (rows, rowIndex, fieldValues) => {
2828
- const src = rows || [];
2829
- const fv = fieldValues || {};
2830
- const out = [];
2831
- for (let i = 0; i < src.length; i++) if (i === rowIndex) out.push({
2832
- ...src[i] || {},
2833
- ...fv
2834
- });
2835
- else out.push(src[i]);
2836
- return out;
2837
- };
2838
3243
  this.nextEditableCell = (fromRow, fromCol) => {
2839
3244
  const rowList = this._rows.value || [];
2840
3245
  const rowCount = rowList.length;
@@ -3019,8 +3424,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3019
3424
  const lastRow = this.bodyRowCount() - 1;
3020
3425
  const maxRow = lastRow < 0 ? 0 : lastRow;
3021
3426
  const maxCol = this.visibleColCount() - 1;
3022
- const r = this.clamp(Math.trunc(Number(rowIndex)) || 0, 0, maxRow);
3023
- const c = this.clamp(Math.trunc(Number(colIndex)) || 0, 0, maxCol < 0 ? 0 : maxCol);
3427
+ const r = clamp(Math.trunc(Number(rowIndex)) || 0, 0, maxRow);
3428
+ const c = clamp(Math.trunc(Number(colIndex)) || 0, 0, maxCol < 0 ? 0 : maxCol);
3024
3429
  this.committedThisSession = false;
3025
3430
  this._activeIsHeader.value = false;
3026
3431
  this._activeRow.value = r;
@@ -3037,7 +3442,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3037
3442
  this.editRow = (rowIndex) => {
3038
3443
  const lastRow = this.bodyRowCount() - 1;
3039
3444
  const maxRow = lastRow < 0 ? 0 : lastRow;
3040
- const r = this.clamp(Math.trunc(Number(rowIndex)) || 0, 0, maxRow);
3445
+ const r = clamp(Math.trunc(Number(rowIndex)) || 0, 0, maxRow);
3041
3446
  const row = (this._rows.value || [])[r];
3042
3447
  if (!row) return;
3043
3448
  this._activeIsHeader.value = false;
@@ -3071,12 +3476,13 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3071
3476
  if (!this.isGrid()) return;
3072
3477
  this.focusIntentEpoch = this.focusIntentEpoch + 1;
3073
3478
  const maxCol = this.visibleColCount() - 1;
3074
- const c = this.clamp(Math.trunc(Number(colIndex)) || 0, 0, maxCol < 0 ? 0 : maxCol);
3479
+ const c = clamp(Math.trunc(Number(colIndex)) || 0, 0, maxCol < 0 ? 0 : maxCol);
3075
3480
  const absLast = this.prePaginationRowCount() - 1;
3076
- const absRow = this.clamp(Math.trunc(Number(rowIndex)) || 0, 0, absLast < 0 ? 0 : absLast);
3481
+ const absRow = clamp(Math.trunc(Number(rowIndex)) || 0, 0, absLast < 0 ? 0 : absLast);
3077
3482
  const prevAbs = this.toAbsRow(this._activeRow.value);
3483
+ const prevCol = this._activeColIndex.value;
3078
3484
  const prevIsHeader = this._activeIsHeader.value;
3079
- if (this.virtual) {
3485
+ if (this.rowsWindowed()) {
3080
3486
  this._activeIsHeader.value = false;
3081
3487
  this._activeInControl.value = false;
3082
3488
  this._activeRow.value = absRow;
@@ -3095,7 +3501,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3095
3501
  if (switched) this.focusAbsCellWhenReady(absRow, localRow, c);
3096
3502
  else this.focusActiveCell(localRow, c, false);
3097
3503
  }
3098
- if (absRow !== prevAbs || prevIsHeader) this.dispatchEvent(new CustomEvent("activecell-change", {
3504
+ if (absRow !== prevAbs || c !== prevCol || prevIsHeader) this.dispatchEvent(new CustomEvent("activecell-change", {
3099
3505
  detail: {
3100
3506
  rowIndex: absRow,
3101
3507
  colIndex: c
@@ -3179,6 +3585,13 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3179
3585
  font: var(--rdt-font, 14px system-ui, sans-serif);
3180
3586
  color: var(--rdt-color, inherit);
3181
3587
  }
3588
+ .rozie-data-table.rdt-col-windowed[data-rozie-s-d5dcab4c] {
3589
+ table-layout: fixed;
3590
+ }
3591
+ .rozie-data-table.rdt-col-windowed[data-rozie-s-d5dcab4c] .rdt-th[data-rozie-s-d5dcab4c],
3592
+ .rozie-data-table.rdt-col-windowed[data-rozie-s-d5dcab4c] .rdt-td[data-rozie-s-d5dcab4c] {
3593
+ box-sizing: border-box;
3594
+ }
3182
3595
  .rdt-sr-live[data-rozie-s-d5dcab4c] {
3183
3596
  position: absolute;
3184
3597
  width: 1px;
@@ -3715,10 +4128,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3715
4128
  this._rows.value = nextRows;
3716
4129
  this._headerGroups.value = nextGroups;
3717
4130
  this._rowModelVer.value = this._rowModelVer.value + 1;
3718
- if (this.virtual && this.virtualizer) {
4131
+ if (this.rowsWindowed() && this.virtualizer) {
3719
4132
  this.virtualizer.setOptions(this.virtualizerOptions());
3720
4133
  this.virtualizer._willUpdate();
3721
4134
  }
4135
+ this.remeasureColumnWindow();
3722
4136
  const nextRowCount = nextRows.length;
3723
4137
  const nextColCount = nextRows.length ? nextRows[0].getVisibleCells().length : nextGroups.length ? (nextGroups[nextGroups.length - 1].headers || []).length : 0;
3724
4138
  this.clampActiveCell(nextRowCount, nextColCount);
@@ -3731,7 +4145,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3731
4145
  if (this.pendingEditFollow && this.isGrid()) {
3732
4146
  const follow = this.pendingEditFollow;
3733
4147
  this.pendingEditFollow = null;
3734
- const followIdx = this.indexOfRowIn(nextRows, follow.rowOriginal, follow.rowId);
4148
+ const followIdx = indexOfRowIn(nextRows, follow.rowOriginal, follow.rowId);
3735
4149
  if (followIdx >= 0) this.focusCellWhenReady(followIdx, follow.col);
3736
4150
  }
3737
4151
  this.syncIndeterminate();
@@ -3740,17 +4154,28 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3740
4154
  };
3741
4155
  this.refreshRowModel();
3742
4156
  this.gridRoot = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rozie-data-table") : null;
3743
- if (this.virtual) {
3744
- this.gridScrollEl = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rdt-scroll") : null;
4157
+ if (this.isWindowed()) this.gridScrollEl = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rdt-scroll") : null;
4158
+ if (this.rowsWindowed()) {
3745
4159
  this.virtualizer = new Virtualizer(this.virtualizerOptions());
3746
4160
  this.virtualizerCleanup = this.virtualizer._didMount();
3747
- this._windowVer.value = this._windowVer.value + 1;
4161
+ }
4162
+ if (this.colsWindowed()) {
4163
+ this.colVirtualizer = new Virtualizer(this.columnVirtualizerOptions());
4164
+ this.colVirtualizerCleanup = this.colVirtualizer._didMount();
4165
+ }
4166
+ if (this.isWindowed()) this._windowVer.value = this._windowVer.value + 1;
4167
+ if (this.isWindowed()) {
3748
4168
  const afterFirstFrame = () => {
3749
- this.remeasureWindow();
3750
- if (!(this.gridScrollEl ? this.gridScrollEl.clientHeight : 0)) console.warn("[rozie-data-table] virtual is on but the scroll container has no bounded height; set maxHeight or --rozie-data-table-max-height");
3751
- const pg = this.pagination;
3752
- const pgConfigured = pg != null && !(pg.pageIndex === 0 && pg.pageSize === 10);
3753
- if (this.manual !== true && pgConfigured) console.warn("[rozie-data-table] virtual+pagination: client pagination is configured but virtual windowing replaces it — the pagination chrome is auto-suppressed. Remove the pagination prop or set manual to silence this.");
4169
+ if (this.rowsWindowed()) {
4170
+ this.remeasureWindow();
4171
+ if (!(this.gridScrollEl ? this.gridScrollEl.clientHeight : 0)) console.warn("[rozie-data-table] virtual is on but the scroll container has no bounded height; set maxHeight or --rozie-data-table-max-height");
4172
+ const pg = this.pagination;
4173
+ const pgConfigured = pg != null && !(pg.pageIndex === 0 && pg.pageSize === 10);
4174
+ if (this.manual !== true && pgConfigured) console.warn("[rozie-data-table] virtual+pagination: client pagination is configured but virtual windowing replaces it — the pagination chrome is auto-suppressed. Remove the pagination prop or set manual to silence this.");
4175
+ }
4176
+ if (this.colsWindowed()) {
4177
+ if (!(this.gridScrollEl ? this.gridScrollEl.clientWidth : 0)) console.warn("[rozie-data-table] virtual is on for columns but the scroll container has no bounded width; set a CSS width on an ancestor so the column window can be measured");
4178
+ }
3754
4179
  };
3755
4180
  if (typeof requestAnimationFrame === "function") requestAnimationFrame(() => requestAnimationFrame(afterFirstFrame));
3756
4181
  else setTimeout(afterFirstFrame, 0);
@@ -3835,10 +4260,11 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
3835
4260
  })()} @rozie-group-bar-apply-grouping=${($event) => this.applyGrouping($event.detail)} @rozie-group-bar-clear-grouping=${($event) => this.clearGrouping($event.detail)}>
3836
4261
  ${repeat(this.groupingKeys(), (gk, _idx) => gk, (gk, _idx) => html`<span class="rdt-group-token" data-group-token="" data-rozie-s-d5dcab4c>${rozieDisplay(gk)}</span>`)}
3837
4262
  </slot>`}
3838
- </div>` : nothing}${this.virtual ? html`<div class="rdt-scroll" style=${rozieStyle(this.maxHeight ? "max-height:" + this.maxHeight + ";overflow:auto;--rozie-data-table-max-height:" + this.maxHeight : "overflow:auto")} data-rozie-s-d5dcab4c>
4263
+ </div>` : nothing}${this.isWindowed() ? html`<div class="rdt-scroll" style=${rozieStyle(this.rowsWindowed() && this.maxHeight ? "max-height:" + this.maxHeight + ";overflow:auto;--rozie-data-table-max-height:" + this.maxHeight : "overflow:auto")} data-rozie-s-d5dcab4c>
3839
4264
  <table class="${Object.entries({
3840
4265
  "rozie-data-table": true,
3841
- "rdt-sticky": this.stickyHeader
4266
+ "rdt-sticky": this.stickyHeader,
4267
+ "rdt-col-windowed": this.colsWindowed()
3842
4268
  }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} @keydown=${($event) => {
3843
4269
  this.onGridKeyDown($event);
3844
4270
  }} @focusin=${($event) => {
@@ -3854,14 +4280,15 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
3854
4280
  }} data-rozie-s-d5dcab4c>
3855
4281
  <thead class="rdt-thead" role="rowgroup" data-rozie-s-d5dcab4c>
3856
4282
  ${repeat(this._headerGroups.value, (hg, hgLevel) => hg.id, (hg, hgLevel) => html`<tr class="rdt-tr" role="row" aria-rowindex=${rozieAttr(hgLevel + 1)} data-rozie-s-d5dcab4c>
3857
- ${repeat(hg.headers, (header, _idx) => header.id, (header, _idx) => html`<th class="${Object.entries({
4283
+
4284
+ ${this.colsWindowed() ? html`<th class="rdt-col-spacer" aria-hidden="true" style=${rozieStyle("width:" + this.colPadLeft() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></th>` : nothing}${repeat(this.windowedHeadersFor(hg, hgLevel), (wh, _idx) => wh.header.id, (wh, _idx) => html`<th class="${Object.entries({
3858
4285
  "rdt-th": true,
3859
- "rdt-select-th": this.isSelectColumn(header.column.id),
3860
- "rdt-expander-th": this.isExpanderColumn(header.column.id),
3861
- "rdt-th-resizing": this.columnIsResizing(header.column.id),
3862
- "rdt-cell-active": this.isActiveCell("__header", this.headerColIndexOf(hg, header), hgLevel)
3863
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role="columnheader" data-col=${rozieAttr(header.column.id)} data-grid-cell="" data-row="__header" data-header-level=${rozieAttr(hgLevel)} colspan=${rozieAttr(header.colSpan > 1 ? header.colSpan : null)} data-col-index=${rozieAttr(this.headerColIndexOf(hg, header))} tabindex=${rozieAttr(this.cellTabindex("__header", this.headerColIndexOf(hg, header), hgLevel))} aria-sort=${rozieAttr(this.ariaSortFor(header.column.id))} style=${rozieStyle(this.thStyle(header.column.id))} data-rozie-s-d5dcab4c>
3864
- ${this.isSelectColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4286
+ "rdt-select-th": this.isSelectColumn(wh.header.column.id),
4287
+ "rdt-expander-th": this.isExpanderColumn(wh.header.column.id),
4288
+ "rdt-th-resizing": this.columnIsResizing(wh.header.column.id),
4289
+ "rdt-cell-active": this.isActiveCell("__header", this.headerColIndexOf(hg, wh.header), hgLevel)
4290
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role="columnheader" data-col=${rozieAttr(wh.header.column.id)} data-grid-cell="" data-row="__header" data-header-level=${rozieAttr(hgLevel)} colspan=${rozieAttr(wh.span > 1 ? wh.span : null)} data-col-index=${rozieAttr(this.headerColIndexOf(hg, wh.header))} tabindex=${rozieAttr(this.cellTabindex("__header", this.headerColIndexOf(hg, wh.header), hgLevel))} aria-sort=${rozieAttr(this.ariaSortFor(wh.header.column.id))} style=${rozieStyle(this.thStyle(wh.header.column.id))} data-rozie-s-d5dcab4c>
4291
+ ${this.isSelectColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
3865
4292
  ${this.selectAll !== void 0 ? this.selectAll({
3866
4293
  checked: this.isAllRowsSelected(),
3867
4294
  indeterminate: this.isSomeRowsSelected(),
@@ -3879,102 +4306,103 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
3879
4306
  ${this.selectionMode === "multiple" ? html`<input class="rdt-select-all" type="checkbox" aria-label="Select all rows" ?checked=${this.isAllRowsSelected()} @change=${($event) => {
3880
4307
  this.onToggleAllRows($event);
3881
4308
  }} data-rozie-s-d5dcab4c />` : nothing}</slot>`}
3882
- </span>` : this.isExpanderColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : html`<span style="display:contents" data-rozie-s-d5dcab4c>
3883
- ${header.column.getCanSort && header.column.getCanSort() ? html`<button class="rdt-sort-btn" type="button" @click=${($event) => {
3884
- this.onHeaderSort(header.column.id, $event);
4309
+ </span>` : this.isExpanderColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : html`<span style="display:contents" data-rozie-s-d5dcab4c>
4310
+ ${wh.header.column.getCanSort && wh.header.column.getCanSort() ? html`<button class="rdt-sort-btn" type="button" @click=${($event) => {
4311
+ this.onHeaderSort(wh.header.column.id, $event);
3885
4312
  }} data-rozie-s-d5dcab4c>
3886
4313
  <span class="rdt-header-label" data-rozie-s-d5dcab4c>
3887
4314
  ${this.colHeader !== void 0 ? this.colHeader({
3888
- columnId: header.column.id,
3889
- column: header.column,
3890
- label: this.headerLabel(header.column.id)
4315
+ columnId: wh.header.column.id,
4316
+ column: wh.header.column,
4317
+ label: this.headerLabel(wh.header.column.id)
3891
4318
  }) : html`<slot name="colHeader" data-rozie-params=${(() => {
3892
4319
  try {
3893
4320
  return JSON.stringify({
3894
- columnId: header.column.id,
3895
- column: header.column,
3896
- label: this.headerLabel(header.column.id)
4321
+ columnId: wh.header.column.id,
4322
+ column: wh.header.column,
4323
+ label: this.headerLabel(wh.header.column.id)
3897
4324
  });
3898
4325
  } catch {
3899
4326
  return "{}";
3900
4327
  }
3901
- })()}>${rozieDisplay(this.headerLabel(header.column.id))}</slot>`}
4328
+ })()}>${rozieDisplay(this.headerLabel(wh.header.column.id))}</slot>`}
3902
4329
  </span>
3903
- <span class="rdt-sort-ind" aria-hidden="true" data-rozie-s-d5dcab4c>${rozieDisplay(this.sortIndicator(header.column.id))}</span>
4330
+ <span class="rdt-sort-ind" aria-hidden="true" data-rozie-s-d5dcab4c>${rozieDisplay(this.sortIndicator(wh.header.column.id))}</span>
3904
4331
  </button>` : html`<span style="display:contents" data-rozie-s-d5dcab4c>
3905
4332
  <span class="rdt-header-label" data-rozie-s-d5dcab4c>
3906
4333
  ${this.colHeader !== void 0 ? this.colHeader({
3907
- columnId: header.column.id,
3908
- column: header.column,
3909
- label: this.headerLabel(header.column.id)
4334
+ columnId: wh.header.column.id,
4335
+ column: wh.header.column,
4336
+ label: this.headerLabel(wh.header.column.id)
3910
4337
  }) : html`<slot name="colHeader" data-rozie-params=${(() => {
3911
4338
  try {
3912
4339
  return JSON.stringify({
3913
- columnId: header.column.id,
3914
- column: header.column,
3915
- label: this.headerLabel(header.column.id)
4340
+ columnId: wh.header.column.id,
4341
+ column: wh.header.column,
4342
+ label: this.headerLabel(wh.header.column.id)
3916
4343
  });
3917
4344
  } catch {
3918
4345
  return "{}";
3919
4346
  }
3920
- })()}>${rozieDisplay(this.headerLabel(header.column.id))}</slot>`}
4347
+ })()}>${rozieDisplay(this.headerLabel(wh.header.column.id))}</slot>`}
3921
4348
  </span>
3922
- </span>`}<rozie-popover trigger="click" placement="bottom-end" strategy="fixed" .offset=${4} data-rozie-s-d5dcab4c><button class="rdt-col-menu-trigger" type="button" aria-label=${rozieAttr("Column options for " + this.headerLabel(header.column.id))} data-rozie-s-d5dcab4c slot="anchor">⋯</button><div class="rdt-col-menu" role="menu" data-rozie-s-d5dcab4c>
3923
- <button class="rdt-col-menu-item" type="button" role="menuitem" aria-pressed=${this.columnPinSide(header.column.id) === "left"} @click=${($event) => {
3924
- this.onPinColumn(header.column.id, "left", $event);
4349
+ </span>`}<rozie-popover trigger="click" placement="bottom-end" strategy="fixed" .offset=${4} data-rozie-s-d5dcab4c><button class="rdt-col-menu-trigger" type="button" aria-label=${rozieAttr("Column options for " + this.headerLabel(wh.header.column.id))} data-rozie-s-d5dcab4c slot="anchor">⋯</button><div class="rdt-col-menu" role="menu" data-rozie-s-d5dcab4c>
4350
+ <button class="rdt-col-menu-item" type="button" role="menuitem" aria-pressed=${this.columnPinSide(wh.header.column.id) === "left"} @click=${($event) => {
4351
+ this.onPinColumn(wh.header.column.id, "left", $event);
3925
4352
  }} data-rozie-s-d5dcab4c>Pin left</button>
3926
- <button class="rdt-col-menu-item" type="button" role="menuitem" aria-pressed=${this.columnPinSide(header.column.id) === "right"} @click=${($event) => {
3927
- this.onPinColumn(header.column.id, "right", $event);
4353
+ <button class="rdt-col-menu-item" type="button" role="menuitem" aria-pressed=${this.columnPinSide(wh.header.column.id) === "right"} @click=${($event) => {
4354
+ this.onPinColumn(wh.header.column.id, "right", $event);
3928
4355
  }} data-rozie-s-d5dcab4c>Pin right</button>
3929
- <button class="rdt-col-menu-item" type="button" role="menuitem" aria-pressed=${!this.columnPinSide(header.column.id)} @click=${($event) => {
3930
- this.onPinColumn(header.column.id, false, $event);
4356
+ <button class="rdt-col-menu-item" type="button" role="menuitem" aria-pressed=${!this.columnPinSide(wh.header.column.id)} @click=${($event) => {
4357
+ this.onPinColumn(wh.header.column.id, false, $event);
3931
4358
  }} data-rozie-s-d5dcab4c>Unpin</button>
3932
4359
  <hr class="rdt-col-menu-sep" data-rozie-s-d5dcab4c />
3933
4360
  <button class="rdt-col-menu-item" type="button" role="menuitem" @click=${($event) => {
3934
- this.onHideColumn(header.column.id, $event);
4361
+ this.onHideColumn(wh.header.column.id, $event);
3935
4362
  }} data-rozie-s-d5dcab4c>Hide column</button>
3936
4363
  </div></rozie-popover>
3937
- <button class="rdt-resize-handle" type="button" aria-label=${rozieAttr("Resize " + this.headerLabel(header.column.id))} @pointerdown=${($event) => {
3938
- this.onResizeStart(header.column.id, $event);
4364
+ <button class="rdt-resize-handle" type="button" aria-label=${rozieAttr("Resize " + this.headerLabel(wh.header.column.id))} @pointerdown=${($event) => {
4365
+ this.onResizeStart(wh.header.column.id, $event);
3939
4366
  }} @touchstart=${($event) => {
3940
- this.onResizeStart(header.column.id, $event);
4367
+ this.onResizeStart(wh.header.column.id, $event);
3941
4368
  }} data-rozie-s-d5dcab4c><span class="rdt-resize-grip" aria-hidden="true" data-rozie-s-d5dcab4c></span></button>
3942
4369
  </span>`}</th>`)}
3943
- </tr>`)}
4370
+
4371
+ ${this.colsWindowed() ? html`<th class="rdt-col-spacer" aria-hidden="true" style=${rozieStyle("width:" + this.colPadRight() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></th>` : nothing}</tr>`)}
3944
4372
 
3945
4373
  ${this.hasAnyFilterableColumn() ? html`<tr class="rdt-filter-row" data-rozie-s-d5dcab4c>
3946
- ${repeat(this._headerGroups.value[this._headerGroups.value.length - 1].headers, (header, _idx) => header.id, (header, _idx) => html`<th class="rdt-filter-cell" role="presentation" style=${rozieStyle(this.pinStyle(header.column.id))} data-rozie-s-d5dcab4c>
3947
- ${this.isSelectColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : this.isExpanderColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : html`<span style="display:contents" data-rozie-s-d5dcab4c>
3948
- ${this.columnIsFilterable(header.column.id) && !this.hasFilterSlot() ? html`<input class="rdt-col-filter" type="text" aria-label=${rozieAttr("Filter " + this.headerLabel(header.column.id))} .value=${this.columnFilterValue(header.column.id)} @input=${($event) => {
3949
- this.onColumnFilterInput(header.column.id, $event);
4374
+ ${this.colsWindowed() ? html`<th class="rdt-col-spacer" aria-hidden="true" style=${rozieStyle("width:" + this.colPadLeft() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></th>` : nothing}${repeat(this.windowedHeadersFor(this._headerGroups.value[this._headerGroups.value.length - 1], this._headerGroups.value.length - 1), (wh, _idx) => wh.header.id, (wh, _idx) => html`<th class="rdt-filter-cell" role="presentation" data-col=${rozieAttr(wh.header.column.id)} style=${rozieStyle(this.pinStyle(wh.header.column.id))} data-rozie-s-d5dcab4c>
4375
+ ${this.isSelectColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : this.isExpanderColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : html`<span style="display:contents" data-rozie-s-d5dcab4c>
4376
+ ${this.columnIsFilterable(wh.header.column.id) && !this.hasFilterSlot() ? html`<input class="rdt-col-filter" type="text" aria-label=${rozieAttr("Filter " + this.headerLabel(wh.header.column.id))} .value=${this.columnFilterValue(wh.header.column.id)} @input=${($event) => {
4377
+ this.onColumnFilterInput(wh.header.column.id, $event);
3950
4378
  }} @click=${($event) => {
3951
4379
  this.stopEvent($event);
3952
- }} data-rozie-s-d5dcab4c />` : nothing}${this.columnIsFilterable(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4380
+ }} data-rozie-s-d5dcab4c />` : nothing}${this.columnIsFilterable(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
3953
4381
  ${this.filter !== void 0 ? this.filter({
3954
- columnId: header.column.id,
3955
- value: this.columnFilterValue(header.column.id),
3956
- uniqueValues: this.getFacetedUniqueValues(header.column.id),
3957
- minMax: this.getFacetedMinMaxValues(header.column.id),
4382
+ columnId: wh.header.column.id,
4383
+ value: this.columnFilterValue(wh.header.column.id),
4384
+ uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4385
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
3958
4386
  setFilter: this.setColumnFilter
3959
4387
  }) : html`<slot name="filter" data-rozie-params=${(() => {
3960
4388
  try {
3961
4389
  return JSON.stringify({
3962
- columnId: header.column.id,
3963
- value: this.columnFilterValue(header.column.id),
3964
- uniqueValues: this.getFacetedUniqueValues(header.column.id),
3965
- minMax: this.getFacetedMinMaxValues(header.column.id)
4390
+ columnId: wh.header.column.id,
4391
+ value: this.columnFilterValue(wh.header.column.id),
4392
+ uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4393
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id)
3966
4394
  });
3967
4395
  } catch {
3968
4396
  return "{}";
3969
4397
  }
3970
4398
  })()} @rozie-filter-set-filter=${($event) => this.setColumnFilter($event.detail)}></slot>`}
3971
4399
  </span>` : nothing}</span>`}</th>`)}
3972
- </tr>` : nothing}</thead>
4400
+ ${this.colsWindowed() ? html`<th class="rdt-col-spacer" aria-hidden="true" style=${rozieStyle("width:" + this.colPadRight() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></th>` : nothing}</tr>` : nothing}</thead>
3973
4401
 
3974
4402
  <tbody class="rdt-tbody" role="rowgroup" data-rozie-s-d5dcab4c>
3975
4403
 
3976
4404
  <tr class="rdt-spacer" aria-hidden="true" data-rozie-s-d5dcab4c>
3977
- <td colspan=${rozieAttr(this.visibleColCount())} style=${rozieStyle("height:" + this.padTop() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></td>
4405
+ <td colspan=${rozieAttr(this.windowedColSpan())} style=${rozieStyle("height:" + this.padTop() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></td>
3978
4406
  </tr>
3979
4407
 
3980
4408
  ${repeat(this.windowedRows(), (wr, _idx) => wr.row.id, (wr, _idx) => html`
@@ -3983,7 +4411,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
3983
4411
  "rdt-group-header": this.rowIsGrouped(wr.row),
3984
4412
  "rdt-row-pinned": wr.pinned
3985
4413
  }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role="row" data-row=${rozieAttr(wr.vi.index)} aria-rowindex=${rozieAttr(this.headerRowCount() + wr.vi.index + 1)} data-index=${rozieAttr(wr.vi.index)} data-pinned=${rozieAttr(wr.pinned ? "true" : null)} data-depth=${rozieAttr(wr.row.depth)} data-group-header=${rozieAttr(this.rowIsGrouped(wr.row) ? wr.row.id : null)} data-group-leaf=${rozieAttr(this.groupingActive() && !this.rowIsGrouped(wr.row) ? wr.row.id : null)} aria-expanded=${rozieAttr(this.rowIsGrouped(wr.row) ? !!this.rowIsExpanded(wr.row) : null)} aria-selected=${rozieAttr(this.selectionMode !== "none" ? !!this.rowIsSelected(wr.row) : null)} aria-level=${rozieAttr(this.groupingActive() ? wr.row.depth + 1 : null)} data-rozie-s-d5dcab4c>
3986
- ${repeat(this.visibleCellsFor(wr.row), (cell, _idx) => cell.id, (cell, _idx) => html`<td class="${Object.entries({
4414
+
4415
+ ${this.colsWindowed() ? html`<td class="rdt-col-spacer" aria-hidden="true" style=${rozieStyle("width:" + this.colPadLeft() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></td>` : nothing}${repeat(this.windowedCells(wr.row), (cell, _idx) => cell.id, (cell, _idx) => html`<td class="${Object.entries({
3987
4416
  "rdt-td": true,
3988
4417
  "rdt-select-td": this.isSelectColumn(cell.column.id),
3989
4418
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
@@ -3996,13 +4425,13 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
3996
4425
  this.onToggleExpand(wr.row, $event);
3997
4426
  }} data-rozie-s-d5dcab4c>${rozieDisplay(this.rowIsExpanded(wr.row) ? "▾" : "▸")}</button>` : nothing}</span>` : this.isSelectColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
3998
4427
  ${this.selectCell !== void 0 ? this.selectCell({
3999
- row: wr.row.original,
4428
+ row: this.cellSlotRow(wr.row),
4000
4429
  checked: this.rowIsSelected(wr.row),
4001
4430
  toggle: (e) => this.onToggleRow(wr.row, e)
4002
4431
  }) : html`<slot name="selectCell" data-rozie-params=${(() => {
4003
4432
  try {
4004
4433
  return JSON.stringify({
4005
- row: wr.row.original,
4434
+ row: this.cellSlotRow(wr.row),
4006
4435
  checked: this.rowIsSelected(wr.row)
4007
4436
  });
4008
4437
  } catch {
@@ -4021,14 +4450,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4021
4450
  ${this.cell !== void 0 ? this.cell({
4022
4451
  columnId: cell.column.id,
4023
4452
  column: cell.column,
4024
- row: wr.row.original,
4453
+ row: this.cellSlotRow(wr.row),
4025
4454
  value: cell.getValue()
4026
4455
  }) : html`<slot name="cell" data-rozie-params=${(() => {
4027
4456
  try {
4028
4457
  return JSON.stringify({
4029
4458
  columnId: cell.column.id,
4030
4459
  column: cell.column,
4031
- row: wr.row.original,
4460
+ row: this.cellSlotRow(wr.row),
4032
4461
  value: cell.getValue()
4033
4462
  });
4034
4463
  } catch {
@@ -4042,7 +4471,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4042
4471
  ${this.editor !== void 0 ? this.editor({
4043
4472
  columnId: cell.column.id,
4044
4473
  column: cell.column,
4045
- row: wr.row.original,
4474
+ row: this.cellSlotRow(wr.row),
4046
4475
  value: this.editorValueFor(cell.column.id),
4047
4476
  commit: this.editorCommitFor(cell.column.id),
4048
4477
  cancel: this.editorCancelFor(),
@@ -4052,7 +4481,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4052
4481
  return JSON.stringify({
4053
4482
  columnId: cell.column.id,
4054
4483
  column: cell.column,
4055
- row: wr.row.original,
4484
+ row: this.cellSlotRow(wr.row),
4056
4485
  value: this.editorValueFor(cell.column.id),
4057
4486
  commit: this.editorCommitFor(cell.column.id),
4058
4487
  cancel: this.editorCancelFor(),
@@ -4092,14 +4521,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4092
4521
  ${this.cell !== void 0 ? this.cell({
4093
4522
  columnId: cell.column.id,
4094
4523
  column: cell.column,
4095
- row: wr.row.original,
4524
+ row: this.cellSlotRow(wr.row),
4096
4525
  value: cell.getValue()
4097
4526
  }) : html`<slot name="cell" data-rozie-params=${(() => {
4098
4527
  try {
4099
4528
  return JSON.stringify({
4100
4529
  columnId: cell.column.id,
4101
4530
  column: cell.column,
4102
- row: wr.row.original,
4531
+ row: this.cellSlotRow(wr.row),
4103
4532
  value: cell.getValue()
4104
4533
  });
4105
4534
  } catch {
@@ -4109,10 +4538,11 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4109
4538
  </span>`}${this.isFillHandleCell(wr.vi.index, this.colIndexOf(wr.row, cell)) ? html`<span class="rdt-fill-handle" data-fill-handle="" data-testid="fill-handle" aria-hidden="true" @pointerdown=${($event) => {
4110
4539
  this.onFillHandlePointerDown($event);
4111
4540
  }} data-rozie-s-d5dcab4c></span>` : nothing}</td>`)}
4112
- </tr>
4541
+
4542
+ ${this.colsWindowed() ? html`<td class="rdt-col-spacer" aria-hidden="true" style=${rozieStyle("width:" + this.colPadRight() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></td>` : nothing}</tr>
4113
4543
 
4114
4544
  ${this.rowShowsDetail(wr.row) ? html`<tr class="rdt-detail-row" role="row" data-detail-row=${rozieAttr(wr.row.id)} data-rozie-s-d5dcab4c>
4115
- <td class="rdt-detail-cell" colspan=${rozieAttr(this.visibleColCount())} data-rozie-s-d5dcab4c>
4545
+ <td class="rdt-detail-cell" colspan=${rozieAttr(this.windowedColSpan())} data-rozie-s-d5dcab4c>
4116
4546
  ${this.detail !== void 0 ? this.detail({ row: wr.row.original }) : html`<slot name="detail" data-rozie-params=${(() => {
4117
4547
  try {
4118
4548
  return JSON.stringify({ row: wr.row.original });
@@ -4124,7 +4554,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4124
4554
  </tr>` : nothing}`)}
4125
4555
 
4126
4556
  <tr class="rdt-spacer" aria-hidden="true" data-rozie-s-d5dcab4c>
4127
- <td colspan=${rozieAttr(this.visibleColCount())} style=${rozieStyle("height:" + this.padBottom() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></td>
4557
+ <td colspan=${rozieAttr(this.windowedColSpan())} style=${rozieStyle("height:" + this.padBottom() + "px;padding:0;border:0")} data-rozie-s-d5dcab4c></td>
4128
4558
  </tr>
4129
4559
  </tbody>
4130
4560
  </table>
@@ -4289,13 +4719,13 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4289
4719
  this.onToggleExpand(row, $event);
4290
4720
  }} data-rozie-s-d5dcab4c>${rozieDisplay(this.rowIsExpanded(row) ? "▾" : "▸")}</button>` : nothing}</span>` : this.isSelectColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4291
4721
  ${this.selectCell !== void 0 ? this.selectCell({
4292
- row: row.original,
4722
+ row: this.cellSlotRow(row),
4293
4723
  checked: this.rowIsSelected(row),
4294
4724
  toggle: (e) => this.onToggleRow(row, e)
4295
4725
  }) : html`<slot name="selectCell" data-rozie-params=${(() => {
4296
4726
  try {
4297
4727
  return JSON.stringify({
4298
- row: row.original,
4728
+ row: this.cellSlotRow(row),
4299
4729
  checked: this.rowIsSelected(row)
4300
4730
  });
4301
4731
  } catch {
@@ -4314,14 +4744,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4314
4744
  ${this.cell !== void 0 ? this.cell({
4315
4745
  columnId: cell.column.id,
4316
4746
  column: cell.column,
4317
- row: row.original,
4747
+ row: this.cellSlotRow(row),
4318
4748
  value: cell.getValue()
4319
4749
  }) : html`<slot name="cell" data-rozie-params=${(() => {
4320
4750
  try {
4321
4751
  return JSON.stringify({
4322
4752
  columnId: cell.column.id,
4323
4753
  column: cell.column,
4324
- row: row.original,
4754
+ row: this.cellSlotRow(row),
4325
4755
  value: cell.getValue()
4326
4756
  });
4327
4757
  } catch {
@@ -4335,7 +4765,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4335
4765
  ${this.editor !== void 0 ? this.editor({
4336
4766
  columnId: cell.column.id,
4337
4767
  column: cell.column,
4338
- row: row.original,
4768
+ row: this.cellSlotRow(row),
4339
4769
  value: this.editorValueFor(cell.column.id),
4340
4770
  commit: this.editorCommitFor(cell.column.id),
4341
4771
  cancel: this.editorCancelFor(),
@@ -4345,7 +4775,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4345
4775
  return JSON.stringify({
4346
4776
  columnId: cell.column.id,
4347
4777
  column: cell.column,
4348
- row: row.original,
4778
+ row: this.cellSlotRow(row),
4349
4779
  value: this.editorValueFor(cell.column.id),
4350
4780
  commit: this.editorCommitFor(cell.column.id),
4351
4781
  cancel: this.editorCancelFor(),
@@ -4385,14 +4815,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4385
4815
  ${this.cell !== void 0 ? this.cell({
4386
4816
  columnId: cell.column.id,
4387
4817
  column: cell.column,
4388
- row: row.original,
4818
+ row: this.cellSlotRow(row),
4389
4819
  value: cell.getValue()
4390
4820
  }) : html`<slot name="cell" data-rozie-params=${(() => {
4391
4821
  try {
4392
4822
  return JSON.stringify({
4393
4823
  columnId: cell.column.id,
4394
4824
  column: cell.column,
4395
- row: row.original,
4825
+ row: this.cellSlotRow(row),
4396
4826
  value: cell.getValue()
4397
4827
  });
4398
4828
  } catch {
@@ -4416,7 +4846,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4416
4846
  </td>
4417
4847
  </tr>` : nothing}`)}
4418
4848
  </tbody>
4419
- </table>`}${!this.virtual ? html`<div class="rdt-pagination" role="group" aria-label="Pagination" data-rozie-s-d5dcab4c>
4849
+ </table>`}${!this.rowsWindowed() ? html`<div class="rdt-pagination" role="group" aria-label="Pagination" data-rozie-s-d5dcab4c>
4420
4850
  <button class="rdt-page-btn rdt-page-prev" type="button" ?disabled=${!this.canPrevPage()} @click=${($event) => {
4421
4851
  this.onPrevPage();
4422
4852
  }} data-rozie-s-d5dcab4c>Prev</button>
@@ -4604,14 +5034,15 @@ __decorate([property({
4604
5034
  type: Number,
4605
5035
  reflect: true
4606
5036
  })], DataTable.prototype, "undoLimit", void 0);
4607
- __decorate([property({
4608
- type: Boolean,
4609
- reflect: true
4610
- })], DataTable.prototype, "virtual", void 0);
5037
+ __decorate([property({ converter: { fromAttribute: (v) => v === null ? false : v === "true" ? true : v === "false" ? false : v === "" ? true : v } })], DataTable.prototype, "virtual", void 0);
4611
5038
  __decorate([property({
4612
5039
  type: Number,
4613
5040
  reflect: true
4614
5041
  })], DataTable.prototype, "estimateRowHeight", void 0);
5042
+ __decorate([property({
5043
+ type: Boolean,
5044
+ reflect: true
5045
+ })], DataTable.prototype, "autoMeasure", void 0);
4615
5046
  __decorate([property({
4616
5047
  type: String,
4617
5048
  reflect: true