@mui/x-tree-view 7.0.0-beta.6 → 7.0.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 (152) hide show
  1. package/CHANGELOG.md +311 -12
  2. package/README.md +1 -1
  3. package/RichTreeView/RichTreeView.js +34 -36
  4. package/RichTreeView/RichTreeView.types.d.ts +3 -2
  5. package/SimpleTreeView/SimpleTreeView.js +25 -26
  6. package/TreeItem/TreeItem.js +94 -82
  7. package/TreeItem/TreeItem.types.d.ts +13 -11
  8. package/TreeItem/TreeItemContent.d.ts +7 -7
  9. package/TreeItem/TreeItemContent.js +10 -10
  10. package/TreeItem/useTreeItemState.d.ts +1 -1
  11. package/TreeItem/useTreeItemState.js +13 -13
  12. package/TreeItem2/TreeItem2.d.ts +18 -0
  13. package/TreeItem2/TreeItem2.js +300 -0
  14. package/TreeItem2/TreeItem2.types.d.ts +64 -0
  15. package/TreeItem2/TreeItem2.types.js +1 -0
  16. package/TreeItem2/index.d.ts +2 -0
  17. package/TreeItem2/index.js +1 -0
  18. package/TreeItem2/package.json +6 -0
  19. package/TreeItem2Icon/TreeItem2Icon.d.ts +7 -0
  20. package/TreeItem2Icon/TreeItem2Icon.js +67 -0
  21. package/TreeItem2Icon/TreeItem2Icon.types.d.ts +40 -0
  22. package/TreeItem2Icon/TreeItem2Icon.types.js +1 -0
  23. package/TreeItem2Icon/index.d.ts +2 -0
  24. package/TreeItem2Icon/index.js +1 -0
  25. package/TreeItem2Icon/package.json +6 -0
  26. package/TreeItem2Provider/TreeItem2Provider.d.ts +7 -0
  27. package/TreeItem2Provider/TreeItem2Provider.js +24 -0
  28. package/TreeItem2Provider/TreeItem2Provider.types.d.ts +6 -0
  29. package/TreeItem2Provider/TreeItem2Provider.types.js +1 -0
  30. package/TreeItem2Provider/index.d.ts +2 -0
  31. package/TreeItem2Provider/index.js +1 -0
  32. package/TreeItem2Provider/package.json +6 -0
  33. package/TreeView/TreeView.d.ts +1 -1
  34. package/TreeView/TreeView.js +23 -23
  35. package/hooks/index.d.ts +1 -0
  36. package/hooks/index.js +2 -1
  37. package/hooks/useTreeItem2Utils/index.d.ts +1 -0
  38. package/hooks/useTreeItem2Utils/index.js +1 -0
  39. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +15 -0
  40. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +61 -0
  41. package/index.d.ts +5 -1
  42. package/index.js +9 -2
  43. package/internals/TreeViewProvider/TreeViewContext.d.ts +3 -1
  44. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +4 -2
  45. package/internals/hooks/useInstanceEventHandler.js +5 -10
  46. package/internals/hooks/useLazyRef.d.ts +1 -2
  47. package/internals/hooks/useLazyRef.js +1 -11
  48. package/internals/hooks/useOnMount.d.ts +1 -2
  49. package/internals/hooks/useOnMount.js +1 -7
  50. package/internals/hooks/useTimeout.d.ts +1 -11
  51. package/internals/hooks/useTimeout.js +1 -36
  52. package/internals/models/plugin.d.ts +19 -16
  53. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +31 -38
  54. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +14 -14
  55. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +67 -51
  56. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +9 -8
  57. package/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  58. package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +1 -1
  59. package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js +30 -31
  60. package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.d.ts +2 -2
  61. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +75 -80
  62. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +4 -1
  63. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +26 -31
  64. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.d.ts +11 -11
  65. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +47 -50
  66. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +15 -15
  67. package/internals/useTreeView/useTreeView.js +28 -27
  68. package/internals/useTreeView/useTreeView.utils.d.ts +2 -2
  69. package/internals/useTreeView/useTreeView.utils.js +22 -22
  70. package/internals/utils/extractPluginParamsFromProps.js +2 -2
  71. package/internals/utils/utils.js +1 -0
  72. package/modern/RichTreeView/RichTreeView.js +29 -29
  73. package/modern/SimpleTreeView/SimpleTreeView.js +23 -23
  74. package/modern/TreeItem/TreeItem.js +83 -70
  75. package/modern/TreeItem/TreeItemContent.js +10 -10
  76. package/modern/TreeItem/useTreeItemState.js +13 -13
  77. package/modern/TreeItem2/TreeItem2.js +300 -0
  78. package/modern/TreeItem2/TreeItem2.types.js +1 -0
  79. package/modern/TreeItem2/index.js +1 -0
  80. package/modern/TreeItem2Icon/TreeItem2Icon.js +67 -0
  81. package/modern/TreeItem2Icon/TreeItem2Icon.types.js +1 -0
  82. package/modern/TreeItem2Icon/index.js +1 -0
  83. package/modern/TreeItem2Provider/TreeItem2Provider.js +24 -0
  84. package/modern/TreeItem2Provider/TreeItem2Provider.types.js +1 -0
  85. package/modern/TreeItem2Provider/index.js +1 -0
  86. package/modern/TreeView/TreeView.js +23 -23
  87. package/modern/hooks/index.js +2 -1
  88. package/modern/hooks/useTreeItem2Utils/index.js +1 -0
  89. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +61 -0
  90. package/modern/index.js +9 -2
  91. package/modern/internals/hooks/useLazyRef.js +1 -11
  92. package/modern/internals/hooks/useOnMount.js +1 -7
  93. package/modern/internals/hooks/useTimeout.js +1 -36
  94. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +29 -29
  95. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +65 -46
  96. package/modern/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  97. package/modern/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js +30 -30
  98. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +74 -77
  99. package/modern/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +21 -22
  100. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +43 -43
  101. package/modern/internals/useTreeView/useTreeView.js +28 -27
  102. package/modern/internals/useTreeView/useTreeView.utils.js +22 -22
  103. package/modern/internals/utils/utils.js +1 -0
  104. package/modern/useTreeItem2/index.js +1 -0
  105. package/modern/useTreeItem2/useTreeItem2.js +146 -0
  106. package/modern/useTreeItem2/useTreeItem2.types.js +1 -0
  107. package/node/RichTreeView/RichTreeView.js +29 -29
  108. package/node/SimpleTreeView/SimpleTreeView.js +23 -23
  109. package/node/TreeItem/TreeItem.js +83 -70
  110. package/node/TreeItem/TreeItemContent.js +10 -10
  111. package/node/TreeItem/useTreeItemState.js +13 -13
  112. package/node/TreeItem2/TreeItem2.js +308 -0
  113. package/node/TreeItem2/TreeItem2.types.js +5 -0
  114. package/node/TreeItem2/index.js +42 -0
  115. package/node/TreeItem2Icon/TreeItem2Icon.js +75 -0
  116. package/node/TreeItem2Icon/TreeItem2Icon.types.js +5 -0
  117. package/node/TreeItem2Icon/index.js +12 -0
  118. package/node/TreeItem2Provider/TreeItem2Provider.js +30 -0
  119. package/node/TreeItem2Provider/TreeItem2Provider.types.js +5 -0
  120. package/node/TreeItem2Provider/index.js +12 -0
  121. package/node/TreeView/TreeView.js +23 -23
  122. package/node/hooks/index.js +8 -1
  123. package/node/hooks/useTreeItem2Utils/index.js +12 -0
  124. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +68 -0
  125. package/node/index.js +61 -13
  126. package/node/internals/hooks/useLazyRef.js +7 -13
  127. package/node/internals/hooks/useOnMount.js +8 -10
  128. package/node/internals/hooks/useTimeout.js +7 -37
  129. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +29 -29
  130. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +65 -46
  131. package/node/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  132. package/node/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js +30 -30
  133. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +74 -77
  134. package/node/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +21 -22
  135. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +43 -43
  136. package/node/internals/useTreeView/useTreeView.js +28 -27
  137. package/node/internals/useTreeView/useTreeView.utils.js +22 -22
  138. package/node/internals/utils/utils.js +1 -0
  139. package/node/useTreeItem2/index.js +12 -0
  140. package/node/useTreeItem2/useTreeItem2.js +154 -0
  141. package/node/useTreeItem2/useTreeItem2.types.js +5 -0
  142. package/package.json +5 -5
  143. package/themeAugmentation/components.d.ts +5 -0
  144. package/themeAugmentation/overrides.d.ts +1 -0
  145. package/themeAugmentation/props.d.ts +2 -0
  146. package/useTreeItem2/index.d.ts +2 -0
  147. package/useTreeItem2/index.js +1 -0
  148. package/useTreeItem2/package.json +6 -0
  149. package/useTreeItem2/useTreeItem2.d.ts +2 -0
  150. package/useTreeItem2/useTreeItem2.js +146 -0
  151. package/useTreeItem2/useTreeItem2.types.d.ts +115 -0
  152. package/useTreeItem2/useTreeItem2.types.js +1 -0
@@ -15,8 +15,7 @@ function findNextFirstChar(firstChars, startIndex, char) {
15
15
  }
16
16
  export const useTreeViewKeyboardNavigation = ({
17
17
  instance,
18
- params,
19
- state
18
+ params
20
19
  }) => {
21
20
  const theme = useTheme();
22
21
  const isRTL = theme.direction === 'rtl';
@@ -33,35 +32,32 @@ export const useTreeViewKeyboardNavigation = ({
33
32
  const newFirstCharMap = {};
34
33
  const processItem = item => {
35
34
  const getItemId = params.getItemId;
36
- const nodeId = getItemId ? getItemId(item) : item.id;
37
- newFirstCharMap[nodeId] = instance.getNode(nodeId).label.substring(0, 1).toLowerCase();
35
+ const itemId = getItemId ? getItemId(item) : item.id;
36
+ newFirstCharMap[itemId] = instance.getNode(itemId).label.substring(0, 1).toLowerCase();
38
37
  item.children?.forEach(processItem);
39
38
  };
40
39
  params.items.forEach(processItem);
41
40
  firstCharMap.current = newFirstCharMap;
42
41
  }, [params.items, params.getItemId, instance]);
43
- populateInstance(instance, {
44
- updateFirstCharMap
45
- });
46
- const getFirstMatchingNode = (nodeId, firstChar) => {
42
+ const getFirstMatchingItem = (itemId, firstChar) => {
47
43
  let start;
48
44
  let index;
49
45
  const lowercaseChar = firstChar.toLowerCase();
50
46
  const firstCharIds = [];
51
47
  const firstChars = [];
52
48
  // This really only works since the ids are strings
53
- Object.keys(firstCharMap.current).forEach(mapNodeId => {
54
- const map = instance.getNode(mapNodeId);
49
+ Object.keys(firstCharMap.current).forEach(mapItemId => {
50
+ const map = instance.getNode(mapItemId);
55
51
  const visible = map.parentId ? instance.isNodeExpanded(map.parentId) : true;
56
- const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isNodeDisabled(mapNodeId);
52
+ const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isNodeDisabled(mapItemId);
57
53
  if (visible && !shouldBeSkipped) {
58
- firstCharIds.push(mapNodeId);
59
- firstChars.push(firstCharMap.current[mapNodeId]);
54
+ firstCharIds.push(mapItemId);
55
+ firstChars.push(firstCharMap.current[mapItemId]);
60
56
  }
61
57
  });
62
58
 
63
59
  // Get start index for search based on position of currentItem
64
- start = firstCharIds.indexOf(nodeId) + 1;
60
+ start = firstCharIds.indexOf(itemId) + 1;
65
61
  if (start >= firstCharIds.length) {
66
62
  start = 0;
67
63
  }
@@ -80,18 +76,17 @@ export const useTreeViewKeyboardNavigation = ({
80
76
  }
81
77
  return null;
82
78
  };
83
- const canToggleNodeSelection = nodeId => !params.disableSelection && !instance.isNodeDisabled(nodeId);
84
- const canToggleNodeExpansion = nodeId => !instance.isNodeDisabled(nodeId) && instance.isNodeExpandable(nodeId);
79
+ const canToggleItemSelection = itemId => !params.disableSelection && !instance.isNodeDisabled(itemId);
80
+ const canToggleItemExpansion = itemId => {
81
+ return !instance.isNodeDisabled(itemId) && instance.isNodeExpandable(itemId);
82
+ };
85
83
 
86
84
  // ARIA specification: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction
87
- const createHandleKeyDown = otherHandlers => event => {
88
- otherHandlers.onKeyDown?.(event);
85
+ const handleItemKeyDown = (event, itemId) => {
89
86
  if (event.defaultMuiPrevented) {
90
87
  return;
91
88
  }
92
-
93
- // If the tree is empty there will be no focused node
94
- if (event.altKey || event.currentTarget !== event.target || state.focusedNodeId == null) {
89
+ if (event.altKey || event.currentTarget !== event.target) {
95
90
  return;
96
91
  }
97
92
  const ctrlPressed = event.ctrlKey || event.metaKey;
@@ -100,17 +95,17 @@ export const useTreeViewKeyboardNavigation = ({
100
95
  // eslint-disable-next-line default-case
101
96
  switch (true) {
102
97
  // Select the node when pressing "Space"
103
- case key === ' ' && canToggleNodeSelection(state.focusedNodeId):
98
+ case key === ' ' && canToggleItemSelection(itemId):
104
99
  {
105
100
  event.preventDefault();
106
101
  if (params.multiSelect && event.shiftKey) {
107
102
  instance.selectRange(event, {
108
- end: state.focusedNodeId
103
+ end: itemId
109
104
  });
110
105
  } else if (params.multiSelect) {
111
- instance.selectNode(event, state.focusedNodeId, true);
106
+ instance.selectNode(event, itemId, true);
112
107
  } else {
113
- instance.selectNode(event, state.focusedNodeId);
108
+ instance.selectNode(event, itemId);
114
109
  }
115
110
  break;
116
111
  }
@@ -119,86 +114,89 @@ export const useTreeViewKeyboardNavigation = ({
119
114
  // If the focused node has no children, we select it.
120
115
  case key === 'Enter':
121
116
  {
122
- if (canToggleNodeExpansion(state.focusedNodeId)) {
123
- instance.toggleNodeExpansion(event, state.focusedNodeId);
117
+ if (canToggleItemExpansion(itemId)) {
118
+ instance.toggleNodeExpansion(event, itemId);
124
119
  event.preventDefault();
125
- } else if (canToggleNodeSelection(state.focusedNodeId)) {
120
+ } else if (canToggleItemSelection(itemId)) {
126
121
  if (params.multiSelect) {
127
122
  event.preventDefault();
128
- instance.selectNode(event, state.focusedNodeId, true);
129
- } else if (!instance.isNodeSelected(state.focusedNodeId)) {
130
- instance.selectNode(event, state.focusedNodeId);
123
+ instance.selectNode(event, itemId, true);
124
+ } else if (!instance.isNodeSelected(itemId)) {
125
+ instance.selectNode(event, itemId);
131
126
  event.preventDefault();
132
127
  }
133
128
  }
134
129
  break;
135
130
  }
136
131
 
137
- // Focus the next focusable node
132
+ // Focus the next focusable item
138
133
  case key === 'ArrowDown':
139
134
  {
140
- const nextNode = getNextNode(instance, state.focusedNodeId);
141
- if (nextNode) {
135
+ const nextItem = getNextNode(instance, itemId);
136
+ if (nextItem) {
142
137
  event.preventDefault();
143
- instance.focusNode(event, nextNode);
138
+ instance.focusItem(event, nextItem);
144
139
 
145
140
  // Multi select behavior when pressing Shift + ArrowDown
146
- // Toggles the selection state of the next node
147
- if (params.multiSelect && event.shiftKey && canToggleNodeSelection(nextNode)) {
141
+ // Toggles the selection state of the next item
142
+ if (params.multiSelect && event.shiftKey && canToggleItemSelection(nextItem)) {
148
143
  instance.selectRange(event, {
149
- end: nextNode,
150
- current: state.focusedNodeId
144
+ end: nextItem,
145
+ current: itemId
151
146
  }, true);
152
147
  }
153
148
  }
154
149
  break;
155
150
  }
156
151
 
157
- // Focuses the previous focusable node
152
+ // Focuses the previous focusable item
158
153
  case key === 'ArrowUp':
159
154
  {
160
- const previousNode = getPreviousNode(instance, state.focusedNodeId);
161
- if (previousNode) {
155
+ const previousItem = getPreviousNode(instance, itemId);
156
+ if (previousItem) {
162
157
  event.preventDefault();
163
- instance.focusNode(event, previousNode);
158
+ instance.focusItem(event, previousItem);
164
159
 
165
160
  // Multi select behavior when pressing Shift + ArrowUp
166
- // Toggles the selection state of the previous node
167
- if (params.multiSelect && event.shiftKey && canToggleNodeSelection(previousNode)) {
161
+ // Toggles the selection state of the previous item
162
+ if (params.multiSelect && event.shiftKey && canToggleItemSelection(previousItem)) {
168
163
  instance.selectRange(event, {
169
- end: previousNode,
170
- current: state.focusedNodeId
164
+ end: previousItem,
165
+ current: itemId
171
166
  }, true);
172
167
  }
173
168
  }
174
169
  break;
175
170
  }
176
171
 
177
- // If the focused node is expanded, we move the focus to its first child
178
- // If the focused node is collapsed and has children, we expand it
172
+ // If the focused item is expanded, we move the focus to its first child
173
+ // If the focused item is collapsed and has children, we expand it
179
174
  case key === 'ArrowRight' && !isRTL || key === 'ArrowLeft' && isRTL:
180
175
  {
181
- if (instance.isNodeExpanded(state.focusedNodeId)) {
182
- instance.focusNode(event, getNextNode(instance, state.focusedNodeId));
183
- event.preventDefault();
184
- } else if (canToggleNodeExpansion(state.focusedNodeId)) {
185
- instance.toggleNodeExpansion(event, state.focusedNodeId);
176
+ if (instance.isNodeExpanded(itemId)) {
177
+ const nextNodeId = getNextNode(instance, itemId);
178
+ if (nextNodeId) {
179
+ instance.focusItem(event, nextNodeId);
180
+ event.preventDefault();
181
+ }
182
+ } else if (canToggleItemExpansion(itemId)) {
183
+ instance.toggleNodeExpansion(event, itemId);
186
184
  event.preventDefault();
187
185
  }
188
186
  break;
189
187
  }
190
188
 
191
- // If the focused node is expanded, we collapse it
192
- // If the focused node is collapsed and has a parent, we move the focus to this parent
189
+ // If the focused item is expanded, we collapse it
190
+ // If the focused item is collapsed and has a parent, we move the focus to this parent
193
191
  case key === 'ArrowLeft' && !isRTL || key === 'ArrowRight' && isRTL:
194
192
  {
195
- if (canToggleNodeExpansion(state.focusedNodeId) && instance.isNodeExpanded(state.focusedNodeId)) {
196
- instance.toggleNodeExpansion(event, state.focusedNodeId);
193
+ if (canToggleItemExpansion(itemId) && instance.isNodeExpanded(itemId)) {
194
+ instance.toggleNodeExpansion(event, itemId);
197
195
  event.preventDefault();
198
196
  } else {
199
- const parent = instance.getNode(state.focusedNodeId).parentId;
197
+ const parent = instance.getNode(itemId).parentId;
200
198
  if (parent) {
201
- instance.focusNode(event, parent);
199
+ instance.focusItem(event, parent);
202
200
  event.preventDefault();
203
201
  }
204
202
  }
@@ -208,35 +206,35 @@ export const useTreeViewKeyboardNavigation = ({
208
206
  // Focuses the first node in the tree
209
207
  case key === 'Home':
210
208
  {
211
- instance.focusNode(event, getFirstNode(instance));
209
+ instance.focusItem(event, getFirstNode(instance));
212
210
 
213
211
  // Multi select behavior when pressing Ctrl + Shift + Home
214
212
  // Selects the focused node and all nodes up to the first node.
215
- if (canToggleNodeSelection(state.focusedNodeId) && params.multiSelect && ctrlPressed && event.shiftKey) {
216
- instance.rangeSelectToFirst(event, state.focusedNodeId);
213
+ if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
214
+ instance.rangeSelectToFirst(event, itemId);
217
215
  }
218
216
  event.preventDefault();
219
217
  break;
220
218
  }
221
219
 
222
- // Focuses the last node in the tree
220
+ // Focuses the last item in the tree
223
221
  case key === 'End':
224
222
  {
225
- instance.focusNode(event, getLastNode(instance));
223
+ instance.focusItem(event, getLastNode(instance));
226
224
 
227
225
  // Multi select behavior when pressing Ctrl + Shirt + End
228
- // Selects the focused node and all the nodes down to the last node.
229
- if (canToggleNodeSelection(state.focusedNodeId) && params.multiSelect && ctrlPressed && event.shiftKey) {
230
- instance.rangeSelectToLast(event, state.focusedNodeId);
226
+ // Selects the focused item and all the items down to the last item.
227
+ if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
228
+ instance.rangeSelectToLast(event, itemId);
231
229
  }
232
230
  event.preventDefault();
233
231
  break;
234
232
  }
235
233
 
236
- // Expand all siblings that are at the same level as the focused node
234
+ // Expand all siblings that are at the same level as the focused item
237
235
  case key === '*':
238
236
  {
239
- instance.expandAllSiblings(event, state.focusedNodeId);
237
+ instance.expandAllSiblings(event, itemId);
240
238
  event.preventDefault();
241
239
  break;
242
240
  }
@@ -257,19 +255,18 @@ export const useTreeViewKeyboardNavigation = ({
257
255
  // TODO: Support typing multiple characters
258
256
  case !ctrlPressed && !event.shiftKey && isPrintableCharacter(key):
259
257
  {
260
- const matchingNode = getFirstMatchingNode(state.focusedNodeId, key);
258
+ const matchingNode = getFirstMatchingItem(itemId, key);
261
259
  if (matchingNode != null) {
262
- instance.focusNode(event, matchingNode);
260
+ instance.focusItem(event, matchingNode);
263
261
  event.preventDefault();
264
262
  }
265
263
  break;
266
264
  }
267
265
  }
268
266
  };
269
- return {
270
- getRootProps: otherHandlers => ({
271
- onKeyDown: createHandleKeyDown(otherHandlers)
272
- })
273
- };
267
+ populateInstance(instance, {
268
+ updateFirstCharMap,
269
+ handleItemKeyDown
270
+ });
274
271
  };
275
272
  useTreeViewKeyboardNavigation.params = {};
@@ -1,6 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import useEventCallback from '@mui/utils/useEventCallback';
4
3
  import { populateInstance, populatePublicAPI } from '../../useTreeView/useTreeView.utils';
5
4
  import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent';
6
5
  const updateNodesState = ({
@@ -52,34 +51,34 @@ export const useTreeViewNodes = ({
52
51
  state,
53
52
  setState
54
53
  }) => {
55
- const getNode = React.useCallback(nodeId => state.nodes.nodeMap[nodeId], [state.nodes.nodeMap]);
56
- const getItem = React.useCallback(nodeId => state.nodes.itemMap[nodeId], [state.nodes.itemMap]);
57
- const isNodeDisabled = React.useCallback(nodeId => {
58
- if (nodeId == null) {
54
+ const getNode = React.useCallback(itemId => state.nodes.nodeMap[itemId], [state.nodes.nodeMap]);
55
+ const getItem = React.useCallback(itemId => state.nodes.itemMap[itemId], [state.nodes.itemMap]);
56
+ const isNodeDisabled = React.useCallback(itemId => {
57
+ if (itemId == null) {
59
58
  return false;
60
59
  }
61
- let node = instance.getNode(nodeId);
60
+ let item = instance.getNode(itemId);
62
61
 
63
- // This can be called before the node has been added to the node map.
64
- if (!node) {
62
+ // This can be called before the item has been added to the node map.
63
+ if (!item) {
65
64
  return false;
66
65
  }
67
- if (node.disabled) {
66
+ if (item.disabled) {
68
67
  return true;
69
68
  }
70
- while (node.parentId != null) {
71
- node = instance.getNode(node.parentId);
72
- if (node.disabled) {
69
+ while (item.parentId != null) {
70
+ item = instance.getNode(item.parentId);
71
+ if (item.disabled) {
73
72
  return true;
74
73
  }
75
74
  }
76
75
  return false;
77
76
  }, [instance]);
78
- const getChildrenIds = useEventCallback(nodeId => Object.values(state.nodes.nodeMap).filter(node => node.parentId === nodeId).sort((a, b) => a.index - b.index).map(child => child.id));
79
- const getNavigableChildrenIds = nodeId => {
80
- let childrenIds = instance.getChildrenIds(nodeId);
77
+ const getChildrenIds = React.useCallback(itemId => Object.values(state.nodes.nodeMap).filter(item => item.parentId === itemId).sort((a, b) => a.index - b.index).map(child => child.id), [state.nodes.nodeMap]);
78
+ const getNavigableChildrenIds = itemId => {
79
+ let childrenIds = instance.getChildrenIds(itemId);
81
80
  if (!params.disabledItemsFocusable) {
82
- childrenIds = childrenIds.filter(node => !instance.isNodeDisabled(node));
81
+ childrenIds = childrenIds.filter(item => !instance.isNodeDisabled(item));
83
82
  }
84
83
  return childrenIds;
85
84
  };
@@ -103,21 +102,21 @@ export const useTreeViewNodes = ({
103
102
  });
104
103
  });
105
104
  }, [instance, setState, params.items, params.isItemDisabled, params.getItemId, params.getItemLabel]);
106
- const getNodesToRender = useEventCallback(() => {
107
- const getPropsFromNodeId = ({
105
+ const getNodesToRender = () => {
106
+ const getPropsFromItemId = ({
108
107
  id,
109
108
  children
110
109
  }) => {
111
110
  const node = state.nodes.nodeMap[id];
112
111
  return {
113
112
  label: node.label,
114
- nodeId: node.id,
113
+ itemId: node.id,
115
114
  id: node.idAttribute,
116
- children: children?.map(getPropsFromNodeId)
115
+ children: children?.map(getPropsFromItemId)
117
116
  };
118
117
  };
119
- return state.nodes.nodeTree.map(getPropsFromNodeId);
120
- });
118
+ return state.nodes.nodeTree.map(getPropsFromItemId);
119
+ };
121
120
  populateInstance(instance, {
122
121
  getNode,
123
122
  getItem,
@@ -10,51 +10,51 @@ export const useTreeViewSelection = ({
10
10
  const lastSelectedNode = React.useRef(null);
11
11
  const lastSelectionWasRange = React.useRef(false);
12
12
  const currentRangeSelection = React.useRef([]);
13
- const setSelectedNodes = (event, newSelectedNodes) => {
14
- if (params.onNodeSelectionToggle) {
13
+ const setSelectedItems = (event, newSelectedItems) => {
14
+ if (params.onItemSelectionToggle) {
15
15
  if (params.multiSelect) {
16
- const addedNodes = newSelectedNodes.filter(nodeId => !instance.isNodeSelected(nodeId));
17
- const removedNodes = models.selectedNodes.value.filter(nodeId => !newSelectedNodes.includes(nodeId));
18
- addedNodes.forEach(nodeId => {
19
- params.onNodeSelectionToggle(event, nodeId, true);
16
+ const addedItems = newSelectedItems.filter(itemId => !instance.isNodeSelected(itemId));
17
+ const removedItems = models.selectedItems.value.filter(itemId => !newSelectedItems.includes(itemId));
18
+ addedItems.forEach(itemId => {
19
+ params.onItemSelectionToggle(event, itemId, true);
20
20
  });
21
- removedNodes.forEach(nodeId => {
22
- params.onNodeSelectionToggle(event, nodeId, false);
21
+ removedItems.forEach(itemId => {
22
+ params.onItemSelectionToggle(event, itemId, false);
23
23
  });
24
- } else if (newSelectedNodes !== models.selectedNodes.value) {
25
- if (models.selectedNodes.value != null) {
26
- params.onNodeSelectionToggle(event, models.selectedNodes.value, false);
24
+ } else if (newSelectedItems !== models.selectedItems.value) {
25
+ if (models.selectedItems.value != null) {
26
+ params.onItemSelectionToggle(event, models.selectedItems.value, false);
27
27
  }
28
- if (newSelectedNodes != null) {
29
- params.onNodeSelectionToggle(event, newSelectedNodes, true);
28
+ if (newSelectedItems != null) {
29
+ params.onItemSelectionToggle(event, newSelectedItems, true);
30
30
  }
31
31
  }
32
32
  }
33
- if (params.onSelectedNodesChange) {
34
- params.onSelectedNodesChange(event, newSelectedNodes);
33
+ if (params.onSelectedItemsChange) {
34
+ params.onSelectedItemsChange(event, newSelectedItems);
35
35
  }
36
- models.selectedNodes.setControlledValue(newSelectedNodes);
36
+ models.selectedItems.setControlledValue(newSelectedItems);
37
37
  };
38
- const isNodeSelected = nodeId => Array.isArray(models.selectedNodes.value) ? models.selectedNodes.value.indexOf(nodeId) !== -1 : models.selectedNodes.value === nodeId;
39
- const selectNode = (event, nodeId, multiple = false) => {
38
+ const isNodeSelected = itemId => Array.isArray(models.selectedItems.value) ? models.selectedItems.value.indexOf(itemId) !== -1 : models.selectedItems.value === itemId;
39
+ const selectNode = (event, itemId, multiple = false) => {
40
40
  if (params.disableSelection) {
41
41
  return;
42
42
  }
43
43
  if (multiple) {
44
- if (Array.isArray(models.selectedNodes.value)) {
44
+ if (Array.isArray(models.selectedItems.value)) {
45
45
  let newSelected;
46
- if (models.selectedNodes.value.indexOf(nodeId) !== -1) {
47
- newSelected = models.selectedNodes.value.filter(id => id !== nodeId);
46
+ if (models.selectedItems.value.indexOf(itemId) !== -1) {
47
+ newSelected = models.selectedItems.value.filter(id => id !== itemId);
48
48
  } else {
49
- newSelected = [nodeId].concat(models.selectedNodes.value);
49
+ newSelected = [itemId].concat(models.selectedItems.value);
50
50
  }
51
- setSelectedNodes(event, newSelected);
51
+ setSelectedItems(event, newSelected);
52
52
  }
53
53
  } else {
54
- const newSelected = params.multiSelect ? [nodeId] : nodeId;
55
- setSelectedNodes(event, newSelected);
54
+ const newSelected = params.multiSelect ? [itemId] : itemId;
55
+ setSelectedItems(event, newSelected);
56
56
  }
57
- lastSelectedNode.current = nodeId;
57
+ lastSelectedNode.current = itemId;
58
58
  lastSelectionWasRange.current = false;
59
59
  currentRangeSelection.current = [];
60
60
  };
@@ -69,7 +69,7 @@ export const useTreeViewSelection = ({
69
69
  return nodes;
70
70
  };
71
71
  const handleRangeArrowSelect = (event, nodes) => {
72
- let base = models.selectedNodes.value.slice();
72
+ let base = models.selectedItems.value.slice();
73
73
  const {
74
74
  start,
75
75
  next,
@@ -93,10 +93,10 @@ export const useTreeViewSelection = ({
93
93
  base.push(next);
94
94
  currentRangeSelection.current.push(current, next);
95
95
  }
96
- setSelectedNodes(event, base);
96
+ setSelectedItems(event, base);
97
97
  };
98
98
  const handleRangeSelect = (event, nodes) => {
99
- let base = models.selectedNodes.value.slice();
99
+ let base = models.selectedItems.value.slice();
100
100
  const {
101
101
  start,
102
102
  end
@@ -110,7 +110,7 @@ export const useTreeViewSelection = ({
110
110
  currentRangeSelection.current = range;
111
111
  let newSelected = base.concat(range);
112
112
  newSelected = newSelected.filter((id, i) => newSelected.indexOf(id) === i);
113
- setSelectedNodes(event, newSelected);
113
+ setSelectedItems(event, newSelected);
114
114
  };
115
115
  const selectRange = (event, nodes, stacked = false) => {
116
116
  if (params.disableSelection) {
@@ -135,21 +135,21 @@ export const useTreeViewSelection = ({
135
135
  }
136
136
  lastSelectionWasRange.current = true;
137
137
  };
138
- const rangeSelectToFirst = (event, nodeId) => {
138
+ const rangeSelectToFirst = (event, itemId) => {
139
139
  if (!lastSelectedNode.current) {
140
- lastSelectedNode.current = nodeId;
140
+ lastSelectedNode.current = itemId;
141
141
  }
142
- const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
142
+ const start = lastSelectionWasRange.current ? lastSelectedNode.current : itemId;
143
143
  instance.selectRange(event, {
144
144
  start,
145
145
  end: getFirstNode(instance)
146
146
  });
147
147
  };
148
- const rangeSelectToLast = (event, nodeId) => {
148
+ const rangeSelectToLast = (event, itemId) => {
149
149
  if (!lastSelectedNode.current) {
150
- lastSelectedNode.current = nodeId;
150
+ lastSelectedNode.current = itemId;
151
151
  }
152
- const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
152
+ const start = lastSelectionWasRange.current ? lastSelectedNode.current : itemId;
153
153
  instance.selectRange(event, {
154
154
  start,
155
155
  end: getLastNode(instance)
@@ -174,21 +174,21 @@ export const useTreeViewSelection = ({
174
174
  };
175
175
  };
176
176
  useTreeViewSelection.models = {
177
- selectedNodes: {
178
- getDefaultValue: params => params.defaultSelectedNodes
177
+ selectedItems: {
178
+ getDefaultValue: params => params.defaultSelectedItems
179
179
  }
180
180
  };
181
181
  const DEFAULT_SELECTED_NODES = [];
182
182
  useTreeViewSelection.getDefaultizedParams = params => _extends({}, params, {
183
183
  disableSelection: params.disableSelection ?? false,
184
184
  multiSelect: params.multiSelect ?? false,
185
- defaultSelectedNodes: params.defaultSelectedNodes ?? (params.multiSelect ? DEFAULT_SELECTED_NODES : null)
185
+ defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_NODES : null)
186
186
  });
187
187
  useTreeViewSelection.params = {
188
188
  disableSelection: true,
189
189
  multiSelect: true,
190
- defaultSelectedNodes: true,
191
- selectedNodes: true,
192
- onSelectedNodesChange: true,
193
- onNodeSelectionToggle: true
190
+ defaultSelectedItems: true,
191
+ selectedItems: true,
192
+ onSelectedItemsChange: true,
193
+ onItemSelectionToggle: true
194
194
  };
@@ -38,6 +38,7 @@ export const useTreeView = inParams => {
38
38
  });
39
39
  const rootPropsGetters = [];
40
40
  const contextValue = {
41
+ publicAPI,
41
42
  instance: instance
42
43
  };
43
44
  const runPlugin = plugin => {
@@ -60,47 +61,47 @@ export const useTreeView = inParams => {
60
61
  }
61
62
  };
62
63
  plugins.forEach(runPlugin);
63
- contextValue.runItemPlugins = ({
64
- props,
65
- ref
66
- }) => {
67
- let finalProps = props;
68
- let finalRef = ref;
69
- const itemWrappers = [];
64
+ contextValue.runItemPlugins = itemPluginProps => {
65
+ let finalRootRef = null;
66
+ let finalContentRef = null;
70
67
  plugins.forEach(plugin => {
71
68
  if (!plugin.itemPlugin) {
72
69
  return;
73
70
  }
74
71
  const itemPluginResponse = plugin.itemPlugin({
75
- props: finalProps,
76
- ref: finalRef
72
+ props: itemPluginProps,
73
+ rootRef: finalRootRef,
74
+ contentRef: finalContentRef
77
75
  });
78
- if (itemPluginResponse?.props) {
79
- finalProps = itemPluginResponse.props;
80
- }
81
- if (itemPluginResponse?.ref) {
82
- finalRef = itemPluginResponse.ref;
76
+ if (itemPluginResponse?.rootRef) {
77
+ finalRootRef = itemPluginResponse.rootRef;
83
78
  }
84
- if (itemPluginResponse?.wrapItem) {
85
- itemWrappers.push(itemPluginResponse.wrapItem);
79
+ if (itemPluginResponse?.contentRef) {
80
+ finalContentRef = itemPluginResponse.contentRef;
86
81
  }
87
82
  });
88
83
  return {
89
- props: finalProps,
90
- ref: finalRef,
91
- wrapItem: children => {
92
- let finalChildren = children;
93
- itemWrappers.forEach(itemWrapper => {
94
- finalChildren = itemWrapper(finalChildren);
95
- });
96
- return finalChildren;
97
- }
84
+ contentRef: finalContentRef,
85
+ rootRef: finalRootRef
98
86
  };
99
87
  };
88
+ const itemWrappers = plugins.map(plugin => plugin.wrapItem).filter(wrapItem => !!wrapItem);
89
+ contextValue.wrapItem = ({
90
+ itemId,
91
+ children
92
+ }) => {
93
+ let finalChildren = children;
94
+ itemWrappers.forEach(itemWrapper => {
95
+ finalChildren = itemWrapper({
96
+ itemId,
97
+ children: finalChildren
98
+ });
99
+ });
100
+ return finalChildren;
101
+ };
100
102
  const getRootProps = (otherHandlers = {}) => {
101
103
  const rootProps = _extends({
102
- role: 'tree',
103
- tabIndex: 0
104
+ role: 'tree'
104
105
  }, otherHandlers, {
105
106
  ref: handleRootRef
106
107
  });