@mui/x-tree-view 8.0.0-beta.0 → 8.0.0-beta.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 (69) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/esm/hooks/useTreeItemUtils/useTreeItemUtils.js +8 -14
  3. package/esm/index.js +1 -1
  4. package/esm/internals/models/itemPlugin.d.ts +3 -3
  5. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.js +3 -8
  6. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +1 -4
  7. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +6 -6
  8. package/esm/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +13 -15
  9. package/esm/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +0 -3
  10. package/esm/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +9 -12
  11. package/esm/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -11
  12. package/esm/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +14 -20
  13. package/esm/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +5 -7
  14. package/esm/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +5 -4
  15. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.d.ts +0 -2
  16. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +16 -21
  17. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +43 -38
  18. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +331 -0
  19. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +38 -1
  20. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +5 -4
  21. package/esm/internals/utils/selectors.d.ts +1 -1
  22. package/esm/useTreeItem/useTreeItem.js +11 -17
  23. package/esm/useTreeItem/useTreeItem.types.d.ts +0 -4
  24. package/hooks/useTreeItemUtils/useTreeItemUtils.js +7 -13
  25. package/index.js +1 -1
  26. package/internals/models/itemPlugin.d.ts +3 -3
  27. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +3 -8
  28. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +1 -4
  29. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +6 -6
  30. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +12 -14
  31. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +0 -3
  32. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +9 -12
  33. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -12
  34. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +14 -20
  35. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +5 -7
  36. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +5 -4
  37. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.d.ts +0 -2
  38. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +15 -20
  39. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +42 -37
  40. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +331 -0
  41. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +39 -2
  42. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +5 -4
  43. package/internals/utils/selectors.d.ts +1 -1
  44. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +8 -14
  45. package/modern/index.js +1 -1
  46. package/modern/internals/models/itemPlugin.d.ts +3 -3
  47. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +3 -8
  48. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +1 -4
  49. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +6 -6
  50. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +13 -15
  51. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +0 -3
  52. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +9 -12
  53. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -11
  54. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +14 -20
  55. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +5 -7
  56. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +5 -4
  57. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.d.ts +0 -2
  58. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +16 -21
  59. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +43 -38
  60. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +331 -0
  61. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +38 -1
  62. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +5 -4
  63. package/modern/internals/utils/selectors.d.ts +1 -1
  64. package/modern/useTreeItem/useTreeItem.js +11 -17
  65. package/modern/useTreeItem/useTreeItem.types.d.ts +0 -4
  66. package/package.json +1 -1
  67. package/tsconfig.build.tsbuildinfo +1 -1
  68. package/useTreeItem/useTreeItem.js +11 -17
  69. package/useTreeItem/useTreeItem.types.d.ts +0 -4
package/CHANGELOG.md CHANGED
@@ -5,6 +5,83 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.0.0-beta.1
9
+
10
+ _Mar 21, 2025_
11
+
12
+ We'd like to offer a big thanks to the 6 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🐞 Bugfixes
15
+
16
+ Special thanks go out to the community members for their valuable contributions:
17
+ @jyash97.
18
+ Following are all team members who have contributed to this release:
19
+ @alexfauquette, @arminmeh, @flaviendelangle, @JCQuintas, @KenanYusuf.
20
+
21
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@8.0.0-beta.1`
26
+
27
+ - [DataGrid] Fix error caused by `forwardRef` to `ClickAwayListener` (#17049) @arminmeh
28
+ - [DataGrid] Fix error while editing rows with custom id (#17048) @arminmeh
29
+
30
+ #### `@mui/x-data-grid-pro@8.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
31
+
32
+ Same changes as in `@mui/x-data-grid@8.0.0-beta.1`, plus:
33
+
34
+ - [DataGridPro] Fix header select checkbox state with `checkboxSelectionVisibleOnly` and `paginationMode="server"` (#17026) @arminmeh
35
+
36
+ #### `@mui/x-data-grid-premium@8.0.0-beta.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
37
+
38
+ Same changes as in `@mui/x-data-grid-pro@8.0.0-beta.1`, plus:
39
+
40
+ - [DataGridPremium] Update column state correctly when grouping mode is updated with one grouping column (#17069) @arminmeh
41
+
42
+ ### Date and Time Pickers
43
+
44
+ #### `@mui/x-date-pickers@8.0.0-beta.1`
45
+
46
+ - [fields] Clean the `useField` hook (part 1) (#16944) @flaviendelangle
47
+ - [fields] Improve the check for year in `doesSectionFormatHaveLeadingZeros` (#17051) @flaviendelangle
48
+ - [pickers] Deprecate the `disableOpenPicker` prop (#17040) @flaviendelangle
49
+ - [pickers] Simplify the `cleanLeadingZeros` method (#17063) @flaviendelangle
50
+ - [pickers] Use the new `ownerState` in `PickersDay` and `DateRangePickerDay` (#17035) @flaviendelangle
51
+
52
+ #### `@mui/x-date-pickers-pro@8.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
53
+
54
+ Same changes as in `@mui/x-date-pickers@8.0.0-beta.1`, plus:
55
+
56
+ - [DateRangePicker] Use desktop media query constant on range pickers (#17052) @flaviendelangle
57
+
58
+ ### Charts
59
+
60
+ #### `@mui/x-charts@8.0.0-beta.1`
61
+
62
+ - [charts] Fix horizontal bar with multiple axes (#17059) @alexfauquette
63
+
64
+ #### `@mui/x-charts-pro@8.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
65
+
66
+ Same changes as in `@mui/x-charts@8.0.0-beta.1`, plus:
67
+
68
+ - [charts-pro] Allow disabling Heatmap tooltip (#17060) @JCQuintas
69
+
70
+ ### Tree View
71
+
72
+ #### `@mui/x-tree-view@8.0.0-beta.1`
73
+
74
+ Internal changes.
75
+
76
+ #### `@mui/x-tree-view-pro@8.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
77
+
78
+ Same changes as in `@mui/x-tree-view@8.0.0-beta.1`.
79
+
80
+ ### Docs
81
+
82
+ - [docs] Fix 404 (#17033) @alexfauquette
83
+ - [docs] Fix Data Grid advanced list view demo (#17064) @KenanYusuf
84
+
8
85
  ## 8.0.0-beta.0
9
86
 
10
87
  <img width="100%" alt="MUI X v8 Beta is live" src="https://github.com/user-attachments/assets/61ec4dd8-c946-456b-8b45-d51de8772f5d">
@@ -7,7 +7,7 @@ import { useSelector } from "../../internals/hooks/useSelector.js";
7
7
  import { selectorIsItemExpandable, selectorIsItemExpanded } from "../../internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js";
8
8
  import { selectorIsItemFocused } from "../../internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js";
9
9
  import { selectorIsItemDisabled } from "../../internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js";
10
- import { selectorIsItemSelected } from "../../internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js";
10
+ import { selectorIsItemSelected, selectorIsMultiSelectEnabled } from "../../internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js";
11
11
  import { selectorGetTreeItemError, selectorIsItemLoading, selectorIsLazyLoadingEnabled } from "../../internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js";
12
12
  import { selectorIsItemBeingEdited, selectorIsItemEditable } from "../../internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js";
13
13
 
@@ -31,15 +31,12 @@ export const useTreeItemUtils = ({
31
31
  }) => {
32
32
  const {
33
33
  instance,
34
- label,
35
34
  store,
36
- selection: {
37
- multiSelect
38
- },
39
35
  publicAPI
40
36
  } = useTreeViewContext();
41
37
  const isItemExpandable = useSelector(store, selectorIsItemExpandable, itemId);
42
38
  const isLazyLoadingEnabled = useSelector(store, selectorIsLazyLoadingEnabled);
39
+ const isMultiSelectEnabled = useSelector(store, selectorIsMultiSelectEnabled);
43
40
  const loading = useSelector(store, state => isLazyLoadingEnabled ? selectorIsItemLoading(state, itemId) : false);
44
41
  const error = useSelector(store, state => isLazyLoadingEnabled ? Boolean(selectorGetTreeItemError(state, itemId)) : false);
45
42
  const isExpandable = itemHasChildren(children) || isItemExpandable;
@@ -47,11 +44,8 @@ export const useTreeItemUtils = ({
47
44
  const isFocused = useSelector(store, selectorIsItemFocused, itemId);
48
45
  const isSelected = useSelector(store, selectorIsItemSelected, itemId);
49
46
  const isDisabled = useSelector(store, selectorIsItemDisabled, itemId);
50
- const isEditing = useSelector(store, state => label == null ? false : selectorIsItemBeingEdited(state, itemId));
51
- const isEditable = useSelector(store, state => label == null ? false : selectorIsItemEditable(state, {
52
- itemId,
53
- isItemEditable: label.isItemEditable
54
- }));
47
+ const isEditing = useSelector(store, selectorIsItemBeingEdited, itemId);
48
+ const isEditable = useSelector(store, selectorIsItemEditable, itemId);
55
49
  const status = {
56
50
  expandable: isExpandable,
57
51
  expanded: isExpanded,
@@ -70,7 +64,7 @@ export const useTreeItemUtils = ({
70
64
  if (!status.focused) {
71
65
  instance.focusItem(event, itemId);
72
66
  }
73
- const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
67
+ const multiple = isMultiSelectEnabled && (event.shiftKey || event.ctrlKey || event.metaKey);
74
68
 
75
69
  // If already expanded and trying to toggle selection don't close
76
70
  if (status.expandable && !(multiple && selectorIsItemExpanded(store.value, itemId))) {
@@ -88,7 +82,7 @@ export const useTreeItemUtils = ({
88
82
  if (!status.focused) {
89
83
  instance.focusItem(event, itemId);
90
84
  }
91
- const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
85
+ const multiple = isMultiSelectEnabled && (event.shiftKey || event.ctrlKey || event.metaKey);
92
86
  if (multiple) {
93
87
  if (event.shiftKey) {
94
88
  instance.expandSelectionRange(event, itemId);
@@ -109,13 +103,13 @@ export const useTreeItemUtils = ({
109
103
  };
110
104
  const handleCheckboxSelection = event => {
111
105
  const hasShift = event.nativeEvent.shiftKey;
112
- if (multiSelect && hasShift) {
106
+ if (isMultiSelectEnabled && hasShift) {
113
107
  instance.expandSelectionRange(event, itemId);
114
108
  } else {
115
109
  instance.setItemSelection({
116
110
  event,
117
111
  itemId,
118
- keepExistingSelection: multiSelect,
112
+ keepExistingSelection: isMultiSelectEnabled,
119
113
  shouldBeSelected: event.target.checked
120
114
  });
121
115
  }
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v8.0.0-beta.0
2
+ * @mui/x-tree-view v8.0.0-beta.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { EventHandlers } from '@mui/utils/types';
3
- import type { UseTreeItemContentSlotOwnProps, UseTreeItemDragAndDropOverlaySlotOwnProps, UseTreeItemLabelInputSlotOwnProps, UseTreeItemRootSlotOwnProps, UseTreeItemCheckboxSlotOwnProps, UseTreeItemStatus } from '../../useTreeItem';
3
+ import type { UseTreeItemContentSlotOwnProps, UseTreeItemDragAndDropOverlaySlotOwnProps, UseTreeItemLabelInputSlotOwnProps, UseTreeItemRootSlotOwnProps, UseTreeItemCheckboxSlotOwnProps, UseTreeItemLabelSlotOwnProps } from '../../useTreeItem';
4
4
  import type { UseTreeItemInteractions } from '../../hooks/useTreeItemUtils/useTreeItemUtils';
5
5
  import type { TreeItemProps } from '../../TreeItem/TreeItem.types';
6
6
  export interface TreeViewItemPluginSlotPropsEnhancerParams {
@@ -8,7 +8,6 @@ export interface TreeViewItemPluginSlotPropsEnhancerParams {
8
8
  contentRefObject: React.RefObject<HTMLDivElement | null>;
9
9
  externalEventHandlers: EventHandlers;
10
10
  interactions: UseTreeItemInteractions;
11
- status: UseTreeItemStatus;
12
11
  }
13
12
  type TreeViewItemPluginSlotPropsEnhancer<TSlotProps> = (params: TreeViewItemPluginSlotPropsEnhancerParams) => Partial<TSlotProps>;
14
13
  export interface TreeViewItemPluginSlotPropsEnhancers {
@@ -16,6 +15,7 @@ export interface TreeViewItemPluginSlotPropsEnhancers {
16
15
  content?: TreeViewItemPluginSlotPropsEnhancer<UseTreeItemContentSlotOwnProps>;
17
16
  dragAndDropOverlay?: TreeViewItemPluginSlotPropsEnhancer<UseTreeItemDragAndDropOverlaySlotOwnProps>;
18
17
  labelInput?: TreeViewItemPluginSlotPropsEnhancer<UseTreeItemLabelInputSlotOwnProps>;
18
+ label?: TreeViewItemPluginSlotPropsEnhancer<UseTreeItemLabelSlotOwnProps>;
19
19
  checkbox?: TreeViewItemPluginSlotPropsEnhancer<UseTreeItemCheckboxSlotOwnProps>;
20
20
  }
21
21
  export interface TreeViewItemPluginResponse {
@@ -31,7 +31,7 @@ export interface TreeViewItemPluginResponse {
31
31
  * Callback to enhance the slot props of the Tree Item.
32
32
  *
33
33
  * Not all slots are enabled by default,
34
- * if a new plugin needs to pass to an unconfigured slot,
34
+ * if a new plugin needs to pass to an un-configured slot,
35
35
  * it just needs to be added to `TreeViewItemPluginSlotPropsEnhancers`
36
36
  */
37
37
  propsEnhancers?: TreeViewItemPluginSlotPropsEnhancers;
@@ -262,11 +262,6 @@ export const useTreeViewItems = ({
262
262
  params.onItemClick(event, itemId);
263
263
  }
264
264
  });
265
- const pluginContextValue = React.useMemo(() => ({
266
- items: {
267
- onItemClick: handleItemClick
268
- }
269
- }), [handleItemClick]);
270
265
  return {
271
266
  getRootProps: () => ({
272
267
  style: {
@@ -288,9 +283,9 @@ export const useTreeViewItems = ({
288
283
  addItems,
289
284
  setTreeViewLoading,
290
285
  setTreeViewError,
291
- removeChildren
292
- },
293
- contextValue: pluginContextValue
286
+ removeChildren,
287
+ handleItemClick
288
+ }
294
289
  };
295
290
  };
296
291
  useTreeViewItems.getInitialState = params => ({
@@ -37,10 +37,7 @@ export const selectorItemOrderedChildrenIds = createSelector([selectorTreeViewIt
37
37
  * @param {TreeViewItemId} itemId The id of the item to get the model of.
38
38
  * @returns {R} The model of the item.
39
39
  */
40
- export const selectorItemModel = createSelector([selectorTreeViewItemsState, (_, itemId) => itemId], (itemsState, itemId) => {
41
- const a = itemsState.itemModelLookup[itemId];
42
- return a;
43
- });
40
+ export const selectorItemModel = createSelector([selectorTreeViewItemsState, (_, itemId) => itemId], (itemsState, itemId) => itemsState.itemModelLookup[itemId]);
44
41
 
45
42
  /**
46
43
  * Get the meta-information of an item.
@@ -83,6 +83,12 @@ export interface UseTreeViewItemsInstance<R extends {}> extends Pick<UseTreeView
83
83
  * @param {Error | null} error The error on the tree view.
84
84
  */
85
85
  setTreeViewError: (error: Error | null) => void;
86
+ /**
87
+ * Event handler to fire when the `content` slot of a given Tree Item is clicked.
88
+ * @param {React.MouseEvent} event The DOM event that triggered the change.
89
+ * @param {TreeViewItemId} itemId The id of the item being clicked.
90
+ */
91
+ handleItemClick: (event: React.MouseEvent, itemId: TreeViewItemId) => void;
86
92
  }
87
93
  export interface UseTreeViewItemsParameters<R extends {
88
94
  children?: R[];
@@ -188,11 +194,6 @@ export interface UseTreeViewItemsState<R extends {}> {
188
194
  error: Error | null;
189
195
  };
190
196
  }
191
- interface UseTreeViewItemsContextValue {
192
- items: {
193
- onItemClick: (event: React.MouseEvent, itemId: string) => void;
194
- };
195
- }
196
197
  export type UseTreeViewItemsSignature = TreeViewPluginSignature<{
197
198
  params: UseTreeViewItemsParameters<any>;
198
199
  defaultizedParams: UseTreeViewItemsDefaultizedParameters<any>;
@@ -200,6 +201,5 @@ export type UseTreeViewItemsSignature = TreeViewPluginSignature<{
200
201
  publicAPI: UseTreeViewItemsPublicAPI<any>;
201
202
  events: UseTreeViewItemsEventLookup;
202
203
  state: UseTreeViewItemsState<TreeViewDefaultItemModelProperties>;
203
- contextValue: UseTreeViewItemsContextValue;
204
204
  }>;
205
205
  export {};
@@ -7,7 +7,7 @@ import { useTreeViewLabel } from "../useTreeViewLabel/index.js";
7
7
  import { useSelector } from "../../hooks/useSelector.js";
8
8
  import { selectorItemMetaLookup, selectorIsItemDisabled, selectorItemParentId } from "../useTreeViewItems/useTreeViewItems.selectors.js";
9
9
  import { selectorIsItemBeingEdited, selectorIsItemEditable } from "../useTreeViewLabel/useTreeViewLabel.selectors.js";
10
- import { selectorIsItemSelected } from "../useTreeViewSelection/useTreeViewSelection.selectors.js";
10
+ import { selectorIsItemSelected, selectorIsMultiSelectEnabled, selectorIsSelectionEnabled } from "../useTreeViewSelection/useTreeViewSelection.selectors.js";
11
11
  import { selectorIsItemExpandable, selectorIsItemExpanded } from "../useTreeViewExpansion/useTreeViewExpansion.selectors.js";
12
12
  function isPrintableKey(string) {
13
13
  return !!string && string.length === 1 && !!string.match(/\S/);
@@ -58,7 +58,7 @@ export const useTreeViewKeyboardNavigation = ({
58
58
  }
59
59
  return matchingItemId;
60
60
  };
61
- const canToggleItemSelection = itemId => !params.disableSelection && !selectorIsItemDisabled(store.value, itemId);
61
+ const canToggleItemSelection = itemId => selectorIsSelectionEnabled(store.value) && !selectorIsItemDisabled(store.value, itemId);
62
62
  const canToggleItemExpansion = itemId => {
63
63
  return !selectorIsItemDisabled(store.value, itemId) && selectorIsItemExpandable(store.value, itemId);
64
64
  };
@@ -73,6 +73,7 @@ export const useTreeViewKeyboardNavigation = ({
73
73
  }
74
74
  const ctrlPressed = event.ctrlKey || event.metaKey;
75
75
  const key = event.key;
76
+ const isMultiSelectEnabled = selectorIsMultiSelectEnabled(store.value);
76
77
 
77
78
  // eslint-disable-next-line default-case
78
79
  switch (true) {
@@ -80,14 +81,14 @@ export const useTreeViewKeyboardNavigation = ({
80
81
  case key === ' ' && canToggleItemSelection(itemId):
81
82
  {
82
83
  event.preventDefault();
83
- if (params.multiSelect && event.shiftKey) {
84
+ if (isMultiSelectEnabled && event.shiftKey) {
84
85
  instance.expandSelectionRange(event, itemId);
85
86
  } else {
86
87
  instance.setItemSelection({
87
88
  event,
88
89
  itemId,
89
- keepExistingSelection: params.multiSelect,
90
- shouldBeSelected: params.multiSelect ? undefined : true
90
+ keepExistingSelection: isMultiSelectEnabled,
91
+ shouldBeSelected: undefined
91
92
  });
92
93
  }
93
94
  break;
@@ -97,10 +98,7 @@ export const useTreeViewKeyboardNavigation = ({
97
98
  // If the focused item has no children, we select it.
98
99
  case key === 'Enter':
99
100
  {
100
- if (hasPlugin(instance, useTreeViewLabel) && selectorIsItemEditable(store.value, {
101
- itemId,
102
- isItemEditable: params.isItemEditable
103
- }) && !selectorIsItemBeingEdited(store.value, itemId)) {
101
+ if (hasPlugin(instance, useTreeViewLabel) && selectorIsItemEditable(store.value, itemId) && !selectorIsItemBeingEdited(store.value, itemId)) {
104
102
  instance.setEditedItemId(itemId);
105
103
  } else if (canToggleItemExpansion(itemId)) {
106
104
  instance.setItemExpansion({
@@ -109,7 +107,7 @@ export const useTreeViewKeyboardNavigation = ({
109
107
  });
110
108
  event.preventDefault();
111
109
  } else if (canToggleItemSelection(itemId)) {
112
- if (params.multiSelect) {
110
+ if (isMultiSelectEnabled) {
113
111
  event.preventDefault();
114
112
  instance.setItemSelection({
115
113
  event,
@@ -137,7 +135,7 @@ export const useTreeViewKeyboardNavigation = ({
137
135
 
138
136
  // Multi select behavior when pressing Shift + ArrowDown
139
137
  // Toggles the selection state of the next item
140
- if (params.multiSelect && event.shiftKey && canToggleItemSelection(nextItem)) {
138
+ if (isMultiSelectEnabled && event.shiftKey && canToggleItemSelection(nextItem)) {
141
139
  instance.selectItemFromArrowNavigation(event, itemId, nextItem);
142
140
  }
143
141
  }
@@ -154,7 +152,7 @@ export const useTreeViewKeyboardNavigation = ({
154
152
 
155
153
  // Multi select behavior when pressing Shift + ArrowUp
156
154
  // Toggles the selection state of the previous item
157
- if (params.multiSelect && event.shiftKey && canToggleItemSelection(previousItem)) {
155
+ if (isMultiSelectEnabled && event.shiftKey && canToggleItemSelection(previousItem)) {
158
156
  instance.selectItemFromArrowNavigation(event, itemId, previousItem);
159
157
  }
160
158
  }
@@ -212,7 +210,7 @@ export const useTreeViewKeyboardNavigation = ({
212
210
  {
213
211
  // Multi select behavior when pressing Ctrl + Shift + Home
214
212
  // Selects the focused item and all items up to the first item.
215
- if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
213
+ if (canToggleItemSelection(itemId) && isMultiSelectEnabled && ctrlPressed && event.shiftKey) {
216
214
  instance.selectRangeFromStartToItem(event, itemId);
217
215
  } else {
218
216
  instance.focusItem(event, getFirstNavigableItem(store.value));
@@ -226,7 +224,7 @@ export const useTreeViewKeyboardNavigation = ({
226
224
  {
227
225
  // Multi select behavior when pressing Ctrl + Shirt + End
228
226
  // Selects the focused item and all the items down to the last item.
229
- if (canToggleItemSelection(itemId) && params.multiSelect && ctrlPressed && event.shiftKey) {
227
+ if (canToggleItemSelection(itemId) && isMultiSelectEnabled && ctrlPressed && event.shiftKey) {
230
228
  instance.selectRangeFromItemToEnd(event, itemId);
231
229
  } else {
232
230
  instance.focusItem(event, getLastNavigableItem(store.value));
@@ -245,7 +243,7 @@ export const useTreeViewKeyboardNavigation = ({
245
243
 
246
244
  // Multi select behavior when pressing Ctrl + a
247
245
  // Selects all the items
248
- case String.fromCharCode(event.keyCode) === 'A' && ctrlPressed && params.multiSelect && !params.disableSelection:
246
+ case String.fromCharCode(event.keyCode) === 'A' && ctrlPressed && isMultiSelectEnabled && selectorIsSelectionEnabled(store.value):
249
247
  {
250
248
  instance.selectAllNavigableItems(event);
251
249
  event.preventDefault();
@@ -5,8 +5,6 @@ import { UseTreeViewSelectionSignature } from "../useTreeViewSelection/index.js"
5
5
  import { UseTreeViewFocusSignature } from "../useTreeViewFocus/index.js";
6
6
  import { UseTreeViewExpansionSignature } from "../useTreeViewExpansion/index.js";
7
7
  import { TreeViewItemId, TreeViewCancellableEvent } from "../../../models/index.js";
8
- import { UseTreeViewLabelSignature } from "../useTreeViewLabel/index.js";
9
- import { UseTreeViewLazyLoadingSignature } from "../useTreeViewLazyLoading/index.js";
10
8
  export interface UseTreeViewKeyboardNavigationInstance {
11
9
  /**
12
10
  * Updates the `firstCharMap` to add/remove the first character of some item's labels.
@@ -26,7 +24,6 @@ export interface UseTreeViewKeyboardNavigationInstance {
26
24
  export type UseTreeViewKeyboardNavigationSignature = TreeViewPluginSignature<{
27
25
  instance: UseTreeViewKeyboardNavigationInstance;
28
26
  dependencies: [UseTreeViewItemsSignature, UseTreeViewSelectionSignature, UseTreeViewFocusSignature, UseTreeViewExpansionSignature];
29
- optionalDependencies: [UseTreeViewLabelSignature, UseTreeViewLazyLoadingSignature];
30
27
  }>;
31
28
  export type TreeViewFirstCharMap = {
32
29
  [itemId: string]: string;
@@ -6,33 +6,30 @@ export const useTreeViewLabelItemPlugin = ({
6
6
  props
7
7
  }) => {
8
8
  const {
9
- store,
10
- label: {
11
- isItemEditable
12
- }
9
+ store
13
10
  } = useTreeViewContext();
14
11
  const {
15
12
  label,
16
13
  itemId
17
14
  } = props;
18
15
  const [labelInputValue, setLabelInputValue] = React.useState(label);
19
- const editable = useSelector(store, selectorIsItemEditable, {
20
- itemId,
21
- isItemEditable
22
- });
23
- const editing = useSelector(store, selectorIsItemBeingEdited, itemId);
16
+ const isItemEditable = useSelector(store, selectorIsItemEditable, itemId);
17
+ const isItemBeingEdited = useSelector(store, selectorIsItemBeingEdited, itemId);
24
18
  React.useEffect(() => {
25
- if (!editing) {
19
+ if (!isItemBeingEdited) {
26
20
  setLabelInputValue(label);
27
21
  }
28
- }, [editing, label]);
22
+ }, [isItemBeingEdited, label]);
29
23
  return {
30
24
  propsEnhancers: {
25
+ label: () => ({
26
+ editable: isItemEditable
27
+ }),
31
28
  labelInput: ({
32
29
  externalEventHandlers,
33
30
  interactions
34
31
  }) => {
35
- if (!editable) {
32
+ if (!isItemEditable) {
36
33
  return {};
37
34
  }
38
35
  const handleKeydown = event => {
@@ -1,5 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import * as React from 'react';
2
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
3
3
  import { useTreeViewLabelItemPlugin } from "./useTreeViewLabel.itemPlugin.js";
4
4
  export const useTreeViewLabel = ({
5
5
  store,
@@ -7,9 +7,9 @@ export const useTreeViewLabel = ({
7
7
  }) => {
8
8
  const setEditedItemId = editedItemId => {
9
9
  store.update(prevState => _extends({}, prevState, {
10
- label: {
10
+ label: _extends({}, prevState.label, {
11
11
  editedItemId
12
- }
12
+ })
13
13
  }));
14
14
  };
15
15
  const updateItemLabel = (itemId, label) => {
@@ -35,11 +35,14 @@ export const useTreeViewLabel = ({
35
35
  params.onItemLabelChange(itemId, label);
36
36
  }
37
37
  };
38
- const pluginContextValue = React.useMemo(() => ({
39
- label: {
40
- isItemEditable: params.isItemEditable
41
- }
42
- }), [params.isItemEditable]);
38
+ useEnhancedEffect(() => {
39
+ const isItemEditable = params.isItemEditable;
40
+ store.update(prevState => _extends({}, prevState, {
41
+ label: _extends({}, prevState.label, {
42
+ isItemEditable: typeof isItemEditable === 'boolean' ? () => isItemEditable : isItemEditable
43
+ })
44
+ }));
45
+ }, [store, params.isItemEditable]);
43
46
  return {
44
47
  instance: {
45
48
  setEditedItemId,
@@ -47,8 +50,7 @@ export const useTreeViewLabel = ({
47
50
  },
48
51
  publicAPI: {
49
52
  updateItemLabel
50
- },
51
- contextValue: pluginContextValue
53
+ }
52
54
  };
53
55
  };
54
56
  useTreeViewLabel.itemPlugin = useTreeViewLabelItemPlugin;
@@ -57,8 +59,11 @@ useTreeViewLabel.getDefaultizedParams = ({
57
59
  }) => _extends({}, params, {
58
60
  isItemEditable: params.isItemEditable ?? false
59
61
  });
60
- useTreeViewLabel.getInitialState = () => ({
62
+ useTreeViewLabel.getInitialState = ({
63
+ isItemEditable
64
+ }) => ({
61
65
  label: {
66
+ isItemEditable: typeof isItemEditable === 'boolean' ? () => isItemEditable : isItemEditable,
62
67
  editedItemId: null
63
68
  }
64
69
  });
@@ -3,36 +3,28 @@ import { TreeViewRootSelector } from "../../utils/selectors.js";
3
3
  /**
4
4
  * Check if an item is editable.
5
5
  * @param {TreeViewState<[UseTreeViewItemsSignature]>} state The state of the tree view.
6
- * @param {object} params The parameters.
7
- * @param {TreeViewItemId} params.itemId The id of the item to check.
8
- * @param {((item: any) => boolean) | boolean} params.isItemEditable The function to determine if an item is editable.
6
+ * @param {TreeViewItemId} itemId The id of the item to check.
9
7
  * @returns {boolean} `true` if the item is editable, `false` otherwise.
10
8
  */
11
- export declare const selectorIsItemEditable: ((state: any, args: any) => boolean) & {
9
+ export declare const selectorIsItemEditable: ((state: any, itemId: string) => boolean) & {
12
10
  clearCache: () => void;
13
11
  resultsCount: () => number;
14
12
  resetResultsCount: () => void;
15
13
  } & {
16
14
  resultFunc: (resultFuncArgs_0: {
17
- itemId: string;
18
- isItemEditable: ((item: any) => boolean) | boolean;
19
- }, resultFuncArgs_1: import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>) => boolean;
15
+ isItemEditable: (item: any) => boolean;
16
+ editedItemId: string | null;
17
+ } | undefined, resultFuncArgs_1: import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>) => boolean;
20
18
  memoizedResultFunc: ((resultFuncArgs_0: {
21
- itemId: string;
22
- isItemEditable: ((item: any) => boolean) | boolean;
23
- }, resultFuncArgs_1: import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>) => boolean) & {
19
+ isItemEditable: (item: any) => boolean;
20
+ editedItemId: string | null;
21
+ } | undefined, resultFuncArgs_1: import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>) => boolean) & {
24
22
  clearCache: () => void;
25
23
  resultsCount: () => number;
26
24
  resetResultsCount: () => void;
27
25
  };
28
26
  lastResult: () => boolean;
29
- dependencies: [(_: any, args: {
30
- itemId: string;
31
- isItemEditable: ((item: any) => boolean) | boolean;
32
- }) => {
33
- itemId: string;
34
- isItemEditable: ((item: any) => boolean) | boolean;
35
- }, (state: any, args: any) => import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>];
27
+ dependencies: [TreeViewRootSelector<UseTreeViewLabelSignature, true>, (state: any, itemId: string) => import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>];
36
28
  recomputations: () => number;
37
29
  resetRecomputations: () => void;
38
30
  dependencyRecomputations: () => number;
@@ -53,17 +45,19 @@ export declare const selectorIsItemBeingEdited: ((state: any, itemId: string) =>
53
45
  resetResultsCount: () => void;
54
46
  } & {
55
47
  resultFunc: (resultFuncArgs_0: {
48
+ isItemEditable: (item: any) => boolean;
56
49
  editedItemId: string | null;
57
- }, resultFuncArgs_1: string) => boolean;
50
+ } | undefined, resultFuncArgs_1: string) => boolean;
58
51
  memoizedResultFunc: ((resultFuncArgs_0: {
52
+ isItemEditable: (item: any) => boolean;
59
53
  editedItemId: string | null;
60
- }, resultFuncArgs_1: string) => boolean) & {
54
+ } | undefined, resultFuncArgs_1: string) => boolean) & {
61
55
  clearCache: () => void;
62
56
  resultsCount: () => number;
63
57
  resetResultsCount: () => void;
64
58
  };
65
59
  lastResult: () => boolean;
66
- dependencies: [TreeViewRootSelector<UseTreeViewLabelSignature>, (_: any, itemId: string) => string];
60
+ dependencies: [TreeViewRootSelector<UseTreeViewLabelSignature, true>, (_: any, itemId: string) => string];
67
61
  recomputations: () => number;
68
62
  resetRecomputations: () => void;
69
63
  dependencyRecomputations: () => number;
@@ -5,16 +5,14 @@ const selectorTreeViewLabelState = state => state.label;
5
5
  /**
6
6
  * Check if an item is editable.
7
7
  * @param {TreeViewState<[UseTreeViewItemsSignature]>} state The state of the tree view.
8
- * @param {object} params The parameters.
9
- * @param {TreeViewItemId} params.itemId The id of the item to check.
10
- * @param {((item: any) => boolean) | boolean} params.isItemEditable The function to determine if an item is editable.
8
+ * @param {TreeViewItemId} itemId The id of the item to check.
11
9
  * @returns {boolean} `true` if the item is editable, `false` otherwise.
12
10
  */
13
- export const selectorIsItemEditable = createSelector([(_, args) => args, (state, args) => selectorItemModel(state, args.itemId)], (args, itemModel) => {
14
- if (!itemModel || !args.isItemEditable) {
11
+ export const selectorIsItemEditable = createSelector([selectorTreeViewLabelState, (state, itemId) => selectorItemModel(state, itemId)], (labelState, itemModel) => {
12
+ if (!itemModel || !labelState) {
15
13
  return false;
16
14
  }
17
- return typeof args.isItemEditable === 'function' ? args.isItemEditable(itemModel) : true;
15
+ return labelState.isItemEditable(itemModel);
18
16
  });
19
17
 
20
18
  /**
@@ -23,4 +21,4 @@ export const selectorIsItemEditable = createSelector([(_, args) => args, (state,
23
21
  * @param {TreeViewItemId} itemId The id of the item to check.
24
22
  * @returns {boolean} `true` if the item is being edited, `false` otherwise.
25
23
  */
26
- export const selectorIsItemBeingEdited = createSelector([selectorTreeViewLabelState, (_, itemId) => itemId], (labelState, itemId) => labelState.editedItemId === itemId);
24
+ export const selectorIsItemBeingEdited = createSelector([selectorTreeViewLabelState, (_, itemId) => itemId], (labelState, itemId) => labelState?.editedItemId === itemId);
@@ -38,22 +38,23 @@ export interface UseTreeViewLabelParameters<R extends {}> {
38
38
  export type UseTreeViewLabelDefaultizedParameters<R extends {}> = DefaultizedProps<UseTreeViewLabelParameters<R>, 'isItemEditable'>;
39
39
  export interface UseTreeViewLabelState {
40
40
  label: {
41
+ isItemEditable: (item: any) => boolean;
41
42
  editedItemId: string | null;
42
43
  };
43
44
  }
44
- export interface UseTreeViewLabelContextValue {
45
- label: Pick<UseTreeViewLabelDefaultizedParameters<any>, 'isItemEditable'>;
46
- }
47
45
  export type UseTreeViewLabelSignature = TreeViewPluginSignature<{
48
46
  params: UseTreeViewLabelParameters<any>;
49
47
  defaultizedParams: UseTreeViewLabelDefaultizedParameters<any>;
50
48
  publicAPI: UseTreeViewLabelPublicAPI;
51
49
  instance: UseTreeViewLabelInstance;
52
50
  state: UseTreeViewLabelState;
53
- contextValue: UseTreeViewLabelContextValue;
54
51
  dependencies: [UseTreeViewItemsSignature];
55
52
  }>;
56
53
  export interface UseTreeItemLabelInputSlotPropsFromLabelEditing extends TreeItemLabelInputProps {}
54
+ export interface UseTreeItemLabelSlotPropsFromLabelEditing {
55
+ editable?: boolean;
56
+ }
57
57
  declare module '@mui/x-tree-view/useTreeItem' {
58
58
  interface UseTreeItemLabelInputSlotOwnProps extends UseTreeItemLabelInputSlotPropsFromLabelEditing {}
59
+ interface UseTreeItemLabelSlotOwnProps extends UseTreeItemLabelSlotPropsFromLabelEditing {}
59
60
  }
@@ -1,7 +1,5 @@
1
- import { TreeViewAnyPluginSignature, TreeViewState } from "../../models/index.js";
2
1
  import { TreeViewRootSelector, TreeViewRootSelectorForOptionalPlugin } from "../../utils/selectors.js";
3
2
  import { UseTreeViewLazyLoadingSignature } from "./useTreeViewLazyLoading.types.js";
4
- export type Temp<TSignature extends TreeViewAnyPluginSignature> = <TSignatures extends [], TOptionalSignatures extends [TSignature]>(state: TreeViewState<TSignatures, TOptionalSignatures>) => TSignature['state'][keyof TSignature['state']];
5
3
  export declare const selectorDataSourceState: ((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewLazyLoading.types").UseTreeViewLazyLoadingState & Partial<{}> & {
6
4
  cacheKey: import("../../models").TreeViewStateCacheKey;
7
5
  }) => {