@mui/x-tree-view-pro 7.22.1 → 8.0.0-alpha.1

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 (30) hide show
  1. package/CHANGELOG.md +486 -11
  2. package/README.md +4 -4
  3. package/RichTreeViewPro/RichTreeViewPro.js +22 -5
  4. package/RichTreeViewPro/RichTreeViewPro.types.d.ts +3 -17
  5. package/index.d.ts +5 -7
  6. package/index.js +6 -8
  7. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.d.ts +1 -2
  8. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.js +12 -14
  9. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +34 -32
  10. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.d.ts +159 -0
  11. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.js +35 -0
  12. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.types.d.ts +11 -10
  13. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.d.ts +4 -6
  14. package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.js +25 -17
  15. package/internals/utils/releaseInfo.js +1 -1
  16. package/modern/RichTreeViewPro/RichTreeViewPro.js +22 -5
  17. package/modern/index.js +6 -8
  18. package/modern/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.js +12 -14
  19. package/modern/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +34 -32
  20. package/modern/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.js +35 -0
  21. package/modern/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.js +25 -17
  22. package/modern/internals/utils/releaseInfo.js +1 -1
  23. package/node/RichTreeViewPro/RichTreeViewPro.js +22 -5
  24. package/node/index.js +18 -42
  25. package/node/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.itemPlugin.js +11 -13
  26. package/node/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +34 -32
  27. package/node/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.selectors.js +42 -0
  28. package/node/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.utils.js +24 -16
  29. package/node/internals/utils/releaseInfo.js +1 -1
  30. package/package.json +9 -7
@@ -1,17 +1,17 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from '@mui/x-tree-view/internals';
2
+ import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID, selectorItemMeta } from '@mui/x-tree-view/internals';
3
3
  /**
4
4
  * Checks if the item with the id itemIdB is an ancestor of the item with the id itemIdA.
5
5
  */
6
- export const isAncestor = (instance, itemIdA, itemIdB) => {
7
- const itemMetaA = instance.getItemMeta(itemIdA);
6
+ export const isAncestor = (store, itemIdA, itemIdB) => {
7
+ const itemMetaA = selectorItemMeta(store.value, itemIdA);
8
8
  if (itemMetaA.parentId === itemIdB) {
9
9
  return true;
10
10
  }
11
11
  if (itemMetaA.parentId == null) {
12
12
  return false;
13
13
  }
14
- return isAncestor(instance, itemMetaA.parentId, itemIdB);
14
+ return isAncestor(store, itemMetaA.parentId, itemIdB);
15
15
  };
16
16
 
17
17
  /**
@@ -88,12 +88,12 @@ export const moveItemInTree = ({
88
88
  newPosition,
89
89
  prevState
90
90
  }) => {
91
- const itemToMoveMeta = prevState.itemMetaMap[itemToMoveId];
91
+ const itemToMoveMeta = prevState.itemMetaLookup[itemToMoveId];
92
92
  const oldParentId = oldPosition.parentId ?? TREE_VIEW_ROOT_PARENT_ID;
93
93
  const newParentId = newPosition.parentId ?? TREE_VIEW_ROOT_PARENT_ID;
94
94
 
95
95
  // 1. Update the `itemOrderedChildrenIds`.
96
- const itemOrderedChildrenIds = _extends({}, prevState.itemOrderedChildrenIds);
96
+ const itemOrderedChildrenIds = _extends({}, prevState.itemOrderedChildrenIdsLookup);
97
97
  if (oldParentId === newParentId) {
98
98
  const updatedChildren = [...itemOrderedChildrenIds[oldParentId]];
99
99
  updatedChildren.splice(oldPosition.index, 1);
@@ -109,42 +109,50 @@ export const moveItemInTree = ({
109
109
  }
110
110
 
111
111
  // 2. Update the `itemChildrenIndexes`
112
- const itemChildrenIndexes = _extends({}, prevState.itemChildrenIndexes);
112
+ const itemChildrenIndexes = _extends({}, prevState.itemChildrenIndexesLookup);
113
113
  itemChildrenIndexes[oldParentId] = buildSiblingIndexes(itemOrderedChildrenIds[oldParentId]);
114
114
  if (newParentId !== oldParentId) {
115
115
  itemChildrenIndexes[newParentId] = buildSiblingIndexes(itemOrderedChildrenIds[newParentId]);
116
116
  }
117
117
 
118
- // 3. Update the `itemMetaMap`
119
- const itemMetaMap = _extends({}, prevState.itemMetaMap);
118
+ // 3. Update the `itemMetaLookup`
119
+ const itemMetaLookup = _extends({}, prevState.itemMetaLookup);
120
120
 
121
121
  // 3.1 Update the `expandable` property of the old and the new parent
122
+ function updateExpandable(itemId) {
123
+ const isExpandable = itemOrderedChildrenIds[itemId].length > 0;
124
+ if (itemMetaLookup[itemId].expandable !== isExpandable) {
125
+ itemMetaLookup[itemId] = _extends({}, itemMetaLookup[itemId], {
126
+ expandable: isExpandable
127
+ });
128
+ }
129
+ }
122
130
  if (oldParentId !== TREE_VIEW_ROOT_PARENT_ID && oldParentId !== newParentId) {
123
- itemMetaMap[oldParentId].expandable = itemOrderedChildrenIds[oldParentId].length > 0;
131
+ updateExpandable(oldParentId);
124
132
  }
125
133
  if (newParentId !== TREE_VIEW_ROOT_PARENT_ID && newParentId !== oldParentId) {
126
- itemMetaMap[newParentId].expandable = itemOrderedChildrenIds[newParentId].length > 0;
134
+ updateExpandable(newParentId);
127
135
  }
128
136
 
129
137
  // 3.2 Update the `parentId` and `depth` properties of the item to move
130
138
  // The depth is always defined because drag&drop is only usable with Rich Tree View components.
131
- const itemToMoveDepth = newPosition.parentId == null ? 0 : itemMetaMap[newParentId].depth + 1;
132
- itemMetaMap[itemToMoveId] = _extends({}, itemToMoveMeta, {
139
+ const itemToMoveDepth = newPosition.parentId == null ? 0 : itemMetaLookup[newParentId].depth + 1;
140
+ itemMetaLookup[itemToMoveId] = _extends({}, itemToMoveMeta, {
133
141
  parentId: newPosition.parentId,
134
142
  depth: itemToMoveDepth
135
143
  });
136
144
 
137
145
  // 3.3 Update the depth of all the children of the item to move
138
146
  const updateItemDepth = (itemId, depth) => {
139
- itemMetaMap[itemId] = _extends({}, itemMetaMap[itemId], {
147
+ itemMetaLookup[itemId] = _extends({}, itemMetaLookup[itemId], {
140
148
  depth
141
149
  });
142
150
  itemOrderedChildrenIds[itemId]?.forEach(childId => updateItemDepth(childId, depth + 1));
143
151
  };
144
152
  itemOrderedChildrenIds[itemToMoveId]?.forEach(childId => updateItemDepth(childId, itemToMoveDepth + 1));
145
153
  return _extends({}, prevState, {
146
- itemOrderedChildrenIds,
147
- itemChildrenIndexes,
148
- itemMetaMap
154
+ itemOrderedChildrenIdsLookup: itemOrderedChildrenIds,
155
+ itemChildrenIndexesLookup: itemChildrenIndexes,
156
+ itemMetaLookup
149
157
  });
150
158
  };
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTczMDQzMzYwMDAwMA==";
3
+ const releaseInfo = "MTczMjIzMDAwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
@@ -59,8 +59,7 @@ const RichTreeViewPro = /*#__PURE__*/React.forwardRef(function RichTreeViewPro(i
59
59
  }
60
60
  const {
61
61
  getRootProps,
62
- contextValue,
63
- instance
62
+ contextValue
64
63
  } = useTreeView({
65
64
  plugins: RICH_TREE_VIEW_PRO_PLUGINS,
66
65
  rootRef: ref,
@@ -84,8 +83,7 @@ const RichTreeViewPro = /*#__PURE__*/React.forwardRef(function RichTreeViewPro(i
84
83
  children: /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
85
84
  children: [/*#__PURE__*/_jsx(RichTreeViewItems, {
86
85
  slots: slots,
87
- slotProps: slotProps,
88
- itemsToRender: instance.getItemsToRender()
86
+ slotProps: slotProps
89
87
  }), /*#__PURE__*/_jsx(Watermark, {
90
88
  packageName: "x-tree-view-pro",
91
89
  releaseInfo: releaseInfo
@@ -170,7 +168,6 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
170
168
  * the feature will be fully disabled and any property / method call will not have any effect.
171
169
  */
172
170
  experimentalFeatures: PropTypes.shape({
173
- indentationAtItemLevel: PropTypes.bool,
174
171
  itemsReordering: PropTypes.bool,
175
172
  labelEditing: PropTypes.bool
176
173
  }),
@@ -298,6 +295,26 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
298
295
  * When `multiSelect` is true this takes an array of strings; when false (default) a string.
299
296
  */
300
297
  selectedItems: PropTypes.any,
298
+ /**
299
+ * When `selectionPropagation.descendants` is set to `true`.
300
+ *
301
+ * - Selecting a parent selects all its descendants automatically.
302
+ * - Deselecting a parent deselects all its descendants automatically.
303
+ *
304
+ * When `selectionPropagation.parents` is set to `true`.
305
+ *
306
+ * - Selecting all the descendants of a parent selects the parent automatically.
307
+ * - Deselecting a descendant of a selected parent deselects the parent automatically.
308
+ *
309
+ * Only works when `multiSelect` is `true`.
310
+ * On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all)
311
+ *
312
+ * @default { parents: false, descendants: false }
313
+ */
314
+ selectionPropagation: PropTypes.shape({
315
+ descendants: PropTypes.bool,
316
+ parents: PropTypes.bool
317
+ }),
301
318
  /**
302
319
  * The props used for each component slot.
303
320
  * @default {}
package/modern/index.js CHANGED
@@ -1,23 +1,21 @@
1
1
  /**
2
- * @mui/x-tree-view-pro v7.22.1
2
+ * @mui/x-tree-view-pro v8.0.0-alpha.1
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  // Tree View
9
- export * from '@mui/x-tree-view/TreeView';
10
9
  export * from '@mui/x-tree-view/SimpleTreeView';
11
10
  export * from "./RichTreeViewPro/index.js";
12
11
 
13
12
  // Tree Item
14
13
  export * from '@mui/x-tree-view/TreeItem';
15
- export * from '@mui/x-tree-view/TreeItem2';
16
- export * from '@mui/x-tree-view/useTreeItem2';
17
- export * from '@mui/x-tree-view/TreeItem2Icon';
18
- export * from '@mui/x-tree-view/TreeItem2Provider';
19
- export * from '@mui/x-tree-view/TreeItem2DragAndDropOverlay';
20
- export * from '@mui/x-tree-view/TreeItem2LabelInput';
14
+ export * from '@mui/x-tree-view/useTreeItem';
15
+ export * from '@mui/x-tree-view/TreeItemIcon';
16
+ export * from '@mui/x-tree-view/TreeItemProvider';
17
+ export * from '@mui/x-tree-view/TreeItemDragAndDropOverlay';
18
+ export * from '@mui/x-tree-view/TreeItemLabelInput';
21
19
  export { unstable_resetCleanupTracking } from '@mui/x-tree-view/internals';
22
20
  export * from '@mui/x-tree-view/models';
23
21
  export * from '@mui/x-tree-view/icons';
@@ -1,17 +1,21 @@
1
1
  import * as React from 'react';
2
- import { useTreeViewContext, isTargetInDescendants } from '@mui/x-tree-view/internals';
2
+ import { useTreeViewContext, isTargetInDescendants, useSelector } from '@mui/x-tree-view/internals';
3
+ import { selectorItemsReorderingDraggedItemProperties, selectorItemsReorderingIsValidTarget } from "./useTreeViewItemsReordering.selectors.js";
3
4
  export const isAndroid = () => navigator.userAgent.toLowerCase().includes('android');
4
5
  export const useTreeViewItemsReorderingItemPlugin = ({
5
6
  props
6
7
  }) => {
7
8
  const {
8
- itemsReordering,
9
- instance
9
+ instance,
10
+ store,
11
+ itemsReordering
10
12
  } = useTreeViewContext();
11
13
  const {
12
14
  itemId
13
15
  } = props;
14
16
  const validActionsRef = React.useRef(null);
17
+ const draggedItemProperties = useSelector(store, selectorItemsReorderingDraggedItemProperties, itemId);
18
+ const isValidTarget = useSelector(store, selectorItemsReorderingIsValidTarget, itemId);
15
19
  return {
16
20
  propsEnhancers: {
17
21
  root: ({
@@ -19,8 +23,7 @@ export const useTreeViewItemsReorderingItemPlugin = ({
19
23
  contentRefObject,
20
24
  externalEventHandlers
21
25
  }) => {
22
- const draggable = instance.canItemBeDragged(itemId);
23
- if (!draggable) {
26
+ if (!itemsReordering.enabled || itemsReordering.isItemReorderable && !itemsReordering.isItemReorderable(itemId)) {
24
27
  return {};
25
28
  }
26
29
  const handleDragStart = event => {
@@ -75,8 +78,7 @@ export const useTreeViewItemsReorderingItemPlugin = ({
75
78
  externalEventHandlers,
76
79
  contentRefObject
77
80
  }) => {
78
- const currentDrag = itemsReordering.currentDrag;
79
- if (!currentDrag || currentDrag.draggedItemId === itemId) {
81
+ if (!isValidTarget) {
80
82
  return {};
81
83
  }
82
84
  const handleDragOver = event => {
@@ -109,17 +111,13 @@ export const useTreeViewItemsReorderingItemPlugin = ({
109
111
  };
110
112
  },
111
113
  dragAndDropOverlay: () => {
112
- const currentDrag = itemsReordering.currentDrag;
113
- if (!currentDrag || currentDrag.targetItemId !== itemId || currentDrag.action == null) {
114
+ if (!draggedItemProperties) {
114
115
  return {};
115
116
  }
116
- const targetDepth = currentDrag.newPosition?.parentId == null ? 0 :
117
- // The depth is always defined because drag&drop is only usable with Rich Tree View components.
118
- instance.getItemMeta(currentDrag.newPosition.parentId).depth + 1;
119
117
  return {
120
- action: currentDrag.action,
118
+ action: draggedItemProperties.action,
121
119
  style: {
122
- '--TreeView-targetDepth': targetDepth
120
+ '--TreeView-targetDepth': draggedItemProperties.targetDepth
123
121
  }
124
122
  };
125
123
  }
@@ -1,13 +1,13 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
+ import { selectorItemIndex, selectorItemMeta, selectorItemOrderedChildrenIds } from '@mui/x-tree-view/internals';
3
4
  import { warnOnce } from '@mui/x-internals/warning';
4
5
  import { chooseActionToApply, isAncestor, moveItemInTree } from "./useTreeViewItemsReordering.utils.js";
5
6
  import { useTreeViewItemsReorderingItemPlugin } from "./useTreeViewItemsReordering.itemPlugin.js";
7
+ import { selectorItemsReordering } from "./useTreeViewItemsReordering.selectors.js";
6
8
  export const useTreeViewItemsReordering = ({
7
9
  params,
8
- instance,
9
- state,
10
- setState
10
+ store
11
11
  }) => {
12
12
  const canItemBeDragged = React.useCallback(itemId => {
13
13
  if (!params.itemsReordering) {
@@ -20,7 +20,7 @@ export const useTreeViewItemsReordering = ({
20
20
  return true;
21
21
  }, [params.itemsReordering, params.isItemReorderable]);
22
22
  const getDroppingTargetValidActions = React.useCallback(itemId => {
23
- const itemsReordering = state.itemsReordering;
23
+ const itemsReordering = selectorItemsReordering(store.value);
24
24
  if (!itemsReordering) {
25
25
  throw new Error('There is no ongoing reordering.');
26
26
  }
@@ -28,10 +28,10 @@ export const useTreeViewItemsReordering = ({
28
28
  return {};
29
29
  }
30
30
  const canMoveItemToNewPosition = params.canMoveItemToNewPosition;
31
- const targetItemMeta = instance.getItemMeta(itemId);
32
- const targetItemIndex = instance.getItemIndex(targetItemMeta.id);
33
- const draggedItemMeta = instance.getItemMeta(itemsReordering.draggedItemId);
34
- const draggedItemIndex = instance.getItemIndex(draggedItemMeta.id);
31
+ const targetItemMeta = selectorItemMeta(store.value, itemId);
32
+ const targetItemIndex = selectorItemIndex(store.value, targetItemMeta.id);
33
+ const draggedItemMeta = selectorItemMeta(store.value, itemsReordering.draggedItemId);
34
+ const draggedItemIndex = selectorItemIndex(store.value, draggedItemMeta.id);
35
35
  const oldPosition = {
36
36
  parentId: draggedItemMeta.parentId,
37
37
  index: draggedItemIndex
@@ -67,7 +67,7 @@ export const useTreeViewItemsReordering = ({
67
67
  },
68
68
  'move-to-parent': targetItemMeta.parentId == null ? null : {
69
69
  parentId: targetItemMeta.parentId,
70
- index: instance.getItemOrderedChildrenIds(targetItemMeta.parentId).length
70
+ index: selectorItemOrderedChildrenIds(store.value, targetItemMeta.parentId).length
71
71
  }
72
72
  };
73
73
  const validActions = {};
@@ -78,9 +78,9 @@ export const useTreeViewItemsReordering = ({
78
78
  }
79
79
  });
80
80
  return validActions;
81
- }, [instance, state.itemsReordering, params.canMoveItemToNewPosition]);
81
+ }, [store, params.canMoveItemToNewPosition]);
82
82
  const startDraggingItem = React.useCallback(itemId => {
83
- setState(prevState => _extends({}, prevState, {
83
+ store.update(prevState => _extends({}, prevState, {
84
84
  itemsReordering: {
85
85
  targetItemId: itemId,
86
86
  draggedItemId: itemId,
@@ -88,24 +88,25 @@ export const useTreeViewItemsReordering = ({
88
88
  newPosition: null
89
89
  }
90
90
  }));
91
- }, [setState]);
91
+ }, [store]);
92
92
  const stopDraggingItem = React.useCallback(itemId => {
93
- if (state.itemsReordering == null || state.itemsReordering.draggedItemId !== itemId) {
93
+ const itemsReordering = selectorItemsReordering(store.value);
94
+ if (itemsReordering == null || itemsReordering.draggedItemId !== itemId) {
94
95
  return;
95
96
  }
96
- if (state.itemsReordering.draggedItemId === state.itemsReordering.targetItemId || state.itemsReordering.action == null || state.itemsReordering.newPosition == null) {
97
- setState(prevState => _extends({}, prevState, {
97
+ if (itemsReordering.draggedItemId === itemsReordering.targetItemId || itemsReordering.action == null || itemsReordering.newPosition == null) {
98
+ store.update(prevState => _extends({}, prevState, {
98
99
  itemsReordering: null
99
100
  }));
100
101
  return;
101
102
  }
102
- const draggedItemMeta = instance.getItemMeta(state.itemsReordering.draggedItemId);
103
+ const draggedItemMeta = selectorItemMeta(store.value, itemsReordering.draggedItemId);
103
104
  const oldPosition = {
104
105
  parentId: draggedItemMeta.parentId,
105
- index: instance.getItemIndex(draggedItemMeta.id)
106
+ index: selectorItemIndex(store.value, draggedItemMeta.id)
106
107
  };
107
- const newPosition = state.itemsReordering.newPosition;
108
- setState(prevState => _extends({}, prevState, {
108
+ const newPosition = itemsReordering.newPosition;
109
+ store.update(prevState => _extends({}, prevState, {
109
110
  itemsReordering: null,
110
111
  items: moveItemInTree({
111
112
  itemToMoveId: itemId,
@@ -120,7 +121,7 @@ export const useTreeViewItemsReordering = ({
120
121
  newPosition,
121
122
  oldPosition
122
123
  });
123
- }, [setState, state.itemsReordering, instance, params.onItemPositionChange]);
124
+ }, [store, params.onItemPositionChange]);
124
125
  const setDragTargetItem = React.useCallback(({
125
126
  itemId,
126
127
  validActions,
@@ -129,16 +130,16 @@ export const useTreeViewItemsReordering = ({
129
130
  cursorX,
130
131
  contentElement
131
132
  }) => {
132
- setState(prevState => {
133
+ store.update(prevState => {
133
134
  const prevSubState = prevState.itemsReordering;
134
- if (prevSubState == null || isAncestor(instance, itemId, prevSubState.draggedItemId)) {
135
+ if (prevSubState == null || isAncestor(store, itemId, prevSubState.draggedItemId)) {
135
136
  return prevState;
136
137
  }
137
138
  const action = chooseActionToApply({
138
139
  itemChildrenIndentation: params.itemChildrenIndentation,
139
140
  validActions,
140
141
  targetHeight,
141
- targetDepth: prevState.items.itemMetaMap[itemId].depth,
142
+ targetDepth: prevState.items.itemMetaLookup[itemId].depth,
142
143
  cursorY,
143
144
  cursorX,
144
145
  contentElement
@@ -155,7 +156,13 @@ export const useTreeViewItemsReordering = ({
155
156
  })
156
157
  });
157
158
  });
158
- }, [instance, setState, params.itemChildrenIndentation]);
159
+ }, [store, params.itemChildrenIndentation]);
160
+ const pluginContextValue = React.useMemo(() => ({
161
+ itemsReordering: {
162
+ enabled: params.itemsReordering,
163
+ isItemReorderable: params.isItemReorderable
164
+ }
165
+ }), [params.itemsReordering, params.isItemReorderable]);
159
166
  return {
160
167
  instance: {
161
168
  canItemBeDragged,
@@ -164,12 +171,7 @@ export const useTreeViewItemsReordering = ({
164
171
  stopDraggingItem,
165
172
  setDragTargetItem
166
173
  },
167
- contextValue: {
168
- itemsReordering: {
169
- enabled: params.itemsReordering,
170
- currentDrag: state.itemsReordering
171
- }
172
- }
174
+ contextValue: pluginContextValue
173
175
  };
174
176
  };
175
177
  useTreeViewItemsReordering.itemPlugin = useTreeViewItemsReorderingItemPlugin;
@@ -177,10 +179,10 @@ useTreeViewItemsReordering.getDefaultizedParams = ({
177
179
  params,
178
180
  experimentalFeatures
179
181
  }) => {
180
- const canUseFeature = experimentalFeatures?.indentationAtItemLevel && experimentalFeatures?.itemsReordering;
182
+ const canUseFeature = experimentalFeatures?.itemsReordering;
181
183
  if (process.env.NODE_ENV !== 'production') {
182
184
  if (params.itemsReordering && !canUseFeature) {
183
- warnOnce(['MUI X: The items reordering feature requires the `indentationAtItemLevel` and `itemsReordering` experimental features to be enabled.', 'You can do it by passing `experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}` to the `<RichTreeViewPro />`component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/']);
185
+ warnOnce(['MUI X: The items reordering feature requires the `itemsReordering` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ itemsReordering: true }}` to the `<RichTreeViewPro />`component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/']);
184
186
  }
185
187
  }
186
188
  return _extends({}, params, {
@@ -0,0 +1,35 @@
1
+ import { createSelector, selectorItemMetaLookup } from '@mui/x-tree-view/internals';
2
+ /**
3
+ * Get the items reordering state.
4
+ * @param {TreeViewState<[UseTreeViewItemsReorderingSignature]>} state The state of the tree view.
5
+ * @returns {TreeViewItemsReorderingState | null} The items reordering state.
6
+ */
7
+ export const selectorItemsReordering = state => state.itemsReordering;
8
+
9
+ /**
10
+ * Get the properties of the dragged item.
11
+ * @param {TreeViewState<[UseTreeViewItemsSignature, UseTreeViewItemsReorderingSignature]>} state The state of the tree view.
12
+ * @param {string} itemId The id of the item.
13
+ * @returns {TreeViewItemDraggedItemProperties | null} The properties of the dragged item if the current item is being dragged, `null` otherwise.
14
+ */
15
+ export const selectorItemsReorderingDraggedItemProperties = createSelector([selectorItemsReordering, selectorItemMetaLookup, (_, itemId) => itemId], (itemsReordering, itemMetaLookup, itemId) => {
16
+ if (!itemsReordering || itemsReordering.targetItemId !== itemId || itemsReordering.action == null) {
17
+ return null;
18
+ }
19
+ const targetDepth = itemsReordering.newPosition?.parentId == null ? 0 :
20
+ // The depth is always defined because drag&drop is only usable with Rich Tree View components.
21
+ itemMetaLookup[itemId].depth + 1;
22
+ return {
23
+ newPosition: itemsReordering.newPosition,
24
+ action: itemsReordering.action,
25
+ targetDepth
26
+ };
27
+ });
28
+
29
+ /**
30
+ * Check if the current item is a valid target for the dragged item.
31
+ * @param {TreeViewState<[UseTreeViewItemsReorderingSignature]>} state The state of the tree view.
32
+ * @param {string} itemId The id of the item.
33
+ * @returns {boolean} `true` if the current item is a valid target for the dragged item, `false` otherwise.
34
+ */
35
+ export const selectorItemsReorderingIsValidTarget = createSelector([selectorItemsReordering, (_, itemId) => itemId], (itemsReordering, itemId) => itemsReordering && itemsReordering.draggedItemId !== itemId);
@@ -1,17 +1,17 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from '@mui/x-tree-view/internals';
2
+ import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID, selectorItemMeta } from '@mui/x-tree-view/internals';
3
3
  /**
4
4
  * Checks if the item with the id itemIdB is an ancestor of the item with the id itemIdA.
5
5
  */
6
- export const isAncestor = (instance, itemIdA, itemIdB) => {
7
- const itemMetaA = instance.getItemMeta(itemIdA);
6
+ export const isAncestor = (store, itemIdA, itemIdB) => {
7
+ const itemMetaA = selectorItemMeta(store.value, itemIdA);
8
8
  if (itemMetaA.parentId === itemIdB) {
9
9
  return true;
10
10
  }
11
11
  if (itemMetaA.parentId == null) {
12
12
  return false;
13
13
  }
14
- return isAncestor(instance, itemMetaA.parentId, itemIdB);
14
+ return isAncestor(store, itemMetaA.parentId, itemIdB);
15
15
  };
16
16
 
17
17
  /**
@@ -88,12 +88,12 @@ export const moveItemInTree = ({
88
88
  newPosition,
89
89
  prevState
90
90
  }) => {
91
- const itemToMoveMeta = prevState.itemMetaMap[itemToMoveId];
91
+ const itemToMoveMeta = prevState.itemMetaLookup[itemToMoveId];
92
92
  const oldParentId = oldPosition.parentId ?? TREE_VIEW_ROOT_PARENT_ID;
93
93
  const newParentId = newPosition.parentId ?? TREE_VIEW_ROOT_PARENT_ID;
94
94
 
95
95
  // 1. Update the `itemOrderedChildrenIds`.
96
- const itemOrderedChildrenIds = _extends({}, prevState.itemOrderedChildrenIds);
96
+ const itemOrderedChildrenIds = _extends({}, prevState.itemOrderedChildrenIdsLookup);
97
97
  if (oldParentId === newParentId) {
98
98
  const updatedChildren = [...itemOrderedChildrenIds[oldParentId]];
99
99
  updatedChildren.splice(oldPosition.index, 1);
@@ -109,42 +109,50 @@ export const moveItemInTree = ({
109
109
  }
110
110
 
111
111
  // 2. Update the `itemChildrenIndexes`
112
- const itemChildrenIndexes = _extends({}, prevState.itemChildrenIndexes);
112
+ const itemChildrenIndexes = _extends({}, prevState.itemChildrenIndexesLookup);
113
113
  itemChildrenIndexes[oldParentId] = buildSiblingIndexes(itemOrderedChildrenIds[oldParentId]);
114
114
  if (newParentId !== oldParentId) {
115
115
  itemChildrenIndexes[newParentId] = buildSiblingIndexes(itemOrderedChildrenIds[newParentId]);
116
116
  }
117
117
 
118
- // 3. Update the `itemMetaMap`
119
- const itemMetaMap = _extends({}, prevState.itemMetaMap);
118
+ // 3. Update the `itemMetaLookup`
119
+ const itemMetaLookup = _extends({}, prevState.itemMetaLookup);
120
120
 
121
121
  // 3.1 Update the `expandable` property of the old and the new parent
122
+ function updateExpandable(itemId) {
123
+ const isExpandable = itemOrderedChildrenIds[itemId].length > 0;
124
+ if (itemMetaLookup[itemId].expandable !== isExpandable) {
125
+ itemMetaLookup[itemId] = _extends({}, itemMetaLookup[itemId], {
126
+ expandable: isExpandable
127
+ });
128
+ }
129
+ }
122
130
  if (oldParentId !== TREE_VIEW_ROOT_PARENT_ID && oldParentId !== newParentId) {
123
- itemMetaMap[oldParentId].expandable = itemOrderedChildrenIds[oldParentId].length > 0;
131
+ updateExpandable(oldParentId);
124
132
  }
125
133
  if (newParentId !== TREE_VIEW_ROOT_PARENT_ID && newParentId !== oldParentId) {
126
- itemMetaMap[newParentId].expandable = itemOrderedChildrenIds[newParentId].length > 0;
134
+ updateExpandable(newParentId);
127
135
  }
128
136
 
129
137
  // 3.2 Update the `parentId` and `depth` properties of the item to move
130
138
  // The depth is always defined because drag&drop is only usable with Rich Tree View components.
131
- const itemToMoveDepth = newPosition.parentId == null ? 0 : itemMetaMap[newParentId].depth + 1;
132
- itemMetaMap[itemToMoveId] = _extends({}, itemToMoveMeta, {
139
+ const itemToMoveDepth = newPosition.parentId == null ? 0 : itemMetaLookup[newParentId].depth + 1;
140
+ itemMetaLookup[itemToMoveId] = _extends({}, itemToMoveMeta, {
133
141
  parentId: newPosition.parentId,
134
142
  depth: itemToMoveDepth
135
143
  });
136
144
 
137
145
  // 3.3 Update the depth of all the children of the item to move
138
146
  const updateItemDepth = (itemId, depth) => {
139
- itemMetaMap[itemId] = _extends({}, itemMetaMap[itemId], {
147
+ itemMetaLookup[itemId] = _extends({}, itemMetaLookup[itemId], {
140
148
  depth
141
149
  });
142
150
  itemOrderedChildrenIds[itemId]?.forEach(childId => updateItemDepth(childId, depth + 1));
143
151
  };
144
152
  itemOrderedChildrenIds[itemToMoveId]?.forEach(childId => updateItemDepth(childId, itemToMoveDepth + 1));
145
153
  return _extends({}, prevState, {
146
- itemOrderedChildrenIds,
147
- itemChildrenIndexes,
148
- itemMetaMap
154
+ itemOrderedChildrenIdsLookup: itemOrderedChildrenIds,
155
+ itemChildrenIndexesLookup: itemChildrenIndexes,
156
+ itemMetaLookup
149
157
  });
150
158
  };
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTczMDQzMzYwMDAwMA==";
3
+ const releaseInfo = "MTczMjIzMDAwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
@@ -66,8 +66,7 @@ const RichTreeViewPro = exports.RichTreeViewPro = /*#__PURE__*/React.forwardRef(
66
66
  }
67
67
  const {
68
68
  getRootProps,
69
- contextValue,
70
- instance
69
+ contextValue
71
70
  } = (0, _internals.useTreeView)({
72
71
  plugins: _RichTreeViewPro.RICH_TREE_VIEW_PRO_PLUGINS,
73
72
  rootRef: ref,
@@ -91,8 +90,7 @@ const RichTreeViewPro = exports.RichTreeViewPro = /*#__PURE__*/React.forwardRef(
91
90
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Root, (0, _extends2.default)({}, rootProps, {
92
91
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_internals.RichTreeViewItems, {
93
92
  slots: slots,
94
- slotProps: slotProps,
95
- itemsToRender: instance.getItemsToRender()
93
+ slotProps: slotProps
96
94
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_xLicense.Watermark, {
97
95
  packageName: "x-tree-view-pro",
98
96
  releaseInfo: releaseInfo
@@ -177,7 +175,6 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
177
175
  * the feature will be fully disabled and any property / method call will not have any effect.
178
176
  */
179
177
  experimentalFeatures: _propTypes.default.shape({
180
- indentationAtItemLevel: _propTypes.default.bool,
181
178
  itemsReordering: _propTypes.default.bool,
182
179
  labelEditing: _propTypes.default.bool
183
180
  }),
@@ -305,6 +302,26 @@ process.env.NODE_ENV !== "production" ? RichTreeViewPro.propTypes = {
305
302
  * When `multiSelect` is true this takes an array of strings; when false (default) a string.
306
303
  */
307
304
  selectedItems: _propTypes.default.any,
305
+ /**
306
+ * When `selectionPropagation.descendants` is set to `true`.
307
+ *
308
+ * - Selecting a parent selects all its descendants automatically.
309
+ * - Deselecting a parent deselects all its descendants automatically.
310
+ *
311
+ * When `selectionPropagation.parents` is set to `true`.
312
+ *
313
+ * - Selecting all the descendants of a parent selects the parent automatically.
314
+ * - Deselecting a descendant of a selected parent deselects the parent automatically.
315
+ *
316
+ * Only works when `multiSelect` is `true`.
317
+ * On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all)
318
+ *
319
+ * @default { parents: false, descendants: false }
320
+ */
321
+ selectionPropagation: _propTypes.default.shape({
322
+ descendants: _propTypes.default.bool,
323
+ parents: _propTypes.default.bool
324
+ }),
308
325
  /**
309
326
  * The props used for each component slot.
310
327
  * @default {}