@design.estate/dees-catalog 3.63.0 → 3.65.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.
@@ -163118,36 +163118,66 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
163118
163118
  <div class="demo-container">
163119
163119
  <div class="demo-section">
163120
163120
  <h2 class="demo-title">Basic Table with Actions</h2>
163121
- <p class="demo-description">A standard table with row actions, editable fields, and context menu support. Double-click on descriptions to edit. Grid lines are enabled by default.</p>
163121
+ <p class="demo-description">A standard table with row actions, editable cells, and context menu support. Double-click any cell to edit. Tab moves to the next editable cell, Enter to the row below, Esc cancels.</p>
163122
163122
  <dees-table
163123
163123
  heading1="Current Account Statement"
163124
163124
  heading2="Bunq - Payment Account 2 - April 2021"
163125
- .editableFields="${["description"]}"
163125
+ .columns=${[
163126
+ { key: "date", header: "Date", sortable: true, editable: true, editor: "date" },
163127
+ { key: "amount", header: "Amount", editable: true, editor: "text" },
163128
+ {
163129
+ key: "category",
163130
+ header: "Category",
163131
+ editable: true,
163132
+ editor: "dropdown",
163133
+ editorOptions: {
163134
+ options: [
163135
+ { option: "Office Supplies", key: "office" },
163136
+ { option: "Hardware", key: "hardware" },
163137
+ { option: "Software", key: "software" },
163138
+ { option: "Travel", key: "travel" }
163139
+ ]
163140
+ }
163141
+ },
163142
+ { key: "description", header: "Description", editable: true },
163143
+ { key: "reconciled", header: "OK", editable: true, editor: "checkbox" }
163144
+ ]}
163145
+ @cellEdit=${(e11) => console.log("cellEdit", e11.detail)}
163126
163146
  .data=${[
163127
163147
  {
163128
163148
  date: "2021-04-01",
163129
163149
  amount: "2464.65 \u20AC",
163130
- description: "Printing Paper (Office Supplies) - STAPLES BREMEN"
163150
+ category: "office",
163151
+ description: "Printing Paper - STAPLES BREMEN",
163152
+ reconciled: true
163131
163153
  },
163132
163154
  {
163133
163155
  date: "2021-04-02",
163134
163156
  amount: "165.65 \u20AC",
163135
- description: "Logitech Mouse (Hardware) - logi.com OnlineShop"
163157
+ category: "hardware",
163158
+ description: "Logitech Mouse - logi.com OnlineShop",
163159
+ reconciled: false
163136
163160
  },
163137
163161
  {
163138
163162
  date: "2021-04-03",
163139
163163
  amount: "2999,00 \u20AC",
163140
- description: "Macbook Pro 16inch (Hardware) - Apple.de OnlineShop"
163164
+ category: "hardware",
163165
+ description: "Macbook Pro 16inch - Apple.de OnlineShop",
163166
+ reconciled: false
163141
163167
  },
163142
163168
  {
163143
163169
  date: "2021-04-01",
163144
163170
  amount: "2464.65 \u20AC",
163145
- description: "Office-Supplies - STAPLES BREMEN"
163171
+ category: "office",
163172
+ description: "Office-Supplies - STAPLES BREMEN",
163173
+ reconciled: true
163146
163174
  },
163147
163175
  {
163148
163176
  date: "2021-04-01",
163149
163177
  amount: "2464.65 \u20AC",
163150
- description: "Office-Supplies - STAPLES BREMEN"
163178
+ category: "office",
163179
+ description: "Office-Supplies - STAPLES BREMEN",
163180
+ reconciled: true
163151
163181
  }
163152
163182
  ]}
163153
163183
  dataName="transactions"
@@ -163578,13 +163608,13 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
163578
163608
  <h2 class="demo-title">Column Filters + Sticky Header (New)</h2>
163579
163609
  <p class="demo-description">Per-column quick filters and sticky header with internal scroll. Try filtering the Name column. Uses --table-max-height var.</p>
163580
163610
  <style>
163581
- dees-table[sticky-header] { --table-max-height: 220px; }
163611
+ dees-table[fixed-height] { --table-max-height: 220px; }
163582
163612
  </style>
163583
163613
  <dees-table
163584
163614
  heading1="Employees"
163585
163615
  heading2="Quick filter per column + sticky header"
163586
163616
  .showColumnFilters=${true}
163587
- .stickyHeader=${true}
163617
+ .fixedHeight=${true}
163588
163618
  .columns=${[
163589
163619
  { key: "name", header: "Name", sortable: true },
163590
163620
  { key: "email", header: "Email", sortable: true },
@@ -163750,7 +163780,7 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
163750
163780
  </style>
163751
163781
  <dees-table
163752
163782
  id="scrollSmallHeight"
163753
- .stickyHeader=${true}
163783
+ .fixedHeight=${true}
163754
163784
  heading1="People Directory (Scrollable)"
163755
163785
  heading2="Forced scrolling with many items"
163756
163786
  .columns=${[
@@ -163996,6 +164026,7 @@ var tableStyles = [
163996
164026
  tbody tr {
163997
164027
  transition: background-color 0.15s ease;
163998
164028
  position: relative;
164029
+ user-select: none;
163999
164030
  }
164000
164031
 
164001
164032
  /* Default horizontal lines (bottom border only) */
@@ -164171,32 +164202,32 @@ var tableStyles = [
164171
164202
  min-height: 24px;
164172
164203
  line-height: 24px;
164173
164204
  }
164174
- td input {
164175
- position: absolute;
164176
- top: 4px;
164177
- bottom: 4px;
164178
- left: 20px;
164179
- right: 20px;
164180
- width: calc(100% - 40px);
164181
- height: calc(100% - 8px);
164182
- padding: 0 12px;
164183
- outline: none;
164184
- border: 1px solid var(--dees-color-border-default);
164185
- border-radius: 6px;
164186
- background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 9%)")};
164187
- color: var(--dees-color-text-primary);
164188
- font-family: inherit;
164189
- font-size: inherit;
164190
- font-weight: inherit;
164191
- transition: all 0.15s ease;
164192
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
164205
+
164206
+ /* Editable cell affordances */
164207
+ td.editable {
164208
+ cursor: text;
164193
164209
  }
164194
-
164195
- td input:focus {
164196
- border-color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
164197
- outline: 2px solid transparent;
164198
- outline-offset: 2px;
164199
- box-shadow: 0 0 0 2px ${cssManager.bdTheme("hsl(222.2 47.4% 51.2% / 0.2)", "hsl(217.2 91.2% 59.8% / 0.2)")};
164210
+ td.focused {
164211
+ outline: 2px solid ${cssManager.bdTheme(
164212
+ "hsl(222.2 47.4% 51.2% / 0.6)",
164213
+ "hsl(217.2 91.2% 59.8% / 0.6)"
164214
+ )};
164215
+ outline-offset: -2px;
164216
+ }
164217
+ td.editingCell {
164218
+ padding: 0;
164219
+ }
164220
+ td.editingCell .innerCellContainer {
164221
+ padding: 0;
164222
+ line-height: normal;
164223
+ }
164224
+ td.editingCell dees-input-text,
164225
+ td.editingCell dees-input-checkbox,
164226
+ td.editingCell dees-input-dropdown,
164227
+ td.editingCell dees-input-datepicker,
164228
+ td.editingCell dees-input-tags {
164229
+ display: block;
164230
+ width: 100%;
164200
164231
  }
164201
164232
 
164202
164233
  /* filter row */
@@ -164549,7 +164580,7 @@ __name(compileLucenePredicate, "compileLucenePredicate");
164549
164580
  init_dist_ts30();
164550
164581
  init_dist_ts29();
164551
164582
  init_theme();
164552
- var _selectedIds_dec, _selectionMode_dec, _searchMode_dec, _fixedHeight_dec, _showColumnFilters_dec, _columnFilters_dec, _filterText_dec, _sortBy_dec, _showGrid_dec, _showHorizontalLines_dec, _showVerticalLines_dec, _editableFields_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, _editableFields, _showVerticalLines, _showHorizontalLines, _showGrid, _sortBy, _filterText, _columnFilters, _showColumnFilters, _fixedHeight, _searchMode, _selectionMode, _selectedIds;
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;
164553
164584
  function ordinalLabel(n12) {
164554
164585
  const s10 = ["th", "st", "nd", "rd"];
164555
164586
  const v5 = n12 % 100;
@@ -164584,8 +164615,6 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164584
164615
  attribute: false
164585
164616
  })], _selectedDataRow_dec = [n5({
164586
164617
  type: Object
164587
- })], _editableFields_dec = [n5({
164588
- type: Array
164589
164618
  })], _showVerticalLines_dec = [n5({
164590
164619
  type: Boolean,
164591
164620
  reflect: true,
@@ -164598,7 +164627,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164598
164627
  type: Boolean,
164599
164628
  reflect: true,
164600
164629
  attribute: "show-grid"
164601
- })], _sortBy_dec = [n5({ attribute: false })], _filterText_dec = [n5({ type: String })], _columnFilters_dec = [n5({ attribute: false })], _showColumnFilters_dec = [n5({ type: Boolean, attribute: "show-column-filters" })], _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 })], _a42) {
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) {
164602
164631
  constructor() {
164603
164632
  super();
164604
164633
  __privateAdd(this, _heading1, __runInitializers(_init39, 8, this, "heading 1")), __runInitializers(_init39, 11, this);
@@ -164618,17 +164647,17 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164618
164647
  __privateAdd(this, _displayFunction, __runInitializers(_init39, 60, this, /* @__PURE__ */ __name((itemArg) => itemArg, "displayFunction"))), __runInitializers(_init39, 63, this);
164619
164648
  __privateAdd(this, _reverseDisplayFunction, __runInitializers(_init39, 64, this, /* @__PURE__ */ __name((itemArg) => itemArg, "reverseDisplayFunction"))), __runInitializers(_init39, 67, this);
164620
164649
  __privateAdd(this, _selectedDataRow, __runInitializers(_init39, 68, this)), __runInitializers(_init39, 71, this);
164621
- __privateAdd(this, _editableFields, __runInitializers(_init39, 72, this, [])), __runInitializers(_init39, 75, this);
164622
- __privateAdd(this, _showVerticalLines, __runInitializers(_init39, 76, this, false)), __runInitializers(_init39, 79, this);
164623
- __privateAdd(this, _showHorizontalLines, __runInitializers(_init39, 80, this, false)), __runInitializers(_init39, 83, this);
164624
- __privateAdd(this, _showGrid, __runInitializers(_init39, 84, this, true)), __runInitializers(_init39, 87, this);
164650
+ __privateAdd(this, _showVerticalLines, __runInitializers(_init39, 72, this, false)), __runInitializers(_init39, 75, this);
164651
+ __privateAdd(this, _showHorizontalLines, __runInitializers(_init39, 76, this, false)), __runInitializers(_init39, 79, this);
164652
+ __privateAdd(this, _showGrid, __runInitializers(_init39, 80, this, true)), __runInitializers(_init39, 83, this);
164625
164653
  __publicField(this, "files", []);
164626
164654
  __publicField(this, "fileWeakMap", /* @__PURE__ */ new WeakMap());
164627
164655
  __publicField(this, "dataChangeSubject", new domtools_pluginexports_exports.smartrx.rxjs.Subject());
164628
- __privateAdd(this, _sortBy, __runInitializers(_init39, 88, this, [])), __runInitializers(_init39, 91, this);
164629
- __privateAdd(this, _filterText, __runInitializers(_init39, 92, this, "")), __runInitializers(_init39, 95, this);
164630
- __privateAdd(this, _columnFilters, __runInitializers(_init39, 96, this, {})), __runInitializers(_init39, 99, this);
164631
- __privateAdd(this, _showColumnFilters, __runInitializers(_init39, 100, this, false)), __runInitializers(_init39, 103, this);
164656
+ __privateAdd(this, _sortBy, __runInitializers(_init39, 84, this, [])), __runInitializers(_init39, 87, this);
164657
+ __privateAdd(this, _filterText, __runInitializers(_init39, 88, this, "")), __runInitializers(_init39, 91, this);
164658
+ __privateAdd(this, _columnFilters, __runInitializers(_init39, 92, this, {})), __runInitializers(_init39, 95, this);
164659
+ __privateAdd(this, _showColumnFilters, __runInitializers(_init39, 96, this, false)), __runInitializers(_init39, 99, this);
164660
+ __privateAdd(this, _showSelectionCheckbox, __runInitializers(_init39, 100, this, false)), __runInitializers(_init39, 103, this);
164632
164661
  __privateAdd(this, _fixedHeight, __runInitializers(_init39, 104, this, false)), __runInitializers(_init39, 107, this);
164633
164662
  __privateAdd(this, _searchMode, __runInitializers(_init39, 108, this, "table")), __runInitializers(_init39, 111, this);
164634
164663
  __publicField(this, "__searchTextSub");
@@ -164637,18 +164666,128 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164637
164666
  __privateAdd(this, _selectedIds, __runInitializers(_init39, 116, this, /* @__PURE__ */ new Set())), __runInitializers(_init39, 119, this);
164638
164667
  __publicField(this, "_rowIdMap", /* @__PURE__ */ new WeakMap());
164639
164668
  __publicField(this, "_rowIdCounter", 0);
164669
+ /**
164670
+ * Anchor row id for shift+click range selection. Set whenever the user
164671
+ * makes a non-range click (plain or cmd/ctrl) so the next shift+click
164672
+ * can compute a contiguous range from this anchor.
164673
+ */
164674
+ __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);
164677
+ /**
164678
+ * Ctrl/Cmd+C copies the currently selected rows as a JSON array. Falls
164679
+ * back to copying the focused-row (`selectedDataRow`) if no multi
164680
+ * selection exists. No-op if a focused input/textarea would normally
164681
+ * receive the copy.
164682
+ */
164683
+ __publicField(this, "__handleHostKeydown", /* @__PURE__ */ __name((eventArg) => {
164684
+ const path2 = eventArg.composedPath?.() || [];
164685
+ let inEditor = false;
164686
+ for (const t9 of path2) {
164687
+ const tag = t9?.tagName;
164688
+ if (tag === "INPUT" || tag === "TEXTAREA" || t9?.isContentEditable) {
164689
+ inEditor = true;
164690
+ break;
164691
+ }
164692
+ }
164693
+ const isCopy = (eventArg.metaKey || eventArg.ctrlKey) && (eventArg.key === "c" || eventArg.key === "C");
164694
+ if (isCopy) {
164695
+ if (inEditor) return;
164696
+ const rows = [];
164697
+ if (this.selectedIds.size > 0) {
164698
+ for (const r11 of this.data) if (this.selectedIds.has(this.getRowId(r11))) rows.push(r11);
164699
+ } else if (this.selectedDataRow) {
164700
+ rows.push(this.selectedDataRow);
164701
+ }
164702
+ if (rows.length === 0) return;
164703
+ eventArg.preventDefault();
164704
+ this.__writeRowsAsJson(rows);
164705
+ return;
164706
+ }
164707
+ if (inEditor || this.__editingCell) return;
164708
+ switch (eventArg.key) {
164709
+ case "ArrowLeft":
164710
+ eventArg.preventDefault();
164711
+ this.moveFocusedCell(-1, 0, false);
164712
+ return;
164713
+ case "ArrowRight":
164714
+ eventArg.preventDefault();
164715
+ this.moveFocusedCell(1, 0, false);
164716
+ return;
164717
+ case "ArrowUp":
164718
+ eventArg.preventDefault();
164719
+ this.moveFocusedCell(0, -1, false);
164720
+ return;
164721
+ case "ArrowDown":
164722
+ eventArg.preventDefault();
164723
+ this.moveFocusedCell(0, 1, false);
164724
+ return;
164725
+ case "Enter":
164726
+ case "F2": {
164727
+ if (!this.__focusedCell) return;
164728
+ const view = this._lastViewData ?? [];
164729
+ const item = view.find((r11) => this.getRowId(r11) === this.__focusedCell.rowId);
164730
+ if (!item) return;
164731
+ const allCols = Array.isArray(this.columns) && this.columns.length > 0 ? computeEffectiveColumns(
164732
+ this.columns,
164733
+ this.augmentFromDisplayFunction,
164734
+ this.displayFunction,
164735
+ this.data
164736
+ ) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
164737
+ const col = allCols.find((c11) => String(c11.key) === this.__focusedCell.colKey);
164738
+ if (!col || !this.__isColumnEditable(col)) return;
164739
+ eventArg.preventDefault();
164740
+ this.startEditing(item, col);
164741
+ return;
164742
+ }
164743
+ case "Escape":
164744
+ if (this.__focusedCell) {
164745
+ this.__focusedCell = void 0;
164746
+ this.requestUpdate();
164747
+ }
164748
+ return;
164749
+ default:
164750
+ return;
164751
+ }
164752
+ }, "__handleHostKeydown"));
164640
164753
  // ─── Floating header (page-sticky) lifecycle ─────────────────────────
164641
164754
  __publicField(this, "__floatingResizeObserver");
164642
164755
  __publicField(this, "__floatingScrollHandler");
164643
164756
  __publicField(this, "__floatingActive", false);
164644
164757
  __publicField(this, "__scrollAncestors", []);
164645
164758
  __publicField(this, "__debounceTimer");
164759
+ if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
164760
+ this.addEventListener("keydown", this.__handleHostKeydown);
164646
164761
  }
164647
164762
  get value() {
164648
164763
  return this.data;
164649
164764
  }
164650
164765
  set value(_valueArg) {
164651
164766
  }
164767
+ /**
164768
+ * Copies the current selection as a JSON array. If `fallbackRow` is given
164769
+ * and there is no multi-selection, that row is copied instead. Used both
164770
+ * by the Ctrl/Cmd+C handler and by the default context-menu action.
164771
+ */
164772
+ copySelectionAsJson(fallbackRow) {
164773
+ const rows = [];
164774
+ if (this.selectedIds.size > 0) {
164775
+ for (const r11 of this.data) if (this.selectedIds.has(this.getRowId(r11))) rows.push(r11);
164776
+ } else if (fallbackRow) {
164777
+ rows.push(fallbackRow);
164778
+ } else if (this.selectedDataRow) {
164779
+ rows.push(this.selectedDataRow);
164780
+ }
164781
+ if (rows.length === 0) return;
164782
+ this.__writeRowsAsJson(rows);
164783
+ }
164784
+ __writeRowsAsJson(rows) {
164785
+ try {
164786
+ const json = JSON.stringify(rows, null, 2);
164787
+ navigator.clipboard?.writeText(json);
164788
+ } catch {
164789
+ }
164790
+ }
164652
164791
  render() {
164653
164792
  const usingColumns = Array.isArray(this.columns) && this.columns.length > 0;
164654
164793
  const effectiveColumns = usingColumns ? computeEffectiveColumns(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
@@ -164745,15 +164884,9 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164745
164884
  }, "getTr");
164746
164885
  return b2`
164747
164886
  <tr
164748
- @click=${() => {
164749
- this.selectedDataRow = itemArg;
164750
- if (this.selectionMode === "single") {
164751
- const id = this.getRowId(itemArg);
164752
- this.selectedIds.clear();
164753
- this.selectedIds.add(id);
164754
- this.emitSelectionChange();
164755
- this.requestUpdate();
164756
- }
164887
+ @click=${(e11) => this.handleRowClick(e11, itemArg, rowIndex, viewData)}
164888
+ @mousedown=${(e11) => {
164889
+ if (e11.shiftKey && this.selectionMode !== "single") e11.preventDefault();
164757
164890
  }}
164758
164891
  @dragenter=${async (eventArg) => {
164759
164892
  eventArg.preventDefault();
@@ -164788,27 +164921,43 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164788
164921
  }
164789
164922
  }}
164790
164923
  @contextmenu=${async (eventArg) => {
164791
- DeesContextmenu.openContextMenuWithOptions(
164792
- eventArg,
164793
- this.getActionsForType("contextmenu").map((action) => {
164794
- const menuItem = {
164795
- name: action.name,
164796
- iconName: action.iconName,
164797
- action: /* @__PURE__ */ __name(async () => {
164798
- await action.actionFunc({
164799
- item: itemArg,
164800
- table: this
164801
- });
164802
- return null;
164803
- }, "action")
164804
- };
164805
- return menuItem;
164806
- })
164807
- );
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
+ ]);
164808
164957
  }}
164809
- class="${itemArg === this.selectedDataRow ? "selected" : ""}"
164958
+ class="${itemArg === this.selectedDataRow || this.isRowSelected(itemArg) ? "selected" : ""}"
164810
164959
  >
164811
- ${this.selectionMode !== "none" ? b2`<td style="width:42px; text-align:center;">
164960
+ ${this.showSelectionCheckbox ? b2`<td style="width:42px; text-align:center;">
164812
164961
  <dees-input-checkbox
164813
164962
  .value=${this.isRowSelected(itemArg)}
164814
164963
  @newValue=${(e11) => {
@@ -164821,20 +164970,42 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164821
164970
  const value2 = getCellValue(itemArg, col, this.displayFunction);
164822
164971
  const content3 = col.renderer ? col.renderer(value2, itemArg, { rowIndex, colIndex, column: col }) : value2;
164823
164972
  const editKey = String(col.key);
164973
+ const isEditable = !!(col.editable || col.editor);
164974
+ const rowId = this.getRowId(itemArg);
164975
+ const isFocused = this.__focusedCell?.rowId === rowId && this.__focusedCell?.colKey === editKey;
164976
+ const isEditing = this.__editingCell?.rowId === rowId && this.__editingCell?.colKey === editKey;
164977
+ const cellClasses = [
164978
+ isEditable ? "editable" : "",
164979
+ isFocused && !isEditing ? "focused" : "",
164980
+ isEditing ? "editingCell" : ""
164981
+ ].filter(Boolean).join(" ");
164824
164982
  return b2`
164825
164983
  <td
164984
+ 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
+ }}
164826
164994
  @dblclick=${(e11) => {
164827
164995
  const dblAction = this.dataActions.find(
164828
164996
  (actionArg) => actionArg.type?.includes("doubleClick")
164829
164997
  );
164830
- if (this.editableFields.includes(editKey)) {
164831
- this.handleCellEditing(e11, itemArg, editKey);
164998
+ if (isEditable) {
164999
+ e11.stopPropagation();
165000
+ this.startEditing(itemArg, col);
164832
165001
  } else if (dblAction) {
164833
165002
  dblAction.actionFunc({ item: itemArg, table: this });
164834
165003
  }
164835
165004
  }}
164836
165005
  >
164837
- <div class="innerCellContainer">${content3}</div>
165006
+ <div class="innerCellContainer">
165007
+ ${isEditing ? this.renderCellEditor(itemArg, col) : content3}
165008
+ </div>
164838
165009
  </td>
164839
165010
  `;
164840
165011
  })}
@@ -164915,7 +165086,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164915
165086
  renderHeaderRows(effectiveColumns) {
164916
165087
  return b2`
164917
165088
  <tr>
164918
- ${this.selectionMode !== "none" ? b2`
165089
+ ${this.showSelectionCheckbox ? b2`
164919
165090
  <th style="width:42px; text-align:center;">
164920
165091
  ${this.selectionMode === "multi" ? b2`
164921
165092
  <dees-input-checkbox
@@ -164947,7 +165118,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164947
165118
  ${this.dataActions && this.dataActions.length > 0 ? b2`<th class="actionsCol">Actions</th>` : b2``}
164948
165119
  </tr>
164949
165120
  ${this.showColumnFilters ? b2`<tr class="filtersRow">
164950
- ${this.selectionMode !== "none" ? b2`<th style="width:42px;"></th>` : b2``}
165121
+ ${this.showSelectionCheckbox ? b2`<th style="width:42px;"></th>` : b2``}
164951
165122
  ${effectiveColumns.filter((c11) => !c11.hidden).map((col) => {
164952
165123
  const key2 = String(col.key);
164953
165124
  if (col.filterable === false) return b2`<th></th>`;
@@ -165571,6 +165742,64 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165571
165742
  this.emitSelectionChange();
165572
165743
  this.requestUpdate();
165573
165744
  }
165745
+ /**
165746
+ * Handles row clicks with file-manager style selection semantics:
165747
+ * - plain click: select only this row, set anchor
165748
+ * - cmd/ctrl+click: toggle this row in/out, set anchor
165749
+ * - shift+click: select the contiguous range from the anchor to this row
165750
+ *
165751
+ * Multi-row click selection is always available (`selectionMode === 'none'`
165752
+ * and `'multi'` both behave this way) so consumers can always copy a set
165753
+ * of rows. Only `selectionMode === 'single'` restricts to one row.
165754
+ */
165755
+ handleRowClick(eventArg, item, rowIndex, view) {
165756
+ const id = this.getRowId(item);
165757
+ if (this.selectionMode === "single") {
165758
+ this.selectedDataRow = item;
165759
+ this.selectedIds.clear();
165760
+ this.selectedIds.add(id);
165761
+ this.__selectionAnchorId = id;
165762
+ this.emitSelectionChange();
165763
+ this.requestUpdate();
165764
+ return;
165765
+ }
165766
+ const isToggle = eventArg.metaKey || eventArg.ctrlKey;
165767
+ const isRange = eventArg.shiftKey;
165768
+ if (isRange && this.__selectionAnchorId !== void 0) {
165769
+ window.getSelection?.()?.removeAllRanges();
165770
+ const anchorIdx = view.findIndex((r11) => this.getRowId(r11) === this.__selectionAnchorId);
165771
+ if (anchorIdx >= 0) {
165772
+ const [a5, b5] = anchorIdx <= rowIndex ? [anchorIdx, rowIndex] : [rowIndex, anchorIdx];
165773
+ this.selectedIds.clear();
165774
+ for (let i11 = a5; i11 <= b5; i11++) this.selectedIds.add(this.getRowId(view[i11]));
165775
+ } else {
165776
+ this.selectedIds.clear();
165777
+ this.selectedIds.add(id);
165778
+ this.__selectionAnchorId = id;
165779
+ }
165780
+ this.selectedDataRow = item;
165781
+ } else if (isToggle) {
165782
+ const wasSelected = this.selectedIds.has(id);
165783
+ if (wasSelected) {
165784
+ this.selectedIds.delete(id);
165785
+ if (this.selectedDataRow === item) {
165786
+ const remaining = view.find((r11) => this.selectedIds.has(this.getRowId(r11)));
165787
+ this.selectedDataRow = remaining;
165788
+ }
165789
+ } else {
165790
+ this.selectedIds.add(id);
165791
+ this.selectedDataRow = item;
165792
+ }
165793
+ this.__selectionAnchorId = id;
165794
+ } else {
165795
+ this.selectedDataRow = item;
165796
+ this.selectedIds.clear();
165797
+ this.selectedIds.add(id);
165798
+ this.__selectionAnchorId = id;
165799
+ }
165800
+ this.emitSelectionChange();
165801
+ this.requestUpdate();
165802
+ }
165574
165803
  setRowSelected(row, checked) {
165575
165804
  const id = this.getRowId(row);
165576
165805
  if (this.selectionMode === "single") {
@@ -165628,38 +165857,193 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165628
165857
  }
165629
165858
  return actions;
165630
165859
  }
165631
- async handleCellEditing(event, itemArg, key2) {
165632
- await this.domtoolsPromise;
165633
- const target = event.target;
165634
- const originalColor = target.style.color;
165635
- target.style.color = "transparent";
165636
- const transformedItem = this.displayFunction(itemArg);
165637
- const initialValue = transformedItem[key2] ?? itemArg[key2] ?? "";
165638
- const input = document.createElement("input");
165639
- input.type = "text";
165640
- input.value = initialValue;
165641
- const blurInput = /* @__PURE__ */ __name(async (blurArg = true, saveArg = false) => {
165642
- if (blurArg) {
165643
- input.blur();
165644
- }
165645
- if (saveArg) {
165646
- itemArg[key2] = input.value;
165647
- this.changeSubject.next(this);
165648
- }
165649
- input.remove();
165650
- target.style.color = originalColor;
165651
- this.requestUpdate();
165652
- }, "blurInput");
165653
- input.addEventListener("blur", () => {
165654
- blurInput(false, false);
165860
+ // ─── Cell editing ─────────────────────────────────────────────────────
165861
+ /** True if the column has any in-cell editor configured. */
165862
+ __isColumnEditable(col) {
165863
+ return !!(col.editable || col.editor);
165864
+ }
165865
+ /** Effective columns filtered to those that can be edited (visible only). */
165866
+ __editableColumns(effectiveColumns) {
165867
+ return effectiveColumns.filter((c11) => !c11.hidden && this.__isColumnEditable(c11));
165868
+ }
165869
+ /**
165870
+ * Opens the editor on the given cell. Sets focus + editing state and
165871
+ * focuses the freshly rendered editor on the next frame.
165872
+ */
165873
+ startEditing(item, col) {
165874
+ if (!this.__isColumnEditable(col)) return;
165875
+ const rowId = this.getRowId(item);
165876
+ const colKey = String(col.key);
165877
+ this.__focusedCell = { rowId, colKey };
165878
+ this.__editingCell = { rowId, colKey };
165879
+ this.requestUpdate();
165880
+ this.updateComplete.then(() => {
165881
+ const el = this.shadowRoot?.querySelector(
165882
+ ".editingCell dees-input-text, .editingCell dees-input-checkbox, .editingCell dees-input-dropdown, .editingCell dees-input-datepicker, .editingCell dees-input-tags"
165883
+ );
165884
+ el?.focus?.();
165655
165885
  });
165656
- input.addEventListener("keydown", (e11) => {
165657
- if (e11.key === "Enter") {
165658
- blurInput(true, true);
165886
+ }
165887
+ /** Closes the editor without committing. */
165888
+ cancelCellEdit() {
165889
+ this.__editingCell = void 0;
165890
+ this.requestUpdate();
165891
+ }
165892
+ /**
165893
+ * Commits an editor value to the row. Runs `parse` then `validate`. On
165894
+ * validation failure, fires `cellEditError` and leaves the editor open.
165895
+ * On success, mutates `data` in place, fires `cellEdit`, and closes the
165896
+ * editor.
165897
+ */
165898
+ commitCellEdit(item, col, editorValue) {
165899
+ const key2 = String(col.key);
165900
+ const oldValue = item[col.key];
165901
+ const parsed = col.parse ? col.parse(editorValue, item) : editorValue;
165902
+ if (col.validate) {
165903
+ const result = col.validate(parsed, item);
165904
+ if (typeof result === "string") {
165905
+ this.dispatchEvent(
165906
+ new CustomEvent("cellEditError", {
165907
+ detail: { row: item, key: key2, value: parsed, message: result },
165908
+ bubbles: true,
165909
+ composed: true
165910
+ })
165911
+ );
165912
+ return;
165659
165913
  }
165660
- });
165661
- target.appendChild(input);
165662
- input.focus();
165914
+ }
165915
+ if (parsed !== oldValue) {
165916
+ item[col.key] = parsed;
165917
+ this.dispatchEvent(
165918
+ new CustomEvent("cellEdit", {
165919
+ detail: { row: item, key: key2, oldValue, newValue: parsed },
165920
+ bubbles: true,
165921
+ composed: true
165922
+ })
165923
+ );
165924
+ this.changeSubject.next(this);
165925
+ }
165926
+ this.__editingCell = void 0;
165927
+ this.requestUpdate();
165928
+ }
165929
+ /** Renders the appropriate dees-input-* component for this column. */
165930
+ renderCellEditor(item, col) {
165931
+ const raw2 = item[col.key];
165932
+ const value2 = col.format ? col.format(raw2, item) : raw2;
165933
+ const editorType = col.editor ?? "text";
165934
+ const onTextCommit = /* @__PURE__ */ __name((target) => this.commitCellEdit(item, col, target.value), "onTextCommit");
165935
+ switch (editorType) {
165936
+ case "checkbox":
165937
+ return b2`<dees-input-checkbox
165938
+ .value=${!!value2}
165939
+ @newValue=${(e11) => {
165940
+ e11.stopPropagation();
165941
+ this.commitCellEdit(item, col, e11.detail);
165942
+ }}
165943
+ ></dees-input-checkbox>`;
165944
+ case "dropdown": {
165945
+ const options2 = col.editorOptions?.options ?? [];
165946
+ const selected = options2.find((o13) => (o13?.option ?? o13?.key ?? o13) === value2) ?? null;
165947
+ return b2`<dees-input-dropdown
165948
+ .options=${options2}
165949
+ .selectedOption=${selected}
165950
+ @selectedOption=${(e11) => {
165951
+ e11.stopPropagation();
165952
+ const detail = e11.detail;
165953
+ const newRaw = detail?.option ?? detail?.key ?? detail;
165954
+ this.commitCellEdit(item, col, newRaw);
165955
+ }}
165956
+ ></dees-input-dropdown>`;
165957
+ }
165958
+ case "date":
165959
+ return b2`<dees-input-datepicker
165960
+ .value=${value2}
165961
+ @focusout=${(e11) => onTextCommit(e11.target)}
165962
+ @keydown=${(e11) => this.__handleEditorKey(e11, item, col)}
165963
+ ></dees-input-datepicker>`;
165964
+ case "tags":
165965
+ return b2`<dees-input-tags
165966
+ .value=${value2 ?? []}
165967
+ @focusout=${(e11) => onTextCommit(e11.target)}
165968
+ @keydown=${(e11) => this.__handleEditorKey(e11, item, col)}
165969
+ ></dees-input-tags>`;
165970
+ case "number":
165971
+ case "text":
165972
+ default:
165973
+ return b2`<dees-input-text
165974
+ .value=${value2 == null ? "" : String(value2)}
165975
+ @focusout=${(e11) => onTextCommit(e11.target)}
165976
+ @keydown=${(e11) => this.__handleEditorKey(e11, item, col)}
165977
+ ></dees-input-text>`;
165978
+ }
165979
+ }
165980
+ /**
165981
+ * Centralized keydown handler for text-style editors. Handles Esc (cancel),
165982
+ * Enter (commit + move down) and Tab/Shift+Tab (commit + move horizontally).
165983
+ */
165984
+ __handleEditorKey(eventArg, item, col) {
165985
+ if (eventArg.key === "Escape") {
165986
+ eventArg.preventDefault();
165987
+ eventArg.stopPropagation();
165988
+ this.cancelCellEdit();
165989
+ this.focus();
165990
+ } else if (eventArg.key === "Enter") {
165991
+ eventArg.preventDefault();
165992
+ eventArg.stopPropagation();
165993
+ const target = eventArg.target;
165994
+ this.commitCellEdit(item, col, target.value);
165995
+ this.moveFocusedCell(0, 1, true);
165996
+ } else if (eventArg.key === "Tab") {
165997
+ eventArg.preventDefault();
165998
+ eventArg.stopPropagation();
165999
+ const target = eventArg.target;
166000
+ this.commitCellEdit(item, col, target.value);
166001
+ this.moveFocusedCell(eventArg.shiftKey ? -1 : 1, 0, true);
166002
+ }
166003
+ }
166004
+ /**
166005
+ * Moves the focused cell by `dx` columns and `dy` rows along the editable
166006
+ * grid. Wraps row-end → next row when moving horizontally. If
166007
+ * `andStartEditing` is true, opens the editor on the new cell.
166008
+ */
166009
+ moveFocusedCell(dx, dy, andStartEditing) {
166010
+ const view = this._lastViewData ?? [];
166011
+ if (view.length === 0) return;
166012
+ const allCols = Array.isArray(this.columns) && this.columns.length > 0 ? computeEffectiveColumns(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
166013
+ const editableCols = this.__editableColumns(allCols);
166014
+ if (editableCols.length === 0) return;
166015
+ let rowIdx = 0;
166016
+ let colIdx = 0;
166017
+ if (this.__focusedCell) {
166018
+ rowIdx = view.findIndex((r11) => this.getRowId(r11) === this.__focusedCell.rowId);
166019
+ colIdx = editableCols.findIndex((c11) => String(c11.key) === this.__focusedCell.colKey);
166020
+ if (rowIdx < 0) rowIdx = 0;
166021
+ if (colIdx < 0) colIdx = 0;
166022
+ }
166023
+ if (dx !== 0) {
166024
+ colIdx += dx;
166025
+ while (colIdx >= editableCols.length) {
166026
+ colIdx -= editableCols.length;
166027
+ rowIdx += 1;
166028
+ }
166029
+ while (colIdx < 0) {
166030
+ colIdx += editableCols.length;
166031
+ rowIdx -= 1;
166032
+ }
166033
+ }
166034
+ if (dy !== 0) rowIdx += dy;
166035
+ if (rowIdx < 0 || rowIdx >= view.length) {
166036
+ this.cancelCellEdit();
166037
+ return;
166038
+ }
166039
+ const item = view[rowIdx];
166040
+ const col = editableCols[colIdx];
166041
+ this.__focusedCell = { rowId: this.getRowId(item), colKey: String(col.key) };
166042
+ if (andStartEditing) {
166043
+ this.startEditing(item, col);
166044
+ } else {
166045
+ this.requestUpdate();
166046
+ }
165663
166047
  }
165664
166048
  };
165665
166049
  _init39 = __decoratorStart(_a42);
@@ -165679,7 +166063,6 @@ _augmentFromDisplayFunction = new WeakMap();
165679
166063
  _displayFunction = new WeakMap();
165680
166064
  _reverseDisplayFunction = new WeakMap();
165681
166065
  _selectedDataRow = new WeakMap();
165682
- _editableFields = new WeakMap();
165683
166066
  _showVerticalLines = new WeakMap();
165684
166067
  _showHorizontalLines = new WeakMap();
165685
166068
  _showGrid = new WeakMap();
@@ -165687,10 +166070,13 @@ _sortBy = new WeakMap();
165687
166070
  _filterText = new WeakMap();
165688
166071
  _columnFilters = new WeakMap();
165689
166072
  _showColumnFilters = new WeakMap();
166073
+ _showSelectionCheckbox = new WeakMap();
165690
166074
  _fixedHeight = new WeakMap();
165691
166075
  _searchMode = new WeakMap();
165692
166076
  _selectionMode = new WeakMap();
165693
166077
  _selectedIds = new WeakMap();
166078
+ ___focusedCell = new WeakMap();
166079
+ ___editingCell = new WeakMap();
165694
166080
  __decorateElement(_init39, 4, "heading1", _heading1_dec, _DeesTable, _heading1);
165695
166081
  __decorateElement(_init39, 4, "heading2", _heading2_dec, _DeesTable, _heading22);
165696
166082
  __decorateElement(_init39, 4, "data", _data_dec, _DeesTable, _data);
@@ -165707,7 +166093,6 @@ __decorateElement(_init39, 4, "augmentFromDisplayFunction", _augmentFromDisplayF
165707
166093
  __decorateElement(_init39, 4, "displayFunction", _displayFunction_dec, _DeesTable, _displayFunction);
165708
166094
  __decorateElement(_init39, 4, "reverseDisplayFunction", _reverseDisplayFunction_dec, _DeesTable, _reverseDisplayFunction);
165709
166095
  __decorateElement(_init39, 4, "selectedDataRow", _selectedDataRow_dec, _DeesTable, _selectedDataRow);
165710
- __decorateElement(_init39, 4, "editableFields", _editableFields_dec, _DeesTable, _editableFields);
165711
166096
  __decorateElement(_init39, 4, "showVerticalLines", _showVerticalLines_dec, _DeesTable, _showVerticalLines);
165712
166097
  __decorateElement(_init39, 4, "showHorizontalLines", _showHorizontalLines_dec, _DeesTable, _showHorizontalLines);
165713
166098
  __decorateElement(_init39, 4, "showGrid", _showGrid_dec, _DeesTable, _showGrid);
@@ -165715,10 +166100,13 @@ __decorateElement(_init39, 4, "sortBy", _sortBy_dec, _DeesTable, _sortBy);
165715
166100
  __decorateElement(_init39, 4, "filterText", _filterText_dec, _DeesTable, _filterText);
165716
166101
  __decorateElement(_init39, 4, "columnFilters", _columnFilters_dec, _DeesTable, _columnFilters);
165717
166102
  __decorateElement(_init39, 4, "showColumnFilters", _showColumnFilters_dec, _DeesTable, _showColumnFilters);
166103
+ __decorateElement(_init39, 4, "showSelectionCheckbox", _showSelectionCheckbox_dec, _DeesTable, _showSelectionCheckbox);
165718
166104
  __decorateElement(_init39, 4, "fixedHeight", _fixedHeight_dec, _DeesTable, _fixedHeight);
165719
166105
  __decorateElement(_init39, 4, "searchMode", _searchMode_dec, _DeesTable, _searchMode);
165720
166106
  __decorateElement(_init39, 4, "selectionMode", _selectionMode_dec, _DeesTable, _selectionMode);
165721
166107
  __decorateElement(_init39, 4, "selectedIds", _selectedIds_dec, _DeesTable, _selectedIds);
166108
+ __decorateElement(_init39, 4, "__focusedCell", ___focusedCell_dec, _DeesTable, ___focusedCell);
166109
+ __decorateElement(_init39, 4, "__editingCell", ___editingCell_dec, _DeesTable, ___editingCell);
165722
166110
  _DeesTable = __decorateElement(_init39, 0, "DeesTable", _DeesTable_decorators, _DeesTable);
165723
166111
  __name(_DeesTable, "DeesTable");
165724
166112
  __publicField(_DeesTable, "demo", demoFunc29);
@@ -199565,7 +199953,7 @@ init_group_runtime();
199565
199953
  // ts_web/00_commitinfo_data.ts
199566
199954
  var commitinfo = {
199567
199955
  name: "@design.estate/dees-catalog",
199568
- version: "3.63.0",
199956
+ version: "3.65.0",
199569
199957
  description: "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."
199570
199958
  };
199571
199959
  export {
@@ -201538,4 +201926,4 @@ ibantools/jsnext/ibantools.js:
201538
201926
  * @preferred
201539
201927
  *)
201540
201928
  */
201541
- //# sourceMappingURL=bundle-1775570157836.js.map
201929
+ //# sourceMappingURL=bundle-1775575945430.js.map