@rozie-ui/data-table-lit 0.5.0 → 0.6.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,12 +1063,84 @@ 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
  };
978
1145
  this.virtualItemKey = (i) => {
979
1146
  const src = this.windowSource();
@@ -1080,6 +1247,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1080
1247
  }
1081
1248
  }
1082
1249
  this.bumpWindowVer();
1250
+ this.scheduleRemeasure();
1083
1251
  };
1084
1252
  this.virtualizerOptions = () => ({
1085
1253
  count: this.windowSource().length,
@@ -1252,20 +1420,29 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1252
1420
  if (filterChanged) return this.totalRowCount() + " results";
1253
1421
  return "";
1254
1422
  };
1423
+ this.rowIdOption = () => {
1424
+ const f = this.getRowId;
1425
+ return f ? (originalRow, index, parent) => this.isLazyPlaceholder(originalRow) ? this.LAZY_PLACEHOLDER_ROW_ID_PREFIX + originalRow.index : String(f(originalRow, index, parent)) : void 0;
1426
+ };
1427
+ this.rowSelectionOption = () => {
1428
+ if (this.selectionMode === "none") return false;
1429
+ return this.lazyRowsActive() ? (row) => !this.rowIsLazyPlaceholder(row) : true;
1430
+ };
1255
1431
  this.reFeed = () => {
1256
1432
  if (!this.table) return;
1257
1433
  this.table.setOptions((prev) => ({
1258
1434
  ...prev,
1259
- data: this.currentData(),
1435
+ data: this.feedData(),
1260
1436
  columns: this.tableColumns(),
1261
1437
  state: this.currentState(),
1262
- enableRowSelection: this.selectionMode !== "none",
1438
+ enableRowSelection: this.rowSelectionOption(),
1263
1439
  enableMultiRowSelection: this.selectionMode === "multiple",
1264
1440
  rowCount: this.rowCount ?? void 0,
1265
1441
  pageCount: this.pageCount ?? void 0,
1266
1442
  getExpandedRowModel: getExpandedRowModel(),
1267
1443
  getSubRows: this.getSubRows || void 0,
1268
- getRowCanExpand: this.expandable === true && this.getSubRows == null ? () => true : void 0,
1444
+ getRowId: this.rowIdOption(),
1445
+ getRowCanExpand: this.expandable === true && this.getSubRows == null ? (row) => !this.rowIsLazyPlaceholder(row) : void 0,
1269
1446
  onExpandedChange: this.onExpandedChangeCb,
1270
1447
  autoResetExpanded: false,
1271
1448
  getGroupedRowModel: getGroupedRowModel(),
@@ -1424,9 +1601,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1424
1601
  if (side === "right") return "position:sticky;right:" + (col.getAfter ? col.getAfter("right") : 0) + "px;z-index:" + zIndex + ";";
1425
1602
  return "";
1426
1603
  };
1427
- this.thStyle = (header) => {
1604
+ this.thStyle = (header, widthPx = null) => {
1428
1605
  let s = "";
1429
- const w = this.headerWidth(header);
1606
+ const w = widthPx != null && widthPx > 0 ? widthPx + "px" : this.headerWidth(header);
1430
1607
  if (w) s += "width:" + w + ";";
1431
1608
  s += this.pinStyle(header && header.column ? header.column.id : null, 2);
1432
1609
  return s;
@@ -1638,6 +1815,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1638
1815
  this.rowIndexOf = (row) => this.tick() >= 0 ? (this._rows.value || []).indexOf(row) : -1;
1639
1816
  this.colIndexOf = (row, cellCtx) => this.tick() >= 0 ? this.visibleCellsFor(row).indexOf(cellCtx) : -1;
1640
1817
  this.headerColIndexOf = (hg, header) => (hg && hg.headers ? hg.headers : []).indexOf(header);
1818
+ this.headerLeafStart = (hg, header) => {
1819
+ const list = hg && hg.headers ? hg.headers : [];
1820
+ let leaf = 0;
1821
+ for (let i = 0; i < list.length; i++) {
1822
+ if (list[i] === header) return leaf;
1823
+ const h = list[i];
1824
+ leaf = leaf + (h && h.colSpan > 1 ? h.colSpan : 1);
1825
+ }
1826
+ return -1;
1827
+ };
1641
1828
  this.pageRowOffset = () => {
1642
1829
  if (!this.isGrid() || this.rowsWindowed()) return 0;
1643
1830
  return this.pageIndex() * this.pageSize();
@@ -1681,14 +1868,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1681
1868
  const header = nextIsHeader == null ? this._activeIsHeader.value : nextIsHeader;
1682
1869
  const rowOut = this.rowsWindowed() && this.virtualizer && this.rowIsOutsideWindow(r);
1683
1870
  const colOut = this.colsWindowed() && this.colVirtualizer && this.colIsOutsideWindow(c);
1684
- if (!header && (rowOut || colOut)) {
1685
- if (rowOut) this.virtualizer.scrollToIndex(r, { align: "center" });
1871
+ const rowScroll = !header && rowOut;
1872
+ if (rowScroll || colOut) {
1873
+ if (rowScroll) this.virtualizer.scrollToIndex(r, { align: "center" });
1686
1874
  if (colOut) this.colVirtualizer.scrollToIndex(c, { align: "center" });
1687
1875
  let focusAttempts = 0;
1688
1876
  const myEpoch = this.focusIntentEpoch;
1689
1877
  const focusWhenReady = () => {
1690
1878
  if (this.focusIntentEpoch !== myEpoch) return;
1691
- const el = this.resolveCellEl(String(r), c);
1879
+ const el = this.resolveCellEl(header ? "__header" : String(r), c, header ? lvl : null);
1692
1880
  if (el) {
1693
1881
  el.focus();
1694
1882
  return;
@@ -1708,6 +1896,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1708
1896
  };
1709
1897
  this.totalRowCount = () => {
1710
1898
  if (!this.table) return (this._rows.value || []).length;
1899
+ if (this.manual === true) {
1900
+ if (this.rowCount != null) return this.rowCount;
1901
+ if (this.pageCount != null) return this.pageCount * this.pageSize();
1902
+ }
1711
1903
  const fm = this.table.getFilteredRowModel();
1712
1904
  return fm && fm.rows ? fm.rows.length : (this._rows.value || []).length;
1713
1905
  };
@@ -1715,6 +1907,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1715
1907
  this.gridAriaRowCount = () => this.headerRowCount() + this.totalRowCount();
1716
1908
  this.ariaPageOffset = () => this.table ? this.pageIndex() * this.pageSize() : 0;
1717
1909
  this.bodyAriaRowIndex = (row) => this.headerRowCount() + this.rowIndexOf(row) + this.ariaPageOffset() + 1;
1910
+ this.gridAriaColCount = () => this.visibleColCount();
1718
1911
  this.visibleColCount = () => {
1719
1912
  const rowList = this._rows.value || [];
1720
1913
  if (rowList.length) return rowList[0].getVisibleCells().length;
@@ -1885,6 +2078,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1885
2078
  const rowKey = this._activeIsHeader.value ? "__header" : String(this._activeRow.value);
1886
2079
  return this.resolveCellEl(rowKey, this._activeColIndex.value, this._activeIsHeader.value ? this._activeHeaderLevel.value : null);
1887
2080
  };
2081
+ this.activeCellHasControls = () => focusables(this.currentCellEl()).length > 0;
1888
2082
  this.enterControl = () => {
1889
2083
  const list = focusables(this.currentCellEl());
1890
2084
  if (!list.length) return;
@@ -1929,10 +2123,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1929
2123
  let nextLevel = prevLevel;
1930
2124
  if ((e.ctrlKey || e.metaKey) && e.shiftKey && !this._activeIsHeader.value && (key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight")) {
1931
2125
  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);
2126
+ if (key === "ArrowUp") this.extendRange(-this.rangeFocusRow(), 0);
2127
+ else if (key === "ArrowDown") this.extendRange(this.bodyRowCount() - 1 - this.rangeFocusRow(), 0);
2128
+ else if (key === "ArrowLeft") this.extendRange(0, -this.rangeFocusCol());
2129
+ else this.extendRange(0, this.visibleColCount() - 1 - this.rangeFocusCol());
1936
2130
  return;
1937
2131
  } else if ((e.ctrlKey || e.metaKey) && !this._activeIsHeader.value && (key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight")) {
1938
2132
  e.preventDefault();
@@ -2015,15 +2209,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2015
2209
  nextCol = en.col;
2016
2210
  nextIsHeader = false;
2017
2211
  } else nextCol = this.gotoColEdge(true);
2018
- } else if ((key === "c" || key === "C") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed()) {
2212
+ } else if ((key === "c" || key === "C") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed() && this.clipboardWriteAvailable()) {
2019
2213
  e.preventDefault();
2020
2214
  this.copyRange();
2021
2215
  return;
2022
- } else if ((key === "v" || key === "V") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed()) {
2216
+ } else if ((key === "v" || key === "V") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed() && this.clipboardReadAvailable()) {
2023
2217
  e.preventDefault();
2024
2218
  this.pasteRange();
2025
2219
  return;
2026
- } else if ((key === "x" || key === "X") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed()) {
2220
+ } else if ((key === "x" || key === "X") && (e.ctrlKey || e.metaKey) && this.clipboardActiveAllowed() && this.clipboardWriteAvailable()) {
2027
2221
  e.preventDefault();
2028
2222
  this.cutRange();
2029
2223
  return;
@@ -2053,6 +2247,23 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2053
2247
  e.preventDefault();
2054
2248
  if (!this._activeIsHeader.value) this.selectAllBody();
2055
2249
  return;
2250
+ } else if (key === " " && e.shiftKey && !e.ctrlKey && !e.metaKey && !this._activeIsHeader.value) {
2251
+ e.preventDefault();
2252
+ if (this.selectionMode !== "none") {
2253
+ const selRow = (this._rows.value || [])[this._activeRow.value];
2254
+ if (selRow && selRow.toggleSelected) selRow.toggleSelected(!this.rowIsSelected(selRow));
2255
+ }
2256
+ return;
2257
+ } else if (key === " " && (e.ctrlKey || e.metaKey) && !e.shiftKey && !this._activeIsHeader.value) {
2258
+ e.preventDefault();
2259
+ this.selectActiveColumn();
2260
+ return;
2261
+ } else if (key === "Escape") {
2262
+ if (this.rangeActive || this._rangeAnchor.value != null) {
2263
+ e.preventDefault();
2264
+ this.clearRange();
2265
+ }
2266
+ return;
2056
2267
  } else if (key === "F2" && e.shiftKey && this.isActiveCellEditable()) {
2057
2268
  e.preventDefault();
2058
2269
  this.beginRowEdit((this._rows.value || [])[this._activeRow.value]);
@@ -2078,6 +2289,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2078
2289
  this.onToggleExpand((this._rows.value || [])[this._activeRow.value], e);
2079
2290
  this.recoverGridFocus(String(grpRow), grpCol, null, true);
2080
2291
  return;
2292
+ } else if (key === "Enter" && !this._activeIsHeader.value && !this.activeCellHasControls()) {
2293
+ e.preventDefault();
2294
+ this.activateRowAt(this._activeRow.value, "keyboard");
2295
+ return;
2081
2296
  } else if (key === "Enter" || key === "F2") {
2082
2297
  e.preventDefault();
2083
2298
  this.enterControl();
@@ -2132,8 +2347,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2132
2347
  this._activeColIndex.value = col;
2133
2348
  if (isHeader !== prevIsHeader || col !== prevCol || (isHeader ? movedLevel !== prevLevel : movedRow !== prevRow)) this.focusIntentEpoch = this.focusIntentEpoch + 1;
2134
2349
  if (this.rangeTransition) this.rangeTransition = false;
2135
- else if (this.rangeClickPending) this.rangeClickPending = false;
2136
- else this.clearRange();
2350
+ else if (this.rangeClickPending && this.rangeClickPending.isHeader === isHeader && this.rangeClickPending.r === movedRow && this.rangeClickPending.c === col) this.rangeClickPending = null;
2351
+ else {
2352
+ this.rangeClickPending = null;
2353
+ this.clearRange();
2354
+ }
2137
2355
  if (tgt === cellEl) this._activeInControl.value = false;
2138
2356
  };
2139
2357
  this.onGridMouseDown = (e) => {
@@ -2154,9 +2372,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2154
2372
  this._activeIsHeader.value = false;
2155
2373
  this._activeRow.value = row;
2156
2374
  this._activeColIndex.value = col;
2157
- this.rangeClickPending = true;
2375
+ this.rangeClickPending = {
2376
+ isHeader: false,
2377
+ r: row,
2378
+ c: col
2379
+ };
2158
2380
  return;
2159
2381
  }
2382
+ if (this.isEditing(row, col)) return;
2160
2383
  this.beginRangeDrag(row, col);
2161
2384
  };
2162
2385
  this.onGridDblClick = (e) => {
@@ -2184,7 +2407,43 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2184
2407
  this.beginEdit(row, col, null);
2185
2408
  }
2186
2409
  };
2410
+ this.activateRowAt = (index, trigger) => {
2411
+ const row = (this._rows.value || [])[index];
2412
+ if (!row || this.rowIsGrouped(row) || this.rowIsLazyPlaceholder(row)) return;
2413
+ this.dispatchEvent(new CustomEvent("row-activate", {
2414
+ detail: {
2415
+ row: row.original,
2416
+ index,
2417
+ trigger
2418
+ },
2419
+ bubbles: true,
2420
+ composed: true
2421
+ }));
2422
+ };
2423
+ this.ROW_ACTIVATE_CONTROLS = "input, button, a[href], select, textarea, label, summary, [contenteditable=\"\"], [contenteditable=\"true\"], [role=\"button\"], [role=\"checkbox\"], [role=\"link\"], [data-editing-cell]";
2424
+ this.maybeActivateRowFromClick = (e) => {
2425
+ if (!e || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;
2426
+ if (this.rangeDragMoved) return;
2427
+ const tgt = e.target;
2428
+ if (!tgt || !tgt.closest) return;
2429
+ const cellEl = tgt.closest("[data-row]");
2430
+ if (!cellEl) return;
2431
+ const control = tgt.closest(this.ROW_ACTIVATE_CONTROLS);
2432
+ if (control && cellEl.contains(control)) return;
2433
+ const rowAttr = cellEl.getAttribute("data-row");
2434
+ if (rowAttr == null || rowAttr === "__header") return;
2435
+ const index = parseInt(rowAttr, 10);
2436
+ if (!Number.isFinite(index)) return;
2437
+ if (this.isGrid() && this.singleClickEdit) {
2438
+ const colAttr = cellEl.getAttribute("data-col-index");
2439
+ const col = colAttr == null ? NaN : parseInt(colAttr, 10);
2440
+ const colId = Number.isFinite(col) ? this.columnIdAt(index, col) : null;
2441
+ if (colId != null && this.columnEditable(colId)) return;
2442
+ }
2443
+ this.activateRowAt(index, "click");
2444
+ };
2187
2445
  this.onGridClick = (e) => {
2446
+ this.maybeActivateRowFromClick(e);
2188
2447
  if (!this.isGrid() || !e) return;
2189
2448
  if (!this.singleClickEdit) return;
2190
2449
  if (e.shiftKey) return;
@@ -2295,7 +2554,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2295
2554
  const headers = hg && hg.headers || [];
2296
2555
  if (!this.colsWindowed()) return headers.map((h) => ({
2297
2556
  header: h,
2298
- span: h && h.colSpan > 1 ? h.colSpan : 1
2557
+ span: h && h.colSpan > 1 ? h.colSpan : 1,
2558
+ width: null
2299
2559
  }));
2300
2560
  const idx = this.windowedColIndices();
2301
2561
  const idxSet = {};
@@ -2309,23 +2569,39 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2309
2569
  const end = cursor + leafCount;
2310
2570
  cursor = end;
2311
2571
  let span = 0;
2312
- for (let c = start; c < end; c++) if (idxSet[c]) span = span + 1;
2572
+ let width = 0;
2573
+ for (let c = start; c < end; c++) if (idxSet[c]) {
2574
+ span = span + 1;
2575
+ width = width + this.columnSize(c);
2576
+ }
2313
2577
  if (span > 0) out.push({
2314
2578
  header: h,
2315
- span
2579
+ span,
2580
+ width
2316
2581
  });
2317
2582
  }
2318
2583
  return out;
2319
2584
  };
2320
2585
  this.windowedColSpan = () => this.colsWindowed() ? this.windowedColIndices().length + 2 : this.visibleColCount();
2586
+ this.lastColSizeSig = 0;
2587
+ this.remeasureColumnSizes = () => {
2588
+ if (!this.colsWindowed() || !this.colVirtualizer || !this.colVirtualizer.measure) return;
2589
+ const n = this.columnCount();
2590
+ let sig = n;
2591
+ for (let i = 0; i < n; i++) sig = Math.imul(sig, 31) + this.columnSize(i) | 0;
2592
+ if (sig === this.lastColSizeSig) return;
2593
+ this.lastColSizeSig = sig;
2594
+ this.colVirtualizer.measure();
2595
+ };
2321
2596
  this.remeasureColumnWindow = () => {
2322
2597
  if (!this.colsWindowed() || !this.colVirtualizer) return;
2323
2598
  this.colVirtualizer.setOptions(this.columnVirtualizerOptions());
2599
+ this.remeasureColumnSizes();
2324
2600
  this.colVirtualizer._willUpdate();
2325
2601
  };
2326
2602
  this.gridEmptyFallback = false;
2327
2603
  this.rangeTransition = false;
2328
- this.rangeClickPending = false;
2604
+ this.rangeClickPending = null;
2329
2605
  this.rangeActive = false;
2330
2606
  this.inRange = (rIdx, cIdx) => {
2331
2607
  const a = this._rangeAnchor.value;
@@ -2367,7 +2643,17 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2367
2643
  const c1 = a.colIndex > f.colIndex ? a.colIndex : f.colIndex;
2368
2644
  return rIdx === r1 && cIdx === c1;
2369
2645
  };
2646
+ this.rangeSummary = (anchor, focus) => {
2647
+ if (!anchor || !focus) return "";
2648
+ const rows = Math.abs(focus.rowIndex - anchor.rowIndex) + 1;
2649
+ const cols = Math.abs(focus.colIndex - anchor.colIndex) + 1;
2650
+ if (rows === 1 && cols === 1) return "1 cell selected";
2651
+ const rowPart = rows + (rows === 1 ? " row" : " rows");
2652
+ const colPart = cols + (cols === 1 ? " column" : " columns");
2653
+ return rowPart + " by " + colPart + " selected, " + rows * cols + " cells";
2654
+ };
2370
2655
  this.emitRangeChange = (anchor, focus) => {
2656
+ this._rangeAnnounce.value = this.rangeSummary(anchor, focus);
2371
2657
  this.dispatchEvent(new CustomEvent("range-change", {
2372
2658
  detail: {
2373
2659
  anchor,
@@ -2410,11 +2696,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2410
2696
  this.focusActiveCell(nextRow, nextCol, false);
2411
2697
  if (!hadRange || nextRow !== focus.rowIndex || nextCol !== focus.colIndex) this.emitRangeChange(anchor, nextFocus);
2412
2698
  };
2413
- this.setRangeFocus = (rIdx, cIdx) => {
2699
+ this.setRangeFocus = (rIdx, cIdx, anchorR = null, anchorC = null) => {
2414
2700
  const maxRow = this.bodyRowCount() - 1;
2415
2701
  const maxCol = this.visibleColCount() - 1;
2416
2702
  if (maxRow < 0 || maxCol < 0) return;
2417
2703
  let anchor = this._rangeAnchor.value;
2704
+ if (!anchor && anchorR != null && anchorC != null) anchor = {
2705
+ rowIndex: clamp(Math.trunc(Number(anchorR)) || 0, 0, maxRow),
2706
+ colIndex: clamp(Math.trunc(Number(anchorC)) || 0, 0, maxCol)
2707
+ };
2418
2708
  if (!anchor) anchor = {
2419
2709
  rowIndex: this._activeRow.value,
2420
2710
  colIndex: this._activeColIndex.value
@@ -2445,6 +2735,32 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2445
2735
  this.rangeActive = true;
2446
2736
  this.emitRangeChange(anchor, focus);
2447
2737
  };
2738
+ this.rangeFocusRow = () => {
2739
+ const f = this._rangeFocus.value;
2740
+ return f && f.rowIndex != null ? f.rowIndex : this._activeRow.value;
2741
+ };
2742
+ this.rangeFocusCol = () => {
2743
+ const f = this._rangeFocus.value;
2744
+ return f && f.colIndex != null ? f.colIndex : this._activeColIndex.value;
2745
+ };
2746
+ this.selectActiveColumn = () => {
2747
+ const maxRow = this.bodyRowCount() - 1;
2748
+ const maxCol = this.visibleColCount() - 1;
2749
+ if (maxRow < 0 || maxCol < 0) return;
2750
+ const c = clamp(Math.trunc(Number(this._activeColIndex.value)) || 0, 0, maxCol);
2751
+ const anchor = {
2752
+ rowIndex: 0,
2753
+ colIndex: c
2754
+ };
2755
+ const focus = {
2756
+ rowIndex: maxRow,
2757
+ colIndex: c
2758
+ };
2759
+ this._rangeAnchor.value = anchor;
2760
+ this._rangeFocus.value = focus;
2761
+ this.rangeActive = true;
2762
+ this.emitRangeChange(anchor, focus);
2763
+ };
2448
2764
  this.clearRange = () => {
2449
2765
  if (!this.rangeActive) return;
2450
2766
  this.rangeActive = false;
@@ -2524,6 +2840,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2524
2840
  }
2525
2841
  return lines.join("\n");
2526
2842
  };
2843
+ this.clipboardWriteAvailable = () => typeof navigator !== "undefined" && !!navigator.clipboard && typeof navigator.clipboard.writeText === "function";
2844
+ this.clipboardReadAvailable = () => typeof navigator !== "undefined" && !!navigator.clipboard && typeof navigator.clipboard.readText === "function";
2527
2845
  this.copyRange = () => {
2528
2846
  if (!this.clipboardActiveAllowed()) return;
2529
2847
  if (typeof navigator === "undefined" || !navigator.clipboard || !navigator.clipboard.writeText) return;
@@ -2532,27 +2850,30 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2532
2850
  if (p && p.catch) p.catch(() => {});
2533
2851
  } catch (err) {}
2534
2852
  };
2535
- this.applyGridToRange = (grid, originRow, originCol) => {
2853
+ this.applyGridToRange = (grid, originRow, originCol, verb) => {
2854
+ const opVerb = typeof verb === "string" && verb !== "" ? verb : "pasted";
2536
2855
  const maxRow = this.bodyRowCount() - 1;
2537
2856
  const maxCol = this.visibleColCount() - 1;
2538
2857
  if (maxRow < 0 || maxCol < 0) return {
2539
2858
  wrote: 0,
2859
+ changed: 0,
2540
2860
  total: 0
2541
2861
  };
2542
2862
  let total = 0;
2543
- let wrote = 0;
2863
+ let applied = 0;
2544
2864
  const committed = [];
2545
2865
  let next = this.currentData();
2546
2866
  for (let gr = 0; gr < grid.length; gr++) {
2547
2867
  const r = originRow + gr;
2548
2868
  if (r > maxRow) break;
2549
2869
  const rowGrouped = this.rowIndexIsGrouped(r);
2870
+ const rowPlaceholder = this.rowIsLazyPlaceholder((this._rows.value || [])[r]);
2550
2871
  const cols = grid[gr] || [];
2551
2872
  for (let gc = 0; gc < cols.length; gc++) {
2552
2873
  const c = originCol + gc;
2553
2874
  if (c > maxCol) break;
2554
2875
  total = total + 1;
2555
- if (rowGrouped) continue;
2876
+ if (rowGrouped || rowPlaceholder) continue;
2556
2877
  const colId = this.columnIdAt(r, c);
2557
2878
  if (colId == null || !this.columnEditable(colId)) continue;
2558
2879
  const rowObj = this.rowOriginalAt(r);
@@ -2561,6 +2882,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2561
2882
  const field = this.fieldOfColId(colId);
2562
2883
  const srcIndex = this.sourceIndexOfRow(r);
2563
2884
  const oldValue = rowObj ? rowObj[field] : null;
2885
+ applied = applied + 1;
2886
+ if (oldValue === value) continue;
2564
2887
  next = replaceRowValue(next, srcIndex, field, value);
2565
2888
  committed.push({
2566
2889
  rowId: this.rowIdAt(r),
@@ -2568,23 +2891,27 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2568
2891
  oldValue,
2569
2892
  newValue: value
2570
2893
  });
2571
- wrote = wrote + 1;
2572
2894
  }
2573
2895
  }
2574
- if (wrote > 0) {
2896
+ if (committed.length > 0) {
2575
2897
  this.editTransition = true;
2576
2898
  this.writeData(next);
2577
2899
  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
- }));
2900
+ for (let i = 0; i < committed.length; i++) try {
2901
+ this.dispatchEvent(new CustomEvent("cell-edit-commit", {
2902
+ detail: committed[i],
2903
+ bubbles: true,
2904
+ composed: true
2905
+ }));
2906
+ } catch (err) {
2907
+ 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);
2908
+ }
2583
2909
  }
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");
2910
+ if (applied > 0) this.announce(applied + " of " + total + " cells " + opVerb);
2911
+ else if (total > 0) this.announce("No cells " + opVerb + " — " + total + " cells were invalid or read-only");
2586
2912
  return {
2587
- wrote,
2913
+ wrote: applied,
2914
+ changed: committed.length,
2588
2915
  total
2589
2916
  };
2590
2917
  };
@@ -2616,11 +2943,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2616
2943
  }
2617
2944
  if (!p || !p.then) return;
2618
2945
  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(() => {});
2946
+ try {
2947
+ const grid = parseTsv(text);
2948
+ if (!grid.length) return;
2949
+ const tiled = tileGridToBox(grid, destBox);
2950
+ this.applyGridToRange(tiled, anchorRow, anchorCol, "pasted");
2951
+ } catch (err) {
2952
+ console.error("[rozie-data-table] paste failed: a row accessor, the data model setter or other consumer code threw. The paste was abandoned.", err);
2953
+ }
2954
+ }, () => {});
2624
2955
  };
2625
2956
  this.cutRange = () => {
2626
2957
  if (!this.clipboardActiveAllowed()) return;
@@ -2639,7 +2970,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2639
2970
  for (let c = c0; c <= c1; c++) cols.push("");
2640
2971
  grid.push(cols);
2641
2972
  }
2642
- this.applyGridToRange(grid, r0, c0);
2973
+ this.applyGridToRange(grid, r0, c0, "cut");
2643
2974
  };
2644
2975
  this.clearActiveRange = () => {
2645
2976
  if (!this.clipboardActiveAllowed()) return;
@@ -2654,7 +2985,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2654
2985
  for (let c = c0; c <= c1; c++) cols.push("");
2655
2986
  grid.push(cols);
2656
2987
  }
2657
- this.applyGridToRange(grid, r0, c0);
2988
+ this.applyGridToRange(grid, r0, c0, "cleared");
2658
2989
  };
2659
2990
  this.fillRange = (sourceBox, endCell) => {
2660
2991
  let box;
@@ -2692,7 +3023,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2692
3023
  }
2693
3024
  grid.push(cols);
2694
3025
  }
2695
- this.applyGridToRange(grid, box.r0, box.c0);
3026
+ this.applyGridToRange(grid, box.r0, box.c0, "filled");
2696
3027
  };
2697
3028
  this.fillDragging = false;
2698
3029
  this.fillDragMove = null;
@@ -2854,7 +3185,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2854
3185
  if (cell && (cell.r !== lastCell.r || cell.c !== lastCell.c)) {
2855
3186
  lastCell = cell;
2856
3187
  this.rangeDragMoved = true;
2857
- this.setRangeFocus(cell.r, cell.c);
3188
+ this.setRangeFocus(cell.r, cell.c, anchorR, anchorC);
2858
3189
  }
2859
3190
  };
2860
3191
  const up = () => {
@@ -2876,6 +3207,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2876
3207
  };
2877
3208
  this.isActiveCellEditable = () => {
2878
3209
  if (this.rowIndexIsGrouped(this._activeRow.value)) return false;
3210
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[this._activeRow.value])) return false;
2879
3211
  const colId = this.activeCellColumnId();
2880
3212
  return colId != null && this.columnEditable(colId);
2881
3213
  };
@@ -2987,12 +3319,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2987
3319
  };
2988
3320
  this.beginEdit = (rowIndex, colIndex, seed) => {
2989
3321
  if (this.rowIndexIsGrouped(rowIndex)) return;
3322
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[rowIndex])) return;
2990
3323
  const colId = this.columnIdAt(rowIndex, colIndex);
2991
3324
  if (colId == null || !this.columnEditable(colId)) return;
2992
3325
  this.committedThisSession = false;
2993
3326
  this.setInvalid("");
2994
3327
  this._editingRowIndex.value = null;
2995
3328
  this._rowDraft.value = {};
3329
+ this.rowDraftSync = {};
2996
3330
  this._editingRow.value = rowIndex;
2997
3331
  this._editingCol.value = colIndex;
2998
3332
  this._draftValue.value = seed != null ? seed : this.cellValueAt(rowIndex, colIndex);
@@ -3035,6 +3369,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3035
3369
  this.endRowEdit = () => {
3036
3370
  this._editingRowIndex.value = null;
3037
3371
  this._rowDraft.value = {};
3372
+ this.rowDraftSync = {};
3038
3373
  this._invalidMsg.value = "";
3039
3374
  this._activeInControl.value = false;
3040
3375
  this._editVer.value = this._editVer.value + 1;
@@ -3048,7 +3383,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3048
3383
  return this._editFocusColId.value != null && this._editFocusColId.value === colId;
3049
3384
  };
3050
3385
  this.coerceCellValue = (colId, raw) => {
3051
- if (this.editorTypeOf(colId) !== "number") return raw;
3386
+ const kind = this.editorTypeOf(colId);
3387
+ if (kind === "checkbox") {
3388
+ if (typeof raw === "boolean") return raw;
3389
+ if (raw == null) return false;
3390
+ if (typeof raw === "number") return raw !== 0;
3391
+ return /^\s*(true|1|yes|y|on)\s*$/i.test(String(raw));
3392
+ }
3393
+ if (kind !== "number") return raw;
3052
3394
  if (raw == null) return null;
3053
3395
  if (typeof raw === "number") return Number.isNaN(raw) ? null : raw;
3054
3396
  const s = String(raw).trim();
@@ -3110,10 +3452,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3110
3452
  };
3111
3453
  this.toggleActiveBooleanCell = () => {
3112
3454
  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
3455
  const row = (this._rows.value || [])[this._activeRow.value];
3116
3456
  if (!row) return;
3457
+ if (this.rowIsLazyPlaceholder(row)) return;
3458
+ const colId = this.columnIdAt(this._activeRow.value, this._activeColIndex.value);
3459
+ if (colId == null || !this.columnEditable(colId)) return;
3117
3460
  const rowOriginal = row.original;
3118
3461
  const rowId = row.id;
3119
3462
  const oldValue = this.cellValueAt(this._activeRow.value, this._activeColIndex.value);
@@ -3199,6 +3542,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3199
3542
  const rowIndex = this.rowIndexOf(row);
3200
3543
  if (rowIndex < 0) return;
3201
3544
  if (this.rowIndexIsGrouped(rowIndex)) return;
3545
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[rowIndex])) return;
3202
3546
  const editable = this.editableColumnsForRow(rowIndex);
3203
3547
  if (editable.length === 0) return;
3204
3548
  this.committedThisSession = false;
@@ -3214,6 +3558,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3214
3558
  draft[ec.colId] = orig ? orig[ec.field] : null;
3215
3559
  }
3216
3560
  this._rowDraft.value = draft;
3561
+ this.rowDraftSync = draft;
3217
3562
  this._editingRowIndex.value = rowIndex;
3218
3563
  this._activeInControl.value = true;
3219
3564
  this._editVer.value = this._editVer.value + 1;
@@ -3231,7 +3576,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3231
3576
  const r = (this._rows.value || [])[rowIndex];
3232
3577
  const rowOriginal = r ? r.original : null;
3233
3578
  const rowId = r ? r.id : null;
3234
- const draft = this._rowDraft.value || {};
3579
+ const draft = this.rowDraftSync || {};
3235
3580
  for (let i = 0; i < editable.length; i++) {
3236
3581
  const ec = editable[i];
3237
3582
  const err = this.runValidator(ec.colId, this.coerceCellValue(ec.colId, draft[ec.colId]), rowOriginal);
@@ -3344,6 +3689,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3344
3689
  this.editTransition = false;
3345
3690
  this.pendingEditFollow = null;
3346
3691
  this.committedThisSession = false;
3692
+ this.rowDraftSync = {};
3693
+ this.dropinTabFlush = null;
3347
3694
  this.inRowEdit = () => this._editingRowIndex.value != null;
3348
3695
  this.editorValueFor = (colId) => this.inRowEdit() ? this._rowDraft.value ? this._rowDraft.value[colId] : null : this._draftValue.value;
3349
3696
  this.editorCheckedFor = (colId) => !!(this.inRowEdit() ? this._rowDraft.value ? this._rowDraft.value[colId] : null : this._draftValue.value);
@@ -3352,6 +3699,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3352
3699
  this.setRowDraft(colId, value);
3353
3700
  return;
3354
3701
  }
3702
+ if (this.dropinTabFlush) {
3703
+ this.dropinTabFlush.called = true;
3704
+ if (this.commitEdit(value, true)) this.dropinTabFlush.committed = true;
3705
+ return;
3706
+ }
3355
3707
  this.commitEdit(value);
3356
3708
  };
3357
3709
  this.editorCancelFor = () => () => {
@@ -3378,10 +3730,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3378
3730
  this._draftValue.value = v;
3379
3731
  };
3380
3732
  this.setRowDraft = (colId, value) => {
3381
- const src = this._rowDraft.value || {};
3733
+ const src = this.rowDraftSync || {};
3382
3734
  const next = {};
3383
3735
  for (const k in src) next[k] = src[k];
3384
3736
  next[colId] = value;
3737
+ this.rowDraftSync = next;
3385
3738
  this._rowDraft.value = next;
3386
3739
  };
3387
3740
  this.rowEditTab = (target, backward) => {
@@ -3436,6 +3789,56 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3436
3789
  this.cancelEdit();
3437
3790
  }
3438
3791
  };
3792
+ this.onEditorDropinKeyDown = (e) => {
3793
+ if (!e) return;
3794
+ const key = e.key;
3795
+ if (this.inRowEdit()) {
3796
+ if (key === "Enter") {
3797
+ e.preventDefault();
3798
+ this.commitRow();
3799
+ return;
3800
+ }
3801
+ if (key === "Escape") {
3802
+ e.preventDefault();
3803
+ this.cancelRow();
3804
+ return;
3805
+ }
3806
+ if (key === "Tab") {
3807
+ e.preventDefault();
3808
+ this.rowEditTab(e.target, e.shiftKey);
3809
+ return;
3810
+ }
3811
+ return;
3812
+ }
3813
+ if (key !== "Tab" || e.defaultPrevented) return;
3814
+ e.preventDefault();
3815
+ const fromRow = this._editingRow.value;
3816
+ const fromCol = this._editingCol.value;
3817
+ const target = e.shiftKey ? this.prevEditableCell(fromRow, fromCol) : this.nextEditableCell(fromRow, fromCol);
3818
+ const el = e.target;
3819
+ const ownCell = el && el.closest ? el.closest("[data-grid-cell]") : null;
3820
+ const flush = {
3821
+ called: false,
3822
+ committed: false
3823
+ };
3824
+ this.dropinTabFlush = flush;
3825
+ if (ownCell && ownCell.focus) ownCell.focus();
3826
+ else if (el && el.blur) el.blur();
3827
+ this.dropinTabFlush = null;
3828
+ if (!flush.called) {
3829
+ this.onEditorKeyDown(e);
3830
+ return;
3831
+ }
3832
+ if (!flush.committed) {
3833
+ if (el && el.focus) el.focus();
3834
+ return;
3835
+ }
3836
+ if (target) {
3837
+ this._activeRow.value = target.row;
3838
+ this._activeColIndex.value = target.col;
3839
+ this.beginEdit(target.row, target.col, null);
3840
+ } else this.focusCellWhenReady(fromRow, fromCol);
3841
+ };
3439
3842
  this.onEditorBlur = (e) => {
3440
3843
  if (this.inRowEdit()) {
3441
3844
  if (this.editTransition) return;
@@ -3448,13 +3851,20 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3448
3851
  }
3449
3852
  if (this._editingRow.value < 0 || this.editTransition) return;
3450
3853
  const next = e ? e.relatedTarget : null;
3451
- if (next == null) return;
3854
+ const fromCell = e && e.target && e.target.closest ? e.target.closest("[data-grid-cell]") : null;
3855
+ if (next == null) {
3856
+ if (!this.outsidePointerDown) return;
3857
+ this.outsidePointerDown = false;
3858
+ if (!fromCell) return;
3859
+ if (fromCell.getAttribute("data-row") !== String(this._editingRow.value) || fromCell.getAttribute("data-col-index") !== String(this._editingCol.value)) return;
3860
+ this.commitEdit(void 0, true);
3861
+ return;
3862
+ }
3452
3863
  if (!(this.gridRoot && this.gridRoot.contains && this.gridRoot.contains(next))) {
3453
3864
  this.commitEdit(void 0);
3454
3865
  return;
3455
3866
  }
3456
3867
  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
3868
  if (!nextCell || !fromCell || nextCell === fromCell) return;
3459
3869
  const fromRow = fromCell.getAttribute("data-row");
3460
3870
  const fromCol = fromCell.getAttribute("data-col-index");
@@ -3633,32 +4043,30 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3633
4043
  this.styles = css`
3634
4044
  :host{display:contents}
3635
4045
  :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);
4046
+ --rdt-color: var(--rozie-data-table-fg, var(--rdt-ds-fg));
4047
+ --rdt-select-accent: var(--rozie-data-table-select-accent, var(--rozie-data-table-accent, var(--rdt-ds-select-accent)));
4048
+ --rdt-border: 1px solid var(--rozie-data-table-border-color, var(--rdt-ds-border-color));
4049
+ --rdt-filter-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4050
+ --rdt-filter-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4051
+ --rdt-font: var(--rozie-data-table-font, var(--rdt-ds-font));
4052
+ --rdt-cell-padding: var(--rozie-data-table-cell-padding, var(--rdt-ds-cell-padding));
4053
+ --rdt-header-bg: var(--rozie-data-table-header-bg, var(--rdt-ds-header-bg));
4054
+ --rdt-header-weight: var(--rozie-data-table-header-weight, var(--rdt-ds-header-weight));
4055
+ --rdt-sort-ind-opacity: var(--rozie-data-table-sort-indicator-opacity, var(--rdt-ds-sort-indicator-opacity));
4056
+ --rdt-resize-grip-color: var(--rozie-data-table-resize-grip-color, var(--rdt-ds-resize-grip-color));
4057
+ --rdt-resize-grip-active: var(--rozie-data-table-resize-grip-active, var(--rozie-data-table-accent, var(--rdt-ds-resize-grip-active)));
4058
+ --rdt-pin-btn-active-bg: var(--rozie-data-table-pin-active-bg, var(--rdt-ds-pin-active-bg));
4059
+ --rdt-colvis-menu-bg: var(--rozie-data-table-menu-bg, var(--rdt-ds-menu-bg));
4060
+ --rdt-colvis-menu-shadow: var(--rozie-data-table-menu-shadow, var(--rdt-ds-menu-shadow));
4061
+ --rdt-colvis-menu-border: 1px solid var(--rozie-data-table-border-color, var(--rdt-ds-border-color));
4062
+ --rdt-colvis-menu-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4063
+ --rdt-colvis-summary-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4064
+ --rdt-colvis-summary-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4065
+ --rdt-page-btn-disabled-opacity: var(--rozie-data-table-disabled-opacity, var(--rdt-ds-disabled-opacity));
4066
+ --rdt-page-btn-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4067
+ --rdt-page-btn-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
4068
+ --rdt-page-size-border: 1px solid var(--rozie-data-table-control-border-color, var(--rdt-ds-control-border-color));
4069
+ --rdt-page-size-radius: var(--rozie-data-table-radius, var(--rdt-ds-radius));
3662
4070
  }
3663
4071
  .rozie-data-table[data-rozie-s-d5dcab4c] {
3664
4072
  border-collapse: collapse;
@@ -3794,6 +4202,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3794
4202
  flex-direction: column;
3795
4203
  gap: var(--rdt-chrome-gap, 0.5rem);
3796
4204
  }
4205
+ .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-skeleton[data-rozie-s-d5dcab4c] {
4206
+ /* inline-block on the cell's own line box, exactly like a text value (a block box was 2px
4207
+ short of a text row). */
4208
+ display: inline-block;
4209
+ width: 100%;
4210
+ vertical-align: baseline;
4211
+ border-radius: 4px;
4212
+ background: color-mix(in srgb, currentColor 12%, transparent);
4213
+ color: transparent;
4214
+ }
3797
4215
  .rozie-data-table-wrap[data-rozie-s-d5dcab4c] .rdt-toolbar[data-rozie-s-d5dcab4c] {
3798
4216
  display: flex;
3799
4217
  gap: var(--rdt-toolbar-gap, 0.5rem);
@@ -3832,6 +4250,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3832
4250
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-filter-row[data-rozie-s-d5dcab4c] {
3833
4251
  background: var(--rdt-filter-row-bg, rgba(0, 0, 0, 0.015));
3834
4252
  }
4253
+ .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-pinned[data-rozie-s-d5dcab4c] {
4254
+ box-sizing: border-box;
4255
+ }
3835
4256
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-filter-cell[data-rozie-s-d5dcab4c] {
3836
4257
  padding: var(--rdt-filter-cell-padding, 0.35rem 0.75rem);
3837
4258
  border-bottom: var(--rdt-border, 1px solid rgba(0, 0, 0, 0.08));
@@ -3951,6 +4372,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3951
4372
  .rozie-data-table-wrap[data-rozie-s-d5dcab4c] .rdt-colvis-summary[data-rozie-s-d5dcab4c] {
3952
4373
  cursor: pointer;
3953
4374
  font: inherit;
4375
+ /* Own the margin too: content-site typography styles bare \`summary\` (VitePress sets
4376
+ \`margin: 16px 0\`), which grew the <details> and stretched the toolbar's search input. */
4377
+ margin: 0;
3954
4378
  padding: var(--rdt-colvis-summary-padding, 0.25rem 0.6rem);
3955
4379
  border: var(--rdt-colvis-summary-border, 1px solid rgba(0, 0, 0, 0.2));
3956
4380
  border-radius: var(--rdt-colvis-summary-radius, 4px);
@@ -3989,6 +4413,51 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3989
4413
  text-align: var(--rdt-expander-col-align, center);
3990
4414
  white-space: nowrap;
3991
4415
  }
4416
+ .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,
4417
+ .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,
4418
+ .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,
4419
+ .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,
4420
+ .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,
4421
+ .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,
4422
+ .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,
4423
+ .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 {
4424
+ content: '';
4425
+ display: inline-block;
4426
+ vertical-align: middle;
4427
+ }
4428
+ .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 {
4429
+ width: calc(1 * var(--rdt-tree-indent, 1.25rem));
4430
+ }
4431
+ .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 {
4432
+ width: calc(2 * var(--rdt-tree-indent, 1.25rem));
4433
+ }
4434
+ .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 {
4435
+ width: calc(3 * var(--rdt-tree-indent, 1.25rem));
4436
+ }
4437
+ .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 {
4438
+ width: calc(4 * var(--rdt-tree-indent, 1.25rem));
4439
+ }
4440
+ .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 {
4441
+ width: calc(5 * var(--rdt-tree-indent, 1.25rem));
4442
+ }
4443
+ .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 {
4444
+ width: calc(6 * var(--rdt-tree-indent, 1.25rem));
4445
+ }
4446
+ .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 {
4447
+ width: calc(7 * var(--rdt-tree-indent, 1.25rem));
4448
+ }
4449
+ .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 {
4450
+ width: calc(8 * var(--rdt-tree-indent, 1.25rem));
4451
+ }
4452
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] {
4453
+ user-select: none;
4454
+ }
4455
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] input[data-rozie-s-d5dcab4c],
4456
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] textarea[data-rozie-s-d5dcab4c],
4457
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] select[data-rozie-s-d5dcab4c],
4458
+ .rozie-data-table[role="grid"][data-rozie-s-d5dcab4c] [contenteditable="true"][data-rozie-s-d5dcab4c] {
4459
+ user-select: text;
4460
+ }
3992
4461
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-select-all[data-rozie-s-d5dcab4c],
3993
4462
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-select-row[data-rozie-s-d5dcab4c] {
3994
4463
  cursor: pointer;
@@ -4052,6 +4521,17 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4052
4521
  update();
4053
4522
  }
4054
4523
  }
4524
+ {
4525
+ const slotEl = this.shadowRoot?.querySelector("slot[name=\"placeholder\"]");
4526
+ if (slotEl !== null && slotEl !== void 0) {
4527
+ const update = () => {
4528
+ this._hasSlotPlaceholder = this._slotPlaceholderElements.length > 0;
4529
+ };
4530
+ slotEl.addEventListener("slotchange", update);
4531
+ this._disconnectCleanups.push(() => slotEl.removeEventListener("slotchange", update));
4532
+ update();
4533
+ }
4534
+ }
4055
4535
  {
4056
4536
  const slotEl = this.shadowRoot?.querySelector("slot[name=\"selectCell\"]");
4057
4537
  if (slotEl !== null && slotEl !== void 0) {
@@ -4147,6 +4627,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4147
4627
  this._hasSlotSelectAll = Array.from(this.children).some((el) => el.getAttribute("slot") === "selectAll");
4148
4628
  this._hasSlotDynamicColHeader = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4149
4629
  this._hasSlotDynamicFilter = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4630
+ this._hasSlotPlaceholder = Array.from(this.children).some((el) => el.getAttribute("slot") === "placeholder");
4150
4631
  this._hasSlotSelectCell = Array.from(this.children).some((el) => el.getAttribute("slot") === "selectCell");
4151
4632
  this._hasSlotDynamicCell = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4152
4633
  this._hasSlotDynamicEditor = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
@@ -4164,12 +4645,22 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4164
4645
  firstUpdated() {
4165
4646
  this._armListeners();
4166
4647
  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;
4648
+ this._windowVer.value;
4168
4649
  untracked(() => {
4169
4650
  if (this.__rozieWatchInitial_0) {
4170
4651
  this.__rozieWatchInitial_0 = false;
4171
4652
  return;
4172
4653
  }
4654
+ this.emitVisibleRangeIfChanged();
4655
+ });
4656
+ }));
4657
+ this._disconnectCleanups.push(effect(() => {
4658
+ 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;
4659
+ untracked(() => {
4660
+ if (this.__rozieWatchInitial_1) {
4661
+ this.__rozieWatchInitial_1 = false;
4662
+ return;
4663
+ }
4173
4664
  (() => {
4174
4665
  this.seedColumnPinning();
4175
4666
  this.reFeed();
@@ -4180,8 +4671,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4180
4671
  this._disconnectCleanups.push(effect(() => {
4181
4672
  this.sorting, this.columnFilters, this.globalFilter, this._sortingDefault.value, this._columnFiltersDefault.value, this._globalFilterDefault.value;
4182
4673
  untracked(() => {
4183
- if (this.__rozieWatchInitial_1) {
4184
- this.__rozieWatchInitial_1 = false;
4674
+ if (this.__rozieWatchInitial_2) {
4675
+ this.__rozieWatchInitial_2 = false;
4185
4676
  return;
4186
4677
  }
4187
4678
  (() => {
@@ -4197,6 +4688,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4197
4688
  if (id == null) return;
4198
4689
  const key = String(id);
4199
4690
  if (key === "__proto__" || key === "constructor" || key === "prototype") return;
4691
+ const prev = __rozieCtxHost._colReg.value ? __rozieCtxHost._colReg.value[key] : void 0;
4692
+ if (prev !== void 0 && columnSpecsEquivalent(prev, spec)) return;
4200
4693
  __rozieCtxHost._colReg.value = {
4201
4694
  ...__rozieCtxHost._colReg.value,
4202
4695
  [key]: spec
@@ -4213,7 +4706,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4213
4706
  this._dataDefault.value = this.data || [];
4214
4707
  this.seedColumnPinning();
4215
4708
  this.table = createTable({
4216
- data: this.currentData(),
4709
+ data: this.feedData(),
4217
4710
  columns: this.tableColumns(),
4218
4711
  state: this.currentState(),
4219
4712
  getCoreRowModel: getCoreRowModel(),
@@ -4222,7 +4715,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4222
4715
  getPaginationRowModel: getPaginationRowModel(),
4223
4716
  getExpandedRowModel: getExpandedRowModel(),
4224
4717
  getSubRows: this.getSubRows || void 0,
4225
- getRowCanExpand: this.expandable === true && this.getSubRows == null ? () => true : void 0,
4718
+ getRowId: this.rowIdOption(),
4719
+ getRowCanExpand: this.expandable === true && this.getSubRows == null ? (row) => !this.rowIsLazyPlaceholder(row) : void 0,
4226
4720
  onExpandedChange: this.onExpandedChangeCb,
4227
4721
  autoResetExpanded: false,
4228
4722
  getGroupedRowModel: getGroupedRowModel(),
@@ -4235,7 +4729,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4235
4729
  manualSorting: this.manual === true,
4236
4730
  rowCount: this.rowCount ?? void 0,
4237
4731
  pageCount: this.pageCount ?? void 0,
4238
- enableRowSelection: this.selectionMode !== "none",
4732
+ enableRowSelection: this.rowSelectionOption(),
4239
4733
  enableMultiRowSelection: this.selectionMode === "multiple",
4240
4734
  onSortingChange: this.onSortingChangeCb,
4241
4735
  onGlobalFilterChange: this.onGlobalFilterChangeCb,
@@ -4260,6 +4754,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4260
4754
  this._headerGroups.value = nextGroups;
4261
4755
  this._rowModelVer.value = this._rowModelVer.value + 1;
4262
4756
  if (this.rowsWindowed() && this.virtualizer) {
4757
+ this.migratePlaceholderSizeCache();
4263
4758
  this.virtualizer.setOptions(this.virtualizerOptions());
4264
4759
  this.virtualizer._willUpdate();
4265
4760
  }
@@ -4285,6 +4780,18 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4285
4780
  };
4286
4781
  this.refreshRowModel();
4287
4782
  this.gridRoot = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rozie-data-table") : null;
4783
+ if (typeof document !== "undefined") {
4784
+ this.docPointerDown = (ev) => {
4785
+ if (!this.gridRoot) {
4786
+ this.outsidePointerDown = false;
4787
+ return;
4788
+ }
4789
+ const path = ev && typeof ev.composedPath === "function" ? ev.composedPath() : null;
4790
+ const inside = path ? path.indexOf(this.gridRoot) !== -1 : !!(ev && ev.target && this.gridRoot.contains && this.gridRoot.contains(ev.target));
4791
+ this.outsidePointerDown = !inside;
4792
+ };
4793
+ document.addEventListener("pointerdown", this.docPointerDown, true);
4794
+ }
4288
4795
  if (this.isWindowed()) this.gridScrollEl = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rdt-scroll") : null;
4289
4796
  if (this.rowsWindowed()) {
4290
4797
  this.virtualizer = new Virtualizer(this.virtualizerOptions());
@@ -4318,6 +4825,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4318
4825
  }
4319
4826
  updated(changedProperties) {
4320
4827
  this.maybeClearHistoryOnExternalSwap();
4828
+ this.emitVisibleRangeIfChanged();
4829
+ this.remeasureColumnSizes();
4321
4830
  if (!this.table) return;
4322
4831
  const d = this.currentData() || [];
4323
4832
  if (d === this.lastData && d.length === this.lastDataLen) return;
@@ -4356,7 +4865,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4356
4865
 
4357
4866
  <div class="rdt-column-defs" style="display:none" aria-hidden="true" data-rozie-s-d5dcab4c><slot></slot></div>
4358
4867
 
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>
4868
+ ${!!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
4869
  <input class="rdt-global-filter" type="text" role="searchbox" aria-label="Search table" .value=${this.globalFilterValue()} @input=${($event) => {
4361
4870
  this.onGlobalFilterInput($event);
4362
4871
  }} data-rozie-s-d5dcab4c />
@@ -4397,7 +4906,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4397
4906
  "rozie-data-table": true,
4398
4907
  "rdt-sticky": this.stickyHeader,
4399
4908
  "rdt-col-windowed": this.colsWindowed()
4400
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} @keydown=${($event) => {
4909
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} aria-colcount=${rozieAttr(this.gridAriaColCount())} @keydown=${($event) => {
4401
4910
  this.onGridKeyDown($event);
4402
4911
  }} @focusin=${($event) => {
4403
4912
  this.syncActiveFromEvent($event);
@@ -4417,9 +4926,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4417
4926
  "rdt-th": true,
4418
4927
  "rdt-select-th": this.isSelectColumn(wh.header.column.id),
4419
4928
  "rdt-expander-th": this.isExpanderColumn(wh.header.column.id),
4929
+ "rdt-pinned": this.columnPinSide(wh.header.column.id) !== "",
4420
4930
  "rdt-th-resizing": this.columnIsResizing(wh.header.column.id),
4421
4931
  "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>
4932
+ }).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
4933
  ${this.isSelectColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4424
4934
  ${this.selectAll !== void 0 ? this.selectAll({
4425
4935
  checked: this.isAllRowsSelected(),
@@ -4535,7 +5045,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4535
5045
  ${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
5046
 
4537
5047
  ${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>
5048
+ ${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({
5049
+ "rdt-filter-cell": true,
5050
+ "rdt-pinned": this.columnPinSide(wh.header.column.id) !== ""
5051
+ }).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
5052
  ${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
5053
  ${this.columnIsFilterable(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4541
5054
  ${this.rozieSlots?.[`filter-${wh.header.column.id}`] !== void 0 ? this.rozieSlots?.[`filter-${wh.header.column.id}`]({
@@ -4543,6 +5056,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4543
5056
  value: this.columnFilterValue(wh.header.column.id),
4544
5057
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4545
5058
  minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5059
+ columnLabel: this.headerLabel(wh.header.column.id),
4546
5060
  setFilter: this.setColumnFilter
4547
5061
  }) : html`<slot name="${`filter-${wh.header.column.id}`}" data-rozie-params=${(() => {
4548
5062
  try {
@@ -4550,7 +5064,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4550
5064
  columnId: wh.header.column.id,
4551
5065
  value: this.columnFilterValue(wh.header.column.id),
4552
5066
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4553
- minMax: this.getFacetedMinMaxValues(wh.header.column.id)
5067
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5068
+ columnLabel: this.headerLabel(wh.header.column.id)
4554
5069
  });
4555
5070
  } catch {
4556
5071
  return "{}";
@@ -4561,6 +5076,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4561
5076
  value: this.columnFilterValue(wh.header.column.id),
4562
5077
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4563
5078
  minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5079
+ columnLabel: this.headerLabel(wh.header.column.id),
4564
5080
  setFilter: this.setColumnFilter
4565
5081
  }) : html`<slot name="filter" data-rozie-params=${(() => {
4566
5082
  try {
@@ -4568,7 +5084,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4568
5084
  columnId: wh.header.column.id,
4569
5085
  value: this.columnFilterValue(wh.header.column.id),
4570
5086
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4571
- minMax: this.getFacetedMinMaxValues(wh.header.column.id)
5087
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5088
+ columnLabel: this.headerLabel(wh.header.column.id)
4572
5089
  });
4573
5090
  } catch {
4574
5091
  return "{}";
@@ -4594,18 +5111,40 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4594
5111
  <tr class="${Object.entries({
4595
5112
  "rdt-tr": true,
4596
5113
  "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>
5114
+ "rdt-row-pinned": wr.pinned,
5115
+ "rdt-placeholder-row": this.rowIsLazyPlaceholder(wr.row)
5116
+ }).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
5117
 
4600
5118
  ${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
5119
  "rdt-td": true,
4602
5120
  "rdt-select-td": this.isSelectColumn(cell.column.id),
4603
5121
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
5122
+ "rdt-pinned": this.columnPinSide(cell.column.id) !== "",
4604
5123
  "rdt-in-range": this.inRange(wr.vi.index, this.colIndexOf(wr.row, cell)),
4605
5124
  "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>
5125
+ }).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
5126
 
4608
- ${this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5127
+
5128
+ ${this.rowIsLazyPlaceholder(wr.row) && this.isSelectColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5129
+
5130
+ <input class="rdt-select-placeholder" type="checkbox" disabled="" tabindex="-1" aria-hidden="true" style="visibility:hidden" data-rozie-s-d5dcab4c />
5131
+ </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>
5132
+ ${this.placeholder !== void 0 ? this.placeholder({
5133
+ index: wr.vi.index,
5134
+ columnId: cell.column.id
5135
+ }) : html`<slot name="placeholder" data-rozie-params=${(() => {
5136
+ try {
5137
+ return JSON.stringify({
5138
+ index: wr.vi.index,
5139
+ columnId: cell.column.id
5140
+ });
5141
+ } catch {
5142
+ return "{}";
5143
+ }
5144
+ })()}>
5145
+ <span class="rdt-skeleton" aria-hidden="true" data-rozie-s-d5dcab4c>&#8203;</span>
5146
+ </slot>`}
5147
+ </span>` : this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4609
5148
  ${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
5149
  this.onToggleExpand(wr.row, $event);
4611
5150
  }} 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 +5209,29 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4670
5209
  </span>
4671
5210
  <span class="rdt-group-count" data-rozie-s-d5dcab4c>${rozieDisplay("(" + this.groupSubRowCount(wr.row) + ")")}</span>
4672
5211
  </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) => {
5212
+ ${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
5213
  this.onCellEditorInput(cell.column.id, $event);
4675
5214
  }} @keydown=${($event) => {
4676
5215
  this.onEditorKeyDown($event);
4677
5216
  }} @blur=${($event) => {
4678
5217
  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) => {
5218
+ }} 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
5219
  this.onCellEditorInput(cell.column.id, $event);
4681
5220
  }} @keydown=${($event) => {
4682
5221
  this.onEditorKeyDown($event);
4683
5222
  }} @blur=${($event) => {
4684
5223
  this.onEditorBlur($event);
4685
5224
  }} 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) => {
5225
+ ${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>`)}
5226
+ </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
5227
  this.onCellEditorCheckbox(cell.column.id, $event);
4689
5228
  }} @keydown=${($event) => {
4690
5229
  this.onEditorKeyDown($event);
4691
5230
  }} @blur=${($event) => {
4692
5231
  this.onEditorBlur($event);
4693
- }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5232
+ }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" @keydown=${($event) => {
5233
+ this.onEditorDropinKeyDown($event);
5234
+ }} data-rozie-s-d5dcab4c>
4694
5235
  ${this.rozieSlots?.[`editor-${cell.column.id}`] !== void 0 ? this.rozieSlots?.[`editor-${cell.column.id}`]({
4695
5236
  columnId: cell.column.id,
4696
5237
  column: cell.column,
@@ -4698,6 +5239,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4698
5239
  value: this.editorValueFor(cell.column.id),
4699
5240
  commit: this.editorCommitFor(cell.column.id),
4700
5241
  cancel: this.editorCancelFor(),
5242
+ columnLabel: this.headerLabel(cell.column.id),
4701
5243
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4702
5244
  }) : html`<slot name="${`editor-${cell.column.id}`}" data-rozie-params=${(() => {
4703
5245
  try {
@@ -4708,6 +5250,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4708
5250
  value: this.editorValueFor(cell.column.id),
4709
5251
  commit: this.editorCommitFor(cell.column.id),
4710
5252
  cancel: this.editorCancelFor(),
5253
+ columnLabel: this.headerLabel(cell.column.id),
4711
5254
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4712
5255
  });
4713
5256
  } catch {
@@ -4721,6 +5264,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4721
5264
  value: this.editorValueFor(cell.column.id),
4722
5265
  commit: this.editorCommitFor(cell.column.id),
4723
5266
  cancel: this.editorCancelFor(),
5267
+ columnLabel: this.headerLabel(cell.column.id),
4724
5268
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4725
5269
  }) : html`<slot name="editor" data-rozie-params=${(() => {
4726
5270
  try {
@@ -4731,13 +5275,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4731
5275
  value: this.editorValueFor(cell.column.id),
4732
5276
  commit: this.editorCommitFor(cell.column.id),
4733
5277
  cancel: this.editorCancelFor(),
5278
+ columnLabel: this.headerLabel(cell.column.id),
4734
5279
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4735
5280
  });
4736
5281
  } catch {
4737
5282
  return "{}";
4738
5283
  }
4739
5284
  })()}>
4740
- <input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5285
+ <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
5286
  this.onCellEditorInput(cell.column.id, $event);
4742
5287
  }} @keydown=${($event) => {
4743
5288
  this.onEditorKeyDown($event);
@@ -4746,7 +5291,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4746
5291
  }} data-rozie-s-d5dcab4c />
4747
5292
  </slot>`}
4748
5293
  </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) => {
5294
+ </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
5295
  this.onCellEditorInput(cell.column.id, $event);
4751
5296
  }} @keydown=${($event) => {
4752
5297
  this.onEditorKeyDown($event);
@@ -4814,7 +5359,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4814
5359
  </div>` : html`<table class="${Object.entries({
4815
5360
  "rozie-data-table": true,
4816
5361
  "rdt-sticky": this.stickyHeader
4817
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} @keydown=${($event) => {
5362
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role=${rozieAttr(this.tableRole())} aria-rowcount=${rozieAttr(this.gridAriaRowCount())} aria-colcount=${rozieAttr(this.gridAriaColCount())} @keydown=${($event) => {
4818
5363
  this.onGridKeyDown($event);
4819
5364
  }} @focusin=${($event) => {
4820
5365
  this.syncActiveFromEvent($event);
@@ -4833,9 +5378,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4833
5378
  "rdt-th": true,
4834
5379
  "rdt-select-th": this.isSelectColumn(header.column.id),
4835
5380
  "rdt-expander-th": this.isExpanderColumn(header.column.id),
5381
+ "rdt-pinned": this.columnPinSide(header.column.id) !== "",
4836
5382
  "rdt-th-resizing": this.columnIsResizing(header.column.id),
4837
5383
  "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>
5384
+ }).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
5385
 
4840
5386
 
4841
5387
  ${this.isSelectColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
@@ -4956,7 +5502,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4956
5502
  </tr>`)}
4957
5503
 
4958
5504
  ${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>
5505
+ ${repeat(this._headerGroups.value[this._headerGroups.value.length - 1].headers, (header, _idx) => header.id, (header, _idx) => html`<th class="${Object.entries({
5506
+ "rdt-filter-cell": true,
5507
+ "rdt-pinned": this.columnPinSide(header.column.id) !== ""
5508
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" role="presentation" style=${rozieStyle(this.pinStyle(header.column.id))} data-rozie-s-d5dcab4c>
4960
5509
  ${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
5510
  ${this.columnIsFilterable(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4962
5511
  ${this.rozieSlots?.[`filter-${header.column.id}`] !== void 0 ? this.rozieSlots?.[`filter-${header.column.id}`]({
@@ -4964,6 +5513,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4964
5513
  value: this.columnFilterValue(header.column.id),
4965
5514
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4966
5515
  minMax: this.getFacetedMinMaxValues(header.column.id),
5516
+ columnLabel: this.headerLabel(header.column.id),
4967
5517
  setFilter: this.setColumnFilter
4968
5518
  }) : html`<slot name="${`filter-${header.column.id}`}" data-rozie-params=${(() => {
4969
5519
  try {
@@ -4971,7 +5521,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4971
5521
  columnId: header.column.id,
4972
5522
  value: this.columnFilterValue(header.column.id),
4973
5523
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4974
- minMax: this.getFacetedMinMaxValues(header.column.id)
5524
+ minMax: this.getFacetedMinMaxValues(header.column.id),
5525
+ columnLabel: this.headerLabel(header.column.id)
4975
5526
  });
4976
5527
  } catch {
4977
5528
  return "{}";
@@ -4982,6 +5533,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4982
5533
  value: this.columnFilterValue(header.column.id),
4983
5534
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4984
5535
  minMax: this.getFacetedMinMaxValues(header.column.id),
5536
+ columnLabel: this.headerLabel(header.column.id),
4985
5537
  setFilter: this.setColumnFilter
4986
5538
  }) : html`<slot name="filter" data-rozie-params=${(() => {
4987
5539
  try {
@@ -4989,7 +5541,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4989
5541
  columnId: header.column.id,
4990
5542
  value: this.columnFilterValue(header.column.id),
4991
5543
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4992
- minMax: this.getFacetedMinMaxValues(header.column.id)
5544
+ minMax: this.getFacetedMinMaxValues(header.column.id),
5545
+ columnLabel: this.headerLabel(header.column.id)
4993
5546
  });
4994
5547
  } catch {
4995
5548
  return "{}";
@@ -5016,9 +5569,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5016
5569
  "rdt-td": true,
5017
5570
  "rdt-select-td": this.isSelectColumn(cell.column.id),
5018
5571
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
5572
+ "rdt-pinned": this.columnPinSide(cell.column.id) !== "",
5019
5573
  "rdt-in-range": this.inRange(this.rowIndexOf(row), this.colIndexOf(row, cell)),
5020
5574
  "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>
5575
+ }).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
5576
 
5023
5577
  ${this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5024
5578
  ${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 +5639,29 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5085
5639
  </span>
5086
5640
  <span class="rdt-group-count" data-rozie-s-d5dcab4c>${rozieDisplay("(" + this.groupSubRowCount(row) + ")")}</span>
5087
5641
  </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) => {
5642
+ ${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
5643
  this.onCellEditorInput(cell.column.id, $event);
5090
5644
  }} @keydown=${($event) => {
5091
5645
  this.onEditorKeyDown($event);
5092
5646
  }} @blur=${($event) => {
5093
5647
  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) => {
5648
+ }} 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
5649
  this.onCellEditorInput(cell.column.id, $event);
5096
5650
  }} @keydown=${($event) => {
5097
5651
  this.onEditorKeyDown($event);
5098
5652
  }} @blur=${($event) => {
5099
5653
  this.onEditorBlur($event);
5100
5654
  }} 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) => {
5655
+ ${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>`)}
5656
+ </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
5657
  this.onCellEditorCheckbox(cell.column.id, $event);
5104
5658
  }} @keydown=${($event) => {
5105
5659
  this.onEditorKeyDown($event);
5106
5660
  }} @blur=${($event) => {
5107
5661
  this.onEditorBlur($event);
5108
- }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5662
+ }} data-rozie-s-d5dcab4c />` : this.editorTypeOf(cell.column.id) === "custom" ? html`<span style="display:contents" @keydown=${($event) => {
5663
+ this.onEditorDropinKeyDown($event);
5664
+ }} data-rozie-s-d5dcab4c>
5109
5665
  ${this.rozieSlots?.[`editor-${cell.column.id}`] !== void 0 ? this.rozieSlots?.[`editor-${cell.column.id}`]({
5110
5666
  columnId: cell.column.id,
5111
5667
  column: cell.column,
@@ -5113,6 +5669,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5113
5669
  value: this.editorValueFor(cell.column.id),
5114
5670
  commit: this.editorCommitFor(cell.column.id),
5115
5671
  cancel: this.editorCancelFor(),
5672
+ columnLabel: this.headerLabel(cell.column.id),
5116
5673
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5117
5674
  }) : html`<slot name="${`editor-${cell.column.id}`}" data-rozie-params=${(() => {
5118
5675
  try {
@@ -5123,6 +5680,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5123
5680
  value: this.editorValueFor(cell.column.id),
5124
5681
  commit: this.editorCommitFor(cell.column.id),
5125
5682
  cancel: this.editorCancelFor(),
5683
+ columnLabel: this.headerLabel(cell.column.id),
5126
5684
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5127
5685
  });
5128
5686
  } catch {
@@ -5136,6 +5694,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5136
5694
  value: this.editorValueFor(cell.column.id),
5137
5695
  commit: this.editorCommitFor(cell.column.id),
5138
5696
  cancel: this.editorCancelFor(),
5697
+ columnLabel: this.headerLabel(cell.column.id),
5139
5698
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5140
5699
  }) : html`<slot name="editor" data-rozie-params=${(() => {
5141
5700
  try {
@@ -5146,13 +5705,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5146
5705
  value: this.editorValueFor(cell.column.id),
5147
5706
  commit: this.editorCommitFor(cell.column.id),
5148
5707
  cancel: this.editorCancelFor(),
5708
+ columnLabel: this.headerLabel(cell.column.id),
5149
5709
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5150
5710
  });
5151
5711
  } catch {
5152
5712
  return "{}";
5153
5713
  }
5154
5714
  })()}>
5155
- <input class="rdt-cell-editor" type="text" data-editing-cell="" data-builtin-editor="" .value=${this.editorValueFor(cell.column.id)} @input=${($event) => {
5715
+ <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
5716
  this.onCellEditorInput(cell.column.id, $event);
5157
5717
  }} @keydown=${($event) => {
5158
5718
  this.onEditorKeyDown($event);
@@ -5161,7 +5721,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5161
5721
  }} data-rozie-s-d5dcab4c />
5162
5722
  </slot>`}
5163
5723
  </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) => {
5724
+ </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
5725
  this.onCellEditorInput(cell.column.id, $event);
5166
5726
  }} @keydown=${($event) => {
5167
5727
  this.onEditorKeyDown($event);
@@ -5233,10 +5793,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5233
5793
  <select class="rdt-page-size" aria-label="Rows per page" .value=${this.pageSize()} @change=${($event) => {
5234
5794
  this.onPageSizeChange($event);
5235
5795
  }} 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>
5796
+ <option value=${10} ?selected=${10 === this.pageSize()} data-rozie-s-d5dcab4c>10</option>
5797
+ <option value=${25} ?selected=${25 === this.pageSize()} data-rozie-s-d5dcab4c>25</option>
5798
+ <option value=${50} ?selected=${50 === this.pageSize()} data-rozie-s-d5dcab4c>50</option>
5799
+ <option value=${100} ?selected=${100 === this.pageSize()} data-rozie-s-d5dcab4c>100</option>
5240
5800
  </select>
5241
5801
  </div>` : nothing}</div>
5242
5802
  `;
@@ -5359,6 +5919,7 @@ __decorate([property({
5359
5919
  type: Object,
5360
5920
  attribute: "expanded"
5361
5921
  })], DataTable.prototype, "_expanded_attr", void 0);
5922
+ __decorate([property({ type: Function })], DataTable.prototype, "getRowId", void 0);
5362
5923
  __decorate([property({ type: Function })], DataTable.prototype, "getSubRows", void 0);
5363
5924
  __decorate([property({
5364
5925
  type: Boolean,
@@ -5440,6 +6001,12 @@ __decorate([state()], DataTable.prototype, "_hasSlotDynamicColHeader", void 0);
5440
6001
  __decorate([queryAssignedElements({ flatten: true })], DataTable.prototype, "_slotDynamicColHeaderElements", void 0);
5441
6002
  __decorate([state()], DataTable.prototype, "_hasSlotDynamicFilter", void 0);
5442
6003
  __decorate([queryAssignedElements({ flatten: true })], DataTable.prototype, "_slotDynamicFilterElements", void 0);
6004
+ __decorate([state()], DataTable.prototype, "_hasSlotPlaceholder", void 0);
6005
+ __decorate([queryAssignedElements({
6006
+ slot: "placeholder",
6007
+ flatten: true
6008
+ })], DataTable.prototype, "_slotPlaceholderElements", void 0);
6009
+ __decorate([property({ attribute: false })], DataTable.prototype, "placeholder", void 0);
5443
6010
  __decorate([state()], DataTable.prototype, "_hasSlotSelectCell", void 0);
5444
6011
  __decorate([queryAssignedElements({
5445
6012
  slot: "selectCell",
@@ -5637,15 +6204,19 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5637
6204
  this.commit = null;
5638
6205
  this.cancel = null;
5639
6206
  this.autofocus = false;
6207
+ this.columnLabel = "";
5640
6208
  this._draft = signal("");
6209
+ this._touched = signal(false);
5641
6210
  this.__rozieFirstUpdateDone = false;
5642
6211
  this._disconnectCleanups = [];
5643
6212
  this._rozieTornDown = false;
6213
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5644
6214
  this.onInput = (e) => {
5645
6215
  this._draft.value = e && e.target ? e.target.value : "";
6216
+ this._touched.value = true;
5646
6217
  };
5647
6218
  this.doCommit = () => {
5648
- this.commit && this.commit(this._draft.value);
6219
+ this.commit && this.commit(this.draftValue());
5649
6220
  };
5650
6221
  this.doCancel = () => {
5651
6222
  this.cancel && this.cancel();
@@ -5662,6 +6233,10 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5662
6233
  this.onBlur = () => {
5663
6234
  this.doCommit();
5664
6235
  };
6236
+ this.a11yLabel = () => {
6237
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6238
+ return this.columnId;
6239
+ };
5665
6240
  }
5666
6241
  static {
5667
6242
  this.styles = css`
@@ -5669,7 +6244,6 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5669
6244
  `;
5670
6245
  }
5671
6246
  firstUpdated() {
5672
- this._draft.value = this.value != null ? String(this.value) : "";
5673
6247
  if (this.autofocus) this._refInputEl?.focus();
5674
6248
  }
5675
6249
  updated(changedProperties) {
@@ -5689,7 +6263,7 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5689
6263
  }
5690
6264
  render() {
5691
6265
  return html`
5692
- <input class="rdt-cell-editor" type="text" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6266
+ <input class="rdt-cell-editor" type="text" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
5693
6267
  this.onInput($event);
5694
6268
  }} @keydown=${($event) => {
5695
6269
  this.onKeydown($event);
@@ -5712,6 +6286,10 @@ __decorate([property({
5712
6286
  type: Boolean,
5713
6287
  reflect: true
5714
6288
  })], EditorText.prototype, "autofocus", void 0);
6289
+ __decorate([property({
6290
+ type: String,
6291
+ reflect: true
6292
+ })], EditorText.prototype, "columnLabel", void 0);
5715
6293
  __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorText.prototype, "_refInputEl", void 0);
5716
6294
  EditorText = __decorate([customElement("rozie-editor-text")], EditorText);
5717
6295
  var EditorText_default = EditorText;
@@ -5726,15 +6304,21 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5726
6304
  this.value = null;
5727
6305
  this.commit = null;
5728
6306
  this.cancel = null;
6307
+ this.autofocus = false;
6308
+ this.columnLabel = "";
5729
6309
  this._draft = signal("");
6310
+ this._touched = signal(false);
6311
+ this.__rozieFirstUpdateDone = false;
5730
6312
  this._disconnectCleanups = [];
5731
6313
  this._rozieTornDown = false;
6314
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5732
6315
  this.onInput = (e) => {
5733
6316
  this._draft.value = e && e.target ? e.target.value : "";
6317
+ this._touched.value = true;
5734
6318
  };
5735
6319
  this.doCommit = () => {
5736
6320
  if (!this.commit) return;
5737
- const raw = this._draft.value;
6321
+ const raw = this.draftValue();
5738
6322
  if (raw == null || String(raw).trim() === "") {
5739
6323
  this.commit(null);
5740
6324
  return;
@@ -5757,6 +6341,10 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5757
6341
  this.onBlur = () => {
5758
6342
  this.doCommit();
5759
6343
  };
6344
+ this.a11yLabel = () => {
6345
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6346
+ return this.columnId;
6347
+ };
5760
6348
  }
5761
6349
  static {
5762
6350
  this.styles = css`
@@ -5764,7 +6352,13 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5764
6352
  `;
5765
6353
  }
5766
6354
  firstUpdated() {
5767
- this._draft.value = this.value != null ? String(this.value) : "";
6355
+ if (this.autofocus) this._refInputEl?.focus();
6356
+ }
6357
+ updated(changedProperties) {
6358
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6359
+ if (v) this._refInputEl?.focus();
6360
+ })(this.autofocus);
6361
+ this.__rozieFirstUpdateDone = true;
5768
6362
  }
5769
6363
  disconnectedCallback() {
5770
6364
  super.disconnectedCallback();
@@ -5777,13 +6371,13 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5777
6371
  }
5778
6372
  render() {
5779
6373
  return html`
5780
- <input class="rdt-cell-editor" type="number" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6374
+ <input class="rdt-cell-editor" type="number" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
5781
6375
  this.onInput($event);
5782
6376
  }} @keydown=${($event) => {
5783
6377
  this.onKeydown($event);
5784
6378
  }} @blur=${($event) => {
5785
6379
  this.onBlur();
5786
- }} data-rozie-s-b2792b32 />
6380
+ }} data-rozie-ref="inputEl" data-rozie-s-b2792b32 />
5787
6381
  `;
5788
6382
  }
5789
6383
  };
@@ -5796,6 +6390,15 @@ __decorate([property({ type: Object })], EditorNumber.prototype, "row", void 0);
5796
6390
  __decorate([property({ type: Object })], EditorNumber.prototype, "value", void 0);
5797
6391
  __decorate([property({ type: Function })], EditorNumber.prototype, "commit", void 0);
5798
6392
  __decorate([property({ type: Function })], EditorNumber.prototype, "cancel", void 0);
6393
+ __decorate([property({
6394
+ type: Boolean,
6395
+ reflect: true
6396
+ })], EditorNumber.prototype, "autofocus", void 0);
6397
+ __decorate([property({
6398
+ type: String,
6399
+ reflect: true
6400
+ })], EditorNumber.prototype, "columnLabel", void 0);
6401
+ __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorNumber.prototype, "_refInputEl", void 0);
5799
6402
  EditorNumber = __decorate([customElement("rozie-editor-number")], EditorNumber);
5800
6403
  var EditorNumber_default = EditorNumber;
5801
6404
  //#endregion
@@ -5810,14 +6413,20 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5810
6413
  this.commit = null;
5811
6414
  this.cancel = null;
5812
6415
  this.options = [];
6416
+ this.autofocus = false;
6417
+ this.columnLabel = "";
5813
6418
  this._draft = signal("");
6419
+ this._touched = signal(false);
6420
+ this.__rozieFirstUpdateDone = false;
5814
6421
  this._disconnectCleanups = [];
5815
6422
  this._rozieTornDown = false;
6423
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5816
6424
  this.onChange = (e) => {
5817
6425
  this._draft.value = e && e.target ? e.target.value : "";
6426
+ this._touched.value = true;
5818
6427
  };
5819
6428
  this.doCommit = () => {
5820
- this.commit && this.commit(this._draft.value);
6429
+ this.commit && this.commit(this.draftValue());
5821
6430
  };
5822
6431
  this.doCancel = () => {
5823
6432
  this.cancel && this.cancel();
@@ -5834,6 +6443,10 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5834
6443
  this.onBlur = () => {
5835
6444
  this.doCommit();
5836
6445
  };
6446
+ this.a11yLabel = () => {
6447
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6448
+ return this.columnId;
6449
+ };
5837
6450
  }
5838
6451
  static {
5839
6452
  this.styles = css`
@@ -5841,7 +6454,13 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5841
6454
  `;
5842
6455
  }
5843
6456
  firstUpdated() {
5844
- this._draft.value = this.value != null ? String(this.value) : "";
6457
+ if (this.autofocus) this._refSelectEl?.focus();
6458
+ }
6459
+ updated(changedProperties) {
6460
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6461
+ if (v) this._refSelectEl?.focus();
6462
+ })(this.autofocus);
6463
+ this.__rozieFirstUpdateDone = true;
5845
6464
  }
5846
6465
  disconnectedCallback() {
5847
6466
  super.disconnectedCallback();
@@ -5854,14 +6473,14 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5854
6473
  }
5855
6474
  render() {
5856
6475
  return html`
5857
- <select class="rdt-cell-editor" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @change=${($event) => {
6476
+ <select class="rdt-cell-editor" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @change=${($event) => {
5858
6477
  this.onChange($event);
5859
6478
  }} @keydown=${($event) => {
5860
6479
  this.onKeydown($event);
5861
6480
  }} @blur=${($event) => {
5862
6481
  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>`)}
6482
+ }} data-rozie-ref="selectEl" data-rozie-s-117f1a16>
6483
+ ${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
6484
  </select>
5866
6485
  `;
5867
6486
  }
@@ -5876,6 +6495,15 @@ __decorate([property({ type: Object })], EditorSelect.prototype, "value", void 0
5876
6495
  __decorate([property({ type: Function })], EditorSelect.prototype, "commit", void 0);
5877
6496
  __decorate([property({ type: Function })], EditorSelect.prototype, "cancel", void 0);
5878
6497
  __decorate([property({ type: Array })], EditorSelect.prototype, "options", void 0);
6498
+ __decorate([property({
6499
+ type: Boolean,
6500
+ reflect: true
6501
+ })], EditorSelect.prototype, "autofocus", void 0);
6502
+ __decorate([property({
6503
+ type: String,
6504
+ reflect: true
6505
+ })], EditorSelect.prototype, "columnLabel", void 0);
6506
+ __decorate([query("[data-rozie-ref=\"selectEl\"]")], EditorSelect.prototype, "_refSelectEl", void 0);
5879
6507
  EditorSelect = __decorate([customElement("rozie-editor-select")], EditorSelect);
5880
6508
  var EditorSelect_default = EditorSelect;
5881
6509
  //#endregion
@@ -5889,6 +6517,9 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5889
6517
  this.value = null;
5890
6518
  this.commit = null;
5891
6519
  this.cancel = null;
6520
+ this.autofocus = false;
6521
+ this.columnLabel = "";
6522
+ this.__rozieFirstUpdateDone = false;
5892
6523
  this._disconnectCleanups = [];
5893
6524
  this._rozieTornDown = false;
5894
6525
  this.onChange = (e) => {
@@ -5900,12 +6531,25 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5900
6531
  this.cancel && this.cancel();
5901
6532
  }
5902
6533
  };
6534
+ this.a11yLabel = () => {
6535
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6536
+ return this.columnId;
6537
+ };
5903
6538
  }
5904
6539
  static {
5905
6540
  this.styles = css`
5906
6541
  :host{display:contents}
5907
6542
  `;
5908
6543
  }
6544
+ firstUpdated() {
6545
+ if (this.autofocus) this._refInputEl?.focus();
6546
+ }
6547
+ updated(changedProperties) {
6548
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6549
+ if (v) this._refInputEl?.focus();
6550
+ })(this.autofocus);
6551
+ this.__rozieFirstUpdateDone = true;
6552
+ }
5909
6553
  disconnectedCallback() {
5910
6554
  super.disconnectedCallback();
5911
6555
  queueMicrotask(() => {
@@ -5917,11 +6561,11 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5917
6561
  }
5918
6562
  render() {
5919
6563
  return html`
5920
- <input class="rdt-cell-editor" type="checkbox" data-editing-cell="" aria-label=${this.columnId} ?checked=${!!this.value} @change=${($event) => {
6564
+ <input class="rdt-cell-editor" type="checkbox" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} ?checked=${!!this.value} @change=${($event) => {
5921
6565
  this.onChange($event);
5922
6566
  }} @keydown=${($event) => {
5923
6567
  this.onKeydown($event);
5924
- }} data-rozie-s-3d792482 />
6568
+ }} data-rozie-ref="inputEl" data-rozie-s-3d792482 />
5925
6569
  `;
5926
6570
  }
5927
6571
  };
@@ -5934,9 +6578,51 @@ __decorate([property({ type: Object })], EditorCheckbox.prototype, "row", void 0
5934
6578
  __decorate([property({ type: Object })], EditorCheckbox.prototype, "value", void 0);
5935
6579
  __decorate([property({ type: Function })], EditorCheckbox.prototype, "commit", void 0);
5936
6580
  __decorate([property({ type: Function })], EditorCheckbox.prototype, "cancel", void 0);
6581
+ __decorate([property({
6582
+ type: Boolean,
6583
+ reflect: true
6584
+ })], EditorCheckbox.prototype, "autofocus", void 0);
6585
+ __decorate([property({
6586
+ type: String,
6587
+ reflect: true
6588
+ })], EditorCheckbox.prototype, "columnLabel", void 0);
6589
+ __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorCheckbox.prototype, "_refInputEl", void 0);
5937
6590
  EditorCheckbox = __decorate([customElement("rozie-editor-checkbox")], EditorCheckbox);
5938
6591
  var EditorCheckbox_default = EditorCheckbox;
5939
6592
  //#endregion
6593
+ //#region src/helpers/dateValue.ts
6594
+ /**
6595
+ * Coerce an arbitrary cell value to the `YYYY-MM-DD` string a native date input accepts.
6596
+ * Returns `''` for anything that cannot be read as a date — which is what the input shows for
6597
+ * "no date", so an unparseable value degrades to empty rather than to a broken control.
6598
+ */
6599
+ const toIsoDateString = (v) => {
6600
+ if (v == null || v === "") return "";
6601
+ if (typeof v === "string") {
6602
+ const s = v.trim();
6603
+ if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s;
6604
+ const iso = /^(\d{4}-\d{2}-\d{2})T/.exec(s);
6605
+ if (iso) return iso[1];
6606
+ return fromDate(new Date(s));
6607
+ }
6608
+ if (typeof v === "number") return Number.isFinite(v) ? fromDate(new Date(v)) : "";
6609
+ if (typeof v === "object" && typeof v.getTime === "function") return fromDate(v);
6610
+ return "";
6611
+ };
6612
+ /**
6613
+ * Format a Date as `YYYY-MM-DD` from its LOCAL parts. Local, not UTC: the input renders a
6614
+ * calendar day, and `toISOString()` would show the previous day for anyone west of UTC on a
6615
+ * midnight-local value.
6616
+ */
6617
+ const fromDate = (d) => {
6618
+ const t = d.getTime();
6619
+ if (!Number.isFinite(t)) return "";
6620
+ const y = d.getFullYear();
6621
+ const m = d.getMonth() + 1;
6622
+ const day = d.getDate();
6623
+ return String(y).padStart(4, "0") + "-" + String(m).padStart(2, "0") + "-" + String(day).padStart(2, "0");
6624
+ };
6625
+ //#endregion
5940
6626
  //#region src/EditorDate.ts
5941
6627
  let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5942
6628
  constructor(..._args) {
@@ -5947,20 +6633,27 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5947
6633
  this.value = null;
5948
6634
  this.commit = null;
5949
6635
  this.cancel = null;
6636
+ this.autofocus = false;
6637
+ this.columnLabel = "";
5950
6638
  this._draft = signal("");
6639
+ this._touched = signal(false);
6640
+ this.__rozieFirstUpdateDone = false;
5951
6641
  this._disconnectCleanups = [];
5952
6642
  this._rozieTornDown = false;
6643
+ this.draftValue = () => this._touched.value ? this._draft.value : toIsoDateString(this.value);
5953
6644
  this.onInput = (e) => {
5954
6645
  this._draft.value = e && e.target ? e.target.value : "";
6646
+ this._touched.value = true;
5955
6647
  };
5956
6648
  this.doCommit = () => {
5957
- this.commit && this.commit(this._draft.value);
6649
+ this.commit && this.commit(this.draftValue());
5958
6650
  };
5959
6651
  this.doCancel = () => {
5960
6652
  this.cancel && this.cancel();
5961
6653
  };
5962
6654
  this.onChange = (e) => {
5963
6655
  this._draft.value = e && e.target ? e.target.value : "";
6656
+ this._touched.value = true;
5964
6657
  };
5965
6658
  this.onKeydown = (e) => {
5966
6659
  if (e && e.key === "Enter") {
@@ -5974,6 +6667,10 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5974
6667
  this.onBlur = () => {
5975
6668
  this.doCommit();
5976
6669
  };
6670
+ this.a11yLabel = () => {
6671
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6672
+ return this.columnId;
6673
+ };
5977
6674
  }
5978
6675
  static {
5979
6676
  this.styles = css`
@@ -5981,7 +6678,13 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5981
6678
  `;
5982
6679
  }
5983
6680
  firstUpdated() {
5984
- this._draft.value = this.value != null ? String(this.value) : "";
6681
+ if (this.autofocus) this._refInputEl?.focus();
6682
+ }
6683
+ updated(changedProperties) {
6684
+ if (this.__rozieFirstUpdateDone && changedProperties.has("autofocus")) ((v) => {
6685
+ if (v) this._refInputEl?.focus();
6686
+ })(this.autofocus);
6687
+ this.__rozieFirstUpdateDone = true;
5985
6688
  }
5986
6689
  disconnectedCallback() {
5987
6690
  super.disconnectedCallback();
@@ -5994,7 +6697,7 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5994
6697
  }
5995
6698
  render() {
5996
6699
  return html`
5997
- <input class="rdt-cell-editor" type="date" data-editing-cell="" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6700
+ <input class="rdt-cell-editor" type="date" data-editing-cell="" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
5998
6701
  this.onInput($event);
5999
6702
  }} @change=${($event) => {
6000
6703
  this.onChange($event);
@@ -6002,7 +6705,7 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
6002
6705
  this.onKeydown($event);
6003
6706
  }} @blur=${($event) => {
6004
6707
  this.onBlur();
6005
- }} data-rozie-s-7abe1a56 />
6708
+ }} data-rozie-ref="inputEl" data-rozie-s-7abe1a56 />
6006
6709
  `;
6007
6710
  }
6008
6711
  };
@@ -6015,6 +6718,15 @@ __decorate([property({ type: Object })], EditorDate.prototype, "row", void 0);
6015
6718
  __decorate([property({ type: Object })], EditorDate.prototype, "value", void 0);
6016
6719
  __decorate([property({ type: Function })], EditorDate.prototype, "commit", void 0);
6017
6720
  __decorate([property({ type: Function })], EditorDate.prototype, "cancel", void 0);
6721
+ __decorate([property({
6722
+ type: Boolean,
6723
+ reflect: true
6724
+ })], EditorDate.prototype, "autofocus", void 0);
6725
+ __decorate([property({
6726
+ type: String,
6727
+ reflect: true
6728
+ })], EditorDate.prototype, "columnLabel", void 0);
6729
+ __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorDate.prototype, "_refInputEl", void 0);
6018
6730
  EditorDate = __decorate([customElement("rozie-editor-date")], EditorDate);
6019
6731
  var EditorDate_default = EditorDate;
6020
6732
  //#endregion
@@ -6026,17 +6738,23 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6026
6738
  this.column = null;
6027
6739
  this.value = null;
6028
6740
  this.setFilter = null;
6741
+ this.columnLabel = "";
6029
6742
  this._draft = signal("");
6743
+ this._touched = signal(false);
6744
+ this.__rozieFirstUpdateDone = false;
6030
6745
  this._disconnectCleanups = [];
6031
6746
  this._rozieTornDown = false;
6747
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
6032
6748
  this.onInput = (e) => {
6033
6749
  this._draft.value = e && e.target ? e.target.value : "";
6750
+ this._touched.value = true;
6034
6751
  };
6035
6752
  this.applyFilter = () => {
6036
- this.setFilter && this.setFilter(this.columnId, this._draft.value);
6753
+ this.setFilter && this.setFilter(this.columnId, this.draftValue());
6037
6754
  };
6038
6755
  this.clearFilter = () => {
6039
6756
  this._draft.value = "";
6757
+ this._touched.value = false;
6040
6758
  this.setFilter && this.setFilter(this.columnId, "");
6041
6759
  };
6042
6760
  this.onKeydown = (e) => {
@@ -6051,14 +6769,22 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6051
6769
  this.onBlur = () => {
6052
6770
  this.applyFilter();
6053
6771
  };
6772
+ this.a11yLabel = () => {
6773
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6774
+ return this.columnId;
6775
+ };
6054
6776
  }
6055
6777
  static {
6056
6778
  this.styles = css`
6057
6779
  :host{display:contents}
6058
6780
  `;
6059
6781
  }
6060
- firstUpdated() {
6061
- this._draft.value = this.value != null ? String(this.value) : "";
6782
+ updated(changedProperties) {
6783
+ if (this.__rozieFirstUpdateDone && changedProperties.has("value")) {
6784
+ this.value;
6785
+ this._touched.value = false;
6786
+ }
6787
+ this.__rozieFirstUpdateDone = true;
6062
6788
  }
6063
6789
  disconnectedCallback() {
6064
6790
  super.disconnectedCallback();
@@ -6071,7 +6797,7 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6071
6797
  }
6072
6798
  render() {
6073
6799
  return html`
6074
- <input class="rdt-col-filter" part="col-filter" type="text" aria-label=${this.columnId} .value=${this._draft.value} @input=${($event) => {
6800
+ <input class="rdt-col-filter" part="col-filter" type="text" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.draftValue()} @input=${($event) => {
6075
6801
  this.onInput($event);
6076
6802
  }} @keydown=${($event) => {
6077
6803
  this.onKeydown($event);
@@ -6088,6 +6814,10 @@ __decorate([property({
6088
6814
  __decorate([property({ type: Object })], FilterText.prototype, "column", void 0);
6089
6815
  __decorate([property({ type: Object })], FilterText.prototype, "value", void 0);
6090
6816
  __decorate([property({ type: Function })], FilterText.prototype, "setFilter", void 0);
6817
+ __decorate([property({
6818
+ type: String,
6819
+ reflect: true
6820
+ })], FilterText.prototype, "columnLabel", void 0);
6091
6821
  FilterText = __decorate([customElement("rozie-filter-text")], FilterText);
6092
6822
  var FilterText_default = FilterText;
6093
6823
  //#endregion
@@ -6100,24 +6830,41 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6100
6830
  this.value = null;
6101
6831
  this.setFilter = null;
6102
6832
  this.minMax = null;
6833
+ this.columnLabel = "";
6103
6834
  this._minDraft = signal("");
6104
6835
  this._maxDraft = signal("");
6836
+ this._touched = signal(false);
6837
+ this.__rozieWatchInitial_0 = true;
6105
6838
  this._disconnectCleanups = [];
6106
6839
  this._rozieTornDown = false;
6840
+ this.minDraftValue = () => this._touched.value ? this._minDraft.value : Array.isArray(this.value) && this.value[0] != null ? String(this.value[0]) : "";
6841
+ this.maxDraftValue = () => this._touched.value ? this._maxDraft.value : Array.isArray(this.value) && this.value[1] != null ? String(this.value[1]) : "";
6107
6842
  this.onMinInput = (e) => {
6108
6843
  this._minDraft.value = e && e.target ? e.target.value : "";
6844
+ this._touched.value = true;
6109
6845
  };
6110
6846
  this.onMaxInput = (e) => {
6111
6847
  this._maxDraft.value = e && e.target ? e.target.value : "";
6848
+ this._touched.value = true;
6849
+ };
6850
+ this.onKeydown = (e) => {
6851
+ if (e && e.key === "Enter") this.applyRange(this.minDraftValue(), this.maxDraftValue());
6852
+ };
6853
+ this.onBlur = () => {
6854
+ this.applyRange(this.minDraftValue(), this.maxDraftValue());
6112
6855
  };
6113
6856
  this.minPlaceholder = () => Array.isArray(this.minMax) && this.minMax[0] != null ? String(this.minMax[0]) : "";
6114
6857
  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);
6858
+ this.applyRange = (minDraft, maxDraft) => {
6859
+ const minNum = minDraft === "" ? void 0 : Number(minDraft);
6860
+ const maxNum = maxDraft === "" ? void 0 : Number(maxDraft);
6118
6861
  if (minNum === void 0 && maxNum === void 0) this.setFilter && this.setFilter(this.columnId, "");
6119
6862
  else this.setFilter && this.setFilter(this.columnId, [minNum, maxNum]);
6120
6863
  };
6864
+ this.a11yLabel = () => {
6865
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6866
+ return this.columnId;
6867
+ };
6121
6868
  }
6122
6869
  static {
6123
6870
  this.styles = css`
@@ -6125,8 +6872,16 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6125
6872
  `;
6126
6873
  }
6127
6874
  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]) : "";
6875
+ this._disconnectCleanups.push(effect(() => {
6876
+ Array.isArray(this.value) && String(this.value[0]) + "" + String(this.value[1]);
6877
+ untracked(() => {
6878
+ if (this.__rozieWatchInitial_0) {
6879
+ this.__rozieWatchInitial_0 = false;
6880
+ return;
6881
+ }
6882
+ this._touched.value = false;
6883
+ });
6884
+ }));
6130
6885
  }
6131
6886
  disconnectedCallback() {
6132
6887
  super.disconnectedCallback();
@@ -6140,16 +6895,20 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6140
6895
  render() {
6141
6896
  return html`
6142
6897
  <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) => {
6898
+ <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
6899
  this.onMinInput($event);
6145
- }} @change=${($event) => {
6146
- this.applyRange();
6900
+ }} @keydown=${($event) => {
6901
+ this.onKeydown($event);
6902
+ }} @blur=${($event) => {
6903
+ this.onBlur();
6147
6904
  }} data-rozie-s-97b2c090 />
6148
6905
  <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) => {
6906
+ <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
6907
  this.onMaxInput($event);
6151
- }} @change=${($event) => {
6152
- this.applyRange();
6908
+ }} @keydown=${($event) => {
6909
+ this.onKeydown($event);
6910
+ }} @blur=${($event) => {
6911
+ this.onBlur();
6153
6912
  }} data-rozie-s-97b2c090 />
6154
6913
  </span>
6155
6914
  `;
@@ -6163,6 +6922,10 @@ __decorate([property({ type: Object })], FilterNumberRange.prototype, "column",
6163
6922
  __decorate([property({ type: Object })], FilterNumberRange.prototype, "value", void 0);
6164
6923
  __decorate([property({ type: Function })], FilterNumberRange.prototype, "setFilter", void 0);
6165
6924
  __decorate([property({ type: Object })], FilterNumberRange.prototype, "minMax", void 0);
6925
+ __decorate([property({
6926
+ type: String,
6927
+ reflect: true
6928
+ })], FilterNumberRange.prototype, "columnLabel", void 0);
6166
6929
  FilterNumberRange = __decorate([customElement("rozie-filter-number-range")], FilterNumberRange);
6167
6930
  var FilterNumberRange_default = FilterNumberRange;
6168
6931
  //#endregion
@@ -6175,6 +6938,7 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6175
6938
  this.value = null;
6176
6939
  this.setFilter = null;
6177
6940
  this.uniqueValues = [];
6941
+ this.columnLabel = "";
6178
6942
  this._disconnectCleanups = [];
6179
6943
  this._rozieTornDown = false;
6180
6944
  this.selectValue = () => this.value != null ? String(this.value) : "";
@@ -6183,6 +6947,10 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6183
6947
  if (v === "") this.setFilter && this.setFilter(this.columnId, "");
6184
6948
  else this.setFilter && this.setFilter(this.columnId, v);
6185
6949
  };
6950
+ this.a11yLabel = () => {
6951
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6952
+ return this.columnId;
6953
+ };
6186
6954
  }
6187
6955
  static {
6188
6956
  this.styles = css`
@@ -6200,11 +6968,11 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6200
6968
  }
6201
6969
  render() {
6202
6970
  return html`
6203
- <select class="rdt-col-filter" part="col-filter" aria-label=${this.columnId} .value=${this.selectValue()} @change=${($event) => {
6971
+ <select class="rdt-col-filter" part="col-filter" aria-label=${rozieAttr(this.a11yLabel())} .value=${this.selectValue()} @change=${($event) => {
6204
6972
  this.onChange($event);
6205
6973
  }} data-rozie-s-d75b42b2>
6206
6974
  <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>`)}
6975
+ ${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
6976
  </select>
6209
6977
  `;
6210
6978
  }
@@ -6217,6 +6985,10 @@ __decorate([property({ type: Object })], FilterSelect.prototype, "column", void
6217
6985
  __decorate([property({ type: Object })], FilterSelect.prototype, "value", void 0);
6218
6986
  __decorate([property({ type: Function })], FilterSelect.prototype, "setFilter", void 0);
6219
6987
  __decorate([property({ type: Array })], FilterSelect.prototype, "uniqueValues", void 0);
6988
+ __decorate([property({
6989
+ type: String,
6990
+ reflect: true
6991
+ })], FilterSelect.prototype, "columnLabel", void 0);
6220
6992
  FilterSelect = __decorate([customElement("rozie-filter-select")], FilterSelect);
6221
6993
  var FilterSelect_default = FilterSelect;
6222
6994
  //#endregion
@@ -6292,6 +7064,42 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6292
7064
  this.removeKey = (key) => {
6293
7065
  this.applyGrouping && this.applyGrouping(this.grouping.filter((k) => k !== key));
6294
7066
  };
7067
+ this.toggleKey = (id) => {
7068
+ if (!id) return;
7069
+ if (this.grouping.indexOf(id) !== -1) {
7070
+ this.removeKey(id);
7071
+ return;
7072
+ }
7073
+ this.applyGrouping && this.applyGrouping(this.grouping.concat([id]));
7074
+ };
7075
+ this.moveKey = (key, delta) => {
7076
+ const cur = this.grouping;
7077
+ const from = cur.indexOf(key);
7078
+ if (from === -1) return;
7079
+ const to = from + delta;
7080
+ if (to < 0 || to >= cur.length) return;
7081
+ const next = cur.slice();
7082
+ next.splice(from, 1);
7083
+ next.splice(to, 0, key);
7084
+ this.applyGrouping && this.applyGrouping(next);
7085
+ };
7086
+ this.onTokenKeydown = (e, gk) => {
7087
+ if (!e) return;
7088
+ const key = e.key;
7089
+ if (key === "Delete" || key === "Backspace") {
7090
+ e.preventDefault();
7091
+ this.removeKey(gk);
7092
+ return;
7093
+ }
7094
+ if (!e.altKey) return;
7095
+ if (key === "ArrowLeft") {
7096
+ e.preventDefault();
7097
+ this.moveKey(gk, -1);
7098
+ } else if (key === "ArrowRight") {
7099
+ e.preventDefault();
7100
+ this.moveKey(gk, 1);
7101
+ }
7102
+ };
6295
7103
  this.clearAll = () => {
6296
7104
  this.clearGrouping && this.clearGrouping();
6297
7105
  };
@@ -6320,6 +7128,18 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6320
7128
  border-color: var(--rdt-group-drop-zone-border-over, rgba(37, 99, 235, 0.7));
6321
7129
  background: var(--rdt-group-drop-zone-bg-over, rgba(37, 99, 235, 0.08));
6322
7130
  }
7131
+ .rdt-group-token-add[data-rozie-s-546c469a] {
7132
+ font: inherit;
7133
+ color: inherit;
7134
+ border: none;
7135
+ background: none;
7136
+ cursor: pointer;
7137
+ }
7138
+ .rdt-group-token-add[data-rozie-s-546c469a]:focus-visible,
7139
+ .rdt-group-drop-zone[data-rozie-s-546c469a] [data-group-token][data-rozie-s-546c469a]:focus-visible {
7140
+ outline: var(--rdt-focus-ring, 2px solid #2563eb);
7141
+ outline-offset: 1px;
7142
+ }
6323
7143
  .rdt-group-drop-hint[data-rozie-s-546c469a] {
6324
7144
  opacity: 0.55;
6325
7145
  font-size: 0.8125em;
@@ -6375,17 +7195,19 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6375
7195
  return html`
6376
7196
  <div class="rdt-group-bar" data-rozie-s-546c469a>
6377
7197
 
6378
- ${repeat(this.groupableColumns, (col, _idx) => col.id, (col, _idx) => html`<span class="rdt-group-token" part="group-token" draggable="true" @dragstart=${($event) => {
7198
+ ${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
7199
  this.onChipDragStart($event, col.id);
6380
7200
  }} @dragend=${($event) => {
6381
7201
  this.onDragEnd();
6382
- }} data-rozie-s-546c469a>${rozieDisplay(col.label)}</span>`)}
7202
+ }} @click=${($event) => {
7203
+ this.toggleKey(col.id);
7204
+ }} data-rozie-s-546c469a>${rozieDisplay(col.label)}</button>`)}
6383
7205
 
6384
7206
 
6385
7207
  <span class="${Object.entries({
6386
7208
  "rdt-group-drop-zone": true,
6387
7209
  "is-over": this._isOver.value
6388
- }).filter(([, v]) => v).map(([k]) => k).join(" ")}" data-group-drop-zone="" @dragover=${($event) => {
7210
+ }).filter(([, v]) => v).map(([k]) => k).join(" ")}" data-group-drop-zone="" role="list" aria-label="Active grouping" @dragover=${($event) => {
6389
7211
  this.onDragOver($event);
6390
7212
  }} @dragleave=${($event) => {
6391
7213
  this.onDragLeave($event);
@@ -6396,12 +7218,14 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6396
7218
  ${!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
7219
  "rdt-group-token": true,
6398
7220
  "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) => {
7221
+ }).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
7222
  this.onTokenDragStart($event, gk);
6401
7223
  }} @dragover=${($event) => {
6402
7224
  this.onTokenDragOver($event, gk);
6403
7225
  }} @dragend=${($event) => {
6404
7226
  this.onDragEnd();
7227
+ }} @keydown=${($event) => {
7228
+ this.onTokenKeydown($event, gk);
6405
7229
  }} data-rozie-s-546c469a>
6406
7230
  ${rozieDisplay(this.labelFor(gk))}
6407
7231
  <button class="rdt-group-token-remove" type="button" aria-label=${rozieAttr("Remove " + this.labelFor(gk) + " grouping")} @click=${($event) => {