@mui/x-tree-view 7.0.0-beta.7 → 7.1.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.
Files changed (136) hide show
  1. package/CHANGELOG.md +266 -12
  2. package/README.md +1 -1
  3. package/RichTreeView/RichTreeView.js +15 -17
  4. package/RichTreeView/RichTreeView.types.d.ts +1 -1
  5. package/SimpleTreeView/SimpleTreeView.js +3 -4
  6. package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
  7. package/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
  8. package/TreeItem/TreeItem.js +43 -35
  9. package/TreeItem/TreeItem.types.d.ts +3 -3
  10. package/TreeItem/TreeItemContent.d.ts +7 -7
  11. package/TreeItem/TreeItemContent.js +10 -10
  12. package/TreeItem/treeItemClasses.d.ts +1 -1
  13. package/TreeItem/useTreeItemState.d.ts +1 -1
  14. package/TreeItem/useTreeItemState.js +13 -13
  15. package/TreeItem2/TreeItem2.js +16 -17
  16. package/TreeItem2Icon/TreeItem2Icon.js +5 -6
  17. package/TreeItem2Icon/TreeItem2Icon.types.d.ts +4 -4
  18. package/TreeItem2Provider/TreeItem2Provider.js +3 -3
  19. package/TreeItem2Provider/TreeItem2Provider.types.d.ts +1 -1
  20. package/TreeView/TreeView.d.ts +1 -1
  21. package/TreeView/TreeView.js +1 -1
  22. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +2 -2
  23. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
  24. package/hooks/useTreeViewApiRef.d.ts +1 -1
  25. package/index.js +1 -1
  26. package/internals/TreeViewProvider/DescendantProvider.d.ts +1 -1
  27. package/internals/TreeViewProvider/DescendantProvider.js +1 -1
  28. package/internals/hooks/useInstanceEventHandler.js +5 -10
  29. package/internals/index.d.ts +2 -2
  30. package/internals/models/plugin.d.ts +1 -1
  31. package/internals/plugins/defaultPlugins.d.ts +3 -3
  32. package/internals/plugins/defaultPlugins.js +2 -2
  33. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +17 -24
  34. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -6
  35. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +76 -58
  36. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +9 -8
  37. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +6 -6
  38. package/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  39. package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +2 -2
  40. package/internals/plugins/useTreeViewItems/index.d.ts +2 -0
  41. package/internals/plugins/useTreeViewItems/index.js +1 -0
  42. package/internals/plugins/useTreeViewItems/useTreeViewItems.d.ts +3 -0
  43. package/{modern/internals/plugins/useTreeViewNodes/useTreeViewNodes.js → internals/plugins/useTreeViewItems/useTreeViewItems.js} +42 -33
  44. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +99 -0
  45. package/internals/plugins/useTreeViewJSXItems/index.d.ts +2 -0
  46. package/internals/plugins/useTreeViewJSXItems/index.js +1 -0
  47. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.d.ts +3 -0
  48. package/{modern/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +41 -40
  49. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +18 -0
  50. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +85 -96
  51. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +6 -3
  52. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +44 -47
  53. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +8 -8
  54. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +7 -7
  55. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
  56. package/internals/useTreeView/useTreeView.js +5 -6
  57. package/internals/useTreeView/useTreeView.utils.d.ts +5 -5
  58. package/internals/useTreeView/useTreeView.utils.js +18 -18
  59. package/internals/utils/extractPluginParamsFromProps.js +2 -2
  60. package/internals/utils/utils.js +1 -0
  61. package/modern/RichTreeView/RichTreeView.js +11 -11
  62. package/modern/SimpleTreeView/SimpleTreeView.js +1 -1
  63. package/modern/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
  64. package/modern/TreeItem/TreeItem.js +31 -22
  65. package/modern/TreeItem/TreeItemContent.js +10 -10
  66. package/modern/TreeItem/useTreeItemState.js +13 -13
  67. package/modern/TreeItem2/TreeItem2.js +11 -11
  68. package/modern/TreeItem2Provider/TreeItem2Provider.js +3 -3
  69. package/modern/TreeView/TreeView.js +1 -1
  70. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
  71. package/modern/index.js +1 -1
  72. package/modern/internals/TreeViewProvider/DescendantProvider.js +1 -1
  73. package/modern/internals/plugins/defaultPlugins.js +2 -2
  74. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +14 -14
  75. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +74 -53
  76. package/modern/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  77. package/modern/internals/plugins/useTreeViewItems/index.js +1 -0
  78. package/{internals/plugins/useTreeViewNodes/useTreeViewNodes.js → modern/internals/plugins/useTreeViewItems/useTreeViewItems.js} +46 -41
  79. package/modern/internals/plugins/useTreeViewJSXItems/index.js +1 -0
  80. package/{internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +41 -41
  81. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +85 -94
  82. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +40 -40
  83. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
  84. package/modern/internals/useTreeView/useTreeView.js +3 -4
  85. package/modern/internals/useTreeView/useTreeView.utils.js +18 -18
  86. package/modern/internals/utils/utils.js +1 -0
  87. package/modern/useTreeItem2/useTreeItem2.js +23 -12
  88. package/node/RichTreeView/RichTreeView.js +11 -11
  89. package/node/SimpleTreeView/SimpleTreeView.js +1 -1
  90. package/node/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
  91. package/node/TreeItem/TreeItem.js +31 -22
  92. package/node/TreeItem/TreeItemContent.js +10 -10
  93. package/node/TreeItem/useTreeItemState.js +13 -13
  94. package/node/TreeItem2/TreeItem2.js +11 -11
  95. package/node/TreeItem2Provider/TreeItem2Provider.js +3 -3
  96. package/node/TreeView/TreeView.js +1 -1
  97. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
  98. package/node/index.js +1 -1
  99. package/node/internals/TreeViewProvider/DescendantProvider.js +1 -1
  100. package/node/internals/plugins/defaultPlugins.js +2 -2
  101. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +14 -14
  102. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +74 -53
  103. package/node/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  104. package/node/internals/plugins/useTreeViewItems/index.js +12 -0
  105. package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +44 -35
  106. package/node/internals/plugins/useTreeViewJSXItems/index.js +12 -0
  107. package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.js → useTreeViewJSXItems/useTreeViewJSXItems.js} +43 -42
  108. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +84 -93
  109. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +39 -39
  110. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
  111. package/node/internals/useTreeView/useTreeView.js +3 -4
  112. package/node/internals/useTreeView/useTreeView.utils.js +23 -23
  113. package/node/internals/utils/utils.js +1 -0
  114. package/node/useTreeItem2/useTreeItem2.js +23 -12
  115. package/package.json +5 -5
  116. package/useTreeItem2/useTreeItem2.d.ts +1 -1
  117. package/useTreeItem2/useTreeItem2.js +26 -18
  118. package/useTreeItem2/useTreeItem2.types.d.ts +9 -7
  119. package/internals/plugins/useTreeViewJSXNodes/index.d.ts +0 -2
  120. package/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
  121. package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.d.ts +0 -3
  122. package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.d.ts +0 -18
  123. package/internals/plugins/useTreeViewNodes/index.d.ts +0 -2
  124. package/internals/plugins/useTreeViewNodes/index.js +0 -1
  125. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.d.ts +0 -3
  126. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.d.ts +0 -88
  127. package/modern/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
  128. package/modern/internals/plugins/useTreeViewNodes/index.js +0 -1
  129. package/node/internals/plugins/useTreeViewJSXNodes/index.js +0 -12
  130. package/node/internals/plugins/useTreeViewNodes/index.js +0 -12
  131. /package/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
  132. /package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
  133. /package/modern/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
  134. /package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
  135. /package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
  136. /package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
@@ -30,47 +30,39 @@ const useTreeViewKeyboardNavigation = ({
30
30
  const theme = (0, _styles.useTheme)();
31
31
  const isRTL = theme.direction === 'rtl';
32
32
  const firstCharMap = React.useRef({});
33
- const hasFirstCharMapBeenUpdatedImperatively = React.useRef(false);
34
33
  const updateFirstCharMap = (0, _useEventCallback.default)(callback => {
35
- hasFirstCharMapBeenUpdatedImperatively.current = true;
36
34
  firstCharMap.current = callback(firstCharMap.current);
37
35
  });
38
36
  React.useEffect(() => {
39
- if (hasFirstCharMapBeenUpdatedImperatively.current) {
37
+ if (instance.areItemUpdatesPrevented()) {
40
38
  return;
41
39
  }
42
40
  const newFirstCharMap = {};
43
- const processItem = item => {
44
- const getItemId = params.getItemId;
45
- const nodeId = getItemId ? getItemId(item) : item.id;
46
- newFirstCharMap[nodeId] = instance.getNode(nodeId).label.substring(0, 1).toLowerCase();
47
- item.children?.forEach(processItem);
41
+ const processItem = node => {
42
+ newFirstCharMap[node.id] = node.label.substring(0, 1).toLowerCase();
48
43
  };
49
- params.items.forEach(processItem);
44
+ Object.values(state.items.nodeMap).forEach(processItem);
50
45
  firstCharMap.current = newFirstCharMap;
51
- }, [params.items, params.getItemId, instance]);
52
- (0, _useTreeView.populateInstance)(instance, {
53
- updateFirstCharMap
54
- });
55
- const getFirstMatchingNode = (nodeId, firstChar) => {
46
+ }, [state.items.nodeMap, params.getItemId, instance]);
47
+ const getFirstMatchingItem = (itemId, firstChar) => {
56
48
  let start;
57
49
  let index;
58
50
  const lowercaseChar = firstChar.toLowerCase();
59
51
  const firstCharIds = [];
60
52
  const firstChars = [];
61
53
  // This really only works since the ids are strings
62
- Object.keys(firstCharMap.current).forEach(mapNodeId => {
63
- const map = instance.getNode(mapNodeId);
64
- const visible = map.parentId ? instance.isNodeExpanded(map.parentId) : true;
65
- const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isNodeDisabled(mapNodeId);
54
+ Object.keys(firstCharMap.current).forEach(mapItemId => {
55
+ const map = instance.getNode(mapItemId);
56
+ const visible = map.parentId ? instance.isItemExpanded(map.parentId) : true;
57
+ const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isItemDisabled(mapItemId);
66
58
  if (visible && !shouldBeSkipped) {
67
- firstCharIds.push(mapNodeId);
68
- firstChars.push(firstCharMap.current[mapNodeId]);
59
+ firstCharIds.push(mapItemId);
60
+ firstChars.push(firstCharMap.current[mapItemId]);
69
61
  }
70
62
  });
71
63
 
72
64
  // Get start index for search based on position of currentItem
73
- start = firstCharIds.indexOf(nodeId) + 1;
65
+ start = firstCharIds.indexOf(itemId) + 1;
74
66
  if (start >= firstCharIds.length) {
75
67
  start = 0;
76
68
  }
@@ -89,20 +81,17 @@ const useTreeViewKeyboardNavigation = ({
89
81
  }
90
82
  return null;
91
83
  };
92
- const canToggleNodeSelection = nodeId => !params.disableSelection && !instance.isNodeDisabled(nodeId);
93
- const canToggleNodeExpansion = nodeId => {
94
- return !instance.isNodeDisabled(nodeId) && instance.isNodeExpandable(nodeId);
84
+ const canToggleItemSelection = itemId => !params.disableSelection && !instance.isItemDisabled(itemId);
85
+ const canToggleItemExpansion = itemId => {
86
+ return !instance.isItemDisabled(itemId) && instance.isItemExpandable(itemId);
95
87
  };
96
88
 
97
89
  // ARIA specification: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction
98
- const createHandleKeyDown = otherHandlers => event => {
99
- otherHandlers.onKeyDown?.(event);
90
+ const handleItemKeyDown = (event, itemId) => {
100
91
  if (event.defaultMuiPrevented) {
101
92
  return;
102
93
  }
103
-
104
- // If the tree is empty, there will be no focused node
105
- if (event.altKey || event.currentTarget !== event.target || state.focusedNodeId == null) {
94
+ if (event.altKey || event.currentTarget !== event.target) {
106
95
  return;
107
96
  }
108
97
  const ctrlPressed = event.ctrlKey || event.metaKey;
@@ -110,104 +99,107 @@ const useTreeViewKeyboardNavigation = ({
110
99
 
111
100
  // eslint-disable-next-line default-case
112
101
  switch (true) {
113
- // Select the node when pressing "Space"
114
- case key === ' ' && canToggleNodeSelection(state.focusedNodeId):
102
+ // Select the item when pressing "Space"
103
+ case key === ' ' && canToggleItemSelection(itemId):
115
104
  {
116
105
  event.preventDefault();
117
106
  if (params.multiSelect && event.shiftKey) {
118
107
  instance.selectRange(event, {
119
- end: state.focusedNodeId
108
+ end: itemId
120
109
  });
121
110
  } else if (params.multiSelect) {
122
- instance.selectNode(event, state.focusedNodeId, true);
111
+ instance.selectItem(event, itemId, true);
123
112
  } else {
124
- instance.selectNode(event, state.focusedNodeId);
113
+ instance.selectItem(event, itemId);
125
114
  }
126
115
  break;
127
116
  }
128
117
 
129
- // If the focused node has children, we expand it.
130
- // If the focused node has no children, we select it.
118
+ // If the focused item has children, we expand it.
119
+ // If the focused item has no children, we select it.
131
120
  case key === 'Enter':
132
121
  {
133
- if (canToggleNodeExpansion(state.focusedNodeId)) {
134
- instance.toggleNodeExpansion(event, state.focusedNodeId);
122
+ if (canToggleItemExpansion(itemId)) {
123
+ instance.toggleItemExpansion(event, itemId);
135
124
  event.preventDefault();
136
- } else if (canToggleNodeSelection(state.focusedNodeId)) {
125
+ } else if (canToggleItemSelection(itemId)) {
137
126
  if (params.multiSelect) {
138
127
  event.preventDefault();
139
- instance.selectNode(event, state.focusedNodeId, true);
140
- } else if (!instance.isNodeSelected(state.focusedNodeId)) {
141
- instance.selectNode(event, state.focusedNodeId);
128
+ instance.selectItem(event, itemId, true);
129
+ } else if (!instance.isItemSelected(itemId)) {
130
+ instance.selectItem(event, itemId);
142
131
  event.preventDefault();
143
132
  }
144
133
  }
145
134
  break;
146
135
  }
147
136
 
148
- // Focus the next focusable node
137
+ // Focus the next focusable item
149
138
  case key === 'ArrowDown':
150
139
  {
151
- const nextNode = (0, _useTreeView.getNextNode)(instance, state.focusedNodeId);
152
- if (nextNode) {
140
+ const nextItem = (0, _useTreeView.getNextItem)(instance, itemId);
141
+ if (nextItem) {
153
142
  event.preventDefault();
154
- instance.focusItem(event, nextNode);
143
+ instance.focusItem(event, nextItem);
155
144
 
156
145
  // Multi select behavior when pressing Shift + ArrowDown
157
- // Toggles the selection state of the next node
158
- if (params.multiSelect && event.shiftKey && canToggleNodeSelection(nextNode)) {
146
+ // Toggles the selection state of the next item
147
+ if (params.multiSelect && event.shiftKey && canToggleItemSelection(nextItem)) {
159
148
  instance.selectRange(event, {
160
- end: nextNode,
161
- current: state.focusedNodeId
149
+ end: nextItem,
150
+ current: itemId
162
151
  }, true);
163
152
  }
164
153
  }
165
154
  break;
166
155
  }
167
156
 
168
- // Focuses the previous focusable node
157
+ // Focuses the previous focusable item
169
158
  case key === 'ArrowUp':
170
159
  {
171
- const previousNode = (0, _useTreeView.getPreviousNode)(instance, state.focusedNodeId);
172
- if (previousNode) {
160
+ const previousItem = (0, _useTreeView.getPreviousItem)(instance, itemId);
161
+ if (previousItem) {
173
162
  event.preventDefault();
174
- instance.focusItem(event, previousNode);
163
+ instance.focusItem(event, previousItem);
175
164
 
176
165
  // Multi select behavior when pressing Shift + ArrowUp
177
- // Toggles the selection state of the previous node
178
- if (params.multiSelect && event.shiftKey && canToggleNodeSelection(previousNode)) {
166
+ // Toggles the selection state of the previous item
167
+ if (params.multiSelect && event.shiftKey && canToggleItemSelection(previousItem)) {
179
168
  instance.selectRange(event, {
180
- end: previousNode,
181
- current: state.focusedNodeId
169
+ end: previousItem,
170
+ current: itemId
182
171
  }, true);
183
172
  }
184
173
  }
185
174
  break;
186
175
  }
187
176
 
188
- // If the focused node is expanded, we move the focus to its first child
189
- // If the focused node is collapsed and has children, we expand it
177
+ // If the focused item is expanded, we move the focus to its first child
178
+ // If the focused item is collapsed and has children, we expand it
190
179
  case key === 'ArrowRight' && !isRTL || key === 'ArrowLeft' && isRTL:
191
180
  {
192
- if (instance.isNodeExpanded(state.focusedNodeId)) {
193
- instance.focusItem(event, (0, _useTreeView.getNextNode)(instance, state.focusedNodeId));
194
- event.preventDefault();
195
- } else if (canToggleNodeExpansion(state.focusedNodeId)) {
196
- instance.toggleNodeExpansion(event, state.focusedNodeId);
181
+ if (instance.isItemExpanded(itemId)) {
182
+ const nextItemId = (0, _useTreeView.getNextItem)(instance, itemId);
183
+ if (nextItemId) {
184
+ instance.focusItem(event, nextItemId);
185
+ event.preventDefault();
186
+ }
187
+ } else if (canToggleItemExpansion(itemId)) {
188
+ instance.toggleItemExpansion(event, itemId);
197
189
  event.preventDefault();
198
190
  }
199
191
  break;
200
192
  }
201
193
 
202
- // If the focused node is expanded, we collapse it
203
- // If the focused node is collapsed and has a parent, we move the focus to this parent
194
+ // If the focused item is expanded, we collapse it
195
+ // If the focused item is collapsed and has a parent, we move the focus to this parent
204
196
  case key === 'ArrowLeft' && !isRTL || key === 'ArrowRight' && isRTL:
205
197
  {
206
- if (canToggleNodeExpansion(state.focusedNodeId) && instance.isNodeExpanded(state.focusedNodeId)) {
207
- instance.toggleNodeExpansion(event, state.focusedNodeId);
198
+ if (canToggleItemExpansion(itemId) && instance.isItemExpanded(itemId)) {
199
+ instance.toggleItemExpansion(event, itemId);
208
200
  event.preventDefault();
209
201
  } else {
210
- const parent = instance.getNode(state.focusedNodeId).parentId;
202
+ const parent = instance.getNode(itemId).parentId;
211
203
  if (parent) {
212
204
  instance.focusItem(event, parent);
213
205
  event.preventDefault();
@@ -216,49 +208,49 @@ const useTreeViewKeyboardNavigation = ({
216
208
  break;
217
209
  }
218
210
 
219
- // Focuses the first node in the tree
211
+ // Focuses the first item in the tree
220
212
  case key === 'Home':
221
213
  {
222
- instance.focusItem(event, (0, _useTreeView.getFirstNode)(instance));
214
+ instance.focusItem(event, (0, _useTreeView.getFirstItem)(instance));
223
215
 
224
216
  // Multi select behavior when pressing Ctrl + Shift + Home
225
- // Selects the focused node and all nodes up to the first node.
226
- if (canToggleNodeSelection(state.focusedNodeId) && params.multiSelect && ctrlPressed && event.shiftKey) {
227
- instance.rangeSelectToFirst(event, state.focusedNodeId);
217
+ // Selects the focused item and all items up to the first item.
218
+ if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
219
+ instance.rangeSelectToFirst(event, itemId);
228
220
  }
229
221
  event.preventDefault();
230
222
  break;
231
223
  }
232
224
 
233
- // Focuses the last node in the tree
225
+ // Focuses the last item in the tree
234
226
  case key === 'End':
235
227
  {
236
- instance.focusItem(event, (0, _useTreeView.getLastNode)(instance));
228
+ instance.focusItem(event, (0, _useTreeView.getLastItem)(instance));
237
229
 
238
230
  // Multi select behavior when pressing Ctrl + Shirt + End
239
- // Selects the focused node and all the nodes down to the last node.
240
- if (canToggleNodeSelection(state.focusedNodeId) && params.multiSelect && ctrlPressed && event.shiftKey) {
241
- instance.rangeSelectToLast(event, state.focusedNodeId);
231
+ // Selects the focused item and all the items down to the last item.
232
+ if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
233
+ instance.rangeSelectToLast(event, itemId);
242
234
  }
243
235
  event.preventDefault();
244
236
  break;
245
237
  }
246
238
 
247
- // Expand all siblings that are at the same level as the focused node
239
+ // Expand all siblings that are at the same level as the focused item
248
240
  case key === '*':
249
241
  {
250
- instance.expandAllSiblings(event, state.focusedNodeId);
242
+ instance.expandAllSiblings(event, itemId);
251
243
  event.preventDefault();
252
244
  break;
253
245
  }
254
246
 
255
247
  // Multi select behavior when pressing Ctrl + a
256
- // Selects all the nodes
248
+ // Selects all the items
257
249
  case key === 'a' && ctrlPressed && params.multiSelect && !params.disableSelection:
258
250
  {
259
251
  instance.selectRange(event, {
260
- start: (0, _useTreeView.getFirstNode)(instance),
261
- end: (0, _useTreeView.getLastNode)(instance)
252
+ start: (0, _useTreeView.getFirstItem)(instance),
253
+ end: (0, _useTreeView.getLastItem)(instance)
262
254
  });
263
255
  event.preventDefault();
264
256
  break;
@@ -268,20 +260,19 @@ const useTreeViewKeyboardNavigation = ({
268
260
  // TODO: Support typing multiple characters
269
261
  case !ctrlPressed && !event.shiftKey && isPrintableCharacter(key):
270
262
  {
271
- const matchingNode = getFirstMatchingNode(state.focusedNodeId, key);
272
- if (matchingNode != null) {
273
- instance.focusItem(event, matchingNode);
263
+ const matchingItem = getFirstMatchingItem(itemId, key);
264
+ if (matchingItem != null) {
265
+ instance.focusItem(event, matchingItem);
274
266
  event.preventDefault();
275
267
  }
276
268
  break;
277
269
  }
278
270
  }
279
271
  };
280
- return {
281
- getRootProps: otherHandlers => ({
282
- onKeyDown: createHandleKeyDown(otherHandlers)
283
- })
284
- };
272
+ (0, _useTreeView.populateInstance)(instance, {
273
+ updateFirstCharMap,
274
+ handleItemKeyDown
275
+ });
285
276
  };
286
277
  exports.useTreeViewKeyboardNavigation = useTreeViewKeyboardNavigation;
287
278
  useTreeViewKeyboardNavigation.params = {};
@@ -16,13 +16,13 @@ const useTreeViewSelection = ({
16
16
  params,
17
17
  models
18
18
  }) => {
19
- const lastSelectedNode = React.useRef(null);
19
+ const lastSelectedItem = React.useRef(null);
20
20
  const lastSelectionWasRange = React.useRef(false);
21
21
  const currentRangeSelection = React.useRef([]);
22
22
  const setSelectedItems = (event, newSelectedItems) => {
23
23
  if (params.onItemSelectionToggle) {
24
24
  if (params.multiSelect) {
25
- const addedItems = newSelectedItems.filter(itemId => !instance.isNodeSelected(itemId));
25
+ const addedItems = newSelectedItems.filter(itemId => !instance.isItemSelected(itemId));
26
26
  const removedItems = models.selectedItems.value.filter(itemId => !newSelectedItems.includes(itemId));
27
27
  addedItems.forEach(itemId => {
28
28
  params.onItemSelectionToggle(event, itemId, true);
@@ -44,46 +44,46 @@ const useTreeViewSelection = ({
44
44
  }
45
45
  models.selectedItems.setControlledValue(newSelectedItems);
46
46
  };
47
- const isNodeSelected = nodeId => Array.isArray(models.selectedItems.value) ? models.selectedItems.value.indexOf(nodeId) !== -1 : models.selectedItems.value === nodeId;
48
- const selectNode = (event, nodeId, multiple = false) => {
47
+ const isItemSelected = itemId => Array.isArray(models.selectedItems.value) ? models.selectedItems.value.indexOf(itemId) !== -1 : models.selectedItems.value === itemId;
48
+ const selectItem = (event, itemId, multiple = false) => {
49
49
  if (params.disableSelection) {
50
50
  return;
51
51
  }
52
52
  if (multiple) {
53
53
  if (Array.isArray(models.selectedItems.value)) {
54
54
  let newSelected;
55
- if (models.selectedItems.value.indexOf(nodeId) !== -1) {
56
- newSelected = models.selectedItems.value.filter(id => id !== nodeId);
55
+ if (models.selectedItems.value.indexOf(itemId) !== -1) {
56
+ newSelected = models.selectedItems.value.filter(id => id !== itemId);
57
57
  } else {
58
- newSelected = [nodeId].concat(models.selectedItems.value);
58
+ newSelected = [itemId].concat(models.selectedItems.value);
59
59
  }
60
60
  setSelectedItems(event, newSelected);
61
61
  }
62
62
  } else {
63
- const newSelected = params.multiSelect ? [nodeId] : nodeId;
63
+ const newSelected = params.multiSelect ? [itemId] : itemId;
64
64
  setSelectedItems(event, newSelected);
65
65
  }
66
- lastSelectedNode.current = nodeId;
66
+ lastSelectedItem.current = itemId;
67
67
  lastSelectionWasRange.current = false;
68
68
  currentRangeSelection.current = [];
69
69
  };
70
- const getNodesInRange = (nodeAId, nodeBId) => {
71
- const [first, last] = (0, _useTreeViewSelection.findOrderInTremauxTree)(instance, nodeAId, nodeBId);
72
- const nodes = [first];
70
+ const getItemsInRange = (itemAId, itemBId) => {
71
+ const [first, last] = (0, _useTreeViewSelection.findOrderInTremauxTree)(instance, itemAId, itemBId);
72
+ const items = [first];
73
73
  let current = first;
74
74
  while (current !== last) {
75
- current = (0, _useTreeView.getNextNode)(instance, current);
76
- nodes.push(current);
75
+ current = (0, _useTreeView.getNextItem)(instance, current);
76
+ items.push(current);
77
77
  }
78
- return nodes;
78
+ return items;
79
79
  };
80
- const handleRangeArrowSelect = (event, nodes) => {
80
+ const handleRangeArrowSelect = (event, items) => {
81
81
  let base = models.selectedItems.value.slice();
82
82
  const {
83
83
  start,
84
84
  next,
85
85
  current
86
- } = nodes;
86
+ } = items;
87
87
  if (!next || !current) {
88
88
  return;
89
89
  }
@@ -104,32 +104,32 @@ const useTreeViewSelection = ({
104
104
  }
105
105
  setSelectedItems(event, base);
106
106
  };
107
- const handleRangeSelect = (event, nodes) => {
107
+ const handleRangeSelect = (event, items) => {
108
108
  let base = models.selectedItems.value.slice();
109
109
  const {
110
110
  start,
111
111
  end
112
- } = nodes;
113
- // If last selection was a range selection ignore nodes that were selected.
112
+ } = items;
113
+ // If last selection was a range selection ignore items that were selected.
114
114
  if (lastSelectionWasRange.current) {
115
115
  base = base.filter(id => currentRangeSelection.current.indexOf(id) === -1);
116
116
  }
117
- let range = getNodesInRange(start, end);
118
- range = range.filter(node => !instance.isNodeDisabled(node));
117
+ let range = getItemsInRange(start, end);
118
+ range = range.filter(item => !instance.isItemDisabled(item));
119
119
  currentRangeSelection.current = range;
120
120
  let newSelected = base.concat(range);
121
121
  newSelected = newSelected.filter((id, i) => newSelected.indexOf(id) === i);
122
122
  setSelectedItems(event, newSelected);
123
123
  };
124
- const selectRange = (event, nodes, stacked = false) => {
124
+ const selectRange = (event, items, stacked = false) => {
125
125
  if (params.disableSelection) {
126
126
  return;
127
127
  }
128
128
  const {
129
- start = lastSelectedNode.current,
129
+ start = lastSelectedItem.current,
130
130
  end,
131
131
  current
132
- } = nodes;
132
+ } = items;
133
133
  if (stacked) {
134
134
  handleRangeArrowSelect(event, {
135
135
  start,
@@ -144,29 +144,29 @@ const useTreeViewSelection = ({
144
144
  }
145
145
  lastSelectionWasRange.current = true;
146
146
  };
147
- const rangeSelectToFirst = (event, nodeId) => {
148
- if (!lastSelectedNode.current) {
149
- lastSelectedNode.current = nodeId;
147
+ const rangeSelectToFirst = (event, itemId) => {
148
+ if (!lastSelectedItem.current) {
149
+ lastSelectedItem.current = itemId;
150
150
  }
151
- const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
151
+ const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId;
152
152
  instance.selectRange(event, {
153
153
  start,
154
- end: (0, _useTreeView.getFirstNode)(instance)
154
+ end: (0, _useTreeView.getFirstItem)(instance)
155
155
  });
156
156
  };
157
- const rangeSelectToLast = (event, nodeId) => {
158
- if (!lastSelectedNode.current) {
159
- lastSelectedNode.current = nodeId;
157
+ const rangeSelectToLast = (event, itemId) => {
158
+ if (!lastSelectedItem.current) {
159
+ lastSelectedItem.current = itemId;
160
160
  }
161
- const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
161
+ const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId;
162
162
  instance.selectRange(event, {
163
163
  start,
164
- end: (0, _useTreeView.getLastNode)(instance)
164
+ end: (0, _useTreeView.getLastItem)(instance)
165
165
  });
166
166
  };
167
167
  (0, _useTreeView.populateInstance)(instance, {
168
- isNodeSelected,
169
- selectNode,
168
+ isItemSelected,
169
+ selectItem,
170
170
  selectRange,
171
171
  rangeSelectToLast,
172
172
  rangeSelectToFirst
@@ -188,11 +188,11 @@ useTreeViewSelection.models = {
188
188
  getDefaultValue: params => params.defaultSelectedItems
189
189
  }
190
190
  };
191
- const DEFAULT_SELECTED_NODES = [];
191
+ const DEFAULT_SELECTED_ITEMS = [];
192
192
  useTreeViewSelection.getDefaultizedParams = params => (0, _extends2.default)({}, params, {
193
193
  disableSelection: params.disableSelection ?? false,
194
194
  multiSelect: params.multiSelect ?? false,
195
- defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_NODES : null)
195
+ defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_ITEMS : null)
196
196
  });
197
197
  useTreeViewSelection.params = {
198
198
  disableSelection: true,
@@ -6,16 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.findOrderInTremauxTree = void 0;
7
7
  /**
8
8
  * This is used to determine the start and end of a selection range so
9
- * we can get the nodes between the two border nodes.
9
+ * we can get the items between the two border items.
10
10
  *
11
- * It finds the nodes' common ancestor using
11
+ * It finds the items' common ancestor using
12
12
  * a naive implementation of a lowest common ancestor algorithm
13
13
  * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
14
- * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB
15
- * so we can compare their indexes to work out which node comes first in a depth first search.
14
+ * Then compares the ancestor's 2 children that are ancestors of itemA and ItemB
15
+ * so we can compare their indexes to work out which item comes first in a depth first search.
16
16
  * (https://en.wikipedia.org/wiki/Depth-first_search)
17
17
  *
18
- * Another way to put it is which node is shallower in a trémaux tree
18
+ * Another way to put it is which item is shallower in a trémaux tree
19
19
  * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
20
20
  */
21
21
  const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
@@ -97,13 +97,13 @@ const useTreeView = inParams => {
97
97
  };
98
98
  const itemWrappers = plugins.map(plugin => plugin.wrapItem).filter(wrapItem => !!wrapItem);
99
99
  contextValue.wrapItem = ({
100
- nodeId,
100
+ itemId,
101
101
  children
102
102
  }) => {
103
103
  let finalChildren = children;
104
104
  itemWrappers.forEach(itemWrapper => {
105
105
  finalChildren = itemWrapper({
106
- nodeId,
106
+ itemId,
107
107
  children: finalChildren
108
108
  });
109
109
  });
@@ -111,8 +111,7 @@ const useTreeView = inParams => {
111
111
  };
112
112
  const getRootProps = (otherHandlers = {}) => {
113
113
  const rootProps = (0, _extends2.default)({
114
- role: 'tree',
115
- tabIndex: 0
114
+ role: 'tree'
116
115
  }, otherHandlers, {
117
116
  ref: handleRootRef
118
117
  });
@@ -3,27 +3,27 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.populatePublicAPI = exports.populateInstance = exports.getPreviousNode = exports.getNextNode = exports.getLastNode = exports.getFirstNode = void 0;
7
- const getPreviousNode = (instance, nodeId) => {
8
- const node = instance.getNode(nodeId);
6
+ exports.populatePublicAPI = exports.populateInstance = exports.getPreviousItem = exports.getNextItem = exports.getLastItem = exports.getFirstItem = void 0;
7
+ const getPreviousItem = (instance, itemId) => {
8
+ const node = instance.getNode(itemId);
9
9
  const siblings = instance.getNavigableChildrenIds(node.parentId);
10
- const nodeIndex = siblings.indexOf(nodeId);
11
- if (nodeIndex === 0) {
10
+ const itemIndex = siblings.indexOf(itemId);
11
+ if (itemIndex === 0) {
12
12
  return node.parentId;
13
13
  }
14
- let currentNode = siblings[nodeIndex - 1];
15
- while (instance.isNodeExpanded(currentNode) && instance.getNavigableChildrenIds(currentNode).length > 0) {
16
- currentNode = instance.getNavigableChildrenIds(currentNode).pop();
14
+ let currentItem = siblings[itemIndex - 1];
15
+ while (instance.isItemExpanded(currentItem) && instance.getNavigableChildrenIds(currentItem).length > 0) {
16
+ currentItem = instance.getNavigableChildrenIds(currentItem).pop();
17
17
  }
18
- return currentNode;
18
+ return currentItem;
19
19
  };
20
- exports.getPreviousNode = getPreviousNode;
21
- const getNextNode = (instance, nodeId) => {
20
+ exports.getPreviousItem = getPreviousItem;
21
+ const getNextItem = (instance, itemId) => {
22
22
  // If expanded get first child
23
- if (instance.isNodeExpanded(nodeId) && instance.getNavigableChildrenIds(nodeId).length > 0) {
24
- return instance.getNavigableChildrenIds(nodeId)[0];
23
+ if (instance.isItemExpanded(itemId) && instance.getNavigableChildrenIds(itemId).length > 0) {
24
+ return instance.getNavigableChildrenIds(itemId)[0];
25
25
  }
26
- let node = instance.getNode(nodeId);
26
+ let node = instance.getNode(itemId);
27
27
  while (node != null) {
28
28
  // Try to get next sibling
29
29
  const siblings = instance.getNavigableChildrenIds(node.parentId);
@@ -37,17 +37,17 @@ const getNextNode = (instance, nodeId) => {
37
37
  }
38
38
  return null;
39
39
  };
40
- exports.getNextNode = getNextNode;
41
- const getLastNode = instance => {
42
- let lastNode = instance.getNavigableChildrenIds(null).pop();
43
- while (instance.isNodeExpanded(lastNode)) {
44
- lastNode = instance.getNavigableChildrenIds(lastNode).pop();
40
+ exports.getNextItem = getNextItem;
41
+ const getLastItem = instance => {
42
+ let lastItem = instance.getNavigableChildrenIds(null).pop();
43
+ while (instance.isItemExpanded(lastItem)) {
44
+ lastItem = instance.getNavigableChildrenIds(lastItem).pop();
45
45
  }
46
- return lastNode;
46
+ return lastItem;
47
47
  };
48
- exports.getLastNode = getLastNode;
49
- const getFirstNode = instance => instance.getNavigableChildrenIds(null)[0];
50
- exports.getFirstNode = getFirstNode;
48
+ exports.getLastItem = getLastItem;
49
+ const getFirstItem = instance => instance.getNavigableChildrenIds(null)[0];
50
+ exports.getFirstItem = getFirstItem;
51
51
  const populateInstance = (instance, methods) => {
52
52
  Object.assign(instance, methods);
53
53
  };
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getActiveElement = void 0;
7
+ // https://www.abeautifulsite.net/posts/finding-the-active-element-in-a-shadow-root/
7
8
  const getActiveElement = (root = document) => {
8
9
  const activeEl = root.activeElement;
9
10
  if (!activeEl) {