@rozie-ui/data-table-lit 0.4.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";
@@ -439,6 +492,34 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
439
492
  left: rail.concat(deduped)
440
493
  };
441
494
  };
495
+ this.pinSeedApplied = false;
496
+ this.seedColumnPinning = () => {
497
+ if (this.pinSeedApplied) return;
498
+ const live = this.columnPinning != null ? this.columnPinning : this._columnPinningDefault.value;
499
+ const isRealPin = (id) => id !== this.SELECT_COL_ID && id !== this.EXPANDER_COL_ID;
500
+ if ((live && live.left ? live.left : []).filter(isRealPin).length > 0 || (live && live.right ? live.right : []).filter(isRealPin).length > 0) {
501
+ this.pinSeedApplied = true;
502
+ return;
503
+ }
504
+ const defs = this.columnDefs();
505
+ if (!defs.length) return;
506
+ const left = [];
507
+ const right = [];
508
+ for (let i = 0; i < defs.length; i++) {
509
+ const def = defs[i];
510
+ if (!def) continue;
511
+ if (def.pinned === "left") left.push(def.id);
512
+ else if (def.pinned === "right") right.push(def.id);
513
+ }
514
+ if (!left.length && !right.length) return;
515
+ this.pinSeedApplied = true;
516
+ const seeded = {
517
+ left,
518
+ right
519
+ };
520
+ this._columnPinningDefault.value = seeded;
521
+ this._columnPinningControllable.write(seeded);
522
+ };
442
523
  this.currentState = () => ({
443
524
  sorting: this.sorting != null ? this.sorting : this._sortingDefault.value,
444
525
  globalFilter: this.globalFilter != null ? this.globalFilter : this._globalFilterDefault.value,
@@ -454,6 +535,26 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
454
535
  columnSizingInfo: this._columnSizingInfo.value
455
536
  });
456
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
+ };
457
558
  this.buildConfigDef = (c) => {
458
559
  if (!c) return null;
459
560
  if (Array.isArray(c.columns)) {
@@ -490,9 +591,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
490
591
  aggregationFn: wrapAggregationFn(c.aggregationFn),
491
592
  pinned: c.pinned != null ? c.pinned : "",
492
593
  width: c.width != null ? c.width : "",
594
+ ...this.parseWidthToSize(c.width) != null ? { size: this.parseWidthToSize(c.width) } : {},
493
595
  meta: {
494
596
  editable: c.editable === true,
495
- editor: c.editor != null ? c.editor : "text",
597
+ editor: c.editor != null ? this.checkEditorKind(id, c.editor) : "text",
496
598
  editorOptions: c.editorOptions != null ? c.editorOptions : [],
497
599
  validate: typeof c.validate === "function" ? c.validate : null
498
600
  }
@@ -532,9 +634,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
532
634
  aggregationFn: wrapAggregationFn(spec.aggregationFn),
533
635
  pinned: spec.pinned != null ? spec.pinned : "",
534
636
  width: spec.width != null ? spec.width : "",
637
+ ...this.parseWidthToSize(spec.width) != null ? { size: this.parseWidthToSize(spec.width) } : {},
535
638
  meta: {
536
639
  editable: spec.editable === true,
537
- editor: spec.editor != null ? spec.editor : "text",
640
+ editor: spec.editor != null ? this.checkEditorKind(id, spec.editor) : "text",
538
641
  editorOptions: spec.editorOptions != null ? spec.editorOptions : [],
539
642
  validate: typeof spec.validate === "function" ? spec.validate : null
540
643
  }
@@ -835,9 +938,12 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
835
938
  this.onColumnPinningChangeCb = (updater) => {
836
939
  this.writeColumnPinning(applyUpdater(updater, this.currentState().columnPinning));
837
940
  };
941
+ this.columnSizingInfoSync = null;
838
942
  this.onColumnSizingInfoChangeCb = (updater) => {
839
- const next = applyUpdater(updater, this._columnSizingInfo.value);
840
- this._columnSizingInfo.value = next != null ? next : this._columnSizingInfo.value;
943
+ const next = applyUpdater(updater, this.columnSizingInfoSync != null ? this.columnSizingInfoSync : this._columnSizingInfo.value);
944
+ if (next == null) return;
945
+ this.columnSizingInfoSync = next;
946
+ this._columnSizingInfo.value = next;
841
947
  };
842
948
  this.resolveVirtual = () => {
843
949
  const v = this.virtual;
@@ -875,7 +981,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
875
981
  if (c && c.getIsPinned && c.getIsPinned()) out.push(i);
876
982
  }
877
983
  }
878
- 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);
879
985
  if (this._editingRow.value >= 0 && this._editingCol.value >= 0 && out.indexOf(this._editingCol.value) === -1) out.push(this._editingCol.value);
880
986
  return out;
881
987
  };
@@ -896,18 +1002,37 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
896
1002
  if (this.rowsWindowed()) return this.table.getPrePaginationRowModel().rows;
897
1003
  return this.table.getRowModel().rows;
898
1004
  };
1005
+ this.REMEASURE_MAX_FRAMES = 10;
899
1006
  this.scheduleRemeasure = () => {
900
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
+ }
901
1013
  if (this.remeasurePending) return;
902
1014
  this.remeasurePending = true;
903
1015
  let ranMicro = false;
904
1016
  const microPass = () => {
905
1017
  this.remeasureWindow();
906
1018
  };
1019
+ let rafAttempts = 0;
907
1020
  const rafPass = () => {
908
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
+ }
909
1035
  this.remeasurePending = false;
910
- this.remeasureWindow();
911
1036
  };
912
1037
  if (typeof queueMicrotask !== "undefined") {
913
1038
  ranMicro = true;
@@ -929,6 +1054,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
929
1054
  this.pinnedEditIndex = () => {
930
1055
  if (this._editingRow.value >= 0) return this._editingRow.value;
931
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;
932
1058
  return -1;
933
1059
  };
934
1060
  this.pinnedMeasurement = (pin) => {
@@ -937,12 +1063,84 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
937
1063
  return ms && ms[pin] ? ms[pin] : null;
938
1064
  };
939
1065
  this.remeasureWindow = () => {
940
- if (this.remeasureDisposed) return;
941
- if (!this.virtualizer || !this.gridRoot) return;
942
- 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;
943
1069
  const trs = this.gridRoot.querySelectorAll("tbody.rdt-tbody > tr[data-index]");
944
- 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
+ }
945
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
+ }));
946
1144
  };
947
1145
  this.virtualItemKey = (i) => {
948
1146
  const src = this.windowSource();
@@ -1049,6 +1247,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1049
1247
  }
1050
1248
  }
1051
1249
  this.bumpWindowVer();
1250
+ this.scheduleRemeasure();
1052
1251
  };
1053
1252
  this.virtualizerOptions = () => ({
1054
1253
  count: this.windowSource().length,
@@ -1221,20 +1420,29 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1221
1420
  if (filterChanged) return this.totalRowCount() + " results";
1222
1421
  return "";
1223
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
+ };
1224
1431
  this.reFeed = () => {
1225
1432
  if (!this.table) return;
1226
1433
  this.table.setOptions((prev) => ({
1227
1434
  ...prev,
1228
- data: this.currentData(),
1435
+ data: this.feedData(),
1229
1436
  columns: this.tableColumns(),
1230
1437
  state: this.currentState(),
1231
- enableRowSelection: this.selectionMode !== "none",
1438
+ enableRowSelection: this.rowSelectionOption(),
1232
1439
  enableMultiRowSelection: this.selectionMode === "multiple",
1233
1440
  rowCount: this.rowCount ?? void 0,
1234
1441
  pageCount: this.pageCount ?? void 0,
1235
1442
  getExpandedRowModel: getExpandedRowModel(),
1236
1443
  getSubRows: this.getSubRows || void 0,
1237
- 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,
1238
1446
  onExpandedChange: this.onExpandedChangeCb,
1239
1447
  autoResetExpanded: false,
1240
1448
  getGroupedRowModel: getGroupedRowModel(),
@@ -1393,9 +1601,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1393
1601
  if (side === "right") return "position:sticky;right:" + (col.getAfter ? col.getAfter("right") : 0) + "px;z-index:" + zIndex + ";";
1394
1602
  return "";
1395
1603
  };
1396
- this.thStyle = (header) => {
1604
+ this.thStyle = (header, widthPx = null) => {
1397
1605
  let s = "";
1398
- const w = this.headerWidth(header);
1606
+ const w = widthPx != null && widthPx > 0 ? widthPx + "px" : this.headerWidth(header);
1399
1607
  if (w) s += "width:" + w + ";";
1400
1608
  s += this.pinStyle(header && header.column ? header.column.id : null, 2);
1401
1609
  return s;
@@ -1607,6 +1815,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1607
1815
  this.rowIndexOf = (row) => this.tick() >= 0 ? (this._rows.value || []).indexOf(row) : -1;
1608
1816
  this.colIndexOf = (row, cellCtx) => this.tick() >= 0 ? this.visibleCellsFor(row).indexOf(cellCtx) : -1;
1609
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
+ };
1610
1828
  this.pageRowOffset = () => {
1611
1829
  if (!this.isGrid() || this.rowsWindowed()) return 0;
1612
1830
  return this.pageIndex() * this.pageSize();
@@ -1650,14 +1868,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1650
1868
  const header = nextIsHeader == null ? this._activeIsHeader.value : nextIsHeader;
1651
1869
  const rowOut = this.rowsWindowed() && this.virtualizer && this.rowIsOutsideWindow(r);
1652
1870
  const colOut = this.colsWindowed() && this.colVirtualizer && this.colIsOutsideWindow(c);
1653
- if (!header && (rowOut || colOut)) {
1654
- 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" });
1655
1874
  if (colOut) this.colVirtualizer.scrollToIndex(c, { align: "center" });
1656
1875
  let focusAttempts = 0;
1657
1876
  const myEpoch = this.focusIntentEpoch;
1658
1877
  const focusWhenReady = () => {
1659
1878
  if (this.focusIntentEpoch !== myEpoch) return;
1660
- const el = this.resolveCellEl(String(r), c);
1879
+ const el = this.resolveCellEl(header ? "__header" : String(r), c, header ? lvl : null);
1661
1880
  if (el) {
1662
1881
  el.focus();
1663
1882
  return;
@@ -1677,6 +1896,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1677
1896
  };
1678
1897
  this.totalRowCount = () => {
1679
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
+ }
1680
1903
  const fm = this.table.getFilteredRowModel();
1681
1904
  return fm && fm.rows ? fm.rows.length : (this._rows.value || []).length;
1682
1905
  };
@@ -1684,6 +1907,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1684
1907
  this.gridAriaRowCount = () => this.headerRowCount() + this.totalRowCount();
1685
1908
  this.ariaPageOffset = () => this.table ? this.pageIndex() * this.pageSize() : 0;
1686
1909
  this.bodyAriaRowIndex = (row) => this.headerRowCount() + this.rowIndexOf(row) + this.ariaPageOffset() + 1;
1910
+ this.gridAriaColCount = () => this.visibleColCount();
1687
1911
  this.visibleColCount = () => {
1688
1912
  const rowList = this._rows.value || [];
1689
1913
  if (rowList.length) return rowList[0].getVisibleCells().length;
@@ -1854,6 +2078,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1854
2078
  const rowKey = this._activeIsHeader.value ? "__header" : String(this._activeRow.value);
1855
2079
  return this.resolveCellEl(rowKey, this._activeColIndex.value, this._activeIsHeader.value ? this._activeHeaderLevel.value : null);
1856
2080
  };
2081
+ this.activeCellHasControls = () => focusables(this.currentCellEl()).length > 0;
1857
2082
  this.enterControl = () => {
1858
2083
  const list = focusables(this.currentCellEl());
1859
2084
  if (!list.length) return;
@@ -1898,10 +2123,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1898
2123
  let nextLevel = prevLevel;
1899
2124
  if ((e.ctrlKey || e.metaKey) && e.shiftKey && !this._activeIsHeader.value && (key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight")) {
1900
2125
  e.preventDefault();
1901
- if (key === "ArrowUp") this.extendRange(-this._activeRow.value, 0);
1902
- else if (key === "ArrowDown") this.extendRange(this.bodyRowCount() - 1 - this._activeRow.value, 0);
1903
- else if (key === "ArrowLeft") this.extendRange(0, -this._activeColIndex.value);
1904
- 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());
1905
2130
  return;
1906
2131
  } else if ((e.ctrlKey || e.metaKey) && !this._activeIsHeader.value && (key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight")) {
1907
2132
  e.preventDefault();
@@ -1984,15 +2209,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
1984
2209
  nextCol = en.col;
1985
2210
  nextIsHeader = false;
1986
2211
  } else nextCol = this.gotoColEdge(true);
1987
- } 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()) {
1988
2213
  e.preventDefault();
1989
2214
  this.copyRange();
1990
2215
  return;
1991
- } 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()) {
1992
2217
  e.preventDefault();
1993
2218
  this.pasteRange();
1994
2219
  return;
1995
- } 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()) {
1996
2221
  e.preventDefault();
1997
2222
  this.cutRange();
1998
2223
  return;
@@ -2022,6 +2247,23 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2022
2247
  e.preventDefault();
2023
2248
  if (!this._activeIsHeader.value) this.selectAllBody();
2024
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;
2025
2267
  } else if (key === "F2" && e.shiftKey && this.isActiveCellEditable()) {
2026
2268
  e.preventDefault();
2027
2269
  this.beginRowEdit((this._rows.value || [])[this._activeRow.value]);
@@ -2047,6 +2289,10 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2047
2289
  this.onToggleExpand((this._rows.value || [])[this._activeRow.value], e);
2048
2290
  this.recoverGridFocus(String(grpRow), grpCol, null, true);
2049
2291
  return;
2292
+ } else if (key === "Enter" && !this._activeIsHeader.value && !this.activeCellHasControls()) {
2293
+ e.preventDefault();
2294
+ this.activateRowAt(this._activeRow.value, "keyboard");
2295
+ return;
2050
2296
  } else if (key === "Enter" || key === "F2") {
2051
2297
  e.preventDefault();
2052
2298
  this.enterControl();
@@ -2101,8 +2347,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2101
2347
  this._activeColIndex.value = col;
2102
2348
  if (isHeader !== prevIsHeader || col !== prevCol || (isHeader ? movedLevel !== prevLevel : movedRow !== prevRow)) this.focusIntentEpoch = this.focusIntentEpoch + 1;
2103
2349
  if (this.rangeTransition) this.rangeTransition = false;
2104
- else if (this.rangeClickPending) this.rangeClickPending = false;
2105
- 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
+ }
2106
2355
  if (tgt === cellEl) this._activeInControl.value = false;
2107
2356
  };
2108
2357
  this.onGridMouseDown = (e) => {
@@ -2123,9 +2372,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2123
2372
  this._activeIsHeader.value = false;
2124
2373
  this._activeRow.value = row;
2125
2374
  this._activeColIndex.value = col;
2126
- this.rangeClickPending = true;
2375
+ this.rangeClickPending = {
2376
+ isHeader: false,
2377
+ r: row,
2378
+ c: col
2379
+ };
2127
2380
  return;
2128
2381
  }
2382
+ if (this.isEditing(row, col)) return;
2129
2383
  this.beginRangeDrag(row, col);
2130
2384
  };
2131
2385
  this.onGridDblClick = (e) => {
@@ -2153,7 +2407,43 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2153
2407
  this.beginEdit(row, col, null);
2154
2408
  }
2155
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
+ };
2156
2445
  this.onGridClick = (e) => {
2446
+ this.maybeActivateRowFromClick(e);
2157
2447
  if (!this.isGrid() || !e) return;
2158
2448
  if (!this.singleClickEdit) return;
2159
2449
  if (e.shiftKey) return;
@@ -2264,7 +2554,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2264
2554
  const headers = hg && hg.headers || [];
2265
2555
  if (!this.colsWindowed()) return headers.map((h) => ({
2266
2556
  header: h,
2267
- span: h && h.colSpan > 1 ? h.colSpan : 1
2557
+ span: h && h.colSpan > 1 ? h.colSpan : 1,
2558
+ width: null
2268
2559
  }));
2269
2560
  const idx = this.windowedColIndices();
2270
2561
  const idxSet = {};
@@ -2278,23 +2569,39 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2278
2569
  const end = cursor + leafCount;
2279
2570
  cursor = end;
2280
2571
  let span = 0;
2281
- 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
+ }
2282
2577
  if (span > 0) out.push({
2283
2578
  header: h,
2284
- span
2579
+ span,
2580
+ width
2285
2581
  });
2286
2582
  }
2287
2583
  return out;
2288
2584
  };
2289
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
+ };
2290
2596
  this.remeasureColumnWindow = () => {
2291
2597
  if (!this.colsWindowed() || !this.colVirtualizer) return;
2292
2598
  this.colVirtualizer.setOptions(this.columnVirtualizerOptions());
2599
+ this.remeasureColumnSizes();
2293
2600
  this.colVirtualizer._willUpdate();
2294
2601
  };
2295
2602
  this.gridEmptyFallback = false;
2296
2603
  this.rangeTransition = false;
2297
- this.rangeClickPending = false;
2604
+ this.rangeClickPending = null;
2298
2605
  this.rangeActive = false;
2299
2606
  this.inRange = (rIdx, cIdx) => {
2300
2607
  const a = this._rangeAnchor.value;
@@ -2336,7 +2643,17 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2336
2643
  const c1 = a.colIndex > f.colIndex ? a.colIndex : f.colIndex;
2337
2644
  return rIdx === r1 && cIdx === c1;
2338
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
+ };
2339
2655
  this.emitRangeChange = (anchor, focus) => {
2656
+ this._rangeAnnounce.value = this.rangeSummary(anchor, focus);
2340
2657
  this.dispatchEvent(new CustomEvent("range-change", {
2341
2658
  detail: {
2342
2659
  anchor,
@@ -2379,11 +2696,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2379
2696
  this.focusActiveCell(nextRow, nextCol, false);
2380
2697
  if (!hadRange || nextRow !== focus.rowIndex || nextCol !== focus.colIndex) this.emitRangeChange(anchor, nextFocus);
2381
2698
  };
2382
- this.setRangeFocus = (rIdx, cIdx) => {
2699
+ this.setRangeFocus = (rIdx, cIdx, anchorR = null, anchorC = null) => {
2383
2700
  const maxRow = this.bodyRowCount() - 1;
2384
2701
  const maxCol = this.visibleColCount() - 1;
2385
2702
  if (maxRow < 0 || maxCol < 0) return;
2386
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
+ };
2387
2708
  if (!anchor) anchor = {
2388
2709
  rowIndex: this._activeRow.value,
2389
2710
  colIndex: this._activeColIndex.value
@@ -2414,6 +2735,32 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2414
2735
  this.rangeActive = true;
2415
2736
  this.emitRangeChange(anchor, focus);
2416
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
+ };
2417
2764
  this.clearRange = () => {
2418
2765
  if (!this.rangeActive) return;
2419
2766
  this.rangeActive = false;
@@ -2493,6 +2840,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2493
2840
  }
2494
2841
  return lines.join("\n");
2495
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";
2496
2845
  this.copyRange = () => {
2497
2846
  if (!this.clipboardActiveAllowed()) return;
2498
2847
  if (typeof navigator === "undefined" || !navigator.clipboard || !navigator.clipboard.writeText) return;
@@ -2501,27 +2850,30 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2501
2850
  if (p && p.catch) p.catch(() => {});
2502
2851
  } catch (err) {}
2503
2852
  };
2504
- this.applyGridToRange = (grid, originRow, originCol) => {
2853
+ this.applyGridToRange = (grid, originRow, originCol, verb) => {
2854
+ const opVerb = typeof verb === "string" && verb !== "" ? verb : "pasted";
2505
2855
  const maxRow = this.bodyRowCount() - 1;
2506
2856
  const maxCol = this.visibleColCount() - 1;
2507
2857
  if (maxRow < 0 || maxCol < 0) return {
2508
2858
  wrote: 0,
2859
+ changed: 0,
2509
2860
  total: 0
2510
2861
  };
2511
2862
  let total = 0;
2512
- let wrote = 0;
2863
+ let applied = 0;
2513
2864
  const committed = [];
2514
2865
  let next = this.currentData();
2515
2866
  for (let gr = 0; gr < grid.length; gr++) {
2516
2867
  const r = originRow + gr;
2517
2868
  if (r > maxRow) break;
2518
2869
  const rowGrouped = this.rowIndexIsGrouped(r);
2870
+ const rowPlaceholder = this.rowIsLazyPlaceholder((this._rows.value || [])[r]);
2519
2871
  const cols = grid[gr] || [];
2520
2872
  for (let gc = 0; gc < cols.length; gc++) {
2521
2873
  const c = originCol + gc;
2522
2874
  if (c > maxCol) break;
2523
2875
  total = total + 1;
2524
- if (rowGrouped) continue;
2876
+ if (rowGrouped || rowPlaceholder) continue;
2525
2877
  const colId = this.columnIdAt(r, c);
2526
2878
  if (colId == null || !this.columnEditable(colId)) continue;
2527
2879
  const rowObj = this.rowOriginalAt(r);
@@ -2530,6 +2882,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2530
2882
  const field = this.fieldOfColId(colId);
2531
2883
  const srcIndex = this.sourceIndexOfRow(r);
2532
2884
  const oldValue = rowObj ? rowObj[field] : null;
2885
+ applied = applied + 1;
2886
+ if (oldValue === value) continue;
2533
2887
  next = replaceRowValue(next, srcIndex, field, value);
2534
2888
  committed.push({
2535
2889
  rowId: this.rowIdAt(r),
@@ -2537,23 +2891,27 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2537
2891
  oldValue,
2538
2892
  newValue: value
2539
2893
  });
2540
- wrote = wrote + 1;
2541
2894
  }
2542
2895
  }
2543
- if (wrote > 0) {
2896
+ if (committed.length > 0) {
2544
2897
  this.editTransition = true;
2545
2898
  this.writeData(next);
2546
2899
  this.editTransition = false;
2547
- for (let i = 0; i < committed.length; i++) this.dispatchEvent(new CustomEvent("cell-edit-commit", {
2548
- detail: committed[i],
2549
- bubbles: true,
2550
- composed: true
2551
- }));
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
+ }
2552
2909
  }
2553
- if (wrote > 0) this.announce(wrote + " of " + total + " cells pasted");
2554
- 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");
2555
2912
  return {
2556
- wrote,
2913
+ wrote: applied,
2914
+ changed: committed.length,
2557
2915
  total
2558
2916
  };
2559
2917
  };
@@ -2585,11 +2943,15 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2585
2943
  }
2586
2944
  if (!p || !p.then) return;
2587
2945
  p.then((text) => {
2588
- const grid = parseTsv(text);
2589
- if (!grid.length) return;
2590
- const tiled = tileGridToBox(grid, destBox);
2591
- this.applyGridToRange(tiled, anchorRow, anchorCol);
2592
- }).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
+ }, () => {});
2593
2955
  };
2594
2956
  this.cutRange = () => {
2595
2957
  if (!this.clipboardActiveAllowed()) return;
@@ -2608,7 +2970,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2608
2970
  for (let c = c0; c <= c1; c++) cols.push("");
2609
2971
  grid.push(cols);
2610
2972
  }
2611
- this.applyGridToRange(grid, r0, c0);
2973
+ this.applyGridToRange(grid, r0, c0, "cut");
2612
2974
  };
2613
2975
  this.clearActiveRange = () => {
2614
2976
  if (!this.clipboardActiveAllowed()) return;
@@ -2623,7 +2985,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2623
2985
  for (let c = c0; c <= c1; c++) cols.push("");
2624
2986
  grid.push(cols);
2625
2987
  }
2626
- this.applyGridToRange(grid, r0, c0);
2988
+ this.applyGridToRange(grid, r0, c0, "cleared");
2627
2989
  };
2628
2990
  this.fillRange = (sourceBox, endCell) => {
2629
2991
  let box;
@@ -2661,7 +3023,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2661
3023
  }
2662
3024
  grid.push(cols);
2663
3025
  }
2664
- this.applyGridToRange(grid, box.r0, box.c0);
3026
+ this.applyGridToRange(grid, box.r0, box.c0, "filled");
2665
3027
  };
2666
3028
  this.fillDragging = false;
2667
3029
  this.fillDragMove = null;
@@ -2823,7 +3185,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2823
3185
  if (cell && (cell.r !== lastCell.r || cell.c !== lastCell.c)) {
2824
3186
  lastCell = cell;
2825
3187
  this.rangeDragMoved = true;
2826
- this.setRangeFocus(cell.r, cell.c);
3188
+ this.setRangeFocus(cell.r, cell.c, anchorR, anchorC);
2827
3189
  }
2828
3190
  };
2829
3191
  const up = () => {
@@ -2845,6 +3207,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2845
3207
  };
2846
3208
  this.isActiveCellEditable = () => {
2847
3209
  if (this.rowIndexIsGrouped(this._activeRow.value)) return false;
3210
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[this._activeRow.value])) return false;
2848
3211
  const colId = this.activeCellColumnId();
2849
3212
  return colId != null && this.columnEditable(colId);
2850
3213
  };
@@ -2956,12 +3319,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2956
3319
  };
2957
3320
  this.beginEdit = (rowIndex, colIndex, seed) => {
2958
3321
  if (this.rowIndexIsGrouped(rowIndex)) return;
3322
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[rowIndex])) return;
2959
3323
  const colId = this.columnIdAt(rowIndex, colIndex);
2960
3324
  if (colId == null || !this.columnEditable(colId)) return;
2961
3325
  this.committedThisSession = false;
2962
3326
  this.setInvalid("");
2963
3327
  this._editingRowIndex.value = null;
2964
3328
  this._rowDraft.value = {};
3329
+ this.rowDraftSync = {};
2965
3330
  this._editingRow.value = rowIndex;
2966
3331
  this._editingCol.value = colIndex;
2967
3332
  this._draftValue.value = seed != null ? seed : this.cellValueAt(rowIndex, colIndex);
@@ -2976,6 +3341,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2976
3341
  const tryFocus = () => {
2977
3342
  const el = this.resolveCellEl(String(row), col);
2978
3343
  if (el) {
3344
+ const ae = this.gridRoot && this.gridRoot.getRootNode ? this.gridRoot.getRootNode().activeElement : null;
3345
+ if (ae && ae !== el && this.gridRoot.contains && this.gridRoot.contains(ae) && ae.closest) {
3346
+ const aeCell = ae.closest("[data-grid-cell]");
3347
+ if (aeCell && aeCell !== el) return;
3348
+ }
2979
3349
  el.focus();
2980
3350
  return;
2981
3351
  }
@@ -2999,6 +3369,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
2999
3369
  this.endRowEdit = () => {
3000
3370
  this._editingRowIndex.value = null;
3001
3371
  this._rowDraft.value = {};
3372
+ this.rowDraftSync = {};
3002
3373
  this._invalidMsg.value = "";
3003
3374
  this._activeInControl.value = false;
3004
3375
  this._editVer.value = this._editVer.value + 1;
@@ -3012,7 +3383,14 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3012
3383
  return this._editFocusColId.value != null && this._editFocusColId.value === colId;
3013
3384
  };
3014
3385
  this.coerceCellValue = (colId, raw) => {
3015
- 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;
3016
3394
  if (raw == null) return null;
3017
3395
  if (typeof raw === "number") return Number.isNaN(raw) ? null : raw;
3018
3396
  const s = String(raw).trim();
@@ -3074,10 +3452,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3074
3452
  };
3075
3453
  this.toggleActiveBooleanCell = () => {
3076
3454
  if (this.rowIndexIsGrouped(this._activeRow.value)) return;
3077
- const colId = this.columnIdAt(this._activeRow.value, this._activeColIndex.value);
3078
- if (colId == null || !this.columnEditable(colId)) return;
3079
3455
  const row = (this._rows.value || [])[this._activeRow.value];
3080
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;
3081
3460
  const rowOriginal = row.original;
3082
3461
  const rowId = row.id;
3083
3462
  const oldValue = this.cellValueAt(this._activeRow.value, this._activeColIndex.value);
@@ -3163,6 +3542,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3163
3542
  const rowIndex = this.rowIndexOf(row);
3164
3543
  if (rowIndex < 0) return;
3165
3544
  if (this.rowIndexIsGrouped(rowIndex)) return;
3545
+ if (this.rowIsLazyPlaceholder((this._rows.value || [])[rowIndex])) return;
3166
3546
  const editable = this.editableColumnsForRow(rowIndex);
3167
3547
  if (editable.length === 0) return;
3168
3548
  this.committedThisSession = false;
@@ -3178,6 +3558,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3178
3558
  draft[ec.colId] = orig ? orig[ec.field] : null;
3179
3559
  }
3180
3560
  this._rowDraft.value = draft;
3561
+ this.rowDraftSync = draft;
3181
3562
  this._editingRowIndex.value = rowIndex;
3182
3563
  this._activeInControl.value = true;
3183
3564
  this._editVer.value = this._editVer.value + 1;
@@ -3195,7 +3576,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3195
3576
  const r = (this._rows.value || [])[rowIndex];
3196
3577
  const rowOriginal = r ? r.original : null;
3197
3578
  const rowId = r ? r.id : null;
3198
- const draft = this._rowDraft.value || {};
3579
+ const draft = this.rowDraftSync || {};
3199
3580
  for (let i = 0; i < editable.length; i++) {
3200
3581
  const ec = editable[i];
3201
3582
  const err = this.runValidator(ec.colId, this.coerceCellValue(ec.colId, draft[ec.colId]), rowOriginal);
@@ -3308,6 +3689,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3308
3689
  this.editTransition = false;
3309
3690
  this.pendingEditFollow = null;
3310
3691
  this.committedThisSession = false;
3692
+ this.rowDraftSync = {};
3693
+ this.dropinTabFlush = null;
3311
3694
  this.inRowEdit = () => this._editingRowIndex.value != null;
3312
3695
  this.editorValueFor = (colId) => this.inRowEdit() ? this._rowDraft.value ? this._rowDraft.value[colId] : null : this._draftValue.value;
3313
3696
  this.editorCheckedFor = (colId) => !!(this.inRowEdit() ? this._rowDraft.value ? this._rowDraft.value[colId] : null : this._draftValue.value);
@@ -3316,6 +3699,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3316
3699
  this.setRowDraft(colId, value);
3317
3700
  return;
3318
3701
  }
3702
+ if (this.dropinTabFlush) {
3703
+ this.dropinTabFlush.called = true;
3704
+ if (this.commitEdit(value, true)) this.dropinTabFlush.committed = true;
3705
+ return;
3706
+ }
3319
3707
  this.commitEdit(value);
3320
3708
  };
3321
3709
  this.editorCancelFor = () => () => {
@@ -3342,10 +3730,11 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3342
3730
  this._draftValue.value = v;
3343
3731
  };
3344
3732
  this.setRowDraft = (colId, value) => {
3345
- const src = this._rowDraft.value || {};
3733
+ const src = this.rowDraftSync || {};
3346
3734
  const next = {};
3347
3735
  for (const k in src) next[k] = src[k];
3348
3736
  next[colId] = value;
3737
+ this.rowDraftSync = next;
3349
3738
  this._rowDraft.value = next;
3350
3739
  };
3351
3740
  this.rowEditTab = (target, backward) => {
@@ -3400,6 +3789,56 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3400
3789
  this.cancelEdit();
3401
3790
  }
3402
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
+ };
3403
3842
  this.onEditorBlur = (e) => {
3404
3843
  if (this.inRowEdit()) {
3405
3844
  if (this.editTransition) return;
@@ -3412,13 +3851,20 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3412
3851
  }
3413
3852
  if (this._editingRow.value < 0 || this.editTransition) return;
3414
3853
  const next = e ? e.relatedTarget : null;
3415
- 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
+ }
3416
3863
  if (!(this.gridRoot && this.gridRoot.contains && this.gridRoot.contains(next))) {
3417
3864
  this.commitEdit(void 0);
3418
3865
  return;
3419
3866
  }
3420
3867
  const nextCell = next.closest ? next.closest("[data-grid-cell]") : null;
3421
- const fromCell = e && e.target && e.target.closest ? e.target.closest("[data-grid-cell]") : null;
3422
3868
  if (!nextCell || !fromCell || nextCell === fromCell) return;
3423
3869
  const fromRow = fromCell.getAttribute("data-row");
3424
3870
  const fromCol = fromCell.getAttribute("data-col-index");
@@ -3596,6 +4042,32 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3596
4042
  static {
3597
4043
  this.styles = css`
3598
4044
  :host{display:contents}
4045
+ :host {
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));
4070
+ }
3599
4071
  .rozie-data-table[data-rozie-s-d5dcab4c] {
3600
4072
  border-collapse: collapse;
3601
4073
  width: 100%;
@@ -3730,6 +4202,16 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3730
4202
  flex-direction: column;
3731
4203
  gap: var(--rdt-chrome-gap, 0.5rem);
3732
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
+ }
3733
4215
  .rozie-data-table-wrap[data-rozie-s-d5dcab4c] .rdt-toolbar[data-rozie-s-d5dcab4c] {
3734
4216
  display: flex;
3735
4217
  gap: var(--rdt-toolbar-gap, 0.5rem);
@@ -3768,6 +4250,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3768
4250
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-filter-row[data-rozie-s-d5dcab4c] {
3769
4251
  background: var(--rdt-filter-row-bg, rgba(0, 0, 0, 0.015));
3770
4252
  }
4253
+ .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-pinned[data-rozie-s-d5dcab4c] {
4254
+ box-sizing: border-box;
4255
+ }
3771
4256
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-filter-cell[data-rozie-s-d5dcab4c] {
3772
4257
  padding: var(--rdt-filter-cell-padding, 0.35rem 0.75rem);
3773
4258
  border-bottom: var(--rdt-border, 1px solid rgba(0, 0, 0, 0.08));
@@ -3887,6 +4372,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3887
4372
  .rozie-data-table-wrap[data-rozie-s-d5dcab4c] .rdt-colvis-summary[data-rozie-s-d5dcab4c] {
3888
4373
  cursor: pointer;
3889
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;
3890
4378
  padding: var(--rdt-colvis-summary-padding, 0.25rem 0.6rem);
3891
4379
  border: var(--rdt-colvis-summary-border, 1px solid rgba(0, 0, 0, 0.2));
3892
4380
  border-radius: var(--rdt-colvis-summary-radius, 4px);
@@ -3925,6 +4413,51 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3925
4413
  text-align: var(--rdt-expander-col-align, center);
3926
4414
  white-space: nowrap;
3927
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
+ }
3928
4461
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-select-all[data-rozie-s-d5dcab4c],
3929
4462
  .rozie-data-table[data-rozie-s-d5dcab4c] .rdt-select-row[data-rozie-s-d5dcab4c] {
3930
4463
  cursor: pointer;
@@ -3988,6 +4521,17 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
3988
4521
  update();
3989
4522
  }
3990
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
+ }
3991
4535
  {
3992
4536
  const slotEl = this.shadowRoot?.querySelector("slot[name=\"selectCell\"]");
3993
4537
  if (slotEl !== null && slotEl !== void 0) {
@@ -4083,6 +4627,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4083
4627
  this._hasSlotSelectAll = Array.from(this.children).some((el) => el.getAttribute("slot") === "selectAll");
4084
4628
  this._hasSlotDynamicColHeader = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4085
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");
4086
4631
  this._hasSlotSelectCell = Array.from(this.children).some((el) => el.getAttribute("slot") === "selectCell");
4087
4632
  this._hasSlotDynamicCell = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
4088
4633
  this._hasSlotDynamicEditor = Array.from(this.children).some((el) => !el.hasAttribute("slot") && (el.nodeType !== 3 || (el.textContent?.trim().length ?? 0) > 0));
@@ -4100,13 +4645,24 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4100
4645
  firstUpdated() {
4101
4646
  this._armListeners();
4102
4647
  this._disconnectCleanups.push(effect(() => {
4103
- 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;
4104
4649
  untracked(() => {
4105
4650
  if (this.__rozieWatchInitial_0) {
4106
4651
  this.__rozieWatchInitial_0 = false;
4107
4652
  return;
4108
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
+ }
4109
4664
  (() => {
4665
+ this.seedColumnPinning();
4110
4666
  this.reFeed();
4111
4667
  this.maybeClearHistoryOnExternalSwap();
4112
4668
  })();
@@ -4115,8 +4671,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4115
4671
  this._disconnectCleanups.push(effect(() => {
4116
4672
  this.sorting, this.columnFilters, this.globalFilter, this._sortingDefault.value, this._columnFiltersDefault.value, this._globalFilterDefault.value;
4117
4673
  untracked(() => {
4118
- if (this.__rozieWatchInitial_1) {
4119
- this.__rozieWatchInitial_1 = false;
4674
+ if (this.__rozieWatchInitial_2) {
4675
+ this.__rozieWatchInitial_2 = false;
4120
4676
  return;
4121
4677
  }
4122
4678
  (() => {
@@ -4132,6 +4688,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4132
4688
  if (id == null) return;
4133
4689
  const key = String(id);
4134
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;
4135
4693
  __rozieCtxHost._colReg.value = {
4136
4694
  ...__rozieCtxHost._colReg.value,
4137
4695
  [key]: spec
@@ -4146,8 +4704,9 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4146
4704
  }))(this));
4147
4705
  }));
4148
4706
  this._dataDefault.value = this.data || [];
4707
+ this.seedColumnPinning();
4149
4708
  this.table = createTable({
4150
- data: this.currentData(),
4709
+ data: this.feedData(),
4151
4710
  columns: this.tableColumns(),
4152
4711
  state: this.currentState(),
4153
4712
  getCoreRowModel: getCoreRowModel(),
@@ -4156,7 +4715,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4156
4715
  getPaginationRowModel: getPaginationRowModel(),
4157
4716
  getExpandedRowModel: getExpandedRowModel(),
4158
4717
  getSubRows: this.getSubRows || void 0,
4159
- 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,
4160
4720
  onExpandedChange: this.onExpandedChangeCb,
4161
4721
  autoResetExpanded: false,
4162
4722
  getGroupedRowModel: getGroupedRowModel(),
@@ -4169,7 +4729,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4169
4729
  manualSorting: this.manual === true,
4170
4730
  rowCount: this.rowCount ?? void 0,
4171
4731
  pageCount: this.pageCount ?? void 0,
4172
- enableRowSelection: this.selectionMode !== "none",
4732
+ enableRowSelection: this.rowSelectionOption(),
4173
4733
  enableMultiRowSelection: this.selectionMode === "multiple",
4174
4734
  onSortingChange: this.onSortingChangeCb,
4175
4735
  onGlobalFilterChange: this.onGlobalFilterChangeCb,
@@ -4194,6 +4754,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4194
4754
  this._headerGroups.value = nextGroups;
4195
4755
  this._rowModelVer.value = this._rowModelVer.value + 1;
4196
4756
  if (this.rowsWindowed() && this.virtualizer) {
4757
+ this.migratePlaceholderSizeCache();
4197
4758
  this.virtualizer.setOptions(this.virtualizerOptions());
4198
4759
  this.virtualizer._willUpdate();
4199
4760
  }
@@ -4219,6 +4780,18 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4219
4780
  };
4220
4781
  this.refreshRowModel();
4221
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
+ }
4222
4795
  if (this.isWindowed()) this.gridScrollEl = this._ref__rozieRoot ? this._ref__rozieRoot.querySelector(".rdt-scroll") : null;
4223
4796
  if (this.rowsWindowed()) {
4224
4797
  this.virtualizer = new Virtualizer(this.virtualizerOptions());
@@ -4240,6 +4813,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4240
4813
  }
4241
4814
  if (this.colsWindowed()) {
4242
4815
  if (!(this.gridScrollEl ? this.gridScrollEl.clientWidth : 0)) console.warn("[rozie-data-table] virtual is on for columns but the scroll container has no bounded width; set a CSS width on an ancestor so the column window can be measured");
4816
+ this.bumpWindowVer();
4243
4817
  }
4244
4818
  };
4245
4819
  if (typeof requestAnimationFrame === "function") requestAnimationFrame(() => requestAnimationFrame(afterFirstFrame));
@@ -4251,6 +4825,8 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4251
4825
  }
4252
4826
  updated(changedProperties) {
4253
4827
  this.maybeClearHistoryOnExternalSwap();
4828
+ this.emitVisibleRangeIfChanged();
4829
+ this.remeasureColumnSizes();
4254
4830
  if (!this.table) return;
4255
4831
  const d = this.currentData() || [];
4256
4832
  if (d === this.lastData && d.length === this.lastDataLen) return;
@@ -4289,7 +4865,7 @@ let DataTable = class DataTable extends SignalWatcher(LitElement) {
4289
4865
 
4290
4866
  <div class="rdt-column-defs" style="display:none" aria-hidden="true" data-rozie-s-d5dcab4c><slot></slot></div>
4291
4867
 
4292
- ${!!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>
4293
4869
  <input class="rdt-global-filter" type="text" role="searchbox" aria-label="Search table" .value=${this.globalFilterValue()} @input=${($event) => {
4294
4870
  this.onGlobalFilterInput($event);
4295
4871
  }} data-rozie-s-d5dcab4c />
@@ -4330,7 +4906,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4330
4906
  "rozie-data-table": true,
4331
4907
  "rdt-sticky": this.stickyHeader,
4332
4908
  "rdt-col-windowed": this.colsWindowed()
4333
- }).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) => {
4334
4910
  this.onGridKeyDown($event);
4335
4911
  }} @focusin=${($event) => {
4336
4912
  this.syncActiveFromEvent($event);
@@ -4350,9 +4926,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4350
4926
  "rdt-th": true,
4351
4927
  "rdt-select-th": this.isSelectColumn(wh.header.column.id),
4352
4928
  "rdt-expander-th": this.isExpanderColumn(wh.header.column.id),
4929
+ "rdt-pinned": this.columnPinSide(wh.header.column.id) !== "",
4353
4930
  "rdt-th-resizing": this.columnIsResizing(wh.header.column.id),
4354
4931
  "rdt-cell-active": this.isActiveCell("__header", this.headerColIndexOf(hg, wh.header), hgLevel)
4355
- }).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>
4356
4933
  ${this.isSelectColumn(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4357
4934
  ${this.selectAll !== void 0 ? this.selectAll({
4358
4935
  checked: this.isAllRowsSelected(),
@@ -4468,7 +5045,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4468
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>`)}
4469
5046
 
4470
5047
  ${this.hasAnyFilterableColumn() ? html`<tr class="rdt-filter-row" data-rozie-s-d5dcab4c>
4471
- ${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>
4472
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>
4473
5053
  ${this.columnIsFilterable(wh.header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4474
5054
  ${this.rozieSlots?.[`filter-${wh.header.column.id}`] !== void 0 ? this.rozieSlots?.[`filter-${wh.header.column.id}`]({
@@ -4476,6 +5056,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4476
5056
  value: this.columnFilterValue(wh.header.column.id),
4477
5057
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4478
5058
  minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5059
+ columnLabel: this.headerLabel(wh.header.column.id),
4479
5060
  setFilter: this.setColumnFilter
4480
5061
  }) : html`<slot name="${`filter-${wh.header.column.id}`}" data-rozie-params=${(() => {
4481
5062
  try {
@@ -4483,7 +5064,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4483
5064
  columnId: wh.header.column.id,
4484
5065
  value: this.columnFilterValue(wh.header.column.id),
4485
5066
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4486
- minMax: this.getFacetedMinMaxValues(wh.header.column.id)
5067
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5068
+ columnLabel: this.headerLabel(wh.header.column.id)
4487
5069
  });
4488
5070
  } catch {
4489
5071
  return "{}";
@@ -4494,6 +5076,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4494
5076
  value: this.columnFilterValue(wh.header.column.id),
4495
5077
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4496
5078
  minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5079
+ columnLabel: this.headerLabel(wh.header.column.id),
4497
5080
  setFilter: this.setColumnFilter
4498
5081
  }) : html`<slot name="filter" data-rozie-params=${(() => {
4499
5082
  try {
@@ -4501,7 +5084,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4501
5084
  columnId: wh.header.column.id,
4502
5085
  value: this.columnFilterValue(wh.header.column.id),
4503
5086
  uniqueValues: this.getFacetedUniqueValues(wh.header.column.id),
4504
- minMax: this.getFacetedMinMaxValues(wh.header.column.id)
5087
+ minMax: this.getFacetedMinMaxValues(wh.header.column.id),
5088
+ columnLabel: this.headerLabel(wh.header.column.id)
4505
5089
  });
4506
5090
  } catch {
4507
5091
  return "{}";
@@ -4527,18 +5111,40 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4527
5111
  <tr class="${Object.entries({
4528
5112
  "rdt-tr": true,
4529
5113
  "rdt-group-header": this.rowIsGrouped(wr.row),
4530
- "rdt-row-pinned": wr.pinned
4531
- }).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>
4532
5117
 
4533
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({
4534
5119
  "rdt-td": true,
4535
5120
  "rdt-select-td": this.isSelectColumn(cell.column.id),
4536
5121
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
5122
+ "rdt-pinned": this.columnPinSide(cell.column.id) !== "",
4537
5123
  "rdt-in-range": this.inRange(wr.vi.index, this.colIndexOf(wr.row, cell)),
4538
5124
  "rdt-cell-active": this.isActiveCell(String(wr.vi.index), this.colIndexOf(wr.row, cell))
4539
- }).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>
4540
5126
 
4541
- ${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>
4542
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) => {
4543
5149
  this.onToggleExpand(wr.row, $event);
4544
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>
@@ -4603,27 +5209,29 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4603
5209
  </span>
4604
5210
  <span class="rdt-group-count" data-rozie-s-d5dcab4c>${rozieDisplay("(" + this.groupSubRowCount(wr.row) + ")")}</span>
4605
5211
  </span>` : this.isEditing(wr.vi.index, this.colIndexOf(wr.row, cell)) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4606
- ${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) => {
4607
5213
  this.onCellEditorInput(cell.column.id, $event);
4608
5214
  }} @keydown=${($event) => {
4609
5215
  this.onEditorKeyDown($event);
4610
5216
  }} @blur=${($event) => {
4611
5217
  this.onEditorBlur($event);
4612
- }} 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) => {
4613
5219
  this.onCellEditorInput(cell.column.id, $event);
4614
5220
  }} @keydown=${($event) => {
4615
5221
  this.onEditorKeyDown($event);
4616
5222
  }} @blur=${($event) => {
4617
5223
  this.onEditorBlur($event);
4618
5224
  }} data-rozie-s-d5dcab4c>
4619
- ${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>`)}
4620
- </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) => {
4621
5227
  this.onCellEditorCheckbox(cell.column.id, $event);
4622
5228
  }} @keydown=${($event) => {
4623
5229
  this.onEditorKeyDown($event);
4624
5230
  }} @blur=${($event) => {
4625
5231
  this.onEditorBlur($event);
4626
- }} 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>
4627
5235
  ${this.rozieSlots?.[`editor-${cell.column.id}`] !== void 0 ? this.rozieSlots?.[`editor-${cell.column.id}`]({
4628
5236
  columnId: cell.column.id,
4629
5237
  column: cell.column,
@@ -4631,6 +5239,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4631
5239
  value: this.editorValueFor(cell.column.id),
4632
5240
  commit: this.editorCommitFor(cell.column.id),
4633
5241
  cancel: this.editorCancelFor(),
5242
+ columnLabel: this.headerLabel(cell.column.id),
4634
5243
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4635
5244
  }) : html`<slot name="${`editor-${cell.column.id}`}" data-rozie-params=${(() => {
4636
5245
  try {
@@ -4641,6 +5250,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4641
5250
  value: this.editorValueFor(cell.column.id),
4642
5251
  commit: this.editorCommitFor(cell.column.id),
4643
5252
  cancel: this.editorCancelFor(),
5253
+ columnLabel: this.headerLabel(cell.column.id),
4644
5254
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4645
5255
  });
4646
5256
  } catch {
@@ -4654,6 +5264,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4654
5264
  value: this.editorValueFor(cell.column.id),
4655
5265
  commit: this.editorCommitFor(cell.column.id),
4656
5266
  cancel: this.editorCancelFor(),
5267
+ columnLabel: this.headerLabel(cell.column.id),
4657
5268
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4658
5269
  }) : html`<slot name="editor" data-rozie-params=${(() => {
4659
5270
  try {
@@ -4664,13 +5275,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4664
5275
  value: this.editorValueFor(cell.column.id),
4665
5276
  commit: this.editorCommitFor(cell.column.id),
4666
5277
  cancel: this.editorCancelFor(),
5278
+ columnLabel: this.headerLabel(cell.column.id),
4667
5279
  autofocus: this.editorAutofocusFor(cell.column.id, wr.vi.index)
4668
5280
  });
4669
5281
  } catch {
4670
5282
  return "{}";
4671
5283
  }
4672
5284
  })()}>
4673
- <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) => {
4674
5286
  this.onCellEditorInput(cell.column.id, $event);
4675
5287
  }} @keydown=${($event) => {
4676
5288
  this.onEditorKeyDown($event);
@@ -4679,7 +5291,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4679
5291
  }} data-rozie-s-d5dcab4c />
4680
5292
  </slot>`}
4681
5293
  </slot>`}
4682
- </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) => {
4683
5295
  this.onCellEditorInput(cell.column.id, $event);
4684
5296
  }} @keydown=${($event) => {
4685
5297
  this.onEditorKeyDown($event);
@@ -4747,7 +5359,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4747
5359
  </div>` : html`<table class="${Object.entries({
4748
5360
  "rozie-data-table": true,
4749
5361
  "rdt-sticky": this.stickyHeader
4750
- }).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) => {
4751
5363
  this.onGridKeyDown($event);
4752
5364
  }} @focusin=${($event) => {
4753
5365
  this.syncActiveFromEvent($event);
@@ -4766,9 +5378,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4766
5378
  "rdt-th": true,
4767
5379
  "rdt-select-th": this.isSelectColumn(header.column.id),
4768
5380
  "rdt-expander-th": this.isExpanderColumn(header.column.id),
5381
+ "rdt-pinned": this.columnPinSide(header.column.id) !== "",
4769
5382
  "rdt-th-resizing": this.columnIsResizing(header.column.id),
4770
5383
  "rdt-cell-active": this.isActiveCell("__header", this.headerColIndexOf(hg, header), hgLevel)
4771
- }).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>
4772
5385
 
4773
5386
 
4774
5387
  ${this.isSelectColumn(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
@@ -4889,7 +5502,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4889
5502
  </tr>`)}
4890
5503
 
4891
5504
  ${this.hasAnyFilterableColumn() ? html`<tr class="rdt-filter-row" data-rozie-s-d5dcab4c>
4892
- ${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>
4893
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>
4894
5510
  ${this.columnIsFilterable(header.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4895
5511
  ${this.rozieSlots?.[`filter-${header.column.id}`] !== void 0 ? this.rozieSlots?.[`filter-${header.column.id}`]({
@@ -4897,6 +5513,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4897
5513
  value: this.columnFilterValue(header.column.id),
4898
5514
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4899
5515
  minMax: this.getFacetedMinMaxValues(header.column.id),
5516
+ columnLabel: this.headerLabel(header.column.id),
4900
5517
  setFilter: this.setColumnFilter
4901
5518
  }) : html`<slot name="${`filter-${header.column.id}`}" data-rozie-params=${(() => {
4902
5519
  try {
@@ -4904,7 +5521,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4904
5521
  columnId: header.column.id,
4905
5522
  value: this.columnFilterValue(header.column.id),
4906
5523
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4907
- minMax: this.getFacetedMinMaxValues(header.column.id)
5524
+ minMax: this.getFacetedMinMaxValues(header.column.id),
5525
+ columnLabel: this.headerLabel(header.column.id)
4908
5526
  });
4909
5527
  } catch {
4910
5528
  return "{}";
@@ -4915,6 +5533,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4915
5533
  value: this.columnFilterValue(header.column.id),
4916
5534
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4917
5535
  minMax: this.getFacetedMinMaxValues(header.column.id),
5536
+ columnLabel: this.headerLabel(header.column.id),
4918
5537
  setFilter: this.setColumnFilter
4919
5538
  }) : html`<slot name="filter" data-rozie-params=${(() => {
4920
5539
  try {
@@ -4922,7 +5541,8 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4922
5541
  columnId: header.column.id,
4923
5542
  value: this.columnFilterValue(header.column.id),
4924
5543
  uniqueValues: this.getFacetedUniqueValues(header.column.id),
4925
- minMax: this.getFacetedMinMaxValues(header.column.id)
5544
+ minMax: this.getFacetedMinMaxValues(header.column.id),
5545
+ columnLabel: this.headerLabel(header.column.id)
4926
5546
  });
4927
5547
  } catch {
4928
5548
  return "{}";
@@ -4949,9 +5569,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
4949
5569
  "rdt-td": true,
4950
5570
  "rdt-select-td": this.isSelectColumn(cell.column.id),
4951
5571
  "rdt-expander-td": this.isExpanderColumn(cell.column.id),
5572
+ "rdt-pinned": this.columnPinSide(cell.column.id) !== "",
4952
5573
  "rdt-in-range": this.inRange(this.rowIndexOf(row), this.colIndexOf(row, cell)),
4953
5574
  "rdt-cell-active": this.isActiveCell(String(this.rowIndexOf(row)), this.colIndexOf(row, cell))
4954
- }).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>
4955
5576
 
4956
5577
  ${this.isExpanderColumn(cell.column.id) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
4957
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) => {
@@ -5018,27 +5639,29 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5018
5639
  </span>
5019
5640
  <span class="rdt-group-count" data-rozie-s-d5dcab4c>${rozieDisplay("(" + this.groupSubRowCount(row) + ")")}</span>
5020
5641
  </span>` : this.isEditing(this.rowIndexOf(row), this.colIndexOf(row, cell)) ? html`<span style="display:contents" data-rozie-s-d5dcab4c>
5021
- ${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) => {
5022
5643
  this.onCellEditorInput(cell.column.id, $event);
5023
5644
  }} @keydown=${($event) => {
5024
5645
  this.onEditorKeyDown($event);
5025
5646
  }} @blur=${($event) => {
5026
5647
  this.onEditorBlur($event);
5027
- }} 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) => {
5028
5649
  this.onCellEditorInput(cell.column.id, $event);
5029
5650
  }} @keydown=${($event) => {
5030
5651
  this.onEditorKeyDown($event);
5031
5652
  }} @blur=${($event) => {
5032
5653
  this.onEditorBlur($event);
5033
5654
  }} data-rozie-s-d5dcab4c>
5034
- ${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>`)}
5035
- </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) => {
5036
5657
  this.onCellEditorCheckbox(cell.column.id, $event);
5037
5658
  }} @keydown=${($event) => {
5038
5659
  this.onEditorKeyDown($event);
5039
5660
  }} @blur=${($event) => {
5040
5661
  this.onEditorBlur($event);
5041
- }} 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>
5042
5665
  ${this.rozieSlots?.[`editor-${cell.column.id}`] !== void 0 ? this.rozieSlots?.[`editor-${cell.column.id}`]({
5043
5666
  columnId: cell.column.id,
5044
5667
  column: cell.column,
@@ -5046,6 +5669,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5046
5669
  value: this.editorValueFor(cell.column.id),
5047
5670
  commit: this.editorCommitFor(cell.column.id),
5048
5671
  cancel: this.editorCancelFor(),
5672
+ columnLabel: this.headerLabel(cell.column.id),
5049
5673
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5050
5674
  }) : html`<slot name="${`editor-${cell.column.id}`}" data-rozie-params=${(() => {
5051
5675
  try {
@@ -5056,6 +5680,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5056
5680
  value: this.editorValueFor(cell.column.id),
5057
5681
  commit: this.editorCommitFor(cell.column.id),
5058
5682
  cancel: this.editorCancelFor(),
5683
+ columnLabel: this.headerLabel(cell.column.id),
5059
5684
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5060
5685
  });
5061
5686
  } catch {
@@ -5069,6 +5694,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5069
5694
  value: this.editorValueFor(cell.column.id),
5070
5695
  commit: this.editorCommitFor(cell.column.id),
5071
5696
  cancel: this.editorCancelFor(),
5697
+ columnLabel: this.headerLabel(cell.column.id),
5072
5698
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5073
5699
  }) : html`<slot name="editor" data-rozie-params=${(() => {
5074
5700
  try {
@@ -5079,13 +5705,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5079
5705
  value: this.editorValueFor(cell.column.id),
5080
5706
  commit: this.editorCommitFor(cell.column.id),
5081
5707
  cancel: this.editorCancelFor(),
5708
+ columnLabel: this.headerLabel(cell.column.id),
5082
5709
  autofocus: this.editorAutofocusFor(cell.column.id, this.rowIndexOf(row))
5083
5710
  });
5084
5711
  } catch {
5085
5712
  return "{}";
5086
5713
  }
5087
5714
  })()}>
5088
- <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) => {
5089
5716
  this.onCellEditorInput(cell.column.id, $event);
5090
5717
  }} @keydown=${($event) => {
5091
5718
  this.onEditorKeyDown($event);
@@ -5094,7 +5721,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5094
5721
  }} data-rozie-s-d5dcab4c />
5095
5722
  </slot>`}
5096
5723
  </slot>`}
5097
- </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) => {
5098
5725
  this.onCellEditorInput(cell.column.id, $event);
5099
5726
  }} @keydown=${($event) => {
5100
5727
  this.onEditorKeyDown($event);
@@ -5166,10 +5793,10 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
5166
5793
  <select class="rdt-page-size" aria-label="Rows per page" .value=${this.pageSize()} @change=${($event) => {
5167
5794
  this.onPageSizeChange($event);
5168
5795
  }} data-rozie-s-d5dcab4c>
5169
- <option value=${10} data-rozie-s-d5dcab4c>10</option>
5170
- <option value=${25} data-rozie-s-d5dcab4c>25</option>
5171
- <option value=${50} data-rozie-s-d5dcab4c>50</option>
5172
- <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>
5173
5800
  </select>
5174
5801
  </div>` : nothing}</div>
5175
5802
  `;
@@ -5292,6 +5919,7 @@ __decorate([property({
5292
5919
  type: Object,
5293
5920
  attribute: "expanded"
5294
5921
  })], DataTable.prototype, "_expanded_attr", void 0);
5922
+ __decorate([property({ type: Function })], DataTable.prototype, "getRowId", void 0);
5295
5923
  __decorate([property({ type: Function })], DataTable.prototype, "getSubRows", void 0);
5296
5924
  __decorate([property({
5297
5925
  type: Boolean,
@@ -5373,6 +6001,12 @@ __decorate([state()], DataTable.prototype, "_hasSlotDynamicColHeader", void 0);
5373
6001
  __decorate([queryAssignedElements({ flatten: true })], DataTable.prototype, "_slotDynamicColHeaderElements", void 0);
5374
6002
  __decorate([state()], DataTable.prototype, "_hasSlotDynamicFilter", void 0);
5375
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);
5376
6010
  __decorate([state()], DataTable.prototype, "_hasSlotSelectCell", void 0);
5377
6011
  __decorate([queryAssignedElements({
5378
6012
  slot: "selectCell",
@@ -5570,15 +6204,19 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5570
6204
  this.commit = null;
5571
6205
  this.cancel = null;
5572
6206
  this.autofocus = false;
6207
+ this.columnLabel = "";
5573
6208
  this._draft = signal("");
6209
+ this._touched = signal(false);
5574
6210
  this.__rozieFirstUpdateDone = false;
5575
6211
  this._disconnectCleanups = [];
5576
6212
  this._rozieTornDown = false;
6213
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5577
6214
  this.onInput = (e) => {
5578
6215
  this._draft.value = e && e.target ? e.target.value : "";
6216
+ this._touched.value = true;
5579
6217
  };
5580
6218
  this.doCommit = () => {
5581
- this.commit && this.commit(this._draft.value);
6219
+ this.commit && this.commit(this.draftValue());
5582
6220
  };
5583
6221
  this.doCancel = () => {
5584
6222
  this.cancel && this.cancel();
@@ -5595,6 +6233,10 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5595
6233
  this.onBlur = () => {
5596
6234
  this.doCommit();
5597
6235
  };
6236
+ this.a11yLabel = () => {
6237
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6238
+ return this.columnId;
6239
+ };
5598
6240
  }
5599
6241
  static {
5600
6242
  this.styles = css`
@@ -5602,7 +6244,6 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5602
6244
  `;
5603
6245
  }
5604
6246
  firstUpdated() {
5605
- this._draft.value = this.value != null ? String(this.value) : "";
5606
6247
  if (this.autofocus) this._refInputEl?.focus();
5607
6248
  }
5608
6249
  updated(changedProperties) {
@@ -5622,7 +6263,7 @@ let EditorText = class EditorText extends SignalWatcher(LitElement) {
5622
6263
  }
5623
6264
  render() {
5624
6265
  return html`
5625
- <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) => {
5626
6267
  this.onInput($event);
5627
6268
  }} @keydown=${($event) => {
5628
6269
  this.onKeydown($event);
@@ -5645,6 +6286,10 @@ __decorate([property({
5645
6286
  type: Boolean,
5646
6287
  reflect: true
5647
6288
  })], EditorText.prototype, "autofocus", void 0);
6289
+ __decorate([property({
6290
+ type: String,
6291
+ reflect: true
6292
+ })], EditorText.prototype, "columnLabel", void 0);
5648
6293
  __decorate([query("[data-rozie-ref=\"inputEl\"]")], EditorText.prototype, "_refInputEl", void 0);
5649
6294
  EditorText = __decorate([customElement("rozie-editor-text")], EditorText);
5650
6295
  var EditorText_default = EditorText;
@@ -5659,15 +6304,21 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5659
6304
  this.value = null;
5660
6305
  this.commit = null;
5661
6306
  this.cancel = null;
6307
+ this.autofocus = false;
6308
+ this.columnLabel = "";
5662
6309
  this._draft = signal("");
6310
+ this._touched = signal(false);
6311
+ this.__rozieFirstUpdateDone = false;
5663
6312
  this._disconnectCleanups = [];
5664
6313
  this._rozieTornDown = false;
6314
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5665
6315
  this.onInput = (e) => {
5666
6316
  this._draft.value = e && e.target ? e.target.value : "";
6317
+ this._touched.value = true;
5667
6318
  };
5668
6319
  this.doCommit = () => {
5669
6320
  if (!this.commit) return;
5670
- const raw = this._draft.value;
6321
+ const raw = this.draftValue();
5671
6322
  if (raw == null || String(raw).trim() === "") {
5672
6323
  this.commit(null);
5673
6324
  return;
@@ -5690,6 +6341,10 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5690
6341
  this.onBlur = () => {
5691
6342
  this.doCommit();
5692
6343
  };
6344
+ this.a11yLabel = () => {
6345
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6346
+ return this.columnId;
6347
+ };
5693
6348
  }
5694
6349
  static {
5695
6350
  this.styles = css`
@@ -5697,7 +6352,13 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5697
6352
  `;
5698
6353
  }
5699
6354
  firstUpdated() {
5700
- 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;
5701
6362
  }
5702
6363
  disconnectedCallback() {
5703
6364
  super.disconnectedCallback();
@@ -5710,13 +6371,13 @@ let EditorNumber = class EditorNumber extends SignalWatcher(LitElement) {
5710
6371
  }
5711
6372
  render() {
5712
6373
  return html`
5713
- <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) => {
5714
6375
  this.onInput($event);
5715
6376
  }} @keydown=${($event) => {
5716
6377
  this.onKeydown($event);
5717
6378
  }} @blur=${($event) => {
5718
6379
  this.onBlur();
5719
- }} data-rozie-s-b2792b32 />
6380
+ }} data-rozie-ref="inputEl" data-rozie-s-b2792b32 />
5720
6381
  `;
5721
6382
  }
5722
6383
  };
@@ -5729,6 +6390,15 @@ __decorate([property({ type: Object })], EditorNumber.prototype, "row", void 0);
5729
6390
  __decorate([property({ type: Object })], EditorNumber.prototype, "value", void 0);
5730
6391
  __decorate([property({ type: Function })], EditorNumber.prototype, "commit", void 0);
5731
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);
5732
6402
  EditorNumber = __decorate([customElement("rozie-editor-number")], EditorNumber);
5733
6403
  var EditorNumber_default = EditorNumber;
5734
6404
  //#endregion
@@ -5743,14 +6413,20 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5743
6413
  this.commit = null;
5744
6414
  this.cancel = null;
5745
6415
  this.options = [];
6416
+ this.autofocus = false;
6417
+ this.columnLabel = "";
5746
6418
  this._draft = signal("");
6419
+ this._touched = signal(false);
6420
+ this.__rozieFirstUpdateDone = false;
5747
6421
  this._disconnectCleanups = [];
5748
6422
  this._rozieTornDown = false;
6423
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5749
6424
  this.onChange = (e) => {
5750
6425
  this._draft.value = e && e.target ? e.target.value : "";
6426
+ this._touched.value = true;
5751
6427
  };
5752
6428
  this.doCommit = () => {
5753
- this.commit && this.commit(this._draft.value);
6429
+ this.commit && this.commit(this.draftValue());
5754
6430
  };
5755
6431
  this.doCancel = () => {
5756
6432
  this.cancel && this.cancel();
@@ -5767,6 +6443,10 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5767
6443
  this.onBlur = () => {
5768
6444
  this.doCommit();
5769
6445
  };
6446
+ this.a11yLabel = () => {
6447
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6448
+ return this.columnId;
6449
+ };
5770
6450
  }
5771
6451
  static {
5772
6452
  this.styles = css`
@@ -5774,7 +6454,13 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5774
6454
  `;
5775
6455
  }
5776
6456
  firstUpdated() {
5777
- 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;
5778
6464
  }
5779
6465
  disconnectedCallback() {
5780
6466
  super.disconnectedCallback();
@@ -5787,14 +6473,14 @@ let EditorSelect = class EditorSelect extends SignalWatcher(LitElement) {
5787
6473
  }
5788
6474
  render() {
5789
6475
  return html`
5790
- <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) => {
5791
6477
  this.onChange($event);
5792
6478
  }} @keydown=${($event) => {
5793
6479
  this.onKeydown($event);
5794
6480
  }} @blur=${($event) => {
5795
6481
  this.onBlur();
5796
- }} data-rozie-s-117f1a16>
5797
- ${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>`)}
5798
6484
  </select>
5799
6485
  `;
5800
6486
  }
@@ -5809,6 +6495,15 @@ __decorate([property({ type: Object })], EditorSelect.prototype, "value", void 0
5809
6495
  __decorate([property({ type: Function })], EditorSelect.prototype, "commit", void 0);
5810
6496
  __decorate([property({ type: Function })], EditorSelect.prototype, "cancel", void 0);
5811
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);
5812
6507
  EditorSelect = __decorate([customElement("rozie-editor-select")], EditorSelect);
5813
6508
  var EditorSelect_default = EditorSelect;
5814
6509
  //#endregion
@@ -5822,6 +6517,9 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5822
6517
  this.value = null;
5823
6518
  this.commit = null;
5824
6519
  this.cancel = null;
6520
+ this.autofocus = false;
6521
+ this.columnLabel = "";
6522
+ this.__rozieFirstUpdateDone = false;
5825
6523
  this._disconnectCleanups = [];
5826
6524
  this._rozieTornDown = false;
5827
6525
  this.onChange = (e) => {
@@ -5833,12 +6531,25 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5833
6531
  this.cancel && this.cancel();
5834
6532
  }
5835
6533
  };
6534
+ this.a11yLabel = () => {
6535
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6536
+ return this.columnId;
6537
+ };
5836
6538
  }
5837
6539
  static {
5838
6540
  this.styles = css`
5839
6541
  :host{display:contents}
5840
6542
  `;
5841
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
+ }
5842
6553
  disconnectedCallback() {
5843
6554
  super.disconnectedCallback();
5844
6555
  queueMicrotask(() => {
@@ -5850,11 +6561,11 @@ let EditorCheckbox = class EditorCheckbox extends SignalWatcher(LitElement) {
5850
6561
  }
5851
6562
  render() {
5852
6563
  return html`
5853
- <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) => {
5854
6565
  this.onChange($event);
5855
6566
  }} @keydown=${($event) => {
5856
6567
  this.onKeydown($event);
5857
- }} data-rozie-s-3d792482 />
6568
+ }} data-rozie-ref="inputEl" data-rozie-s-3d792482 />
5858
6569
  `;
5859
6570
  }
5860
6571
  };
@@ -5867,9 +6578,51 @@ __decorate([property({ type: Object })], EditorCheckbox.prototype, "row", void 0
5867
6578
  __decorate([property({ type: Object })], EditorCheckbox.prototype, "value", void 0);
5868
6579
  __decorate([property({ type: Function })], EditorCheckbox.prototype, "commit", void 0);
5869
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);
5870
6590
  EditorCheckbox = __decorate([customElement("rozie-editor-checkbox")], EditorCheckbox);
5871
6591
  var EditorCheckbox_default = EditorCheckbox;
5872
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
5873
6626
  //#region src/EditorDate.ts
5874
6627
  let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5875
6628
  constructor(..._args) {
@@ -5880,20 +6633,27 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5880
6633
  this.value = null;
5881
6634
  this.commit = null;
5882
6635
  this.cancel = null;
6636
+ this.autofocus = false;
6637
+ this.columnLabel = "";
5883
6638
  this._draft = signal("");
6639
+ this._touched = signal(false);
6640
+ this.__rozieFirstUpdateDone = false;
5884
6641
  this._disconnectCleanups = [];
5885
6642
  this._rozieTornDown = false;
6643
+ this.draftValue = () => this._touched.value ? this._draft.value : toIsoDateString(this.value);
5886
6644
  this.onInput = (e) => {
5887
6645
  this._draft.value = e && e.target ? e.target.value : "";
6646
+ this._touched.value = true;
5888
6647
  };
5889
6648
  this.doCommit = () => {
5890
- this.commit && this.commit(this._draft.value);
6649
+ this.commit && this.commit(this.draftValue());
5891
6650
  };
5892
6651
  this.doCancel = () => {
5893
6652
  this.cancel && this.cancel();
5894
6653
  };
5895
6654
  this.onChange = (e) => {
5896
6655
  this._draft.value = e && e.target ? e.target.value : "";
6656
+ this._touched.value = true;
5897
6657
  };
5898
6658
  this.onKeydown = (e) => {
5899
6659
  if (e && e.key === "Enter") {
@@ -5907,6 +6667,10 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5907
6667
  this.onBlur = () => {
5908
6668
  this.doCommit();
5909
6669
  };
6670
+ this.a11yLabel = () => {
6671
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6672
+ return this.columnId;
6673
+ };
5910
6674
  }
5911
6675
  static {
5912
6676
  this.styles = css`
@@ -5914,7 +6678,13 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5914
6678
  `;
5915
6679
  }
5916
6680
  firstUpdated() {
5917
- 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;
5918
6688
  }
5919
6689
  disconnectedCallback() {
5920
6690
  super.disconnectedCallback();
@@ -5927,7 +6697,7 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5927
6697
  }
5928
6698
  render() {
5929
6699
  return html`
5930
- <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) => {
5931
6701
  this.onInput($event);
5932
6702
  }} @change=${($event) => {
5933
6703
  this.onChange($event);
@@ -5935,7 +6705,7 @@ let EditorDate = class EditorDate extends SignalWatcher(LitElement) {
5935
6705
  this.onKeydown($event);
5936
6706
  }} @blur=${($event) => {
5937
6707
  this.onBlur();
5938
- }} data-rozie-s-7abe1a56 />
6708
+ }} data-rozie-ref="inputEl" data-rozie-s-7abe1a56 />
5939
6709
  `;
5940
6710
  }
5941
6711
  };
@@ -5948,6 +6718,15 @@ __decorate([property({ type: Object })], EditorDate.prototype, "row", void 0);
5948
6718
  __decorate([property({ type: Object })], EditorDate.prototype, "value", void 0);
5949
6719
  __decorate([property({ type: Function })], EditorDate.prototype, "commit", void 0);
5950
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);
5951
6730
  EditorDate = __decorate([customElement("rozie-editor-date")], EditorDate);
5952
6731
  var EditorDate_default = EditorDate;
5953
6732
  //#endregion
@@ -5959,17 +6738,23 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
5959
6738
  this.column = null;
5960
6739
  this.value = null;
5961
6740
  this.setFilter = null;
6741
+ this.columnLabel = "";
5962
6742
  this._draft = signal("");
6743
+ this._touched = signal(false);
6744
+ this.__rozieFirstUpdateDone = false;
5963
6745
  this._disconnectCleanups = [];
5964
6746
  this._rozieTornDown = false;
6747
+ this.draftValue = () => this._touched.value ? this._draft.value : this.value != null ? String(this.value) : "";
5965
6748
  this.onInput = (e) => {
5966
6749
  this._draft.value = e && e.target ? e.target.value : "";
6750
+ this._touched.value = true;
5967
6751
  };
5968
6752
  this.applyFilter = () => {
5969
- this.setFilter && this.setFilter(this.columnId, this._draft.value);
6753
+ this.setFilter && this.setFilter(this.columnId, this.draftValue());
5970
6754
  };
5971
6755
  this.clearFilter = () => {
5972
6756
  this._draft.value = "";
6757
+ this._touched.value = false;
5973
6758
  this.setFilter && this.setFilter(this.columnId, "");
5974
6759
  };
5975
6760
  this.onKeydown = (e) => {
@@ -5984,14 +6769,22 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
5984
6769
  this.onBlur = () => {
5985
6770
  this.applyFilter();
5986
6771
  };
6772
+ this.a11yLabel = () => {
6773
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6774
+ return this.columnId;
6775
+ };
5987
6776
  }
5988
6777
  static {
5989
6778
  this.styles = css`
5990
6779
  :host{display:contents}
5991
6780
  `;
5992
6781
  }
5993
- firstUpdated() {
5994
- 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;
5995
6788
  }
5996
6789
  disconnectedCallback() {
5997
6790
  super.disconnectedCallback();
@@ -6004,7 +6797,7 @@ let FilterText = class FilterText extends SignalWatcher(LitElement) {
6004
6797
  }
6005
6798
  render() {
6006
6799
  return html`
6007
- <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) => {
6008
6801
  this.onInput($event);
6009
6802
  }} @keydown=${($event) => {
6010
6803
  this.onKeydown($event);
@@ -6021,6 +6814,10 @@ __decorate([property({
6021
6814
  __decorate([property({ type: Object })], FilterText.prototype, "column", void 0);
6022
6815
  __decorate([property({ type: Object })], FilterText.prototype, "value", void 0);
6023
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);
6024
6821
  FilterText = __decorate([customElement("rozie-filter-text")], FilterText);
6025
6822
  var FilterText_default = FilterText;
6026
6823
  //#endregion
@@ -6033,24 +6830,41 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6033
6830
  this.value = null;
6034
6831
  this.setFilter = null;
6035
6832
  this.minMax = null;
6833
+ this.columnLabel = "";
6036
6834
  this._minDraft = signal("");
6037
6835
  this._maxDraft = signal("");
6836
+ this._touched = signal(false);
6837
+ this.__rozieWatchInitial_0 = true;
6038
6838
  this._disconnectCleanups = [];
6039
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]) : "";
6040
6842
  this.onMinInput = (e) => {
6041
6843
  this._minDraft.value = e && e.target ? e.target.value : "";
6844
+ this._touched.value = true;
6042
6845
  };
6043
6846
  this.onMaxInput = (e) => {
6044
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());
6045
6855
  };
6046
6856
  this.minPlaceholder = () => Array.isArray(this.minMax) && this.minMax[0] != null ? String(this.minMax[0]) : "";
6047
6857
  this.maxPlaceholder = () => Array.isArray(this.minMax) && this.minMax[1] != null ? String(this.minMax[1]) : "";
6048
- this.applyRange = () => {
6049
- const minNum = this._minDraft.value === "" ? void 0 : Number(this._minDraft.value);
6050
- 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);
6051
6861
  if (minNum === void 0 && maxNum === void 0) this.setFilter && this.setFilter(this.columnId, "");
6052
6862
  else this.setFilter && this.setFilter(this.columnId, [minNum, maxNum]);
6053
6863
  };
6864
+ this.a11yLabel = () => {
6865
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6866
+ return this.columnId;
6867
+ };
6054
6868
  }
6055
6869
  static {
6056
6870
  this.styles = css`
@@ -6058,8 +6872,16 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6058
6872
  `;
6059
6873
  }
6060
6874
  firstUpdated() {
6061
- this._minDraft.value = Array.isArray(this.value) && this.value[0] != null ? String(this.value[0]) : "";
6062
- 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
+ }));
6063
6885
  }
6064
6886
  disconnectedCallback() {
6065
6887
  super.disconnectedCallback();
@@ -6073,16 +6895,20 @@ let FilterNumberRange = class FilterNumberRange extends SignalWatcher(LitElement
6073
6895
  render() {
6074
6896
  return html`
6075
6897
  <span style="display:flex; align-items: center" data-rozie-s-97b2c090>
6076
- <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) => {
6077
6899
  this.onMinInput($event);
6078
- }} @change=${($event) => {
6079
- this.applyRange();
6900
+ }} @keydown=${($event) => {
6901
+ this.onKeydown($event);
6902
+ }} @blur=${($event) => {
6903
+ this.onBlur();
6080
6904
  }} data-rozie-s-97b2c090 />
6081
6905
  <span data-rozie-s-97b2c090> - </span>
6082
- <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) => {
6083
6907
  this.onMaxInput($event);
6084
- }} @change=${($event) => {
6085
- this.applyRange();
6908
+ }} @keydown=${($event) => {
6909
+ this.onKeydown($event);
6910
+ }} @blur=${($event) => {
6911
+ this.onBlur();
6086
6912
  }} data-rozie-s-97b2c090 />
6087
6913
  </span>
6088
6914
  `;
@@ -6096,6 +6922,10 @@ __decorate([property({ type: Object })], FilterNumberRange.prototype, "column",
6096
6922
  __decorate([property({ type: Object })], FilterNumberRange.prototype, "value", void 0);
6097
6923
  __decorate([property({ type: Function })], FilterNumberRange.prototype, "setFilter", void 0);
6098
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);
6099
6929
  FilterNumberRange = __decorate([customElement("rozie-filter-number-range")], FilterNumberRange);
6100
6930
  var FilterNumberRange_default = FilterNumberRange;
6101
6931
  //#endregion
@@ -6108,6 +6938,7 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6108
6938
  this.value = null;
6109
6939
  this.setFilter = null;
6110
6940
  this.uniqueValues = [];
6941
+ this.columnLabel = "";
6111
6942
  this._disconnectCleanups = [];
6112
6943
  this._rozieTornDown = false;
6113
6944
  this.selectValue = () => this.value != null ? String(this.value) : "";
@@ -6116,6 +6947,10 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6116
6947
  if (v === "") this.setFilter && this.setFilter(this.columnId, "");
6117
6948
  else this.setFilter && this.setFilter(this.columnId, v);
6118
6949
  };
6950
+ this.a11yLabel = () => {
6951
+ if (typeof this.columnLabel === "string" && this.columnLabel !== "") return this.columnLabel;
6952
+ return this.columnId;
6953
+ };
6119
6954
  }
6120
6955
  static {
6121
6956
  this.styles = css`
@@ -6133,11 +6968,11 @@ let FilterSelect = class FilterSelect extends SignalWatcher(LitElement) {
6133
6968
  }
6134
6969
  render() {
6135
6970
  return html`
6136
- <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) => {
6137
6972
  this.onChange($event);
6138
6973
  }} data-rozie-s-d75b42b2>
6139
6974
  <option value="" data-rozie-s-d75b42b2>All</option>
6140
- ${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>`)}
6141
6976
  </select>
6142
6977
  `;
6143
6978
  }
@@ -6150,6 +6985,10 @@ __decorate([property({ type: Object })], FilterSelect.prototype, "column", void
6150
6985
  __decorate([property({ type: Object })], FilterSelect.prototype, "value", void 0);
6151
6986
  __decorate([property({ type: Function })], FilterSelect.prototype, "setFilter", void 0);
6152
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);
6153
6992
  FilterSelect = __decorate([customElement("rozie-filter-select")], FilterSelect);
6154
6993
  var FilterSelect_default = FilterSelect;
6155
6994
  //#endregion
@@ -6225,6 +7064,42 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6225
7064
  this.removeKey = (key) => {
6226
7065
  this.applyGrouping && this.applyGrouping(this.grouping.filter((k) => k !== key));
6227
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
+ };
6228
7103
  this.clearAll = () => {
6229
7104
  this.clearGrouping && this.clearGrouping();
6230
7105
  };
@@ -6253,6 +7128,18 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6253
7128
  border-color: var(--rdt-group-drop-zone-border-over, rgba(37, 99, 235, 0.7));
6254
7129
  background: var(--rdt-group-drop-zone-bg-over, rgba(37, 99, 235, 0.08));
6255
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
+ }
6256
7143
  .rdt-group-drop-hint[data-rozie-s-546c469a] {
6257
7144
  opacity: 0.55;
6258
7145
  font-size: 0.8125em;
@@ -6308,17 +7195,19 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6308
7195
  return html`
6309
7196
  <div class="rdt-group-bar" data-rozie-s-546c469a>
6310
7197
 
6311
- ${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) => {
6312
7199
  this.onChipDragStart($event, col.id);
6313
7200
  }} @dragend=${($event) => {
6314
7201
  this.onDragEnd();
6315
- }} 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>`)}
6316
7205
 
6317
7206
 
6318
7207
  <span class="${Object.entries({
6319
7208
  "rdt-group-drop-zone": true,
6320
7209
  "is-over": this._isOver.value
6321
- }).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) => {
6322
7211
  this.onDragOver($event);
6323
7212
  }} @dragleave=${($event) => {
6324
7213
  this.onDragLeave($event);
@@ -6329,12 +7218,14 @@ let GroupBar = class GroupBar extends SignalWatcher(LitElement) {
6329
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({
6330
7219
  "rdt-group-token": true,
6331
7220
  "is-drop-target": this._dragKind.value === "token" && this._dropKey.value === gk && this._draggingId.value !== gk
6332
- }).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) => {
6333
7222
  this.onTokenDragStart($event, gk);
6334
7223
  }} @dragover=${($event) => {
6335
7224
  this.onTokenDragOver($event, gk);
6336
7225
  }} @dragend=${($event) => {
6337
7226
  this.onDragEnd();
7227
+ }} @keydown=${($event) => {
7228
+ this.onTokenKeydown($event, gk);
6338
7229
  }} data-rozie-s-546c469a>
6339
7230
  ${rozieDisplay(this.labelFor(gk))}
6340
7231
  <button class="rdt-group-token-remove" type="button" aria-label=${rozieAttr("Remove " + this.labelFor(gk) + " grouping")} @click=${($event) => {