@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.
@@ -168464,36 +168464,66 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
168464
168464
  <div class="demo-container">
168465
168465
  <div class="demo-section">
168466
168466
  <h2 class="demo-title">Basic Table with Actions</h2>
168467
- <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>
168467
+ <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>
168468
168468
  <dees-table
168469
168469
  heading1="Current Account Statement"
168470
168470
  heading2="Bunq - Payment Account 2 - April 2021"
168471
- .editableFields="${["description"]}"
168471
+ .columns=${[
168472
+ { key: "date", header: "Date", sortable: true, editable: true, editor: "date" },
168473
+ { key: "amount", header: "Amount", editable: true, editor: "text" },
168474
+ {
168475
+ key: "category",
168476
+ header: "Category",
168477
+ editable: true,
168478
+ editor: "dropdown",
168479
+ editorOptions: {
168480
+ options: [
168481
+ { option: "Office Supplies", key: "office" },
168482
+ { option: "Hardware", key: "hardware" },
168483
+ { option: "Software", key: "software" },
168484
+ { option: "Travel", key: "travel" }
168485
+ ]
168486
+ }
168487
+ },
168488
+ { key: "description", header: "Description", editable: true },
168489
+ { key: "reconciled", header: "OK", editable: true, editor: "checkbox" }
168490
+ ]}
168491
+ @cellEdit=${(e11) => console.log("cellEdit", e11.detail)}
168472
168492
  .data=${[
168473
168493
  {
168474
168494
  date: "2021-04-01",
168475
168495
  amount: "2464.65 \u20AC",
168476
- description: "Printing Paper (Office Supplies) - STAPLES BREMEN"
168496
+ category: "office",
168497
+ description: "Printing Paper - STAPLES BREMEN",
168498
+ reconciled: true
168477
168499
  },
168478
168500
  {
168479
168501
  date: "2021-04-02",
168480
168502
  amount: "165.65 \u20AC",
168481
- description: "Logitech Mouse (Hardware) - logi.com OnlineShop"
168503
+ category: "hardware",
168504
+ description: "Logitech Mouse - logi.com OnlineShop",
168505
+ reconciled: false
168482
168506
  },
168483
168507
  {
168484
168508
  date: "2021-04-03",
168485
168509
  amount: "2999,00 \u20AC",
168486
- description: "Macbook Pro 16inch (Hardware) - Apple.de OnlineShop"
168510
+ category: "hardware",
168511
+ description: "Macbook Pro 16inch - Apple.de OnlineShop",
168512
+ reconciled: false
168487
168513
  },
168488
168514
  {
168489
168515
  date: "2021-04-01",
168490
168516
  amount: "2464.65 \u20AC",
168491
- description: "Office-Supplies - STAPLES BREMEN"
168517
+ category: "office",
168518
+ description: "Office-Supplies - STAPLES BREMEN",
168519
+ reconciled: true
168492
168520
  },
168493
168521
  {
168494
168522
  date: "2021-04-01",
168495
168523
  amount: "2464.65 \u20AC",
168496
- description: "Office-Supplies - STAPLES BREMEN"
168524
+ category: "office",
168525
+ description: "Office-Supplies - STAPLES BREMEN",
168526
+ reconciled: true
168497
168527
  }
168498
168528
  ]}
168499
168529
  dataName="transactions"
@@ -168924,13 +168954,13 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
168924
168954
  <h2 class="demo-title">Column Filters + Sticky Header (New)</h2>
168925
168955
  <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>
168926
168956
  <style>
168927
- dees-table[sticky-header] { --table-max-height: 220px; }
168957
+ dees-table[fixed-height] { --table-max-height: 220px; }
168928
168958
  </style>
168929
168959
  <dees-table
168930
168960
  heading1="Employees"
168931
168961
  heading2="Quick filter per column + sticky header"
168932
168962
  .showColumnFilters=${true}
168933
- .stickyHeader=${true}
168963
+ .fixedHeight=${true}
168934
168964
  .columns=${[
168935
168965
  { key: "name", header: "Name", sortable: true },
168936
168966
  { key: "email", header: "Email", sortable: true },
@@ -169096,7 +169126,7 @@ var demoFunc29 = /* @__PURE__ */ __name(() => b2`
169096
169126
  </style>
169097
169127
  <dees-table
169098
169128
  id="scrollSmallHeight"
169099
- .stickyHeader=${true}
169129
+ .fixedHeight=${true}
169100
169130
  heading1="People Directory (Scrollable)"
169101
169131
  heading2="Forced scrolling with many items"
169102
169132
  .columns=${[
@@ -169342,6 +169372,7 @@ var tableStyles = [
169342
169372
  tbody tr {
169343
169373
  transition: background-color 0.15s ease;
169344
169374
  position: relative;
169375
+ user-select: none;
169345
169376
  }
169346
169377
 
169347
169378
  /* Default horizontal lines (bottom border only) */
@@ -169517,32 +169548,32 @@ var tableStyles = [
169517
169548
  min-height: 24px;
169518
169549
  line-height: 24px;
169519
169550
  }
169520
- td input {
169521
- position: absolute;
169522
- top: 4px;
169523
- bottom: 4px;
169524
- left: 20px;
169525
- right: 20px;
169526
- width: calc(100% - 40px);
169527
- height: calc(100% - 8px);
169528
- padding: 0 12px;
169529
- outline: none;
169530
- border: 1px solid var(--dees-color-border-default);
169531
- border-radius: 6px;
169532
- background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 9%)")};
169533
- color: var(--dees-color-text-primary);
169534
- font-family: inherit;
169535
- font-size: inherit;
169536
- font-weight: inherit;
169537
- transition: all 0.15s ease;
169538
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
169551
+
169552
+ /* Editable cell affordances */
169553
+ td.editable {
169554
+ cursor: text;
169539
169555
  }
169540
-
169541
- td input:focus {
169542
- border-color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
169543
- outline: 2px solid transparent;
169544
- outline-offset: 2px;
169545
- 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)")};
169556
+ td.focused {
169557
+ outline: 2px solid ${cssManager.bdTheme(
169558
+ "hsl(222.2 47.4% 51.2% / 0.6)",
169559
+ "hsl(217.2 91.2% 59.8% / 0.6)"
169560
+ )};
169561
+ outline-offset: -2px;
169562
+ }
169563
+ td.editingCell {
169564
+ padding: 0;
169565
+ }
169566
+ td.editingCell .innerCellContainer {
169567
+ padding: 0;
169568
+ line-height: normal;
169569
+ }
169570
+ td.editingCell dees-input-text,
169571
+ td.editingCell dees-input-checkbox,
169572
+ td.editingCell dees-input-dropdown,
169573
+ td.editingCell dees-input-datepicker,
169574
+ td.editingCell dees-input-tags {
169575
+ display: block;
169576
+ width: 100%;
169546
169577
  }
169547
169578
 
169548
169579
  /* filter row */
@@ -169895,7 +169926,7 @@ __name(compileLucenePredicate, "compileLucenePredicate");
169895
169926
  init_dist_ts30();
169896
169927
  init_dist_ts29();
169897
169928
  init_theme();
169898
- 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;
169929
+ 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;
169899
169930
  function ordinalLabel(n12) {
169900
169931
  const s10 = ["th", "st", "nd", "rd"];
169901
169932
  const v5 = n12 % 100;
@@ -169930,8 +169961,6 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
169930
169961
  attribute: false
169931
169962
  })], _selectedDataRow_dec = [n5({
169932
169963
  type: Object
169933
- })], _editableFields_dec = [n5({
169934
- type: Array
169935
169964
  })], _showVerticalLines_dec = [n5({
169936
169965
  type: Boolean,
169937
169966
  reflect: true,
@@ -169944,7 +169973,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
169944
169973
  type: Boolean,
169945
169974
  reflect: true,
169946
169975
  attribute: "show-grid"
169947
- })], _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) {
169976
+ })], _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) {
169948
169977
  constructor() {
169949
169978
  super();
169950
169979
  __privateAdd(this, _heading1, __runInitializers(_init39, 8, this, "heading 1")), __runInitializers(_init39, 11, this);
@@ -169964,17 +169993,17 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
169964
169993
  __privateAdd(this, _displayFunction, __runInitializers(_init39, 60, this, /* @__PURE__ */ __name((itemArg) => itemArg, "displayFunction"))), __runInitializers(_init39, 63, this);
169965
169994
  __privateAdd(this, _reverseDisplayFunction, __runInitializers(_init39, 64, this, /* @__PURE__ */ __name((itemArg) => itemArg, "reverseDisplayFunction"))), __runInitializers(_init39, 67, this);
169966
169995
  __privateAdd(this, _selectedDataRow, __runInitializers(_init39, 68, this)), __runInitializers(_init39, 71, this);
169967
- __privateAdd(this, _editableFields, __runInitializers(_init39, 72, this, [])), __runInitializers(_init39, 75, this);
169968
- __privateAdd(this, _showVerticalLines, __runInitializers(_init39, 76, this, false)), __runInitializers(_init39, 79, this);
169969
- __privateAdd(this, _showHorizontalLines, __runInitializers(_init39, 80, this, false)), __runInitializers(_init39, 83, this);
169970
- __privateAdd(this, _showGrid, __runInitializers(_init39, 84, this, true)), __runInitializers(_init39, 87, this);
169996
+ __privateAdd(this, _showVerticalLines, __runInitializers(_init39, 72, this, false)), __runInitializers(_init39, 75, this);
169997
+ __privateAdd(this, _showHorizontalLines, __runInitializers(_init39, 76, this, false)), __runInitializers(_init39, 79, this);
169998
+ __privateAdd(this, _showGrid, __runInitializers(_init39, 80, this, true)), __runInitializers(_init39, 83, this);
169971
169999
  __publicField(this, "files", []);
169972
170000
  __publicField(this, "fileWeakMap", /* @__PURE__ */ new WeakMap());
169973
170001
  __publicField(this, "dataChangeSubject", new domtools_pluginexports_exports.smartrx.rxjs.Subject());
169974
- __privateAdd(this, _sortBy, __runInitializers(_init39, 88, this, [])), __runInitializers(_init39, 91, this);
169975
- __privateAdd(this, _filterText, __runInitializers(_init39, 92, this, "")), __runInitializers(_init39, 95, this);
169976
- __privateAdd(this, _columnFilters, __runInitializers(_init39, 96, this, {})), __runInitializers(_init39, 99, this);
169977
- __privateAdd(this, _showColumnFilters, __runInitializers(_init39, 100, this, false)), __runInitializers(_init39, 103, this);
170002
+ __privateAdd(this, _sortBy, __runInitializers(_init39, 84, this, [])), __runInitializers(_init39, 87, this);
170003
+ __privateAdd(this, _filterText, __runInitializers(_init39, 88, this, "")), __runInitializers(_init39, 91, this);
170004
+ __privateAdd(this, _columnFilters, __runInitializers(_init39, 92, this, {})), __runInitializers(_init39, 95, this);
170005
+ __privateAdd(this, _showColumnFilters, __runInitializers(_init39, 96, this, false)), __runInitializers(_init39, 99, this);
170006
+ __privateAdd(this, _showSelectionCheckbox, __runInitializers(_init39, 100, this, false)), __runInitializers(_init39, 103, this);
169978
170007
  __privateAdd(this, _fixedHeight, __runInitializers(_init39, 104, this, false)), __runInitializers(_init39, 107, this);
169979
170008
  __privateAdd(this, _searchMode, __runInitializers(_init39, 108, this, "table")), __runInitializers(_init39, 111, this);
169980
170009
  __publicField(this, "__searchTextSub");
@@ -169983,18 +170012,128 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
169983
170012
  __privateAdd(this, _selectedIds, __runInitializers(_init39, 116, this, /* @__PURE__ */ new Set())), __runInitializers(_init39, 119, this);
169984
170013
  __publicField(this, "_rowIdMap", /* @__PURE__ */ new WeakMap());
169985
170014
  __publicField(this, "_rowIdCounter", 0);
170015
+ /**
170016
+ * Anchor row id for shift+click range selection. Set whenever the user
170017
+ * makes a non-range click (plain or cmd/ctrl) so the next shift+click
170018
+ * can compute a contiguous range from this anchor.
170019
+ */
170020
+ __publicField(this, "__selectionAnchorId");
170021
+ __privateAdd(this, ___focusedCell, __runInitializers(_init39, 120, this)), __runInitializers(_init39, 123, this);
170022
+ __privateAdd(this, ___editingCell, __runInitializers(_init39, 124, this)), __runInitializers(_init39, 127, this);
170023
+ /**
170024
+ * Ctrl/Cmd+C copies the currently selected rows as a JSON array. Falls
170025
+ * back to copying the focused-row (`selectedDataRow`) if no multi
170026
+ * selection exists. No-op if a focused input/textarea would normally
170027
+ * receive the copy.
170028
+ */
170029
+ __publicField(this, "__handleHostKeydown", /* @__PURE__ */ __name((eventArg) => {
170030
+ const path2 = eventArg.composedPath?.() || [];
170031
+ let inEditor = false;
170032
+ for (const t9 of path2) {
170033
+ const tag = t9?.tagName;
170034
+ if (tag === "INPUT" || tag === "TEXTAREA" || t9?.isContentEditable) {
170035
+ inEditor = true;
170036
+ break;
170037
+ }
170038
+ }
170039
+ const isCopy = (eventArg.metaKey || eventArg.ctrlKey) && (eventArg.key === "c" || eventArg.key === "C");
170040
+ if (isCopy) {
170041
+ if (inEditor) return;
170042
+ const rows = [];
170043
+ if (this.selectedIds.size > 0) {
170044
+ for (const r11 of this.data) if (this.selectedIds.has(this.getRowId(r11))) rows.push(r11);
170045
+ } else if (this.selectedDataRow) {
170046
+ rows.push(this.selectedDataRow);
170047
+ }
170048
+ if (rows.length === 0) return;
170049
+ eventArg.preventDefault();
170050
+ this.__writeRowsAsJson(rows);
170051
+ return;
170052
+ }
170053
+ if (inEditor || this.__editingCell) return;
170054
+ switch (eventArg.key) {
170055
+ case "ArrowLeft":
170056
+ eventArg.preventDefault();
170057
+ this.moveFocusedCell(-1, 0, false);
170058
+ return;
170059
+ case "ArrowRight":
170060
+ eventArg.preventDefault();
170061
+ this.moveFocusedCell(1, 0, false);
170062
+ return;
170063
+ case "ArrowUp":
170064
+ eventArg.preventDefault();
170065
+ this.moveFocusedCell(0, -1, false);
170066
+ return;
170067
+ case "ArrowDown":
170068
+ eventArg.preventDefault();
170069
+ this.moveFocusedCell(0, 1, false);
170070
+ return;
170071
+ case "Enter":
170072
+ case "F2": {
170073
+ if (!this.__focusedCell) return;
170074
+ const view = this._lastViewData ?? [];
170075
+ const item = view.find((r11) => this.getRowId(r11) === this.__focusedCell.rowId);
170076
+ if (!item) return;
170077
+ const allCols = Array.isArray(this.columns) && this.columns.length > 0 ? computeEffectiveColumns(
170078
+ this.columns,
170079
+ this.augmentFromDisplayFunction,
170080
+ this.displayFunction,
170081
+ this.data
170082
+ ) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
170083
+ const col = allCols.find((c11) => String(c11.key) === this.__focusedCell.colKey);
170084
+ if (!col || !this.__isColumnEditable(col)) return;
170085
+ eventArg.preventDefault();
170086
+ this.startEditing(item, col);
170087
+ return;
170088
+ }
170089
+ case "Escape":
170090
+ if (this.__focusedCell) {
170091
+ this.__focusedCell = void 0;
170092
+ this.requestUpdate();
170093
+ }
170094
+ return;
170095
+ default:
170096
+ return;
170097
+ }
170098
+ }, "__handleHostKeydown"));
169986
170099
  // ─── Floating header (page-sticky) lifecycle ─────────────────────────
169987
170100
  __publicField(this, "__floatingResizeObserver");
169988
170101
  __publicField(this, "__floatingScrollHandler");
169989
170102
  __publicField(this, "__floatingActive", false);
169990
170103
  __publicField(this, "__scrollAncestors", []);
169991
170104
  __publicField(this, "__debounceTimer");
170105
+ if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
170106
+ this.addEventListener("keydown", this.__handleHostKeydown);
169992
170107
  }
169993
170108
  get value() {
169994
170109
  return this.data;
169995
170110
  }
169996
170111
  set value(_valueArg) {
169997
170112
  }
170113
+ /**
170114
+ * Copies the current selection as a JSON array. If `fallbackRow` is given
170115
+ * and there is no multi-selection, that row is copied instead. Used both
170116
+ * by the Ctrl/Cmd+C handler and by the default context-menu action.
170117
+ */
170118
+ copySelectionAsJson(fallbackRow) {
170119
+ const rows = [];
170120
+ if (this.selectedIds.size > 0) {
170121
+ for (const r11 of this.data) if (this.selectedIds.has(this.getRowId(r11))) rows.push(r11);
170122
+ } else if (fallbackRow) {
170123
+ rows.push(fallbackRow);
170124
+ } else if (this.selectedDataRow) {
170125
+ rows.push(this.selectedDataRow);
170126
+ }
170127
+ if (rows.length === 0) return;
170128
+ this.__writeRowsAsJson(rows);
170129
+ }
170130
+ __writeRowsAsJson(rows) {
170131
+ try {
170132
+ const json = JSON.stringify(rows, null, 2);
170133
+ navigator.clipboard?.writeText(json);
170134
+ } catch {
170135
+ }
170136
+ }
169998
170137
  render() {
169999
170138
  const usingColumns = Array.isArray(this.columns) && this.columns.length > 0;
170000
170139
  const effectiveColumns = usingColumns ? computeEffectiveColumns(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
@@ -170091,15 +170230,9 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170091
170230
  }, "getTr");
170092
170231
  return b2`
170093
170232
  <tr
170094
- @click=${() => {
170095
- this.selectedDataRow = itemArg;
170096
- if (this.selectionMode === "single") {
170097
- const id = this.getRowId(itemArg);
170098
- this.selectedIds.clear();
170099
- this.selectedIds.add(id);
170100
- this.emitSelectionChange();
170101
- this.requestUpdate();
170102
- }
170233
+ @click=${(e11) => this.handleRowClick(e11, itemArg, rowIndex, viewData)}
170234
+ @mousedown=${(e11) => {
170235
+ if (e11.shiftKey && this.selectionMode !== "single") e11.preventDefault();
170103
170236
  }}
170104
170237
  @dragenter=${async (eventArg) => {
170105
170238
  eventArg.preventDefault();
@@ -170134,27 +170267,43 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170134
170267
  }
170135
170268
  }}
170136
170269
  @contextmenu=${async (eventArg) => {
170137
- DeesContextmenu.openContextMenuWithOptions(
170138
- eventArg,
170139
- this.getActionsForType("contextmenu").map((action) => {
170140
- const menuItem = {
170141
- name: action.name,
170142
- iconName: action.iconName,
170143
- action: /* @__PURE__ */ __name(async () => {
170144
- await action.actionFunc({
170145
- item: itemArg,
170146
- table: this
170147
- });
170148
- return null;
170149
- }, "action")
170150
- };
170151
- return menuItem;
170152
- })
170153
- );
170270
+ if (!this.isRowSelected(itemArg)) {
170271
+ this.selectedDataRow = itemArg;
170272
+ this.selectedIds.clear();
170273
+ this.selectedIds.add(this.getRowId(itemArg));
170274
+ this.__selectionAnchorId = this.getRowId(itemArg);
170275
+ this.emitSelectionChange();
170276
+ this.requestUpdate();
170277
+ }
170278
+ const userItems = this.getActionsForType("contextmenu").map((action) => ({
170279
+ name: action.name,
170280
+ iconName: action.iconName,
170281
+ action: /* @__PURE__ */ __name(async () => {
170282
+ await action.actionFunc({
170283
+ item: itemArg,
170284
+ table: this
170285
+ });
170286
+ return null;
170287
+ }, "action")
170288
+ }));
170289
+ const defaultItems = [
170290
+ {
170291
+ name: this.selectedIds.size > 1 ? `Copy ${this.selectedIds.size} rows as JSON` : "Copy row as JSON",
170292
+ iconName: "lucide:Copy",
170293
+ action: /* @__PURE__ */ __name(async () => {
170294
+ this.copySelectionAsJson(itemArg);
170295
+ return null;
170296
+ }, "action")
170297
+ }
170298
+ ];
170299
+ DeesContextmenu.openContextMenuWithOptions(eventArg, [
170300
+ ...userItems,
170301
+ ...defaultItems
170302
+ ]);
170154
170303
  }}
170155
- class="${itemArg === this.selectedDataRow ? "selected" : ""}"
170304
+ class="${itemArg === this.selectedDataRow || this.isRowSelected(itemArg) ? "selected" : ""}"
170156
170305
  >
170157
- ${this.selectionMode !== "none" ? b2`<td style="width:42px; text-align:center;">
170306
+ ${this.showSelectionCheckbox ? b2`<td style="width:42px; text-align:center;">
170158
170307
  <dees-input-checkbox
170159
170308
  .value=${this.isRowSelected(itemArg)}
170160
170309
  @newValue=${(e11) => {
@@ -170167,20 +170316,42 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170167
170316
  const value2 = getCellValue(itemArg, col, this.displayFunction);
170168
170317
  const content3 = col.renderer ? col.renderer(value2, itemArg, { rowIndex, colIndex, column: col }) : value2;
170169
170318
  const editKey = String(col.key);
170319
+ const isEditable = !!(col.editable || col.editor);
170320
+ const rowId = this.getRowId(itemArg);
170321
+ const isFocused = this.__focusedCell?.rowId === rowId && this.__focusedCell?.colKey === editKey;
170322
+ const isEditing = this.__editingCell?.rowId === rowId && this.__editingCell?.colKey === editKey;
170323
+ const cellClasses = [
170324
+ isEditable ? "editable" : "",
170325
+ isFocused && !isEditing ? "focused" : "",
170326
+ isEditing ? "editingCell" : ""
170327
+ ].filter(Boolean).join(" ");
170170
170328
  return b2`
170171
170329
  <td
170330
+ class=${cellClasses}
170331
+ @click=${(e11) => {
170332
+ if (isEditing) {
170333
+ e11.stopPropagation();
170334
+ return;
170335
+ }
170336
+ if (isEditable) {
170337
+ this.__focusedCell = { rowId, colKey: editKey };
170338
+ }
170339
+ }}
170172
170340
  @dblclick=${(e11) => {
170173
170341
  const dblAction = this.dataActions.find(
170174
170342
  (actionArg) => actionArg.type?.includes("doubleClick")
170175
170343
  );
170176
- if (this.editableFields.includes(editKey)) {
170177
- this.handleCellEditing(e11, itemArg, editKey);
170344
+ if (isEditable) {
170345
+ e11.stopPropagation();
170346
+ this.startEditing(itemArg, col);
170178
170347
  } else if (dblAction) {
170179
170348
  dblAction.actionFunc({ item: itemArg, table: this });
170180
170349
  }
170181
170350
  }}
170182
170351
  >
170183
- <div class="innerCellContainer">${content3}</div>
170352
+ <div class="innerCellContainer">
170353
+ ${isEditing ? this.renderCellEditor(itemArg, col) : content3}
170354
+ </div>
170184
170355
  </td>
170185
170356
  `;
170186
170357
  })}
@@ -170261,7 +170432,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170261
170432
  renderHeaderRows(effectiveColumns) {
170262
170433
  return b2`
170263
170434
  <tr>
170264
- ${this.selectionMode !== "none" ? b2`
170435
+ ${this.showSelectionCheckbox ? b2`
170265
170436
  <th style="width:42px; text-align:center;">
170266
170437
  ${this.selectionMode === "multi" ? b2`
170267
170438
  <dees-input-checkbox
@@ -170293,7 +170464,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170293
170464
  ${this.dataActions && this.dataActions.length > 0 ? b2`<th class="actionsCol">Actions</th>` : b2``}
170294
170465
  </tr>
170295
170466
  ${this.showColumnFilters ? b2`<tr class="filtersRow">
170296
- ${this.selectionMode !== "none" ? b2`<th style="width:42px;"></th>` : b2``}
170467
+ ${this.showSelectionCheckbox ? b2`<th style="width:42px;"></th>` : b2``}
170297
170468
  ${effectiveColumns.filter((c11) => !c11.hidden).map((col) => {
170298
170469
  const key2 = String(col.key);
170299
170470
  if (col.filterable === false) return b2`<th></th>`;
@@ -170917,6 +171088,64 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170917
171088
  this.emitSelectionChange();
170918
171089
  this.requestUpdate();
170919
171090
  }
171091
+ /**
171092
+ * Handles row clicks with file-manager style selection semantics:
171093
+ * - plain click: select only this row, set anchor
171094
+ * - cmd/ctrl+click: toggle this row in/out, set anchor
171095
+ * - shift+click: select the contiguous range from the anchor to this row
171096
+ *
171097
+ * Multi-row click selection is always available (`selectionMode === 'none'`
171098
+ * and `'multi'` both behave this way) so consumers can always copy a set
171099
+ * of rows. Only `selectionMode === 'single'` restricts to one row.
171100
+ */
171101
+ handleRowClick(eventArg, item, rowIndex, view) {
171102
+ const id = this.getRowId(item);
171103
+ if (this.selectionMode === "single") {
171104
+ this.selectedDataRow = item;
171105
+ this.selectedIds.clear();
171106
+ this.selectedIds.add(id);
171107
+ this.__selectionAnchorId = id;
171108
+ this.emitSelectionChange();
171109
+ this.requestUpdate();
171110
+ return;
171111
+ }
171112
+ const isToggle = eventArg.metaKey || eventArg.ctrlKey;
171113
+ const isRange = eventArg.shiftKey;
171114
+ if (isRange && this.__selectionAnchorId !== void 0) {
171115
+ window.getSelection?.()?.removeAllRanges();
171116
+ const anchorIdx = view.findIndex((r11) => this.getRowId(r11) === this.__selectionAnchorId);
171117
+ if (anchorIdx >= 0) {
171118
+ const [a5, b5] = anchorIdx <= rowIndex ? [anchorIdx, rowIndex] : [rowIndex, anchorIdx];
171119
+ this.selectedIds.clear();
171120
+ for (let i11 = a5; i11 <= b5; i11++) this.selectedIds.add(this.getRowId(view[i11]));
171121
+ } else {
171122
+ this.selectedIds.clear();
171123
+ this.selectedIds.add(id);
171124
+ this.__selectionAnchorId = id;
171125
+ }
171126
+ this.selectedDataRow = item;
171127
+ } else if (isToggle) {
171128
+ const wasSelected = this.selectedIds.has(id);
171129
+ if (wasSelected) {
171130
+ this.selectedIds.delete(id);
171131
+ if (this.selectedDataRow === item) {
171132
+ const remaining = view.find((r11) => this.selectedIds.has(this.getRowId(r11)));
171133
+ this.selectedDataRow = remaining;
171134
+ }
171135
+ } else {
171136
+ this.selectedIds.add(id);
171137
+ this.selectedDataRow = item;
171138
+ }
171139
+ this.__selectionAnchorId = id;
171140
+ } else {
171141
+ this.selectedDataRow = item;
171142
+ this.selectedIds.clear();
171143
+ this.selectedIds.add(id);
171144
+ this.__selectionAnchorId = id;
171145
+ }
171146
+ this.emitSelectionChange();
171147
+ this.requestUpdate();
171148
+ }
170920
171149
  setRowSelected(row, checked) {
170921
171150
  const id = this.getRowId(row);
170922
171151
  if (this.selectionMode === "single") {
@@ -170974,38 +171203,193 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
170974
171203
  }
170975
171204
  return actions;
170976
171205
  }
170977
- async handleCellEditing(event, itemArg, key2) {
170978
- await this.domtoolsPromise;
170979
- const target = event.target;
170980
- const originalColor = target.style.color;
170981
- target.style.color = "transparent";
170982
- const transformedItem = this.displayFunction(itemArg);
170983
- const initialValue = transformedItem[key2] ?? itemArg[key2] ?? "";
170984
- const input = document.createElement("input");
170985
- input.type = "text";
170986
- input.value = initialValue;
170987
- const blurInput = /* @__PURE__ */ __name(async (blurArg = true, saveArg = false) => {
170988
- if (blurArg) {
170989
- input.blur();
170990
- }
170991
- if (saveArg) {
170992
- itemArg[key2] = input.value;
170993
- this.changeSubject.next(this);
170994
- }
170995
- input.remove();
170996
- target.style.color = originalColor;
170997
- this.requestUpdate();
170998
- }, "blurInput");
170999
- input.addEventListener("blur", () => {
171000
- blurInput(false, false);
171206
+ // ─── Cell editing ─────────────────────────────────────────────────────
171207
+ /** True if the column has any in-cell editor configured. */
171208
+ __isColumnEditable(col) {
171209
+ return !!(col.editable || col.editor);
171210
+ }
171211
+ /** Effective columns filtered to those that can be edited (visible only). */
171212
+ __editableColumns(effectiveColumns) {
171213
+ return effectiveColumns.filter((c11) => !c11.hidden && this.__isColumnEditable(c11));
171214
+ }
171215
+ /**
171216
+ * Opens the editor on the given cell. Sets focus + editing state and
171217
+ * focuses the freshly rendered editor on the next frame.
171218
+ */
171219
+ startEditing(item, col) {
171220
+ if (!this.__isColumnEditable(col)) return;
171221
+ const rowId = this.getRowId(item);
171222
+ const colKey = String(col.key);
171223
+ this.__focusedCell = { rowId, colKey };
171224
+ this.__editingCell = { rowId, colKey };
171225
+ this.requestUpdate();
171226
+ this.updateComplete.then(() => {
171227
+ const el = this.shadowRoot?.querySelector(
171228
+ ".editingCell dees-input-text, .editingCell dees-input-checkbox, .editingCell dees-input-dropdown, .editingCell dees-input-datepicker, .editingCell dees-input-tags"
171229
+ );
171230
+ el?.focus?.();
171001
171231
  });
171002
- input.addEventListener("keydown", (e11) => {
171003
- if (e11.key === "Enter") {
171004
- blurInput(true, true);
171232
+ }
171233
+ /** Closes the editor without committing. */
171234
+ cancelCellEdit() {
171235
+ this.__editingCell = void 0;
171236
+ this.requestUpdate();
171237
+ }
171238
+ /**
171239
+ * Commits an editor value to the row. Runs `parse` then `validate`. On
171240
+ * validation failure, fires `cellEditError` and leaves the editor open.
171241
+ * On success, mutates `data` in place, fires `cellEdit`, and closes the
171242
+ * editor.
171243
+ */
171244
+ commitCellEdit(item, col, editorValue) {
171245
+ const key2 = String(col.key);
171246
+ const oldValue = item[col.key];
171247
+ const parsed = col.parse ? col.parse(editorValue, item) : editorValue;
171248
+ if (col.validate) {
171249
+ const result = col.validate(parsed, item);
171250
+ if (typeof result === "string") {
171251
+ this.dispatchEvent(
171252
+ new CustomEvent("cellEditError", {
171253
+ detail: { row: item, key: key2, value: parsed, message: result },
171254
+ bubbles: true,
171255
+ composed: true
171256
+ })
171257
+ );
171258
+ return;
171005
171259
  }
171006
- });
171007
- target.appendChild(input);
171008
- input.focus();
171260
+ }
171261
+ if (parsed !== oldValue) {
171262
+ item[col.key] = parsed;
171263
+ this.dispatchEvent(
171264
+ new CustomEvent("cellEdit", {
171265
+ detail: { row: item, key: key2, oldValue, newValue: parsed },
171266
+ bubbles: true,
171267
+ composed: true
171268
+ })
171269
+ );
171270
+ this.changeSubject.next(this);
171271
+ }
171272
+ this.__editingCell = void 0;
171273
+ this.requestUpdate();
171274
+ }
171275
+ /** Renders the appropriate dees-input-* component for this column. */
171276
+ renderCellEditor(item, col) {
171277
+ const raw2 = item[col.key];
171278
+ const value2 = col.format ? col.format(raw2, item) : raw2;
171279
+ const editorType = col.editor ?? "text";
171280
+ const onTextCommit = /* @__PURE__ */ __name((target) => this.commitCellEdit(item, col, target.value), "onTextCommit");
171281
+ switch (editorType) {
171282
+ case "checkbox":
171283
+ return b2`<dees-input-checkbox
171284
+ .value=${!!value2}
171285
+ @newValue=${(e11) => {
171286
+ e11.stopPropagation();
171287
+ this.commitCellEdit(item, col, e11.detail);
171288
+ }}
171289
+ ></dees-input-checkbox>`;
171290
+ case "dropdown": {
171291
+ const options2 = col.editorOptions?.options ?? [];
171292
+ const selected = options2.find((o13) => (o13?.option ?? o13?.key ?? o13) === value2) ?? null;
171293
+ return b2`<dees-input-dropdown
171294
+ .options=${options2}
171295
+ .selectedOption=${selected}
171296
+ @selectedOption=${(e11) => {
171297
+ e11.stopPropagation();
171298
+ const detail = e11.detail;
171299
+ const newRaw = detail?.option ?? detail?.key ?? detail;
171300
+ this.commitCellEdit(item, col, newRaw);
171301
+ }}
171302
+ ></dees-input-dropdown>`;
171303
+ }
171304
+ case "date":
171305
+ return b2`<dees-input-datepicker
171306
+ .value=${value2}
171307
+ @focusout=${(e11) => onTextCommit(e11.target)}
171308
+ @keydown=${(e11) => this.__handleEditorKey(e11, item, col)}
171309
+ ></dees-input-datepicker>`;
171310
+ case "tags":
171311
+ return b2`<dees-input-tags
171312
+ .value=${value2 ?? []}
171313
+ @focusout=${(e11) => onTextCommit(e11.target)}
171314
+ @keydown=${(e11) => this.__handleEditorKey(e11, item, col)}
171315
+ ></dees-input-tags>`;
171316
+ case "number":
171317
+ case "text":
171318
+ default:
171319
+ return b2`<dees-input-text
171320
+ .value=${value2 == null ? "" : String(value2)}
171321
+ @focusout=${(e11) => onTextCommit(e11.target)}
171322
+ @keydown=${(e11) => this.__handleEditorKey(e11, item, col)}
171323
+ ></dees-input-text>`;
171324
+ }
171325
+ }
171326
+ /**
171327
+ * Centralized keydown handler for text-style editors. Handles Esc (cancel),
171328
+ * Enter (commit + move down) and Tab/Shift+Tab (commit + move horizontally).
171329
+ */
171330
+ __handleEditorKey(eventArg, item, col) {
171331
+ if (eventArg.key === "Escape") {
171332
+ eventArg.preventDefault();
171333
+ eventArg.stopPropagation();
171334
+ this.cancelCellEdit();
171335
+ this.focus();
171336
+ } else if (eventArg.key === "Enter") {
171337
+ eventArg.preventDefault();
171338
+ eventArg.stopPropagation();
171339
+ const target = eventArg.target;
171340
+ this.commitCellEdit(item, col, target.value);
171341
+ this.moveFocusedCell(0, 1, true);
171342
+ } else if (eventArg.key === "Tab") {
171343
+ eventArg.preventDefault();
171344
+ eventArg.stopPropagation();
171345
+ const target = eventArg.target;
171346
+ this.commitCellEdit(item, col, target.value);
171347
+ this.moveFocusedCell(eventArg.shiftKey ? -1 : 1, 0, true);
171348
+ }
171349
+ }
171350
+ /**
171351
+ * Moves the focused cell by `dx` columns and `dy` rows along the editable
171352
+ * grid. Wraps row-end → next row when moving horizontally. If
171353
+ * `andStartEditing` is true, opens the editor on the new cell.
171354
+ */
171355
+ moveFocusedCell(dx, dy, andStartEditing) {
171356
+ const view = this._lastViewData ?? [];
171357
+ if (view.length === 0) return;
171358
+ const allCols = Array.isArray(this.columns) && this.columns.length > 0 ? computeEffectiveColumns(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
171359
+ const editableCols = this.__editableColumns(allCols);
171360
+ if (editableCols.length === 0) return;
171361
+ let rowIdx = 0;
171362
+ let colIdx = 0;
171363
+ if (this.__focusedCell) {
171364
+ rowIdx = view.findIndex((r11) => this.getRowId(r11) === this.__focusedCell.rowId);
171365
+ colIdx = editableCols.findIndex((c11) => String(c11.key) === this.__focusedCell.colKey);
171366
+ if (rowIdx < 0) rowIdx = 0;
171367
+ if (colIdx < 0) colIdx = 0;
171368
+ }
171369
+ if (dx !== 0) {
171370
+ colIdx += dx;
171371
+ while (colIdx >= editableCols.length) {
171372
+ colIdx -= editableCols.length;
171373
+ rowIdx += 1;
171374
+ }
171375
+ while (colIdx < 0) {
171376
+ colIdx += editableCols.length;
171377
+ rowIdx -= 1;
171378
+ }
171379
+ }
171380
+ if (dy !== 0) rowIdx += dy;
171381
+ if (rowIdx < 0 || rowIdx >= view.length) {
171382
+ this.cancelCellEdit();
171383
+ return;
171384
+ }
171385
+ const item = view[rowIdx];
171386
+ const col = editableCols[colIdx];
171387
+ this.__focusedCell = { rowId: this.getRowId(item), colKey: String(col.key) };
171388
+ if (andStartEditing) {
171389
+ this.startEditing(item, col);
171390
+ } else {
171391
+ this.requestUpdate();
171392
+ }
171009
171393
  }
171010
171394
  };
171011
171395
  _init39 = __decoratorStart(_a42);
@@ -171025,7 +171409,6 @@ _augmentFromDisplayFunction = new WeakMap();
171025
171409
  _displayFunction = new WeakMap();
171026
171410
  _reverseDisplayFunction = new WeakMap();
171027
171411
  _selectedDataRow = new WeakMap();
171028
- _editableFields = new WeakMap();
171029
171412
  _showVerticalLines = new WeakMap();
171030
171413
  _showHorizontalLines = new WeakMap();
171031
171414
  _showGrid = new WeakMap();
@@ -171033,10 +171416,13 @@ _sortBy = new WeakMap();
171033
171416
  _filterText = new WeakMap();
171034
171417
  _columnFilters = new WeakMap();
171035
171418
  _showColumnFilters = new WeakMap();
171419
+ _showSelectionCheckbox = new WeakMap();
171036
171420
  _fixedHeight = new WeakMap();
171037
171421
  _searchMode = new WeakMap();
171038
171422
  _selectionMode = new WeakMap();
171039
171423
  _selectedIds = new WeakMap();
171424
+ ___focusedCell = new WeakMap();
171425
+ ___editingCell = new WeakMap();
171040
171426
  __decorateElement(_init39, 4, "heading1", _heading1_dec, _DeesTable, _heading1);
171041
171427
  __decorateElement(_init39, 4, "heading2", _heading2_dec, _DeesTable, _heading22);
171042
171428
  __decorateElement(_init39, 4, "data", _data_dec, _DeesTable, _data);
@@ -171053,7 +171439,6 @@ __decorateElement(_init39, 4, "augmentFromDisplayFunction", _augmentFromDisplayF
171053
171439
  __decorateElement(_init39, 4, "displayFunction", _displayFunction_dec, _DeesTable, _displayFunction);
171054
171440
  __decorateElement(_init39, 4, "reverseDisplayFunction", _reverseDisplayFunction_dec, _DeesTable, _reverseDisplayFunction);
171055
171441
  __decorateElement(_init39, 4, "selectedDataRow", _selectedDataRow_dec, _DeesTable, _selectedDataRow);
171056
- __decorateElement(_init39, 4, "editableFields", _editableFields_dec, _DeesTable, _editableFields);
171057
171442
  __decorateElement(_init39, 4, "showVerticalLines", _showVerticalLines_dec, _DeesTable, _showVerticalLines);
171058
171443
  __decorateElement(_init39, 4, "showHorizontalLines", _showHorizontalLines_dec, _DeesTable, _showHorizontalLines);
171059
171444
  __decorateElement(_init39, 4, "showGrid", _showGrid_dec, _DeesTable, _showGrid);
@@ -171061,10 +171446,13 @@ __decorateElement(_init39, 4, "sortBy", _sortBy_dec, _DeesTable, _sortBy);
171061
171446
  __decorateElement(_init39, 4, "filterText", _filterText_dec, _DeesTable, _filterText);
171062
171447
  __decorateElement(_init39, 4, "columnFilters", _columnFilters_dec, _DeesTable, _columnFilters);
171063
171448
  __decorateElement(_init39, 4, "showColumnFilters", _showColumnFilters_dec, _DeesTable, _showColumnFilters);
171449
+ __decorateElement(_init39, 4, "showSelectionCheckbox", _showSelectionCheckbox_dec, _DeesTable, _showSelectionCheckbox);
171064
171450
  __decorateElement(_init39, 4, "fixedHeight", _fixedHeight_dec, _DeesTable, _fixedHeight);
171065
171451
  __decorateElement(_init39, 4, "searchMode", _searchMode_dec, _DeesTable, _searchMode);
171066
171452
  __decorateElement(_init39, 4, "selectionMode", _selectionMode_dec, _DeesTable, _selectionMode);
171067
171453
  __decorateElement(_init39, 4, "selectedIds", _selectedIds_dec, _DeesTable, _selectedIds);
171454
+ __decorateElement(_init39, 4, "__focusedCell", ___focusedCell_dec, _DeesTable, ___focusedCell);
171455
+ __decorateElement(_init39, 4, "__editingCell", ___editingCell_dec, _DeesTable, ___editingCell);
171068
171456
  _DeesTable = __decorateElement(_init39, 0, "DeesTable", _DeesTable_decorators, _DeesTable);
171069
171457
  __name(_DeesTable, "DeesTable");
171070
171458
  __publicField(_DeesTable, "demo", demoFunc29);