@mui/x-tree-view 7.1.1 → 7.2.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 (77) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/RichTreeView/RichTreeView.types.d.ts +3 -3
  3. package/TreeItem/TreeItem.js +1 -1
  4. package/TreeItem2/TreeItem2.d.ts +5 -1
  5. package/TreeItem2/TreeItem2.js +0 -1
  6. package/index.js +1 -1
  7. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +16 -0
  8. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +57 -0
  9. package/internals/TreeViewProvider/TreeViewContext.d.ts +2 -0
  10. package/internals/TreeViewProvider/TreeViewProvider.js +2 -3
  11. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +3 -1
  12. package/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +7 -8
  13. package/internals/models/plugin.d.ts +13 -5
  14. package/internals/models/treeView.d.ts +1 -2
  15. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +15 -15
  16. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +25 -26
  17. package/internals/plugins/useTreeViewId/useTreeViewId.js +5 -7
  18. package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +1 -1
  19. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -50
  20. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +19 -15
  21. package/internals/plugins/useTreeViewItems/useTreeViewItems.utils.d.ts +4 -0
  22. package/internals/plugins/useTreeViewItems/useTreeViewItems.utils.js +8 -0
  23. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +66 -41
  24. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +3 -2
  25. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +20 -18
  26. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +11 -22
  27. package/internals/useTreeView/useTreeView.js +21 -3
  28. package/internals/utils/tree.d.ts +8 -0
  29. package/internals/utils/tree.js +137 -0
  30. package/modern/TreeItem/TreeItem.js +1 -1
  31. package/modern/TreeItem2/TreeItem2.js +0 -1
  32. package/modern/index.js +1 -1
  33. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +57 -0
  34. package/modern/internals/TreeViewProvider/TreeViewProvider.js +2 -3
  35. package/modern/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +7 -8
  36. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +15 -15
  37. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +25 -26
  38. package/modern/internals/plugins/useTreeViewId/useTreeViewId.js +5 -7
  39. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -50
  40. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.utils.js +8 -0
  41. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +66 -41
  42. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +20 -18
  43. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +11 -22
  44. package/modern/internals/useTreeView/useTreeView.js +21 -3
  45. package/modern/internals/utils/tree.js +137 -0
  46. package/modern/useTreeItem2/useTreeItem2.js +1 -1
  47. package/node/TreeItem/TreeItem.js +1 -1
  48. package/node/TreeItem2/TreeItem2.js +0 -1
  49. package/node/index.js +1 -1
  50. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +67 -0
  51. package/node/internals/TreeViewProvider/TreeViewProvider.js +2 -3
  52. package/node/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.js +7 -8
  53. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +15 -15
  54. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +25 -26
  55. package/node/internals/plugins/useTreeViewId/useTreeViewId.js +5 -7
  56. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -50
  57. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.utils.js +15 -0
  58. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +66 -41
  59. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +20 -18
  60. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +11 -22
  61. package/node/internals/useTreeView/useTreeView.js +21 -3
  62. package/node/internals/utils/tree.js +148 -0
  63. package/node/useTreeItem2/useTreeItem2.js +1 -1
  64. package/package.json +1 -1
  65. package/useTreeItem2/useTreeItem2.js +1 -1
  66. package/internals/TreeViewProvider/DescendantProvider.d.ts +0 -38
  67. package/internals/TreeViewProvider/DescendantProvider.js +0 -176
  68. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +0 -17
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +0 -55
  70. package/internals/useTreeView/useTreeView.utils.d.ts +0 -9
  71. package/internals/useTreeView/useTreeView.utils.js +0 -46
  72. package/modern/internals/TreeViewProvider/DescendantProvider.js +0 -176
  73. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +0 -55
  74. package/modern/internals/useTreeView/useTreeView.utils.js +0 -46
  75. package/node/internals/TreeViewProvider/DescendantProvider.js +0 -185
  76. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +0 -62
  77. package/node/internals/useTreeView/useTreeView.utils.js +0 -58
@@ -1,86 +1,98 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { populateInstance, populatePublicAPI } from '../../useTreeView/useTreeView.utils';
4
3
  import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent';
4
+ import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './useTreeViewItems.utils';
5
5
  const updateItemsState = ({
6
6
  items,
7
7
  isItemDisabled,
8
8
  getItemLabel,
9
9
  getItemId
10
10
  }) => {
11
- const nodeMap = {};
11
+ const itemMetaMap = {};
12
12
  const itemMap = {};
13
- const processItem = (item, index, parentId) => {
13
+ const itemOrderedChildrenIds = {
14
+ [TREE_VIEW_ROOT_PARENT_ID]: []
15
+ };
16
+ const processItem = (item, parentId) => {
14
17
  const id = getItemId ? getItemId(item) : item.id;
15
18
  if (id == null) {
16
19
  throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', 'An item was provided without id in the `items` prop:', JSON.stringify(item)].join('\n'));
17
20
  }
18
- if (nodeMap[id] != null) {
21
+ if (itemMetaMap[id] != null) {
19
22
  throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', `Two items were provided with the same id in the \`items\` prop: "${id}"`].join('\n'));
20
23
  }
21
24
  const label = getItemLabel ? getItemLabel(item) : item.label;
22
25
  if (label == null) {
23
26
  throw new Error(['MUI X: The Tree View component requires all items to have a `label` property.', 'Alternatively, you can use the `getItemLabel` prop to specify a custom label for each item.', 'An item was provided without label in the `items` prop:', JSON.stringify(item)].join('\n'));
24
27
  }
25
- nodeMap[id] = {
28
+ itemMetaMap[id] = {
26
29
  id,
27
30
  label,
28
- index,
29
31
  parentId,
30
32
  idAttribute: undefined,
31
33
  expandable: !!item.children?.length,
32
34
  disabled: isItemDisabled ? isItemDisabled(item) : false
33
35
  };
34
36
  itemMap[id] = item;
35
- return {
36
- id,
37
- children: item.children?.map((child, childIndex) => processItem(child, childIndex, id))
38
- };
37
+ itemOrderedChildrenIds[id] = [];
38
+ const parentIdWithDefault = parentId ?? TREE_VIEW_ROOT_PARENT_ID;
39
+ if (!itemOrderedChildrenIds[parentIdWithDefault]) {
40
+ itemOrderedChildrenIds[parentIdWithDefault] = [];
41
+ }
42
+ itemOrderedChildrenIds[parentIdWithDefault].push(id);
43
+ item.children?.forEach(child => processItem(child, id));
39
44
  };
40
- const nodeTree = items.map((item, itemIndex) => processItem(item, itemIndex, null));
45
+ items.forEach(item => processItem(item, null));
46
+ const itemChildrenIndexes = {};
47
+ Object.keys(itemOrderedChildrenIds).forEach(parentId => {
48
+ itemChildrenIndexes[parentId] = buildSiblingIndexes(itemOrderedChildrenIds[parentId]);
49
+ });
41
50
  return {
42
- nodeMap,
43
- nodeTree,
44
- itemMap
51
+ itemMetaMap,
52
+ itemMap,
53
+ itemOrderedChildrenIds,
54
+ itemChildrenIndexes
45
55
  };
46
56
  };
47
57
  export const useTreeViewItems = ({
48
58
  instance,
49
- publicAPI,
50
59
  params,
51
60
  state,
52
61
  setState
53
62
  }) => {
54
- const getNode = React.useCallback(itemId => state.items.nodeMap[itemId], [state.items.nodeMap]);
63
+ const getItemMeta = React.useCallback(itemId => state.items.itemMetaMap[itemId], [state.items.itemMetaMap]);
55
64
  const getItem = React.useCallback(itemId => state.items.itemMap[itemId], [state.items.itemMap]);
56
65
  const isItemDisabled = React.useCallback(itemId => {
57
66
  if (itemId == null) {
58
67
  return false;
59
68
  }
60
- let node = instance.getNode(itemId);
69
+ let itemMeta = instance.getItemMeta(itemId);
61
70
 
62
71
  // This can be called before the item has been added to the item map.
63
- if (!node) {
72
+ if (!itemMeta) {
64
73
  return false;
65
74
  }
66
- if (node.disabled) {
75
+ if (itemMeta.disabled) {
67
76
  return true;
68
77
  }
69
- while (node.parentId != null) {
70
- node = instance.getNode(node.parentId);
71
- if (node.disabled) {
78
+ while (itemMeta.parentId != null) {
79
+ itemMeta = instance.getItemMeta(itemMeta.parentId);
80
+ if (itemMeta.disabled) {
72
81
  return true;
73
82
  }
74
83
  }
75
84
  return false;
76
85
  }, [instance]);
77
- const getChildrenIds = React.useCallback(itemId => Object.values(state.items.nodeMap).filter(item => item.parentId === itemId).sort((a, b) => a.index - b.index).map(child => child.id), [state.items.nodeMap]);
78
- const getNavigableChildrenIds = itemId => {
79
- let childrenIds = instance.getChildrenIds(itemId);
80
- if (!params.disabledItemsFocusable) {
81
- childrenIds = childrenIds.filter(item => !instance.isItemDisabled(item));
86
+ const getItemIndex = React.useCallback(itemId => {
87
+ const parentId = instance.getItemMeta(itemId).parentId ?? TREE_VIEW_ROOT_PARENT_ID;
88
+ return state.items.itemChildrenIndexes[parentId][itemId];
89
+ }, [instance, state.items.itemChildrenIndexes]);
90
+ const getItemOrderedChildrenIds = React.useCallback(itemId => state.items.itemOrderedChildrenIds[itemId ?? TREE_VIEW_ROOT_PARENT_ID] ?? [], [state.items.itemOrderedChildrenIds]);
91
+ const isItemNavigable = itemId => {
92
+ if (params.disabledItemsFocusable) {
93
+ return true;
82
94
  }
83
- return childrenIds;
95
+ return !instance.isItemDisabled(itemId);
84
96
  };
85
97
  const areItemUpdatesPreventedRef = React.useRef(false);
86
98
  const preventItemUpdates = React.useCallback(() => {
@@ -98,8 +110,8 @@ export const useTreeViewItems = ({
98
110
  getItemId: params.getItemId,
99
111
  getItemLabel: params.getItemLabel
100
112
  });
101
- Object.values(prevState.items.nodeMap).forEach(item => {
102
- if (!newState.nodeMap[item.id]) {
113
+ Object.values(prevState.items.itemMetaMap).forEach(item => {
114
+ if (!newState.itemMetaMap[item.id]) {
103
115
  publishTreeViewEvent(instance, 'removeItem', {
104
116
  id: item.id
105
117
  });
@@ -111,34 +123,32 @@ export const useTreeViewItems = ({
111
123
  });
112
124
  }, [instance, setState, params.items, params.isItemDisabled, params.getItemId, params.getItemLabel]);
113
125
  const getItemsToRender = () => {
114
- const getPropsFromItemId = ({
115
- id,
116
- children
117
- }) => {
118
- const item = state.items.nodeMap[id];
126
+ const getPropsFromItemId = id => {
127
+ const item = state.items.itemMetaMap[id];
119
128
  return {
120
129
  label: item.label,
121
130
  itemId: item.id,
122
131
  id: item.idAttribute,
123
- children: children?.map(getPropsFromItemId)
132
+ children: state.items.itemOrderedChildrenIds[id].map(getPropsFromItemId)
124
133
  };
125
134
  };
126
- return state.items.nodeTree.map(getPropsFromItemId);
135
+ return state.items.itemOrderedChildrenIds[TREE_VIEW_ROOT_PARENT_ID].map(getPropsFromItemId);
127
136
  };
128
- populateInstance(instance, {
129
- getNode,
130
- getItem,
131
- getItemsToRender,
132
- getChildrenIds,
133
- getNavigableChildrenIds,
134
- isItemDisabled,
135
- preventItemUpdates,
136
- areItemUpdatesPrevented
137
- });
138
- populatePublicAPI(publicAPI, {
139
- getItem
140
- });
141
137
  return {
138
+ publicAPI: {
139
+ getItem
140
+ },
141
+ instance: {
142
+ getItemMeta,
143
+ getItem,
144
+ getItemsToRender,
145
+ getItemIndex,
146
+ getItemOrderedChildrenIds,
147
+ isItemDisabled,
148
+ isItemNavigable,
149
+ preventItemUpdates,
150
+ areItemUpdatesPrevented
151
+ },
142
152
  contextValue: {
143
153
  disabledItemsFocusable: params.disabledItemsFocusable
144
154
  }
@@ -0,0 +1,8 @@
1
+ export const TREE_VIEW_ROOT_PARENT_ID = '__TREE_VIEW_ROOT_PARENT_ID__';
2
+ export const buildSiblingIndexes = siblings => {
3
+ const siblingsIndexLookup = {};
4
+ siblings.forEach((childId, index) => {
5
+ siblingsIndexLookup[childId] = index;
6
+ });
7
+ return siblingsIndexLookup;
8
+ };
@@ -2,10 +2,11 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import useEventCallback from '@mui/utils/useEventCallback';
4
4
  import useForkRef from '@mui/utils/useForkRef';
5
- import { populateInstance } from '../../useTreeView/useTreeView.utils';
5
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
6
6
  import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent';
7
7
  import { useTreeViewContext } from '../../TreeViewProvider/useTreeViewContext';
8
- import { DescendantProvider, useDescendant } from '../../TreeViewProvider/DescendantProvider';
8
+ import { TreeViewChildrenItemContext, TreeViewChildrenItemProvider } from '../../TreeViewProvider/TreeViewChildrenItemProvider';
9
+ import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from '../useTreeViewItems/useTreeViewItems.utils';
9
10
  import { jsx as _jsx } from "react/jsx-runtime";
10
11
  export const useTreeViewJSXItems = ({
11
12
  instance,
@@ -14,12 +15,12 @@ export const useTreeViewJSXItems = ({
14
15
  instance.preventItemUpdates();
15
16
  const insertJSXItem = useEventCallback(item => {
16
17
  setState(prevState => {
17
- if (prevState.items.nodeMap[item.id] != null) {
18
+ if (prevState.items.itemMetaMap[item.id] != null) {
18
19
  throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', `Two items were provided with the same id in the \`items\` prop: "${item.id}"`].join('\n'));
19
20
  }
20
21
  return _extends({}, prevState, {
21
22
  items: _extends({}, prevState.items, {
22
- nodeMap: _extends({}, prevState.items.nodeMap, {
23
+ itemMetaMap: _extends({}, prevState.items.itemMetaMap, {
23
24
  [item.id]: item
24
25
  }),
25
26
  // For `SimpleTreeView`, we don't have a proper `item` object, so we create a very basic one.
@@ -33,15 +34,28 @@ export const useTreeViewJSXItems = ({
33
34
  });
34
35
  });
35
36
  });
37
+ const setJSXItemsOrderedChildrenIds = (parentId, orderedChildrenIds) => {
38
+ const parentIdWithDefault = parentId ?? TREE_VIEW_ROOT_PARENT_ID;
39
+ setState(prevState => _extends({}, prevState, {
40
+ items: _extends({}, prevState.items, {
41
+ itemOrderedChildrenIds: _extends({}, prevState.items.itemOrderedChildrenIds, {
42
+ [parentIdWithDefault]: orderedChildrenIds
43
+ }),
44
+ itemChildrenIndexes: _extends({}, prevState.items.itemChildrenIndexes, {
45
+ [parentIdWithDefault]: buildSiblingIndexes(orderedChildrenIds)
46
+ })
47
+ })
48
+ }));
49
+ };
36
50
  const removeJSXItem = useEventCallback(itemId => {
37
51
  setState(prevState => {
38
- const newNodeMap = _extends({}, prevState.items.nodeMap);
52
+ const newItemMetaMap = _extends({}, prevState.items.itemMetaMap);
39
53
  const newItemMap = _extends({}, prevState.items.itemMap);
40
- delete newNodeMap[itemId];
54
+ delete newItemMetaMap[itemId];
41
55
  delete newItemMap[itemId];
42
56
  return _extends({}, prevState, {
43
57
  items: _extends({}, prevState.items, {
44
- nodeMap: newNodeMap,
58
+ itemMetaMap: newItemMetaMap,
45
59
  itemMap: newItemMap
46
60
  })
47
61
  });
@@ -63,17 +77,23 @@ export const useTreeViewJSXItems = ({
63
77
  });
64
78
  };
65
79
  });
66
- populateInstance(instance, {
67
- insertJSXItem,
68
- removeJSXItem,
69
- mapFirstCharFromJSX
70
- });
80
+ return {
81
+ instance: {
82
+ insertJSXItem,
83
+ removeJSXItem,
84
+ setJSXItemsOrderedChildrenIds,
85
+ mapFirstCharFromJSX
86
+ }
87
+ };
71
88
  };
72
89
  const useTreeViewJSXItemsItemPlugin = ({
73
90
  props,
74
91
  rootRef,
75
92
  contentRef
76
93
  }) => {
94
+ const {
95
+ instance
96
+ } = useTreeViewContext();
77
97
  const {
78
98
  children,
79
99
  disabled = false,
@@ -81,9 +101,15 @@ const useTreeViewJSXItemsItemPlugin = ({
81
101
  itemId,
82
102
  id
83
103
  } = props;
104
+ const parentContext = React.useContext(TreeViewChildrenItemContext);
105
+ if (parentContext == null) {
106
+ throw new Error(['MUI X: Could not find the Tree View Children Item context.', 'It looks like you rendered your component outside of a SimpleTreeView parent component.', 'This can also happen if you are bundling multiple versions of the Tree View.'].join('\n'));
107
+ }
84
108
  const {
85
- instance
86
- } = useTreeViewContext();
109
+ registerChild,
110
+ unregisterChild,
111
+ parentId
112
+ } = parentContext;
87
113
  const isExpandable = reactChildren => {
88
114
  if (Array.isArray(reactChildren)) {
89
115
  return reactChildren.length > 0 && reactChildren.some(isExpandable);
@@ -91,33 +117,27 @@ const useTreeViewJSXItemsItemPlugin = ({
91
117
  return Boolean(reactChildren);
92
118
  };
93
119
  const expandable = isExpandable(children);
94
- const [treeItemElement, setTreeItemElement] = React.useState(null);
95
120
  const pluginContentRef = React.useRef(null);
96
- const handleRootRef = useForkRef(setTreeItemElement, rootRef);
97
121
  const handleContentRef = useForkRef(pluginContentRef, contentRef);
98
- const descendant = React.useMemo(() => ({
99
- element: treeItemElement,
100
- id: itemId
101
- }), [itemId, treeItemElement]);
102
- const {
103
- index,
104
- parentId
105
- } = useDescendant(descendant);
122
+
123
+ // Prevent any flashing
124
+ useEnhancedEffect(() => {
125
+ const idAttributeWithDefault = instance.getTreeItemIdAttribute(itemId, id);
126
+ registerChild(idAttributeWithDefault, itemId);
127
+ return () => {
128
+ unregisterChild(idAttributeWithDefault);
129
+ };
130
+ }, [instance, registerChild, unregisterChild, itemId, id]);
106
131
  React.useEffect(() => {
107
- // On the first render a item's index will be -1. We want to wait for the real index.
108
- if (index !== -1) {
109
- instance.insertJSXItem({
110
- id: itemId,
111
- idAttribute: id,
112
- index,
113
- parentId,
114
- expandable,
115
- disabled
116
- });
117
- return () => instance.removeJSXItem(itemId);
118
- }
119
- return undefined;
120
- }, [instance, parentId, index, itemId, expandable, disabled, id]);
132
+ instance.insertJSXItem({
133
+ id: itemId,
134
+ idAttribute: id,
135
+ parentId,
136
+ expandable,
137
+ disabled
138
+ });
139
+ return () => instance.removeJSXItem(itemId);
140
+ }, [instance, parentId, itemId, expandable, disabled, id]);
121
141
  React.useEffect(() => {
122
142
  if (label) {
123
143
  return instance.mapFirstCharFromJSX(itemId, (pluginContentRef.current?.textContent ?? '').substring(0, 1).toLowerCase());
@@ -126,15 +146,20 @@ const useTreeViewJSXItemsItemPlugin = ({
126
146
  }, [instance, itemId, label]);
127
147
  return {
128
148
  contentRef: handleContentRef,
129
- rootRef: handleRootRef
149
+ rootRef
130
150
  };
131
151
  };
132
152
  useTreeViewJSXItems.itemPlugin = useTreeViewJSXItemsItemPlugin;
133
153
  useTreeViewJSXItems.wrapItem = ({
134
154
  children,
135
155
  itemId
136
- }) => /*#__PURE__*/_jsx(DescendantProvider, {
137
- id: itemId,
156
+ }) => /*#__PURE__*/_jsx(TreeViewChildrenItemProvider, {
157
+ itemId: itemId,
158
+ children: children
159
+ });
160
+ useTreeViewJSXItems.wrapRoot = ({
161
+ children
162
+ }) => /*#__PURE__*/_jsx(TreeViewChildrenItemProvider, {
138
163
  children: children
139
164
  });
140
165
  useTreeViewJSXItems.params = {};
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { useTheme } from '@mui/material/styles';
3
3
  import useEventCallback from '@mui/utils/useEventCallback';
4
- import { getFirstItem, getLastItem, getNextItem, getPreviousItem, populateInstance } from '../../useTreeView/useTreeView.utils';
4
+ import { getFirstNavigableItem, getLastNavigableItem, getNextNavigableItem, getPreviousNavigableItem } from '../../utils/tree';
5
5
  function isPrintableCharacter(string) {
6
6
  return !!string && string.length === 1 && !!string.match(/\S/);
7
7
  }
@@ -29,12 +29,12 @@ export const useTreeViewKeyboardNavigation = ({
29
29
  return;
30
30
  }
31
31
  const newFirstCharMap = {};
32
- const processItem = node => {
33
- newFirstCharMap[node.id] = node.label.substring(0, 1).toLowerCase();
32
+ const processItem = item => {
33
+ newFirstCharMap[item.id] = item.label.substring(0, 1).toLowerCase();
34
34
  };
35
- Object.values(state.items.nodeMap).forEach(processItem);
35
+ Object.values(state.items.itemMetaMap).forEach(processItem);
36
36
  firstCharMap.current = newFirstCharMap;
37
- }, [state.items.nodeMap, params.getItemId, instance]);
37
+ }, [state.items.itemMetaMap, params.getItemId, instance]);
38
38
  const getFirstMatchingItem = (itemId, firstChar) => {
39
39
  let start;
40
40
  let index;
@@ -43,7 +43,7 @@ export const useTreeViewKeyboardNavigation = ({
43
43
  const firstChars = [];
44
44
  // This really only works since the ids are strings
45
45
  Object.keys(firstCharMap.current).forEach(mapItemId => {
46
- const map = instance.getNode(mapItemId);
46
+ const map = instance.getItemMeta(mapItemId);
47
47
  const visible = map.parentId ? instance.isItemExpanded(map.parentId) : true;
48
48
  const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isItemDisabled(mapItemId);
49
49
  if (visible && !shouldBeSkipped) {
@@ -128,7 +128,7 @@ export const useTreeViewKeyboardNavigation = ({
128
128
  // Focus the next focusable item
129
129
  case key === 'ArrowDown':
130
130
  {
131
- const nextItem = getNextItem(instance, itemId);
131
+ const nextItem = getNextNavigableItem(instance, itemId);
132
132
  if (nextItem) {
133
133
  event.preventDefault();
134
134
  instance.focusItem(event, nextItem);
@@ -148,7 +148,7 @@ export const useTreeViewKeyboardNavigation = ({
148
148
  // Focuses the previous focusable item
149
149
  case key === 'ArrowUp':
150
150
  {
151
- const previousItem = getPreviousItem(instance, itemId);
151
+ const previousItem = getPreviousNavigableItem(instance, itemId);
152
152
  if (previousItem) {
153
153
  event.preventDefault();
154
154
  instance.focusItem(event, previousItem);
@@ -170,7 +170,7 @@ export const useTreeViewKeyboardNavigation = ({
170
170
  case key === 'ArrowRight' && !isRTL || key === 'ArrowLeft' && isRTL:
171
171
  {
172
172
  if (instance.isItemExpanded(itemId)) {
173
- const nextItemId = getNextItem(instance, itemId);
173
+ const nextItemId = getNextNavigableItem(instance, itemId);
174
174
  if (nextItemId) {
175
175
  instance.focusItem(event, nextItemId);
176
176
  event.preventDefault();
@@ -190,7 +190,7 @@ export const useTreeViewKeyboardNavigation = ({
190
190
  instance.toggleItemExpansion(event, itemId);
191
191
  event.preventDefault();
192
192
  } else {
193
- const parent = instance.getNode(itemId).parentId;
193
+ const parent = instance.getItemMeta(itemId).parentId;
194
194
  if (parent) {
195
195
  instance.focusItem(event, parent);
196
196
  event.preventDefault();
@@ -202,7 +202,7 @@ export const useTreeViewKeyboardNavigation = ({
202
202
  // Focuses the first item in the tree
203
203
  case key === 'Home':
204
204
  {
205
- instance.focusItem(event, getFirstItem(instance));
205
+ instance.focusItem(event, getFirstNavigableItem(instance));
206
206
 
207
207
  // Multi select behavior when pressing Ctrl + Shift + Home
208
208
  // Selects the focused item and all items up to the first item.
@@ -216,7 +216,7 @@ export const useTreeViewKeyboardNavigation = ({
216
216
  // Focuses the last item in the tree
217
217
  case key === 'End':
218
218
  {
219
- instance.focusItem(event, getLastItem(instance));
219
+ instance.focusItem(event, getLastNavigableItem(instance));
220
220
 
221
221
  // Multi select behavior when pressing Ctrl + Shirt + End
222
222
  // Selects the focused item and all the items down to the last item.
@@ -240,8 +240,8 @@ export const useTreeViewKeyboardNavigation = ({
240
240
  case key === 'a' && ctrlPressed && params.multiSelect && !params.disableSelection:
241
241
  {
242
242
  instance.selectRange(event, {
243
- start: getFirstItem(instance),
244
- end: getLastItem(instance)
243
+ start: getFirstNavigableItem(instance),
244
+ end: getLastNavigableItem(instance)
245
245
  });
246
246
  event.preventDefault();
247
247
  break;
@@ -260,9 +260,11 @@ export const useTreeViewKeyboardNavigation = ({
260
260
  }
261
261
  }
262
262
  };
263
- populateInstance(instance, {
264
- updateFirstCharMap,
265
- handleItemKeyDown
266
- });
263
+ return {
264
+ instance: {
265
+ updateFirstCharMap,
266
+ handleItemKeyDown
267
+ }
268
+ };
267
269
  };
268
270
  useTreeViewKeyboardNavigation.params = {};
@@ -1,7 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { populateInstance, getNextItem, getFirstItem, getLastItem } from '../../useTreeView/useTreeView.utils';
4
- import { findOrderInTremauxTree } from './useTreeViewSelection.utils';
3
+ import { getFirstNavigableItem, getLastNavigableItem, getNavigableItemsInRange } from '../../utils/tree';
5
4
  export const useTreeViewSelection = ({
6
5
  instance,
7
6
  params,
@@ -58,16 +57,6 @@ export const useTreeViewSelection = ({
58
57
  lastSelectionWasRange.current = false;
59
58
  currentRangeSelection.current = [];
60
59
  };
61
- const getItemsInRange = (itemAId, itemBId) => {
62
- const [first, last] = findOrderInTremauxTree(instance, itemAId, itemBId);
63
- const items = [first];
64
- let current = first;
65
- while (current !== last) {
66
- current = getNextItem(instance, current);
67
- items.push(current);
68
- }
69
- return items;
70
- };
71
60
  const handleRangeArrowSelect = (event, items) => {
72
61
  let base = models.selectedItems.value.slice();
73
62
  const {
@@ -105,7 +94,7 @@ export const useTreeViewSelection = ({
105
94
  if (lastSelectionWasRange.current) {
106
95
  base = base.filter(id => currentRangeSelection.current.indexOf(id) === -1);
107
96
  }
108
- let range = getItemsInRange(start, end);
97
+ let range = getNavigableItemsInRange(instance, start, end);
109
98
  range = range.filter(item => !instance.isItemDisabled(item));
110
99
  currentRangeSelection.current = range;
111
100
  let newSelected = base.concat(range);
@@ -142,7 +131,7 @@ export const useTreeViewSelection = ({
142
131
  const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId;
143
132
  instance.selectRange(event, {
144
133
  start,
145
- end: getFirstItem(instance)
134
+ end: getFirstNavigableItem(instance)
146
135
  });
147
136
  };
148
137
  const rangeSelectToLast = (event, itemId) => {
@@ -152,20 +141,20 @@ export const useTreeViewSelection = ({
152
141
  const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId;
153
142
  instance.selectRange(event, {
154
143
  start,
155
- end: getLastItem(instance)
144
+ end: getLastNavigableItem(instance)
156
145
  });
157
146
  };
158
- populateInstance(instance, {
159
- isItemSelected,
160
- selectItem,
161
- selectRange,
162
- rangeSelectToLast,
163
- rangeSelectToFirst
164
- });
165
147
  return {
166
148
  getRootProps: () => ({
167
149
  'aria-multiselectable': params.multiSelect
168
150
  }),
151
+ instance: {
152
+ isItemSelected,
153
+ selectItem,
154
+ selectRange,
155
+ rangeSelectToLast,
156
+ rangeSelectToFirst
157
+ },
169
158
  contextValue: {
170
159
  selection: {
171
160
  multiSelect: params.multiSelect
@@ -39,12 +39,12 @@ export const useTreeView = inParams => {
39
39
  const rootPropsGetters = [];
40
40
  const contextValue = {
41
41
  publicAPI,
42
- instance: instance
42
+ instance: instance,
43
+ rootRef: innerRootRef
43
44
  };
44
45
  const runPlugin = plugin => {
45
46
  const pluginResponse = plugin({
46
47
  instance,
47
- publicAPI,
48
48
  params,
49
49
  slots: params.slots,
50
50
  slotProps: params.slotProps,
@@ -52,10 +52,16 @@ export const useTreeView = inParams => {
52
52
  setState,
53
53
  rootRef: innerRootRef,
54
54
  models
55
- }) || {};
55
+ });
56
56
  if (pluginResponse.getRootProps) {
57
57
  rootPropsGetters.push(pluginResponse.getRootProps);
58
58
  }
59
+ if (pluginResponse.publicAPI) {
60
+ Object.assign(publicAPI, pluginResponse.publicAPI);
61
+ }
62
+ if (pluginResponse.instance) {
63
+ Object.assign(instance, pluginResponse.instance);
64
+ }
59
65
  if (pluginResponse.contextValue) {
60
66
  Object.assign(contextValue, pluginResponse.contextValue);
61
67
  }
@@ -99,6 +105,18 @@ export const useTreeView = inParams => {
99
105
  });
100
106
  return finalChildren;
101
107
  };
108
+ const rootWrappers = plugins.map(plugin => plugin.wrapRoot).filter(wrapRoot => !!wrapRoot);
109
+ contextValue.wrapRoot = ({
110
+ children
111
+ }) => {
112
+ let finalChildren = children;
113
+ rootWrappers.forEach(rootWrapper => {
114
+ finalChildren = rootWrapper({
115
+ children: finalChildren
116
+ });
117
+ });
118
+ return finalChildren;
119
+ };
102
120
  const getRootProps = (otherHandlers = {}) => {
103
121
  const rootProps = _extends({
104
122
  role: 'tree'