@syncfusion/ej2-navigations 34.2.2 → 34.2.3

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.
Files changed (79) hide show
  1. package/dist/ej2-navigations.min.js +2 -2
  2. package/dist/ej2-navigations.umd.min.js +2 -2
  3. package/dist/ej2-navigations.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-navigations.es2015.js +121 -32
  5. package/dist/es6/ej2-navigations.es2015.js.map +1 -1
  6. package/dist/es6/ej2-navigations.es5.js +121 -32
  7. package/dist/es6/ej2-navigations.es5.js.map +1 -1
  8. package/dist/global/ej2-navigations.min.js +2 -2
  9. package/dist/global/ej2-navigations.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +2 -2
  12. package/src/common/menu-base.js +14 -6
  13. package/src/treeview/treeview-model.d.ts +1 -0
  14. package/src/treeview/treeview.d.ts +14 -1
  15. package/src/treeview/treeview.js +107 -26
  16. package/styles/bds-lite.css +3 -0
  17. package/styles/bds.css +3 -0
  18. package/styles/bootstrap-dark-lite.css +3 -0
  19. package/styles/bootstrap-dark.css +3 -0
  20. package/styles/bootstrap-lite.css +3 -0
  21. package/styles/bootstrap.css +3 -0
  22. package/styles/bootstrap4-lite.css +3 -0
  23. package/styles/bootstrap4.css +3 -0
  24. package/styles/bootstrap5-dark-lite.css +3 -0
  25. package/styles/bootstrap5-dark.css +3 -0
  26. package/styles/bootstrap5-lite.css +3 -0
  27. package/styles/bootstrap5.3-lite.css +3 -0
  28. package/styles/bootstrap5.3.css +3 -0
  29. package/styles/bootstrap5.css +3 -0
  30. package/styles/fabric-dark-lite.css +3 -0
  31. package/styles/fabric-dark.css +3 -0
  32. package/styles/fabric-lite.css +3 -0
  33. package/styles/fabric.css +3 -0
  34. package/styles/fluent-dark-lite.css +3 -0
  35. package/styles/fluent-dark.css +3 -0
  36. package/styles/fluent-lite.css +3 -0
  37. package/styles/fluent.css +3 -0
  38. package/styles/fluent2-lite.css +3 -0
  39. package/styles/fluent2.css +3 -0
  40. package/styles/highcontrast-light-lite.css +3 -0
  41. package/styles/highcontrast-light.css +3 -0
  42. package/styles/highcontrast-lite.css +3 -0
  43. package/styles/highcontrast.css +3 -0
  44. package/styles/material-dark-lite.css +3 -0
  45. package/styles/material-dark.css +3 -0
  46. package/styles/material-lite.css +3 -0
  47. package/styles/material.css +3 -0
  48. package/styles/material3-dark-lite.css +3 -0
  49. package/styles/material3-dark.css +3 -0
  50. package/styles/material3-lite.css +3 -0
  51. package/styles/material3.css +3 -0
  52. package/styles/tailwind-dark-lite.css +3 -0
  53. package/styles/tailwind-dark.css +3 -0
  54. package/styles/tailwind-lite.css +3 -0
  55. package/styles/tailwind.css +3 -0
  56. package/styles/tailwind3-lite.css +3 -0
  57. package/styles/tailwind3.css +3 -0
  58. package/styles/toolbar/_layout.scss +4 -0
  59. package/styles/toolbar/bds.css +3 -0
  60. package/styles/toolbar/bootstrap-dark.css +3 -0
  61. package/styles/toolbar/bootstrap.css +3 -0
  62. package/styles/toolbar/bootstrap4.css +3 -0
  63. package/styles/toolbar/bootstrap5-dark.css +3 -0
  64. package/styles/toolbar/bootstrap5.3.css +3 -0
  65. package/styles/toolbar/bootstrap5.css +3 -0
  66. package/styles/toolbar/fabric-dark.css +3 -0
  67. package/styles/toolbar/fabric.css +3 -0
  68. package/styles/toolbar/fluent-dark.css +3 -0
  69. package/styles/toolbar/fluent.css +3 -0
  70. package/styles/toolbar/fluent2.css +3 -0
  71. package/styles/toolbar/highcontrast-light.css +3 -0
  72. package/styles/toolbar/highcontrast.css +3 -0
  73. package/styles/toolbar/material-dark.css +3 -0
  74. package/styles/toolbar/material.css +3 -0
  75. package/styles/toolbar/material3-dark.css +3 -0
  76. package/styles/toolbar/material3.css +3 -0
  77. package/styles/toolbar/tailwind-dark.css +3 -0
  78. package/styles/toolbar/tailwind.css +3 -0
  79. package/styles/toolbar/tailwind3.css +3 -0
@@ -1430,8 +1430,10 @@ let MenuBase = class MenuBase extends Component {
1430
1430
  if (!active) {
1431
1431
  return;
1432
1432
  }
1433
+ const isInputElement = active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' ||
1434
+ active.contentEditable === 'true';
1433
1435
  const expanded = active.getAttribute('aria-expanded') === 'true';
1434
- if (!expanded) {
1436
+ if (!expanded || isInputElement) {
1435
1437
  return;
1436
1438
  }
1437
1439
  const ul = this.element;
@@ -1545,13 +1547,19 @@ let MenuBase = class MenuBase extends Component {
1545
1547
  const cli = cul.children[fliIdx];
1546
1548
  fliIdx = this.isValidLI(cli, fliIdx, e.action);
1547
1549
  cul.children[fliIdx].classList.add(FOCUSED);
1548
- cul.children[fliIdx].focus();
1550
+ const liToFocus = cul.children[fliIdx];
1549
1551
  if (closest(this.element, '.e-popup')) {
1550
- const focusedLiItem = cul.children[fliIdx];
1551
- const focusableChild = focusedLiItem.querySelector('[tabindex], span[tabindex], a, button, [tabindex]:not([tabindex="-1"])');
1552
- if (!focusableChild) {
1553
- cul.focus();
1552
+ const focusableChild = liToFocus.querySelector('[tabindex], span[tabindex], a, button, [tabindex]:not([tabindex="-1"])');
1553
+ const isSpreadsheet = this.element.id.includes('_cf_menu') && this.element.parentElement.classList.contains('e-cf-menu');
1554
+ if (focusableChild && !isSpreadsheet) {
1555
+ focusableChild.focus();
1554
1556
  }
1557
+ else {
1558
+ liToFocus.focus();
1559
+ }
1560
+ }
1561
+ else {
1562
+ liToFocus.focus();
1555
1563
  }
1556
1564
  }
1557
1565
  isValidLI(cli, index, action) {
@@ -12152,7 +12160,9 @@ let TreeView = TreeView_1 = class TreeView extends Component {
12152
12160
  this.virtualIndeterminateNodesSet.delete(id);
12153
12161
  this.virtualCheckedNodesSet.delete(id);
12154
12162
  this.virtualFlatNodes[parseInt(actualIndex.toString(), 10)].isChecked = false;
12155
- this.treeData[parseInt(id.toString(), 10) - 1].isChecked = false;
12163
+ if (this.treeData && this.fields && this.fields.isChecked) {
12164
+ setValue(this.fields.isChecked, false, this.treeData[parseInt(id.toString(), 10) - 1]);
12165
+ }
12156
12166
  if (this.autoCheck && this.virtualFlatNodes[parseInt(actualIndex.toString(), 10)].hasChildren) {
12157
12167
  this.setVirtualChildCheckState(id, false);
12158
12168
  }
@@ -13085,6 +13095,13 @@ let TreeView = TreeView_1 = class TreeView extends Component {
13085
13095
  if (!isNullOrUndefined(id) && this.selectedNodes.indexOf(id) === -1) {
13086
13096
  this.selectedNodes.push(id);
13087
13097
  }
13098
+ if (this.enableVirtualization && !isNullOrUndefined(this.height)) {
13099
+ this.virtualSelectedNodesSet.add(id);
13100
+ const actualIndex = this.virtualNodeMap.get(id);
13101
+ if (actualIndex && actualIndex > -1) {
13102
+ this.virtualFlatNodes[parseInt(actualIndex.toString(), 10)].selected = true;
13103
+ }
13104
+ }
13088
13105
  }
13089
13106
  removeSelect(liEle) {
13090
13107
  if (this.allowMultiSelection) {
@@ -13098,6 +13115,14 @@ let TreeView = TreeView_1 = class TreeView extends Component {
13098
13115
  if (index > -1) {
13099
13116
  this.selectedNodes.splice(index, 1);
13100
13117
  }
13118
+ if (this.enableVirtualization && !isNullOrUndefined(this.height)) {
13119
+ const id = liEle.getAttribute('data-uid');
13120
+ this.virtualSelectedNodesSet.delete(id);
13121
+ const actualIndex = this.virtualNodeMap.get(id);
13122
+ if (actualIndex && actualIndex > -1) {
13123
+ this.virtualFlatNodes[parseInt(actualIndex.toString(), 10)].selected = false;
13124
+ }
13125
+ }
13101
13126
  }
13102
13127
  removeSelectAll() {
13103
13128
  const selectedLI = this.element.querySelectorAll('.' + ACTIVE);
@@ -13111,6 +13136,15 @@ let TreeView = TreeView_1 = class TreeView extends Component {
13111
13136
  }
13112
13137
  removeClass(selectedLI, ACTIVE);
13113
13138
  this.setProperties({ selectedNodes: [] }, true);
13139
+ if (this.enableVirtualization && !isNullOrUndefined(this.height)) {
13140
+ this.virtualSelectedNodesSet.clear();
13141
+ for (let i = 0; i < this.virtualFlatNodes.length; i++) {
13142
+ const node = this.virtualFlatNodes[parseInt(i.toString(), 10)];
13143
+ if (node.selected) {
13144
+ node.selected = false;
13145
+ }
13146
+ }
13147
+ }
13114
13148
  }
13115
13149
  getSelectEvent(currLi, action, e) {
13116
13150
  const nodeData = this.getNodeData(currLi);
@@ -16070,6 +16104,7 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16070
16104
  const imageUrlFieldName = this.fields.imageUrl;
16071
16105
  const idFieldName = this.fields.id;
16072
16106
  const textFieldName = this.fields.text;
16107
+ const selectedFieldName = this.fields.selected;
16073
16108
  const needsSorting = this.sortOrder !== 'None';
16074
16109
  const isDataTypeFlat = this.dataType === 1;
16075
16110
  const enableVirtualization = this.enableVirtualization;
@@ -16080,7 +16115,7 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16080
16115
  // Use expandedNodes as the single source of truth.
16081
16116
  const inExpandedNodes = this.virtualExpandedNodesSet.has(id);
16082
16117
  const rawExpanded = !inExpandedNodes && getValue(expandedFieldName, raw) === true;
16083
- const isExpanded = inExpandedNodes || rawExpanded;
16118
+ const expanded = inExpandedNodes || rawExpanded;
16084
16119
  if (rawExpanded && id) {
16085
16120
  this.expandedNodes.push(id);
16086
16121
  this.virtualExpandedNodesSet.add(id);
@@ -16107,24 +16142,32 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16107
16142
  }
16108
16143
  }
16109
16144
  }
16145
+ if (this.initialRender && enableVirtualization && id && selectedFieldName && !this.virtualSelectedNodesSet.has(id)) {
16146
+ const rawSelected = getValue(selectedFieldName, raw);
16147
+ if (!isNullOrUndefined(rawSelected) && rawSelected.toString() === 'true') {
16148
+ this.virtualSelectedNodesSet.add(id);
16149
+ if (this.selectedNodes && this.selectedNodes.indexOf(id) === -1) {
16150
+ this.selectedNodes.push(id);
16151
+ }
16152
+ }
16153
+ }
16110
16154
  // Use cached Sets for O(1) lookup
16111
- const isSelected = this.virtualSelectedNodesSet.has(id);
16155
+ const selected = this.virtualSelectedNodesSet.has(id);
16112
16156
  // Resolve checkbox state: indeterminate takes precedence over the checked set,
16113
16157
  // because a node can be in the indeterminate state without being in checkedNodes.
16114
16158
  const isChecked = (enableVirtualization && this.virtualIndeterminateNodesSet.has(id))
16115
16159
  ? 'indeterminate'
16116
16160
  : this.virtualCheckedNodesSet.has(id);
16117
- const isDisabled = false; // TODO: Check if any per-node disabled field exists
16118
16161
  const iconCssVal = raw[iconCssFieldName];
16119
16162
  const iconCss = isNullOrUndefined(iconCssVal) ? '' : iconCssVal.toString();
16120
16163
  const imageUrlVal = raw[imageUrlFieldName];
16121
16164
  const imageUrl = isNullOrUndefined(imageUrlVal) ? '' : imageUrlVal.toString();
16122
16165
  const node = {
16123
- id, text, level, parentId, hasChildren, isExpanded,
16124
- isSelected, isChecked, isDisabled, iconCss, imageUrl, rawData: raw
16166
+ id, text, level, parentId, hasChildren, expanded,
16167
+ selected, isChecked, iconCss, imageUrl
16125
16168
  };
16126
16169
  result.push(node);
16127
- if (isExpanded && hasChildren) {
16170
+ if (expanded && hasChildren) {
16128
16171
  // Determine children list
16129
16172
  let children = [];
16130
16173
  if (isDataTypeFlat) {
@@ -16334,7 +16377,7 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16334
16377
  targetUl.appendChild(li);
16335
16378
  liListBuf.push(li);
16336
16379
  // Register this node so its children in the same window can nest under it
16337
- if (node.isExpanded && node.hasChildren) {
16380
+ if (node.expanded && node.hasChildren) {
16338
16381
  renderedParentMap.set(node.id, { li, childUl: null });
16339
16382
  }
16340
16383
  }
@@ -16429,7 +16472,7 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16429
16472
  // Expand/collapse icon
16430
16473
  if (node.hasChildren) {
16431
16474
  const iconSpan = this.createElement('div', {
16432
- className: ICON + ' ' + (node.isExpanded ? COLLAPSIBLE : EXPANDABLE)
16475
+ className: ICON + ' ' + (node.expanded ? COLLAPSIBLE : EXPANDABLE)
16433
16476
  });
16434
16477
  textWrap.appendChild(iconSpan);
16435
16478
  }
@@ -16468,8 +16511,16 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16468
16511
  });
16469
16512
  textWrap.appendChild(anchor);
16470
16513
  li.appendChild(textWrap);
16514
+ // nodeTemplate
16515
+ if (!isNullOrUndefined(this.nodeTemplateFn)) {
16516
+ const rawData = this.findNodeInTreeData(node.id);
16517
+ if (!isNullOrUndefined(rawData)) {
16518
+ anchor.innerHTML = '';
16519
+ this.renderNodeTemplate(rawData, anchor, node.id);
16520
+ }
16521
+ }
16471
16522
  // State classes
16472
- if (node.isExpanded) {
16523
+ if (node.expanded) {
16473
16524
  li.classList.add(EXPANDED);
16474
16525
  li.setAttribute('aria-expanded', 'true');
16475
16526
  }
@@ -16477,14 +16528,10 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16477
16528
  li.classList.add(NODECOLLAPSED);
16478
16529
  li.setAttribute('aria-expanded', 'false');
16479
16530
  }
16480
- if (node.isSelected) {
16531
+ if (node.selected) {
16481
16532
  li.classList.add(ACTIVE);
16482
16533
  li.setAttribute('aria-selected', 'true');
16483
16534
  }
16484
- if (node.isDisabled) {
16485
- li.classList.add(DISABLED$1);
16486
- li.setAttribute('aria-disabled', 'true');
16487
- }
16488
16535
  if (node.hasChildren) {
16489
16536
  li.classList.add(CHILD);
16490
16537
  }
@@ -16786,6 +16833,44 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16786
16833
  this.virtualEndIndex = win.endIndex;
16787
16834
  this.renderVirtualItems();
16788
16835
  }
16836
+ /**
16837
+ * Recursively walks the treeData (and any nested `childFieldName` arrays) to
16838
+ * find the node whose `idFieldName` matches the given `id` (compared as
16839
+ * strings). Used by the virtual-mode expand/collapse handlers so they can
16840
+ * locate nodes at any depth — not just the root level — before writing the
16841
+ * `expanded` flag back to the datasource.
16842
+ *
16843
+ * @param {string} id - The id (as a string) of the node to locate.
16844
+ * @returns {Object | null} The matching raw datasource node, or null if not found.
16845
+ * @private
16846
+ */
16847
+ findNodeInTreeData(id) {
16848
+ if (!this.treeData) {
16849
+ return null;
16850
+ }
16851
+ const idFieldName = this.fields.id.toString();
16852
+ const childFieldName = this.fields.child.toString();
16853
+ const findRecursive = (nodes) => {
16854
+ if (!nodes || nodes.length === 0) {
16855
+ return null;
16856
+ }
16857
+ for (let i = 0; i < nodes.length; i++) {
16858
+ const node = nodes[i];
16859
+ if (node[idFieldName] && node[idFieldName].toString() === id) {
16860
+ return node;
16861
+ }
16862
+ const children = getValue(childFieldName, node);
16863
+ if (children && Array.isArray(children)) {
16864
+ const found = findRecursive(children);
16865
+ if (found) {
16866
+ return found;
16867
+ }
16868
+ }
16869
+ }
16870
+ return null;
16871
+ };
16872
+ return findRecursive(this.treeData);
16873
+ }
16789
16874
  handleVirtualExpand(id, isKeyboardNav) {
16790
16875
  // ── Cancel any pending scroll RAF ─────────────────────────────────────────
16791
16876
  // A scroll RAF queued before the expand click would run asynchronously after
@@ -16803,9 +16888,11 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16803
16888
  if (this.virtualExpandedNodesSet) {
16804
16889
  this.virtualExpandedNodesSet.add(id);
16805
16890
  }
16806
- if (this.rootData) {
16807
- const acutalRootData = this.rootData.find((item) => item.id === parseInt(id, 10));
16808
- acutalRootData.isExpanded = true;
16891
+ if (this.treeData) {
16892
+ const acutalRootData = this.findNodeInTreeData(id);
16893
+ if (acutalRootData && this.fields && this.fields.expanded) {
16894
+ setValue(this.fields.expanded, true, acutalRootData);
16895
+ }
16809
16896
  }
16810
16897
  // ── Fix: Pin focused ID to the expanding node for keyboard navigation ──
16811
16898
  // When keyboard-triggered, the expanded node IS definitively the focused node
@@ -16884,9 +16971,11 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16884
16971
  if (this.virtualExpandedNodesSet) {
16885
16972
  this.virtualExpandedNodesSet.delete(id);
16886
16973
  }
16887
- if (this.rootData) {
16888
- const acutalRootData = this.rootData.find((item) => item.id === parseInt(id, 10));
16889
- acutalRootData.isExpanded = false;
16974
+ if (this.treeData) {
16975
+ const acutalRootData = this.findNodeInTreeData(id);
16976
+ if (acutalRootData && this.fields && this.fields.expanded) {
16977
+ setValue(this.fields.expanded, false, acutalRootData);
16978
+ }
16890
16979
  }
16891
16980
  // ── Fix: Pin focused ID to the collapsing node for keyboard navigation ──
16892
16981
  // Same reasoning as handleVirtualExpand: when keyboard-triggered, `id` is
@@ -16940,14 +17029,14 @@ let TreeView = TreeView_1 = class TreeView extends Component {
16940
17029
  * Updates the selected state of a node in `virtualFlatNodes` and re-renders the window.
16941
17030
  *
16942
17031
  * @param {string} id - The `data-uid` of the target node.
16943
- * @param {boolean} isSelected - Whether the node is now selected.
17032
+ * @param {boolean} selected - Whether the node is now selected.
16944
17033
  * @returns {void}
16945
17034
  * @private
16946
17035
  */
16947
- updateVirtualNodeSelection(id, isSelected) {
17036
+ updateVirtualNodeSelection(id, selected) {
16948
17037
  const idx = this.virtualNodeMap.get(id);
16949
17038
  if (!isNullOrUndefined(idx)) {
16950
- this.virtualFlatNodes[parseInt(idx.toString(), 10)].isSelected = isSelected;
17039
+ this.virtualFlatNodes[parseInt(idx.toString(), 10)].selected = selected;
16951
17040
  this.renderVirtualItems();
16952
17041
  }
16953
17042
  }
@@ -17313,7 +17402,7 @@ let TreeView = TreeView_1 = class TreeView extends Component {
17313
17402
  }
17314
17403
  for (let i = 0; i < nodes.length; i++) {
17315
17404
  const node = nodes[parseInt(i.toString(), 10)];
17316
- node['isExpanded'] = false;
17405
+ node['expanded'] = false;
17317
17406
  const children = getValue(this.fields.child.toString(), node);
17318
17407
  if (children && Array.isArray(children)) {
17319
17408
  setAllCollapsed(children);
@@ -17413,7 +17502,7 @@ let TreeView = TreeView_1 = class TreeView extends Component {
17413
17502
  const nodeId = getValue(idFieldName, node);
17414
17503
  if (node.hasChild) {
17415
17504
  allParentIds.push(nodeId);
17416
- node.isExpanded = true;
17505
+ node.expanded = true;
17417
17506
  }
17418
17507
  }
17419
17508
  };