@mui/x-tree-view 7.18.0 → 7.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +213 -11
  2. package/RichTreeView/RichTreeView.js +6 -45
  3. package/RichTreeView/RichTreeView.plugins.d.ts +1 -1
  4. package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
  5. package/TreeItem/TreeItem.js +19 -1
  6. package/TreeItem/TreeItem.types.d.ts +2 -0
  7. package/TreeItem/TreeItemContent.js +25 -29
  8. package/TreeItem2/TreeItem2.d.ts +6 -6
  9. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +24 -6
  10. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +10 -8
  11. package/index.js +1 -1
  12. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +7 -1
  13. package/internals/TreeViewProvider/TreeViewProvider.js +2 -1
  14. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +2 -1
  15. package/internals/TreeViewProvider/useTreeViewContext.d.ts +1 -1
  16. package/internals/components/RichTreeViewItems.d.ts +35 -0
  17. package/internals/components/RichTreeViewItems.js +56 -0
  18. package/internals/corePlugins/corePlugins.d.ts +1 -1
  19. package/internals/corePlugins/useTreeViewId/useTreeViewId.js +28 -7
  20. package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +11 -13
  21. package/internals/corePlugins/useTreeViewId/useTreeViewId.utils.d.ts +17 -0
  22. package/internals/corePlugins/useTreeViewId/useTreeViewId.utils.js +26 -0
  23. package/internals/index.d.ts +1 -0
  24. package/internals/index.js +1 -0
  25. package/internals/models/plugin.d.ts +4 -1
  26. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +3 -1
  27. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -1
  28. package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
  29. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +9 -2
  30. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +6 -6
  31. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +11 -5
  32. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +6 -0
  33. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -8
  34. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +3 -2
  35. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +3 -1
  36. package/internals/useTreeView/extractPluginParamsFromProps.d.ts +1 -1
  37. package/internals/useTreeView/extractPluginParamsFromProps.js +7 -3
  38. package/modern/RichTreeView/RichTreeView.js +6 -45
  39. package/modern/TreeItem/TreeItem.js +19 -1
  40. package/modern/TreeItem/TreeItemContent.js +25 -29
  41. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +10 -8
  42. package/modern/index.js +1 -1
  43. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +7 -1
  44. package/modern/internals/TreeViewProvider/TreeViewProvider.js +2 -1
  45. package/modern/internals/components/RichTreeViewItems.js +56 -0
  46. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +28 -7
  47. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.utils.js +26 -0
  48. package/modern/internals/index.js +1 -0
  49. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +3 -1
  50. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -1
  51. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +9 -2
  52. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +11 -5
  53. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +6 -0
  54. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -8
  55. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +3 -1
  56. package/modern/internals/useTreeView/extractPluginParamsFromProps.js +7 -3
  57. package/modern/useTreeItem2/useTreeItem2.js +7 -1
  58. package/node/RichTreeView/RichTreeView.js +6 -45
  59. package/node/TreeItem/TreeItem.js +19 -1
  60. package/node/TreeItem/TreeItemContent.js +25 -29
  61. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +10 -9
  62. package/node/index.js +1 -1
  63. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +7 -1
  64. package/node/internals/TreeViewProvider/TreeViewProvider.js +2 -1
  65. package/node/internals/components/RichTreeViewItems.js +64 -0
  66. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +29 -8
  67. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.utils.js +34 -0
  68. package/node/internals/index.js +7 -0
  69. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +3 -1
  70. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -1
  71. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +9 -2
  72. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +11 -5
  73. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +6 -0
  74. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -8
  75. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +3 -1
  76. package/node/internals/useTreeView/extractPluginParamsFromProps.js +7 -3
  77. package/node/useTreeItem2/useTreeItem2.js +7 -1
  78. package/package.json +4 -4
  79. package/useTreeItem2/index.d.ts +3 -3
  80. package/useTreeItem2/useTreeItem2.js +7 -1
  81. package/useTreeItem2/useTreeItem2.types.d.ts +1 -1
@@ -174,7 +174,9 @@ useTreeViewSelection.models = {
174
174
  }
175
175
  };
176
176
  const DEFAULT_SELECTED_ITEMS = [];
177
- useTreeViewSelection.getDefaultizedParams = params => _extends({}, params, {
177
+ useTreeViewSelection.getDefaultizedParams = ({
178
+ params
179
+ }) => _extends({}, params, {
178
180
  disableSelection: params.disableSelection ?? false,
179
181
  multiSelect: params.multiSelect ?? false,
180
182
  checkboxSelection: params.checkboxSelection ?? false,
@@ -9,5 +9,5 @@ interface ExtractPluginParamsFromPropsReturnValue<TSignatures extends readonly T
9
9
  pluginParams: MergeSignaturesProperty<TSignatures, 'defaultizedParams'>;
10
10
  forwardedProps: Omit<TProps, keyof MergeSignaturesProperty<TSignatures, 'params'>>;
11
11
  }
12
- export declare const extractPluginParamsFromProps: <TSignatures extends readonly TreeViewPluginSignature<any>[], TProps extends Partial<UseTreeViewBaseProps<TSignatures>>>({ props: { slots, slotProps, apiRef, experimentalFeatures, ...props }, plugins, }: ExtractPluginParamsFromPropsParameters<TSignatures, TProps>) => ExtractPluginParamsFromPropsReturnValue<TSignatures, TProps>;
12
+ export declare const extractPluginParamsFromProps: <TSignatures extends readonly TreeViewPluginSignature<any>[], TProps extends Partial<UseTreeViewBaseProps<TSignatures>>>({ props: { slots, slotProps, apiRef, experimentalFeatures: inExperimentalFeatures, ...props }, plugins, }: ExtractPluginParamsFromPropsParameters<TSignatures, TProps>) => ExtractPluginParamsFromPropsReturnValue<TSignatures, TProps>;
13
13
  export {};
@@ -6,7 +6,7 @@ export const extractPluginParamsFromProps = _ref => {
6
6
  slots,
7
7
  slotProps,
8
8
  apiRef,
9
- experimentalFeatures
9
+ experimentalFeatures: inExperimentalFeatures
10
10
  },
11
11
  plugins
12
12
  } = _ref,
@@ -25,9 +25,13 @@ export const extractPluginParamsFromProps = _ref => {
25
25
  forwardedProps[propName] = prop;
26
26
  }
27
27
  });
28
+ const experimentalFeatures = inExperimentalFeatures ?? {};
28
29
  const defaultizedPluginParams = plugins.reduce((acc, plugin) => {
29
30
  if (plugin.getDefaultizedParams) {
30
- return plugin.getDefaultizedParams(acc);
31
+ return plugin.getDefaultizedParams({
32
+ params: acc,
33
+ experimentalFeatures
34
+ });
31
35
  }
32
36
  return acc;
33
37
  }, pluginParams);
@@ -37,6 +41,6 @@ export const extractPluginParamsFromProps = _ref => {
37
41
  pluginParams: defaultizedPluginParams,
38
42
  slots: slots ?? {},
39
43
  slotProps: slotProps ?? {},
40
- experimentalFeatures: experimentalFeatures ?? {}
44
+ experimentalFeatures
41
45
  };
42
46
  };
@@ -11,7 +11,7 @@ import { styled, createUseThemeProps } from "../internals/zero-styled/index.js";
11
11
  import { useTreeView } from "../internals/useTreeView/index.js";
12
12
  import { TreeViewProvider } from "../internals/TreeViewProvider/index.js";
13
13
  import { RICH_TREE_VIEW_PLUGINS } from "./RichTreeView.plugins.js";
14
- import { TreeItem } from "../TreeItem/index.js";
14
+ import { RichTreeViewItems } from "../internals/components/RichTreeViewItems.js";
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
16
  const useThemeProps = createUseThemeProps('MuiRichTreeView');
17
17
  const useUtilityClasses = ownerState => {
@@ -34,33 +34,6 @@ export const RichTreeViewRoot = styled('ul', {
34
34
  outline: 0,
35
35
  position: 'relative'
36
36
  });
37
- function WrappedTreeItem({
38
- slots,
39
- slotProps,
40
- label,
41
- id,
42
- itemId,
43
- children
44
- }) {
45
- const Item = slots?.item ?? TreeItem;
46
- const itemProps = useSlotProps({
47
- elementType: Item,
48
- externalSlotProps: slotProps?.item,
49
- additionalProps: {
50
- itemId,
51
- id,
52
- label
53
- },
54
- ownerState: {
55
- itemId,
56
- label
57
- }
58
- });
59
- return /*#__PURE__*/_jsx(Item, _extends({}, itemProps, {
60
- children: children
61
- }));
62
- }
63
-
64
37
  /**
65
38
  *
66
39
  * Demos:
@@ -103,26 +76,14 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
103
76
  getSlotProps: getRootProps,
104
77
  ownerState: props
105
78
  });
106
- const itemsToRender = instance.getItemsToRender();
107
- const renderItem = ({
108
- label,
109
- itemId,
110
- id,
111
- children
112
- }) => {
113
- return /*#__PURE__*/_jsx(WrappedTreeItem, {
114
- slots: slots,
115
- slotProps: slotProps,
116
- label: label,
117
- id: id,
118
- itemId: itemId,
119
- children: children?.map(renderItem)
120
- }, itemId);
121
- };
122
79
  return /*#__PURE__*/_jsx(TreeViewProvider, {
123
80
  value: contextValue,
124
81
  children: /*#__PURE__*/_jsx(Root, _extends({}, rootProps, {
125
- children: itemsToRender.map(renderItem)
82
+ children: /*#__PURE__*/_jsx(RichTreeViewItems, {
83
+ slots: slots,
84
+ slotProps: slotProps,
85
+ itemsToRender: instance.getItemsToRender()
86
+ })
126
87
  }))
127
88
  });
128
89
  });
@@ -19,6 +19,7 @@ import resolveComponentProps from '@mui/utils/resolveComponentProps';
19
19
  import useSlotProps from '@mui/utils/useSlotProps';
20
20
  import unsupportedProp from '@mui/utils/unsupportedProp';
21
21
  import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef';
22
+ import { warnOnce } from '@mui/x-internals/warning';
22
23
  import { styled, createUseThemeProps } from "../internals/zero-styled/index.js";
23
24
  import { TreeItemContent } from "./TreeItemContent.js";
24
25
  import { treeItemClasses, getTreeItemUtilityClass } from "./treeItemClasses.js";
@@ -28,6 +29,7 @@ import { TreeItem2Provider } from "../TreeItem2Provider/index.js";
28
29
  import { TreeViewItemDepthContext } from "../internals/TreeViewItemDepthContext/index.js";
29
30
  import { useTreeItemState } from "./useTreeItemState.js";
30
31
  import { isTargetInDescendants } from "../internals/utils/tree.js";
32
+ import { generateTreeItemIdAttribute } from "../internals/corePlugins/useTreeViewId/useTreeViewId.utils.js";
31
33
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
32
34
  const useThemeProps = createUseThemeProps('MuiTreeItem');
33
35
  const useUtilityClasses = ownerState => {
@@ -185,6 +187,7 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
185
187
  expansion: {
186
188
  expansionTrigger
187
189
  },
190
+ treeId,
188
191
  instance
189
192
  } = useTreeViewContext();
190
193
  const depthContext = React.useContext(TreeViewItemDepthContext);
@@ -218,6 +221,15 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
218
221
  handleCancelItemLabelEditing,
219
222
  handleSaveItemLabel
220
223
  } = useTreeItemState(itemId);
224
+ if (process.env.NODE_ENV !== 'production') {
225
+ // Checking directly the `props` to avoid having the default value applied
226
+ if (props.ContentComponent) {
227
+ warnOnce(['MUI X: The ContentComponent prop of the TreeItem component is deprecated and will be removed in the next major release.', 'You can use the new TreeItem2 component or the new useTreeItem2 hook to customize the rendering of the content.', 'For more detail, see https://mui.com/x/react-tree-view/tree-item-customization/.']);
228
+ }
229
+ if (props.ContentProps) {
230
+ warnOnce(['MUI X: The ContentProps prop of the TreeItem component is deprecated and will be removed in the next major release.', 'You can use the new TreeItem2 component or the new useTreeItem2 hook to customize the rendering of the content.', 'For more detail, see https://mui.com/x/react-tree-view/tree-item-customization/.']);
231
+ }
232
+ }
221
233
  const {
222
234
  contentRef,
223
235
  rootRef,
@@ -341,7 +353,11 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
341
353
  }
342
354
  instance.handleItemKeyDown(event, itemId);
343
355
  };
344
- const idAttribute = instance.getTreeItemIdAttribute(itemId, id);
356
+ const idAttribute = generateTreeItemIdAttribute({
357
+ itemId,
358
+ treeId,
359
+ id
360
+ });
345
361
  const tabIndex = instance.canItemBeTabbed(itemId) ? 0 : -1;
346
362
  const sharedPropsEnhancerParams = {
347
363
  rootRefObject,
@@ -436,11 +452,13 @@ process.env.NODE_ENV !== "production" ? TreeItem.propTypes = {
436
452
  className: PropTypes.string,
437
453
  /**
438
454
  * The component used to render the content of the item.
455
+ * @deprecated Consider using the `TreeItem2` component or the `useTreeItem2` hook instead. For more detail, see https://mui.com/x/react-tree-view/tree-item-customization/.
439
456
  * @default TreeItemContent
440
457
  */
441
458
  ContentComponent: elementTypeAcceptingRef,
442
459
  /**
443
460
  * Props applied to ContentComponent.
461
+ * @deprecated Consider using the `TreeItem2` component or the `useTreeItem2` hook instead. For more detail, see https://mui.com/x/react-tree-view/tree-item-customization/.
444
462
  */
445
463
  ContentProps: PropTypes.object,
446
464
  /**
@@ -73,35 +73,31 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
73
73
  }
74
74
  toggleItemEditing();
75
75
  };
76
- return (
77
- /*#__PURE__*/
78
- /* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions -- Key event is handled by the TreeView */
79
- _jsxs("div", _extends({}, other, {
80
- className: clsx(className, classes.root, expanded && classes.expanded, selected && classes.selected, focused && classes.focused, disabled && classes.disabled, editing && classes.editing, editable && classes.editable),
81
- onClick: handleClick,
82
- onMouseDown: handleMouseDown,
83
- ref: ref,
84
- children: [/*#__PURE__*/_jsx("div", {
85
- className: classes.iconContainer,
86
- children: icon
87
- }), checkboxSelection && /*#__PURE__*/_jsx(Checkbox, {
88
- className: classes.checkbox,
89
- checked: selected,
90
- onChange: handleCheckboxSelection,
91
- disabled: disabled || disableSelection,
92
- ref: checkboxRef,
93
- tabIndex: -1
94
- }), editing ? /*#__PURE__*/_jsx(TreeItem2LabelInput, _extends({}, labelInputProps, {
95
- className: classes.labelInput
96
- })) : /*#__PURE__*/_jsx("div", _extends({
97
- className: classes.label
98
- }, editable && {
99
- onDoubleClick: handleLabelDoubleClick
100
- }, {
101
- children: label
102
- })), dragAndDropOverlayProps && /*#__PURE__*/_jsx(TreeItem2DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
103
- }))
104
- );
76
+ return /*#__PURE__*/ /* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions -- Key event is handled by the TreeView */_jsxs("div", _extends({}, other, {
77
+ className: clsx(classes.root, className, expanded && classes.expanded, selected && classes.selected, focused && classes.focused, disabled && classes.disabled, editing && classes.editing, editable && classes.editable),
78
+ onClick: handleClick,
79
+ onMouseDown: handleMouseDown,
80
+ ref: ref,
81
+ children: [/*#__PURE__*/_jsx("div", {
82
+ className: classes.iconContainer,
83
+ children: icon
84
+ }), checkboxSelection && /*#__PURE__*/_jsx(Checkbox, {
85
+ className: classes.checkbox,
86
+ checked: selected,
87
+ onChange: handleCheckboxSelection,
88
+ disabled: disabled || disableSelection,
89
+ ref: checkboxRef,
90
+ tabIndex: -1
91
+ }), editing ? /*#__PURE__*/_jsx(TreeItem2LabelInput, _extends({}, labelInputProps, {
92
+ className: classes.labelInput
93
+ })) : /*#__PURE__*/_jsx("div", _extends({
94
+ className: classes.label
95
+ }, editable && {
96
+ onDoubleClick: handleLabelDoubleClick
97
+ }, {
98
+ children: label
99
+ })), dragAndDropOverlayProps && /*#__PURE__*/_jsx(TreeItem2DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
100
+ }));
105
101
  });
106
102
  process.env.NODE_ENV !== "production" ? TreeItemContent.propTypes = {
107
103
  // ----------------------------- Warning --------------------------------
@@ -1,12 +1,6 @@
1
1
  import { useTreeViewContext } from "../../internals/TreeViewProvider/index.js";
2
2
  import { useTreeViewLabel } from "../../internals/plugins/useTreeViewLabel/index.js";
3
3
  import { hasPlugin } from "../../internals/utils/plugins.js";
4
- const isItemExpandable = reactChildren => {
5
- if (Array.isArray(reactChildren)) {
6
- return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
7
- }
8
- return Boolean(reactChildren);
9
- };
10
4
 
11
5
  /**
12
6
  * Plugins that need to be present in the Tree View in order for `useTreeItem2Utils` to work correctly.
@@ -16,6 +10,12 @@ const isItemExpandable = reactChildren => {
16
10
  * Plugins that `useTreeItem2Utils` can use if they are present, but are not required.
17
11
  */
18
12
 
13
+ const isItemExpandable = reactChildren => {
14
+ if (Array.isArray(reactChildren)) {
15
+ return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
16
+ }
17
+ return Boolean(reactChildren);
18
+ };
19
19
  export const useTreeItem2Utils = ({
20
20
  itemId,
21
21
  children
@@ -24,7 +24,8 @@ export const useTreeItem2Utils = ({
24
24
  instance,
25
25
  selection: {
26
26
  multiSelect
27
- }
27
+ },
28
+ publicAPI
28
29
  } = useTreeViewContext();
29
30
  const status = {
30
31
  expandable: isItemExpandable(children),
@@ -134,6 +135,7 @@ export const useTreeItem2Utils = ({
134
135
  };
135
136
  return {
136
137
  interactions,
137
- status
138
+ status,
139
+ publicAPI
138
140
  };
139
141
  };
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.18.0
2
+ * @mui/x-tree-view v7.20.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -2,6 +2,7 @@ import * as React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useTreeViewContext } from "./useTreeViewContext.js";
4
4
  import { escapeOperandAttributeSelector } from "../utils/utils.js";
5
+ import { generateTreeItemIdAttribute } from "../corePlugins/useTreeViewId/useTreeViewId.utils.js";
5
6
  import { jsx as _jsx } from "react/jsx-runtime";
6
7
  export const TreeViewChildrenItemContext = /*#__PURE__*/React.createContext(null);
7
8
  if (process.env.NODE_ENV !== 'production') {
@@ -14,6 +15,7 @@ export function TreeViewChildrenItemProvider(props) {
14
15
  } = props;
15
16
  const {
16
17
  instance,
18
+ treeId,
17
19
  rootRef
18
20
  } = useTreeViewContext();
19
21
  const childrenIdAttrToIdRef = React.useRef(new Map());
@@ -28,7 +30,11 @@ export function TreeViewChildrenItemProvider(props) {
28
30
  // Undefined during 1st render
29
31
  const itemMeta = instance.getItemMeta(itemId);
30
32
  if (itemMeta !== undefined) {
31
- idAttr = instance.getTreeItemIdAttribute(itemId, itemMeta.idAttribute);
33
+ idAttr = generateTreeItemIdAttribute({
34
+ itemId,
35
+ treeId,
36
+ id: itemMeta.idAttribute
37
+ });
32
38
  }
33
39
  }
34
40
  if (idAttr == null) {
@@ -14,7 +14,8 @@ export function TreeViewProvider(props) {
14
14
  return /*#__PURE__*/_jsx(TreeViewContext.Provider, {
15
15
  value: value,
16
16
  children: value.wrapRoot({
17
- children
17
+ children,
18
+ instance: value.instance
18
19
  })
19
20
  });
20
21
  }
@@ -0,0 +1,56 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["ownerState"];
4
+ import * as React from 'react';
5
+ import useSlotProps from '@mui/utils/useSlotProps';
6
+ import { TreeItem } from "../../TreeItem/index.js";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ function WrappedTreeItem({
9
+ slots,
10
+ slotProps,
11
+ label,
12
+ id,
13
+ itemId,
14
+ itemsToRender
15
+ }) {
16
+ const Item = slots?.item ?? TreeItem;
17
+ const _useSlotProps = useSlotProps({
18
+ elementType: Item,
19
+ externalSlotProps: slotProps?.item,
20
+ additionalProps: {
21
+ itemId,
22
+ id,
23
+ label
24
+ },
25
+ ownerState: {
26
+ itemId,
27
+ label
28
+ }
29
+ }),
30
+ itemProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded);
31
+ const children = React.useMemo(() => itemsToRender ? /*#__PURE__*/_jsx(RichTreeViewItems, {
32
+ itemsToRender: itemsToRender,
33
+ slots: slots,
34
+ slotProps: slotProps
35
+ }) : null, [itemsToRender, slots, slotProps]);
36
+ return /*#__PURE__*/_jsx(Item, _extends({}, itemProps, {
37
+ children: children
38
+ }));
39
+ }
40
+ export function RichTreeViewItems(props) {
41
+ const {
42
+ itemsToRender,
43
+ slots,
44
+ slotProps
45
+ } = props;
46
+ return /*#__PURE__*/_jsx(React.Fragment, {
47
+ children: itemsToRender.map(item => /*#__PURE__*/_jsx(WrappedTreeItem, {
48
+ slots: slots,
49
+ slotProps: slotProps,
50
+ label: item.label,
51
+ id: item.id,
52
+ itemId: item.itemId,
53
+ itemsToRender: item.children
54
+ }, item.itemId))
55
+ });
56
+ }
@@ -1,19 +1,40 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
1
2
  import * as React from 'react';
2
- import useId from '@mui/utils/useId';
3
+ import { createTreeViewDefaultId } from "./useTreeViewId.utils.js";
3
4
  export const useTreeViewId = ({
4
- params
5
+ params,
6
+ state,
7
+ setState
5
8
  }) => {
6
- const treeId = useId(params.id);
7
- const getTreeItemIdAttribute = React.useCallback((itemId, idAttribute) => idAttribute ?? `${treeId}-${itemId}`, [treeId]);
9
+ const treeId = state.id.treeId;
10
+ React.useEffect(() => {
11
+ setState(prevState => {
12
+ if (prevState.id.treeId === params.id) {
13
+ return prevState;
14
+ }
15
+ return _extends({}, prevState, {
16
+ id: _extends({}, prevState.id, {
17
+ treeId: params.id ?? createTreeViewDefaultId()
18
+ })
19
+ });
20
+ });
21
+ }, [setState, params.id]);
8
22
  return {
9
23
  getRootProps: () => ({
10
24
  id: treeId
11
25
  }),
12
- instance: {
13
- getTreeItemIdAttribute
26
+ contextValue: {
27
+ treeId
14
28
  }
15
29
  };
16
30
  };
17
31
  useTreeViewId.params = {
18
32
  id: true
19
- };
33
+ };
34
+ useTreeViewId.getInitialState = ({
35
+ id
36
+ }) => ({
37
+ id: {
38
+ treeId: id ?? createTreeViewDefaultId()
39
+ }
40
+ });
@@ -0,0 +1,26 @@
1
+ let globalTreeViewDefaultId = 0;
2
+ export const createTreeViewDefaultId = () => {
3
+ globalTreeViewDefaultId += 1;
4
+ return `mui-tree-view-${globalTreeViewDefaultId}`;
5
+ };
6
+
7
+ /**
8
+ * Generate the id attribute (i.e.: the `id` attribute passed to the DOM element) of a tree item.
9
+ * If the user explicitly defined an id attribute, it will be returned.
10
+ * Otherwise, the method creates a unique id for the item based on the Tree View id attribute and the item `itemId`
11
+ * @param {object} params The parameters to determine the id attribute of the item.
12
+ * @param {TreeViewItemId} params.itemId The id of the item to get the id attribute of.
13
+ * @param {string | undefined} params.idAttribute The id attribute of the item if explicitly defined by the user.
14
+ * @param {string} params.treeId The id attribute of the Tree View.
15
+ * @returns {string} The id attribute of the item.
16
+ */
17
+ export const generateTreeItemIdAttribute = ({
18
+ id,
19
+ treeId = '',
20
+ itemId
21
+ }) => {
22
+ if (id != null) {
23
+ return id;
24
+ }
25
+ return `${treeId}-${itemId}`;
26
+ };
@@ -1,5 +1,6 @@
1
1
  export { useTreeView } from "./useTreeView/index.js";
2
2
  export { TreeViewProvider, useTreeViewContext } from "./TreeViewProvider/index.js";
3
+ export { RichTreeViewItems } from "./components/RichTreeViewItems.js";
3
4
  export { unstable_resetCleanupTracking } from "./hooks/useInstanceEventHandler.js";
4
5
 
5
6
  // Core plugins
@@ -86,7 +86,9 @@ useTreeViewExpansion.models = {
86
86
  }
87
87
  };
88
88
  const DEFAULT_EXPANDED_ITEMS = [];
89
- useTreeViewExpansion.getDefaultizedParams = params => _extends({}, params, {
89
+ useTreeViewExpansion.getDefaultizedParams = ({
90
+ params
91
+ }) => _extends({}, params, {
90
92
  defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS
91
93
  });
92
94
  useTreeViewExpansion.params = {
@@ -64,7 +64,7 @@ export const useTreeViewFocus = ({
64
64
  }
65
65
  const itemMeta = instance.getItemMeta(state.focusedItemId);
66
66
  if (itemMeta) {
67
- const itemElement = document.getElementById(instance.getTreeItemIdAttribute(state.focusedItemId, itemMeta.idAttribute));
67
+ const itemElement = instance.getItemDOMElement(state.focusedItemId);
68
68
  if (itemElement) {
69
69
  itemElement.blur();
70
70
  }
@@ -5,6 +5,7 @@ import * as React from 'react';
5
5
  import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js";
6
6
  import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "./useTreeViewItems.utils.js";
7
7
  import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js";
8
+ import { generateTreeItemIdAttribute } from "../../corePlugins/useTreeViewId/useTreeViewId.utils.js";
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
9
10
  const updateItemsState = ({
10
11
  items,
@@ -110,7 +111,11 @@ export const useTreeViewItems = ({
110
111
  if (itemMeta == null) {
111
112
  return null;
112
113
  }
113
- return document.getElementById(instance.getTreeItemIdAttribute(itemId, itemMeta.idAttribute));
114
+ return document.getElementById(generateTreeItemIdAttribute({
115
+ treeId: state.id.treeId,
116
+ itemId,
117
+ id: itemMeta.idAttribute
118
+ }));
114
119
  };
115
120
  const isItemNavigable = itemId => {
116
121
  if (params.disabledItemsFocusable) {
@@ -200,7 +205,9 @@ useTreeViewItems.getInitialState = params => ({
200
205
  getItemLabel: params.getItemLabel
201
206
  })
202
207
  });
203
- useTreeViewItems.getDefaultizedParams = params => _extends({}, params, {
208
+ useTreeViewItems.getDefaultizedParams = ({
209
+ params
210
+ }) => _extends({}, params, {
204
211
  disabledItemsFocusable: params.disabledItemsFocusable ?? false,
205
212
  itemChildrenIndentation: params.itemChildrenIndentation ?? '12px'
206
213
  });
@@ -8,6 +8,7 @@ import { useTreeViewContext } from "../../TreeViewProvider/index.js";
8
8
  import { TreeViewChildrenItemContext, TreeViewChildrenItemProvider } from "../../TreeViewProvider/TreeViewChildrenItemProvider.js";
9
9
  import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "../useTreeViewItems/useTreeViewItems.utils.js";
10
10
  import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js";
11
+ import { generateTreeItemIdAttribute } from "../../corePlugins/useTreeViewId/useTreeViewId.utils.js";
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  export const useTreeViewJSXItems = ({
13
14
  instance,
@@ -98,7 +99,8 @@ const useTreeViewJSXItemsItemPlugin = ({
98
99
  contentRef
99
100
  }) => {
100
101
  const {
101
- instance
102
+ instance,
103
+ treeId
102
104
  } = useTreeViewContext();
103
105
  const {
104
106
  children,
@@ -122,12 +124,16 @@ const useTreeViewJSXItemsItemPlugin = ({
122
124
 
123
125
  // Prevent any flashing
124
126
  useEnhancedEffect(() => {
125
- const idAttributeWithDefault = instance.getTreeItemIdAttribute(itemId, id);
126
- registerChild(idAttributeWithDefault, itemId);
127
+ const idAttribute = generateTreeItemIdAttribute({
128
+ itemId,
129
+ treeId,
130
+ id
131
+ });
132
+ registerChild(idAttribute, itemId);
127
133
  return () => {
128
- unregisterChild(idAttributeWithDefault);
134
+ unregisterChild(idAttribute);
129
135
  };
130
- }, [instance, registerChild, unregisterChild, itemId, id]);
136
+ }, [registerChild, unregisterChild, itemId, id, treeId]);
131
137
  React.useEffect(() => {
132
138
  return instance.insertJSXItem({
133
139
  id: itemId,
@@ -153,6 +153,9 @@ export const useTreeViewKeyboardNavigation = ({
153
153
  // If the focused item is collapsed and has children, we expand it
154
154
  case key === 'ArrowRight' && !isRtl || key === 'ArrowLeft' && isRtl:
155
155
  {
156
+ if (ctrlPressed) {
157
+ return;
158
+ }
156
159
  if (instance.isItemExpanded(itemId)) {
157
160
  const nextItemId = getNextNavigableItem(instance, itemId);
158
161
  if (nextItemId) {
@@ -170,6 +173,9 @@ export const useTreeViewKeyboardNavigation = ({
170
173
  // If the focused item is collapsed and has a parent, we move the focus to this parent
171
174
  case key === 'ArrowLeft' && !isRtl || key === 'ArrowRight' && isRtl:
172
175
  {
176
+ if (ctrlPressed) {
177
+ return;
178
+ }
173
179
  if (canToggleItemExpansion(itemId) && instance.isItemExpanded(itemId)) {
174
180
  instance.toggleItemExpansion(event, itemId);
175
181
  event.preventDefault();
@@ -6,14 +6,8 @@ export const useTreeViewLabel = ({
6
6
  instance,
7
7
  state,
8
8
  setState,
9
- params,
10
- experimentalFeatures
9
+ params
11
10
  }) => {
12
- if (process.env.NODE_ENV !== 'production') {
13
- if (params.isItemEditable && !experimentalFeatures?.labelEditing) {
14
- warnOnce(['MUI X: The label editing feature requires the `labelEditing` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ labelEditing: true}}` to the `RichTreeViewPro` component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/editing/']);
15
- }
16
- }
17
11
  const editedItemRef = React.useRef(state.editedItemId);
18
12
  const isItemBeingEditedRef = itemId => editedItemRef.current === itemId;
19
13
  const setEditedItemId = editedItemId => {
@@ -23,7 +17,7 @@ export const useTreeViewLabel = ({
23
17
  editedItemRef.current = editedItemId;
24
18
  };
25
19
  const isItemBeingEdited = itemId => itemId === state.editedItemId;
26
- const isTreeViewEditable = Boolean(params.isItemEditable) && !!experimentalFeatures.labelEditing;
20
+ const isTreeViewEditable = Boolean(params.isItemEditable);
27
21
  const isItemEditable = itemId => {
28
22
  if (itemId == null || !isTreeViewEditable) {
29
23
  return false;
@@ -72,6 +66,20 @@ export const useTreeViewLabel = ({
72
66
  };
73
67
  };
74
68
  useTreeViewLabel.itemPlugin = useTreeViewLabelItemPlugin;
69
+ useTreeViewLabel.getDefaultizedParams = ({
70
+ params,
71
+ experimentalFeatures
72
+ }) => {
73
+ const canUseFeature = experimentalFeatures?.labelEditing;
74
+ if (process.env.NODE_ENV !== 'production') {
75
+ if (params.isItemEditable && !canUseFeature) {
76
+ warnOnce(['MUI X: The label editing feature requires the `labelEditing` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ labelEditing: true}}` to the `RichTreeViewPro` component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/editing/']);
77
+ }
78
+ }
79
+ return _extends({}, params, {
80
+ isItemEditable: canUseFeature ? params.isItemEditable ?? false : false
81
+ });
82
+ };
75
83
  useTreeViewLabel.getInitialState = () => ({
76
84
  editedItemId: null
77
85
  });
@@ -174,7 +174,9 @@ useTreeViewSelection.models = {
174
174
  }
175
175
  };
176
176
  const DEFAULT_SELECTED_ITEMS = [];
177
- useTreeViewSelection.getDefaultizedParams = params => _extends({}, params, {
177
+ useTreeViewSelection.getDefaultizedParams = ({
178
+ params
179
+ }) => _extends({}, params, {
178
180
  disableSelection: params.disableSelection ?? false,
179
181
  multiSelect: params.multiSelect ?? false,
180
182
  checkboxSelection: params.checkboxSelection ?? false,