@design.estate/dees-catalog 3.63.0 → 3.64.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.
@@ -163996,6 +163996,7 @@ var tableStyles = [
163996
163996
  tbody tr {
163997
163997
  transition: background-color 0.15s ease;
163998
163998
  position: relative;
163999
+ user-select: none;
163999
164000
  }
164000
164001
 
164001
164002
  /* Default horizontal lines (bottom border only) */
@@ -164549,7 +164550,7 @@ __name(compileLucenePredicate, "compileLucenePredicate");
164549
164550
  init_dist_ts30();
164550
164551
  init_dist_ts29();
164551
164552
  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;
164553
+ var _selectedIds_dec, _selectionMode_dec, _searchMode_dec, _fixedHeight_dec, _showSelectionCheckbox_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, _showSelectionCheckbox, _fixedHeight, _searchMode, _selectionMode, _selectedIds;
164553
164554
  function ordinalLabel(n12) {
164554
164555
  const s10 = ["th", "st", "nd", "rd"];
164555
164556
  const v5 = n12 % 100;
@@ -164598,7 +164599,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164598
164599
  type: Boolean,
164599
164600
  reflect: true,
164600
164601
  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) {
164602
+ })], _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 })], _a42) {
164602
164603
  constructor() {
164603
164604
  super();
164604
164605
  __privateAdd(this, _heading1, __runInitializers(_init39, 8, this, "heading 1")), __runInitializers(_init39, 11, this);
@@ -164629,26 +164630,84 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164629
164630
  __privateAdd(this, _filterText, __runInitializers(_init39, 92, this, "")), __runInitializers(_init39, 95, this);
164630
164631
  __privateAdd(this, _columnFilters, __runInitializers(_init39, 96, this, {})), __runInitializers(_init39, 99, this);
164631
164632
  __privateAdd(this, _showColumnFilters, __runInitializers(_init39, 100, this, false)), __runInitializers(_init39, 103, this);
164632
- __privateAdd(this, _fixedHeight, __runInitializers(_init39, 104, this, false)), __runInitializers(_init39, 107, this);
164633
- __privateAdd(this, _searchMode, __runInitializers(_init39, 108, this, "table")), __runInitializers(_init39, 111, this);
164633
+ __privateAdd(this, _showSelectionCheckbox, __runInitializers(_init39, 104, this, false)), __runInitializers(_init39, 107, this);
164634
+ __privateAdd(this, _fixedHeight, __runInitializers(_init39, 108, this, false)), __runInitializers(_init39, 111, this);
164635
+ __privateAdd(this, _searchMode, __runInitializers(_init39, 112, this, "table")), __runInitializers(_init39, 115, this);
164634
164636
  __publicField(this, "__searchTextSub");
164635
164637
  __publicField(this, "__searchModeSub");
164636
- __privateAdd(this, _selectionMode, __runInitializers(_init39, 112, this, "none")), __runInitializers(_init39, 115, this);
164637
- __privateAdd(this, _selectedIds, __runInitializers(_init39, 116, this, /* @__PURE__ */ new Set())), __runInitializers(_init39, 119, this);
164638
+ __privateAdd(this, _selectionMode, __runInitializers(_init39, 116, this, "none")), __runInitializers(_init39, 119, this);
164639
+ __privateAdd(this, _selectedIds, __runInitializers(_init39, 120, this, /* @__PURE__ */ new Set())), __runInitializers(_init39, 123, this);
164638
164640
  __publicField(this, "_rowIdMap", /* @__PURE__ */ new WeakMap());
164639
164641
  __publicField(this, "_rowIdCounter", 0);
164642
+ /**
164643
+ * Anchor row id for shift+click range selection. Set whenever the user
164644
+ * makes a non-range click (plain or cmd/ctrl) so the next shift+click
164645
+ * can compute a contiguous range from this anchor.
164646
+ */
164647
+ __publicField(this, "__selectionAnchorId");
164648
+ /**
164649
+ * Ctrl/Cmd+C copies the currently selected rows as a JSON array. Falls
164650
+ * back to copying the focused-row (`selectedDataRow`) if no multi
164651
+ * selection exists. No-op if a focused input/textarea would normally
164652
+ * receive the copy.
164653
+ */
164654
+ __publicField(this, "__handleHostKeydown", /* @__PURE__ */ __name((eventArg) => {
164655
+ const isCopy = (eventArg.metaKey || eventArg.ctrlKey) && (eventArg.key === "c" || eventArg.key === "C");
164656
+ if (!isCopy) return;
164657
+ const path2 = eventArg.composedPath?.() || [];
164658
+ for (const t9 of path2) {
164659
+ const tag = t9?.tagName;
164660
+ if (tag === "INPUT" || tag === "TEXTAREA") return;
164661
+ if (t9?.isContentEditable) return;
164662
+ }
164663
+ const rows = [];
164664
+ if (this.selectedIds.size > 0) {
164665
+ for (const r11 of this.data) if (this.selectedIds.has(this.getRowId(r11))) rows.push(r11);
164666
+ } else if (this.selectedDataRow) {
164667
+ rows.push(this.selectedDataRow);
164668
+ }
164669
+ if (rows.length === 0) return;
164670
+ eventArg.preventDefault();
164671
+ this.__writeRowsAsJson(rows);
164672
+ }, "__handleHostKeydown"));
164640
164673
  // ─── Floating header (page-sticky) lifecycle ─────────────────────────
164641
164674
  __publicField(this, "__floatingResizeObserver");
164642
164675
  __publicField(this, "__floatingScrollHandler");
164643
164676
  __publicField(this, "__floatingActive", false);
164644
164677
  __publicField(this, "__scrollAncestors", []);
164645
164678
  __publicField(this, "__debounceTimer");
164679
+ if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
164680
+ this.addEventListener("keydown", this.__handleHostKeydown);
164646
164681
  }
164647
164682
  get value() {
164648
164683
  return this.data;
164649
164684
  }
164650
164685
  set value(_valueArg) {
164651
164686
  }
164687
+ /**
164688
+ * Copies the current selection as a JSON array. If `fallbackRow` is given
164689
+ * and there is no multi-selection, that row is copied instead. Used both
164690
+ * by the Ctrl/Cmd+C handler and by the default context-menu action.
164691
+ */
164692
+ copySelectionAsJson(fallbackRow) {
164693
+ const rows = [];
164694
+ if (this.selectedIds.size > 0) {
164695
+ for (const r11 of this.data) if (this.selectedIds.has(this.getRowId(r11))) rows.push(r11);
164696
+ } else if (fallbackRow) {
164697
+ rows.push(fallbackRow);
164698
+ } else if (this.selectedDataRow) {
164699
+ rows.push(this.selectedDataRow);
164700
+ }
164701
+ if (rows.length === 0) return;
164702
+ this.__writeRowsAsJson(rows);
164703
+ }
164704
+ __writeRowsAsJson(rows) {
164705
+ try {
164706
+ const json = JSON.stringify(rows, null, 2);
164707
+ navigator.clipboard?.writeText(json);
164708
+ } catch {
164709
+ }
164710
+ }
164652
164711
  render() {
164653
164712
  const usingColumns = Array.isArray(this.columns) && this.columns.length > 0;
164654
164713
  const effectiveColumns = usingColumns ? computeEffectiveColumns(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data) : computeColumnsFromDisplayFunction(this.displayFunction, this.data);
@@ -164745,15 +164804,9 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164745
164804
  }, "getTr");
164746
164805
  return b2`
164747
164806
  <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
- }
164807
+ @click=${(e11) => this.handleRowClick(e11, itemArg, rowIndex, viewData)}
164808
+ @mousedown=${(e11) => {
164809
+ if (e11.shiftKey && this.selectionMode !== "single") e11.preventDefault();
164757
164810
  }}
164758
164811
  @dragenter=${async (eventArg) => {
164759
164812
  eventArg.preventDefault();
@@ -164788,27 +164841,43 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164788
164841
  }
164789
164842
  }}
164790
164843
  @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
- );
164844
+ if (!this.isRowSelected(itemArg)) {
164845
+ this.selectedDataRow = itemArg;
164846
+ this.selectedIds.clear();
164847
+ this.selectedIds.add(this.getRowId(itemArg));
164848
+ this.__selectionAnchorId = this.getRowId(itemArg);
164849
+ this.emitSelectionChange();
164850
+ this.requestUpdate();
164851
+ }
164852
+ const userItems = this.getActionsForType("contextmenu").map((action) => ({
164853
+ name: action.name,
164854
+ iconName: action.iconName,
164855
+ action: /* @__PURE__ */ __name(async () => {
164856
+ await action.actionFunc({
164857
+ item: itemArg,
164858
+ table: this
164859
+ });
164860
+ return null;
164861
+ }, "action")
164862
+ }));
164863
+ const defaultItems = [
164864
+ {
164865
+ name: this.selectedIds.size > 1 ? `Copy ${this.selectedIds.size} rows as JSON` : "Copy row as JSON",
164866
+ iconName: "lucide:Copy",
164867
+ action: /* @__PURE__ */ __name(async () => {
164868
+ this.copySelectionAsJson(itemArg);
164869
+ return null;
164870
+ }, "action")
164871
+ }
164872
+ ];
164873
+ DeesContextmenu.openContextMenuWithOptions(eventArg, [
164874
+ ...userItems,
164875
+ ...defaultItems
164876
+ ]);
164808
164877
  }}
164809
- class="${itemArg === this.selectedDataRow ? "selected" : ""}"
164878
+ class="${itemArg === this.selectedDataRow || this.isRowSelected(itemArg) ? "selected" : ""}"
164810
164879
  >
164811
- ${this.selectionMode !== "none" ? b2`<td style="width:42px; text-align:center;">
164880
+ ${this.showSelectionCheckbox ? b2`<td style="width:42px; text-align:center;">
164812
164881
  <dees-input-checkbox
164813
164882
  .value=${this.isRowSelected(itemArg)}
164814
164883
  @newValue=${(e11) => {
@@ -164915,7 +164984,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164915
164984
  renderHeaderRows(effectiveColumns) {
164916
164985
  return b2`
164917
164986
  <tr>
164918
- ${this.selectionMode !== "none" ? b2`
164987
+ ${this.showSelectionCheckbox ? b2`
164919
164988
  <th style="width:42px; text-align:center;">
164920
164989
  ${this.selectionMode === "multi" ? b2`
164921
164990
  <dees-input-checkbox
@@ -164947,7 +165016,7 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
164947
165016
  ${this.dataActions && this.dataActions.length > 0 ? b2`<th class="actionsCol">Actions</th>` : b2``}
164948
165017
  </tr>
164949
165018
  ${this.showColumnFilters ? b2`<tr class="filtersRow">
164950
- ${this.selectionMode !== "none" ? b2`<th style="width:42px;"></th>` : b2``}
165019
+ ${this.showSelectionCheckbox ? b2`<th style="width:42px;"></th>` : b2``}
164951
165020
  ${effectiveColumns.filter((c11) => !c11.hidden).map((col) => {
164952
165021
  const key2 = String(col.key);
164953
165022
  if (col.filterable === false) return b2`<th></th>`;
@@ -165571,6 +165640,64 @@ var _DeesTable = class _DeesTable extends (_a42 = DeesElement, _heading1_dec = [
165571
165640
  this.emitSelectionChange();
165572
165641
  this.requestUpdate();
165573
165642
  }
165643
+ /**
165644
+ * Handles row clicks with file-manager style selection semantics:
165645
+ * - plain click: select only this row, set anchor
165646
+ * - cmd/ctrl+click: toggle this row in/out, set anchor
165647
+ * - shift+click: select the contiguous range from the anchor to this row
165648
+ *
165649
+ * Multi-row click selection is always available (`selectionMode === 'none'`
165650
+ * and `'multi'` both behave this way) so consumers can always copy a set
165651
+ * of rows. Only `selectionMode === 'single'` restricts to one row.
165652
+ */
165653
+ handleRowClick(eventArg, item, rowIndex, view) {
165654
+ const id = this.getRowId(item);
165655
+ if (this.selectionMode === "single") {
165656
+ this.selectedDataRow = item;
165657
+ this.selectedIds.clear();
165658
+ this.selectedIds.add(id);
165659
+ this.__selectionAnchorId = id;
165660
+ this.emitSelectionChange();
165661
+ this.requestUpdate();
165662
+ return;
165663
+ }
165664
+ const isToggle = eventArg.metaKey || eventArg.ctrlKey;
165665
+ const isRange = eventArg.shiftKey;
165666
+ if (isRange && this.__selectionAnchorId !== void 0) {
165667
+ window.getSelection?.()?.removeAllRanges();
165668
+ const anchorIdx = view.findIndex((r11) => this.getRowId(r11) === this.__selectionAnchorId);
165669
+ if (anchorIdx >= 0) {
165670
+ const [a5, b5] = anchorIdx <= rowIndex ? [anchorIdx, rowIndex] : [rowIndex, anchorIdx];
165671
+ this.selectedIds.clear();
165672
+ for (let i11 = a5; i11 <= b5; i11++) this.selectedIds.add(this.getRowId(view[i11]));
165673
+ } else {
165674
+ this.selectedIds.clear();
165675
+ this.selectedIds.add(id);
165676
+ this.__selectionAnchorId = id;
165677
+ }
165678
+ this.selectedDataRow = item;
165679
+ } else if (isToggle) {
165680
+ const wasSelected = this.selectedIds.has(id);
165681
+ if (wasSelected) {
165682
+ this.selectedIds.delete(id);
165683
+ if (this.selectedDataRow === item) {
165684
+ const remaining = view.find((r11) => this.selectedIds.has(this.getRowId(r11)));
165685
+ this.selectedDataRow = remaining;
165686
+ }
165687
+ } else {
165688
+ this.selectedIds.add(id);
165689
+ this.selectedDataRow = item;
165690
+ }
165691
+ this.__selectionAnchorId = id;
165692
+ } else {
165693
+ this.selectedDataRow = item;
165694
+ this.selectedIds.clear();
165695
+ this.selectedIds.add(id);
165696
+ this.__selectionAnchorId = id;
165697
+ }
165698
+ this.emitSelectionChange();
165699
+ this.requestUpdate();
165700
+ }
165574
165701
  setRowSelected(row, checked) {
165575
165702
  const id = this.getRowId(row);
165576
165703
  if (this.selectionMode === "single") {
@@ -165687,6 +165814,7 @@ _sortBy = new WeakMap();
165687
165814
  _filterText = new WeakMap();
165688
165815
  _columnFilters = new WeakMap();
165689
165816
  _showColumnFilters = new WeakMap();
165817
+ _showSelectionCheckbox = new WeakMap();
165690
165818
  _fixedHeight = new WeakMap();
165691
165819
  _searchMode = new WeakMap();
165692
165820
  _selectionMode = new WeakMap();
@@ -165715,6 +165843,7 @@ __decorateElement(_init39, 4, "sortBy", _sortBy_dec, _DeesTable, _sortBy);
165715
165843
  __decorateElement(_init39, 4, "filterText", _filterText_dec, _DeesTable, _filterText);
165716
165844
  __decorateElement(_init39, 4, "columnFilters", _columnFilters_dec, _DeesTable, _columnFilters);
165717
165845
  __decorateElement(_init39, 4, "showColumnFilters", _showColumnFilters_dec, _DeesTable, _showColumnFilters);
165846
+ __decorateElement(_init39, 4, "showSelectionCheckbox", _showSelectionCheckbox_dec, _DeesTable, _showSelectionCheckbox);
165718
165847
  __decorateElement(_init39, 4, "fixedHeight", _fixedHeight_dec, _DeesTable, _fixedHeight);
165719
165848
  __decorateElement(_init39, 4, "searchMode", _searchMode_dec, _DeesTable, _searchMode);
165720
165849
  __decorateElement(_init39, 4, "selectionMode", _selectionMode_dec, _DeesTable, _selectionMode);
@@ -199565,7 +199694,7 @@ init_group_runtime();
199565
199694
  // ts_web/00_commitinfo_data.ts
199566
199695
  var commitinfo = {
199567
199696
  name: "@design.estate/dees-catalog",
199568
- version: "3.63.0",
199697
+ version: "3.64.0",
199569
199698
  description: "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."
199570
199699
  };
199571
199700
  export {
@@ -201538,4 +201667,4 @@ ibantools/jsnext/ibantools.js:
201538
201667
  * @preferred
201539
201668
  *)
201540
201669
  */
201541
- //# sourceMappingURL=bundle-1775570157836.js.map
201670
+ //# sourceMappingURL=bundle-1775572474370.js.map
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-catalog',
6
- version: '3.63.0',
6
+ version: '3.64.0',
7
7
  description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsNkJBQTZCO0lBQ25DLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSxzSkFBc0o7Q0FDcEssQ0FBQSJ9
@@ -56,6 +56,12 @@ export declare class DeesTable<T> extends DeesElement {
56
56
  accessor filterText: string;
57
57
  accessor columnFilters: Record<string, string>;
58
58
  accessor showColumnFilters: boolean;
59
+ /**
60
+ * When true, the table renders a leftmost checkbox column for click-driven
61
+ * (de)selection. Row selection by mouse (plain/shift/ctrl click) is always
62
+ * available regardless of this flag.
63
+ */
64
+ accessor showSelectionCheckbox: boolean;
59
65
  /**
60
66
  * When set, the table renders inside a fixed-height scroll container
61
67
  * (`max-height: var(--table-max-height, 360px)`) and the header sticks
@@ -73,7 +79,27 @@ export declare class DeesTable<T> extends DeesElement {
73
79
  accessor selectedIds: Set<string>;
74
80
  private _rowIdMap;
75
81
  private _rowIdCounter;
82
+ /**
83
+ * Anchor row id for shift+click range selection. Set whenever the user
84
+ * makes a non-range click (plain or cmd/ctrl) so the next shift+click
85
+ * can compute a contiguous range from this anchor.
86
+ */
87
+ private __selectionAnchorId?;
76
88
  constructor();
89
+ /**
90
+ * Ctrl/Cmd+C copies the currently selected rows as a JSON array. Falls
91
+ * back to copying the focused-row (`selectedDataRow`) if no multi
92
+ * selection exists. No-op if a focused input/textarea would normally
93
+ * receive the copy.
94
+ */
95
+ private __handleHostKeydown;
96
+ /**
97
+ * Copies the current selection as a JSON array. If `fallbackRow` is given
98
+ * and there is no multi-selection, that row is copied instead. Used both
99
+ * by the Ctrl/Cmd+C handler and by the default context-menu action.
100
+ */
101
+ copySelectionAsJson(fallbackRow?: T): void;
102
+ private __writeRowsAsJson;
77
103
  static styles: import("@design.estate/dees-element").CSSResult[];
78
104
  render(): TemplateResult;
79
105
  /**
@@ -182,6 +208,17 @@ export declare class DeesTable<T> extends DeesElement {
182
208
  private getRowId;
183
209
  private isRowSelected;
184
210
  private toggleRowSelected;
211
+ /**
212
+ * Handles row clicks with file-manager style selection semantics:
213
+ * - plain click: select only this row, set anchor
214
+ * - cmd/ctrl+click: toggle this row in/out, set anchor
215
+ * - shift+click: select the contiguous range from the anchor to this row
216
+ *
217
+ * Multi-row click selection is always available (`selectionMode === 'none'`
218
+ * and `'multi'` both behave this way) so consumers can always copy a set
219
+ * of rows. Only `selectionMode === 'single'` restricts to one row.
220
+ */
221
+ private handleRowClick;
185
222
  private setRowSelected;
186
223
  private areAllVisibleSelected;
187
224
  private isVisibleSelectionIndeterminate;