@rozie-ui/data-table-lit 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -53,6 +53,48 @@ const collectGroupableLeafDefs = (defs) => {
53
53
  }
54
54
  return out;
55
55
  };
56
+ const EDITOR_KINDS = [
57
+ "text",
58
+ "number",
59
+ "select",
60
+ "checkbox",
61
+ "custom"
62
+ ];
63
+ const editorKindWarning = (id, editor) => {
64
+ if (editor == null) return null;
65
+ if (typeof editor === "string" && EDITOR_KINDS.indexOf(editor) !== -1) return null;
66
+ return "[rozie-data-table] column \"" + String(id) + "\": editor=\"" + String(editor) + "\" is not a built-in editor. The built-ins are text | number | select | checkbox; anything else needs editor=\"custom\" plus an #editor slot fill (that is how <EditorDate> is used). Falling back to the text input.";
67
+ };
68
+ const columnSpecsEquivalent = (a, b, depth) => {
69
+ const d = typeof depth === "number" ? depth : 0;
70
+ if (a === b) return true;
71
+ if (d > 4) return false;
72
+ const ta = typeof a;
73
+ if (ta !== typeof b) return false;
74
+ if (ta === "function") try {
75
+ return String(a) === String(b);
76
+ } catch (err) {
77
+ return false;
78
+ }
79
+ if (ta === "number") return a !== a && b !== b;
80
+ if (a === null || b === null || ta !== "object") return false;
81
+ const aArr = Array.isArray(a);
82
+ if (aArr !== Array.isArray(b)) return false;
83
+ if (aArr) {
84
+ if (a.length !== b.length) return false;
85
+ for (let i = 0; i < a.length; i++) if (!columnSpecsEquivalent(a[i], b[i], d + 1)) return false;
86
+ return true;
87
+ }
88
+ const ka = Object.keys(a);
89
+ const kb = Object.keys(b);
90
+ if (ka.length !== kb.length) return false;
91
+ for (let i = 0; i < ka.length; i++) {
92
+ const k = ka[i];
93
+ if (!Object.prototype.hasOwnProperty.call(b, k)) return false;
94
+ if (!columnSpecsEquivalent(a[k], b[k], d + 1)) return false;
95
+ }
96
+ return true;
97
+ };
56
98
  //#endregion
57
99
  //#region src/helpers/indexMath.ts
58
100
  const clamp = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
@@ -263,6 +305,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
263
305
  defaultValue: null,
264
306
  initialControlledValue: void 0
265
307
  });
308
+ this.getRowId = null;
266
309
  this.getSubRows = null;
267
310
  this.groupable = false;
268
311
  this._grouping_attr = null;
@@ -369,9 +412,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
369
412
  this._rangeAnchor = signal(null);
370
413
  this._rangeFocus = signal(null);
371
414
  this._pasteAnnounce = signal("");
415
+ this._rangeAnnounce = signal("");
372
416
  this._liveAnnounce = signal("");
373
417
  this.__rozieWatchInitial_0 = true;
374
418
  this.__rozieWatchInitial_1 = true;
419
+ this.__rozieWatchInitial_2 = true;
375
420
  this.__rozieCtxProvider_data_table_columns = new ContextProvider(this, {
376
421
  context: __rozieCtx_data_table_columns$1,
377
422
  initialValue: ((__rozieCtxHost) => ({
@@ -379,6 +424,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
379
424
  if (id == null) return;
380
425
  const key = String(id);
381
426
  if (key === "__proto__" || key === "constructor" || key === "prototype") return;
427
+ const prev = __rozieCtxHost._colReg.value ? __rozieCtxHost._colReg.value[key] : void 0;
428
+ if (prev !== void 0 && columnSpecsEquivalent(prev, spec)) return;
382
429
  __rozieCtxHost._colReg.value = {
383
430
  ...__rozieCtxHost._colReg.value,
384
431
  [key]: spec
@@ -398,6 +445,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
398
445
  this._hasSlotSelectAll = false;
399
446
  this._hasSlotDynamicColHeader = false;
400
447
  this._hasSlotDynamicFilter = false;
448
+ this._hasSlotPlaceholder = false;
401
449
  this._hasSlotSelectCell = false;
402
450
  this._hasSlotDynamicCell = false;
403
451
  this._hasSlotDynamicEditor = false;
@@ -417,8 +465,13 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
417
465
  this.remeasurePending = false;
418
466
  this.remeasureRaf = null;
419
467
  this.remeasureDisposed = false;
468
+ this.scrollEndPinned = false;
469
+ this.scrollEndPinnedCount = -1;
470
+ this.scrollEndPinnedTop = -1;
420
471
  this.GRID_PAGE_STEP = 10;
421
472
  this.gridRoot = null;
473
+ this.outsidePointerDown = false;
474
+ this.docPointerDown = null;
422
475
  this.programmatic = 0;
423
476
  this.focusIntentEpoch = 0;
424
477
  this.DATA_WRITE_TOKEN_KEY = "__rozieDataWriteToken";
@@ -482,6 +535,26 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
482
535
  columnSizingInfo: this._columnSizingInfo.value
483
536
  });
484
537
  this.currentData = () => this.data != null ? this.data : this._dataDefault.value;
538
+ this.parseWidthToSize = (w) => {
539
+ if (typeof w === "number") return Number.isFinite(w) && w > 0 ? w : null;
540
+ if (typeof w !== "string") return null;
541
+ const t = w.trim();
542
+ if (t === "") return null;
543
+ const m = /^(\d+(?:\.\d+)?)(px)?$/i.exec(t);
544
+ if (!m) return null;
545
+ const n = Number.parseFloat(m[1]);
546
+ return Number.isFinite(n) && n > 0 ? n : null;
547
+ };
548
+ this.editorWarned = Object.create(null);
549
+ this.checkEditorKind = (id, editor) => {
550
+ const msg = editorKindWarning(id, editor);
551
+ if (!msg) return editor;
552
+ const key = id + "\0" + String(editor);
553
+ if (this.editorWarned[key]) return editor;
554
+ this.editorWarned[key] = true;
555
+ console.warn(msg);
556
+ return editor;
557
+ };
485
558
  this.buildConfigDef = (c) => {
486
559
  if (!c) return null;
487
560
  if (Array.isArray(c.columns)) {
@@ -518,9 +591,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
518
591
  aggregationFn: wrapAggregationFn(c.aggregationFn),
519
592
  pinned: c.pinned != null ? c.pinned : "",
520
593
  width: c.width != null ? c.width : "",
594
+ ...this.parseWidthToSize(c.width) != null ? { size: this.parseWidthToSize(c.width) } : {},
521
595
  meta: {
522
596
  editable: c.editable === true,
523
- editor: c.editor != null ? c.editor : "text",
597
+ editor: c.editor != null ? this.checkEditorKind(id, c.editor) : "text",
524
598
  editorOptions: c.editorOptions != null ? c.editorOptions : [],
525
599
  validate: typeof c.validate === "function" ? c.validate : null
526
600
  }
@@ -560,9 +634,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
560
634
  aggregationFn: wrapAggregationFn(spec.aggregationFn),
561
635
  pinned: spec.pinned != null ? spec.pinned : "",
562
636
  width: spec.width != null ? spec.width : "",
637
+ ...this.parseWidthToSize(spec.width) != null ? { size: this.parseWidthToSize(spec.width) } : {},
563
638
  meta: {
564
639
  editable: spec.editable === true,
565
- editor: spec.editor != null ? spec.editor : "text",
640
+ editor: spec.editor != null ? this.checkEditorKind(id, spec.editor) : "text",
566
641
  editorOptions: spec.editorOptions != null ? spec.editorOptions : [],
567
642
  validate: typeof spec.validate === "function" ? spec.validate : null
568
643
  }
@@ -906,7 +981,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
906
981
  if (c && c.getIsPinned && c.getIsPinned()) out.push(i);
907
982
  }
908
983
  }
909
- if (!this._activeIsHeader.value && this._activeColIndex.value >= 0 && out.indexOf(this._activeColIndex.value) === -1) out.push(this._activeColIndex.value);
984
+ if (this._activeColIndex.value >= 0 && out.indexOf(this._activeColIndex.value) === -1) out.push(this._activeColIndex.value);
910
985
  if (this._editingRow.value >= 0 && this._editingCol.value >= 0 && out.indexOf(this._editingCol.value) === -1) out.push(this._editingCol.value);
911
986
  return out;
912
987
  };
@@ -927,18 +1002,37 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
927
1002
  if (this.rowsWindowed()) return this.table.getPrePaginationRowModel().rows;
928
1003
  return this.table.getRowModel().rows;
929
1004
  };
1005
+ this.REMEASURE_MAX_FRAMES = 10;
930
1006
  this.scheduleRemeasure = () => {
931
1007
  if (this.remeasureDisposed) return;
1008
+ if (this.virtualizer && this.gridScrollEl && !this.virtualizer.scrollState && this.gridScrollEl.scrollTop !== this.scrollEndPinnedTop) {
1009
+ this.scrollEndPinnedTop = this.gridScrollEl.scrollTop;
1010
+ this.scrollEndPinned = this.virtualizer.getVirtualDistanceFromEnd() <= 1;
1011
+ this.scrollEndPinnedCount = this.windowSource().length;
1012
+ }
932
1013
  if (this.remeasurePending) return;
933
1014
  this.remeasurePending = true;
934
1015
  let ranMicro = false;
935
1016
  const microPass = () => {
936
1017
  this.remeasureWindow();
937
1018
  };
1019
+ let rafAttempts = 0;
938
1020
  const rafPass = () => {
939
1021
  this.remeasureRaf = null;
1022
+ const covered = this.remeasureWindow();
1023
+ rafAttempts = rafAttempts + 1;
1024
+ if (!covered && rafAttempts < this.REMEASURE_MAX_FRAMES && !this.remeasureDisposed && typeof requestAnimationFrame === "function") {
1025
+ this.remeasureRaf = requestAnimationFrame(rafPass);
1026
+ return;
1027
+ }
1028
+ if (this.scrollEndPinned && this.gridScrollEl && !this.remeasureDisposed && this.windowSource().length === this.scrollEndPinnedCount) {
1029
+ const maxTop = this.gridScrollEl.scrollHeight - this.gridScrollEl.clientHeight;
1030
+ if (maxTop - this.gridScrollEl.scrollTop > 1) {
1031
+ this.gridScrollEl.scrollTop = maxTop;
1032
+ this.scrollEndPinnedTop = this.gridScrollEl.scrollTop;
1033
+ }
1034
+ }
940
1035
  this.remeasurePending = false;
941
- this.remeasureWindow();
942
1036
  };
943
1037
  if (typeof queueMicrotask !== "undefined") {
944
1038
  ranMicro = true;
@@ -960,6 +1054,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
960
1054
  this.pinnedEditIndex = () => {
961
1055
  if (this._editingRow.value >= 0) return this._editingRow.value;
962
1056
  if (this._editingRowIndex.value != null) return this._editingRowIndex.value;
1057
+ if (this.interactionMode === "grid" && !this._activeIsHeader.value && this._activeRow.value >= 0) return this._activeRow.value;
963
1058
  return -1;
964
1059
  };
965
1060
  this.pinnedMeasurement = (pin) => {
@@ -968,13 +1063,90 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
968
1063
  return ms && ms[pin] ? ms[pin] : null;
969
1064
  };
970
1065
  this.remeasureWindow = () => {
971
- if (this.remeasureDisposed) return;
972
- if (!this.virtualizer || !this.gridRoot) return;
973
- if (this.virtualizer.scrollState) return;
1066
+ if (this.remeasureDisposed) return true;
1067
+ if (!this.virtualizer || !this.gridRoot) return true;
1068
+ if (this.virtualizer.scrollState) return true;
974
1069
  const trs = this.gridRoot.querySelectorAll("tbody.rdt-tbody > tr[data-index]");
975
- for (const tr of trs) this.virtualizer.measureElement(tr);
1070
+ const rendered = /* @__PURE__ */ new Set();
1071
+ for (const tr of trs) {
1072
+ this.virtualizer.measureElement(tr);
1073
+ rendered.add(tr.getAttribute("data-index"));
1074
+ }
1075
+ let covered = true;
1076
+ const items = this.virtualizer.getVirtualItems();
1077
+ for (let i = 0; i < items.length; i++) if (!rendered.has(String(items[i].index))) {
1078
+ covered = false;
1079
+ break;
1080
+ }
976
1081
  if (this.afterRowRemeasure) this.afterRowRemeasure();
1082
+ return covered;
1083
+ };
1084
+ this.LAZY_PLACEHOLDER_KEY = "__rdtLazyPlaceholder";
1085
+ this.LAZY_PLACEHOLDER_ROW_ID_PREFIX = "__rdt_ph_";
1086
+ this.lazyPlaceholders = {};
1087
+ this.lazyRowsActive = () => this.rowsWindowed() && !!this.manual && this.rowCount != null && this.rowCount > 0;
1088
+ this.isLazyPlaceholder = (orig) => !!orig && orig[this.LAZY_PLACEHOLDER_KEY] === true;
1089
+ this.rowIsLazyPlaceholder = (row) => !!row && this.isLazyPlaceholder(row.original);
1090
+ this.feedData = () => {
1091
+ const d = this.currentData() || [];
1092
+ if (!this.lazyRowsActive()) return d;
1093
+ const n = Math.max(d.length, Number(this.rowCount));
1094
+ const out = new Array(n);
1095
+ for (let i = 0; i < n; i++) {
1096
+ const v = d[i];
1097
+ if (v != null) out[i] = v;
1098
+ else {
1099
+ if (!this.lazyPlaceholders[i]) this.lazyPlaceholders[i] = {
1100
+ [this.LAZY_PLACEHOLDER_KEY]: true,
1101
+ index: i
1102
+ };
1103
+ out[i] = this.lazyPlaceholders[i];
1104
+ }
1105
+ }
1106
+ return out;
1107
+ };
1108
+ this.migratePlaceholderSizeCache = () => {
1109
+ if (!this.virtualizer || !this.virtualizer.itemSizeCache || !this.table) return;
1110
+ const cache = this.virtualizer.itemSizeCache;
1111
+ const coreRows = this.table.getCoreRowModel().rows;
1112
+ let migrated = false;
1113
+ for (const oldKey of Array.from(cache.keys())) {
1114
+ if (typeof oldKey !== "string" || oldKey.indexOf(this.LAZY_PLACEHOLDER_ROW_ID_PREFIX) !== 0) continue;
1115
+ const row = coreRows[Number(oldKey.slice(this.LAZY_PLACEHOLDER_ROW_ID_PREFIX.length))];
1116
+ if (!row || this.rowIsLazyPlaceholder(row) || row.id === oldKey) continue;
1117
+ cache.set(row.id, cache.get(oldKey));
1118
+ cache.delete(oldKey);
1119
+ migrated = true;
1120
+ }
1121
+ if (!migrated) return;
1122
+ this.virtualizer.itemSizeCache = new Map(cache);
1123
+ if (typeof this.virtualizer.itemSizeCacheVersion === "number") this.virtualizer.itemSizeCacheVersion++;
1124
+ };
1125
+ this.lastRangeStart = -1;
1126
+ this.lastRangeEnd = -1;
1127
+ this.emitVisibleRangeIfChanged = () => {
1128
+ if (!this.rowsWindowed() || !this.virtualizer) return;
1129
+ const items = this.virtualizer.getVirtualItems();
1130
+ if (!items.length) return;
1131
+ const start = items[0].index;
1132
+ const end = items[items.length - 1].index + 1;
1133
+ if (start === this.lastRangeStart && end === this.lastRangeEnd) return;
1134
+ this.lastRangeStart = start;
1135
+ this.lastRangeEnd = end;
1136
+ this.dispatchEvent(new CustomEvent("visible-range-change", {
1137
+ detail: {
1138
+ start,
1139
+ end
1140
+ },
1141
+ bubbles: true,
1142
+ composed: true
1143
+ }));
977
1144
  };
1145
+ this.scrollToRow = (index, options) => {
1146
+ if (!this.rowsWindowed() || !this.virtualizer) return;
1147
+ this.virtualizer.scrollToIndex(Math.trunc(Number(index)) || 0, options || void 0);
1148
+ };
1149
+ this.getScrollElement = () => this.gridScrollEl;
978
1150
  this.virtualItemKey = (i) => {
979
1151
  const src = this.windowSource();
980
1152
  return src && src[i] ? src[i].id : void 0;
@@ -1080,6 +1252,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1080
1252
  }
1081
1253
  }
1082
1254
  this.bumpWindowVer();
1255
+ this.scheduleRemeasure();
1083
1256
  };
1084
1257
  this.virtualizerOptions = () => ({
1085
1258
  count: this.windowSource().length,
@@ -1252,20 +1425,29 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1252
1425
  if (filterChanged) return this.totalRowCount() + " results";
1253
1426
  return "";
1254
1427
  };
1428
+ this.rowIdOption = () => {
1429
+ const f = this.getRowId;
1430
+ return f ? (originalRow, index, parent) => this.isLazyPlaceholder(originalRow) ? this.LAZY_PLACEHOLDER_ROW_ID_PREFIX + originalRow.index : String(f(originalRow, index, parent)) : void 0;
1431
+ };
1432
+ this.rowSelectionOption = () => {
1433
+ if (this.selectionMode === "none") return false;
1434
+ return this.lazyRowsActive() ? (row) => !this.rowIsLazyPlaceholder(row) : true;
1435
+ };
1255
1436
  this.reFeed = () => {
1256
1437
  if (!this.table) return;
1257
1438
  this.table.setOptions((prev) => ({
1258
1439
  ...prev,
1259
- data: this.currentData(),
1440
+ data: this.feedData(),
1260
1441
  columns: this.tableColumns(),
1261
1442
  state: this.currentState(),
1262
- enableRowSelection: this.selectionMode !== "none",
1443
+ enableRowSelection: this.rowSelectionOption(),
1263
1444
  enableMultiRowSelection: this.selectionMode === "multiple",
1264
1445
  rowCount: this.rowCount ?? void 0,
1265
1446
  pageCount: this.pageCount ?? void 0,
1266
1447
  getExpandedRowModel: getExpandedRowModel(),
1267
1448
  getSubRows: this.getSubRows || void 0,
1268
- getRowCanExpand: this.expandable === true && this.getSubRows == null ? () => true : void 0,
1449
+ getRowId: this.rowIdOption(),
1450
+ getRowCanExpand: this.expandable === true && this.getSubRows == null ? (row) => !this.rowIsLazyPlaceholder(row) : void 0,
1269
1451
  onExpandedChange: this.onExpandedChangeCb,
1270
1452
  autoResetExpanded: false,
1271
1453
  getGroupedRowModel: getGroupedRowModel(),
@@ -1424,9 +1606,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1424
1606
  if (side === "right") return "position:sticky;right:" + (col.getAfter ? col.getAfter("right") : 0) + "px;z-index:" + zIndex + ";";
1425
1607
  return "";
1426
1608
  };
1427
- this.thStyle = (header) => {
1609
+ this.thStyle = (header, widthPx = null) => {
1428
1610
  let s = "";
1429
- const w = this.headerWidth(header);
1611
+ const w = widthPx != null && widthPx > 0 ? widthPx + "px" : this.headerWidth(header);
1430
1612
  if (w) s += "width:" + w + ";";
1431
1613
  s += this.pinStyle(header && header.column ? header.column.id : null, 2);
1432
1614
  return s;
@@ -1638,6 +1820,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1638
1820
  this.rowIndexOf = (row) => this.tick() >= 0 ? (this._rows.value || []).indexOf(row) : -1;
1639
1821
  this.colIndexOf = (row, cellCtx) => this.tick() >= 0 ? this.visibleCellsFor(row).indexOf(cellCtx) : -1;
1640
1822
  this.headerColIndexOf = (hg, header) => (hg && hg.headers ? hg.headers : []).indexOf(header);
1823
+ this.headerLeafStart = (hg, header) => {
1824
+ const list = hg && hg.headers ? hg.headers : [];
1825
+ let leaf = 0;
1826
+ for (let i = 0; i < list.length; i++) {
1827
+ if (list[i] === header) return leaf;
1828
+ const h = list[i];
1829
+ leaf = leaf + (h && h.colSpan > 1 ? h.colSpan : 1);
1830
+ }
1831
+ return -1;
1832
+ };
1641
1833
  this.pageRowOffset = () => {
1642
1834
  if (!this.isGrid() || this.rowsWindowed()) return 0;
1643
1835
  return this.pageIndex() * this.pageSize();
@@ -1681,14 +1873,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1681
1873
  const header = nextIsHeader == null ? this._activeIsHeader.value : nextIsHeader;
1682
1874
  const rowOut = this.rowsWindowed() && this.virtualizer && this.rowIsOutsideWindow(r);
1683
1875
  const colOut = this.colsWindowed() && this.colVirtualizer && this.colIsOutsideWindow(c);
1684
- if (!header && (rowOut || colOut)) {
1685
- if (rowOut) this.virtualizer.scrollToIndex(r, { align: "center" });
1876
+ const rowScroll = !header && rowOut;
1877
+ if (rowScroll || colOut) {
1878
+ if (rowScroll) this.virtualizer.scrollToIndex(r, { align: "center" });
1686
1879
  if (colOut) this.colVirtualizer.scrollToIndex(c, { align: "center" });
1687
1880
  let focusAttempts = 0;
1688
1881
  const myEpoch = this.focusIntentEpoch;
1689
1882
  const focusWhenReady = () => {
1690
1883
  if (this.focusIntentEpoch !== myEpoch) return;
1691
- const el = this.resolveCellEl(String(r), c);
1884
+ const el = this.resolveCellEl(header ? "__header" : String(r), c, header ? lvl : null);
1692
1885
  if (el) {
1693
1886
  el.focus();
1694
1887
  return;
@@ -1708,6 +1901,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1708
1901
  };
1709
1902
  this.totalRowCount = () => {
1710
1903
  if (!this.table) return (this._rows.value || []).length;
1904
+ if (this.manual === true) {
1905
+ if (this.rowCount != null) return this.rowCount;
1906
+ if (this.pageCount != null) return this.pageCount * this.pageSize();
1907
+ }
1711
1908
  const fm = this.table.getFilteredRowModel();
1712
1909
  return fm && fm.rows ? fm.rows.length : (this._rows.value || []).length;
1713
1910
  };
@@ -1715,6 +1912,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1715
1912
  this.gridAriaRowCount = () => this.headerRowCount() + this.totalRowCount();
1716
1913
  this.ariaPageOffset = () => this.table ? this.pageIndex() * this.pageSize() : 0;
1717
1914
  this.bodyAriaRowIndex = (row) => this.headerRowCount() + this.rowIndexOf(row) + this.ariaPageOffset() + 1;
1915
+ this.gridAriaColCount = () => this.visibleColCount();
1718
1916
  this.visibleColCount = () => {
1719
1917
  const rowList = this._rows.value || [];
1720
1918
  if (rowList.length) return rowList[0].getVisibleCells().length;
@@ -1885,6 +2083,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1885
2083
  const rowKey = this._activeIsHeader.value ? "__header" : String(this._activeRow.value);
1886
2084
  return this.resolveCellEl(rowKey, this._activeColIndex.value, this._activeIsHeader.value ? this._activeHeaderLevel.value : null);
1887
2085
  };
2086
+ this.activeCellHasControls = () => focusables(this.currentCellEl()).length > 0;
1888
2087
  this.enterControl = () => {
1889
2088
  const list = focusables(this.currentCellEl());
1890
2089
  if (!list.length) return;
@@ -1929,10 +2128,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1929
2128
  let nextLevel = prevLevel;
1930
2129
  if ((e.ctrlKey || e.metaKey) && e.shiftKey && !this._activeIsHeader.value && (key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight")) {
1931
2130
  e.preventDefault();
1932
- if (key === "ArrowUp") this.extendRange(-this._activeRow.value, 0);
1933
- else if (key === "ArrowDown") this.extendRange(this.bodyRowCount() - 1 - this._activeRow.value, 0);
1934
- else if (key === "ArrowLeft") this.extendRange(0, -this._activeColIndex.value);
1935
- else this.extendRange(0, this.visibleColCount() - 1 - this._activeColIndex.value);
2131
+ if (key === "ArrowUp") this.extendRange(-this.rangeFocusRow(), 0);
2132
+ else if (key === "ArrowDown") this.extendRange(this.bodyRowCount() - 1 - this.rangeFocusRow(), 0);
2133
+ else if (key === "ArrowLeft") this.extendRange(0, -this.rangeFocusCol());
2134
+ else this.extendRange(0, this.visibleColCount() - 1 - this.rangeFocusCol());
1936
2135
  return;
1937
2136
  } else if ((e.ctrlKey || e.metaKey) && !this._activeIsHeader.value && (key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight")) {
1938
2137
  e.preventDefault();
@@ -2015,15 +2214,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2015
2214
  nextCol = en.col;
2016
2215
  nextIsHeader = false;
2017
2216
  } else nextCol = this.gotoColEdge(true);
2018
- } else if ((key === "c" || key === "C") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed()) {
2217
+ } else if ((key === "c" || key === "C") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed() && this.clipboardWriteAvailable()) {
2019
2218
  e.preventDefault();
2020
2219
  this.copyRange();
2021
2220
  return;
2022
- } else if ((key === "v" || key === "V") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed()) {
2221
+ } else if ((key === "v" || key === "V") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed() && this.clipboardReadAvailable()) {
2023
2222
  e.preventDefault();
2024
2223
  this.pasteRange();
2025
2224
  return;
2026
- } else if ((key === "x" || key === "X") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed()) {
2225
+ } else if ((key === "x" || key === "X") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed() && this.clipboardWriteAvailable()) {
2027
2226
  e.preventDefault();
2028
2227
  this.cutRange();
2029
2228
  return;
@@ -2053,6 +2252,23 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2053
2252
  e.preventDefault();
2054
2253
  if (!this._activeIsHeader.value) this.selectAllBody();
2055
2254
  return;
2255
+ } else if (key === " " && e.shiftKey && !e.ctrlKey && !e.metaKey && !this._activeIsHeader.value) {
2256
+ e.preventDefault();
2257
+ if (this.selectionMode !== "none") {
2258
+ const selRow = (this._rows.value || [])[this._activeRow.value];
2259
+ if (selRow && selRow.toggleSelected) selRow.toggleSelected(!this.rowIsSelected(selRow));
2260
+ }
2261
+ return;
2262
+ } else if (key === " " && (e.ctrlKey || e.metaKey) && !e.shiftKey && !this._activeIsHeader.value) {
2263
+ e.preventDefault();
2264
+ this.selectActiveColumn();
2265
+ return;
2266
+ } else if (key === "Escape") {
2267
+ if (this.rangeActive || this._rangeAnchor.value != null) {
2268
+ e.preventDefault();
2269
+ this.clearRange();
2270
+ }
2271
+ return;
2056
2272
  } else if (key === "F2" && e.shiftKey && this.isActiveCellEditable()) {
2057
2273
  e.preventDefault();
2058
2274
  this.beginRowEdit((this._rows.value || [])[this._activeRow.value]);
@@ -2078,6 +2294,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2078
2294
  this.onToggleExpand((this._rows.value || [])[this._activeRow.value], e);
2079
2295
  this.recoverGridFocus(String(grpRow), grpCol, null, true);
2080
2296
  return;
2297
+ } else if (key === "Enter" && !this._activeIsHeader.value && !this.activeCellHasControls()) {
2298
+ e.preventDefault();
2299
+ this.activateRowAt(this._activeRow.value, "keyboard");
2300
+ return;
2081
2301
  } else if (key === "Enter" || key === "F2") {
2082
2302
  e.preventDefault();
2083
2303
  this.enterControl();
@@ -2132,8 +2352,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2132
2352
  this._activeColIndex.value = col;
2133
2353
  if (isHeader !== prevIsHeader || col !== prevCol || (isHeader ? movedLevel !== prevLevel : movedRow !== prevRow)) this.focusIntentEpoch = this.focusIntentEpoch + 1;
2134
2354
  if (this.rangeTransition) this.rangeTransition = false;
2135
- else if (this.rangeClickPending) this.rangeClickPending = false;
2136
- else this.clearRange();
2355
+ else if (this.rangeClickPending && this.rangeClickPending.isHeader === isHeader && this.rangeClickPending.r === movedRow && this.rangeClickPending.c === col) this.rangeClickPending = null;
2356
+ else {
2357
+ this.rangeClickPending = null;
2358
+ this.clearRange();
2359
+ }
2137
2360
  if (tgt === cellEl) this._activeInControl.value = false;
2138
2361
  };
2139
2362
  this.onGridMouseDown = (e) => {
@@ -2154,9 +2377,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2154
2377
  this._activeIsHeader.value = false;
2155
2378
  this._activeRow.value = row;
2156
2379
  this._activeColIndex.value = col;
2157
- this.rangeClickPending = true;
2380
+ this.rangeClickPending = {
2381
+ isHeader: false,
2382
+ r: row,
2383
+ c: col
2384
+ };
2158
2385
  return;
2159
2386
  }
2387
+ if (this.isEditing(row, col)) return;
2160
2388
  this.beginRangeDrag(row, col);
2161
2389
  };
2162
2390
  this.onGridDblClick = (e) => {
@@ -2184,7 +2412,43 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2184
2412
  this.beginEdit(row, col, null);
2185
2413
  }
2186
2414
  };
2415
+ this.activateRowAt = (index, trigger) => {
2416
+ const row = (this._rows.value || [])[index];
2417
+ if (!row || this.rowIsGrouped(row) || this.rowIsLazyPlaceholder(row)) return;
2418
+ this.dispatchEvent(new CustomEvent("row-activate", {
2419
+ detail: {
2420
+ row: row.original,
2421
+ index,
2422
+ trigger
2423
+ },
2424
+ bubbles: true,
2425
+ composed: true
2426
+ }));
2427
+ };
2428
+ this.ROW_ACTIVATE_CONTROLS = "input, button, a[href], select, textarea, label, summary, [contenteditable=\"\"], [contenteditable=\"true\"], [role=\"button\"], [role=\"checkbox\"], [role=\"link\"], [data-editing-cell]";
2429
+ this.maybeActivateRowFromClick = (e) => {
2430
+ if (!e || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;
2431
+ if (this.rangeDragMoved) return;
2432
+ const tgt = e.target;
2433
+ if (!tgt || !tgt.closest) return;
2434
+ const cellEl = tgt.closest("[data-row]");
2435
+ if (!cellEl) return;
2436
+ const control = tgt.closest(this.ROW_ACTIVATE_CONTROLS);
2437
+ if (control && cellEl.contains(control)) return;
2438
+ const rowAttr = cellEl.getAttribute("data-row");
2439
+ if (rowAttr == null || rowAttr === "__header") return;
2440
+ const index = parseInt(rowAttr, 10);
2441
+ if (!Number.isFinite(index)) return;
2442
+ if (this.isGrid() && this.singleClickEdit) {
2443
+ const colAttr = cellEl.getAttribute("data-col-index");
2444
+ const col = colAttr == null ? NaN : parseInt(colAttr, 10);
2445
+ const colId = Number.isFinite(col) ? this.columnIdAt(index, col) : null;
2446
+ if (colId != null && this.columnEditable(colId)) return;
2447
+ }
2448
+ this.activateRowAt(index, "click");
2449
+ };
2187
2450
  this.onGridClick = (e) => {
2451
+ this.maybeActivateRowFromClick(e);
2188
2452
  if (!this.isGrid() || !e) return;
2189
2453
  if (!this.singleClickEdit) return;
2190
2454
  if (e.shiftKey) return;
@@ -2295,7 +2559,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2295
2559
  const headers = hg && hg.headers || [];
2296
2560
  if (!this.colsWindowed()) return headers.map((h) => ({
2297
2561
  header: h,
2298
- span: h && h.colSpan > 1 ? h.colSpan : 1
2562
+ span: h && h.colSpan > 1 ? h.colSpan : 1,
2563
+ width: null
2299
2564
  }));
2300
2565
  const idx = this.windowedColIndices();
2301
2566
  const idxSet = {};
@@ -2309,23 +2574,39 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2309
2574
  const end = cursor + leafCount;
2310
2575
  cursor = end;
2311
2576
  let span = 0;
2312
- for (let c = start; c < end; c++) if (idxSet[c]) span = span + 1;
2577
+ let width = 0;
2578
+ for (let c = start; c < end; c++) if (idxSet[c]) {
2579
+ span = span + 1;
2580
+ width = width + this.columnSize(c);
2581
+ }
2313
2582
  if (span > 0) out.push({
2314
2583
  header: h,
2315
- span
2584
+ span,
2585
+ width
2316
2586
  });
2317
2587
  }
2318
2588
  return out;
2319
2589
  };
2320
2590
  this.windowedColSpan = () => this.colsWindowed() ? this.windowedColIndices().length + 2 : this.visibleColCount();
2591
+ this.lastColSizeSig = 0;
2592
+ this.remeasureColumnSizes = () => {
2593
+ if (!this.colsWindowed() || !this.colVirtualizer || !this.colVirtualizer.measure) return;
2594
+ const n = this.columnCount();
2595
+ let sig = n;
2596
+ for (let i = 0; i < n; i++) sig = Math.imul(sig, 31) + this.columnSize(i) | 0;
2597
+ if (sig === this.lastColSizeSig) return;
2598
+ this.lastColSizeSig = sig;
2599
+ this.colVirtualizer.measure();
2600
+ };
2321
2601
  this.remeasureColumnWindow = () => {
2322
2602
  if (!this.colsWindowed() || !this.colVirtualizer) return;
2323
2603
  this.colVirtualizer.setOptions(this.columnVirtualizerOptions());
2604
+ this.remeasureColumnSizes();
2324
2605
  this.colVirtualizer._willUpdate();
2325
2606
  };
2326
2607
  this.gridEmptyFallback = false;
2327
2608
  this.rangeTransition = false;
2328
- this.rangeClickPending = false;
2609
+ this.rangeClickPending = null;
2329
2610
  this.rangeActive = false;
2330
2611
  this.inRange = (rIdx, cIdx) => {
2331
2612
  const a = this._rangeAnchor.value;
@@ -2367,7 +2648,17 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2367
2648
  const c1 = a.colIndex > f.colIndex ? a.colIndex : f.colIndex;
2368
2649
  return rIdx === r1 && cIdx === c1;
2369
2650
  };
2651
+ this.rangeSummary = (anchor, focus) => {
2652
+ if (!anchor || !focus) return "";
2653
+ const rows = Math.abs(focus.rowIndex - anchor.rowIndex) + 1;
2654
+ const cols = Math.abs(focus.colIndex - anchor.colIndex) + 1;
2655
+ if (rows === 1 && cols === 1) return "1 cell selected";
2656
+ const rowPart = rows + (rows === 1 ? " row" : " rows");
2657
+ const colPart = cols + (cols === 1 ? " column" : " columns");
2658
+ return rowPart + " by " + colPart + " selected, " + rows * cols + " cells";
2659
+ };
2370
2660
  this.emitRangeChange = (anchor, focus) => {
2661
+ this._rangeAnnounce.value = this.rangeSummary(anchor, focus);
2371
2662
  this.dispatchEvent(new CustomEvent("range-change", {
2372
2663
  detail: {
2373
2664
  anchor,
@@ -2410,11 +2701,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2410
2701
  this.focusActiveCell(nextRow, nextCol, false);
2411
2702
  if (!hadRange || nextRow !== focus.rowIndex || nextCol !== focus.colIndex) this.emitRangeChange(anchor, nextFocus);
2412
2703
  };
2413
- this.setRangeFocus = (rIdx, cIdx) => {
2704
+ this.setRangeFocus = (rIdx, cIdx, anchorR = null, anchorC = null) => {
2414
2705
  const maxRow = this.bodyRowCount() - 1;
2415
2706
  const maxCol = this.visibleColCount() - 1;
2416
2707
  if (maxRow < 0 || maxCol < 0) return;
2417
2708
  let anchor = this._rangeAnchor.value;
2709
+ if (!anchor && anchorR != null && anchorC != null) anchor = {
2710
+ rowIndex: clamp(Math.trunc(Number(anchorR)) || 0, 0, maxRow),
2711
+ colIndex: clamp(Math.trunc(Number(anchorC)) || 0, 0, maxCol)
2712
+ };
2418
2713
  if (!anchor) anchor = {
2419
2714
  rowIndex: this._activeRow.value,
2420
2715
  colIndex: this._activeColIndex.value
@@ -2445,6 +2740,32 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2445
2740
  this.rangeActive = true;
2446
2741
  this.emitRangeChange(anchor, focus);
2447
2742
  };
2743
+ this.rangeFocusRow = () => {
2744
+ const f = this._rangeFocus.value;
2745
+ return f && f.rowIndex != null ? f.rowIndex : this._activeRow.value;
2746
+ };
2747
+ this.rangeFocusCol = () => {
2748
+ const f = this._rangeFocus.value;
2749
+ return f && f.colIndex != null ? f.colIndex : this._activeColIndex.value;
2750
+ };
2751
+ this.selectActiveColumn = () => {
2752
+ const maxRow = this.bodyRowCount() - 1;
2753
+ const maxCol = this.visibleColCount() - 1;
2754
+ if (maxRow < 0 || maxCol < 0) return;
2755
+ const c = clamp(Math.trunc(Number(this._activeColIndex.value)) || 0, 0, maxCol);
2756
+ const anchor = {
2757
+ rowIndex: 0,
2758
+ colIndex: c
2759
+ };
2760
+ const focus = {
2761
+ rowIndex: maxRow,
2762
+ colIndex: c
2763
+ };
2764
+ this._rangeAnchor.value = anchor;
2765
+ this._rangeFocus.value = focus;
2766
+ this.rangeActive = true;
2767
+ this.emitRangeChange(anchor, focus);
2768
+ };
2448
2769
  this.clearRange = () => {
2449
2770
  if (!this.rangeActive) return;
2450
2771
  this.rangeActive = false;
@@ -2524,6 +2845,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2524
2845
  }
2525
2846
  return lines.join("\n");
2526
2847
  };
2848
+ this.clipboardWriteAvailable = () => typeof navigator !== "undefined" && !!navigator.clipboard && typeof navigator.clipboard.writeText === "function";
2849
+ this.clipboardReadAvailable = () => typeof navigator !== "undefined" && !!navigator.clipboard && typeof navigator.clipboard.readText === "function";
2527
2850
  this.copyRange = () => {
2528
2851
  if (!this.clipboardActiveAllowed()) return;
2529
2852
  if (typeof navigator === "undefined" || !navigator.clipboard || !navigator.clipboard.writeText) return;
@@ -2532,27 +2855,30 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2532
2855
  if (p && p.catch) p.catch(() => {});
2533
2856
  } catch (err) {}
2534
2857
  };
2535
- this.applyGridToRange = (grid, originRow, originCol) => {
2858
+ this.applyGridToRange = (grid, originRow, originCol, verb) => {
2859
+ const opVerb = typeof verb === "string" && verb !== "" ? verb : "pasted";
2536
2860
  const maxRow = this.bodyRowCount() - 1;
2537
2861
  const maxCol = this.visibleColCount() - 1;
2538
2862
  if (maxRow < 0 || maxCol < 0) return {
2539
2863
  wrote: 0,
2864
+ changed: 0,
2540
2865
  total: 0
2541
2866
  };
2542
2867
  let total = 0;
2543
- let wrote = 0;
2868
+ let applied = 0;
2544
2869
  const committed = [];
2545
2870
  let next = this.currentData();
2546
2871
  for (let gr = 0; gr < grid.length; gr++) {
2547
2872
  const r = originRow + gr;
2548
2873
  if (r > maxRow) break;
2549
2874
  const rowGrouped = this.rowIndexIsGrouped(r);
2875
+ const rowPlaceholder = this.rowIsLazyPlaceholder((this._rows.value || [])[r]);
2550
2876
  const cols = grid[gr] || [];
2551
2877
  for (let gc = 0; gc < cols.length; gc++) {
2552
2878
  const c = originCol + gc;
2553
2879
  if (c > maxCol) break;
2554
2880
  total = total + 1;
2555
- if (rowGrouped) continue;
2881
+ if (rowGrouped || rowPlaceholder) continue;
2556
2882
  const colId = this.columnIdAt(r, c);
2557
2883
  if (colId == null || !this.columnEditable(colId)) continue;
2558
2884
  const rowObj = this.rowOriginalAt(r);
@@ -2561,6 +2887,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2561
2887
  const field = this.fieldOfColId(colId);
2562
2888
  const srcIndex = this.sourceIndexOfRow(r);
2563
2889
  const oldValue = rowObj ? rowObj[field] : null;
2890
+ applied = applied + 1;
2891
+ if (oldValue === value) continue;
2564
2892
  next = replaceRowValue(next, srcIndex, field, value);
2565
2893
  committed.push({
2566
2894
  rowId: this.rowIdAt(r),
@@ -2568,23 +2896,27 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2568
2896
  oldValue,
2569
2897
  newValue: value
2570
2898
  });
2571
- wrote = wrote + 1;
2572
2899
  }
2573
2900
  }
2574
- if (wrote > 0) {
2901
+ if (committed.length > 0) {
2575
2902
  this.editTransition = true;
2576
2903
  this.writeData(next);
2577
2904
  this.editTransition = false;
2578
- for (let i = 0; i < committed.length; i++) this.dispatchEvent(new CustomEvent("cell-edit-commit", {
2579
- detail: committed[i],
2580
- bubbles: true,
2581
- composed: true
2582
- }));
2905
+ for (let i = 0; i < committed.length; i++) try {
2906
+ this.dispatchEvent(new CustomEvent("cell-edit-commit", {
2907
+ detail: committed[i],
2908
+ bubbles: true,
2909
+ composed: true
2910
+ }));
2911
+ } catch (err) {
2912
+ console.error("[rozie-data-table] paste failed partway: a cell-edit-commit listener threw. The model was already written; the remaining cells still notify.", err);
2913
+ }
2583
2914
  }
2584
- if (wrote > 0) this.announce(wrote + " of " + total + " cells pasted");
2585
- else if (total > 0) this.announce("No cells pasted — " + total + " cells were invalid or read-only");
2915
+ if (applied > 0) this.announce(applied + " of " + total + " cells " + opVerb);
2916
+ else if (total > 0) this.announce("No cells " + opVerb + " — " + total + " cells were invalid or read-only");
2586
2917
  return {
2587
- wrote,
2918
+ wrote: applied,
2919
+ changed: committed.length,
2588
2920
  total
2589
2921
  };
2590
2922
  };
@@ -2616,11 +2948,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2616
2948
  }
2617
2949
  if (!p || !p.then) return;
2618
2950
  p.then((text) => {
2619
- const grid = parseTsv(text);
2620
- if (!grid.length) return;
2621
- const tiled = tileGridToBox(grid, destBox);
2622
- this.applyGridToRange(tiled, anchorRow, anchorCol);
2623
- }).catch(() => {});
2951
+ try {
2952
+ const grid = parseTsv(text);
2953
+ if (!grid.length) return;
2954
+ const tiled = tileGridToBox(grid, destBox);
2955
+ this.applyGridToRange(tiled, anchorRow, anchorCol, "pasted");
2956
+ } catch (err) {
2957
+ console.error("[rozie-data-table] paste failed: a row accessor, the data model setter or other consumer code threw. The paste was abandoned.", err);
2958
+ }
2959
+ }, () => {});
2624
2960
  };
2625
2961
  this.cutRange = () => {
2626
2962
  if (!this.clipboardActiveAllowed()) return;
@@ -2639,7 +2975,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2639
2975
  for (let c = c0; c <= c1; c++) cols.push("");
2640
2976
  grid.push(cols);
2641
2977
  }
2642
- this.applyGridToRange(grid, r0, c0);
2978
+ this.applyGridToRange(grid, r0, c0, "cut");
2643
2979
  };
2644
2980
  this.clearActiveRange = () => {
2645
2981
  if (!this.clipboardActiveAllowed()) return;
@@ -2654,7 +2990,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2654
2990
  for (let c = c0; c <= c1; c++) cols.push("");
2655
2991
  grid.push(cols);
2656
2992
  }
2657
- this.applyGridToRange(grid, r0, c0);
2993
+ this.applyGridToRange(grid, r0, c0, "cleared");
2658
2994
  };
2659
2995
  this.fillRange = (sourceBox, endCell) => {
2660
2996
  let box;
@@ -2692,7 +3028,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2692
3028
  }
2693
3029
  grid.push(cols);
2694
3030
  }
2695
- this.applyGridToRange(grid, box.r0, box.c0);
3031
+ this.applyGridToRange(grid, box.r0, box.c0, "filled");
2696
3032
  };
2697
3033
  this.fillDragging = false;
2698
3034
  this.fillDragMove = null;
@@ -2854,7 +3190,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2854
3190
  if (cell && (cell.r !== lastCell.r || cell.c !== lastCell.c)) {
2855
3191
  lastCell = cell;
2856
3192
  this.rangeDragMoved = true;
2857
- this.setRangeFocus(cell.r, cell.c);
3193
+ this.setRangeFocus(cell.r, cell.c, anchorR, anchorC);
2858
3194
  }
2859
3195
  };
2860
3196
  const up = () => {
@@ -2876,6 +3212,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2876
3212
  };
2877
3213
  this.isActiveCellEditable = () => {
2878
3214
  if (this.rowIndexIsGrouped(this._activeRow.value)) return false;
3215
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[this._activeRow.value])) return false;
2879
3216
  const colId = this.activeCellColumnId();
2880
3217
  return colId != null && this.columnEditable(colId);
2881
3218
  };
@@ -2987,12 +3324,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2987
3324
  };
2988
3325
  this.beginEdit = (rowIndex, colIndex, seed) => {
2989
3326
  if (this.rowIndexIsGrouped(rowIndex)) return;
3327
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[rowIndex])) return;
2990
3328
  const colId = this.columnIdAt(rowIndex, colIndex);
2991
3329
  if (colId == null || !this.columnEditable(colId)) return;
2992
3330
  this.committedThisSession = false;
2993
3331
  this.setInvalid("");
2994
3332
  this._editingRowIndex.value = null;
2995
3333
  this._rowDraft.value = {};
3334
+ this.rowDraftSync = {};
2996
3335
  this._editingRow.value = rowIndex;
2997
3336
  this._editingCol.value = colIndex;
2998
3337
  this._draftValue.value = seed != null ? seed : this.cellValueAt(rowIndex, colIndex);
@@ -3035,6 +3374,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3035
3374
  this.endRowEdit = () => {
3036
3375
  this._editingRowIndex.value = null;
3037
3376
  this._rowDraft.value = {};
3377
+ this.rowDraftSync = {};
3038
3378
  this._invalidMsg.value = "";
3039
3379
  this._activeInControl.value = false;
3040
3380
  this._editVer.value = this._editVer.value + 1;
@@ -3048,7 +3388,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3048
3388
  return this._editFocusColId.value != null && this._editFocusColId.value === colId;
3049
3389
  };
3050
3390
  this.coerceCellValue = (colId, raw) => {
3051
- if (this.editorTypeOf(colId) !== "number") return raw;
3391
+ const kind = this.editorTypeOf(colId);
3392
+ if (kind === "checkbox") {
3393
+ if (typeof raw === "boolean") return raw;
3394
+ if (raw == null) return false;
3395
+ if (typeof raw === "number") return raw !== 0;
3396
+ return /^\s*(true|1|yes|y|on)\s*$/i.test(String(raw));
3397
+ }
3398
+ if (kind !== "number") return raw;
3052
3399
  if (raw == null) return null;
3053
3400
  if (typeof raw === "number") return Number.isNaN(raw) ? null : raw;
3054
3401
  const s = String(raw).trim();
@@ -3110,10 +3457,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3110
3457
  };
3111
3458
  this.toggleActiveBooleanCell = () => {
3112
3459
  if (this.rowIndexIsGrouped(this._activeRow.value)) return;
3113
- const colId = this.columnIdAt(this._activeRow.value, this._activeColIndex.value);
3114
- if (colId == null || !this.columnEditable(colId)) return;
3115
3460
  const row = (this._rows.value || [])[this._activeRow.value];
3116
3461
  if (!row) return;
3462
+ if (this.rowIsLazyPlaceholder(row)) return;
3463
+ const colId = this.columnIdAt(this._activeRow.value, this._activeColIndex.value);
3464
+ if (colId == null || !this.columnEditable(colId)) return;
3117
3465
  const rowOriginal = row.original;
3118
3466
  const rowId = row.id;
3119
3467
  const oldValue = this.cellValueAt(this._activeRow.value, this._activeColIndex.value);
@@ -3199,6 +3547,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3199
3547
  const rowIndex = this.rowIndexOf(row);
3200
3548
  if (rowIndex < 0) return;
3201
3549
  if (this.rowIndexIsGrouped(rowIndex)) return;
3550
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[rowIndex])) return;
3202
3551
  const editable = this.editableColumnsForRow(rowIndex);
3203
3552
  if (editable.length === 0) return;
3204
3553
  this.committedThisSession = false;
@@ -3214,6 +3563,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3214
3563
  draft[ec.colId] = orig ? orig[ec.field] : null;
3215
3564
  }
3216
3565
  this._rowDraft.value = draft;
3566
+ this.rowDraftSync = draft;
3217
3567
  this._editingRowIndex.value = rowIndex;
3218
3568
  this._activeInControl.value = true;
3219
3569
  this._editVer.value = this._editVer.value + 1;
@@ -3231,7 +3581,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3231
3581
  const r = (this._rows.value || [])[rowIndex];
3232
3582
  const rowOriginal = r ? r.original : null;
3233
3583
  const rowId = r ? r.id : null;
3234
- const draft = this._rowDraft.value || {};
3584
+ const draft = this.rowDraftSync || {};
3235
3585
  for (let i = 0; i < editable.length; i++) {
3236
3586
  const ec = editable[i];
3237
3587
  const err = this.runValidator(ec.colId, this.coerceCellValue(ec.colId, draft[ec.colId]), rowOriginal);
@@ -3344,6 +3694,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3344
3694
  this.editTransition = false;
3345
3695
  this.pendingEditFollow = null;
3346
3696
  this.committedThisSession = false;
3697
+ this.rowDraftSync = {};
3698
+ this.dropinTabFlush = null;
3347
3699
  this.inRowEdit = () => this._editingRowIndex.value != null;
3348
3700
  this.editorValueFor = (colId) => this.inRowEdit() ? this._rowDraft.value ? this._rowDraft.value[colId] : null : this._draftValue.value;
3349
3701
  this.editorCheckedFor = (colId) => !!(this.inRowEdit() ? this._rowDraft.value ? this._rowDraft.value[colId] : null : this._draftValue.value);
@@ -3352,6 +3704,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3352
3704
  this.setRowDraft(colId, value);
3353
3705
  return;
3354
3706
  }
3707
+ if (this.dropinTabFlush) {
3708
+ this.dropinTabFlush.called = true;
3709
+ if (this.commitEdit(value, true)) this.dropinTabFlush.committed = true;
3710
+ return;
3711
+ }
3355
3712
  this.commitEdit(value);
3356
3713
  };
3357
3714
  this.editorCancelFor = () => () => {
@@ -3378,10 +3735,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3378
3735
  this._draftValue.value = v;
3379
3736
  };
3380
3737
  this.setRowDraft = (colId, value) => {
3381
- const src = this._rowDraft.value || {};
3738
+ const src = this.rowDraftSync || {};
3382
3739
  const next = {};
3383
3740
  for (const k in src) next[k] = src[k];
3384
3741
  next[colId] = value;
3742
+ this.rowDraftSync = next;
3385
3743
  this._rowDraft.value = next;
3386
3744
  };
3387
3745
  this.rowEditTab = (target, backward) => {
@@ -3436,6 +3794,56 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3436
3794
  this.cancelEdit();
3437
3795
  }
3438
3796
  };
3797
+ this.onEditorDropinKeyDown = (e) => {
3798
+ if (!e) return;
3799
+ const key = e.key;
3800
+ if (this.inRowEdit()) {
3801
+ if (key === "Enter") {
3802
+ e.preventDefault();
3803
+ this.commitRow();
3804
+ return;
3805
+ }
3806
+ if (key === "Escape") {
3807
+ e.preventDefault();
3808
+ this.cancelRow();
3809
+ return;
3810
+ }
3811
+ if (key === "Tab") {
3812
+ e.preventDefault();
3813
+ this.rowEditTab(e.target, e.shiftKey);
3814
+ return;
3815
+ }
3816
+ return;
3817
+ }
3818
+ if (key !== "Tab" || e.defaultPrevented) return;
3819
+ e.preventDefault();
3820
+ const fromRow = this._editingRow.value;
3821
+ const fromCol = this._editingCol.value;
3822
+ const target = e.shiftKey ? this.prevEditableCell(fromRow, fromCol) : this.nextEditableCell(fromRow, fromCol);
3823
+ const el = e.target;
3824
+ const ownCell = el && el.closest ? el.closest("[data-grid-cell]") : null;
3825
+ const flush = {
3826
+ called: false,
3827
+ committed: false
3828
+ };
3829
+ this.dropinTabFlush = flush;
3830
+ if (ownCell && ownCell.focus) ownCell.focus();
3831
+ else if (el && el.blur) el.blur();
3832
+ this.dropinTabFlush = null;
3833
+ if (!flush.called) {
3834
+ this.onEditorKeyDown(e);
3835
+ return;
3836
+ }
3837
+ if (!flush.committed) {
3838
+ if (el && el.focus) el.focus();
3839
+ return;
3840
+ }
3841
+ if (target) {
3842
+ this._activeRow.value = target.row;
3843
+ this._activeColIndex.value = target.col;
3844
+ this.beginEdit(target.row, target.col, null);
3845
+ } else this.focusCellWhenReady(fromRow, fromCol);
3846
+ };
3439
3847
  this.onEditorBlur = (e) => {
3440
3848
  if (this.inRowEdit()) {
3441
3849
  if (this.editTransition) return;
@@ -3448,13 +3856,20 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3448
3856
  }
3449
3857
  if (this._editingRow.value < 0 || this.editTransition) return;
3450
3858
  const next = e ? e.relatedTarget : null;
3451
- if (next == null) return;
3859
+ const fromCell = e && e.target && e.target.closest ? e.target.closest("[data-grid-cell]") : null;
3860
+ if (next == null) {
3861
+ if (!this.outsidePointerDown) return;
3862
+ this.outsidePointerDown = false;
3863
+ if (!fromCell) return;
3864
+ if (fromCell.getAttribute("data-row") !== String(this._editingRow.value) || fromCell.getAttribute("data-col-index") !== String(this._editingCol.value)) return;
3865
+ this.commitEdit(void 0, true);
3866
+ return;
3867
+ }
3452
3868
  if (!(this.gridRoot && this.gridRoot.contains && this.gridRoot.contains(next))) {
3453
3869
  this.commitEdit(void 0);
3454
3870
  return;
3455
3871
  }
3456
3872
  const nextCell = next.closest ? next.closest("[data-grid-cell]") : null;
3457
- const fromCell = e && e.target && e.target.closest ? e.target.closest("[data-grid-cell]") : null;
3458
3873
  if (!nextCell || !fromCell || nextCell === fromCell) return;
3459
3874
  const fromRow = fromCell.getAttribute("data-row");
3460
3875
  const fromCol = fromCell.getAttribute("data-col-index");
@@ -3633,32 +4048,30 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3633
4048
  this.styles = css`
3634
4049
  :host{display:contents}
3635
4050
  :host {
3636
- --rdt-font: var(--rozie-data-table-font);
3637
- --rdt-color: var(--rozie-data-table-fg);
3638
- --rdt-cell-padding: var(--rozie-data-table-cell-padding);
3639
- --rdt-border: 1px solid var(--rozie-data-table-border-color);
3640
- --rdt-header-bg: var(--rozie-data-table-header-bg);
3641
- --rdt-header-weight: var(--rozie-data-table-header-weight);
3642
- --rdt-sort-ind-opacity: var(--rozie-data-table-sort-indicator-opacity);
3643
- --rdt-filter-border: 1px solid var(--rozie-data-table-control-border-color);
3644
- --rdt-filter-radius: var(--rozie-data-table-radius);
3645
- --rdt-page-btn-border: 1px solid var(--rozie-data-table-control-border-color);
3646
- --rdt-page-btn-radius: var(--rozie-data-table-radius);
3647
- --rdt-page-btn-disabled-opacity: var(--rozie-data-table-disabled-opacity);
3648
- --rdt-page-size-border: 1px solid var(--rozie-data-table-control-border-color);
3649
- --rdt-page-size-radius: var(--rozie-data-table-radius);
3650
- --rdt-resize-grip-color: var(--rozie-data-table-resize-grip-color);
3651
- --rdt-resize-grip-active: var(--rozie-data-table-resize-grip-active);
3652
- --rdt-pin-btn-border: 1px solid var(--rozie-data-table-control-border-color);
3653
- --rdt-pin-btn-radius: var(--rozie-data-table-radius);
3654
- --rdt-pin-btn-active-bg: var(--rozie-data-table-pin-active-bg);
3655
- --rdt-colvis-summary-border: 1px solid var(--rozie-data-table-control-border-color);
3656
- --rdt-colvis-summary-radius: var(--rozie-data-table-radius);
3657
- --rdt-colvis-menu-border: 1px solid var(--rozie-data-table-border-color);
3658
- --rdt-colvis-menu-radius: var(--rozie-data-table-radius);
3659
- --rdt-colvis-menu-bg: var(--rozie-data-table-menu-bg);
3660
- --rdt-colvis-menu-shadow: var(--rozie-data-table-menu-shadow);
3661
- --rdt-select-accent: var(--rozie-data-table-select-accent);
4051
+ --rdt-color: var(--rozie-data-table-fg, var(--rdt-ds-fg));
4052
+ --rdt-select-accent: var(--rozie-data-table-select-accent, var(--rozie-data-table-accent, var(--rdt-ds-select-accent)));
4053
+ --rdt-border: 1px solid var(--rozie-data-table-border-color, var(--rdt-ds-border-color));
4054
+ --rdt-filter-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4055
+ --rdt-filter-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4056
+ --rdt-font: var(--rozie-data-table-font, var(--rdt-ds-font));
4057
+ --rdt-cell-padding: var(--rozie-data-table-cell-padding, var(--rdt-ds-cell-padding));
4058
+ --rdt-header-bg: var(--rozie-data-table-header-bg, var(--rdt-ds-header-bg));
4059
+ --rdt-header-weight: var(--rozie-data-table-header-weight, var(--rdt-ds-header-weight));
4060
+ --rdt-sort-ind-opacity: var(--rozie-data-table-sort-indicator-opacity, var(--rdt-ds-sort-indicator-opacity));
4061
+ --rdt-resize-grip-color: var(--rozie-data-table-resize-grip-color, var(--rdt-ds-resize-grip-color));
4062
+ --rdt-resize-grip-active: var(--rozie-data-table-resize-grip-active, var(--rozie-data-table-accent, var(--rdt-ds-resize-grip-active)));
4063
+ --rdt-pin-btn-active-bg: var(--rozie-data-table-pin-active-bg, var(--rdt-ds-pin-active-bg));
4064
+ --rdt-colvis-menu-bg: var(--rozie-data-table-menu-bg, var(--rdt-ds-menu-bg));
4065
+ --rdt-colvis-menu-shadow: var(--rozie-data-table-menu-shadow, var(--rdt-ds-menu-shadow));
4066
+ --rdt-colvis-menu-border: 1px solid var(--rozie-data-table-border-color, var(--rdt-ds-border-color));
4067
+ --rdt-colvis-menu-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4068
+ --rdt-colvis-summary-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4069
+ --rdt-colvis-summary-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4070
+ --rdt-page-btn-disabled-opacity: var(--rozie-data-table-disabled-opacity, var(--rdt-ds-disabled-opacity));
4071
+ --rdt-page-btn-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4072
+ --rdt-page-btn-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4073
+ --rdt-page-size-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4074
+ --rdt-page-size-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
3662
4075
  }
3663
4076
  .rozie-data-table[data-rozie-s-d5dcab4c] {
3664
4077
  border-collapse: collapse;
@@ -3794,6 +4207,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3794
4207
  flex-direction: column;
3795
4208
  gap: var(--rdt-chrome-gap, 0.5rem);
3796
4209
  }
4210
+ .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-skeleton[data-rozie-s-d5dcab4c] {
4211
+ /* inline-block on the cell's own line box, exactly like a text value (a block box was 2px
4212
+ short of a text row). */
4213
+ display: inline-block;
4214
+ width: 100%;
4215
+ vertical-align: baseline;
4216
+ border-radius: 4px;
4217
+ background: color-mix(in srgb, currentColor 12%, transparent);
4218
+ color: transparent;
4219
+ }
3797
4220
  .rozie-data-table-wrap[data-rozie-s-d5dcab4c] .rdt-toolbar[data-rozie-s-d5dcab4c] {
3798
4221
  display: flex;
3799
4222
  gap: var(--rdt-toolbar-gap, 0.5rem);
@@ -3832,6 +4255,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3832
4255
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-filter-row[data-rozie-s-d5dcab4c] {
3833
4256
  background: var(--rdt-filter-row-bg, rgba(0, 0, 0, 0.015));
3834
4257
  }
4258
+ .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-pinned[data-rozie-s-d5dcab4c] {
4259
+ box-sizing: border-box;
4260
+ }
3835
4261
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-filter-cell[data-rozie-s-d5dcab4c] {
3836
4262
  padding: var(--rdt-filter-cell-padding, 0.35rem 0.75rem);
3837
4263
  border-bottom: var(--rdt-border, 1px solid rgba(0, 0, 0, 0.08));
@@ -3951,6 +4377,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3951
4377
  .rozie-data-table-wrap[data-rozie-s-d5dcab4c] .rdt-colvis-summary[data-rozie-s-d5dcab4c] {
3952
4378
  cursor: pointer;
3953
4379
  font: inherit;
4380
+ /* Own the margin too: content-site typography styles bare \`summary\` (VitePress sets
4381
+ \`margin: 16px 0\`), which grew the <details> and stretched the toolbar's search input. */
4382
+ margin: 0;
3954
4383
  padding: var(--rdt-colvis-summary-padding, 0.25rem 0.6rem);
3955
4384
  border: var(--rdt-colvis-summary-border, 1px solid rgba(0, 0, 0, 0.2));
3956
4385
  border-radius: var(--rdt-colvis-summary-radius, 4px);
@@ -3989,6 +4418,51 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3989
4418
  text-align: var(--rdt-expander-col-align, center);
3990
4419
  white-space: nowrap;
3991
4420
  }
4421
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="1"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4422
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="2"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4423
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="3"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4424
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="4"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4425
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="5"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4426
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="6"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4427
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="7"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before,
4428
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="8"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4429
+ content: '';
4430
+ display: inline-block;
4431
+ vertical-align: middle;
4432
+ }
4433
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="1"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4434
+ width: calc(1 * var(--rdt-tree-indent, 1.25rem));
4435
+ }
4436
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="2"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4437
+ width: calc(2 * var(--rdt-tree-indent, 1.25rem));
4438
+ }
4439
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="3"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4440
+ width: calc(3 * var(--rdt-tree-indent, 1.25rem));
4441
+ }
4442
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="4"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4443
+ width: calc(4 * var(--rdt-tree-indent, 1.25rem));
4444
+ }
4445
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="5"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4446
+ width: calc(5 * var(--rdt-tree-indent, 1.25rem));
4447
+ }
4448
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="6"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4449
+ width: calc(6 * var(--rdt-tree-indent, 1.25rem));
4450
+ }
4451
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="7"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4452
+ width: calc(7 * var(--rdt-tree-indent, 1.25rem));
4453
+ }
4454
+ .rozie-data-table[data-rozie-s-d5dcab4c] tbody[data-rozie-s-d5dcab4c] tr[data-depth="8"][data-rozie-s-d5dcab4c] > .rdt-expander-td[data-rozie-s-d5dcab4c] + .rdt-td[data-rozie-s-d5dcab4c]::before {
4455
+ width: calc(8 * var(--rdt-tree-indent, 1.25rem));
4456
+ }
4457
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] {
4458
+ user-select: none;
4459
+ }
4460
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] input[data-rozie-s-d5dcab4c],
4461
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] textarea[data-rozie-s-d5dcab4c],
4462
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] select[data-rozie-s-d5dcab4c],
4463
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] [contenteditable="true"][data-rozie-s-d5dcab4c] {
4464
+ user-select: text;
4465
+ }
3992
4466
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-select-all[data-rozie-s-d5dcab4c],
3993
4467
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-select-row[data-rozie-s-d5dcab4c] {
3994
4468
  cursor: pointer;
@@ -4052,6 +4526,17 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4052
4526
  update();
4053
4527
  }
4054
4528
  }
4529
+ {
4530
+ const slotEl = this.shadowRoot?.querySelector("slot[name=\"placeholder\"]");
4531
+ if (slotEl !== null && slotEl !== void 0) {
4532
+ const update = () => {
4533
+ this._hasSlotPlaceholder = this._slotPlaceholderElements.length > 0;
4534
+ };
4535
+ slotEl.addEventListener("slotchange", update);
4536
+ this._disconnectCleanups.push(() => slotEl.removeEventListener("slotchange", update));
4537
+ update();
4538
+ }
4539
+ }
4055
4540
  {
4056
4541
  const slotEl = this.shadowRoot?.querySelector("slot[name=\"selectCell\"]");
4057
4542
  if (slotEl !== null && slotEl !== void 0) {
@@ -4147,6 +4632,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4147
4632
  this._hasSlotSelectAll = Array.from(this.children).some((el) => el.getAttribute("slot") === "selectAll");
4148
4633
  this._hasSlotDynamicColHeader = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4149
4634
  this._hasSlotDynamicFilter = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4635
+ this._hasSlotPlaceholder = Array.from(this.children).some((el) => el.getAttribute("slot") === "placeholder");
4150
4636
  this._hasSlotSelectCell = Array.from(this.children).some((el) => el.getAttribute("slot") === "selectCell");
4151
4637
  this._hasSlotDynamicCell = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4152
4638
  this._hasSlotDynamicEditor = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
@@ -4164,12 +4650,22 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4164
4650
  firstUpdated() {
4165
4651
  this._armListeners();
4166
4652
  this._disconnectCleanups.push(effect(() => {
4167
- this.sorting, this.globalFilter, this.columnFilters, this.pagination, this.rowCount, this.pageCount, this.rowSelection, this.expanded, this.expandable, this.grouping, this.groupable, this.columnVisibility, this.columnSizing, this.columnOrder, this.columnPinning, this.selectionMode, (this.data || []).length, this.data, this._dataDefault.value, this.columns, this._colReg.value;
4653
+ this._windowVer.value;
4168
4654
  untracked(() => {
4169
4655
  if (this.__rozieWatchInitial_0) {
4170
4656
  this.__rozieWatchInitial_0 = false;
4171
4657
  return;
4172
4658
  }
4659
+ this.emitVisibleRangeIfChanged();
4660
+ });
4661
+ }));
4662
+ this._disconnectCleanups.push(effect(() => {
4663
+ this.sorting, this.globalFilter, this.columnFilters, this.pagination, this.rowCount, this.pageCount, this.rowSelection, this.expanded, this.expandable, this.grouping, this.groupable, this.columnVisibility, this.columnSizing, this.columnOrder, this.columnPinning, this.selectionMode, (this.data || []).length, this.data, this._dataDefault.value, this.columns, this._colReg.value;
4664
+ untracked(() => {
4665
+ if (this.__rozieWatchInitial_1) {
4666
+ this.__rozieWatchInitial_1 = false;
4667
+ return;
4668
+ }
4173
4669
  (() => {
4174
4670
  this.seedColumnPinning();
4175
4671
  this.reFeed();
@@ -4180,8 +4676,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4180
4676
  this._disconnectCleanups.push(effect(() => {
4181
4677
  this.sorting, this.columnFilters, this.globalFilter, this._sortingDefault.value, this._columnFiltersDefault.value, this._globalFilterDefault.value;
4182
4678
  untracked(() => {
4183
- if (this.__rozieWatchInitial_1) {
4184
- this.__rozieWatchInitial_1 = false;
4679
+ if (this.__rozieWatchInitial_2) {
4680
+ this.__rozieWatchInitial_2 = false;
4185
4681
  return;
4186
4682
  }
4187
4683
  (() => {
@@ -4197,6 +4693,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4197
4693
  if (id == null) return;
4198
4694
  const key = String(id);
4199
4695
  if (key === "__proto__" || key === "constructor" || key === "prototype") return;
4696
+ const prev = __rozieCtxHost._colReg.value ? __rozieCtxHost._colReg.value[key] : void 0;
4697
+ if (prev !== void 0 && columnSpecsEquivalent(prev, spec)) return;
4200
4698
  __rozieCtxHost._colReg.value = {
4201
4699
  ...__rozieCtxHost._colReg.value,
4202
4700
  [key]: spec
@@ -4213,7 +4711,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4213
4711
  this._dataDefault.value = this.data || [];
4214
4712
  this.seedColumnPinning();
4215
4713
  this.table = createTable({
4216
- data: this.currentData(),
4714
+ data: this.feedData(),
4217
4715
  columns: this.tableColumns(),
4218
4716
  state: this.currentState(),
4219
4717
  getCoreRowModel: getCoreRowModel(),
@@ -4222,7 +4720,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4222
4720
  getPaginationRowModel: getPaginationRowModel(),
4223
4721
  getExpandedRowModel: getExpandedRowModel(),
4224
4722
  getSubRows: this.getSubRows || void 0,
4225
- getRowCanExpand: this.expandable === true && this.getSubRows == null ? () => true : void 0,
4723
+ getRowId: this.rowIdOption(),
4724
+ getRowCanExpand: this.expandable === true && this.getSubRows == null ? (row) => !this.rowIsLazyPlaceholder(row) : void 0,
4226
4725
  onExpandedChange: this.onExpandedChangeCb,
4227
4726
  autoResetExpanded: false,
4228
4727
  getGroupedRowModel: getGroupedRowModel(),
@@ -4235,7 +4734,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4235
4734
  manualSorting: this.manual === true,
4236
4735
  rowCount: this.rowCount ?? void 0,
4237
4736
  pageCount: this.pageCount ?? void 0,
4238
- enableRowSelection: this.selectionMode !== "none",
4737
+ enableRowSelection: this.rowSelectionOption(),
4239
4738
  enableMultiRowSelection: this.selectionMode === "multiple",
4240
4739
  onSortingChange: this.onSortingChangeCb,
4241
4740
  onGlobalFilterChange: this.onGlobalFilterChangeCb,
@@ -4260,6 +4759,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4260
4759
  this._headerGroups.value = nextGroups;
4261
4760
  this._rowModelVer.value = this._rowModelVer.value + 1;
4262
4761
  if (this.rowsWindowed() && this.virtualizer) {
4762
+ this.migratePlaceholderSizeCache();
4263
4763
  this.virtualizer.setOptions(this.virtualizerOptions());
4264
4764
  this.virtualizer._willUpdate();
4265
4765
  }
@@ -4285,6 +4785,18 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4285
4785
  };
4286
4786
  this.refreshRowModel();
4287
4787
  this.gridRoot = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rozie-data-table") : null;
4788
+ if (typeof document !== "undefined") {
4789
+ this.docPointerDown = (ev) => {
4790
+ if (!this.gridRoot) {
4791
+ this.outsidePointerDown = false;
4792
+ return;
4793
+ }
4794
+ const path = ev && typeof ev.composedPath === "function" ? ev.composedPath() : null;
4795
+ const inside = path ? path.indexOf(this.gridRoot) !== -1 : !!(ev && ev.target && this.gridRoot.contains && this.gridRoot.contains(ev.target));
4796
+ this.outsidePointerDown = !inside;
4797
+ };
4798
+ document.addEventListener("pointerdown", this.docPointerDown, true);
4799
+ }
4288
4800
  if (this.isWindowed()) this.gridScrollEl = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rdt-scroll") : null;
4289
4801
  if (this.rowsWindowed()) {
4290
4802
  this.virtualizer = new Virtualizer(this.virtualizerOptions());
@@ -4318,6 +4830,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4318
4830
  }
4319
4831
  updated(changedProperties) {
4320
4832
  this.maybeClearHistoryOnExternalSwap();
4833
+ this.emitVisibleRangeIfChanged();
4834
+ this.remeasureColumnSizes();
4321
4835
  if (!this.table) return;
4322
4836
  const d = this.currentData() || [];
4323
4837
  if (d === this.lastData && d.length === this.lastDataLen) return;
@@ -4356,7 +4870,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4356
4870
 
4357
4871
  <div class="rdt-column-defs" style="display:none" aria-hidden="true" data-rozie-s-d5dcab4c><slot></slot></div>
4358
4872
 
4359
- ${!!this._invalidMsg.value ? html`<div class="rdt-sr-live" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._invalidMsg.value}</div>` : nothing}${!!this._pasteAnnounce.value ? html`<div class="rdt-sr-live rdt-sr-paste" data-testid="paste-announce" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._pasteAnnounce.value}</div>` : nothing}${!!this._liveAnnounce.value ? html`<div class="rdt-sr-live rdt-sr-sortfilter" data-testid="sortfilter-announce" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._liveAnnounce.value}</div>` : nothing}<div class="rdt-toolbar" data-rozie-s-d5dcab4c>
4873
+ ${!!this._invalidMsg.value ? html`<div class="rdt-sr-live" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._invalidMsg.value}</div>` : nothing}${!!this._pasteAnnounce.value ? html`<div class="rdt-sr-live rdt-sr-paste" data-testid="paste-announce" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._pasteAnnounce.value}</div>` : nothing}${!!this._rangeAnnounce.value ? html`<div class="rdt-sr-live rdt-sr-range" data-testid="range-announce" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._rangeAnnounce.value}</div>` : nothing}${!!this._liveAnnounce.value ? html`<div class="rdt-sr-live rdt-sr-sortfilter" data-testid="sortfilter-announce" role="status" aria-live="polite" aria-atomic="true" data-rozie-s-d5dcab4c>${this._liveAnnounce.value}</div>` : nothing}<div class="rdt-toolbar" data-rozie-s-d5dcab4c>
4360
4874
  <input class="rdt-global-filter" type="text" role="searchbox" aria-label="Search table" .value=${this.globalFilterValue()} @input=${($event) => {
4361
4875
  this.onGlobalFilterInput($event);
4362
4876
  }} data-rozie-s-d5dcab4c />
@@ -4397,7 +4911,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4397
4911
  "rozie-data-table": true,
4398
4912
  "rdt-sticky": this.stickyHeader,
4399
4913
  "rdt-col-windowed": this.colsWindowed()
4400
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} @keydown=${($event) => {
4914
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} aria-colcount=${rozieAttr(this.gridAriaColCount())} @keydown=${($event) => {
4401
4915
  this.onGridKeyDown($event);
4402
4916
  }} @focusin=${($event) => {
4403
4917
  this.syncActiveFromEvent($event);
@@ -4417,9 +4931,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4417
4931
  "rdt-th": true,
4418
4932
  "rdt-select-th": this.isSelectColumn(wh.header.column.id),
4419
4933
  "rdt-expander-th": this.isExpanderColumn(wh.header.column.id),
4934
+ "rdt-pinned": this.columnPinSide(wh.header.column.id) !== "",
4420
4935
  "rdt-th-resizing": this.columnIsResizing(wh.header.column.id),
4421
4936
  "rdt-cell-active": this.isActiveCell("__header", this.headerColIndexOf(hg, wh.header), hgLevel)
4422
- }).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))} data-rozie-s-d5dcab4c>
4937
+ }).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))} aria-colindex=${rozieAttr(this.headerLeafStart(hg, wh.header) + 1)} 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, wh.width))} data-rozie-s-d5dcab4c>
4423
4938
  ${this.isSelectColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4424
4939
  ${this.selectAll !== void 0 ? this.selectAll({
4425
4940
  checked: this.isAllRowsSelected(),
@@ -4535,7 +5050,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4535
5050
  ${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>`)}
4536
5051
 
4537
5052
  ${this.hasAnyFilterableColumn() ? html`<tr class="rdt-filter-row" data-rozie-s-d5dcab4c>
4538
- ${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>
5053
+ ${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="${Object.entries({
5054
+ "rdt-filter-cell": true,
5055
+ "rdt-pinned": this.columnPinSide(wh.header.column.id) !== ""
5056
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role="presentation" data-col=${rozieAttr(wh.header.column.id)} style=${rozieStyle(this.pinStyle(wh.header.column.id))} data-rozie-s-d5dcab4c>
4539
5057
  ${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>
4540
5058
  ${this.columnIsFilterable(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4541
5059
  ${this.rozieSlots?.[`filter-${wh.header.column.id}`] !== void 0 ? this.rozieSlots?.[`filter-${wh.header.column.id}`]({
@@ -4543,6 +5061,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4543
5061
  value: this.columnFilterValue(wh.header.column.id),
4544
5062
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4545
5063
  minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5064
+ columnLabel: this.headerLabel(wh.header.column.id),
4546
5065
  setFilter: this.setColumnFilter
4547
5066
  }) : html`<slot name="${`filter-${wh.header.column.id}`}" data-rozie-params=${(() => {
4548
5067
  try {
@@ -4550,7 +5069,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4550
5069
  columnId: wh.header.column.id,
4551
5070
  value: this.columnFilterValue(wh.header.column.id),
4552
5071
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4553
- minMax: this.getFacetedMinMaxValues(wh.header.column.id)
5072
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5073
+ columnLabel: this.headerLabel(wh.header.column.id)
4554
5074
  });
4555
5075
  } catch {
4556
5076
  return "{}";
@@ -4561,6 +5081,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4561
5081
  value: this.columnFilterValue(wh.header.column.id),
4562
5082
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4563
5083
  minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5084
+ columnLabel: this.headerLabel(wh.header.column.id),
4564
5085
  setFilter: this.setColumnFilter
4565
5086
  }) : html`<slot name="filter" data-rozie-params=${(() => {
4566
5087
  try {
@@ -4568,7 +5089,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4568
5089
  columnId: wh.header.column.id,
4569
5090
  value: this.columnFilterValue(wh.header.column.id),
4570
5091
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4571
- minMax: this.getFacetedMinMaxValues(wh.header.column.id)
5092
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5093
+ columnLabel: this.headerLabel(wh.header.column.id)
4572
5094
  });
4573
5095
  } catch {
4574
5096
  return "{}";
@@ -4594,18 +5116,40 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4594
5116
  <tr class="${Object.entries({
4595
5117
  "rdt-tr": true,
4596
5118
  "rdt-group-header": this.rowIsGrouped(wr.row),
4597
- "rdt-row-pinned": wr.pinned
4598
- }).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>
5119
+ "rdt-row-pinned": wr.pinned,
5120
+ "rdt-placeholder-row": this.rowIsLazyPlaceholder(wr.row)
5121
+ }).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)} aria-busy=${rozieAttr(this.rowIsLazyPlaceholder(wr.row) ? "true" : null)} data-rozie-s-d5dcab4c>
4599
5122
 
4600
5123
  ${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({
4601
5124
  "rdt-td": true,
4602
5125
  "rdt-select-td": this.isSelectColumn(cell.column.id),
4603
5126
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
5127
+ "rdt-pinned": this.columnPinSide(cell.column.id) !== "",
4604
5128
  "rdt-in-range": this.inRange(wr.vi.index, this.colIndexOf(wr.row, cell)),
4605
5129
  "rdt-cell-active": this.isActiveCell(String(wr.vi.index), this.colIndexOf(wr.row, cell))
4606
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.cellRole())} data-col=${rozieAttr(cell.column.id)} data-grid-cell="" data-row=${rozieAttr(wr.vi.index)} data-col-index=${rozieAttr(this.colIndexOf(wr.row, cell))} tabindex=${rozieAttr(this.cellTabindex(String(wr.vi.index), this.colIndexOf(wr.row, cell)))} style=${rozieStyle(this.bodyCellStyle(wr.row, cell.column.id))} aria-invalid=${rozieAttr(this.cellAriaInvalid(wr.vi.index, this.colIndexOf(wr.row, cell)))} data-in-range=${rozieAttr(this.inRange(wr.vi.index, this.colIndexOf(wr.row, cell)) ? "true" : null)} data-agg-cell=${rozieAttr(this.cellIsAggregated(cell) ? cell.column.id : null)} data-rozie-s-d5dcab4c>
5130
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.cellRole())} data-col=${rozieAttr(cell.column.id)} data-grid-cell="" data-row=${rozieAttr(wr.vi.index)} data-col-index=${rozieAttr(this.colIndexOf(wr.row, cell))} tabindex=${rozieAttr(this.cellTabindex(String(wr.vi.index), this.colIndexOf(wr.row, cell)))} style=${rozieStyle(this.bodyCellStyle(wr.row, cell.column.id))} aria-invalid=${rozieAttr(this.cellAriaInvalid(wr.vi.index, this.colIndexOf(wr.row, cell)))} aria-colindex=${rozieAttr(this.colIndexOf(wr.row, cell) + 1)} aria-selected=${rozieAttr(this.inRange(wr.vi.index, this.colIndexOf(wr.row, cell)) ? "true" : null)} data-in-range=${rozieAttr(this.inRange(wr.vi.index, this.colIndexOf(wr.row, cell)) ? "true" : null)} data-agg-cell=${rozieAttr(this.cellIsAggregated(cell) ? cell.column.id : null)} data-rozie-s-d5dcab4c>
4607
5131
 
4608
- ${this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5132
+
5133
+ ${this.rowIsLazyPlaceholder(wr.row) && this.isSelectColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5134
+
5135
+ <input class="rdt-select-placeholder" type="checkbox" disabled="" tabindex="-1" aria-hidden="true" style="visibility:hidden" data-rozie-s-d5dcab4c />
5136
+ </span>` : this.rowIsLazyPlaceholder(wr.row) && this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c></span>` : this.rowIsLazyPlaceholder(wr.row) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5137
+ ${this.placeholder !== void 0 ? this.placeholder({
5138
+ index: wr.vi.index,
5139
+ columnId: cell.column.id
5140
+ }) : html`<slot name="placeholder" data-rozie-params=${(() => {
5141
+ try {
5142
+ return JSON.stringify({
5143
+ index: wr.vi.index,
5144
+ columnId: cell.column.id
5145
+ });
5146
+ } catch {
5147
+ return "{}";
5148
+ }
5149
+ })()}>
5150
+ <span class="rdt-skeleton" aria-hidden="true" data-rozie-s-d5dcab4c>&#8203;</span>
5151
+ </slot>`}
5152
+ </span>` : this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4609
5153
  ${this.rowCanExpand(wr.row) ? html`<button class="rdt-expander" type="button" data-expander="" aria-expanded=${!!this.rowIsExpanded(wr.row)} aria-label=${rozieAttr(this.rowIsExpanded(wr.row) ? "Collapse row" : "Expand row")} @click=${($event) => {
4610
5154
  this.onToggleExpand(wr.row, $event);
4611
5155
  }} 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>
@@ -4670,27 +5214,29 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4670
5214
  </span>
4671
5215
  <span class="rdt-group-count" data-rozie-s-d5dcab4c>${rozieDisplay("(" + this.groupSubRowCount(wr.row) + ")")}</span>
4672
5216
  </span>` : this.isEditing(wr.vi.index, this.colIndexOf(wr.row, cell)) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4673
- ${this.editorTypeOf(cell.column.id) === "number" ? html`<input class="rdt-cell-editor" type="number" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5217
+ ${this.editorTypeOf(cell.column.id) === "number" ? html`<input class="rdt-cell-editor" type="number" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
4674
5218
  this.onCellEditorInput(cell.column.id, $event);
4675
5219
  }} @keydown=${($event) => {
4676
5220
  this.onEditorKeyDown($event);
4677
5221
  }} @blur=${($event) => {
4678
5222
  this.onEditorBlur($event);
4679
- }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "select" ? html`<select class="rdt-cell-editor" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @change=${($event) => {
5223
+ }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "select" ? html`<select class="rdt-cell-editor" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @change=${($event) => {
4680
5224
  this.onCellEditorInput(cell.column.id, $event);
4681
5225
  }} @keydown=${($event) => {
4682
5226
  this.onEditorKeyDown($event);
4683
5227
  }} @blur=${($event) => {
4684
5228
  this.onEditorBlur($event);
4685
5229
  }} data-rozie-s-d5dcab4c>
4686
- ${repeat(this.editorOptionsOf(cell.column.id), (opt, _idx) => opt.value, (opt, _idx) => html`<option value=${rozieAttr(opt.value)} data-rozie-s-d5dcab4c>${rozieDisplay(opt.label)}</option>`)}
4687
- </select>` : this.editorTypeOf(cell.column.id) === "checkbox" ? html`<input class="rdt-cell-editor" type="checkbox" data-editing-cell="" data-builtin-editor="" ?checked=${this.editorCheckedFor(cell.column.id)} @change=${($event) => {
5230
+ ${repeat(this.editorOptionsOf(cell.column.id), (opt, _idx) => opt.value, (opt, _idx) => html`<option value=${rozieAttr(opt.value)} ?selected=${opt.value === this.editorValueFor(cell.column.id)} data-rozie-s-d5dcab4c>${rozieDisplay(opt.label)}</option>`)}
5231
+ </select>` : this.editorTypeOf(cell.column.id) === "checkbox" ? html`<input class="rdt-cell-editor" type="checkbox" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} ?checked=${this.editorCheckedFor(cell.column.id)} @change=${($event) => {
4688
5232
  this.onCellEditorCheckbox(cell.column.id, $event);
4689
5233
  }} @keydown=${($event) => {
4690
5234
  this.onEditorKeyDown($event);
4691
5235
  }} @blur=${($event) => {
4692
5236
  this.onEditorBlur($event);
4693
- }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5237
+ }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" @keydown=${($event) => {
5238
+ this.onEditorDropinKeyDown($event);
5239
+ }} data-rozie-s-d5dcab4c>
4694
5240
  ${this.rozieSlots?.[`editor-${cell.column.id}`] !== void 0 ? this.rozieSlots?.[`editor-${cell.column.id}`]({
4695
5241
  columnId: cell.column.id,
4696
5242
  column: cell.column,
@@ -4698,6 +5244,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4698
5244
  value: this.editorValueFor(cell.column.id),
4699
5245
  commit: this.editorCommitFor(cell.column.id),
4700
5246
  cancel: this.editorCancelFor(),
5247
+ columnLabel: this.headerLabel(cell.column.id),
4701
5248
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4702
5249
  }) : html`<slot name="${`editor-${cell.column.id}`}" data-rozie-params=${(() => {
4703
5250
  try {
@@ -4708,6 +5255,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4708
5255
  value: this.editorValueFor(cell.column.id),
4709
5256
  commit: this.editorCommitFor(cell.column.id),
4710
5257
  cancel: this.editorCancelFor(),
5258
+ columnLabel: this.headerLabel(cell.column.id),
4711
5259
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4712
5260
  });
4713
5261
  } catch {
@@ -4721,6 +5269,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4721
5269
  value: this.editorValueFor(cell.column.id),
4722
5270
  commit: this.editorCommitFor(cell.column.id),
4723
5271
  cancel: this.editorCancelFor(),
5272
+ columnLabel: this.headerLabel(cell.column.id),
4724
5273
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4725
5274
  }) : html`<slot name="editor" data-rozie-params=${(() => {
4726
5275
  try {
@@ -4731,13 +5280,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4731
5280
  value: this.editorValueFor(cell.column.id),
4732
5281
  commit: this.editorCommitFor(cell.column.id),
4733
5282
  cancel: this.editorCancelFor(),
5283
+ columnLabel: this.headerLabel(cell.column.id),
4734
5284
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4735
5285
  });
4736
5286
  } catch {
4737
5287
  return "{}";
4738
5288
  }
4739
5289
  })()}>
4740
- <input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5290
+ <input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
4741
5291
  this.onCellEditorInput(cell.column.id, $event);
4742
5292
  }} @keydown=${($event) => {
4743
5293
  this.onEditorKeyDown($event);
@@ -4746,7 +5296,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4746
5296
  }} data-rozie-s-d5dcab4c />
4747
5297
  </slot>`}
4748
5298
  </slot>`}
4749
- </span>` : html`<input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5299
+ </span>` : html`<input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
4750
5300
  this.onCellEditorInput(cell.column.id, $event);
4751
5301
  }} @keydown=${($event) => {
4752
5302
  this.onEditorKeyDown($event);
@@ -4814,7 +5364,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4814
5364
  </div>` : html`<table class="${Object.entries({
4815
5365
  "rozie-data-table": true,
4816
5366
  "rdt-sticky": this.stickyHeader
4817
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} @keydown=${($event) => {
5367
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} aria-colcount=${rozieAttr(this.gridAriaColCount())} @keydown=${($event) => {
4818
5368
  this.onGridKeyDown($event);
4819
5369
  }} @focusin=${($event) => {
4820
5370
  this.syncActiveFromEvent($event);
@@ -4833,9 +5383,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4833
5383
  "rdt-th": true,
4834
5384
  "rdt-select-th": this.isSelectColumn(header.column.id),
4835
5385
  "rdt-expander-th": this.isExpanderColumn(header.column.id),
5386
+ "rdt-pinned": this.columnPinSide(header.column.id) !== "",
4836
5387
  "rdt-th-resizing": this.columnIsResizing(header.column.id),
4837
5388
  "rdt-cell-active": this.isActiveCell("__header", this.headerColIndexOf(hg, header), hgLevel)
4838
- }).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))} data-rozie-s-d5dcab4c>
5389
+ }).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))} aria-colindex=${rozieAttr(this.headerLeafStart(hg, header) + 1)} tabindex=${rozieAttr(this.cellTabindex("__header", this.headerColIndexOf(hg, header), hgLevel))} aria-sort=${rozieAttr(this.ariaSortFor(header.column.id))} style=${rozieStyle(this.thStyle(header))} data-rozie-s-d5dcab4c>
4839
5390
 
4840
5391
 
4841
5392
  ${this.isSelectColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
@@ -4956,7 +5507,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4956
5507
  </tr>`)}
4957
5508
 
4958
5509
  ${this.hasAnyFilterableColumn() ? html`<tr class="rdt-filter-row" data-rozie-s-d5dcab4c>
4959
- ${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>
5510
+ ${repeat(this._headerGroups.value[this._headerGroups.value.length - 1].headers, (header, _idx) => header.id, (header, _idx) => html`<th class="${Object.entries({
5511
+ "rdt-filter-cell": true,
5512
+ "rdt-pinned": this.columnPinSide(header.column.id) !== ""
5513
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role="presentation" style=${rozieStyle(this.pinStyle(header.column.id))} data-rozie-s-d5dcab4c>
4960
5514
  ${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>
4961
5515
  ${this.columnIsFilterable(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4962
5516
  ${this.rozieSlots?.[`filter-${header.column.id}`] !== void 0 ? this.rozieSlots?.[`filter-${header.column.id}`]({
@@ -4964,6 +5518,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4964
5518
  value: this.columnFilterValue(header.column.id),
4965
5519
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4966
5520
  minMax: this.getFacetedMinMaxValues(header.column.id),
5521
+ columnLabel: this.headerLabel(header.column.id),
4967
5522
  setFilter: this.setColumnFilter
4968
5523
  }) : html`<slot name="${`filter-${header.column.id}`}" data-rozie-params=${(() => {
4969
5524
  try {
@@ -4971,7 +5526,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4971
5526
  columnId: header.column.id,
4972
5527
  value: this.columnFilterValue(header.column.id),
4973
5528
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4974
- minMax: this.getFacetedMinMaxValues(header.column.id)
5529
+ minMax: this.getFacetedMinMaxValues(header.column.id),
5530
+ columnLabel: this.headerLabel(header.column.id)
4975
5531
  });
4976
5532
  } catch {
4977
5533
  return "{}";
@@ -4982,6 +5538,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4982
5538
  value: this.columnFilterValue(header.column.id),
4983
5539
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4984
5540
  minMax: this.getFacetedMinMaxValues(header.column.id),
5541
+ columnLabel: this.headerLabel(header.column.id),
4985
5542
  setFilter: this.setColumnFilter
4986
5543
  }) : html`<slot name="filter" data-rozie-params=${(() => {
4987
5544
  try {
@@ -4989,7 +5546,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4989
5546
  columnId: header.column.id,
4990
5547
  value: this.columnFilterValue(header.column.id),
4991
5548
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4992
- minMax: this.getFacetedMinMaxValues(header.column.id)
5549
+ minMax: this.getFacetedMinMaxValues(header.column.id),
5550
+ columnLabel: this.headerLabel(header.column.id)
4993
5551
  });
4994
5552
  } catch {
4995
5553
  return "{}";
@@ -5016,9 +5574,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5016
5574
  "rdt-td": true,
5017
5575
  "rdt-select-td": this.isSelectColumn(cell.column.id),
5018
5576
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
5577
+ "rdt-pinned": this.columnPinSide(cell.column.id) !== "",
5019
5578
  "rdt-in-range": this.inRange(this.rowIndexOf(row), this.colIndexOf(row, cell)),
5020
5579
  "rdt-cell-active": this.isActiveCell(String(this.rowIndexOf(row)), this.colIndexOf(row, cell))
5021
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.cellRole())} data-col=${rozieAttr(cell.column.id)} data-grid-cell="" data-row=${rozieAttr(this.rowIndexOf(row))} data-col-index=${rozieAttr(this.colIndexOf(row, cell))} tabindex=${rozieAttr(this.cellTabindex(String(this.rowIndexOf(row)), this.colIndexOf(row, cell)))} style=${rozieStyle(this.bodyCellStyle(row, cell.column.id))} aria-invalid=${rozieAttr(this.cellAriaInvalid(this.rowIndexOf(row), this.colIndexOf(row, cell)))} data-in-range=${rozieAttr(this.inRange(this.rowIndexOf(row), this.colIndexOf(row, cell)) ? "true" : null)} data-agg-cell=${rozieAttr(this.cellIsAggregated(cell) ? cell.column.id : null)} data-rozie-s-d5dcab4c>
5580
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.cellRole())} data-col=${rozieAttr(cell.column.id)} data-grid-cell="" data-row=${rozieAttr(this.rowIndexOf(row))} data-col-index=${rozieAttr(this.colIndexOf(row, cell))} tabindex=${rozieAttr(this.cellTabindex(String(this.rowIndexOf(row)), this.colIndexOf(row, cell)))} style=${rozieStyle(this.bodyCellStyle(row, cell.column.id))} aria-invalid=${rozieAttr(this.cellAriaInvalid(this.rowIndexOf(row), this.colIndexOf(row, cell)))} aria-colindex=${rozieAttr(this.colIndexOf(row, cell) + 1)} aria-selected=${rozieAttr(this.inRange(this.rowIndexOf(row), this.colIndexOf(row, cell)) ? "true" : null)} data-in-range=${rozieAttr(this.inRange(this.rowIndexOf(row), this.colIndexOf(row, cell)) ? "true" : null)} data-agg-cell=${rozieAttr(this.cellIsAggregated(cell) ? cell.column.id : null)} data-rozie-s-d5dcab4c>
5022
5581
 
5023
5582
  ${this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5024
5583
  ${this.rowCanExpand(row) ? html`<button class="rdt-expander" type="button" data-expander="" aria-expanded=${!!this.rowIsExpanded(row)} aria-label=${rozieAttr(this.rowIsExpanded(row) ? "Collapse row" : "Expand row")} @click=${($event) => {
@@ -5085,27 +5644,29 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5085
5644
  </span>
5086
5645
  <span class="rdt-group-count" data-rozie-s-d5dcab4c>${rozieDisplay("(" + this.groupSubRowCount(row) + ")")}</span>
5087
5646
  </span>` : this.isEditing(this.rowIndexOf(row), this.colIndexOf(row, cell)) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5088
- ${this.editorTypeOf(cell.column.id) === "number" ? html`<input class="rdt-cell-editor" type="number" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5647
+ ${this.editorTypeOf(cell.column.id) === "number" ? html`<input class="rdt-cell-editor" type="number" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5089
5648
  this.onCellEditorInput(cell.column.id, $event);
5090
5649
  }} @keydown=${($event) => {
5091
5650
  this.onEditorKeyDown($event);
5092
5651
  }} @blur=${($event) => {
5093
5652
  this.onEditorBlur($event);
5094
- }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "select" ? html`<select class="rdt-cell-editor" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @change=${($event) => {
5653
+ }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "select" ? html`<select class="rdt-cell-editor" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @change=${($event) => {
5095
5654
  this.onCellEditorInput(cell.column.id, $event);
5096
5655
  }} @keydown=${($event) => {
5097
5656
  this.onEditorKeyDown($event);
5098
5657
  }} @blur=${($event) => {
5099
5658
  this.onEditorBlur($event);
5100
5659
  }} data-rozie-s-d5dcab4c>
5101
- ${repeat(this.editorOptionsOf(cell.column.id), (opt, _idx) => opt.value, (opt, _idx) => html`<option value=${rozieAttr(opt.value)} data-rozie-s-d5dcab4c>${rozieDisplay(opt.label)}</option>`)}
5102
- </select>` : this.editorTypeOf(cell.column.id) === "checkbox" ? html`<input class="rdt-cell-editor" type="checkbox" data-editing-cell="" data-builtin-editor="" ?checked=${this.editorCheckedFor(cell.column.id)} @change=${($event) => {
5660
+ ${repeat(this.editorOptionsOf(cell.column.id), (opt, _idx) => opt.value, (opt, _idx) => html`<option value=${rozieAttr(opt.value)} ?selected=${opt.value === this.editorValueFor(cell.column.id)} data-rozie-s-d5dcab4c>${rozieDisplay(opt.label)}</option>`)}
5661
+ </select>` : this.editorTypeOf(cell.column.id) === "checkbox" ? html`<input class="rdt-cell-editor" type="checkbox" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} ?checked=${this.editorCheckedFor(cell.column.id)} @change=${($event) => {
5103
5662
  this.onCellEditorCheckbox(cell.column.id, $event);
5104
5663
  }} @keydown=${($event) => {
5105
5664
  this.onEditorKeyDown($event);
5106
5665
  }} @blur=${($event) => {
5107
5666
  this.onEditorBlur($event);
5108
- }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5667
+ }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" @keydown=${($event) => {
5668
+ this.onEditorDropinKeyDown($event);
5669
+ }} data-rozie-s-d5dcab4c>
5109
5670
  ${this.rozieSlots?.[`editor-${cell.column.id}`] !== void 0 ? this.rozieSlots?.[`editor-${cell.column.id}`]({
5110
5671
  columnId: cell.column.id,
5111
5672
  column: cell.column,
@@ -5113,6 +5674,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5113
5674
  value: this.editorValueFor(cell.column.id),
5114
5675
  commit: this.editorCommitFor(cell.column.id),
5115
5676
  cancel: this.editorCancelFor(),
5677
+ columnLabel: this.headerLabel(cell.column.id),
5116
5678
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5117
5679
  }) : html`<slot name="${`editor-${cell.column.id}`}" data-rozie-params=${(() => {
5118
5680
  try {
@@ -5123,6 +5685,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5123
5685
  value: this.editorValueFor(cell.column.id),
5124
5686
  commit: this.editorCommitFor(cell.column.id),
5125
5687
  cancel: this.editorCancelFor(),
5688
+ columnLabel: this.headerLabel(cell.column.id),
5126
5689
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5127
5690
  });
5128
5691
  } catch {
@@ -5136,6 +5699,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5136
5699
  value: this.editorValueFor(cell.column.id),
5137
5700
  commit: this.editorCommitFor(cell.column.id),
5138
5701
  cancel: this.editorCancelFor(),
5702
+ columnLabel: this.headerLabel(cell.column.id),
5139
5703
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5140
5704
  }) : html`<slot name="editor" data-rozie-params=${(() => {
5141
5705
  try {
@@ -5146,13 +5710,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5146
5710
  value: this.editorValueFor(cell.column.id),
5147
5711
  commit: this.editorCommitFor(cell.column.id),
5148
5712
  cancel: this.editorCancelFor(),
5713
+ columnLabel: this.headerLabel(cell.column.id),
5149
5714
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5150
5715
  });
5151
5716
  } catch {
5152
5717
  return "{}";
5153
5718
  }
5154
5719
  })()}>
5155
- <input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5720
+ <input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5156
5721
  this.onCellEditorInput(cell.column.id, $event);
5157
5722
  }} @keydown=${($event) => {
5158
5723
  this.onEditorKeyDown($event);
@@ -5161,7 +5726,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5161
5726
  }} data-rozie-s-d5dcab4c />
5162
5727
  </slot>`}
5163
5728
  </slot>`}
5164
- </span>` : html`<input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5729
+ </span>` : html`<input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" aria-invalid=${rozieAttr(this._invalidMsg.value ? "true" : null)} .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5165
5730
  this.onCellEditorInput(cell.column.id, $event);
5166
5731
  }} @keydown=${($event) => {
5167
5732
  this.onEditorKeyDown($event);
@@ -5233,10 +5798,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5233
5798
  <select class="rdt-page-size" aria-label="Rows per page" .value=${this.pageSize()} @change=${($event) => {
5234
5799
  this.onPageSizeChange($event);
5235
5800
  }} data-rozie-s-d5dcab4c>
5236
- <option value=${10} data-rozie-s-d5dcab4c>10</option>
5237
- <option value=${25} data-rozie-s-d5dcab4c>25</option>
5238
- <option value=${50} data-rozie-s-d5dcab4c>50</option>
5239
- <option value=${100} data-rozie-s-d5dcab4c>100</option>
5801
+ <option value=${10} ?selected=${10 === this.pageSize()} data-rozie-s-d5dcab4c>10</option>
5802
+ <option value=${25} ?selected=${25 === this.pageSize()} data-rozie-s-d5dcab4c>25</option>
5803
+ <option value=${50} ?selected=${50 === this.pageSize()} data-rozie-s-d5dcab4c>50</option>
5804
+ <option value=${100} ?selected=${100 === this.pageSize()} data-rozie-s-d5dcab4c>100</option>
5240
5805
  </select>
5241
5806
  </div>` : nothing}</div>
5242
5807
  `;
@@ -5359,6 +5924,7 @@ __decorate([property({
5359
5924
  type: Object,
5360
5925
  attribute: "expanded"
5361
5926
  })], DataTable.prototype, "_expanded_attr", void 0);
5927
+ __decorate([property({ type: Function })], DataTable.prototype, "getRowId", void 0);
5362
5928
  __decorate([property({ type: Function })], DataTable.prototype, "getSubRows", void 0);
5363
5929
  __decorate([property({
5364
5930
  type: Boolean,
@@ -5440,6 +6006,12 @@ __decorate([state()], DataTable.prototype, "_hasSlotDynamicColHeader", void 0);
5440
6006
  __decorate([queryAssignedElements({ flatten: true })], DataTable.prototype, "_slotDynamicColHeaderElements", void 0);
5441
6007
  __decorate([state()], DataTable.prototype, "_hasSlotDynamicFilter", void 0);
5442
6008
  __decorate([queryAssignedElements({ flatten: true })], DataTable.prototype, "_slotDynamicFilterElements", void 0);
6009
+ __decorate([state()], DataTable.prototype, "_hasSlotPlaceholder", void 0);
6010
+ __decorate([queryAssignedElements({
6011
+ slot: "placeholder",
6012
+ flatten: true
6013
+ })], DataTable.prototype, "_slotPlaceholderElements", void 0);
6014
+ __decorate([property({ attribute: false })], DataTable.prototype, "placeholder", void 0);
5443
6015
  __decorate([state()], DataTable.prototype, "_hasSlotSelectCell", void 0);
5444
6016
  __decorate([queryAssignedElements({
5445
6017
  slot: "selectCell",
@@ -5637,15 +6209,19 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5637
6209
  this.commit = null;
5638
6210
  this.cancel = null;
5639
6211
  this.autofocus = false;
6212
+ this.columnLabel = "";
5640
6213
  this._draft = signal("");
6214
+ this._touched = signal(false);
5641
6215
  this.__rozieFirstUpdateDone = false;
5642
6216
  this._disconnectCleanups = [];
5643
6217
  this._rozieTornDown = false;
6218
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5644
6219
  this.onInput = (e) => {
5645
6220
  this._draft.value = e && e.target ? e.target.value : "";
6221
+ this._touched.value = true;
5646
6222
  };
5647
6223
  this.doCommit = () => {
5648
- this.commit && this.commit(this._draft.value);
6224
+ this.commit && this.commit(this.draftValue());
5649
6225
  };
5650
6226
  this.doCancel = () => {
5651
6227
  this.cancel && this.cancel();
@@ -5662,6 +6238,10 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5662
6238
  this.onBlur = () => {
5663
6239
  this.doCommit();
5664
6240
  };
6241
+ this.a11yLabel = () => {
6242
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6243
+ return this.columnId;
6244
+ };
5665
6245
  }
5666
6246
  static {
5667
6247
  this.styles = css`
@@ -5669,7 +6249,6 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5669
6249
  `;
5670
6250
  }
5671
6251
  firstUpdated() {
5672
- this._draft.value = this.value != null ? String(this.value) : "";
5673
6252
  if (this.autofocus) this._refInputEl?.focus();
5674
6253
  }
5675
6254
  updated(changedProperties) {
@@ -5689,7 +6268,7 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5689
6268
  }
5690
6269
  render() {
5691
6270
  return html`
5692
- <input class="rdt-cell-editor" type="text" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6271
+ <input class="rdt-cell-editor" type="text" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
5693
6272
  this.onInput($event);
5694
6273
  }} @keydown=${($event) => {
5695
6274
  this.onKeydown($event);
@@ -5712,6 +6291,10 @@ __decorate([property({
5712
6291
  type: Boolean,
5713
6292
  reflect: true
5714
6293
  })], EditorText.prototype, "autofocus", void 0);
6294
+ __decorate([property({
6295
+ type: String,
6296
+ reflect: true
6297
+ })], EditorText.prototype, "columnLabel", void 0);
5715
6298
  __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorText.prototype, "_refInputEl", void 0);
5716
6299
  EditorText = __decorate([customElement("rozie-editor-text")], EditorText);
5717
6300
  var EditorText_default = EditorText;
@@ -5726,15 +6309,21 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5726
6309
  this.value = null;
5727
6310
  this.commit = null;
5728
6311
  this.cancel = null;
6312
+ this.autofocus = false;
6313
+ this.columnLabel = "";
5729
6314
  this._draft = signal("");
6315
+ this._touched = signal(false);
6316
+ this.__rozieFirstUpdateDone = false;
5730
6317
  this._disconnectCleanups = [];
5731
6318
  this._rozieTornDown = false;
6319
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5732
6320
  this.onInput = (e) => {
5733
6321
  this._draft.value = e && e.target ? e.target.value : "";
6322
+ this._touched.value = true;
5734
6323
  };
5735
6324
  this.doCommit = () => {
5736
6325
  if (!this.commit) return;
5737
- const raw = this._draft.value;
6326
+ const raw = this.draftValue();
5738
6327
  if (raw == null || String(raw).trim() === "") {
5739
6328
  this.commit(null);
5740
6329
  return;
@@ -5757,6 +6346,10 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5757
6346
  this.onBlur = () => {
5758
6347
  this.doCommit();
5759
6348
  };
6349
+ this.a11yLabel = () => {
6350
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6351
+ return this.columnId;
6352
+ };
5760
6353
  }
5761
6354
  static {
5762
6355
  this.styles = css`
@@ -5764,7 +6357,13 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5764
6357
  `;
5765
6358
  }
5766
6359
  firstUpdated() {
5767
- this._draft.value = this.value != null ? String(this.value) : "";
6360
+ if (this.autofocus) this._refInputEl?.focus();
6361
+ }
6362
+ updated(changedProperties) {
6363
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6364
+ if (v) this._refInputEl?.focus();
6365
+ })(this.autofocus);
6366
+ this.__rozieFirstUpdateDone = true;
5768
6367
  }
5769
6368
  disconnectedCallback() {
5770
6369
  super.disconnectedCallback();
@@ -5777,13 +6376,13 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5777
6376
  }
5778
6377
  render() {
5779
6378
  return html`
5780
- <input class="rdt-cell-editor" type="number" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6379
+ <input class="rdt-cell-editor" type="number" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
5781
6380
  this.onInput($event);
5782
6381
  }} @keydown=${($event) => {
5783
6382
  this.onKeydown($event);
5784
6383
  }} @blur=${($event) => {
5785
6384
  this.onBlur();
5786
- }} data-rozie-s-b2792b32 />
6385
+ }} data-rozie-ref="inputEl" data-rozie-s-b2792b32 />
5787
6386
  `;
5788
6387
  }
5789
6388
  };
@@ -5796,6 +6395,15 @@ __decorate([property({ type: Object })], EditorNumber.prototype, "row", void 0);
5796
6395
  __decorate([property({ type: Object })], EditorNumber.prototype, "value", void 0);
5797
6396
  __decorate([property({ type: Function })], EditorNumber.prototype, "commit", void 0);
5798
6397
  __decorate([property({ type: Function })], EditorNumber.prototype, "cancel", void 0);
6398
+ __decorate([property({
6399
+ type: Boolean,
6400
+ reflect: true
6401
+ })], EditorNumber.prototype, "autofocus", void 0);
6402
+ __decorate([property({
6403
+ type: String,
6404
+ reflect: true
6405
+ })], EditorNumber.prototype, "columnLabel", void 0);
6406
+ __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorNumber.prototype, "_refInputEl", void 0);
5799
6407
  EditorNumber = __decorate([customElement("rozie-editor-number")], EditorNumber);
5800
6408
  var EditorNumber_default = EditorNumber;
5801
6409
  //#endregion
@@ -5810,14 +6418,20 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5810
6418
  this.commit = null;
5811
6419
  this.cancel = null;
5812
6420
  this.options = [];
6421
+ this.autofocus = false;
6422
+ this.columnLabel = "";
5813
6423
  this._draft = signal("");
6424
+ this._touched = signal(false);
6425
+ this.__rozieFirstUpdateDone = false;
5814
6426
  this._disconnectCleanups = [];
5815
6427
  this._rozieTornDown = false;
6428
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5816
6429
  this.onChange = (e) => {
5817
6430
  this._draft.value = e && e.target ? e.target.value : "";
6431
+ this._touched.value = true;
5818
6432
  };
5819
6433
  this.doCommit = () => {
5820
- this.commit && this.commit(this._draft.value);
6434
+ this.commit && this.commit(this.draftValue());
5821
6435
  };
5822
6436
  this.doCancel = () => {
5823
6437
  this.cancel && this.cancel();
@@ -5834,6 +6448,10 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5834
6448
  this.onBlur = () => {
5835
6449
  this.doCommit();
5836
6450
  };
6451
+ this.a11yLabel = () => {
6452
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6453
+ return this.columnId;
6454
+ };
5837
6455
  }
5838
6456
  static {
5839
6457
  this.styles = css`
@@ -5841,7 +6459,13 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5841
6459
  `;
5842
6460
  }
5843
6461
  firstUpdated() {
5844
- this._draft.value = this.value != null ? String(this.value) : "";
6462
+ if (this.autofocus) this._refSelectEl?.focus();
6463
+ }
6464
+ updated(changedProperties) {
6465
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6466
+ if (v) this._refSelectEl?.focus();
6467
+ })(this.autofocus);
6468
+ this.__rozieFirstUpdateDone = true;
5845
6469
  }
5846
6470
  disconnectedCallback() {
5847
6471
  super.disconnectedCallback();
@@ -5854,14 +6478,14 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5854
6478
  }
5855
6479
  render() {
5856
6480
  return html`
5857
- <select class="rdt-cell-editor" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @change=${($event) => {
6481
+ <select class="rdt-cell-editor" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @change=${($event) => {
5858
6482
  this.onChange($event);
5859
6483
  }} @keydown=${($event) => {
5860
6484
  this.onKeydown($event);
5861
6485
  }} @blur=${($event) => {
5862
6486
  this.onBlur();
5863
- }} data-rozie-s-117f1a16>
5864
- ${repeat(this.options, (opt, _idx) => opt.value, (opt, _idx) => html`<option value=${rozieAttr(opt.value)} data-rozie-s-117f1a16>${rozieDisplay(opt.label)}</option>`)}
6487
+ }} data-rozie-ref="selectEl" data-rozie-s-117f1a16>
6488
+ ${repeat(this.options, (opt, _idx) => opt.value, (opt, _idx) => html`<option value=${rozieAttr(opt.value)} ?selected=${opt.value === this.draftValue()} data-rozie-s-117f1a16>${rozieDisplay(opt.label)}</option>`)}
5865
6489
  </select>
5866
6490
  `;
5867
6491
  }
@@ -5876,6 +6500,15 @@ __decorate([property({ type: Object })], EditorSelect.prototype, "value", void 0
5876
6500
  __decorate([property({ type: Function })], EditorSelect.prototype, "commit", void 0);
5877
6501
  __decorate([property({ type: Function })], EditorSelect.prototype, "cancel", void 0);
5878
6502
  __decorate([property({ type: Array })], EditorSelect.prototype, "options", void 0);
6503
+ __decorate([property({
6504
+ type: Boolean,
6505
+ reflect: true
6506
+ })], EditorSelect.prototype, "autofocus", void 0);
6507
+ __decorate([property({
6508
+ type: String,
6509
+ reflect: true
6510
+ })], EditorSelect.prototype, "columnLabel", void 0);
6511
+ __decorate([query("[data-rozie-ref=\"selectEl\"]")], EditorSelect.prototype, "_refSelectEl", void 0);
5879
6512
  EditorSelect = __decorate([customElement("rozie-editor-select")], EditorSelect);
5880
6513
  var EditorSelect_default = EditorSelect;
5881
6514
  //#endregion
@@ -5889,6 +6522,9 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5889
6522
  this.value = null;
5890
6523
  this.commit = null;
5891
6524
  this.cancel = null;
6525
+ this.autofocus = false;
6526
+ this.columnLabel = "";
6527
+ this.__rozieFirstUpdateDone = false;
5892
6528
  this._disconnectCleanups = [];
5893
6529
  this._rozieTornDown = false;
5894
6530
  this.onChange = (e) => {
@@ -5900,12 +6536,25 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5900
6536
  this.cancel && this.cancel();
5901
6537
  }
5902
6538
  };
6539
+ this.a11yLabel = () => {
6540
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6541
+ return this.columnId;
6542
+ };
5903
6543
  }
5904
6544
  static {
5905
6545
  this.styles = css`
5906
6546
  :host{display:contents}
5907
6547
  `;
5908
6548
  }
6549
+ firstUpdated() {
6550
+ if (this.autofocus) this._refInputEl?.focus();
6551
+ }
6552
+ updated(changedProperties) {
6553
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6554
+ if (v) this._refInputEl?.focus();
6555
+ })(this.autofocus);
6556
+ this.__rozieFirstUpdateDone = true;
6557
+ }
5909
6558
  disconnectedCallback() {
5910
6559
  super.disconnectedCallback();
5911
6560
  queueMicrotask(() => {
@@ -5917,11 +6566,11 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5917
6566
  }
5918
6567
  render() {
5919
6568
  return html`
5920
- <input class="rdt-cell-editor" type="checkbox" data-editing-cell="" aria-label=${this.columnId} ?checked=${!!this.value} @change=${($event) => {
6569
+ <input class="rdt-cell-editor" type="checkbox" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} ?checked=${!!this.value} @change=${($event) => {
5921
6570
  this.onChange($event);
5922
6571
  }} @keydown=${($event) => {
5923
6572
  this.onKeydown($event);
5924
- }} data-rozie-s-3d792482 />
6573
+ }} data-rozie-ref="inputEl" data-rozie-s-3d792482 />
5925
6574
  `;
5926
6575
  }
5927
6576
  };
@@ -5934,9 +6583,51 @@ __decorate([property({ type: Object })], EditorCheckbox.prototype, "row", void 0
5934
6583
  __decorate([property({ type: Object })], EditorCheckbox.prototype, "value", void 0);
5935
6584
  __decorate([property({ type: Function })], EditorCheckbox.prototype, "commit", void 0);
5936
6585
  __decorate([property({ type: Function })], EditorCheckbox.prototype, "cancel", void 0);
6586
+ __decorate([property({
6587
+ type: Boolean,
6588
+ reflect: true
6589
+ })], EditorCheckbox.prototype, "autofocus", void 0);
6590
+ __decorate([property({
6591
+ type: String,
6592
+ reflect: true
6593
+ })], EditorCheckbox.prototype, "columnLabel", void 0);
6594
+ __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorCheckbox.prototype, "_refInputEl", void 0);
5937
6595
  EditorCheckbox = __decorate([customElement("rozie-editor-checkbox")], EditorCheckbox);
5938
6596
  var EditorCheckbox_default = EditorCheckbox;
5939
6597
  //#endregion
6598
+ //#region src/helpers/dateValue.ts
6599
+ /**
6600
+ * Coerce an arbitrary cell value to the `YYYY-MM-DD` string a native date input accepts.
6601
+ * Returns `''` for anything that cannot be read as a date — which is what the input shows for
6602
+ * "no date", so an unparseable value degrades to empty rather than to a broken control.
6603
+ */
6604
+ const toIsoDateString = (v) => {
6605
+ if (v == null || v === "") return "";
6606
+ if (typeof v === "string") {
6607
+ const s = v.trim();
6608
+ if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s;
6609
+ const iso = /^(\d{4}-\d{2}-\d{2})T/.exec(s);
6610
+ if (iso) return iso[1];
6611
+ return fromDate(new Date(s));
6612
+ }
6613
+ if (typeof v === "number") return Number.isFinite(v) ? fromDate(new Date(v)) : "";
6614
+ if (typeof v === "object" && typeof v.getTime === "function") return fromDate(v);
6615
+ return "";
6616
+ };
6617
+ /**
6618
+ * Format a Date as `YYYY-MM-DD` from its LOCAL parts. Local, not UTC: the input renders a
6619
+ * calendar day, and `toISOString()` would show the previous day for anyone west of UTC on a
6620
+ * midnight-local value.
6621
+ */
6622
+ const fromDate = (d) => {
6623
+ const t = d.getTime();
6624
+ if (!Number.isFinite(t)) return "";
6625
+ const y = d.getFullYear();
6626
+ const m = d.getMonth() + 1;
6627
+ const day = d.getDate();
6628
+ return String(y).padStart(4, "0") + "-" + String(m).padStart(2, "0") + "-" + String(day).padStart(2, "0");
6629
+ };
6630
+ //#endregion
5940
6631
  //#region src/EditorDate.ts
5941
6632
  let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5942
6633
  constructor(..._args) {
@@ -5947,20 +6638,27 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5947
6638
  this.value = null;
5948
6639
  this.commit = null;
5949
6640
  this.cancel = null;
6641
+ this.autofocus = false;
6642
+ this.columnLabel = "";
5950
6643
  this._draft = signal("");
6644
+ this._touched = signal(false);
6645
+ this.__rozieFirstUpdateDone = false;
5951
6646
  this._disconnectCleanups = [];
5952
6647
  this._rozieTornDown = false;
6648
+ this.draftValue = () => this._touched.value ? this._draft.value : toIsoDateString(this.value);
5953
6649
  this.onInput = (e) => {
5954
6650
  this._draft.value = e && e.target ? e.target.value : "";
6651
+ this._touched.value = true;
5955
6652
  };
5956
6653
  this.doCommit = () => {
5957
- this.commit && this.commit(this._draft.value);
6654
+ this.commit && this.commit(this.draftValue());
5958
6655
  };
5959
6656
  this.doCancel = () => {
5960
6657
  this.cancel && this.cancel();
5961
6658
  };
5962
6659
  this.onChange = (e) => {
5963
6660
  this._draft.value = e && e.target ? e.target.value : "";
6661
+ this._touched.value = true;
5964
6662
  };
5965
6663
  this.onKeydown = (e) => {
5966
6664
  if (e && e.key === "Enter") {
@@ -5974,6 +6672,10 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5974
6672
  this.onBlur = () => {
5975
6673
  this.doCommit();
5976
6674
  };
6675
+ this.a11yLabel = () => {
6676
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6677
+ return this.columnId;
6678
+ };
5977
6679
  }
5978
6680
  static {
5979
6681
  this.styles = css`
@@ -5981,7 +6683,13 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5981
6683
  `;
5982
6684
  }
5983
6685
  firstUpdated() {
5984
- this._draft.value = this.value != null ? String(this.value) : "";
6686
+ if (this.autofocus) this._refInputEl?.focus();
6687
+ }
6688
+ updated(changedProperties) {
6689
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6690
+ if (v) this._refInputEl?.focus();
6691
+ })(this.autofocus);
6692
+ this.__rozieFirstUpdateDone = true;
5985
6693
  }
5986
6694
  disconnectedCallback() {
5987
6695
  super.disconnectedCallback();
@@ -5994,7 +6702,7 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5994
6702
  }
5995
6703
  render() {
5996
6704
  return html`
5997
- <input class="rdt-cell-editor" type="date" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6705
+ <input class="rdt-cell-editor" type="date" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
5998
6706
  this.onInput($event);
5999
6707
  }} @change=${($event) => {
6000
6708
  this.onChange($event);
@@ -6002,7 +6710,7 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
6002
6710
  this.onKeydown($event);
6003
6711
  }} @blur=${($event) => {
6004
6712
  this.onBlur();
6005
- }} data-rozie-s-7abe1a56 />
6713
+ }} data-rozie-ref="inputEl" data-rozie-s-7abe1a56 />
6006
6714
  `;
6007
6715
  }
6008
6716
  };
@@ -6015,6 +6723,15 @@ __decorate([property({ type: Object })], EditorDate.prototype, "row", void 0);
6015
6723
  __decorate([property({ type: Object })], EditorDate.prototype, "value", void 0);
6016
6724
  __decorate([property({ type: Function })], EditorDate.prototype, "commit", void 0);
6017
6725
  __decorate([property({ type: Function })], EditorDate.prototype, "cancel", void 0);
6726
+ __decorate([property({
6727
+ type: Boolean,
6728
+ reflect: true
6729
+ })], EditorDate.prototype, "autofocus", void 0);
6730
+ __decorate([property({
6731
+ type: String,
6732
+ reflect: true
6733
+ })], EditorDate.prototype, "columnLabel", void 0);
6734
+ __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorDate.prototype, "_refInputEl", void 0);
6018
6735
  EditorDate = __decorate([customElement("rozie-editor-date")], EditorDate);
6019
6736
  var EditorDate_default = EditorDate;
6020
6737
  //#endregion
@@ -6026,17 +6743,23 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6026
6743
  this.column = null;
6027
6744
  this.value = null;
6028
6745
  this.setFilter = null;
6746
+ this.columnLabel = "";
6029
6747
  this._draft = signal("");
6748
+ this._touched = signal(false);
6749
+ this.__rozieFirstUpdateDone = false;
6030
6750
  this._disconnectCleanups = [];
6031
6751
  this._rozieTornDown = false;
6752
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
6032
6753
  this.onInput = (e) => {
6033
6754
  this._draft.value = e && e.target ? e.target.value : "";
6755
+ this._touched.value = true;
6034
6756
  };
6035
6757
  this.applyFilter = () => {
6036
- this.setFilter && this.setFilter(this.columnId, this._draft.value);
6758
+ this.setFilter && this.setFilter(this.columnId, this.draftValue());
6037
6759
  };
6038
6760
  this.clearFilter = () => {
6039
6761
  this._draft.value = "";
6762
+ this._touched.value = false;
6040
6763
  this.setFilter && this.setFilter(this.columnId, "");
6041
6764
  };
6042
6765
  this.onKeydown = (e) => {
@@ -6051,14 +6774,22 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6051
6774
  this.onBlur = () => {
6052
6775
  this.applyFilter();
6053
6776
  };
6777
+ this.a11yLabel = () => {
6778
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6779
+ return this.columnId;
6780
+ };
6054
6781
  }
6055
6782
  static {
6056
6783
  this.styles = css`
6057
6784
  :host{display:contents}
6058
6785
  `;
6059
6786
  }
6060
- firstUpdated() {
6061
- this._draft.value = this.value != null ? String(this.value) : "";
6787
+ updated(changedProperties) {
6788
+ if (this.__rozieFirstUpdateDone && changedProperties.has("value")) {
6789
+ this.value;
6790
+ this._touched.value = false;
6791
+ }
6792
+ this.__rozieFirstUpdateDone = true;
6062
6793
  }
6063
6794
  disconnectedCallback() {
6064
6795
  super.disconnectedCallback();
@@ -6071,7 +6802,7 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6071
6802
  }
6072
6803
  render() {
6073
6804
  return html`
6074
- <input class="rdt-col-filter" part="col-filter" type="text" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6805
+ <input class="rdt-col-filter" part="col-filter" type="text" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
6075
6806
  this.onInput($event);
6076
6807
  }} @keydown=${($event) => {
6077
6808
  this.onKeydown($event);
@@ -6088,6 +6819,10 @@ __decorate([property({
6088
6819
  __decorate([property({ type: Object })], FilterText.prototype, "column", void 0);
6089
6820
  __decorate([property({ type: Object })], FilterText.prototype, "value", void 0);
6090
6821
  __decorate([property({ type: Function })], FilterText.prototype, "setFilter", void 0);
6822
+ __decorate([property({
6823
+ type: String,
6824
+ reflect: true
6825
+ })], FilterText.prototype, "columnLabel", void 0);
6091
6826
  FilterText = __decorate([customElement("rozie-filter-text")], FilterText);
6092
6827
  var FilterText_default = FilterText;
6093
6828
  //#endregion
@@ -6100,24 +6835,41 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6100
6835
  this.value = null;
6101
6836
  this.setFilter = null;
6102
6837
  this.minMax = null;
6838
+ this.columnLabel = "";
6103
6839
  this._minDraft = signal("");
6104
6840
  this._maxDraft = signal("");
6841
+ this._touched = signal(false);
6842
+ this.__rozieWatchInitial_0 = true;
6105
6843
  this._disconnectCleanups = [];
6106
6844
  this._rozieTornDown = false;
6845
+ this.minDraftValue = () => this._touched.value ? this._minDraft.value : Array.isArray(this.value) && this.value[0] != null ? String(this.value[0]) : "";
6846
+ this.maxDraftValue = () => this._touched.value ? this._maxDraft.value : Array.isArray(this.value) && this.value[1] != null ? String(this.value[1]) : "";
6107
6847
  this.onMinInput = (e) => {
6108
6848
  this._minDraft.value = e && e.target ? e.target.value : "";
6849
+ this._touched.value = true;
6109
6850
  };
6110
6851
  this.onMaxInput = (e) => {
6111
6852
  this._maxDraft.value = e && e.target ? e.target.value : "";
6853
+ this._touched.value = true;
6854
+ };
6855
+ this.onKeydown = (e) => {
6856
+ if (e && e.key === "Enter") this.applyRange(this.minDraftValue(), this.maxDraftValue());
6857
+ };
6858
+ this.onBlur = () => {
6859
+ this.applyRange(this.minDraftValue(), this.maxDraftValue());
6112
6860
  };
6113
6861
  this.minPlaceholder = () => Array.isArray(this.minMax) && this.minMax[0] != null ? String(this.minMax[0]) : "";
6114
6862
  this.maxPlaceholder = () => Array.isArray(this.minMax) && this.minMax[1] != null ? String(this.minMax[1]) : "";
6115
- this.applyRange = () => {
6116
- const minNum = this._minDraft.value === "" ? void 0 : Number(this._minDraft.value);
6117
- const maxNum = this._maxDraft.value === "" ? void 0 : Number(this._maxDraft.value);
6863
+ this.applyRange = (minDraft, maxDraft) => {
6864
+ const minNum = minDraft === "" ? void 0 : Number(minDraft);
6865
+ const maxNum = maxDraft === "" ? void 0 : Number(maxDraft);
6118
6866
  if (minNum === void 0 && maxNum === void 0) this.setFilter && this.setFilter(this.columnId, "");
6119
6867
  else this.setFilter && this.setFilter(this.columnId, [minNum, maxNum]);
6120
6868
  };
6869
+ this.a11yLabel = () => {
6870
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6871
+ return this.columnId;
6872
+ };
6121
6873
  }
6122
6874
  static {
6123
6875
  this.styles = css`
@@ -6125,8 +6877,16 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6125
6877
  `;
6126
6878
  }
6127
6879
  firstUpdated() {
6128
- this._minDraft.value = Array.isArray(this.value) && this.value[0] != null ? String(this.value[0]) : "";
6129
- this._maxDraft.value = Array.isArray(this.value) && this.value[1] != null ? String(this.value[1]) : "";
6880
+ this._disconnectCleanups.push(effect(() => {
6881
+ Array.isArray(this.value) && String(this.value[0]) + "" + String(this.value[1]);
6882
+ untracked(() => {
6883
+ if (this.__rozieWatchInitial_0) {
6884
+ this.__rozieWatchInitial_0 = false;
6885
+ return;
6886
+ }
6887
+ this._touched.value = false;
6888
+ });
6889
+ }));
6130
6890
  }
6131
6891
  disconnectedCallback() {
6132
6892
  super.disconnectedCallback();
@@ -6140,16 +6900,20 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6140
6900
  render() {
6141
6901
  return html`
6142
6902
  <span style="display:flex; align-items: center" data-rozie-s-97b2c090>
6143
- <input class="rdt-col-filter" part="col-filter" type="number" aria-label=${rozieAttr(this.columnId + " min")} placeholder=${rozieAttr(this.minPlaceholder())} .value=${this._minDraft.value} @input=${($event) => {
6903
+ <input class="rdt-col-filter" part="col-filter" type="number" aria-label=${rozieAttr(this.a11yLabel() + " min")} placeholder=${rozieAttr(this.minPlaceholder())} .value=${this.minDraftValue()} @input=${($event) => {
6144
6904
  this.onMinInput($event);
6145
- }} @change=${($event) => {
6146
- this.applyRange();
6905
+ }} @keydown=${($event) => {
6906
+ this.onKeydown($event);
6907
+ }} @blur=${($event) => {
6908
+ this.onBlur();
6147
6909
  }} data-rozie-s-97b2c090 />
6148
6910
  <span data-rozie-s-97b2c090> - </span>
6149
- <input class="rdt-col-filter" part="col-filter" type="number" aria-label=${rozieAttr(this.columnId + " max")} placeholder=${rozieAttr(this.maxPlaceholder())} .value=${this._maxDraft.value} @input=${($event) => {
6911
+ <input class="rdt-col-filter" part="col-filter" type="number" aria-label=${rozieAttr(this.a11yLabel() + " max")} placeholder=${rozieAttr(this.maxPlaceholder())} .value=${this.maxDraftValue()} @input=${($event) => {
6150
6912
  this.onMaxInput($event);
6151
- }} @change=${($event) => {
6152
- this.applyRange();
6913
+ }} @keydown=${($event) => {
6914
+ this.onKeydown($event);
6915
+ }} @blur=${($event) => {
6916
+ this.onBlur();
6153
6917
  }} data-rozie-s-97b2c090 />
6154
6918
  </span>
6155
6919
  `;
@@ -6163,6 +6927,10 @@ __decorate([property({ type: Object })], FilterNumberRange.prototype, "column",
6163
6927
  __decorate([property({ type: Object })], FilterNumberRange.prototype, "value", void 0);
6164
6928
  __decorate([property({ type: Function })], FilterNumberRange.prototype, "setFilter", void 0);
6165
6929
  __decorate([property({ type: Object })], FilterNumberRange.prototype, "minMax", void 0);
6930
+ __decorate([property({
6931
+ type: String,
6932
+ reflect: true
6933
+ })], FilterNumberRange.prototype, "columnLabel", void 0);
6166
6934
  FilterNumberRange = __decorate([customElement("rozie-filter-number-range")], FilterNumberRange);
6167
6935
  var FilterNumberRange_default = FilterNumberRange;
6168
6936
  //#endregion
@@ -6175,6 +6943,7 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6175
6943
  this.value = null;
6176
6944
  this.setFilter = null;
6177
6945
  this.uniqueValues = [];
6946
+ this.columnLabel = "";
6178
6947
  this._disconnectCleanups = [];
6179
6948
  this._rozieTornDown = false;
6180
6949
  this.selectValue = () => this.value != null ? String(this.value) : "";
@@ -6183,6 +6952,10 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6183
6952
  if (v === "") this.setFilter && this.setFilter(this.columnId, "");
6184
6953
  else this.setFilter && this.setFilter(this.columnId, v);
6185
6954
  };
6955
+ this.a11yLabel = () => {
6956
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6957
+ return this.columnId;
6958
+ };
6186
6959
  }
6187
6960
  static {
6188
6961
  this.styles = css`
@@ -6200,11 +6973,11 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6200
6973
  }
6201
6974
  render() {
6202
6975
  return html`
6203
- <select class="rdt-col-filter" part="col-filter" aria-label=${this.columnId} .value=${this.selectValue()} @change=${($event) => {
6976
+ <select class="rdt-col-filter" part="col-filter" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.selectValue()} @change=${($event) => {
6204
6977
  this.onChange($event);
6205
6978
  }} data-rozie-s-d75b42b2>
6206
6979
  <option value="" data-rozie-s-d75b42b2>All</option>
6207
- ${repeat(this.uniqueValues, (opt, _idx) => opt, (opt, _idx) => html`<option value=${rozieAttr(opt)} data-rozie-s-d75b42b2>${rozieDisplay(opt)}</option>`)}
6980
+ ${repeat(this.uniqueValues, (opt, _idx) => opt, (opt, _idx) => html`<option value=${rozieAttr(opt)} ?selected=${opt === this.selectValue()} data-rozie-s-d75b42b2>${rozieDisplay(opt)}</option>`)}
6208
6981
  </select>
6209
6982
  `;
6210
6983
  }
@@ -6217,6 +6990,10 @@ __decorate([property({ type: Object })], FilterSelect.prototype, "column", void
6217
6990
  __decorate([property({ type: Object })], FilterSelect.prototype, "value", void 0);
6218
6991
  __decorate([property({ type: Function })], FilterSelect.prototype, "setFilter", void 0);
6219
6992
  __decorate([property({ type: Array })], FilterSelect.prototype, "uniqueValues", void 0);
6993
+ __decorate([property({
6994
+ type: String,
6995
+ reflect: true
6996
+ })], FilterSelect.prototype, "columnLabel", void 0);
6220
6997
  FilterSelect = __decorate([customElement("rozie-filter-select")], FilterSelect);
6221
6998
  var FilterSelect_default = FilterSelect;
6222
6999
  //#endregion
@@ -6292,6 +7069,42 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6292
7069
  this.removeKey = (key) => {
6293
7070
  this.applyGrouping && this.applyGrouping(this.grouping.filter((k) => k !== key));
6294
7071
  };
7072
+ this.toggleKey = (id) => {
7073
+ if (!id) return;
7074
+ if (this.grouping.indexOf(id) !== -1) {
7075
+ this.removeKey(id);
7076
+ return;
7077
+ }
7078
+ this.applyGrouping && this.applyGrouping(this.grouping.concat([id]));
7079
+ };
7080
+ this.moveKey = (key, delta) => {
7081
+ const cur = this.grouping;
7082
+ const from = cur.indexOf(key);
7083
+ if (from === -1) return;
7084
+ const to = from + delta;
7085
+ if (to < 0 || to >= cur.length) return;
7086
+ const next = cur.slice();
7087
+ next.splice(from, 1);
7088
+ next.splice(to, 0, key);
7089
+ this.applyGrouping && this.applyGrouping(next);
7090
+ };
7091
+ this.onTokenKeydown = (e, gk) => {
7092
+ if (!e) return;
7093
+ const key = e.key;
7094
+ if (key === "Delete" || key === "Backspace") {
7095
+ e.preventDefault();
7096
+ this.removeKey(gk);
7097
+ return;
7098
+ }
7099
+ if (!e.altKey) return;
7100
+ if (key === "ArrowLeft") {
7101
+ e.preventDefault();
7102
+ this.moveKey(gk, -1);
7103
+ } else if (key === "ArrowRight") {
7104
+ e.preventDefault();
7105
+ this.moveKey(gk, 1);
7106
+ }
7107
+ };
6295
7108
  this.clearAll = () => {
6296
7109
  this.clearGrouping && this.clearGrouping();
6297
7110
  };
@@ -6320,6 +7133,18 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6320
7133
  border-color: var(--rdt-group-drop-zone-border-over, rgba(37, 99, 235, 0.7));
6321
7134
  background: var(--rdt-group-drop-zone-bg-over, rgba(37, 99, 235, 0.08));
6322
7135
  }
7136
+ .rdt-group-token-add[data-rozie-s-546c469a] {
7137
+ font: inherit;
7138
+ color: inherit;
7139
+ border: none;
7140
+ background: none;
7141
+ cursor: pointer;
7142
+ }
7143
+ .rdt-group-token-add[data-rozie-s-546c469a]:focus-visible,
7144
+ .rdt-group-drop-zone[data-rozie-s-546c469a] [data-group-token][data-rozie-s-546c469a]:focus-visible {
7145
+ outline: var(--rdt-focus-ring, 2px solid #2563eb);
7146
+ outline-offset: 1px;
7147
+ }
6323
7148
  .rdt-group-drop-hint[data-rozie-s-546c469a] {
6324
7149
  opacity: 0.55;
6325
7150
  font-size: 0.8125em;
@@ -6375,17 +7200,19 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6375
7200
  return html`
6376
7201
  <div class="rdt-group-bar" data-rozie-s-546c469a>
6377
7202
 
6378
- ${repeat(this.groupableColumns, (col, _idx) => col.id, (col, _idx) => html`<span class="rdt-group-token" part="group-token" draggable="true" @dragstart=${($event) => {
7203
+ ${repeat(this.groupableColumns, (col, _idx) => col.id, (col, _idx) => html`<button class="rdt-group-token rdt-group-token-add" type="button" part="group-token" draggable="true" aria-pressed=${rozieAttr(this.grouping.indexOf(col.id) !== -1 ? "true" : "false")} aria-label=${rozieAttr("Group by " + col.label)} @dragstart=${($event) => {
6379
7204
  this.onChipDragStart($event, col.id);
6380
7205
  }} @dragend=${($event) => {
6381
7206
  this.onDragEnd();
6382
- }} data-rozie-s-546c469a>${rozieDisplay(col.label)}</span>`)}
7207
+ }} @click=${($event) => {
7208
+ this.toggleKey(col.id);
7209
+ }} data-rozie-s-546c469a>${rozieDisplay(col.label)}</button>`)}
6383
7210
 
6384
7211
 
6385
7212
  <span class="${Object.entries({
6386
7213
  "rdt-group-drop-zone": true,
6387
7214
  "is-over": this._isOver.value
6388
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" data-group-drop-zone="" @dragover=${($event) => {
7215
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" data-group-drop-zone="" role="list" aria-label="Active grouping" @dragover=${($event) => {
6389
7216
  this.onDragOver($event);
6390
7217
  }} @dragleave=${($event) => {
6391
7218
  this.onDragLeave($event);
@@ -6396,12 +7223,14 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6396
7223
  ${!this.grouping.length ? html`<span class="rdt-group-drop-hint" data-rozie-s-546c469a>Drag columns here to group</span>` : nothing}${repeat(this.grouping, (gk, _idx) => gk, (gk, _idx) => html`<span class="${Object.entries({
6397
7224
  "rdt-group-token": true,
6398
7225
  "is-drop-target": this._dragKind.value === "token" && this._dropKey.value === gk && this._draggingId.value !== gk
6399
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" part="group-token" data-group-token="" draggable="true" @dragstart=${($event) => {
7226
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" part="group-token" data-group-token="" draggable="true" role="listitem" tabindex="0" aria-label=${rozieAttr(this.labelFor(gk) + " grouping, position " + (this.grouping.indexOf(gk) + 1) + " of " + this.grouping.length + ". Alt+Arrow to reorder, Delete to remove.")} @dragstart=${($event) => {
6400
7227
  this.onTokenDragStart($event, gk);
6401
7228
  }} @dragover=${($event) => {
6402
7229
  this.onTokenDragOver($event, gk);
6403
7230
  }} @dragend=${($event) => {
6404
7231
  this.onDragEnd();
7232
+ }} @keydown=${($event) => {
7233
+ this.onTokenKeydown($event, gk);
6405
7234
  }} data-rozie-s-546c469a>
6406
7235
  ${rozieDisplay(this.labelFor(gk))}
6407
7236
  <button class="rdt-group-token-remove" type="button" aria-label=${rozieAttr("Remove " + this.labelFor(gk) + " grouping")} @click=${($event) => {