@design.estate/dees-catalog 3.65.0 → 3.66.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.
@@ -163781,7 +163781,8 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
163781
163781
  <dees-table
163782
163782
  id="scrollSmallHeight"
163783
163783
  .fixedHeight=${true}
163784
- heading1="People Directory (Scrollable)"
163784
+ .virtualized=${true}
163785
+ heading1="People Directory (Scrollable, Virtualized)"
163785
163786
  heading2="Forced scrolling with many items"
163786
163787
  .columns=${[
163787
163788
  { key: "id", header: "ID", sortable: true },
@@ -164580,7 +164581,7 @@ __name(compileLucenePredicate, "compileLucenePredicate");
164580
164581
  init_dist_ts30();
164581
164582
  init_dist_ts29();
164582
164583
  init_theme();
164583
- var ___editingCell_dec, ___focusedCell_dec, _selectedIds_dec, _selectionMode_dec, _searchMode_dec, _fixedHeight_dec, _showSelectionCheckbox_dec, _showColumnFilters_dec, _columnFilters_dec, _filterText_dec, _sortBy_dec, _showGrid_dec, _showHorizontalLines_dec, _showVerticalLines_dec, _selectedDataRow_dec, _reverseDisplayFunction_dec, _displayFunction_dec, _augmentFromDisplayFunction_dec, _rowKey_dec, _columns_dec, _dataActions_dec, _searchable_dec, _dataName_dec, _required_dec3, _disabled_dec3, _label_dec3, _key_dec2, _data_dec, _heading2_dec, _heading1_dec, _a42, _DeesTable_decorators, _init39, _heading1, _heading22, _data, _key2, _label3, _disabled3, _required3, _dataName, _searchable, _dataActions, _columns, _rowKey, _augmentFromDisplayFunction, _displayFunction, _reverseDisplayFunction, _selectedDataRow, _showVerticalLines, _showHorizontalLines, _showGrid, _sortBy, _filterText, _columnFilters, _showColumnFilters, _showSelectionCheckbox, _fixedHeight, _searchMode, _selectionMode, _selectedIds, ___focusedCell, ___editingCell;
164584
+ var ___virtualRange_dec, ___floatingActive_dec, ___editingCell_dec, ___focusedCell_dec, _selectedIds_dec, _selectionMode_dec, _searchMode_dec, _fixedHeight_dec, _virtualOverscan_dec, _virtualized_dec, _showSelectionCheckbox_dec, _showColumnFilters_dec, _columnFilters_dec, _filterText_dec, _sortBy_dec, _showGrid_dec, _showHorizontalLines_dec, _showVerticalLines_dec, _selectedDataRow_dec, _reverseDisplayFunction_dec, _displayFunction_dec, _augmentFromDisplayFunction_dec, _rowKey_dec, _columns_dec, _dataActions_dec, _searchable_dec, _dataName_dec, _required_dec3, _disabled_dec3, _label_dec3, _key_dec2, _data_dec, _heading2_dec, _heading1_dec, _a42, _DeesTable_decorators, _init39, _heading1, _heading22, _data, _key2, _label3, _disabled3, _required3, _dataName, _searchable, _dataActions, _columns, _rowKey, _augmentFromDisplayFunction, _displayFunction, _reverseDisplayFunction, _selectedDataRow, _showVerticalLines, _showHorizontalLines, _showGrid, _sortBy, _filterText, _columnFilters, _showColumnFilters, _showSelectionCheckbox, _virtualized, _virtualOverscan, _fixedHeight, _searchMode, _selectionMode, _selectedIds, ___focusedCell, ___editingCell, ___floatingActive, ___virtualRange;
164584
164585
  function ordinalLabel(n12) {
164585
164586
  const s10 = ["th", "st", "nd", "rd"];
164586
164587
  const v5 = n12 % 100;
@@ -164627,7 +164628,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164627
164628
  type: Boolean,
164628
164629
  reflect: true,
164629
164630
  attribute: "show-grid"
164630
- })], _sortBy_dec = [n5({ attribute: false })], _filterText_dec = [n5({ type: String })], _columnFilters_dec = [n5({ attribute: false })], _showColumnFilters_dec = [n5({ type: Boolean, attribute: "show-column-filters" })], _showSelectionCheckbox_dec = [n5({ type: Boolean, reflect: true, attribute: "show-selection-checkbox" })], _fixedHeight_dec = [n5({ type: Boolean, reflect: true, attribute: "fixed-height" })], _searchMode_dec = [n5({ type: String })], _selectionMode_dec = [n5({ type: String })], _selectedIds_dec = [n5({ attribute: false })], ___focusedCell_dec = [r5()], ___editingCell_dec = [r5()], _a42) {
164631
+ })], _sortBy_dec = [n5({ attribute: false })], _filterText_dec = [n5({ type: String })], _columnFilters_dec = [n5({ attribute: false })], _showColumnFilters_dec = [n5({ type: Boolean, attribute: "show-column-filters" })], _showSelectionCheckbox_dec = [n5({ type: Boolean, reflect: true, attribute: "show-selection-checkbox" })], _virtualized_dec = [n5({ type: Boolean, reflect: true, attribute: "virtualized" })], _virtualOverscan_dec = [n5({ type: Number, attribute: "virtual-overscan" })], _fixedHeight_dec = [n5({ type: Boolean, reflect: true, attribute: "fixed-height" })], _searchMode_dec = [n5({ type: String })], _selectionMode_dec = [n5({ type: String })], _selectedIds_dec = [n5({ attribute: false })], ___focusedCell_dec = [r5()], ___editingCell_dec = [r5()], ___floatingActive_dec = [r5()], ___virtualRange_dec = [r5()], _a42) {
164631
164632
  constructor() {
164632
164633
  super();
164633
164634
  __privateAdd(this, _heading1, __runInitializers(_init39, 8, this, "heading 1")), __runInitializers(_init39, 11, this);
@@ -164658,12 +164659,14 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164658
164659
  __privateAdd(this, _columnFilters, __runInitializers(_init39, 92, this, {})), __runInitializers(_init39, 95, this);
164659
164660
  __privateAdd(this, _showColumnFilters, __runInitializers(_init39, 96, this, false)), __runInitializers(_init39, 99, this);
164660
164661
  __privateAdd(this, _showSelectionCheckbox, __runInitializers(_init39, 100, this, false)), __runInitializers(_init39, 103, this);
164661
- __privateAdd(this, _fixedHeight, __runInitializers(_init39, 104, this, false)), __runInitializers(_init39, 107, this);
164662
- __privateAdd(this, _searchMode, __runInitializers(_init39, 108, this, "table")), __runInitializers(_init39, 111, this);
164662
+ __privateAdd(this, _virtualized, __runInitializers(_init39, 104, this, false)), __runInitializers(_init39, 107, this);
164663
+ __privateAdd(this, _virtualOverscan, __runInitializers(_init39, 108, this, 8)), __runInitializers(_init39, 111, this);
164664
+ __privateAdd(this, _fixedHeight, __runInitializers(_init39, 112, this, false)), __runInitializers(_init39, 115, this);
164665
+ __privateAdd(this, _searchMode, __runInitializers(_init39, 116, this, "table")), __runInitializers(_init39, 119, this);
164663
164666
  __publicField(this, "__searchTextSub");
164664
164667
  __publicField(this, "__searchModeSub");
164665
- __privateAdd(this, _selectionMode, __runInitializers(_init39, 112, this, "none")), __runInitializers(_init39, 115, this);
164666
- __privateAdd(this, _selectedIds, __runInitializers(_init39, 116, this, /* @__PURE__ */ new Set())), __runInitializers(_init39, 119, this);
164668
+ __privateAdd(this, _selectionMode, __runInitializers(_init39, 120, this, "none")), __runInitializers(_init39, 123, this);
164669
+ __privateAdd(this, _selectedIds, __runInitializers(_init39, 124, this, /* @__PURE__ */ new Set())), __runInitializers(_init39, 127, this);
164667
164670
  __publicField(this, "_rowIdMap", /* @__PURE__ */ new WeakMap());
164668
164671
  __publicField(this, "_rowIdCounter", 0);
164669
164672
  /**
@@ -164672,8 +164675,23 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164672
164675
  * can compute a contiguous range from this anchor.
164673
164676
  */
164674
164677
  __publicField(this, "__selectionAnchorId");
164675
- __privateAdd(this, ___focusedCell, __runInitializers(_init39, 120, this)), __runInitializers(_init39, 123, this);
164676
- __privateAdd(this, ___editingCell, __runInitializers(_init39, 124, this)), __runInitializers(_init39, 127, this);
164678
+ __privateAdd(this, ___focusedCell, __runInitializers(_init39, 128, this)), __runInitializers(_init39, 131, this);
164679
+ __privateAdd(this, ___editingCell, __runInitializers(_init39, 132, this)), __runInitializers(_init39, 135, this);
164680
+ __privateAdd(this, ___floatingActive, __runInitializers(_init39, 136, this, false)), __runInitializers(_init39, 139, this);
164681
+ // ─── Render memoization ──────────────────────────────────────────────
164682
+ // These caches let render() short-circuit when the relevant inputs
164683
+ // (by reference) haven't changed. They are NOT @state — mutating them
164684
+ // must never trigger a re-render.
164685
+ __publicField(this, "__memoEffectiveCols");
164686
+ __publicField(this, "__memoViewData");
164687
+ /** Tracks the (data, columns) pair that `determineColumnWidths()` last sized for. */
164688
+ __publicField(this, "__columnsSizedFor");
164689
+ // ─── Virtualization state ────────────────────────────────────────────
164690
+ /** Estimated row height (px). Measured once from the first rendered row. */
164691
+ __publicField(this, "__rowHeight", 36);
164692
+ /** True once we've measured `__rowHeight` from a real DOM row. */
164693
+ __publicField(this, "__rowHeightMeasured", false);
164694
+ __privateAdd(this, ___virtualRange, __runInitializers(_init39, 140, this, { start: 0, end: 0 })), __runInitializers(_init39, 143, this);
164677
164695
  /**
164678
164696
  * Ctrl/Cmd+C copies the currently selected rows as a JSON array. Falls
164679
164697
  * back to copying the focused-row (`selectedDataRow`) if no multi
@@ -164753,9 +164771,110 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164753
164771
  // ─── Floating header (page-sticky) lifecycle ─────────────────────────
164754
164772
  __publicField(this, "__floatingResizeObserver");
164755
164773
  __publicField(this, "__floatingScrollHandler");
164756
- __publicField(this, "__floatingActive", false);
164774
+ // __floatingActive is declared as a @state field above so its toggle
164775
+ // triggers re-rendering of the floating-header clone subtree.
164757
164776
  __publicField(this, "__scrollAncestors", []);
164758
164777
  __publicField(this, "__debounceTimer");
164778
+ __publicField(this, "__onTbodyClick", /* @__PURE__ */ __name((eventArg) => {
164779
+ if (this.__isInEditor(eventArg) || this.__isInActionsCol(eventArg)) return;
164780
+ const cell2 = this.__resolveCell(eventArg);
164781
+ if (!cell2) return;
164782
+ const view = this._lastViewData ?? [];
164783
+ if (cell2.col.editable || cell2.col.editor) {
164784
+ this.__focusedCell = {
164785
+ rowId: this.getRowId(cell2.item),
164786
+ colKey: String(cell2.col.key)
164787
+ };
164788
+ }
164789
+ this.handleRowClick(eventArg, cell2.item, cell2.rowIdx, view);
164790
+ }, "__onTbodyClick"));
164791
+ __publicField(this, "__onTbodyDblclick", /* @__PURE__ */ __name((eventArg) => {
164792
+ if (this.__isInEditor(eventArg) || this.__isInActionsCol(eventArg)) return;
164793
+ const cell2 = this.__resolveCell(eventArg);
164794
+ if (!cell2) return;
164795
+ const isEditable = !!(cell2.col.editable || cell2.col.editor);
164796
+ if (isEditable) {
164797
+ eventArg.stopPropagation();
164798
+ this.startEditing(cell2.item, cell2.col);
164799
+ return;
164800
+ }
164801
+ const dblAction = this.dataActions.find((a5) => a5.type?.includes("doubleClick"));
164802
+ if (dblAction) dblAction.actionFunc({ item: cell2.item, table: this });
164803
+ }, "__onTbodyDblclick"));
164804
+ __publicField(this, "__onTbodyMousedown", /* @__PURE__ */ __name((eventArg) => {
164805
+ if (eventArg.shiftKey && this.selectionMode !== "single") eventArg.preventDefault();
164806
+ }, "__onTbodyMousedown"));
164807
+ __publicField(this, "__onTbodyContextmenu", /* @__PURE__ */ __name((eventArg) => {
164808
+ if (this.__isInActionsCol(eventArg)) return;
164809
+ const row = this.__resolveRow(eventArg);
164810
+ if (!row) return;
164811
+ const item = row.item;
164812
+ if (!this.isRowSelected(item)) {
164813
+ this.selectedDataRow = item;
164814
+ this.selectedIds.clear();
164815
+ this.selectedIds.add(this.getRowId(item));
164816
+ this.__selectionAnchorId = this.getRowId(item);
164817
+ this.emitSelectionChange();
164818
+ this.requestUpdate();
164819
+ }
164820
+ const userItems = this.getActionsForType("contextmenu").map(
164821
+ (action) => ({
164822
+ name: action.name,
164823
+ iconName: action.iconName,
164824
+ action: /* @__PURE__ */ __name(async () => {
164825
+ await action.actionFunc({ item, table: this });
164826
+ return null;
164827
+ }, "action")
164828
+ })
164829
+ );
164830
+ const defaultItems = [
164831
+ {
164832
+ name: this.selectedIds.size > 1 ? `Copy ${this.selectedIds.size} rows as JSON` : "Copy row as JSON",
164833
+ iconName: "lucide:Copy",
164834
+ action: /* @__PURE__ */ __name(async () => {
164835
+ this.copySelectionAsJson(item);
164836
+ return null;
164837
+ }, "action")
164838
+ }
164839
+ ];
164840
+ DeesContextmenu.openContextMenuWithOptions(eventArg, [...userItems, ...defaultItems]);
164841
+ }, "__onTbodyContextmenu"));
164842
+ __publicField(this, "__onTbodyDragenter", /* @__PURE__ */ __name((eventArg) => {
164843
+ eventArg.preventDefault();
164844
+ eventArg.stopPropagation();
164845
+ const row = this.__resolveRow(eventArg);
164846
+ if (!row) return;
164847
+ const tr3 = (eventArg.composedPath?.() || []).find(
164848
+ (t9) => t9?.tagName === "TR"
164849
+ );
164850
+ if (tr3) setTimeout(() => tr3.classList.add("hasAttachment"), 0);
164851
+ }, "__onTbodyDragenter"));
164852
+ __publicField(this, "__onTbodyDragleave", /* @__PURE__ */ __name((eventArg) => {
164853
+ eventArg.preventDefault();
164854
+ eventArg.stopPropagation();
164855
+ const tr3 = (eventArg.composedPath?.() || []).find(
164856
+ (t9) => t9?.tagName === "TR"
164857
+ );
164858
+ if (tr3) tr3.classList.remove("hasAttachment");
164859
+ }, "__onTbodyDragleave"));
164860
+ __publicField(this, "__onTbodyDragover", /* @__PURE__ */ __name((eventArg) => {
164861
+ eventArg.preventDefault();
164862
+ }, "__onTbodyDragover"));
164863
+ __publicField(this, "__onTbodyDrop", /* @__PURE__ */ __name(async (eventArg) => {
164864
+ eventArg.preventDefault();
164865
+ const row = this.__resolveRow(eventArg);
164866
+ if (!row) return;
164867
+ const item = row.item;
164868
+ const newFiles = [];
164869
+ for (const file of Array.from(eventArg.dataTransfer.files)) {
164870
+ this.files.push(file);
164871
+ newFiles.push(file);
164872
+ this.requestUpdate();
164873
+ }
164874
+ const existing = this.fileWeakMap.get(item);
164875
+ if (!existing) this.fileWeakMap.set(item, newFiles);
164876
+ else existing.push(...newFiles);
164877
+ }, "__onTbodyDrop"));
164759
164878
  if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
164760
164879
  this.addEventListener("keydown", this.__handleHostKeydown);
164761
164880
  }
@@ -164788,24 +164907,83 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164788
164907
  } catch {
164789
164908
  }
164790
164909
  }
164791
- render() {
164910
+ /**
164911
+ * Returns the effective column schema, memoized by reference of the inputs
164912
+ * that affect it. Avoids re-running `computeEffectiveColumnsFn` /
164913
+ * `computeColumnsFromDisplayFunctionFn` on every Lit update.
164914
+ */
164915
+ __getEffectiveColumns() {
164792
164916
  const usingColumns = Array.isArray(this.columns) && this.columns.length > 0;
164793
- const effectiveColumns = usingColumns ? computeEffectiveColumns(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
164794
- const lucenePred = compileLucenePredicate(
164795
- this.filterText,
164796
- this.searchMode === "data" ? "data" : "table",
164797
- effectiveColumns
164798
- );
164799
- const viewData = getViewData(
164917
+ const cache = this.__memoEffectiveCols;
164918
+ if (cache && cache.columns === this.columns && cache.augment === this.augmentFromDisplayFunction && cache.displayFunction === this.displayFunction && cache.data === this.data) {
164919
+ return cache.out;
164920
+ }
164921
+ const out = usingColumns ? computeEffectiveColumns(
164922
+ this.columns,
164923
+ this.augmentFromDisplayFunction,
164924
+ this.displayFunction,
164925
+ this.data
164926
+ ) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
164927
+ this.__memoEffectiveCols = {
164928
+ columns: this.columns,
164929
+ augment: this.augmentFromDisplayFunction,
164930
+ displayFunction: this.displayFunction,
164931
+ data: this.data,
164932
+ out
164933
+ };
164934
+ return out;
164935
+ }
164936
+ /**
164937
+ * Returns the sorted/filtered view of the data, memoized by reference of
164938
+ * everything that affects it. Avoids re-running the lucene compiler and
164939
+ * the sort/filter pipeline on every render.
164940
+ */
164941
+ __getViewData(effectiveColumns) {
164942
+ const searchMode = this.searchMode === "data" ? "data" : "table";
164943
+ const cache = this.__memoViewData;
164944
+ if (cache && cache.data === this.data && cache.sortBy === this.sortBy && cache.filterText === this.filterText && cache.columnFilters === this.columnFilters && cache.searchMode === searchMode && cache.effectiveColumns === effectiveColumns) {
164945
+ return cache.out;
164946
+ }
164947
+ const lucenePred = compileLucenePredicate(this.filterText, searchMode, effectiveColumns);
164948
+ const out = getViewData(
164800
164949
  this.data,
164801
164950
  effectiveColumns,
164802
164951
  this.sortBy,
164803
164952
  this.filterText,
164804
164953
  this.columnFilters,
164805
- this.searchMode === "data" ? "data" : "table",
164954
+ searchMode,
164806
164955
  lucenePred || void 0
164807
164956
  );
164957
+ this.__memoViewData = {
164958
+ data: this.data,
164959
+ sortBy: this.sortBy,
164960
+ filterText: this.filterText,
164961
+ columnFilters: this.columnFilters,
164962
+ searchMode,
164963
+ effectiveColumns,
164964
+ out
164965
+ };
164966
+ return out;
164967
+ }
164968
+ render() {
164969
+ const effectiveColumns = this.__getEffectiveColumns();
164970
+ const viewData = this.__getViewData(effectiveColumns);
164808
164971
  this._lastViewData = viewData;
164972
+ const useVirtual = this.virtualized && viewData.length > 0;
164973
+ let renderRows = viewData;
164974
+ let renderStart = 0;
164975
+ let topSpacerHeight = 0;
164976
+ let bottomSpacerHeight = 0;
164977
+ if (useVirtual) {
164978
+ const range2 = this.__virtualRange;
164979
+ const start = Math.max(0, range2.start);
164980
+ const end3 = Math.min(viewData.length, range2.end || 0);
164981
+ const initialEnd = end3 > 0 ? end3 : Math.min(viewData.length, this.virtualOverscan * 2 + 16);
164982
+ renderStart = start;
164983
+ renderRows = viewData.slice(start, initialEnd);
164984
+ topSpacerHeight = start * this.__rowHeight;
164985
+ bottomSpacerHeight = Math.max(0, viewData.length - initialEnd) * this.__rowHeight;
164986
+ }
164809
164987
  return b2`
164810
164988
  <dees-tile>
164811
164989
  <div slot="header" class="header">
@@ -164873,88 +165051,23 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164873
165051
  <thead>
164874
165052
  ${this.renderHeaderRows(effectiveColumns)}
164875
165053
  </thead>
164876
- <tbody>
164877
- ${viewData.map((itemArg, rowIndex) => {
164878
- const getTr = /* @__PURE__ */ __name((elementArg) => {
164879
- if (elementArg.tagName === "TR") {
164880
- return elementArg;
164881
- } else {
164882
- return getTr(elementArg.parentElement);
164883
- }
164884
- }, "getTr");
165054
+ <tbody
165055
+ @click=${this.__onTbodyClick}
165056
+ @dblclick=${this.__onTbodyDblclick}
165057
+ @mousedown=${this.__onTbodyMousedown}
165058
+ @contextmenu=${this.__onTbodyContextmenu}
165059
+ @dragenter=${this.__onTbodyDragenter}
165060
+ @dragleave=${this.__onTbodyDragleave}
165061
+ @dragover=${this.__onTbodyDragover}
165062
+ @drop=${this.__onTbodyDrop}
165063
+ >
165064
+ ${useVirtual && topSpacerHeight > 0 ? b2`<tr aria-hidden="true" style="height:${topSpacerHeight}px"><td></td></tr>` : b2``}
165065
+ ${renderRows.map((itemArg, sliceIdx) => {
165066
+ const rowIndex = renderStart + sliceIdx;
165067
+ const rowId = this.getRowId(itemArg);
164885
165068
  return b2`
164886
165069
  <tr
164887
- @click=${(e11) => this.handleRowClick(e11, itemArg, rowIndex, viewData)}
164888
- @mousedown=${(e11) => {
164889
- if (e11.shiftKey && this.selectionMode !== "single") e11.preventDefault();
164890
- }}
164891
- @dragenter=${async (eventArg) => {
164892
- eventArg.preventDefault();
164893
- eventArg.stopPropagation();
164894
- const realTarget = getTr(eventArg.target);
164895
- setTimeout(() => {
164896
- realTarget.classList.add("hasAttachment");
164897
- }, 0);
164898
- }}
164899
- @dragleave=${async (eventArg) => {
164900
- eventArg.preventDefault();
164901
- eventArg.stopPropagation();
164902
- const realTarget = getTr(eventArg.target);
164903
- realTarget.classList.remove("hasAttachment");
164904
- }}
164905
- @dragover=${async (eventArg) => {
164906
- eventArg.preventDefault();
164907
- }}
164908
- @drop=${async (eventArg) => {
164909
- eventArg.preventDefault();
164910
- const newFiles = [];
164911
- for (const file of Array.from(eventArg.dataTransfer.files)) {
164912
- this.files.push(file);
164913
- newFiles.push(file);
164914
- this.requestUpdate();
164915
- }
164916
- const result = this.fileWeakMap.get(itemArg);
164917
- if (!result) {
164918
- this.fileWeakMap.set(itemArg, newFiles);
164919
- } else {
164920
- result.push(...newFiles);
164921
- }
164922
- }}
164923
- @contextmenu=${async (eventArg) => {
164924
- if (!this.isRowSelected(itemArg)) {
164925
- this.selectedDataRow = itemArg;
164926
- this.selectedIds.clear();
164927
- this.selectedIds.add(this.getRowId(itemArg));
164928
- this.__selectionAnchorId = this.getRowId(itemArg);
164929
- this.emitSelectionChange();
164930
- this.requestUpdate();
164931
- }
164932
- const userItems = this.getActionsForType("contextmenu").map((action) => ({
164933
- name: action.name,
164934
- iconName: action.iconName,
164935
- action: /* @__PURE__ */ __name(async () => {
164936
- await action.actionFunc({
164937
- item: itemArg,
164938
- table: this
164939
- });
164940
- return null;
164941
- }, "action")
164942
- }));
164943
- const defaultItems = [
164944
- {
164945
- name: this.selectedIds.size > 1 ? `Copy ${this.selectedIds.size} rows as JSON` : "Copy row as JSON",
164946
- iconName: "lucide:Copy",
164947
- action: /* @__PURE__ */ __name(async () => {
164948
- this.copySelectionAsJson(itemArg);
164949
- return null;
164950
- }, "action")
164951
- }
164952
- ];
164953
- DeesContextmenu.openContextMenuWithOptions(eventArg, [
164954
- ...userItems,
164955
- ...defaultItems
164956
- ]);
164957
- }}
165070
+ data-row-idx=${rowIndex}
164958
165071
  class="${itemArg === this.selectedDataRow || this.isRowSelected(itemArg) ? "selected" : ""}"
164959
165072
  >
164960
165073
  ${this.showSelectionCheckbox ? b2`<td style="width:42px; text-align:center;">
@@ -164971,7 +165084,6 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164971
165084
  const content3 = col.renderer ? col.renderer(value2, itemArg, { rowIndex, colIndex, column: col }) : value2;
164972
165085
  const editKey = String(col.key);
164973
165086
  const isEditable = !!(col.editable || col.editor);
164974
- const rowId = this.getRowId(itemArg);
164975
165087
  const isFocused = this.__focusedCell?.rowId === rowId && this.__focusedCell?.colKey === editKey;
164976
165088
  const isEditing = this.__editingCell?.rowId === rowId && this.__editingCell?.colKey === editKey;
164977
165089
  const cellClasses = [
@@ -164982,26 +165094,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164982
165094
  return b2`
164983
165095
  <td
164984
165096
  class=${cellClasses}
164985
- @click=${(e11) => {
164986
- if (isEditing) {
164987
- e11.stopPropagation();
164988
- return;
164989
- }
164990
- if (isEditable) {
164991
- this.__focusedCell = { rowId, colKey: editKey };
164992
- }
164993
- }}
164994
- @dblclick=${(e11) => {
164995
- const dblAction = this.dataActions.find(
164996
- (actionArg) => actionArg.type?.includes("doubleClick")
164997
- );
164998
- if (isEditable) {
164999
- e11.stopPropagation();
165000
- this.startEditing(itemArg, col);
165001
- } else if (dblAction) {
165002
- dblAction.actionFunc({ item: itemArg, table: this });
165003
- }
165004
- }}
165097
+ data-col-key=${editKey}
165005
165098
  >
165006
165099
  <div class="innerCellContainer">
165007
165100
  ${isEditing ? this.renderCellEditor(itemArg, col) : content3}
@@ -165034,15 +165127,16 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165034
165127
  })()}
165035
165128
  </tr>`;
165036
165129
  })}
165130
+ ${useVirtual && bottomSpacerHeight > 0 ? b2`<tr aria-hidden="true" style="height:${bottomSpacerHeight}px"><td></td></tr>` : b2``}
165037
165131
  </tbody>
165038
165132
  </table>
165039
165133
  </div>
165040
165134
  <div class="floatingHeader" aria-hidden="true">
165041
- <table>
165042
- <thead>
165043
- ${this.renderHeaderRows(effectiveColumns)}
165044
- </thead>
165045
- </table>
165135
+ ${this.__floatingActive ? b2`<table>
165136
+ <thead>
165137
+ ${this.renderHeaderRows(effectiveColumns)}
165138
+ </thead>
165139
+ </table>` : b2``}
165046
165140
  </div>
165047
165141
  ` : b2` <div class="noDataSet">No data set!</div> `}
165048
165142
  <div slot="footer" class="footer">
@@ -165202,24 +165296,33 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165202
165296
  }
165203
165297
  setupFloatingHeader() {
165204
165298
  this.teardownFloatingHeader();
165205
- if (this.fixedHeight) return;
165299
+ if (this.fixedHeight && !this.virtualized) return;
165206
165300
  const realTable = this.__realTableEl;
165207
165301
  if (!realTable) return;
165208
165302
  this.__scrollAncestors = this.__collectScrollAncestors();
165209
165303
  const tableScrollEl = this.shadowRoot?.querySelector(".tableScroll");
165210
165304
  if (tableScrollEl) {
165211
- this.__scrollAncestors.unshift({ target: tableScrollEl, scrollsY: false, scrollsX: true });
165305
+ this.__scrollAncestors.unshift({
165306
+ target: tableScrollEl,
165307
+ scrollsY: this.fixedHeight,
165308
+ scrollsX: true
165309
+ });
165212
165310
  }
165213
165311
  this.__floatingResizeObserver = new ResizeObserver(() => {
165214
- this.__syncFloatingHeader();
165312
+ if (!this.fixedHeight) this.__syncFloatingHeader();
165313
+ if (this.virtualized) this.__computeVirtualRange();
165215
165314
  });
165216
165315
  this.__floatingResizeObserver.observe(realTable);
165217
- this.__floatingScrollHandler = () => this.__syncFloatingHeader();
165316
+ this.__floatingScrollHandler = () => {
165317
+ if (!this.fixedHeight) this.__syncFloatingHeader();
165318
+ if (this.virtualized) this.__computeVirtualRange();
165319
+ };
165218
165320
  for (const a5 of this.__scrollAncestors) {
165219
165321
  a5.target.addEventListener("scroll", this.__floatingScrollHandler, { passive: true });
165220
165322
  }
165221
165323
  window.addEventListener("resize", this.__floatingScrollHandler, { passive: true });
165222
- this.__syncFloatingHeader();
165324
+ if (!this.fixedHeight) this.__syncFloatingHeader();
165325
+ if (this.virtualized) this.__computeVirtualRange();
165223
165326
  }
165224
165327
  teardownFloatingHeader() {
165225
165328
  this.__floatingResizeObserver?.disconnect();
@@ -165236,24 +165339,106 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165236
165339
  const fh = this.__floatingHeaderEl;
165237
165340
  if (fh) fh.classList.remove("active");
165238
165341
  }
165342
+ // ─── Virtualization ─────────────────────────────────────────────────
165343
+ /**
165344
+ * Computes the visible row range based on the table's position in its
165345
+ * nearest vertical scroll ancestor (or the viewport). Updates
165346
+ * `__virtualRange` if it changed; that triggers a Lit re-render.
165347
+ */
165348
+ __computeVirtualRange() {
165349
+ if (!this.virtualized) return;
165350
+ const view = this._lastViewData ?? [];
165351
+ const total = view.length;
165352
+ if (total === 0) {
165353
+ if (this.__virtualRange.start !== 0 || this.__virtualRange.end !== 0) {
165354
+ this.__virtualRange = { start: 0, end: 0 };
165355
+ }
165356
+ return;
165357
+ }
165358
+ const realTable = this.__realTableEl;
165359
+ if (!realTable) return;
165360
+ const tableRect = realTable.getBoundingClientRect();
165361
+ let viewportTop = 0;
165362
+ let viewportBottom = window.innerHeight;
165363
+ for (const a5 of this.__scrollAncestors) {
165364
+ if (a5.target === window || !a5.scrollsY) continue;
165365
+ const r11 = a5.target.getBoundingClientRect();
165366
+ const cs = getComputedStyle(a5.target);
165367
+ const bt = parseFloat(cs.borderTopWidth) || 0;
165368
+ const bb = parseFloat(cs.borderBottomWidth) || 0;
165369
+ viewportTop = Math.max(viewportTop, r11.top + bt);
165370
+ viewportBottom = Math.min(viewportBottom, r11.bottom - bb);
165371
+ }
165372
+ const rowH = Math.max(1, this.__rowHeight);
165373
+ const headerHeight = realTable.tHead?.getBoundingClientRect().height ?? 0;
165374
+ const bodyTop = tableRect.top + headerHeight;
165375
+ const offsetIntoBody = Math.max(0, viewportTop - bodyTop);
165376
+ const visiblePx = Math.max(0, viewportBottom - Math.max(viewportTop, bodyTop));
165377
+ const startRaw = Math.floor(offsetIntoBody / rowH);
165378
+ const visibleCount = Math.ceil(visiblePx / rowH) + 1;
165379
+ const start = Math.max(0, startRaw - this.virtualOverscan);
165380
+ const end3 = Math.min(total, startRaw + visibleCount + this.virtualOverscan);
165381
+ if (start !== this.__virtualRange.start || end3 !== this.__virtualRange.end) {
165382
+ this.__virtualRange = { start, end: end3 };
165383
+ }
165384
+ }
165385
+ /**
165386
+ * Measures the height of the first rendered body row and stores it for
165387
+ * subsequent virtualization math. Idempotent — only measures once per
165388
+ * `data`/`columns` pair (cleared in `updated()` when those change).
165389
+ */
165390
+ __measureRowHeight() {
165391
+ if (!this.virtualized || this.__rowHeightMeasured) return;
165392
+ const tbody3 = this.shadowRoot?.querySelector("tbody");
165393
+ if (!tbody3) return;
165394
+ const firstRow = Array.from(tbody3.rows).find((r11) => r11.hasAttribute("data-row-idx"));
165395
+ if (!firstRow) return;
165396
+ const h8 = firstRow.getBoundingClientRect().height;
165397
+ if (h8 > 0) {
165398
+ this.__rowHeight = h8;
165399
+ this.__rowHeightMeasured = true;
165400
+ }
165401
+ }
165239
165402
  /**
165240
165403
  * Single function that drives both activation and geometry of the floating
165241
- * header. Called on scroll, resize, table-resize, and after each render.
165404
+ * header. Called on scroll, resize, table-resize, and after relevant
165405
+ * renders.
165406
+ *
165407
+ * Activation is decided from the *real* header geometry, so this function
165408
+ * works even when the clone subtree hasn't been rendered yet (it's only
165409
+ * rendered when `__floatingActive` is true). The first activation flips
165410
+ * `__floatingActive`; the next render materializes the clone; the next
165411
+ * call here mirrors widths and positions.
165242
165412
  */
165243
165413
  __syncFloatingHeader() {
165244
165414
  const fh = this.__floatingHeaderEl;
165245
165415
  const realTable = this.__realTableEl;
165246
- const floatTable = this.__floatingTableEl;
165247
- if (!fh || !realTable || !floatTable) return;
165416
+ if (!fh || !realTable) return;
165248
165417
  const tableRect = realTable.getBoundingClientRect();
165249
165418
  const stick = this.__getStickContext();
165250
- floatTable.style.tableLayout = realTable.style.tableLayout || "auto";
165251
165419
  const realHeadRows = realTable.tHead?.rows;
165252
- const floatHeadRows = floatTable.tHead?.rows;
165253
165420
  let headerHeight = 0;
165421
+ if (realHeadRows) {
165422
+ for (let r11 = 0; r11 < realHeadRows.length; r11++) {
165423
+ headerHeight += realHeadRows[r11].getBoundingClientRect().height;
165424
+ }
165425
+ }
165426
+ const shouldBeActive = tableRect.top < stick.top && tableRect.bottom > stick.top + Math.min(headerHeight, 1);
165427
+ if (shouldBeActive !== this.__floatingActive) {
165428
+ this.__floatingActive = shouldBeActive;
165429
+ fh.classList.toggle("active", shouldBeActive);
165430
+ if (shouldBeActive) {
165431
+ this.updateComplete.then(() => this.__syncFloatingHeader());
165432
+ return;
165433
+ }
165434
+ }
165435
+ if (!shouldBeActive) return;
165436
+ const floatTable = this.__floatingTableEl;
165437
+ if (!floatTable) return;
165438
+ floatTable.style.tableLayout = realTable.style.tableLayout || "auto";
165439
+ const floatHeadRows = floatTable.tHead?.rows;
165254
165440
  if (realHeadRows && floatHeadRows) {
165255
165441
  for (let r11 = 0; r11 < realHeadRows.length && r11 < floatHeadRows.length; r11++) {
165256
- headerHeight += realHeadRows[r11].getBoundingClientRect().height;
165257
165442
  const realCells = realHeadRows[r11].cells;
165258
165443
  const floatCells = floatHeadRows[r11].cells;
165259
165444
  for (let c11 = 0; c11 < realCells.length && c11 < floatCells.length; c11++) {
@@ -165264,12 +165449,6 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165264
165449
  }
165265
165450
  }
165266
165451
  }
165267
- const shouldBeActive = tableRect.top < stick.top && tableRect.bottom > stick.top + Math.min(headerHeight, 1);
165268
- if (shouldBeActive !== this.__floatingActive) {
165269
- this.__floatingActive = shouldBeActive;
165270
- fh.classList.toggle("active", shouldBeActive);
165271
- }
165272
- if (!shouldBeActive) return;
165273
165452
  const clipLeft = Math.max(tableRect.left, stick.left);
165274
165453
  const clipRight = Math.min(tableRect.right, stick.right);
165275
165454
  const clipWidth = Math.max(0, clipRight - clipLeft);
@@ -165287,15 +165466,25 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165287
165466
  }
165288
165467
  async updated(changedProperties) {
165289
165468
  super.updated(changedProperties);
165290
- this.determineColumnWidths();
165291
- if (changedProperties.has("fixedHeight") || changedProperties.has("data") || changedProperties.has("columns") || !this.__floatingScrollHandler) {
165292
- if (!this.fixedHeight && this.data.length > 0) {
165469
+ const dataOrColsChanged = !this.__columnsSizedFor || this.__columnsSizedFor.data !== this.data || this.__columnsSizedFor.columns !== this.columns;
165470
+ if (dataOrColsChanged) {
165471
+ this.__columnsSizedFor = { data: this.data, columns: this.columns };
165472
+ this.determineColumnWidths();
165473
+ this.__rowHeightMeasured = false;
165474
+ }
165475
+ if (this.virtualized) {
165476
+ this.__measureRowHeight();
165477
+ this.__computeVirtualRange();
165478
+ }
165479
+ if (changedProperties.has("fixedHeight") || changedProperties.has("virtualized") || changedProperties.has("data") || changedProperties.has("columns") || !this.__floatingScrollHandler) {
165480
+ const needsScrollWatchers = (!this.fixedHeight || this.virtualized) && this.data.length > 0;
165481
+ if (needsScrollWatchers) {
165293
165482
  this.setupFloatingHeader();
165294
165483
  } else {
165295
165484
  this.teardownFloatingHeader();
165296
165485
  }
165297
165486
  }
165298
- if (!this.fixedHeight && this.data.length > 0) {
165487
+ if (!this.fixedHeight && this.data.length > 0 && (this.__floatingActive || dataOrColsChanged)) {
165299
165488
  this.__syncFloatingHeader();
165300
165489
  }
165301
165490
  if (this.searchable) {
@@ -165742,6 +165931,65 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165742
165931
  this.emitSelectionChange();
165743
165932
  this.requestUpdate();
165744
165933
  }
165934
+ // ─── Delegated tbody event handlers ─────────────────────────────────
165935
+ // Hoisted from per-<tr> closures to a single set of handlers on <tbody>.
165936
+ // Cuts ~7 closure allocations per row per render. Each handler resolves
165937
+ // the source row via `data-row-idx` (and `data-col-key` for cell-level
165938
+ // events) using the latest `_lastViewData`.
165939
+ __resolveRow(eventArg) {
165940
+ const path2 = eventArg.composedPath?.() || [];
165941
+ let tr3 = null;
165942
+ for (const t9 of path2) {
165943
+ const el = t9;
165944
+ if (el?.tagName === "TR" && el.hasAttribute("data-row-idx")) {
165945
+ tr3 = el;
165946
+ break;
165947
+ }
165948
+ }
165949
+ if (!tr3) return null;
165950
+ const rowIdx = Number(tr3.getAttribute("data-row-idx"));
165951
+ const view = this._lastViewData ?? [];
165952
+ const item = view[rowIdx];
165953
+ if (!item) return null;
165954
+ return { item, rowIdx };
165955
+ }
165956
+ __resolveCell(eventArg) {
165957
+ const row = this.__resolveRow(eventArg);
165958
+ if (!row) return null;
165959
+ const path2 = eventArg.composedPath?.() || [];
165960
+ let td = null;
165961
+ for (const t9 of path2) {
165962
+ const el = t9;
165963
+ if (el?.tagName === "TD" && el.hasAttribute("data-col-key")) {
165964
+ td = el;
165965
+ break;
165966
+ }
165967
+ }
165968
+ if (!td) return null;
165969
+ const colKey = td.getAttribute("data-col-key");
165970
+ const cols = this.__getEffectiveColumns();
165971
+ const col = cols.find((c11) => String(c11.key) === colKey);
165972
+ if (!col) return null;
165973
+ return { item: row.item, rowIdx: row.rowIdx, col };
165974
+ }
165975
+ __isInActionsCol(eventArg) {
165976
+ const path2 = eventArg.composedPath?.() || [];
165977
+ for (const t9 of path2) {
165978
+ const el = t9;
165979
+ if (el?.classList?.contains("actionsCol")) return true;
165980
+ }
165981
+ return false;
165982
+ }
165983
+ __isInEditor(eventArg) {
165984
+ const path2 = eventArg.composedPath?.() || [];
165985
+ for (const t9 of path2) {
165986
+ const el = t9;
165987
+ const tag = el?.tagName;
165988
+ if (tag === "INPUT" || tag === "TEXTAREA" || el?.isContentEditable) return true;
165989
+ if (tag && tag.startsWith("DEES-INPUT-")) return true;
165990
+ }
165991
+ return false;
165992
+ }
165745
165993
  /**
165746
165994
  * Handles row clicks with file-manager style selection semantics:
165747
165995
  * - plain click: select only this row, set anchor
@@ -166071,12 +166319,16 @@ _filterText = new WeakMap();
166071
166319
  _columnFilters = new WeakMap();
166072
166320
  _showColumnFilters = new WeakMap();
166073
166321
  _showSelectionCheckbox = new WeakMap();
166322
+ _virtualized = new WeakMap();
166323
+ _virtualOverscan = new WeakMap();
166074
166324
  _fixedHeight = new WeakMap();
166075
166325
  _searchMode = new WeakMap();
166076
166326
  _selectionMode = new WeakMap();
166077
166327
  _selectedIds = new WeakMap();
166078
166328
  ___focusedCell = new WeakMap();
166079
166329
  ___editingCell = new WeakMap();
166330
+ ___floatingActive = new WeakMap();
166331
+ ___virtualRange = new WeakMap();
166080
166332
  __decorateElement(_init39, 4, "heading1", _heading1_dec, _DeesTable, _heading1);
166081
166333
  __decorateElement(_init39, 4, "heading2", _heading2_dec, _DeesTable, _heading22);
166082
166334
  __decorateElement(_init39, 4, "data", _data_dec, _DeesTable, _data);
@@ -166101,12 +166353,16 @@ __decorateElement(_init39, 4, "filterText", _filterText_dec, _DeesTable, _filter
166101
166353
  __decorateElement(_init39, 4, "columnFilters", _columnFilters_dec, _DeesTable, _columnFilters);
166102
166354
  __decorateElement(_init39, 4, "showColumnFilters", _showColumnFilters_dec, _DeesTable, _showColumnFilters);
166103
166355
  __decorateElement(_init39, 4, "showSelectionCheckbox", _showSelectionCheckbox_dec, _DeesTable, _showSelectionCheckbox);
166356
+ __decorateElement(_init39, 4, "virtualized", _virtualized_dec, _DeesTable, _virtualized);
166357
+ __decorateElement(_init39, 4, "virtualOverscan", _virtualOverscan_dec, _DeesTable, _virtualOverscan);
166104
166358
  __decorateElement(_init39, 4, "fixedHeight", _fixedHeight_dec, _DeesTable, _fixedHeight);
166105
166359
  __decorateElement(_init39, 4, "searchMode", _searchMode_dec, _DeesTable, _searchMode);
166106
166360
  __decorateElement(_init39, 4, "selectionMode", _selectionMode_dec, _DeesTable, _selectionMode);
166107
166361
  __decorateElement(_init39, 4, "selectedIds", _selectedIds_dec, _DeesTable, _selectedIds);
166108
166362
  __decorateElement(_init39, 4, "__focusedCell", ___focusedCell_dec, _DeesTable, ___focusedCell);
166109
166363
  __decorateElement(_init39, 4, "__editingCell", ___editingCell_dec, _DeesTable, ___editingCell);
166364
+ __decorateElement(_init39, 4, "__floatingActive", ___floatingActive_dec, _DeesTable, ___floatingActive);
166365
+ __decorateElement(_init39, 4, "__virtualRange", ___virtualRange_dec, _DeesTable, ___virtualRange);
166110
166366
  _DeesTable = __decorateElement(_init39, 0, "DeesTable", _DeesTable_decorators, _DeesTable);
166111
166367
  __name(_DeesTable, "DeesTable");
166112
166368
  __publicField(_DeesTable, "demo", demoFunc29);
@@ -199953,7 +200209,7 @@ init_group_runtime();
199953
200209
  // ts_web/00_commitinfo_data.ts
199954
200210
  var commitinfo = {
199955
200211
  name: "@design.estate/dees-catalog",
199956
- version: "3.65.0",
200212
+ version: "3.66.0",
199957
200213
  description: "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."
199958
200214
  };
199959
200215
  export {
@@ -201926,4 +202182,4 @@ ibantools/jsnext/ibantools.js:
201926
202182
  * @preferred
201927
202183
  *)
201928
202184
  */
201929
- //# sourceMappingURL=bundle-1775575945430.js.map
202185
+ //# sourceMappingURL=bundle-1775577430289.js.map