@mui/x-tree-view 6.0.0-alpha.3 → 6.0.0-beta.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 (265) hide show
  1. package/CHANGELOG.md +167 -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 +89 -0
  59. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +27 -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 +99 -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 +84 -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 +94 -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,27 @@
1
+ import { TreeViewNode, DefaultizedProps, TreeViewPluginSignature } from '../../models';
2
+ export interface UseTreeViewNodesInstance {
3
+ getNode: (nodeId: string) => TreeViewNode;
4
+ updateNode: (node: TreeViewNode) => void;
5
+ removeNode: (nodeId: string) => void;
6
+ getChildrenIds: (nodeId: string | null) => string[];
7
+ getNavigableChildrenIds: (nodeId: string | null) => string[];
8
+ isNodeDisabled: (nodeId: string | null) => nodeId is string;
9
+ }
10
+ export interface UseTreeViewNodesParameters {
11
+ /**
12
+ * If `true`, will allow focus on disabled items.
13
+ * @default false
14
+ */
15
+ disabledItemsFocusable?: boolean;
16
+ }
17
+ export type UseTreeViewNodesDefaultizedParameters = DefaultizedProps<UseTreeViewNodesParameters, 'disabledItemsFocusable'>;
18
+ interface UseTreeViewNodesEventLookup {
19
+ removeNode: {
20
+ params: {
21
+ id: string;
22
+ };
23
+ };
24
+ }
25
+ export type UseTreeViewNodesSignature = TreeViewPluginSignature<UseTreeViewNodesParameters, UseTreeViewNodesDefaultizedParameters, UseTreeViewNodesInstance, UseTreeViewNodesEventLookup, {}, never, [
26
+ ]>;
27
+ export {};
@@ -0,0 +1,2 @@
1
+ export { useTreeViewSelection } from './useTreeViewSelection';
2
+ export type { UseTreeViewSelectionSignature, UseTreeViewSelectionParameters, UseTreeViewSelectionDefaultizedParameters, } from './useTreeViewSelection.types';
@@ -0,0 +1 @@
1
+ export { useTreeViewSelection } from './useTreeViewSelection';
@@ -0,0 +1,3 @@
1
+ import { TreeViewPlugin } from '../../models';
2
+ import { UseTreeViewSelectionSignature } from './useTreeViewSelection.types';
3
+ export declare const useTreeViewSelection: TreeViewPlugin<UseTreeViewSelectionSignature<any>>;
@@ -0,0 +1,172 @@
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 => {
166
+ var _params$disableSelect, _params$multiSelect, _params$defaultSelect;
167
+ return _extends({}, params, {
168
+ disableSelection: (_params$disableSelect = params.disableSelection) != null ? _params$disableSelect : false,
169
+ multiSelect: (_params$multiSelect = params.multiSelect) != null ? _params$multiSelect : false,
170
+ defaultSelected: (_params$defaultSelect = params.defaultSelected) != null ? _params$defaultSelect : params.multiSelect ? DEFAULT_SELECTED : null
171
+ });
172
+ };
@@ -0,0 +1,49 @@
1
+ import * as React from 'react';
2
+ import type { DefaultizedProps, TreeViewItemRange, TreeViewPluginSignature } from '../../models';
3
+ import { UseTreeViewNodesSignature } from '../useTreeViewNodes';
4
+ import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
5
+ export interface UseTreeViewSelectionInstance {
6
+ isNodeSelected: (nodeId: string) => boolean;
7
+ selectNode: (event: React.SyntheticEvent, nodeId: string, multiple?: boolean) => void;
8
+ selectRange: (event: React.SyntheticEvent, nodes: TreeViewItemRange, stacked?: boolean) => void;
9
+ rangeSelectToFirst: (event: React.KeyboardEvent<HTMLUListElement>, nodeId: string) => void;
10
+ rangeSelectToLast: (event: React.KeyboardEvent<HTMLUListElement>, nodeId: string) => void;
11
+ }
12
+ type TreeViewSelectionValue<Multiple extends boolean | undefined> = Multiple extends true ? string[] : string | null;
13
+ export interface UseTreeViewSelectionParameters<Multiple extends boolean | undefined> {
14
+ /**
15
+ * If `true` selection is disabled.
16
+ * @default false
17
+ */
18
+ disableSelection?: boolean;
19
+ /**
20
+ * Selected node ids. (Uncontrolled)
21
+ * When `multiSelect` is true this takes an array of strings; when false (default) a string.
22
+ * @default []
23
+ */
24
+ defaultSelected?: TreeViewSelectionValue<Multiple>;
25
+ /**
26
+ * Selected node ids. (Controlled)
27
+ * When `multiSelect` is true this takes an array of strings; when false (default) a string.
28
+ */
29
+ selected?: TreeViewSelectionValue<Multiple>;
30
+ /**
31
+ * If true `ctrl` and `shift` will trigger multiselect.
32
+ * @default false
33
+ */
34
+ multiSelect?: Multiple;
35
+ /**
36
+ * Callback fired when tree items are selected/unselected.
37
+ * @param {React.SyntheticEvent} event The event source of the callback
38
+ * @param {string[] | string} nodeIds Ids of the selected nodes. When `multiSelect` is true
39
+ * this is an array of strings; when false (default) a string.
40
+ */
41
+ onNodeSelect?: (event: React.SyntheticEvent, nodeIds: Exclude<TreeViewSelectionValue<Multiple>, null>) => void;
42
+ }
43
+ export type UseTreeViewSelectionDefaultizedParameters<Multiple extends boolean> = DefaultizedProps<UseTreeViewSelectionParameters<Multiple>, 'disableSelection' | 'defaultSelected' | 'multiSelect'>;
44
+ export type UseTreeViewSelectionSignature<Multiple extends boolean | undefined> = TreeViewPluginSignature<UseTreeViewSelectionParameters<Multiple>, UseTreeViewSelectionDefaultizedParameters<Multiple extends undefined ? false : Multiple>, UseTreeViewSelectionInstance, {}, {}, 'selected', [
45
+ UseTreeViewNodesSignature,
46
+ UseTreeViewExpansionSignature,
47
+ UseTreeViewNodesSignature
48
+ ]>;
49
+ export {};
@@ -0,0 +1,17 @@
1
+ import { TreeViewInstance } from '../../models';
2
+ import { UseTreeViewNodesSignature } from '../useTreeViewNodes';
3
+ /**
4
+ * This is used to determine the start and end of a selection range so
5
+ * we can get the nodes between the two border nodes.
6
+ *
7
+ * It finds the nodes' common ancestor using
8
+ * a naive implementation of a lowest common ancestor algorithm
9
+ * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
10
+ * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB
11
+ * so we can compare their indexes to work out which node comes first in a depth first search.
12
+ * (https://en.wikipedia.org/wiki/Depth-first_search)
13
+ *
14
+ * Another way to put it is which node is shallower in a trémaux tree
15
+ * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
16
+ */
17
+ export declare const findOrderInTremauxTree: (instance: TreeViewInstance<[UseTreeViewNodesSignature]>, nodeAId: string, nodeBId: string) => string[];
@@ -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,2 @@
1
+ export { useTreeView } from './useTreeView';
2
+ export type { UseTreeViewParameters, UseTreeViewDefaultizedParameters } from './useTreeView.types';
@@ -0,0 +1 @@
1
+ export { useTreeView } from './useTreeView';
@@ -0,0 +1,3 @@
1
+ import { TreeViewAnyPluginSignature, TreeViewPlugin, ConvertPluginsIntoSignatures } from '../models';
2
+ import { UseTreeViewParameters, UseTreeViewReturnValue } from './useTreeView.types';
3
+ export declare const useTreeView: <Plugins extends readonly TreeViewPlugin<TreeViewAnyPluginSignature>[]>(inParams: UseTreeViewParameters<Plugins>) => UseTreeViewReturnValue<ConvertPluginsIntoSignatures<Plugins>>;
@@ -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,20 @@
1
+ import * as React from 'react';
2
+ import { EventHandlers } from '@mui/base/utils';
3
+ import type { TreeViewContextValue } from '../TreeViewProvider';
4
+ import { TreeViewAnyPluginSignature, TreeViewPlugin, ConvertPluginsIntoSignatures, MergePluginsProperty } from '../models';
5
+ export type UseTreeViewParameters<TPlugins extends readonly TreeViewPlugin<TreeViewAnyPluginSignature>[]> = {
6
+ rootRef?: React.Ref<HTMLUListElement> | undefined;
7
+ plugins: TPlugins;
8
+ } & MergePluginsProperty<ConvertPluginsIntoSignatures<TPlugins>, 'params'>;
9
+ export type UseTreeViewDefaultizedParameters<TPlugins extends readonly TreeViewPlugin<TreeViewAnyPluginSignature>[]> = {
10
+ rootRef?: React.Ref<HTMLUListElement> | undefined;
11
+ plugins: TPlugins;
12
+ } & MergePluginsProperty<ConvertPluginsIntoSignatures<TPlugins>, 'defaultizedParams'>;
13
+ export interface UseTreeViewRootSlotProps extends Pick<React.HTMLAttributes<HTMLUListElement>, 'onFocus' | 'onBlur' | 'onKeyDown' | 'id' | 'aria-activedescendant' | 'aria-multiselectable' | 'role' | 'tabIndex'> {
14
+ ref: React.Ref<HTMLUListElement>;
15
+ }
16
+ export interface UseTreeViewReturnValue<TPlugins extends readonly TreeViewAnyPluginSignature[]> {
17
+ getRootProps: <TOther extends EventHandlers = {}>(otherHandlers?: TOther) => UseTreeViewRootSlotProps;
18
+ rootRef: React.RefCallback<HTMLUListElement> | null;
19
+ contextValue: TreeViewContextValue<TPlugins>;
20
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { TreeViewAnyPluginSignature, TreeViewInstance, TreeViewUsedInstance } from '../models';
2
+ import type { UseTreeViewExpansionSignature } from '../plugins/useTreeViewExpansion';
3
+ import type { UseTreeViewNodesSignature } from '../plugins/useTreeViewNodes';
4
+ export declare const getPreviousNode: (instance: TreeViewInstance<[UseTreeViewNodesSignature, UseTreeViewExpansionSignature]>, nodeId: string) => string | null;
5
+ export declare const getNextNode: (instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewNodesSignature]>, nodeId: string) => string | null;
6
+ export declare const getLastNode: (instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewNodesSignature]>) => string;
7
+ export declare const getFirstNode: (instance: TreeViewInstance<[UseTreeViewNodesSignature]>) => string;
8
+ export declare const populateInstance: <T extends TreeViewAnyPluginSignature>(instance: TreeViewUsedInstance<T>, methods: T["instance"]) => void;
@@ -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,6 @@
1
+ import { TreeViewAnyPluginSignature, TreeViewPlugin, ConvertPluginsIntoSignatures, MergePluginsProperty } from '../models';
2
+ /**
3
+ * Implements the same behavior as `useControlled` but for several models.
4
+ * The controlled models are never stored in the state and the state is only updated if the model is not controlled.
5
+ */
6
+ export declare const useTreeViewModels: <TPlugins extends readonly TreeViewPlugin<TreeViewAnyPluginSignature>[]>(plugins: TPlugins, props: MergePluginsProperty<ConvertPluginsIntoSignatures<TPlugins>, "defaultizedParams">) => MergePluginsProperty<ConvertPluginsIntoSignatures<TPlugins>, "models">;
@@ -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,29 @@
1
+ export type EventListener = (...args: any[]) => void;
2
+ export interface EventListenerOptions {
3
+ isFirst?: boolean;
4
+ }
5
+ interface EventListenerCollection {
6
+ /**
7
+ * List of listeners to run before the others
8
+ * They are run in the opposite order of the registration order
9
+ */
10
+ highPriority: Map<EventListener, true>;
11
+ /**
12
+ * List of events to run after the high priority listeners
13
+ * They are run in the registration order
14
+ */
15
+ regular: Map<EventListener, true>;
16
+ }
17
+ export declare class EventManager {
18
+ maxListeners: number;
19
+ warnOnce: boolean;
20
+ events: {
21
+ [eventName: string]: EventListenerCollection;
22
+ };
23
+ on(eventName: string, listener: EventListener, options?: EventListenerOptions): void;
24
+ removeListener(eventName: string, listener: EventListener): void;
25
+ removeAllListeners(): void;
26
+ emit(eventName: string, ...args: any[]): void;
27
+ once(eventName: string, listener: EventListener): void;
28
+ }
29
+ export {};