@mui/x-tree-view 8.0.0-alpha.0 → 8.0.0-alpha.2

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 (159) hide show
  1. package/CHANGELOG.md +651 -6
  2. package/README.md +2 -2
  3. package/RichTreeView/RichTreeView.js +2 -4
  4. package/RichTreeView/RichTreeView.types.d.ts +5 -18
  5. package/SimpleTreeView/SimpleTreeView.types.d.ts +2 -2
  6. package/TreeItem/TreeItem.js +4 -4
  7. package/TreeItem/TreeItem.types.d.ts +4 -2
  8. package/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  9. package/TreeItemIcon/TreeItemIcon.types.d.ts +1 -1
  10. package/TreeItemProvider/TreeItemProvider.d.ts +2 -4
  11. package/TreeItemProvider/TreeItemProvider.js +26 -11
  12. package/TreeItemProvider/TreeItemProvider.types.d.ts +1 -0
  13. package/hooks/index.d.ts +1 -0
  14. package/hooks/index.js +2 -1
  15. package/hooks/useTreeItemModel.d.ts +2 -0
  16. package/hooks/useTreeItemModel.js +11 -0
  17. package/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +2 -1
  18. package/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  19. package/hooks/useTreeViewApiRef.d.ts +1 -0
  20. package/index.js +1 -1
  21. package/internals/TreeViewItemDepthContext/TreeViewItemDepthContext.d.ts +3 -1
  22. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +2 -1
  23. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  24. package/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  25. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +4 -2
  26. package/internals/components/RichTreeViewItems.d.ts +3 -5
  27. package/internals/components/RichTreeViewItems.js +42 -30
  28. package/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  29. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.d.ts +36 -0
  30. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  31. package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +1 -5
  32. package/internals/hooks/useSelector.d.ts +4 -0
  33. package/internals/hooks/useSelector.js +6 -0
  34. package/internals/index.d.ts +6 -1
  35. package/internals/index.js +5 -1
  36. package/internals/models/itemPlugin.d.ts +5 -5
  37. package/internals/models/plugin.d.ts +20 -8
  38. package/internals/models/treeView.d.ts +6 -0
  39. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  40. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +124 -0
  41. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
  42. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -14
  43. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.d.ts +1 -0
  44. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
  45. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  46. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.d.ts +182 -0
  47. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  48. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +4 -16
  49. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  50. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
  51. package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
  52. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  53. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +718 -0
  54. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  55. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +15 -52
  56. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  57. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  58. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  59. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  60. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +74 -0
  61. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  62. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +7 -24
  63. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  64. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  65. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +32 -0
  66. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  67. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
  68. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +6 -6
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  70. package/internals/useTreeView/useTreeView.js +30 -17
  71. package/internals/useTreeView/useTreeView.types.d.ts +2 -3
  72. package/internals/useTreeView/useTreeViewBuildContext.d.ts +3 -1
  73. package/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  74. package/internals/utils/TreeViewStore.d.ts +12 -0
  75. package/internals/utils/TreeViewStore.js +24 -0
  76. package/internals/utils/selectors.d.ts +9 -0
  77. package/internals/utils/selectors.js +37 -0
  78. package/internals/utils/tree.d.ts +8 -8
  79. package/internals/utils/tree.js +51 -43
  80. package/models/items.d.ts +3 -2
  81. package/modern/RichTreeView/RichTreeView.js +2 -4
  82. package/modern/TreeItem/TreeItem.js +4 -4
  83. package/modern/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  84. package/modern/TreeItemProvider/TreeItemProvider.js +26 -11
  85. package/modern/hooks/index.js +2 -1
  86. package/modern/hooks/useTreeItemModel.js +11 -0
  87. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  88. package/modern/index.js +1 -1
  89. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  90. package/modern/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  91. package/modern/internals/components/RichTreeViewItems.js +42 -30
  92. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  93. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  94. package/modern/internals/hooks/useSelector.js +6 -0
  95. package/modern/internals/index.js +5 -1
  96. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  97. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
  98. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
  99. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  100. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  101. package/modern/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  102. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  103. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  104. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  105. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  106. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  107. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  108. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  109. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  110. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  111. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  112. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  113. package/modern/internals/useTreeView/useTreeView.js +30 -17
  114. package/modern/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  115. package/modern/internals/utils/TreeViewStore.js +24 -0
  116. package/modern/internals/utils/selectors.js +37 -0
  117. package/modern/internals/utils/tree.js +51 -43
  118. package/modern/useTreeItem/useTreeItem.js +26 -11
  119. package/node/RichTreeView/RichTreeView.js +2 -4
  120. package/node/TreeItem/TreeItem.js +4 -4
  121. package/node/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +2 -2
  122. package/node/TreeItemProvider/TreeItemProvider.js +26 -10
  123. package/node/hooks/index.js +8 -1
  124. package/node/hooks/useTreeItemModel.js +17 -0
  125. package/node/hooks/useTreeItemUtils/useTreeItemUtils.js +32 -15
  126. package/node/index.js +1 -1
  127. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  128. package/node/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  129. package/node/internals/components/RichTreeViewItems.js +42 -30
  130. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +12 -13
  131. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +15 -0
  132. package/node/internals/hooks/useSelector.js +13 -0
  133. package/node/internals/index.js +47 -1
  134. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  135. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +23 -0
  136. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +14 -0
  137. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  138. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +40 -0
  139. package/node/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +16 -13
  140. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -100
  141. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +109 -0
  142. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +30 -27
  143. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  144. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  145. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  146. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +32 -0
  147. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  148. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +46 -35
  149. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +15 -0
  150. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +24 -14
  151. package/node/internals/useTreeView/useTreeView.js +30 -17
  152. package/node/internals/useTreeView/useTreeViewBuildContext.js +25 -18
  153. package/node/internals/utils/TreeViewStore.js +31 -0
  154. package/node/internals/utils/selectors.js +44 -0
  155. package/node/internals/utils/tree.js +51 -43
  156. package/node/useTreeItem/useTreeItem.js +26 -11
  157. package/package.json +6 -4
  158. package/useTreeItem/useTreeItem.js +26 -11
  159. package/useTreeItem/useTreeItem.types.d.ts +9 -0
@@ -12,19 +12,25 @@ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallb
12
12
  var _tree = require("../../utils/tree");
13
13
  var _plugins = require("../../utils/plugins");
14
14
  var _useTreeViewLabel = require("../useTreeViewLabel");
15
+ var _useSelector = require("../../hooks/useSelector");
16
+ var _useTreeViewItems = require("../useTreeViewItems/useTreeViewItems.selectors");
17
+ var _useTreeViewLabel2 = require("../useTreeViewLabel/useTreeViewLabel.selectors");
18
+ var _useTreeViewSelection = require("../useTreeViewSelection/useTreeViewSelection.selectors");
19
+ var _useTreeViewExpansion = require("../useTreeViewExpansion/useTreeViewExpansion.selectors");
15
20
  function isPrintableKey(string) {
16
21
  return !!string && string.length === 1 && !!string.match(/\S/);
17
22
  }
18
23
  const useTreeViewKeyboardNavigation = ({
19
24
  instance,
20
- params,
21
- state
25
+ store,
26
+ params
22
27
  }) => {
23
28
  const isRtl = (0, _RtlProvider.useRtl)();
24
29
  const firstCharMap = React.useRef({});
25
30
  const updateFirstCharMap = (0, _useEventCallback.default)(callback => {
26
31
  firstCharMap.current = callback(firstCharMap.current);
27
32
  });
33
+ const itemMetaLookup = (0, _useSelector.useSelector)(store, _useTreeViewItems.selectorItemMetaLookup);
28
34
  React.useEffect(() => {
29
35
  if (instance.areItemUpdatesPrevented()) {
30
36
  return;
@@ -33,16 +39,16 @@ const useTreeViewKeyboardNavigation = ({
33
39
  const processItem = item => {
34
40
  newFirstCharMap[item.id] = item.label.substring(0, 1).toLowerCase();
35
41
  };
36
- Object.values(state.items.itemMetaMap).forEach(processItem);
42
+ Object.values(itemMetaLookup).forEach(processItem);
37
43
  firstCharMap.current = newFirstCharMap;
38
- }, [state.items.itemMetaMap, params.getItemId, instance]);
44
+ }, [itemMetaLookup, params.getItemId, instance]);
39
45
  const getFirstMatchingItem = (itemId, query) => {
40
46
  const cleanQuery = query.toLowerCase();
41
47
  const getNextItem = itemIdToCheck => {
42
- const nextItemId = (0, _tree.getNextNavigableItem)(instance, itemIdToCheck);
48
+ const nextItemId = (0, _tree.getNextNavigableItem)(store.value, itemIdToCheck);
43
49
  // We reached the end of the tree, check from the beginning
44
50
  if (nextItemId === null) {
45
- return (0, _tree.getFirstNavigableItem)(instance);
51
+ return (0, _tree.getFirstNavigableItem)(store.value);
46
52
  }
47
53
  return nextItemId;
48
54
  };
@@ -60,9 +66,9 @@ const useTreeViewKeyboardNavigation = ({
60
66
  }
61
67
  return matchingItemId;
62
68
  };
63
- const canToggleItemSelection = itemId => !params.disableSelection && !instance.isItemDisabled(itemId);
69
+ const canToggleItemSelection = itemId => !params.disableSelection && !(0, _useTreeViewItems.selectorIsItemDisabled)(store.value, itemId);
64
70
  const canToggleItemExpansion = itemId => {
65
- return !instance.isItemDisabled(itemId) && instance.isItemExpandable(itemId);
71
+ return !(0, _useTreeViewItems.selectorIsItemDisabled)(store.value, itemId) && (0, _useTreeViewExpansion.selectorIsItemExpandable)(store.value, itemId);
66
72
  };
67
73
 
68
74
  // ARIA specification: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/#keyboardinteraction
@@ -99,7 +105,10 @@ const useTreeViewKeyboardNavigation = ({
99
105
  // If the focused item has no children, we select it.
100
106
  case key === 'Enter':
101
107
  {
102
- if ((0, _plugins.hasPlugin)(instance, _useTreeViewLabel.useTreeViewLabel) && instance.isItemEditable(itemId) && !instance.isItemBeingEdited(itemId)) {
108
+ if ((0, _plugins.hasPlugin)(instance, _useTreeViewLabel.useTreeViewLabel) && (0, _useTreeViewLabel2.selectorIsItemEditable)(store.value, {
109
+ itemId,
110
+ isItemEditable: params.isItemEditable
111
+ }) && !(0, _useTreeViewLabel2.selectorIsItemBeingEdited)(store.value, itemId)) {
103
112
  instance.setEditedItemId(itemId);
104
113
  } else if (canToggleItemExpansion(itemId)) {
105
114
  instance.toggleItemExpansion(event, itemId);
@@ -112,7 +121,7 @@ const useTreeViewKeyboardNavigation = ({
112
121
  itemId,
113
122
  keepExistingSelection: true
114
123
  });
115
- } else if (!instance.isItemSelected(itemId)) {
124
+ } else if (!(0, _useTreeViewSelection.selectorIsItemSelected)(store.value, itemId)) {
116
125
  instance.selectItem({
117
126
  event,
118
127
  itemId
@@ -126,7 +135,7 @@ const useTreeViewKeyboardNavigation = ({
126
135
  // Focus the next focusable item
127
136
  case key === 'ArrowDown':
128
137
  {
129
- const nextItem = (0, _tree.getNextNavigableItem)(instance, itemId);
138
+ const nextItem = (0, _tree.getNextNavigableItem)(store.value, itemId);
130
139
  if (nextItem) {
131
140
  event.preventDefault();
132
141
  instance.focusItem(event, nextItem);
@@ -143,7 +152,7 @@ const useTreeViewKeyboardNavigation = ({
143
152
  // Focuses the previous focusable item
144
153
  case key === 'ArrowUp':
145
154
  {
146
- const previousItem = (0, _tree.getPreviousNavigableItem)(instance, itemId);
155
+ const previousItem = (0, _tree.getPreviousNavigableItem)(store.value, itemId);
147
156
  if (previousItem) {
148
157
  event.preventDefault();
149
158
  instance.focusItem(event, previousItem);
@@ -164,8 +173,8 @@ const useTreeViewKeyboardNavigation = ({
164
173
  if (ctrlPressed) {
165
174
  return;
166
175
  }
167
- if (instance.isItemExpanded(itemId)) {
168
- const nextItemId = (0, _tree.getNextNavigableItem)(instance, itemId);
176
+ if ((0, _useTreeViewExpansion.selectorIsItemExpanded)(store.value, itemId)) {
177
+ const nextItemId = (0, _tree.getNextNavigableItem)(store.value, itemId);
169
178
  if (nextItemId) {
170
179
  instance.focusItem(event, nextItemId);
171
180
  event.preventDefault();
@@ -184,11 +193,11 @@ const useTreeViewKeyboardNavigation = ({
184
193
  if (ctrlPressed) {
185
194
  return;
186
195
  }
187
- if (canToggleItemExpansion(itemId) && instance.isItemExpanded(itemId)) {
196
+ if (canToggleItemExpansion(itemId) && (0, _useTreeViewExpansion.selectorIsItemExpanded)(store.value, itemId)) {
188
197
  instance.toggleItemExpansion(event, itemId);
189
198
  event.preventDefault();
190
199
  } else {
191
- const parent = instance.getItemMeta(itemId).parentId;
200
+ const parent = (0, _useTreeViewItems.selectorItemParentId)(store.value, itemId);
192
201
  if (parent) {
193
202
  instance.focusItem(event, parent);
194
203
  event.preventDefault();
@@ -205,7 +214,7 @@ const useTreeViewKeyboardNavigation = ({
205
214
  if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
206
215
  instance.selectRangeFromStartToItem(event, itemId);
207
216
  } else {
208
- instance.focusItem(event, (0, _tree.getFirstNavigableItem)(instance));
217
+ instance.focusItem(event, (0, _tree.getFirstNavigableItem)(store.value));
209
218
  }
210
219
  event.preventDefault();
211
220
  break;
@@ -219,7 +228,7 @@ const useTreeViewKeyboardNavigation = ({
219
228
  if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
220
229
  instance.selectRangeFromItemToEnd(event, itemId);
221
230
  } else {
222
- instance.focusItem(event, (0, _tree.getLastNavigableItem)(instance));
231
+ instance.focusItem(event, (0, _tree.getLastNavigableItem)(store.value));
223
232
  }
224
233
  event.preventDefault();
225
234
  break;
@@ -7,30 +7,38 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.useTreeViewLabelItemPlugin = void 0;
8
8
  var React = _interopRequireWildcard(require("react"));
9
9
  var _TreeViewProvider = require("../../TreeViewProvider");
10
+ var _useSelector = require("../../hooks/useSelector");
11
+ var _useTreeViewLabel = require("./useTreeViewLabel.selectors");
10
12
  const useTreeViewLabelItemPlugin = ({
11
13
  props
12
14
  }) => {
13
15
  const {
14
- instance
16
+ store,
17
+ label: {
18
+ isItemEditable
19
+ }
15
20
  } = (0, _TreeViewProvider.useTreeViewContext)();
16
21
  const {
17
22
  label,
18
23
  itemId
19
24
  } = props;
20
25
  const [labelInputValue, setLabelInputValue] = React.useState(label);
21
- const isItemBeingEdited = instance.isItemBeingEdited(itemId);
26
+ const editable = (0, _useSelector.useSelector)(store, _useTreeViewLabel.selectorIsItemEditable, {
27
+ itemId,
28
+ isItemEditable
29
+ });
30
+ const editing = (0, _useSelector.useSelector)(store, _useTreeViewLabel.selectorIsItemBeingEdited, itemId);
22
31
  React.useEffect(() => {
23
- if (!isItemBeingEdited) {
32
+ if (!editing) {
24
33
  setLabelInputValue(label);
25
34
  }
26
- }, [isItemBeingEdited, label]);
35
+ }, [editing, label]);
27
36
  return {
28
37
  propsEnhancers: {
29
38
  labelInput: ({
30
39
  externalEventHandlers,
31
40
  interactions
32
41
  }) => {
33
- const editable = instance.isItemEditable(itemId);
34
42
  if (!editable) {
35
43
  return {};
36
44
  }
@@ -11,41 +11,26 @@ var React = _interopRequireWildcard(require("react"));
11
11
  var _warning = require("@mui/x-internals/warning");
12
12
  var _useTreeViewLabel = require("./useTreeViewLabel.itemPlugin");
13
13
  const useTreeViewLabel = ({
14
- instance,
15
- state,
16
- setState,
14
+ store,
17
15
  params
18
16
  }) => {
19
- const editedItemRef = React.useRef(state.editedItemId);
20
- const isItemBeingEditedRef = itemId => editedItemRef.current === itemId;
21
17
  const setEditedItemId = editedItemId => {
22
- setState(prevState => (0, _extends2.default)({}, prevState, {
23
- editedItemId
18
+ store.update(prevState => (0, _extends2.default)({}, prevState, {
19
+ label: {
20
+ editedItemId
21
+ }
24
22
  }));
25
- editedItemRef.current = editedItemId;
26
- };
27
- const isItemBeingEdited = itemId => itemId === state.editedItemId;
28
- const isTreeViewEditable = Boolean(params.isItemEditable);
29
- const isItemEditable = itemId => {
30
- if (itemId == null || !isTreeViewEditable) {
31
- return false;
32
- }
33
- const item = instance.getItem(itemId);
34
- if (!item) {
35
- return false;
36
- }
37
- return typeof params.isItemEditable === 'function' ? params.isItemEditable(item) : Boolean(params.isItemEditable);
38
23
  };
39
24
  const updateItemLabel = (itemId, label) => {
40
25
  if (!label) {
41
26
  throw new Error(['MUI X: The Tree View component requires all items to have a `label` property.', 'The label of an item cannot be empty.', itemId].join('\n'));
42
27
  }
43
- setState(prevState => {
44
- const item = prevState.items.itemMetaMap[itemId];
28
+ store.update(prevState => {
29
+ const item = prevState.items.itemMetaLookup[itemId];
45
30
  if (item.label !== label) {
46
31
  return (0, _extends2.default)({}, prevState, {
47
32
  items: (0, _extends2.default)({}, prevState.items, {
48
- itemMetaMap: (0, _extends2.default)({}, prevState.items.itemMetaMap, {
33
+ itemMetaLookup: (0, _extends2.default)({}, prevState.items.itemMetaLookup, {
49
34
  [itemId]: (0, _extends2.default)({}, item, {
50
35
  label
51
36
  })
@@ -59,18 +44,20 @@ const useTreeViewLabel = ({
59
44
  params.onItemLabelChange(itemId, label);
60
45
  }
61
46
  };
47
+ const pluginContextValue = React.useMemo(() => ({
48
+ label: {
49
+ isItemEditable: params.isItemEditable
50
+ }
51
+ }), [params.isItemEditable]);
62
52
  return {
63
53
  instance: {
64
54
  setEditedItemId,
65
- isItemBeingEdited,
66
- updateItemLabel,
67
- isItemEditable,
68
- isTreeViewEditable,
69
- isItemBeingEditedRef
55
+ updateItemLabel
70
56
  },
71
57
  publicAPI: {
72
58
  updateItemLabel
73
- }
59
+ },
60
+ contextValue: pluginContextValue
74
61
  };
75
62
  };
76
63
  exports.useTreeViewLabel = useTreeViewLabel;
@@ -90,7 +77,9 @@ useTreeViewLabel.getDefaultizedParams = ({
90
77
  });
91
78
  };
92
79
  useTreeViewLabel.getInitialState = () => ({
93
- editedItemId: null
80
+ label: {
81
+ editedItemId: null
82
+ }
94
83
  });
95
84
  useTreeViewLabel.params = {
96
85
  onItemLabelChange: true,
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.selectorIsItemEditable = exports.selectorIsItemBeingEdited = void 0;
7
+ var _selectors = require("../../utils/selectors");
8
+ var _useTreeViewItems = require("../useTreeViewItems/useTreeViewItems.selectors");
9
+ const selectorTreeViewLabelState = state => state.label;
10
+
11
+ /**
12
+ * Check if an item is editable.
13
+ * @param {TreeViewState<[UseTreeViewItemsSignature]>} state The state of the tree view.
14
+ * @param {object} params The parameters.
15
+ * @param {TreeViewItemId} params.itemId The id of the item to check.
16
+ * @param {((item: any) => boolean) | boolean} params.isItemEditable The function to determine if an item is editable.
17
+ * @returns {boolean} `true` if the item is editable, `false` otherwise.
18
+ */
19
+ const selectorIsItemEditable = exports.selectorIsItemEditable = (0, _selectors.createSelector)([(_, args) => args, (state, args) => (0, _useTreeViewItems.selectorItemModel)(state, args.itemId)], (args, itemModel) => {
20
+ if (!itemModel || !args.isItemEditable) {
21
+ return false;
22
+ }
23
+ return typeof args.isItemEditable === 'function' ? args.isItemEditable(itemModel) : true;
24
+ });
25
+
26
+ /**
27
+ * Check if an item is being edited.
28
+ * @param {TreeViewState<[UseTreeViewLabelSignature]>} state The state of the tree view.
29
+ * @param {TreeViewItemId} itemId The id of the item to check.
30
+ * @returns {boolean} `true` if the item is being edited, `false` otherwise.
31
+ */
32
+ const selectorIsItemBeingEdited = exports.selectorIsItemBeingEdited = (0, _selectors.createSelector)([selectorTreeViewLabelState, (_, itemId) => itemId], (labelState, itemId) => labelState.editedItemId === itemId);
@@ -7,9 +7,11 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.useTreeViewSelectionItemPlugin = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var _TreeViewProvider = require("../../TreeViewProvider");
10
+ var _useTreeViewItems = require("../useTreeViewItems/useTreeViewItems.selectors");
11
+ var _useTreeViewSelection = require("./useTreeViewSelection.selectors");
10
12
  function getCheckboxStatus({
11
13
  itemId,
12
- instance,
14
+ store,
13
15
  selectionPropagation,
14
16
  selected
15
17
  }) {
@@ -19,7 +21,7 @@ function getCheckboxStatus({
19
21
  checked: true
20
22
  };
21
23
  }
22
- const children = instance.getItemOrderedChildrenIds(itemId);
24
+ const children = (0, _useTreeViewItems.selectorItemOrderedChildrenIds)(store.value, itemId);
23
25
  if (children.length === 0) {
24
26
  return {
25
27
  indeterminate: false,
@@ -30,13 +32,13 @@ function getCheckboxStatus({
30
32
  let hasUnSelectedDescendant = false;
31
33
  const traverseDescendants = itemToTraverseId => {
32
34
  if (itemToTraverseId !== itemId) {
33
- if (instance.isItemSelected(itemToTraverseId)) {
35
+ if ((0, _useTreeViewSelection.selectorIsItemSelected)(store.value, itemToTraverseId)) {
34
36
  hasSelectedDescendant = true;
35
37
  } else {
36
38
  hasUnSelectedDescendant = true;
37
39
  }
38
40
  }
39
- instance.getItemOrderedChildrenIds(itemToTraverseId).forEach(traverseDescendants);
41
+ (0, _useTreeViewItems.selectorItemOrderedChildrenIds)(store.value, itemToTraverseId).forEach(traverseDescendants);
40
42
  };
41
43
  traverseDescendants(itemId);
42
44
  return {
@@ -51,7 +53,7 @@ const useTreeViewSelectionItemPlugin = ({
51
53
  itemId
52
54
  } = props;
53
55
  const {
54
- instance,
56
+ store,
55
57
  selection: {
56
58
  disableSelection,
57
59
  checkboxSelection,
@@ -76,7 +78,7 @@ const useTreeViewSelectionItemPlugin = ({
76
78
  interactions.handleCheckboxSelection(event);
77
79
  };
78
80
  const checkboxStatus = getCheckboxStatus({
79
- instance,
81
+ store,
80
82
  itemId,
81
83
  selectionPropagation,
82
84
  selected: status.selected
@@ -8,32 +8,30 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.useTreeViewSelection = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var React = _interopRequireWildcard(require("react"));
11
+ var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
11
12
  var _tree = require("../../utils/tree");
12
13
  var _useTreeViewSelection = require("./useTreeViewSelection.utils");
13
- var _useTreeViewSelection2 = require("./useTreeViewSelection.itemPlugin");
14
+ var _useTreeViewSelection2 = require("./useTreeViewSelection.selectors");
15
+ var _useTreeViewSelection3 = require("./useTreeViewSelection.itemPlugin");
14
16
  const useTreeViewSelection = ({
15
- instance,
17
+ store,
16
18
  params,
17
19
  models
18
20
  }) => {
19
21
  const lastSelectedItem = React.useRef(null);
20
22
  const lastSelectedRange = React.useRef({});
21
- const selectedItemsMap = React.useMemo(() => {
22
- const temp = new Map();
23
- if (Array.isArray(models.selectedItems.value)) {
24
- models.selectedItems.value.forEach(id => {
25
- temp.set(id, true);
26
- });
27
- } else if (models.selectedItems.value != null) {
28
- temp.set(models.selectedItems.value, true);
29
- }
30
- return temp;
31
- }, [models.selectedItems.value]);
23
+ (0, _useEnhancedEffect.default)(() => {
24
+ store.update(prevState => (0, _extends2.default)({}, prevState, {
25
+ selection: {
26
+ selectedItemsMap: (0, _useTreeViewSelection.createSelectedItemsMap)(models.selectedItems.value)
27
+ }
28
+ }));
29
+ }, [store, models.selectedItems.value]);
32
30
  const setSelectedItems = (event, newModel, additionalItemsToPropagate) => {
33
31
  let cleanModel;
34
32
  if (params.multiSelect && (params.selectionPropagation.descendants || params.selectionPropagation.parents)) {
35
33
  cleanModel = (0, _useTreeViewSelection.propagateSelection)({
36
- instance,
34
+ store,
37
35
  selectionPropagation: params.selectionPropagation,
38
36
  newModel: newModel,
39
37
  oldModel: models.selectedItems.value,
@@ -45,7 +43,7 @@ const useTreeViewSelection = ({
45
43
  if (params.onItemSelectionToggle) {
46
44
  if (params.multiSelect) {
47
45
  const changes = (0, _useTreeViewSelection.getAddedAndRemovedItems)({
48
- instance,
46
+ store,
49
47
  newModel: cleanModel,
50
48
  oldModel: models.selectedItems.value
51
49
  });
@@ -71,7 +69,6 @@ const useTreeViewSelection = ({
71
69
  }
72
70
  models.selectedItems.setControlledValue(cleanModel);
73
71
  };
74
- const isItemSelected = itemId => selectedItemsMap.has(itemId);
75
72
  const selectItem = ({
76
73
  event,
77
74
  itemId,
@@ -84,7 +81,7 @@ const useTreeViewSelection = ({
84
81
  let newSelected;
85
82
  if (keepExistingSelection) {
86
83
  const cleanSelectedItems = (0, _useTreeViewSelection.convertSelectedItemsToArray)(models.selectedItems.value);
87
- const isSelectedBefore = instance.isItemSelected(itemId);
84
+ const isSelectedBefore = (0, _useTreeViewSelection2.selectorIsItemSelected)(store.value, itemId);
88
85
  if (isSelectedBefore && (shouldBeSelected === false || shouldBeSelected == null)) {
89
86
  newSelected = cleanSelectedItems.filter(id => id !== itemId);
90
87
  } else if (!isSelectedBefore && (shouldBeSelected === true || shouldBeSelected == null)) {
@@ -94,14 +91,14 @@ const useTreeViewSelection = ({
94
91
  }
95
92
  } else {
96
93
  // eslint-disable-next-line no-lonely-if
97
- if (shouldBeSelected === false || shouldBeSelected == null && instance.isItemSelected(itemId)) {
94
+ if (shouldBeSelected === false || shouldBeSelected == null && (0, _useTreeViewSelection2.selectorIsItemSelected)(store.value, itemId)) {
98
95
  newSelected = params.multiSelect ? [] : null;
99
96
  } else {
100
97
  newSelected = params.multiSelect ? [itemId] : itemId;
101
98
  }
102
99
  }
103
100
  setSelectedItems(event, newSelected,
104
- // If shouldBeSelected === instance.isItemSelect(itemId), we still want to propagate the select.
101
+ // If shouldBeSelected === selectorIsItemSelected(store, itemId), we still want to propagate the select.
105
102
  // This is useful when the element is in an indeterminate state.
106
103
  [itemId]);
107
104
  lastSelectedItem.current = itemId;
@@ -121,7 +118,7 @@ const useTreeViewSelection = ({
121
118
 
122
119
  // Add to the model the items that are part of the new range and not already part of the model.
123
120
  const selectedItemsLookup = (0, _useTreeViewSelection.getLookupFromArray)(newSelectedItems);
124
- const range = (0, _tree.getNonDisabledItemsInRange)(instance, start, end);
121
+ const range = (0, _tree.getNonDisabledItemsInRange)(store.value, start, end);
125
122
  const itemsToAddToModel = range.filter(id => !selectedItemsLookup[id]);
126
123
  newSelectedItems = newSelectedItems.concat(itemsToAddToModel);
127
124
  setSelectedItems(event, newSelectedItems);
@@ -129,21 +126,21 @@ const useTreeViewSelection = ({
129
126
  };
130
127
  const expandSelectionRange = (event, itemId) => {
131
128
  if (lastSelectedItem.current != null) {
132
- const [start, end] = (0, _tree.findOrderInTremauxTree)(instance, itemId, lastSelectedItem.current);
129
+ const [start, end] = (0, _tree.findOrderInTremauxTree)(store.value, itemId, lastSelectedItem.current);
133
130
  selectRange(event, [start, end]);
134
131
  }
135
132
  };
136
133
  const selectRangeFromStartToItem = (event, itemId) => {
137
- selectRange(event, [(0, _tree.getFirstNavigableItem)(instance), itemId]);
134
+ selectRange(event, [(0, _tree.getFirstNavigableItem)(store.value), itemId]);
138
135
  };
139
136
  const selectRangeFromItemToEnd = (event, itemId) => {
140
- selectRange(event, [itemId, (0, _tree.getLastNavigableItem)(instance)]);
137
+ selectRange(event, [itemId, (0, _tree.getLastNavigableItem)(store.value)]);
141
138
  };
142
139
  const selectAllNavigableItems = event => {
143
140
  if (params.disableSelection || !params.multiSelect) {
144
141
  return;
145
142
  }
146
- const navigableItems = (0, _tree.getAllNavigableItems)(instance);
143
+ const navigableItems = (0, _tree.getAllNavigableItems)(store.value);
147
144
  setSelectedItems(event, navigableItems);
148
145
  lastSelectedRange.current = (0, _useTreeViewSelection.getLookupFromArray)(navigableItems);
149
146
  };
@@ -172,6 +169,17 @@ const useTreeViewSelection = ({
172
169
  }
173
170
  setSelectedItems(event, newSelectedItems);
174
171
  };
172
+ const pluginContextValue = React.useMemo(() => ({
173
+ selection: {
174
+ multiSelect: params.multiSelect,
175
+ checkboxSelection: params.checkboxSelection,
176
+ disableSelection: params.disableSelection,
177
+ selectionPropagation: {
178
+ descendants: params.selectionPropagation.descendants,
179
+ parents: params.selectionPropagation.parents
180
+ }
181
+ }
182
+ }), [params.multiSelect, params.checkboxSelection, params.disableSelection, params.selectionPropagation.descendants, params.selectionPropagation.parents]);
175
183
  return {
176
184
  getRootProps: () => ({
177
185
  'aria-multiselectable': params.multiSelect
@@ -180,7 +188,6 @@ const useTreeViewSelection = ({
180
188
  selectItem
181
189
  },
182
190
  instance: {
183
- isItemSelected,
184
191
  selectItem,
185
192
  selectAllNavigableItems,
186
193
  expandSelectionRange,
@@ -188,24 +195,18 @@ const useTreeViewSelection = ({
188
195
  selectRangeFromItemToEnd,
189
196
  selectItemFromArrowNavigation
190
197
  },
191
- contextValue: {
192
- selection: {
193
- multiSelect: params.multiSelect,
194
- checkboxSelection: params.checkboxSelection,
195
- disableSelection: params.disableSelection,
196
- selectionPropagation: params.selectionPropagation
197
- }
198
- }
198
+ contextValue: pluginContextValue
199
199
  };
200
200
  };
201
201
  exports.useTreeViewSelection = useTreeViewSelection;
202
- useTreeViewSelection.itemPlugin = _useTreeViewSelection2.useTreeViewSelectionItemPlugin;
202
+ useTreeViewSelection.itemPlugin = _useTreeViewSelection3.useTreeViewSelectionItemPlugin;
203
203
  useTreeViewSelection.models = {
204
204
  selectedItems: {
205
205
  getDefaultValue: params => params.defaultSelectedItems
206
206
  }
207
207
  };
208
208
  const DEFAULT_SELECTED_ITEMS = [];
209
+ const EMPTY_SELECTION_PROPAGATION = {};
209
210
  useTreeViewSelection.getDefaultizedParams = ({
210
211
  params
211
212
  }) => (0, _extends2.default)({}, params, {
@@ -213,7 +214,17 @@ useTreeViewSelection.getDefaultizedParams = ({
213
214
  multiSelect: params.multiSelect ?? false,
214
215
  checkboxSelection: params.checkboxSelection ?? false,
215
216
  defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_ITEMS : null),
216
- selectionPropagation: params.selectionPropagation ?? {}
217
+ selectionPropagation: params.selectionPropagation ?? EMPTY_SELECTION_PROPAGATION
218
+ });
219
+ useTreeViewSelection.getInitialState = params => ({
220
+ selection: {
221
+ selectedItemsMap: (0, _useTreeViewSelection.createSelectedItemsMap)(params.selectedItems === undefined ? params.defaultSelectedItems : params.selectedItems)
222
+ }
223
+ });
224
+ useTreeViewSelection.getInitialState = params => ({
225
+ selection: {
226
+ selectedItemsMap: (0, _useTreeViewSelection.createSelectedItemsMap)(params.selectedItems === undefined ? params.defaultSelectedItems : params.selectedItems)
227
+ }
217
228
  });
218
229
  useTreeViewSelection.params = {
219
230
  disableSelection: true,
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.selectorIsItemSelected = void 0;
7
+ var _selectors = require("../../utils/selectors");
8
+ const selectorTreeViewSelectionState = state => state.selection;
9
+
10
+ /**
11
+ * Check if an item is selected.
12
+ * @param {TreeViewState<[UseTreeViewSelectionSignature]>} state The state of the tree view.
13
+ * @returns {boolean} `true` if the item is selected, `false` otherwise.
14
+ */
15
+ const selectorIsItemSelected = exports.selectorIsItemSelected = (0, _selectors.createSelector)([selectorTreeViewSelectionState, (_, itemId) => itemId], (selectionState, itemId) => selectionState.selectedItemsMap.has(itemId));