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

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 (164) hide show
  1. package/CHANGELOG.md +2215 -119
  2. package/README.md +3 -3
  3. package/RichTreeView/RichTreeView.js +2 -4
  4. package/RichTreeView/RichTreeView.types.d.ts +6 -19
  5. package/SimpleTreeView/SimpleTreeView.types.d.ts +3 -3
  6. package/TreeItem/TreeItem.d.ts +1 -1
  7. package/TreeItem/TreeItem.js +4 -4
  8. package/TreeItem/TreeItem.types.d.ts +4 -2
  9. package/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  10. package/TreeItemIcon/TreeItemIcon.types.d.ts +1 -1
  11. package/TreeItemProvider/TreeItemProvider.d.ts +2 -4
  12. package/TreeItemProvider/TreeItemProvider.js +26 -11
  13. package/TreeItemProvider/TreeItemProvider.types.d.ts +1 -0
  14. package/hooks/index.d.ts +1 -0
  15. package/hooks/index.js +2 -1
  16. package/hooks/useTreeItemModel.d.ts +2 -0
  17. package/hooks/useTreeItemModel.js +11 -0
  18. package/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +6 -5
  19. package/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  20. package/hooks/useTreeViewApiRef.d.ts +2 -1
  21. package/index.js +1 -1
  22. package/internals/TreeViewItemDepthContext/TreeViewItemDepthContext.d.ts +3 -1
  23. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +2 -1
  24. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  25. package/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  26. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +5 -3
  27. package/internals/components/RichTreeViewItems.d.ts +3 -5
  28. package/internals/components/RichTreeViewItems.js +42 -30
  29. package/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  30. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.d.ts +36 -0
  31. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  32. package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +1 -5
  33. package/internals/hooks/useInstanceEventHandler.js +1 -1
  34. package/internals/hooks/useSelector.d.ts +4 -0
  35. package/internals/hooks/useSelector.js +6 -0
  36. package/internals/index.d.ts +6 -1
  37. package/internals/index.js +5 -1
  38. package/internals/models/itemPlugin.d.ts +7 -7
  39. package/internals/models/plugin.d.ts +22 -10
  40. package/internals/models/treeView.d.ts +6 -0
  41. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +41 -30
  42. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +180 -0
  43. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +24 -0
  44. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -18
  45. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.d.ts +4 -0
  46. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +19 -0
  47. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  48. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.d.ts +182 -0
  49. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  50. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +4 -16
  51. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  52. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
  53. package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
  54. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  55. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +886 -0
  56. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  57. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +36 -55
  58. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  59. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  60. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  61. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  62. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +74 -0
  63. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  64. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +7 -24
  65. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +16 -17
  66. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  67. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +32 -0
  68. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
  70. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +6 -6
  71. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  72. package/internals/useTreeView/useTreeView.d.ts +1 -1
  73. package/internals/useTreeView/useTreeView.js +30 -17
  74. package/internals/useTreeView/useTreeView.types.d.ts +3 -4
  75. package/internals/useTreeView/useTreeViewBuildContext.d.ts +4 -2
  76. package/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  77. package/internals/utils/TreeViewStore.d.ts +12 -0
  78. package/internals/utils/TreeViewStore.js +24 -0
  79. package/internals/utils/selectors.d.ts +9 -0
  80. package/internals/utils/selectors.js +37 -0
  81. package/internals/utils/tree.d.ts +8 -8
  82. package/internals/utils/tree.js +51 -43
  83. package/models/items.d.ts +3 -2
  84. package/modern/RichTreeView/RichTreeView.js +2 -4
  85. package/modern/TreeItem/TreeItem.js +4 -4
  86. package/modern/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  87. package/modern/TreeItemProvider/TreeItemProvider.js +26 -11
  88. package/modern/hooks/index.js +2 -1
  89. package/modern/hooks/useTreeItemModel.js +11 -0
  90. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  91. package/modern/index.js +1 -1
  92. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  93. package/modern/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  94. package/modern/internals/components/RichTreeViewItems.js +42 -30
  95. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  96. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  97. package/modern/internals/hooks/useInstanceEventHandler.js +1 -1
  98. package/modern/internals/hooks/useSelector.js +6 -0
  99. package/modern/internals/index.js +5 -1
  100. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +41 -30
  101. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +24 -0
  102. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +19 -0
  103. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  104. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  105. package/modern/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  106. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  107. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  108. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  109. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  110. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  111. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  112. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  113. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +16 -17
  114. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  115. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  116. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  117. package/modern/internals/useTreeView/useTreeView.js +30 -17
  118. package/modern/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  119. package/modern/internals/utils/TreeViewStore.js +24 -0
  120. package/modern/internals/utils/selectors.js +37 -0
  121. package/modern/internals/utils/tree.js +51 -43
  122. package/modern/useTreeItem/useTreeItem.js +29 -16
  123. package/node/RichTreeView/RichTreeView.js +2 -4
  124. package/node/TreeItem/TreeItem.js +4 -4
  125. package/node/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +2 -2
  126. package/node/TreeItemProvider/TreeItemProvider.js +26 -10
  127. package/node/hooks/index.js +8 -1
  128. package/node/hooks/useTreeItemModel.js +17 -0
  129. package/node/hooks/useTreeItemUtils/useTreeItemUtils.js +32 -15
  130. package/node/index.js +1 -1
  131. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  132. package/node/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  133. package/node/internals/components/RichTreeViewItems.js +42 -30
  134. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +12 -13
  135. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +15 -0
  136. package/node/internals/hooks/useInstanceEventHandler.js +1 -1
  137. package/node/internals/hooks/useSelector.js +13 -0
  138. package/node/internals/index.js +47 -1
  139. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +41 -31
  140. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +30 -0
  141. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +27 -0
  142. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  143. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +40 -0
  144. package/node/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +16 -13
  145. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -100
  146. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +109 -0
  147. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +30 -27
  148. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  149. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  150. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  151. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +32 -0
  152. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +16 -17
  153. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +46 -35
  154. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +15 -0
  155. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +24 -14
  156. package/node/internals/useTreeView/useTreeView.js +30 -17
  157. package/node/internals/useTreeView/useTreeViewBuildContext.js +25 -18
  158. package/node/internals/utils/TreeViewStore.js +31 -0
  159. package/node/internals/utils/selectors.js +44 -0
  160. package/node/internals/utils/tree.js +51 -43
  161. package/node/useTreeItem/useTreeItem.js +29 -16
  162. package/package.json +8 -6
  163. package/useTreeItem/useTreeItem.js +29 -16
  164. package/useTreeItem/useTreeItem.types.d.ts +10 -1
@@ -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));
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.propagateSelection = exports.getLookupFromArray = exports.getAddedAndRemovedItems = exports.convertSelectedItemsToArray = void 0;
6
+ exports.propagateSelection = exports.getLookupFromArray = exports.getAddedAndRemovedItems = exports.createSelectedItemsMap = exports.convertSelectedItemsToArray = void 0;
7
+ var _useTreeViewSelection = require("./useTreeViewSelection.selectors");
8
+ var _useTreeViewItems = require("../useTreeViewItems/useTreeViewItems.selectors");
7
9
  /**
8
10
  * Transform the `selectedItems` model to be an array if it was a string or null.
9
11
  * @param {string[] | string | null} model The raw model.
@@ -19,6 +21,14 @@ const convertSelectedItemsToArray = model => {
19
21
  return [];
20
22
  };
21
23
  exports.convertSelectedItemsToArray = convertSelectedItemsToArray;
24
+ const createSelectedItemsMap = selectedItems => {
25
+ const selectedItemsMap = new Map();
26
+ convertSelectedItemsToArray(selectedItems).forEach(id => {
27
+ selectedItemsMap.set(id, true);
28
+ });
29
+ return selectedItemsMap;
30
+ };
31
+ exports.createSelectedItemsMap = createSelectedItemsMap;
22
32
  const getLookupFromArray = array => {
23
33
  const lookup = {};
24
34
  array.forEach(itemId => {
@@ -28,19 +38,19 @@ const getLookupFromArray = array => {
28
38
  };
29
39
  exports.getLookupFromArray = getLookupFromArray;
30
40
  const getAddedAndRemovedItems = ({
31
- instance,
41
+ store,
32
42
  oldModel,
33
43
  newModel
34
44
  }) => {
35
- const newModelLookup = getLookupFromArray(newModel);
45
+ const newModelLookup = createSelectedItemsMap(newModel);
36
46
  return {
37
- added: newModel.filter(itemId => !instance.isItemSelected(itemId)),
38
- removed: oldModel.filter(itemId => !newModelLookup[itemId])
47
+ added: newModel.filter(itemId => !(0, _useTreeViewSelection.selectorIsItemSelected)(store.value, itemId)),
48
+ removed: oldModel.filter(itemId => !newModelLookup.has(itemId))
39
49
  };
40
50
  };
41
51
  exports.getAddedAndRemovedItems = getAddedAndRemovedItems;
42
52
  const propagateSelection = ({
43
- instance,
53
+ store,
44
54
  selectionPropagation,
45
55
  newModel,
46
56
  oldModel,
@@ -52,7 +62,7 @@ const propagateSelection = ({
52
62
  let shouldRegenerateModel = false;
53
63
  const newModelLookup = getLookupFromArray(newModel);
54
64
  const changes = getAddedAndRemovedItems({
55
- instance,
65
+ store,
56
66
  newModel,
57
67
  oldModel
58
68
  });
@@ -72,7 +82,7 @@ const propagateSelection = ({
72
82
  shouldRegenerateModel = true;
73
83
  newModelLookup[itemId] = true;
74
84
  }
75
- instance.getItemOrderedChildrenIds(itemId).forEach(selectDescendants);
85
+ (0, _useTreeViewItems.selectorItemOrderedChildrenIds)(store.value, itemId).forEach(selectDescendants);
76
86
  };
77
87
  selectDescendants(addedItemId);
78
88
  }
@@ -81,15 +91,15 @@ const propagateSelection = ({
81
91
  if (!newModelLookup[itemId]) {
82
92
  return false;
83
93
  }
84
- const children = instance.getItemOrderedChildrenIds(itemId);
94
+ const children = (0, _useTreeViewItems.selectorItemOrderedChildrenIds)(store.value, itemId);
85
95
  return children.every(checkAllDescendantsSelected);
86
96
  };
87
97
  const selectParents = itemId => {
88
- const parentId = instance.getItemMeta(itemId).parentId;
98
+ const parentId = (0, _useTreeViewItems.selectorItemParentId)(store.value, itemId);
89
99
  if (parentId == null) {
90
100
  return;
91
101
  }
92
- const siblings = instance.getItemOrderedChildrenIds(parentId);
102
+ const siblings = (0, _useTreeViewItems.selectorItemOrderedChildrenIds)(store.value, parentId);
93
103
  if (siblings.every(checkAllDescendantsSelected)) {
94
104
  shouldRegenerateModel = true;
95
105
  newModelLookup[parentId] = true;
@@ -101,13 +111,13 @@ const propagateSelection = ({
101
111
  });
102
112
  changes.removed.forEach(removedItemId => {
103
113
  if (selectionPropagation.parents) {
104
- let parentId = instance.getItemMeta(removedItemId).parentId;
114
+ let parentId = (0, _useTreeViewItems.selectorItemParentId)(store.value, removedItemId);
105
115
  while (parentId != null) {
106
116
  if (newModelLookup[parentId]) {
107
117
  shouldRegenerateModel = true;
108
118
  delete newModelLookup[parentId];
109
119
  }
110
- parentId = instance.getItemMeta(parentId).parentId;
120
+ parentId = (0, _useTreeViewItems.selectorItemParentId)(store.value, parentId);
111
121
  }
112
122
  }
113
123
  if (selectionPropagation.descendants) {
@@ -116,7 +126,7 @@ const propagateSelection = ({
116
126
  shouldRegenerateModel = true;
117
127
  delete newModelLookup[itemId];
118
128
  }
119
- instance.getItemOrderedChildrenIds(itemId).forEach(deSelectDescendants);
129
+ (0, _useTreeViewItems.selectorItemOrderedChildrenIds)(store.value, itemId).forEach(deSelectDescendants);
120
130
  };
121
131
  deSelectDescendants(removedItemId);
122
132
  }
@@ -14,6 +14,7 @@ var _useTreeViewModels = require("./useTreeViewModels");
14
14
  var _corePlugins = require("../corePlugins");
15
15
  var _extractPluginParamsFromProps = require("./extractPluginParamsFromProps");
16
16
  var _useTreeViewBuildContext = require("./useTreeViewBuildContext");
17
+ var _TreeViewStore = require("../utils/TreeViewStore");
17
18
  function useTreeViewApiInitialization(inputApiRef) {
18
19
  const fallbackPublicApiRef = React.useRef({});
19
20
  if (inputApiRef) {
@@ -24,12 +25,13 @@ function useTreeViewApiInitialization(inputApiRef) {
24
25
  }
25
26
  return fallbackPublicApiRef.current;
26
27
  }
28
+ let globalId = 0;
27
29
  const useTreeView = ({
28
30
  plugins: inPlugins,
29
31
  rootRef,
30
32
  props
31
33
  }) => {
32
- const plugins = [..._corePlugins.TREE_VIEW_CORE_PLUGINS, ...inPlugins];
34
+ const plugins = React.useMemo(() => [..._corePlugins.TREE_VIEW_CORE_PLUGINS, ...inPlugins], [inPlugins]);
33
35
  const {
34
36
  pluginParams,
35
37
  forwardedProps,
@@ -47,22 +49,30 @@ const useTreeView = ({
47
49
  const publicAPI = useTreeViewApiInitialization(apiRef);
48
50
  const innerRootRef = React.useRef(null);
49
51
  const handleRootRef = (0, _useForkRef.default)(innerRootRef, rootRef);
50
- const contextValue = (0, _useTreeViewBuildContext.useTreeViewBuildContext)({
51
- plugins,
52
- instance,
53
- publicAPI,
54
- rootRef: innerRootRef
55
- });
56
- const [state, setState] = React.useState(() => {
57
- const temp = {};
52
+ const storeRef = React.useRef(null);
53
+ if (storeRef.current == null) {
54
+ globalId += 1;
55
+ const initialState = {
56
+ cacheKey: {
57
+ id: globalId
58
+ }
59
+ };
58
60
  plugins.forEach(plugin => {
59
61
  if (plugin.getInitialState) {
60
- Object.assign(temp, plugin.getInitialState(pluginParams));
62
+ Object.assign(initialState, plugin.getInitialState(pluginParams));
61
63
  }
62
64
  });
63
- return temp;
65
+ storeRef.current = new _TreeViewStore.TreeViewStore(initialState);
66
+ }
67
+ const baseContextValue = (0, _useTreeViewBuildContext.useTreeViewBuildContext)({
68
+ plugins,
69
+ instance,
70
+ publicAPI,
71
+ store: storeRef.current,
72
+ rootRef: innerRootRef
64
73
  });
65
74
  const rootPropsGetters = [];
75
+ const pluginContextValues = [];
66
76
  const runPlugin = plugin => {
67
77
  const pluginResponse = plugin({
68
78
  instance,
@@ -70,11 +80,10 @@ const useTreeView = ({
70
80
  slots,
71
81
  slotProps,
72
82
  experimentalFeatures,
73
- state,
74
- setState,
75
83
  rootRef: innerRootRef,
76
84
  models,
77
- plugins
85
+ plugins,
86
+ store: storeRef.current
78
87
  });
79
88
  if (pluginResponse.getRootProps) {
80
89
  rootPropsGetters.push(pluginResponse.getRootProps);
@@ -86,7 +95,7 @@ const useTreeView = ({
86
95
  Object.assign(instance, pluginResponse.instance);
87
96
  }
88
97
  if (pluginResponse.contextValue) {
89
- Object.assign(contextValue, pluginResponse.contextValue);
98
+ pluginContextValues.push(pluginResponse.contextValue);
90
99
  }
91
100
  };
92
101
  plugins.forEach(runPlugin);
@@ -101,11 +110,15 @@ const useTreeView = ({
101
110
  });
102
111
  return rootProps;
103
112
  };
113
+ const contextValue = React.useMemo(() => {
114
+ const copiedBaseContextValue = (0, _extends2.default)({}, baseContextValue);
115
+ return Object.assign(copiedBaseContextValue, ...pluginContextValues);
116
+ // eslint-disable-next-line react-hooks/exhaustive-deps
117
+ }, [baseContextValue, ...pluginContextValues]);
104
118
  return {
105
119
  getRootProps,
106
120
  rootRef: handleRootRef,
107
- contextValue,
108
- instance
121
+ contextValue
109
122
  };
110
123
  };
111
124
  exports.useTreeView = useTreeView;
@@ -1,16 +1,19 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.useTreeViewBuildContext = void 0;
8
+ var React = _interopRequireWildcard(require("react"));
7
9
  const useTreeViewBuildContext = ({
8
10
  plugins,
9
11
  instance,
10
12
  publicAPI,
13
+ store,
11
14
  rootRef
12
15
  }) => {
13
- const runItemPlugins = itemPluginProps => {
16
+ const runItemPlugins = React.useCallback(itemPluginProps => {
14
17
  let finalRootRef = null;
15
18
  let finalContentRef = null;
16
19
  const pluginPropEnhancers = [];
@@ -55,10 +58,11 @@ const useTreeViewBuildContext = ({
55
58
  rootRef: finalRootRef,
56
59
  propsEnhancers
57
60
  };
58
- };
59
- const wrapItem = ({
61
+ }, [plugins]);
62
+ const wrapItem = React.useCallback(({
60
63
  itemId,
61
- children
64
+ children,
65
+ idAttribute
62
66
  }) => {
63
67
  let finalChildren = children;
64
68
  // The wrappers are reversed to ensure that the first wrapper is the outermost one.
@@ -66,15 +70,16 @@ const useTreeViewBuildContext = ({
66
70
  const plugin = plugins[i];
67
71
  if (plugin.wrapItem) {
68
72
  finalChildren = plugin.wrapItem({
73
+ instance,
69
74
  itemId,
70
75
  children: finalChildren,
71
- instance
76
+ idAttribute
72
77
  });
73
78
  }
74
79
  }
75
80
  return finalChildren;
76
- };
77
- const wrapRoot = ({
81
+ }, [plugins, instance]);
82
+ const wrapRoot = React.useCallback(({
78
83
  children
79
84
  }) => {
80
85
  let finalChildren = children;
@@ -83,20 +88,22 @@ const useTreeViewBuildContext = ({
83
88
  const plugin = plugins[i];
84
89
  if (plugin.wrapRoot) {
85
90
  finalChildren = plugin.wrapRoot({
86
- children: finalChildren,
87
- instance
91
+ children: finalChildren
88
92
  });
89
93
  }
90
94
  }
91
95
  return finalChildren;
92
- };
93
- return {
94
- runItemPlugins,
95
- wrapItem,
96
- wrapRoot,
97
- instance,
98
- rootRef,
99
- publicAPI
100
- };
96
+ }, [plugins]);
97
+ return React.useMemo(() => {
98
+ return {
99
+ runItemPlugins,
100
+ wrapItem,
101
+ wrapRoot,
102
+ instance,
103
+ publicAPI,
104
+ store,
105
+ rootRef
106
+ };
107
+ }, [runItemPlugins, wrapItem, wrapRoot, instance, publicAPI, store, rootRef]);
101
108
  };
102
109
  exports.useTreeViewBuildContext = useTreeViewBuildContext;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TreeViewStore = void 0;
7
+ class TreeViewStore {
8
+ constructor(value) {
9
+ this.value = void 0;
10
+ this.listeners = void 0;
11
+ this.subscribe = fn => {
12
+ this.listeners.add(fn);
13
+ return () => {
14
+ this.listeners.delete(fn);
15
+ };
16
+ };
17
+ this.getSnapshot = () => {
18
+ return this.value;
19
+ };
20
+ this.update = updater => {
21
+ const newState = updater(this.value);
22
+ if (newState !== this.value) {
23
+ this.value = newState;
24
+ this.listeners.forEach(l => l(newState));
25
+ }
26
+ };
27
+ this.value = value;
28
+ this.listeners = new Set();
29
+ }
30
+ }
31
+ exports.TreeViewStore = TreeViewStore;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createSelector = void 0;
7
+ var _reselect = require("reselect");
8
+ const reselectCreateSelector = (0, _reselect.createSelectorCreator)({
9
+ memoize: _reselect.lruMemoize,
10
+ memoizeOptions: {
11
+ maxSize: 1,
12
+ equalityCheck: Object.is
13
+ }
14
+ });
15
+ const cache = new WeakMap();
16
+ /**
17
+ * Method wrapping reselect's createSelector to provide caching for tree view instances.
18
+ *
19
+ */
20
+ const createSelector = (...createSelectorArgs) => {
21
+ const selector = (state, selectorArgs) => {
22
+ const cacheKey = state.cacheKey;
23
+
24
+ // If there is no cache for the current tree view instance, create one.
25
+ let cacheForCurrentTreeViewInstance = cache.get(cacheKey);
26
+ if (!cacheForCurrentTreeViewInstance) {
27
+ cacheForCurrentTreeViewInstance = new Map();
28
+ cache.set(cacheKey, cacheForCurrentTreeViewInstance);
29
+ }
30
+
31
+ // If there is a cached selector, execute it.
32
+ const cachedSelector = cacheForCurrentTreeViewInstance.get(createSelectorArgs);
33
+ if (cachedSelector) {
34
+ return cachedSelector(state, selectorArgs);
35
+ }
36
+
37
+ // Otherwise, create a new selector and cache it and execute it.
38
+ const fn = reselectCreateSelector(...createSelectorArgs);
39
+ cacheForCurrentTreeViewInstance.set(createSelectorArgs, fn);
40
+ return fn(state, selectorArgs);
41
+ };
42
+ return selector;
43
+ };
44
+ exports.createSelector = createSelector;