@mui/x-tree-view 7.1.1 → 7.3.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 +211 -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 +31 -28
  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 +73 -48
  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 +31 -28
  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 +73 -48
  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 +31 -28
  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 +73 -48
  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
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.useTreeViewItems = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var React = _interopRequireWildcard(require("react"));
10
- var _useTreeView = require("../../useTreeView/useTreeView.utils");
11
10
  var _publishTreeViewEvent = require("../../utils/publishTreeViewEvent");
11
+ var _useTreeViewItems = require("./useTreeViewItems.utils");
12
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
14
  const updateItemsState = ({
@@ -17,79 +17,91 @@ const updateItemsState = ({
17
17
  getItemLabel,
18
18
  getItemId
19
19
  }) => {
20
- const nodeMap = {};
20
+ const itemMetaMap = {};
21
21
  const itemMap = {};
22
- const processItem = (item, index, parentId) => {
22
+ const itemOrderedChildrenIds = {
23
+ [_useTreeViewItems.TREE_VIEW_ROOT_PARENT_ID]: []
24
+ };
25
+ const processItem = (item, parentId) => {
23
26
  const id = getItemId ? getItemId(item) : item.id;
24
27
  if (id == null) {
25
28
  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'));
26
29
  }
27
- if (nodeMap[id] != null) {
30
+ if (itemMetaMap[id] != null) {
28
31
  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'));
29
32
  }
30
33
  const label = getItemLabel ? getItemLabel(item) : item.label;
31
34
  if (label == null) {
32
35
  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'));
33
36
  }
34
- nodeMap[id] = {
37
+ itemMetaMap[id] = {
35
38
  id,
36
39
  label,
37
- index,
38
40
  parentId,
39
41
  idAttribute: undefined,
40
42
  expandable: !!item.children?.length,
41
43
  disabled: isItemDisabled ? isItemDisabled(item) : false
42
44
  };
43
45
  itemMap[id] = item;
44
- return {
45
- id,
46
- children: item.children?.map((child, childIndex) => processItem(child, childIndex, id))
47
- };
46
+ itemOrderedChildrenIds[id] = [];
47
+ const parentIdWithDefault = parentId ?? _useTreeViewItems.TREE_VIEW_ROOT_PARENT_ID;
48
+ if (!itemOrderedChildrenIds[parentIdWithDefault]) {
49
+ itemOrderedChildrenIds[parentIdWithDefault] = [];
50
+ }
51
+ itemOrderedChildrenIds[parentIdWithDefault].push(id);
52
+ item.children?.forEach(child => processItem(child, id));
48
53
  };
49
- const nodeTree = items.map((item, itemIndex) => processItem(item, itemIndex, null));
54
+ items.forEach(item => processItem(item, null));
55
+ const itemChildrenIndexes = {};
56
+ Object.keys(itemOrderedChildrenIds).forEach(parentId => {
57
+ itemChildrenIndexes[parentId] = (0, _useTreeViewItems.buildSiblingIndexes)(itemOrderedChildrenIds[parentId]);
58
+ });
50
59
  return {
51
- nodeMap,
52
- nodeTree,
53
- itemMap
60
+ itemMetaMap,
61
+ itemMap,
62
+ itemOrderedChildrenIds,
63
+ itemChildrenIndexes
54
64
  };
55
65
  };
56
66
  const useTreeViewItems = ({
57
67
  instance,
58
- publicAPI,
59
68
  params,
60
69
  state,
61
70
  setState
62
71
  }) => {
63
- const getNode = React.useCallback(itemId => state.items.nodeMap[itemId], [state.items.nodeMap]);
72
+ const getItemMeta = React.useCallback(itemId => state.items.itemMetaMap[itemId], [state.items.itemMetaMap]);
64
73
  const getItem = React.useCallback(itemId => state.items.itemMap[itemId], [state.items.itemMap]);
65
74
  const isItemDisabled = React.useCallback(itemId => {
66
75
  if (itemId == null) {
67
76
  return false;
68
77
  }
69
- let node = instance.getNode(itemId);
78
+ let itemMeta = instance.getItemMeta(itemId);
70
79
 
71
80
  // This can be called before the item has been added to the item map.
72
- if (!node) {
81
+ if (!itemMeta) {
73
82
  return false;
74
83
  }
75
- if (node.disabled) {
84
+ if (itemMeta.disabled) {
76
85
  return true;
77
86
  }
78
- while (node.parentId != null) {
79
- node = instance.getNode(node.parentId);
80
- if (node.disabled) {
87
+ while (itemMeta.parentId != null) {
88
+ itemMeta = instance.getItemMeta(itemMeta.parentId);
89
+ if (itemMeta.disabled) {
81
90
  return true;
82
91
  }
83
92
  }
84
93
  return false;
85
94
  }, [instance]);
86
- 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]);
87
- const getNavigableChildrenIds = itemId => {
88
- let childrenIds = instance.getChildrenIds(itemId);
89
- if (!params.disabledItemsFocusable) {
90
- childrenIds = childrenIds.filter(item => !instance.isItemDisabled(item));
95
+ const getItemIndex = React.useCallback(itemId => {
96
+ const parentId = instance.getItemMeta(itemId).parentId ?? _useTreeViewItems.TREE_VIEW_ROOT_PARENT_ID;
97
+ return state.items.itemChildrenIndexes[parentId][itemId];
98
+ }, [instance, state.items.itemChildrenIndexes]);
99
+ const getItemOrderedChildrenIds = React.useCallback(itemId => state.items.itemOrderedChildrenIds[itemId ?? _useTreeViewItems.TREE_VIEW_ROOT_PARENT_ID] ?? [], [state.items.itemOrderedChildrenIds]);
100
+ const isItemNavigable = itemId => {
101
+ if (params.disabledItemsFocusable) {
102
+ return true;
91
103
  }
92
- return childrenIds;
104
+ return !instance.isItemDisabled(itemId);
93
105
  };
94
106
  const areItemUpdatesPreventedRef = React.useRef(false);
95
107
  const preventItemUpdates = React.useCallback(() => {
@@ -107,8 +119,8 @@ const useTreeViewItems = ({
107
119
  getItemId: params.getItemId,
108
120
  getItemLabel: params.getItemLabel
109
121
  });
110
- Object.values(prevState.items.nodeMap).forEach(item => {
111
- if (!newState.nodeMap[item.id]) {
122
+ Object.values(prevState.items.itemMetaMap).forEach(item => {
123
+ if (!newState.itemMetaMap[item.id]) {
112
124
  (0, _publishTreeViewEvent.publishTreeViewEvent)(instance, 'removeItem', {
113
125
  id: item.id
114
126
  });
@@ -120,34 +132,32 @@ const useTreeViewItems = ({
120
132
  });
121
133
  }, [instance, setState, params.items, params.isItemDisabled, params.getItemId, params.getItemLabel]);
122
134
  const getItemsToRender = () => {
123
- const getPropsFromItemId = ({
124
- id,
125
- children
126
- }) => {
127
- const item = state.items.nodeMap[id];
135
+ const getPropsFromItemId = id => {
136
+ const item = state.items.itemMetaMap[id];
128
137
  return {
129
138
  label: item.label,
130
139
  itemId: item.id,
131
140
  id: item.idAttribute,
132
- children: children?.map(getPropsFromItemId)
141
+ children: state.items.itemOrderedChildrenIds[id].map(getPropsFromItemId)
133
142
  };
134
143
  };
135
- return state.items.nodeTree.map(getPropsFromItemId);
144
+ return state.items.itemOrderedChildrenIds[_useTreeViewItems.TREE_VIEW_ROOT_PARENT_ID].map(getPropsFromItemId);
136
145
  };
137
- (0, _useTreeView.populateInstance)(instance, {
138
- getNode,
139
- getItem,
140
- getItemsToRender,
141
- getChildrenIds,
142
- getNavigableChildrenIds,
143
- isItemDisabled,
144
- preventItemUpdates,
145
- areItemUpdatesPrevented
146
- });
147
- (0, _useTreeView.populatePublicAPI)(publicAPI, {
148
- getItem
149
- });
150
146
  return {
147
+ publicAPI: {
148
+ getItem
149
+ },
150
+ instance: {
151
+ getItemMeta,
152
+ getItem,
153
+ getItemsToRender,
154
+ getItemIndex,
155
+ getItemOrderedChildrenIds,
156
+ isItemDisabled,
157
+ isItemNavigable,
158
+ preventItemUpdates,
159
+ areItemUpdatesPrevented
160
+ },
151
161
  contextValue: {
152
162
  disabledItemsFocusable: params.disabledItemsFocusable
153
163
  }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.buildSiblingIndexes = exports.TREE_VIEW_ROOT_PARENT_ID = void 0;
7
+ const TREE_VIEW_ROOT_PARENT_ID = exports.TREE_VIEW_ROOT_PARENT_ID = '__TREE_VIEW_ROOT_PARENT_ID__';
8
+ const buildSiblingIndexes = siblings => {
9
+ const siblingsIndexLookup = {};
10
+ siblings.forEach((childId, index) => {
11
+ siblingsIndexLookup[childId] = index;
12
+ });
13
+ return siblingsIndexLookup;
14
+ };
15
+ exports.buildSiblingIndexes = buildSiblingIndexes;
@@ -9,10 +9,11 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
9
9
  var React = _interopRequireWildcard(require("react"));
10
10
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
11
11
  var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
12
- var _useTreeView = require("../../useTreeView/useTreeView.utils");
12
+ var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
13
13
  var _publishTreeViewEvent = require("../../utils/publishTreeViewEvent");
14
14
  var _useTreeViewContext = require("../../TreeViewProvider/useTreeViewContext");
15
- var _DescendantProvider = require("../../TreeViewProvider/DescendantProvider");
15
+ var _TreeViewChildrenItemProvider = require("../../TreeViewProvider/TreeViewChildrenItemProvider");
16
+ var _useTreeViewItems = require("../useTreeViewItems/useTreeViewItems.utils");
16
17
  var _jsxRuntime = require("react/jsx-runtime");
17
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
18
19
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -23,12 +24,12 @@ const useTreeViewJSXItems = ({
23
24
  instance.preventItemUpdates();
24
25
  const insertJSXItem = (0, _useEventCallback.default)(item => {
25
26
  setState(prevState => {
26
- if (prevState.items.nodeMap[item.id] != null) {
27
+ if (prevState.items.itemMetaMap[item.id] != null) {
27
28
  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'));
28
29
  }
29
30
  return (0, _extends2.default)({}, prevState, {
30
31
  items: (0, _extends2.default)({}, prevState.items, {
31
- nodeMap: (0, _extends2.default)({}, prevState.items.nodeMap, {
32
+ itemMetaMap: (0, _extends2.default)({}, prevState.items.itemMetaMap, {
32
33
  [item.id]: item
33
34
  }),
34
35
  // For `SimpleTreeView`, we don't have a proper `item` object, so we create a very basic one.
@@ -42,15 +43,28 @@ const useTreeViewJSXItems = ({
42
43
  });
43
44
  });
44
45
  });
46
+ const setJSXItemsOrderedChildrenIds = (parentId, orderedChildrenIds) => {
47
+ const parentIdWithDefault = parentId ?? _useTreeViewItems.TREE_VIEW_ROOT_PARENT_ID;
48
+ setState(prevState => (0, _extends2.default)({}, prevState, {
49
+ items: (0, _extends2.default)({}, prevState.items, {
50
+ itemOrderedChildrenIds: (0, _extends2.default)({}, prevState.items.itemOrderedChildrenIds, {
51
+ [parentIdWithDefault]: orderedChildrenIds
52
+ }),
53
+ itemChildrenIndexes: (0, _extends2.default)({}, prevState.items.itemChildrenIndexes, {
54
+ [parentIdWithDefault]: (0, _useTreeViewItems.buildSiblingIndexes)(orderedChildrenIds)
55
+ })
56
+ })
57
+ }));
58
+ };
45
59
  const removeJSXItem = (0, _useEventCallback.default)(itemId => {
46
60
  setState(prevState => {
47
- const newNodeMap = (0, _extends2.default)({}, prevState.items.nodeMap);
61
+ const newItemMetaMap = (0, _extends2.default)({}, prevState.items.itemMetaMap);
48
62
  const newItemMap = (0, _extends2.default)({}, prevState.items.itemMap);
49
- delete newNodeMap[itemId];
63
+ delete newItemMetaMap[itemId];
50
64
  delete newItemMap[itemId];
51
65
  return (0, _extends2.default)({}, prevState, {
52
66
  items: (0, _extends2.default)({}, prevState.items, {
53
- nodeMap: newNodeMap,
67
+ itemMetaMap: newItemMetaMap,
54
68
  itemMap: newItemMap
55
69
  })
56
70
  });
@@ -72,18 +86,30 @@ const useTreeViewJSXItems = ({
72
86
  });
73
87
  };
74
88
  });
75
- (0, _useTreeView.populateInstance)(instance, {
76
- insertJSXItem,
77
- removeJSXItem,
78
- mapFirstCharFromJSX
79
- });
89
+ return {
90
+ instance: {
91
+ insertJSXItem,
92
+ removeJSXItem,
93
+ setJSXItemsOrderedChildrenIds,
94
+ mapFirstCharFromJSX
95
+ }
96
+ };
80
97
  };
81
98
  exports.useTreeViewJSXItems = useTreeViewJSXItems;
99
+ const isItemExpandable = reactChildren => {
100
+ if (Array.isArray(reactChildren)) {
101
+ return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
102
+ }
103
+ return Boolean(reactChildren);
104
+ };
82
105
  const useTreeViewJSXItemsItemPlugin = ({
83
106
  props,
84
107
  rootRef,
85
108
  contentRef
86
109
  }) => {
110
+ const {
111
+ instance
112
+ } = (0, _useTreeViewContext.useTreeViewContext)();
87
113
  const {
88
114
  children,
89
115
  disabled = false,
@@ -91,43 +117,37 @@ const useTreeViewJSXItemsItemPlugin = ({
91
117
  itemId,
92
118
  id
93
119
  } = props;
120
+ const parentContext = React.useContext(_TreeViewChildrenItemProvider.TreeViewChildrenItemContext);
121
+ if (parentContext == null) {
122
+ 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'));
123
+ }
94
124
  const {
95
- instance
96
- } = (0, _useTreeViewContext.useTreeViewContext)();
97
- const isExpandable = reactChildren => {
98
- if (Array.isArray(reactChildren)) {
99
- return reactChildren.length > 0 && reactChildren.some(isExpandable);
100
- }
101
- return Boolean(reactChildren);
102
- };
103
- const expandable = isExpandable(children);
104
- const [treeItemElement, setTreeItemElement] = React.useState(null);
125
+ registerChild,
126
+ unregisterChild,
127
+ parentId
128
+ } = parentContext;
129
+ const expandable = isItemExpandable(children);
105
130
  const pluginContentRef = React.useRef(null);
106
- const handleRootRef = (0, _useForkRef.default)(setTreeItemElement, rootRef);
107
131
  const handleContentRef = (0, _useForkRef.default)(pluginContentRef, contentRef);
108
- const descendant = React.useMemo(() => ({
109
- element: treeItemElement,
110
- id: itemId
111
- }), [itemId, treeItemElement]);
112
- const {
113
- index,
114
- parentId
115
- } = (0, _DescendantProvider.useDescendant)(descendant);
132
+
133
+ // Prevent any flashing
134
+ (0, _useEnhancedEffect.default)(() => {
135
+ const idAttributeWithDefault = instance.getTreeItemIdAttribute(itemId, id);
136
+ registerChild(idAttributeWithDefault, itemId);
137
+ return () => {
138
+ unregisterChild(idAttributeWithDefault);
139
+ };
140
+ }, [instance, registerChild, unregisterChild, itemId, id]);
116
141
  React.useEffect(() => {
117
- // On the first render a item's index will be -1. We want to wait for the real index.
118
- if (index !== -1) {
119
- instance.insertJSXItem({
120
- id: itemId,
121
- idAttribute: id,
122
- index,
123
- parentId,
124
- expandable,
125
- disabled
126
- });
127
- return () => instance.removeJSXItem(itemId);
128
- }
129
- return undefined;
130
- }, [instance, parentId, index, itemId, expandable, disabled, id]);
142
+ instance.insertJSXItem({
143
+ id: itemId,
144
+ idAttribute: id,
145
+ parentId,
146
+ expandable,
147
+ disabled
148
+ });
149
+ return () => instance.removeJSXItem(itemId);
150
+ }, [instance, parentId, itemId, expandable, disabled, id]);
131
151
  React.useEffect(() => {
132
152
  if (label) {
133
153
  return instance.mapFirstCharFromJSX(itemId, (pluginContentRef.current?.textContent ?? '').substring(0, 1).toLowerCase());
@@ -136,15 +156,20 @@ const useTreeViewJSXItemsItemPlugin = ({
136
156
  }, [instance, itemId, label]);
137
157
  return {
138
158
  contentRef: handleContentRef,
139
- rootRef: handleRootRef
159
+ rootRef
140
160
  };
141
161
  };
142
162
  useTreeViewJSXItems.itemPlugin = useTreeViewJSXItemsItemPlugin;
143
163
  useTreeViewJSXItems.wrapItem = ({
144
164
  children,
145
165
  itemId
146
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_DescendantProvider.DescendantProvider, {
147
- id: itemId,
166
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_TreeViewChildrenItemProvider.TreeViewChildrenItemProvider, {
167
+ itemId: itemId,
168
+ children: children
169
+ });
170
+ useTreeViewJSXItems.wrapRoot = ({
171
+ children
172
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_TreeViewChildrenItemProvider.TreeViewChildrenItemProvider, {
148
173
  children: children
149
174
  });
150
175
  useTreeViewJSXItems.params = {};
@@ -8,7 +8,7 @@ exports.useTreeViewKeyboardNavigation = void 0;
8
8
  var React = _interopRequireWildcard(require("react"));
9
9
  var _styles = require("@mui/material/styles");
10
10
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
11
- var _useTreeView = require("../../useTreeView/useTreeView.utils");
11
+ var _tree = require("../../utils/tree");
12
12
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
13
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
14
  function isPrintableCharacter(string) {
@@ -38,12 +38,12 @@ const useTreeViewKeyboardNavigation = ({
38
38
  return;
39
39
  }
40
40
  const newFirstCharMap = {};
41
- const processItem = node => {
42
- newFirstCharMap[node.id] = node.label.substring(0, 1).toLowerCase();
41
+ const processItem = item => {
42
+ newFirstCharMap[item.id] = item.label.substring(0, 1).toLowerCase();
43
43
  };
44
- Object.values(state.items.nodeMap).forEach(processItem);
44
+ Object.values(state.items.itemMetaMap).forEach(processItem);
45
45
  firstCharMap.current = newFirstCharMap;
46
- }, [state.items.nodeMap, params.getItemId, instance]);
46
+ }, [state.items.itemMetaMap, params.getItemId, instance]);
47
47
  const getFirstMatchingItem = (itemId, firstChar) => {
48
48
  let start;
49
49
  let index;
@@ -52,7 +52,7 @@ const useTreeViewKeyboardNavigation = ({
52
52
  const firstChars = [];
53
53
  // This really only works since the ids are strings
54
54
  Object.keys(firstCharMap.current).forEach(mapItemId => {
55
- const map = instance.getNode(mapItemId);
55
+ const map = instance.getItemMeta(mapItemId);
56
56
  const visible = map.parentId ? instance.isItemExpanded(map.parentId) : true;
57
57
  const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isItemDisabled(mapItemId);
58
58
  if (visible && !shouldBeSkipped) {
@@ -137,7 +137,7 @@ const useTreeViewKeyboardNavigation = ({
137
137
  // Focus the next focusable item
138
138
  case key === 'ArrowDown':
139
139
  {
140
- const nextItem = (0, _useTreeView.getNextItem)(instance, itemId);
140
+ const nextItem = (0, _tree.getNextNavigableItem)(instance, itemId);
141
141
  if (nextItem) {
142
142
  event.preventDefault();
143
143
  instance.focusItem(event, nextItem);
@@ -157,7 +157,7 @@ const useTreeViewKeyboardNavigation = ({
157
157
  // Focuses the previous focusable item
158
158
  case key === 'ArrowUp':
159
159
  {
160
- const previousItem = (0, _useTreeView.getPreviousItem)(instance, itemId);
160
+ const previousItem = (0, _tree.getPreviousNavigableItem)(instance, itemId);
161
161
  if (previousItem) {
162
162
  event.preventDefault();
163
163
  instance.focusItem(event, previousItem);
@@ -179,7 +179,7 @@ const useTreeViewKeyboardNavigation = ({
179
179
  case key === 'ArrowRight' && !isRTL || key === 'ArrowLeft' && isRTL:
180
180
  {
181
181
  if (instance.isItemExpanded(itemId)) {
182
- const nextItemId = (0, _useTreeView.getNextItem)(instance, itemId);
182
+ const nextItemId = (0, _tree.getNextNavigableItem)(instance, itemId);
183
183
  if (nextItemId) {
184
184
  instance.focusItem(event, nextItemId);
185
185
  event.preventDefault();
@@ -199,7 +199,7 @@ const useTreeViewKeyboardNavigation = ({
199
199
  instance.toggleItemExpansion(event, itemId);
200
200
  event.preventDefault();
201
201
  } else {
202
- const parent = instance.getNode(itemId).parentId;
202
+ const parent = instance.getItemMeta(itemId).parentId;
203
203
  if (parent) {
204
204
  instance.focusItem(event, parent);
205
205
  event.preventDefault();
@@ -211,7 +211,7 @@ const useTreeViewKeyboardNavigation = ({
211
211
  // Focuses the first item in the tree
212
212
  case key === 'Home':
213
213
  {
214
- instance.focusItem(event, (0, _useTreeView.getFirstItem)(instance));
214
+ instance.focusItem(event, (0, _tree.getFirstNavigableItem)(instance));
215
215
 
216
216
  // Multi select behavior when pressing Ctrl + Shift + Home
217
217
  // Selects the focused item and all items up to the first item.
@@ -225,7 +225,7 @@ const useTreeViewKeyboardNavigation = ({
225
225
  // Focuses the last item in the tree
226
226
  case key === 'End':
227
227
  {
228
- instance.focusItem(event, (0, _useTreeView.getLastItem)(instance));
228
+ instance.focusItem(event, (0, _tree.getLastNavigableItem)(instance));
229
229
 
230
230
  // Multi select behavior when pressing Ctrl + Shirt + End
231
231
  // Selects the focused item and all the items down to the last item.
@@ -249,8 +249,8 @@ const useTreeViewKeyboardNavigation = ({
249
249
  case key === 'a' && ctrlPressed && params.multiSelect && !params.disableSelection:
250
250
  {
251
251
  instance.selectRange(event, {
252
- start: (0, _useTreeView.getFirstItem)(instance),
253
- end: (0, _useTreeView.getLastItem)(instance)
252
+ start: (0, _tree.getFirstNavigableItem)(instance),
253
+ end: (0, _tree.getLastNavigableItem)(instance)
254
254
  });
255
255
  event.preventDefault();
256
256
  break;
@@ -269,10 +269,12 @@ const useTreeViewKeyboardNavigation = ({
269
269
  }
270
270
  }
271
271
  };
272
- (0, _useTreeView.populateInstance)(instance, {
273
- updateFirstCharMap,
274
- handleItemKeyDown
275
- });
272
+ return {
273
+ instance: {
274
+ updateFirstCharMap,
275
+ handleItemKeyDown
276
+ }
277
+ };
276
278
  };
277
279
  exports.useTreeViewKeyboardNavigation = useTreeViewKeyboardNavigation;
278
280
  useTreeViewKeyboardNavigation.params = {};
@@ -7,8 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.useTreeViewSelection = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var React = _interopRequireWildcard(require("react"));
10
- var _useTreeView = require("../../useTreeView/useTreeView.utils");
11
- var _useTreeViewSelection = require("./useTreeViewSelection.utils");
10
+ var _tree = require("../../utils/tree");
12
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
13
  const useTreeViewSelection = ({
@@ -67,16 +66,6 @@ const useTreeViewSelection = ({
67
66
  lastSelectionWasRange.current = false;
68
67
  currentRangeSelection.current = [];
69
68
  };
70
- const getItemsInRange = (itemAId, itemBId) => {
71
- const [first, last] = (0, _useTreeViewSelection.findOrderInTremauxTree)(instance, itemAId, itemBId);
72
- const items = [first];
73
- let current = first;
74
- while (current !== last) {
75
- current = (0, _useTreeView.getNextItem)(instance, current);
76
- items.push(current);
77
- }
78
- return items;
79
- };
80
69
  const handleRangeArrowSelect = (event, items) => {
81
70
  let base = models.selectedItems.value.slice();
82
71
  const {
@@ -114,7 +103,7 @@ const useTreeViewSelection = ({
114
103
  if (lastSelectionWasRange.current) {
115
104
  base = base.filter(id => currentRangeSelection.current.indexOf(id) === -1);
116
105
  }
117
- let range = getItemsInRange(start, end);
106
+ let range = (0, _tree.getNavigableItemsInRange)(instance, start, end);
118
107
  range = range.filter(item => !instance.isItemDisabled(item));
119
108
  currentRangeSelection.current = range;
120
109
  let newSelected = base.concat(range);
@@ -151,7 +140,7 @@ const useTreeViewSelection = ({
151
140
  const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId;
152
141
  instance.selectRange(event, {
153
142
  start,
154
- end: (0, _useTreeView.getFirstItem)(instance)
143
+ end: (0, _tree.getFirstNavigableItem)(instance)
155
144
  });
156
145
  };
157
146
  const rangeSelectToLast = (event, itemId) => {
@@ -161,20 +150,20 @@ const useTreeViewSelection = ({
161
150
  const start = lastSelectionWasRange.current ? lastSelectedItem.current : itemId;
162
151
  instance.selectRange(event, {
163
152
  start,
164
- end: (0, _useTreeView.getLastItem)(instance)
153
+ end: (0, _tree.getLastNavigableItem)(instance)
165
154
  });
166
155
  };
167
- (0, _useTreeView.populateInstance)(instance, {
168
- isItemSelected,
169
- selectItem,
170
- selectRange,
171
- rangeSelectToLast,
172
- rangeSelectToFirst
173
- });
174
156
  return {
175
157
  getRootProps: () => ({
176
158
  'aria-multiselectable': params.multiSelect
177
159
  }),
160
+ instance: {
161
+ isItemSelected,
162
+ selectItem,
163
+ selectRange,
164
+ rangeSelectToLast,
165
+ rangeSelectToFirst
166
+ },
178
167
  contextValue: {
179
168
  selection: {
180
169
  multiSelect: params.multiSelect
@@ -49,12 +49,12 @@ const useTreeView = inParams => {
49
49
  const rootPropsGetters = [];
50
50
  const contextValue = {
51
51
  publicAPI,
52
- instance: instance
52
+ instance: instance,
53
+ rootRef: innerRootRef
53
54
  };
54
55
  const runPlugin = plugin => {
55
56
  const pluginResponse = plugin({
56
57
  instance,
57
- publicAPI,
58
58
  params,
59
59
  slots: params.slots,
60
60
  slotProps: params.slotProps,
@@ -62,10 +62,16 @@ const useTreeView = inParams => {
62
62
  setState,
63
63
  rootRef: innerRootRef,
64
64
  models
65
- }) || {};
65
+ });
66
66
  if (pluginResponse.getRootProps) {
67
67
  rootPropsGetters.push(pluginResponse.getRootProps);
68
68
  }
69
+ if (pluginResponse.publicAPI) {
70
+ Object.assign(publicAPI, pluginResponse.publicAPI);
71
+ }
72
+ if (pluginResponse.instance) {
73
+ Object.assign(instance, pluginResponse.instance);
74
+ }
69
75
  if (pluginResponse.contextValue) {
70
76
  Object.assign(contextValue, pluginResponse.contextValue);
71
77
  }
@@ -109,6 +115,18 @@ const useTreeView = inParams => {
109
115
  });
110
116
  return finalChildren;
111
117
  };
118
+ const rootWrappers = plugins.map(plugin => plugin.wrapRoot).filter(wrapRoot => !!wrapRoot);
119
+ contextValue.wrapRoot = ({
120
+ children
121
+ }) => {
122
+ let finalChildren = children;
123
+ rootWrappers.forEach(rootWrapper => {
124
+ finalChildren = rootWrapper({
125
+ children: finalChildren
126
+ });
127
+ });
128
+ return finalChildren;
129
+ };
112
130
  const getRootProps = (otherHandlers = {}) => {
113
131
  const rootProps = (0, _extends2.default)({
114
132
  role: 'tree'