@mui/x-tree-view 6.0.0-alpha.3 → 6.0.0-alpha.4

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 (265) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/TreeItem/TreeItem.js +18 -31
  3. package/TreeItem/useTreeItem.js +18 -27
  4. package/TreeView/TreeView.d.ts +4 -1
  5. package/TreeView/TreeView.js +65 -708
  6. package/TreeView/TreeView.types.d.ts +4 -147
  7. package/index.d.ts +1 -0
  8. package/index.js +3 -2
  9. package/{TreeView/descendants.d.ts → internals/TreeViewProvider/DescendantProvider.d.ts} +1 -5
  10. package/internals/TreeViewProvider/TreeViewContext.d.ts +7 -0
  11. package/{TreeView → internals/TreeViewProvider}/TreeViewContext.js +8 -18
  12. package/internals/TreeViewProvider/TreeViewProvider.d.ts +9 -0
  13. package/internals/TreeViewProvider/TreeViewProvider.js +21 -0
  14. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +18 -0
  15. package/internals/TreeViewProvider/index.d.ts +2 -0
  16. package/internals/TreeViewProvider/index.js +1 -0
  17. package/internals/TreeViewProvider/useTreeViewContext.d.ts +3 -0
  18. package/internals/TreeViewProvider/useTreeViewContext.js +3 -0
  19. package/internals/corePlugins/corePlugins.d.ts +7 -0
  20. package/internals/corePlugins/corePlugins.js +6 -0
  21. package/internals/corePlugins/index.d.ts +2 -0
  22. package/internals/corePlugins/index.js +1 -0
  23. package/internals/corePlugins/useTreeViewInstanceEvents/index.d.ts +2 -0
  24. package/internals/corePlugins/useTreeViewInstanceEvents/index.js +1 -0
  25. package/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.d.ts +8 -0
  26. package/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +35 -0
  27. package/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.d.ts +21 -0
  28. package/internals/hooks/useInstanceEventHandler.d.ts +15 -0
  29. package/internals/hooks/useInstanceEventHandler.js +82 -0
  30. package/internals/models/events.d.ts +9 -0
  31. package/internals/models/helpers.d.ts +13 -0
  32. package/internals/models/helpers.js +1 -0
  33. package/internals/models/index.d.ts +3 -0
  34. package/internals/models/index.js +3 -0
  35. package/internals/models/plugin.d.ts +69 -0
  36. package/internals/models/plugin.js +1 -0
  37. package/internals/models/treeView.d.ts +23 -0
  38. package/internals/models/treeView.js +1 -0
  39. package/internals/plugins/defaultPlugins.d.ts +10 -0
  40. package/internals/plugins/defaultPlugins.js +9 -0
  41. package/internals/plugins/index.d.ts +2 -0
  42. package/internals/plugins/index.js +1 -0
  43. package/internals/plugins/useTreeViewContextValueBuilder/index.d.ts +2 -0
  44. package/internals/plugins/useTreeViewContextValueBuilder/index.js +1 -0
  45. package/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.d.ts +3 -0
  46. package/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.js +24 -0
  47. package/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.d.ts +34 -0
  48. package/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.js +1 -0
  49. package/internals/plugins/useTreeViewExpansion/index.d.ts +2 -0
  50. package/internals/plugins/useTreeViewExpansion/index.js +1 -0
  51. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.d.ts +3 -0
  52. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +63 -0
  53. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +32 -0
  54. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.js +1 -0
  55. package/internals/plugins/useTreeViewFocus/index.d.ts +2 -0
  56. package/internals/plugins/useTreeViewFocus/index.js +1 -0
  57. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.d.ts +3 -0
  58. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +77 -0
  59. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +25 -0
  60. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.js +1 -0
  61. package/internals/plugins/useTreeViewKeyboardNavigation/index.d.ts +2 -0
  62. package/internals/plugins/useTreeViewKeyboardNavigation/index.js +1 -0
  63. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.d.ts +3 -0
  64. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +223 -0
  65. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +14 -0
  66. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.js +1 -0
  67. package/internals/plugins/useTreeViewNodes/index.d.ts +2 -0
  68. package/internals/plugins/useTreeViewNodes/index.js +1 -0
  69. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.d.ts +3 -0
  70. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +60 -0
  71. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.d.ts +27 -0
  72. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.js +1 -0
  73. package/internals/plugins/useTreeViewSelection/index.d.ts +2 -0
  74. package/internals/plugins/useTreeViewSelection/index.js +1 -0
  75. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.d.ts +3 -0
  76. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +172 -0
  77. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +49 -0
  78. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.js +1 -0
  79. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +17 -0
  80. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +55 -0
  81. package/internals/useTreeView/index.d.ts +2 -0
  82. package/internals/useTreeView/index.js +1 -0
  83. package/internals/useTreeView/useTreeView.d.ts +3 -0
  84. package/internals/useTreeView/useTreeView.js +65 -0
  85. package/internals/useTreeView/useTreeView.types.d.ts +20 -0
  86. package/internals/useTreeView/useTreeView.types.js +1 -0
  87. package/internals/useTreeView/useTreeView.utils.d.ts +8 -0
  88. package/internals/useTreeView/useTreeView.utils.js +43 -0
  89. package/internals/useTreeView/useTreeViewModels.d.ts +6 -0
  90. package/internals/useTreeView/useTreeViewModels.js +63 -0
  91. package/internals/utils/EventManager.d.ts +29 -0
  92. package/internals/utils/EventManager.js +69 -0
  93. package/internals/utils/cleanupTracking/CleanupTracking.d.ts +9 -0
  94. package/internals/utils/cleanupTracking/CleanupTracking.js +1 -0
  95. package/internals/utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking.d.ts +7 -0
  96. package/internals/utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking.js +18 -0
  97. package/internals/utils/cleanupTracking/TimerBasedCleanupTracking.d.ts +10 -0
  98. package/internals/utils/cleanupTracking/TimerBasedCleanupTracking.js +38 -0
  99. package/internals/utils/publishTreeViewEvent.d.ts +5 -0
  100. package/internals/utils/publishTreeViewEvent.js +3 -0
  101. package/legacy/TreeItem/TreeItem.js +21 -32
  102. package/legacy/TreeItem/useTreeItem.js +18 -27
  103. package/legacy/TreeView/TreeView.js +65 -766
  104. package/legacy/index.js +3 -2
  105. package/legacy/internals/TreeViewProvider/TreeViewContext.js +21 -0
  106. package/legacy/internals/TreeViewProvider/TreeViewProvider.js +19 -0
  107. package/legacy/internals/TreeViewProvider/TreeViewProvider.types.js +1 -0
  108. package/legacy/internals/TreeViewProvider/index.js +1 -0
  109. package/legacy/internals/TreeViewProvider/useTreeViewContext.js +5 -0
  110. package/legacy/internals/corePlugins/corePlugins.js +6 -0
  111. package/legacy/internals/corePlugins/index.js +1 -0
  112. package/legacy/internals/corePlugins/useTreeViewInstanceEvents/index.js +1 -0
  113. package/legacy/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +45 -0
  114. package/legacy/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.js +1 -0
  115. package/legacy/internals/hooks/useInstanceEventHandler.js +87 -0
  116. package/legacy/internals/models/events.js +1 -0
  117. package/legacy/internals/models/helpers.js +1 -0
  118. package/legacy/internals/models/index.js +3 -0
  119. package/legacy/internals/models/plugin.js +1 -0
  120. package/legacy/internals/models/treeView.js +1 -0
  121. package/legacy/internals/plugins/defaultPlugins.js +9 -0
  122. package/legacy/internals/plugins/index.js +1 -0
  123. package/legacy/internals/plugins/useTreeViewContextValueBuilder/index.js +1 -0
  124. package/legacy/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.js +25 -0
  125. package/legacy/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.js +1 -0
  126. package/legacy/internals/plugins/useTreeViewExpansion/index.js +1 -0
  127. package/legacy/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +66 -0
  128. package/legacy/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.js +1 -0
  129. package/legacy/internals/plugins/useTreeViewFocus/index.js +1 -0
  130. package/legacy/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +87 -0
  131. package/legacy/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.js +1 -0
  132. package/legacy/internals/plugins/useTreeViewKeyboardNavigation/index.js +1 -0
  133. package/legacy/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +226 -0
  134. package/legacy/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.js +1 -0
  135. package/legacy/internals/plugins/useTreeViewNodes/index.js +1 -0
  136. package/legacy/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +71 -0
  137. package/legacy/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.js +1 -0
  138. package/legacy/internals/plugins/useTreeViewSelection/index.js +1 -0
  139. package/legacy/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +188 -0
  140. package/legacy/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.js +1 -0
  141. package/legacy/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +55 -0
  142. package/legacy/internals/useTreeView/index.js +1 -0
  143. package/legacy/internals/useTreeView/useTreeView.js +71 -0
  144. package/legacy/internals/useTreeView/useTreeView.types.js +1 -0
  145. package/legacy/internals/useTreeView/useTreeView.utils.js +46 -0
  146. package/legacy/internals/useTreeView/useTreeViewModels.js +76 -0
  147. package/legacy/internals/utils/EventManager.js +91 -0
  148. package/legacy/internals/utils/cleanupTracking/CleanupTracking.js +1 -0
  149. package/legacy/internals/utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking.js +29 -0
  150. package/legacy/internals/utils/cleanupTracking/TimerBasedCleanupTracking.js +52 -0
  151. package/legacy/internals/utils/publishTreeViewEvent.js +3 -0
  152. package/modern/TreeItem/TreeItem.js +18 -31
  153. package/modern/TreeItem/useTreeItem.js +18 -27
  154. package/modern/TreeView/TreeView.js +65 -707
  155. package/modern/index.js +3 -2
  156. package/modern/{TreeView → internals/TreeViewProvider}/TreeViewContext.js +8 -18
  157. package/modern/internals/TreeViewProvider/TreeViewProvider.js +21 -0
  158. package/modern/internals/TreeViewProvider/TreeViewProvider.types.js +1 -0
  159. package/modern/internals/TreeViewProvider/index.js +1 -0
  160. package/modern/internals/TreeViewProvider/useTreeViewContext.js +3 -0
  161. package/modern/internals/corePlugins/corePlugins.js +6 -0
  162. package/modern/internals/corePlugins/index.js +1 -0
  163. package/modern/internals/corePlugins/useTreeViewInstanceEvents/index.js +1 -0
  164. package/modern/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +35 -0
  165. package/modern/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.js +1 -0
  166. package/modern/internals/hooks/useInstanceEventHandler.js +77 -0
  167. package/modern/internals/models/events.js +1 -0
  168. package/modern/internals/models/helpers.js +1 -0
  169. package/modern/internals/models/index.js +3 -0
  170. package/modern/internals/models/plugin.js +1 -0
  171. package/modern/internals/models/treeView.js +1 -0
  172. package/modern/internals/plugins/defaultPlugins.js +9 -0
  173. package/modern/internals/plugins/index.js +1 -0
  174. package/modern/internals/plugins/useTreeViewContextValueBuilder/index.js +1 -0
  175. package/modern/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.js +24 -0
  176. package/modern/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.js +1 -0
  177. package/modern/internals/plugins/useTreeViewExpansion/index.js +1 -0
  178. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +57 -0
  179. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.js +1 -0
  180. package/modern/internals/plugins/useTreeViewFocus/index.js +1 -0
  181. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +72 -0
  182. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.js +1 -0
  183. package/modern/internals/plugins/useTreeViewKeyboardNavigation/index.js +1 -0
  184. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +222 -0
  185. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.js +1 -0
  186. package/modern/internals/plugins/useTreeViewNodes/index.js +1 -0
  187. package/modern/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +60 -0
  188. package/modern/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.js +1 -0
  189. package/modern/internals/plugins/useTreeViewSelection/index.js +1 -0
  190. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +169 -0
  191. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.js +1 -0
  192. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +55 -0
  193. package/modern/internals/useTreeView/index.js +1 -0
  194. package/modern/internals/useTreeView/useTreeView.js +65 -0
  195. package/modern/internals/useTreeView/useTreeView.types.js +1 -0
  196. package/modern/internals/useTreeView/useTreeView.utils.js +43 -0
  197. package/modern/internals/useTreeView/useTreeViewModels.js +63 -0
  198. package/modern/internals/utils/EventManager.js +69 -0
  199. package/modern/internals/utils/cleanupTracking/CleanupTracking.js +1 -0
  200. package/modern/internals/utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking.js +18 -0
  201. package/modern/internals/utils/cleanupTracking/TimerBasedCleanupTracking.js +38 -0
  202. package/modern/internals/utils/publishTreeViewEvent.js +3 -0
  203. package/node/TreeItem/TreeItem.js +20 -33
  204. package/node/TreeItem/useTreeItem.js +18 -29
  205. package/node/TreeView/TreeView.js +65 -707
  206. package/node/index.js +14 -2
  207. package/node/{TreeView → internals/TreeViewProvider}/TreeViewContext.js +10 -19
  208. package/node/internals/TreeViewProvider/TreeViewProvider.js +29 -0
  209. package/node/internals/TreeViewProvider/index.js +12 -0
  210. package/node/internals/TreeViewProvider/useTreeViewContext.js +12 -0
  211. package/node/internals/corePlugins/corePlugins.js +13 -0
  212. package/node/internals/corePlugins/index.js +12 -0
  213. package/node/internals/corePlugins/useTreeViewInstanceEvents/index.js +12 -0
  214. package/node/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +44 -0
  215. package/node/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.js +5 -0
  216. package/node/internals/hooks/useInstanceEventHandler.js +88 -0
  217. package/node/internals/models/events.js +5 -0
  218. package/node/internals/models/helpers.js +5 -0
  219. package/node/internals/models/index.js +38 -0
  220. package/node/internals/models/plugin.js +5 -0
  221. package/node/internals/models/treeView.js +5 -0
  222. package/node/internals/plugins/defaultPlugins.js +16 -0
  223. package/node/internals/plugins/index.js +12 -0
  224. package/node/internals/plugins/useTreeViewContextValueBuilder/index.js +12 -0
  225. package/node/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.js +32 -0
  226. package/node/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.js +5 -0
  227. package/node/internals/plugins/useTreeViewExpansion/index.js +12 -0
  228. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +67 -0
  229. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.js +5 -0
  230. package/node/internals/plugins/useTreeViewFocus/index.js +12 -0
  231. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +82 -0
  232. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.js +5 -0
  233. package/node/internals/plugins/useTreeViewKeyboardNavigation/index.js +12 -0
  234. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +232 -0
  235. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.js +5 -0
  236. package/node/internals/plugins/useTreeViewNodes/index.js +12 -0
  237. package/node/internals/plugins/useTreeViewNodes/useTreeViewNodes.js +70 -0
  238. package/node/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.js +5 -0
  239. package/node/internals/plugins/useTreeViewSelection/index.js +12 -0
  240. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +179 -0
  241. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.js +5 -0
  242. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +62 -0
  243. package/node/internals/useTreeView/index.js +12 -0
  244. package/node/internals/useTreeView/useTreeView.js +75 -0
  245. package/node/internals/useTreeView/useTreeView.types.js +5 -0
  246. package/node/internals/useTreeView/useTreeView.utils.js +54 -0
  247. package/node/internals/useTreeView/useTreeViewModels.js +73 -0
  248. package/node/internals/utils/EventManager.js +76 -0
  249. package/node/internals/utils/cleanupTracking/CleanupTracking.js +5 -0
  250. package/node/internals/utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking.js +25 -0
  251. package/node/internals/utils/cleanupTracking/TimerBasedCleanupTracking.js +45 -0
  252. package/node/internals/utils/publishTreeViewEvent.js +10 -0
  253. package/package.json +1 -1
  254. package/themeAugmentation/props.d.ts +1 -1
  255. package/TreeView/TreeViewContext.d.ts +0 -6
  256. package/internals/models.d.ts +0 -1
  257. package/legacy/TreeView/TreeViewContext.js +0 -41
  258. /package/{TreeView/descendants.js → internals/TreeViewProvider/DescendantProvider.js} +0 -0
  259. /package/internals/{models.js → TreeViewProvider/TreeViewProvider.types.js} +0 -0
  260. /package/{legacy/internals/models.js → internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.js} +0 -0
  261. /package/{modern/internals/models.js → internals/models/events.js} +0 -0
  262. /package/legacy/{TreeView/descendants.js → internals/TreeViewProvider/DescendantProvider.js} +0 -0
  263. /package/modern/{TreeView/descendants.js → internals/TreeViewProvider/DescendantProvider.js} +0 -0
  264. /package/node/{TreeView/descendants.js → internals/TreeViewProvider/DescendantProvider.js} +0 -0
  265. /package/node/internals/{models.js → TreeViewProvider/TreeViewProvider.types.js} +0 -0
@@ -0,0 +1,60 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import useEventCallback from '@mui/utils/useEventCallback';
4
+ import { populateInstance } from '../../useTreeView/useTreeView.utils';
5
+ import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent';
6
+ export const useTreeViewNodes = ({
7
+ instance,
8
+ params
9
+ }) => {
10
+ const nodeMap = React.useRef({});
11
+ const getNode = React.useCallback(nodeId => nodeMap.current[nodeId], []);
12
+ const insertNode = React.useCallback(node => {
13
+ nodeMap.current[node.id] = node;
14
+ }, []);
15
+ const removeNode = React.useCallback(nodeId => {
16
+ const newMap = _extends({}, nodeMap.current);
17
+ delete newMap[nodeId];
18
+ nodeMap.current = newMap;
19
+ publishTreeViewEvent(instance, 'removeNode', {
20
+ id: nodeId
21
+ });
22
+ }, [instance]);
23
+ const isNodeDisabled = React.useCallback(nodeId => {
24
+ if (nodeId == null) {
25
+ return false;
26
+ }
27
+ let node = instance.getNode(nodeId);
28
+
29
+ // This can be called before the node has been added to the node map.
30
+ if (!node) {
31
+ return false;
32
+ }
33
+ if (node.disabled) {
34
+ return true;
35
+ }
36
+ while (node.parentId != null) {
37
+ node = instance.getNode(node.parentId);
38
+ if (node.disabled) {
39
+ return true;
40
+ }
41
+ }
42
+ return false;
43
+ }, [instance]);
44
+ const getChildrenIds = useEventCallback(nodeId => Object.values(nodeMap.current).filter(node => node.parentId === nodeId).sort((a, b) => a.index - b.index).map(child => child.id));
45
+ const getNavigableChildrenIds = nodeId => {
46
+ let childrenIds = instance.getChildrenIds(nodeId);
47
+ if (!params.disabledItemsFocusable) {
48
+ childrenIds = childrenIds.filter(node => !instance.isNodeDisabled(node));
49
+ }
50
+ return childrenIds;
51
+ };
52
+ populateInstance(instance, {
53
+ getNode,
54
+ updateNode: insertNode,
55
+ removeNode,
56
+ getChildrenIds,
57
+ getNavigableChildrenIds,
58
+ isNodeDisabled
59
+ });
60
+ };
@@ -0,0 +1 @@
1
+ export { useTreeViewSelection } from './useTreeViewSelection';
@@ -0,0 +1,169 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { populateInstance, getNextNode, getFirstNode, getLastNode } from '../../useTreeView/useTreeView.utils';
4
+ import { findOrderInTremauxTree } from './useTreeViewSelection.utils';
5
+ export const useTreeViewSelection = ({
6
+ instance,
7
+ params,
8
+ models
9
+ }) => {
10
+ const lastSelectedNode = React.useRef(null);
11
+ const lastSelectionWasRange = React.useRef(false);
12
+ const currentRangeSelection = React.useRef([]);
13
+ const isNodeSelected = nodeId => Array.isArray(models.selected.value) ? models.selected.value.indexOf(nodeId) !== -1 : models.selected.value === nodeId;
14
+ const selectNode = (event, nodeId, multiple = false) => {
15
+ if (params.disableSelection) {
16
+ return;
17
+ }
18
+ if (multiple) {
19
+ if (Array.isArray(models.selected.value)) {
20
+ let newSelected;
21
+ if (models.selected.value.indexOf(nodeId) !== -1) {
22
+ newSelected = models.selected.value.filter(id => id !== nodeId);
23
+ } else {
24
+ newSelected = [nodeId].concat(models.selected.value);
25
+ }
26
+ if (params.onNodeSelect) {
27
+ params.onNodeSelect(event, newSelected);
28
+ }
29
+ models.selected.setValue(newSelected);
30
+ }
31
+ } else {
32
+ const newSelected = params.multiSelect ? [nodeId] : nodeId;
33
+ if (params.onNodeSelect) {
34
+ params.onNodeSelect(event, newSelected);
35
+ }
36
+ models.selected.setValue(newSelected);
37
+ }
38
+ lastSelectedNode.current = nodeId;
39
+ lastSelectionWasRange.current = false;
40
+ currentRangeSelection.current = [];
41
+ };
42
+ const getNodesInRange = (nodeAId, nodeBId) => {
43
+ const [first, last] = findOrderInTremauxTree(instance, nodeAId, nodeBId);
44
+ const nodes = [first];
45
+ let current = first;
46
+ while (current !== last) {
47
+ current = getNextNode(instance, current);
48
+ nodes.push(current);
49
+ }
50
+ return nodes;
51
+ };
52
+ const handleRangeArrowSelect = (event, nodes) => {
53
+ let base = models.selected.value.slice();
54
+ const {
55
+ start,
56
+ next,
57
+ current
58
+ } = nodes;
59
+ if (!next || !current) {
60
+ return;
61
+ }
62
+ if (currentRangeSelection.current.indexOf(current) === -1) {
63
+ currentRangeSelection.current = [];
64
+ }
65
+ if (lastSelectionWasRange.current) {
66
+ if (currentRangeSelection.current.indexOf(next) !== -1) {
67
+ base = base.filter(id => id === start || id !== current);
68
+ currentRangeSelection.current = currentRangeSelection.current.filter(id => id === start || id !== current);
69
+ } else {
70
+ base.push(next);
71
+ currentRangeSelection.current.push(next);
72
+ }
73
+ } else {
74
+ base.push(next);
75
+ currentRangeSelection.current.push(current, next);
76
+ }
77
+ if (params.onNodeSelect) {
78
+ params.onNodeSelect(event, base);
79
+ }
80
+ models.selected.setValue(base);
81
+ };
82
+ const handleRangeSelect = (event, nodes) => {
83
+ let base = models.selected.value.slice();
84
+ const {
85
+ start,
86
+ end
87
+ } = nodes;
88
+ // If last selection was a range selection ignore nodes that were selected.
89
+ if (lastSelectionWasRange.current) {
90
+ base = base.filter(id => currentRangeSelection.current.indexOf(id) === -1);
91
+ }
92
+ let range = getNodesInRange(start, end);
93
+ range = range.filter(node => !instance.isNodeDisabled(node));
94
+ currentRangeSelection.current = range;
95
+ let newSelected = base.concat(range);
96
+ newSelected = newSelected.filter((id, i) => newSelected.indexOf(id) === i);
97
+ if (params.onNodeSelect) {
98
+ params.onNodeSelect(event, newSelected);
99
+ }
100
+ models.selected.setValue(newSelected);
101
+ };
102
+ const selectRange = (event, nodes, stacked = false) => {
103
+ if (params.disableSelection) {
104
+ return;
105
+ }
106
+ const {
107
+ start = lastSelectedNode.current,
108
+ end,
109
+ current
110
+ } = nodes;
111
+ if (stacked) {
112
+ handleRangeArrowSelect(event, {
113
+ start,
114
+ next: end,
115
+ current
116
+ });
117
+ } else if (start != null && end != null) {
118
+ handleRangeSelect(event, {
119
+ start,
120
+ end
121
+ });
122
+ }
123
+ lastSelectionWasRange.current = true;
124
+ };
125
+ const rangeSelectToFirst = (event, nodeId) => {
126
+ if (!lastSelectedNode.current) {
127
+ lastSelectedNode.current = nodeId;
128
+ }
129
+ const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
130
+ instance.selectRange(event, {
131
+ start,
132
+ end: getFirstNode(instance)
133
+ });
134
+ };
135
+ const rangeSelectToLast = (event, nodeId) => {
136
+ if (!lastSelectedNode.current) {
137
+ lastSelectedNode.current = nodeId;
138
+ }
139
+ const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
140
+ instance.selectRange(event, {
141
+ start,
142
+ end: getLastNode(instance)
143
+ });
144
+ };
145
+ populateInstance(instance, {
146
+ isNodeSelected,
147
+ selectNode,
148
+ selectRange,
149
+ rangeSelectToLast,
150
+ rangeSelectToFirst
151
+ });
152
+ return {
153
+ getRootProps: () => ({
154
+ 'aria-multiselectable': params.multiSelect
155
+ })
156
+ };
157
+ };
158
+ useTreeViewSelection.models = {
159
+ selected: {
160
+ controlledProp: 'selected',
161
+ defaultProp: 'defaultSelected'
162
+ }
163
+ };
164
+ const DEFAULT_SELECTED = [];
165
+ useTreeViewSelection.getDefaultizedParams = params => _extends({}, params, {
166
+ disableSelection: params.disableSelection ?? false,
167
+ multiSelect: params.multiSelect ?? false,
168
+ defaultSelected: params.defaultSelected ?? (params.multiSelect ? DEFAULT_SELECTED : null)
169
+ });
@@ -0,0 +1,55 @@
1
+ /**
2
+ * This is used to determine the start and end of a selection range so
3
+ * we can get the nodes between the two border nodes.
4
+ *
5
+ * It finds the nodes' common ancestor using
6
+ * a naive implementation of a lowest common ancestor algorithm
7
+ * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
8
+ * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB
9
+ * so we can compare their indexes to work out which node comes first in a depth first search.
10
+ * (https://en.wikipedia.org/wiki/Depth-first_search)
11
+ *
12
+ * Another way to put it is which node is shallower in a trémaux tree
13
+ * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
14
+ */
15
+ export const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
16
+ if (nodeAId === nodeBId) {
17
+ return [nodeAId, nodeBId];
18
+ }
19
+ const nodeA = instance.getNode(nodeAId);
20
+ const nodeB = instance.getNode(nodeBId);
21
+ if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) {
22
+ return nodeB.parentId === nodeA.id ? [nodeA.id, nodeB.id] : [nodeB.id, nodeA.id];
23
+ }
24
+ const aFamily = [nodeA.id];
25
+ const bFamily = [nodeB.id];
26
+ let aAncestor = nodeA.parentId;
27
+ let bAncestor = nodeB.parentId;
28
+ let aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
29
+ let bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
30
+ let continueA = true;
31
+ let continueB = true;
32
+ while (!bAncestorIsCommon && !aAncestorIsCommon) {
33
+ if (continueA) {
34
+ aFamily.push(aAncestor);
35
+ aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
36
+ continueA = aAncestor !== null;
37
+ if (!aAncestorIsCommon && continueA) {
38
+ aAncestor = instance.getNode(aAncestor).parentId;
39
+ }
40
+ }
41
+ if (continueB && !aAncestorIsCommon) {
42
+ bFamily.push(bAncestor);
43
+ bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
44
+ continueB = bAncestor !== null;
45
+ if (!bAncestorIsCommon && continueB) {
46
+ bAncestor = instance.getNode(bAncestor).parentId;
47
+ }
48
+ }
49
+ }
50
+ const commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor;
51
+ const ancestorFamily = instance.getChildrenIds(commonAncestor);
52
+ const aSide = aFamily[aFamily.indexOf(commonAncestor) - 1];
53
+ const bSide = bFamily[bFamily.indexOf(commonAncestor) - 1];
54
+ return ancestorFamily.indexOf(aSide) < ancestorFamily.indexOf(bSide) ? [nodeAId, nodeBId] : [nodeBId, nodeAId];
55
+ };
@@ -0,0 +1 @@
1
+ export { useTreeView } from './useTreeView';
@@ -0,0 +1,65 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import useForkRef from '@mui/utils/useForkRef';
4
+ import { DEFAULT_TREE_VIEW_CONTEXT_VALUE } from '../TreeViewProvider/TreeViewContext';
5
+ import { useTreeViewModels } from './useTreeViewModels';
6
+ import { TREE_VIEW_CORE_PLUGINS } from '../corePlugins';
7
+ export const useTreeView = inParams => {
8
+ const plugins = [...TREE_VIEW_CORE_PLUGINS, ...inParams.plugins];
9
+ const params = plugins.reduce((acc, plugin) => {
10
+ if (plugin.getDefaultizedParams) {
11
+ return plugin.getDefaultizedParams(acc);
12
+ }
13
+ return acc;
14
+ }, inParams);
15
+ const models = useTreeViewModels(plugins, params);
16
+ const instanceRef = React.useRef({});
17
+ const instance = instanceRef.current;
18
+ const innerRootRef = React.useRef(null);
19
+ const handleRootRef = useForkRef(innerRootRef, inParams.rootRef);
20
+ const [state, setState] = React.useState(() => {
21
+ const temp = {};
22
+ plugins.forEach(plugin => {
23
+ if (plugin.getInitialState) {
24
+ Object.assign(temp, plugin.getInitialState(params));
25
+ }
26
+ });
27
+ return temp;
28
+ });
29
+ const rootPropsGetters = [];
30
+ let contextValue = DEFAULT_TREE_VIEW_CONTEXT_VALUE;
31
+ const runPlugin = plugin => {
32
+ const pluginResponse = plugin({
33
+ instance,
34
+ params,
35
+ state,
36
+ setState,
37
+ rootRef: innerRootRef,
38
+ models
39
+ }) || {};
40
+ if (pluginResponse.getRootProps) {
41
+ rootPropsGetters.push(pluginResponse.getRootProps);
42
+ }
43
+ if (pluginResponse.contextValue) {
44
+ contextValue = pluginResponse.contextValue;
45
+ }
46
+ };
47
+ plugins.forEach(runPlugin);
48
+ const getRootProps = (otherHandlers = {}) => {
49
+ const rootProps = _extends({
50
+ role: 'tree',
51
+ tabIndex: 0
52
+ }, otherHandlers, {
53
+ ref: handleRootRef
54
+ });
55
+ rootPropsGetters.forEach(rootPropsGetter => {
56
+ Object.assign(rootProps, rootPropsGetter(otherHandlers));
57
+ });
58
+ return rootProps;
59
+ };
60
+ return {
61
+ getRootProps,
62
+ rootRef: handleRootRef,
63
+ contextValue
64
+ };
65
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ export const getPreviousNode = (instance, nodeId) => {
2
+ const node = instance.getNode(nodeId);
3
+ const siblings = instance.getNavigableChildrenIds(node.parentId);
4
+ const nodeIndex = siblings.indexOf(nodeId);
5
+ if (nodeIndex === 0) {
6
+ return node.parentId;
7
+ }
8
+ let currentNode = siblings[nodeIndex - 1];
9
+ while (instance.isNodeExpanded(currentNode) && instance.getNavigableChildrenIds(currentNode).length > 0) {
10
+ currentNode = instance.getNavigableChildrenIds(currentNode).pop();
11
+ }
12
+ return currentNode;
13
+ };
14
+ export const getNextNode = (instance, nodeId) => {
15
+ // If expanded get first child
16
+ if (instance.isNodeExpanded(nodeId) && instance.getNavigableChildrenIds(nodeId).length > 0) {
17
+ return instance.getNavigableChildrenIds(nodeId)[0];
18
+ }
19
+ let node = instance.getNode(nodeId);
20
+ while (node != null) {
21
+ // Try to get next sibling
22
+ const siblings = instance.getNavigableChildrenIds(node.parentId);
23
+ const nextSibling = siblings[siblings.indexOf(node.id) + 1];
24
+ if (nextSibling) {
25
+ return nextSibling;
26
+ }
27
+
28
+ // If the sibling does not exist, go up a level to the parent and try again.
29
+ node = instance.getNode(node.parentId);
30
+ }
31
+ return null;
32
+ };
33
+ export const getLastNode = instance => {
34
+ let lastNode = instance.getNavigableChildrenIds(null).pop();
35
+ while (instance.isNodeExpanded(lastNode)) {
36
+ lastNode = instance.getNavigableChildrenIds(lastNode).pop();
37
+ }
38
+ return lastNode;
39
+ };
40
+ export const getFirstNode = instance => instance.getNavigableChildrenIds(null)[0];
41
+ export const populateInstance = (instance, methods) => {
42
+ Object.assign(instance, methods);
43
+ };
@@ -0,0 +1,63 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ /**
4
+ * Implements the same behavior as `useControlled` but for several models.
5
+ * The controlled models are never stored in the state and the state is only updated if the model is not controlled.
6
+ */
7
+ export const useTreeViewModels = (plugins, props) => {
8
+ const modelsRef = React.useRef({});
9
+ const [modelsState, setModelsState] = React.useState(() => {
10
+ const initialState = {};
11
+ plugins.forEach(plugin => {
12
+ if (plugin.models) {
13
+ Object.entries(plugin.models).forEach(([modelName, model]) => {
14
+ modelsRef.current[modelName] = {
15
+ controlledProp: model.controlledProp,
16
+ defaultProp: model.defaultProp,
17
+ isControlled: props[model.controlledProp] !== undefined
18
+ };
19
+ initialState[modelName] = props[model.defaultProp];
20
+ });
21
+ }
22
+ });
23
+ return initialState;
24
+ });
25
+ const models = Object.fromEntries(Object.entries(modelsRef.current).map(([modelName, model]) => {
26
+ const value = model.isControlled ? props[model.controlledProp] : modelsState[modelName];
27
+ return [modelName, {
28
+ value,
29
+ setValue: newValue => {
30
+ if (!model.isControlled) {
31
+ setModelsState(prevState => _extends({}, prevState, {
32
+ [modelName]: newValue
33
+ }));
34
+ }
35
+ }
36
+ }];
37
+ }));
38
+
39
+ // We know that `modelsRef` do not vary across renders.
40
+ /* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */
41
+ if (process.env.NODE_ENV !== 'production') {
42
+ Object.entries(modelsRef.current).forEach(([modelName, model]) => {
43
+ const controlled = props[model.controlledProp];
44
+ const defaultProp = props[model.defaultProp];
45
+ React.useEffect(() => {
46
+ if (model.isControlled !== (controlled !== undefined)) {
47
+ console.error([`MUI: A component is changing the ${model.isControlled ? '' : 'un'}controlled ${modelName} state of TreeView to be ${model.isControlled ? 'un' : ''}controlled.`, 'Elements should not switch from uncontrolled to controlled (or vice versa).', `Decide between using a controlled or uncontrolled ${modelName} ` + 'element for the lifetime of the component.', "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", 'More info: https://fb.me/react-controlled-components'].join('\n'));
48
+ }
49
+ }, [controlled]);
50
+ const {
51
+ current: defaultValue
52
+ } = React.useRef(defaultProp);
53
+ React.useEffect(() => {
54
+ if (!model.isControlled && defaultValue !== defaultProp) {
55
+ console.error([`MUI: A component is changing the default ${modelName} state of an uncontrolled TreeView after being initialized. ` + `To suppress this warning opt to use a controlled TreeView.`].join('\n'));
56
+ }
57
+ }, [JSON.stringify(defaultValue)]);
58
+ });
59
+ }
60
+ /* eslint-enable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */
61
+
62
+ return models;
63
+ };
@@ -0,0 +1,69 @@
1
+ // Used https://gist.github.com/mudge/5830382 as a starting point.
2
+ // See https://github.com/browserify/events/blob/master/events.js for
3
+ // the Node.js (https://nodejs.org/api/events.html) polyfill used by webpack.
4
+ export class EventManager {
5
+ constructor() {
6
+ this.maxListeners = 20;
7
+ this.warnOnce = false;
8
+ this.events = {};
9
+ }
10
+ on(eventName, listener, options = {}) {
11
+ let collection = this.events[eventName];
12
+ if (!collection) {
13
+ collection = {
14
+ highPriority: new Map(),
15
+ regular: new Map()
16
+ };
17
+ this.events[eventName] = collection;
18
+ }
19
+ if (options.isFirst) {
20
+ collection.highPriority.set(listener, true);
21
+ } else {
22
+ collection.regular.set(listener, true);
23
+ }
24
+ if (process.env.NODE_ENV !== 'production') {
25
+ const collectionSize = collection.highPriority.size + collection.regular.size;
26
+ if (collectionSize > this.maxListeners && !this.warnOnce) {
27
+ this.warnOnce = true;
28
+ console.warn([`Possible EventEmitter memory leak detected. ${collectionSize} ${eventName} listeners added.`].join('\n'));
29
+ }
30
+ }
31
+ }
32
+ removeListener(eventName, listener) {
33
+ if (this.events[eventName]) {
34
+ this.events[eventName].regular.delete(listener);
35
+ this.events[eventName].highPriority.delete(listener);
36
+ }
37
+ }
38
+ removeAllListeners() {
39
+ this.events = {};
40
+ }
41
+ emit(eventName, ...args) {
42
+ const collection = this.events[eventName];
43
+ if (!collection) {
44
+ return;
45
+ }
46
+ const highPriorityListeners = Array.from(collection.highPriority.keys());
47
+ const regularListeners = Array.from(collection.regular.keys());
48
+ for (let i = highPriorityListeners.length - 1; i >= 0; i -= 1) {
49
+ const listener = highPriorityListeners[i];
50
+ if (collection.highPriority.has(listener)) {
51
+ listener.apply(this, args);
52
+ }
53
+ }
54
+ for (let i = 0; i < regularListeners.length; i += 1) {
55
+ const listener = regularListeners[i];
56
+ if (collection.regular.has(listener)) {
57
+ listener.apply(this, args);
58
+ }
59
+ }
60
+ }
61
+ once(eventName, listener) {
62
+ // eslint-disable-next-line consistent-this
63
+ const that = this;
64
+ this.on(eventName, function oneTimeListener(...args) {
65
+ that.removeListener(eventName, oneTimeListener);
66
+ listener.apply(that, args);
67
+ });
68
+ }
69
+ }
@@ -0,0 +1,18 @@
1
+ export class FinalizationRegistryBasedCleanupTracking {
2
+ constructor() {
3
+ this.registry = new FinalizationRegistry(unsubscribe => {
4
+ if (typeof unsubscribe === 'function') {
5
+ unsubscribe();
6
+ }
7
+ });
8
+ }
9
+ register(object, unsubscribe, unregisterToken) {
10
+ this.registry.register(object, unsubscribe, unregisterToken);
11
+ }
12
+ unregister(unregisterToken) {
13
+ this.registry.unregister(unregisterToken);
14
+ }
15
+
16
+ // eslint-disable-next-line class-methods-use-this
17
+ reset() {}
18
+ }
@@ -0,0 +1,38 @@
1
+ // If no effect ran after this amount of time, we assume that the render was not committed by React
2
+ const CLEANUP_TIMER_LOOP_MILLIS = 1000;
3
+ export class TimerBasedCleanupTracking {
4
+ constructor(timeout = CLEANUP_TIMER_LOOP_MILLIS) {
5
+ this.timeouts = new Map();
6
+ this.cleanupTimeout = CLEANUP_TIMER_LOOP_MILLIS;
7
+ this.cleanupTimeout = timeout;
8
+ }
9
+ register(object, unsubscribe, unregisterToken) {
10
+ if (!this.timeouts) {
11
+ this.timeouts = new Map();
12
+ }
13
+ const timeout = setTimeout(() => {
14
+ if (typeof unsubscribe === 'function') {
15
+ unsubscribe();
16
+ }
17
+ this.timeouts.delete(unregisterToken.cleanupToken);
18
+ }, this.cleanupTimeout);
19
+ this.timeouts.set(unregisterToken.cleanupToken, timeout);
20
+ }
21
+ unregister(unregisterToken) {
22
+ const timeout = this.timeouts.get(unregisterToken.cleanupToken);
23
+ if (timeout) {
24
+ this.timeouts.delete(unregisterToken.cleanupToken);
25
+ clearTimeout(timeout);
26
+ }
27
+ }
28
+ reset() {
29
+ if (this.timeouts) {
30
+ this.timeouts.forEach((value, key) => {
31
+ this.unregister({
32
+ cleanupToken: key
33
+ });
34
+ });
35
+ this.timeouts = undefined;
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,3 @@
1
+ export const publishTreeViewEvent = (instance, eventName, params) => {
2
+ instance.$$publishEvent(eventName, params);
3
+ };