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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/CHANGELOG.md +651 -6
  2. package/README.md +2 -2
  3. package/RichTreeView/RichTreeView.js +2 -4
  4. package/RichTreeView/RichTreeView.types.d.ts +5 -18
  5. package/SimpleTreeView/SimpleTreeView.types.d.ts +2 -2
  6. package/TreeItem/TreeItem.js +4 -4
  7. package/TreeItem/TreeItem.types.d.ts +4 -2
  8. package/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  9. package/TreeItemIcon/TreeItemIcon.types.d.ts +1 -1
  10. package/TreeItemProvider/TreeItemProvider.d.ts +2 -4
  11. package/TreeItemProvider/TreeItemProvider.js +26 -11
  12. package/TreeItemProvider/TreeItemProvider.types.d.ts +1 -0
  13. package/hooks/index.d.ts +1 -0
  14. package/hooks/index.js +2 -1
  15. package/hooks/useTreeItemModel.d.ts +2 -0
  16. package/hooks/useTreeItemModel.js +11 -0
  17. package/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +2 -1
  18. package/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  19. package/hooks/useTreeViewApiRef.d.ts +1 -0
  20. package/index.js +1 -1
  21. package/internals/TreeViewItemDepthContext/TreeViewItemDepthContext.d.ts +3 -1
  22. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +2 -1
  23. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  24. package/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  25. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +4 -2
  26. package/internals/components/RichTreeViewItems.d.ts +3 -5
  27. package/internals/components/RichTreeViewItems.js +42 -30
  28. package/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  29. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.d.ts +36 -0
  30. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  31. package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +1 -5
  32. package/internals/hooks/useSelector.d.ts +4 -0
  33. package/internals/hooks/useSelector.js +6 -0
  34. package/internals/index.d.ts +6 -1
  35. package/internals/index.js +5 -1
  36. package/internals/models/itemPlugin.d.ts +5 -5
  37. package/internals/models/plugin.d.ts +20 -8
  38. package/internals/models/treeView.d.ts +6 -0
  39. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  40. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +124 -0
  41. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
  42. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -14
  43. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.d.ts +1 -0
  44. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
  45. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  46. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.d.ts +182 -0
  47. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  48. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +4 -16
  49. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  50. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
  51. package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
  52. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  53. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +718 -0
  54. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  55. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +15 -52
  56. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  57. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  58. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  59. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  60. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +74 -0
  61. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  62. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +7 -24
  63. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  64. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  65. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +32 -0
  66. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  67. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
  68. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +6 -6
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  70. package/internals/useTreeView/useTreeView.js +30 -17
  71. package/internals/useTreeView/useTreeView.types.d.ts +2 -3
  72. package/internals/useTreeView/useTreeViewBuildContext.d.ts +3 -1
  73. package/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  74. package/internals/utils/TreeViewStore.d.ts +12 -0
  75. package/internals/utils/TreeViewStore.js +24 -0
  76. package/internals/utils/selectors.d.ts +9 -0
  77. package/internals/utils/selectors.js +37 -0
  78. package/internals/utils/tree.d.ts +8 -8
  79. package/internals/utils/tree.js +51 -43
  80. package/models/items.d.ts +3 -2
  81. package/modern/RichTreeView/RichTreeView.js +2 -4
  82. package/modern/TreeItem/TreeItem.js +4 -4
  83. package/modern/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  84. package/modern/TreeItemProvider/TreeItemProvider.js +26 -11
  85. package/modern/hooks/index.js +2 -1
  86. package/modern/hooks/useTreeItemModel.js +11 -0
  87. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  88. package/modern/index.js +1 -1
  89. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  90. package/modern/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  91. package/modern/internals/components/RichTreeViewItems.js +42 -30
  92. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  93. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  94. package/modern/internals/hooks/useSelector.js +6 -0
  95. package/modern/internals/index.js +5 -1
  96. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  97. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
  98. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
  99. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  100. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  101. package/modern/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  102. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  103. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  104. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  105. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  106. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  107. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  108. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  109. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  110. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  111. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  112. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  113. package/modern/internals/useTreeView/useTreeView.js +30 -17
  114. package/modern/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  115. package/modern/internals/utils/TreeViewStore.js +24 -0
  116. package/modern/internals/utils/selectors.js +37 -0
  117. package/modern/internals/utils/tree.js +51 -43
  118. package/modern/useTreeItem/useTreeItem.js +26 -11
  119. package/node/RichTreeView/RichTreeView.js +2 -4
  120. package/node/TreeItem/TreeItem.js +4 -4
  121. package/node/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +2 -2
  122. package/node/TreeItemProvider/TreeItemProvider.js +26 -10
  123. package/node/hooks/index.js +8 -1
  124. package/node/hooks/useTreeItemModel.js +17 -0
  125. package/node/hooks/useTreeItemUtils/useTreeItemUtils.js +32 -15
  126. package/node/index.js +1 -1
  127. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  128. package/node/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  129. package/node/internals/components/RichTreeViewItems.js +42 -30
  130. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +12 -13
  131. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +15 -0
  132. package/node/internals/hooks/useSelector.js +13 -0
  133. package/node/internals/index.js +47 -1
  134. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  135. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +23 -0
  136. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +14 -0
  137. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  138. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +40 -0
  139. package/node/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +16 -13
  140. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -100
  141. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +109 -0
  142. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +30 -27
  143. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  144. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  145. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  146. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +32 -0
  147. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  148. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +46 -35
  149. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +15 -0
  150. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +24 -14
  151. package/node/internals/useTreeView/useTreeView.js +30 -17
  152. package/node/internals/useTreeView/useTreeViewBuildContext.js +25 -18
  153. package/node/internals/utils/TreeViewStore.js +31 -0
  154. package/node/internals/utils/selectors.js +44 -0
  155. package/node/internals/utils/tree.js +51 -43
  156. package/node/useTreeItem/useTreeItem.js +26 -11
  157. package/package.json +6 -4
  158. package/useTreeItem/useTreeItem.js +26 -11
  159. package/useTreeItem/useTreeItem.types.d.ts +9 -0
package/README.md CHANGED
@@ -16,8 +16,8 @@ This component has the following peer dependencies that you need to install as w
16
16
  ```json
17
17
  "peerDependencies": {
18
18
  "@mui/material": "^5.15.14 || ^6.0.0",
19
- "react": "^17.0.0 || ^18.0.0",
20
- "react-dom": "^17.0.0 || ^18.0.0"
19
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
20
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
21
21
  },
22
22
  ```
23
23
 
@@ -56,8 +56,7 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
56
56
  }
57
57
  const {
58
58
  getRootProps,
59
- contextValue,
60
- instance
59
+ contextValue
61
60
  } = useTreeView({
62
61
  plugins: RICH_TREE_VIEW_PLUGINS,
63
62
  rootRef: ref,
@@ -81,8 +80,7 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
81
80
  children: /*#__PURE__*/_jsx(Root, _extends({}, rootProps, {
82
81
  children: /*#__PURE__*/_jsx(RichTreeViewItems, {
83
82
  slots: slots,
84
- slotProps: slotProps,
85
- itemsToRender: instance.getItemsToRender()
83
+ slotProps: slotProps
86
84
  })
87
85
  }))
88
86
  });
@@ -1,32 +1,20 @@
1
1
  import * as React from 'react';
2
2
  import { Theme } from '@mui/material/styles';
3
- import { SxProps } from '@mui/system';
4
- import { SlotComponentProps } from '@mui/utils';
5
- import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
3
+ import { SxProps } from '@mui/system/styleFunctionSx';
4
+ import { SlotComponentProps } from '@mui/utils/types';
6
5
  import { RichTreeViewClasses } from './richTreeViewClasses';
7
6
  import { RichTreeViewPluginParameters, RichTreeViewPluginSlotProps, RichTreeViewPluginSlots, RichTreeViewPluginSignatures } from './RichTreeView.plugins';
8
- import { TreeItemProps } from '../TreeItem';
9
- import { TreeViewItemId } from '../models';
10
7
  import { TreeViewExperimentalFeatures, TreeViewPublicAPI } from '../internals/models';
11
- interface RichTreeViewItemSlotOwnerState {
12
- itemId: TreeViewItemId;
13
- label: string;
14
- }
15
- export interface RichTreeViewSlots extends RichTreeViewPluginSlots {
8
+ import { RichTreeViewItemsSlotProps, RichTreeViewItemsSlots } from '../internals/components/RichTreeViewItems';
9
+ export interface RichTreeViewSlots extends RichTreeViewPluginSlots, RichTreeViewItemsSlots {
16
10
  /**
17
11
  * Element rendered at the root.
18
12
  * @default RichTreeViewRoot
19
13
  */
20
14
  root?: React.ElementType;
21
- /**
22
- * Custom component for the item.
23
- * @default TreeItem.
24
- */
25
- item?: React.JSXElementConstructor<TreeItemProps>;
26
15
  }
27
- export interface RichTreeViewSlotProps<R extends {}, Multiple extends boolean | undefined> extends RichTreeViewPluginSlotProps {
16
+ export interface RichTreeViewSlotProps<R extends {}, Multiple extends boolean | undefined> extends RichTreeViewPluginSlotProps, RichTreeViewItemsSlotProps {
28
17
  root?: SlotComponentProps<'ul', {}, RichTreeViewProps<R, Multiple>>;
29
- item?: SlotComponentPropsFromProps<TreeItemProps, {}, RichTreeViewItemSlotOwnerState>;
30
18
  }
31
19
  export type RichTreeViewApiRef = React.MutableRefObject<TreeViewPublicAPI<RichTreeViewPluginSignatures> | undefined>;
32
20
  export interface RichTreeViewPropsBase extends React.HTMLAttributes<HTMLUListElement> {
@@ -62,4 +50,3 @@ export interface RichTreeViewProps<R extends {}, Multiple extends boolean | unde
62
50
  */
63
51
  experimentalFeatures?: TreeViewExperimentalFeatures<RichTreeViewPluginSignatures>;
64
52
  }
65
- export {};
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Theme } from '@mui/material/styles';
3
- import { SlotComponentProps } from '@mui/utils';
4
- import { SxProps } from '@mui/system';
3
+ import { SlotComponentProps } from '@mui/utils/types';
4
+ import { SxProps } from '@mui/system/styleFunctionSx';
5
5
  import { SimpleTreeViewClasses } from './simpleTreeViewClasses';
6
6
  import { SimpleTreeViewPluginParameters, SimpleTreeViewPluginSlotProps, SimpleTreeViewPluginSlots, SimpleTreeViewPluginSignatures } from './SimpleTreeView.plugins';
7
7
  import { TreeViewExperimentalFeatures, TreeViewPublicAPI } from '../internals/models';
@@ -210,6 +210,7 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
210
210
  } = props,
211
211
  other = _objectWithoutPropertiesLoose(props, _excluded2);
212
212
  const {
213
+ getContextProviderProps,
213
214
  getRootProps,
214
215
  getContentProps,
215
216
  getIconContainerProps,
@@ -296,8 +297,7 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
296
297
  ownerState: {},
297
298
  className: classes.dragAndDropOverlay
298
299
  });
299
- return /*#__PURE__*/_jsx(TreeItemProvider, {
300
- itemId: itemId,
300
+ return /*#__PURE__*/_jsx(TreeItemProvider, _extends({}, getContextProviderProps(), {
301
301
  children: /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
302
302
  children: [/*#__PURE__*/_jsxs(Content, _extends({}, contentProps, {
303
303
  children: [/*#__PURE__*/_jsx(IconContainer, _extends({}, iconContainerProps, {
@@ -311,7 +311,7 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
311
311
  as: GroupTransition
312
312
  }, groupTransitionProps))]
313
313
  }))
314
- });
314
+ }));
315
315
  });
316
316
  process.env.NODE_ENV !== "production" ? TreeItem.propTypes = {
317
317
  // ----------------------------- Warning --------------------------------
@@ -321,7 +321,7 @@ process.env.NODE_ENV !== "production" ? TreeItem.propTypes = {
321
321
  /**
322
322
  * The content of the component.
323
323
  */
324
- children: PropTypes.node,
324
+ children: PropTypes /* @typescript-to-proptypes-ignore */.any,
325
325
  /**
326
326
  * Override or extend the styles applied to the component.
327
327
  */
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
- import { SlotComponentProps } from '@mui/utils';
2
+ import { SlotComponentPropsFromProps } from '@mui/x-internals/types';
3
+ import { TransitionProps } from '@mui/material/transitions';
4
+ import { SlotComponentProps } from '@mui/utils/types';
3
5
  import { UseTreeItemParameters, UseTreeItemStatus } from '../useTreeItem';
4
6
  import { TreeItemClasses } from './treeItemClasses';
5
7
  import { TreeItemIconSlotProps, TreeItemIconSlots } from '../TreeItemIcon';
@@ -51,7 +53,7 @@ export interface TreeItemSlots extends TreeItemIconSlots {
51
53
  export interface TreeItemSlotProps extends TreeItemIconSlotProps {
52
54
  root?: SlotComponentProps<'li', {}, {}>;
53
55
  content?: SlotComponentProps<'div', {}, {}>;
54
- groupTransition?: SlotComponentProps<'div', {}, {}>;
56
+ groupTransition?: SlotComponentPropsFromProps<TransitionProps, {}, {}>;
55
57
  iconContainer?: SlotComponentProps<'div', {}, {}>;
56
58
  checkbox?: SlotComponentProps<'button', {}, {}>;
57
59
  label?: SlotComponentProps<'div', {}, {}>;
@@ -4,7 +4,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { alpha } from '@mui/material/styles';
7
- import { shouldForwardProp } from '@mui/system';
7
+ import { shouldForwardProp } from '@mui/system/createStyled';
8
8
  import { styled } from "../internals/zero-styled/index.js";
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  const TreeItemDragAndDropOverlayRoot = styled('div', {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { SlotComponentProps } from '@mui/utils';
2
+ import { SlotComponentProps } from '@mui/utils/types';
3
3
  import { UseTreeItemStatus } from '../useTreeItem';
4
4
  export interface TreeItemIconSlots {
5
5
  /**
@@ -1,8 +1,6 @@
1
+ import * as React from 'react';
1
2
  import { TreeItemProviderProps } from './TreeItemProvider.types';
2
- /**
3
- * @ignore - internal component.
4
- */
5
- declare function TreeItemProvider(props: TreeItemProviderProps): import("react").ReactNode;
3
+ declare function TreeItemProvider(props: TreeItemProviderProps): React.JSX.Element;
6
4
  declare namespace TreeItemProvider {
7
5
  var propTypes: any;
8
6
  }
@@ -1,30 +1,45 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
1
4
  import PropTypes from 'prop-types';
2
5
  import { useTreeViewContext } from "../internals/TreeViewProvider/index.js";
3
-
4
- /**
5
- * @ignore - internal component.
6
- */
6
+ import { generateTreeItemIdAttribute } from "../internals/corePlugins/useTreeViewId/useTreeViewId.utils.js";
7
+ import { useSelector } from "../internals/hooks/useSelector.js";
8
+ import { selectorTreeViewId } from "../internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
7
10
  function TreeItemProvider(props) {
8
11
  const {
9
12
  children,
10
- itemId
13
+ itemId,
14
+ id
11
15
  } = props;
12
16
  const {
13
17
  wrapItem,
14
- instance
18
+ instance,
19
+ store
15
20
  } = useTreeViewContext();
16
- return wrapItem({
17
- children,
21
+ const treeId = useSelector(store, selectorTreeViewId);
22
+ const idAttribute = generateTreeItemIdAttribute({
18
23
  itemId,
19
- instance
24
+ treeId,
25
+ id
26
+ });
27
+ return /*#__PURE__*/_jsx(React.Fragment, {
28
+ children: wrapItem({
29
+ children,
30
+ itemId,
31
+ instance,
32
+ idAttribute
33
+ })
20
34
  });
21
35
  }
22
- TreeItemProvider.propTypes = {
36
+ process.env.NODE_ENV !== "production" ? TreeItemProvider.propTypes = {
23
37
  // ----------------------------- Warning --------------------------------
24
38
  // | These PropTypes are generated from the TypeScript type definitions |
25
39
  // | To update them edit the TypeScript types and run "pnpm proptypes" |
26
40
  // ----------------------------------------------------------------------
27
41
  children: PropTypes.node,
42
+ id: PropTypes.string,
28
43
  itemId: PropTypes.string.isRequired
29
- };
44
+ } : void 0;
30
45
  export { TreeItemProvider };
@@ -3,4 +3,5 @@ import { TreeViewItemId } from '../models';
3
3
  export interface TreeItemProviderProps {
4
4
  children: React.ReactNode;
5
5
  itemId: TreeViewItemId;
6
+ id: string | undefined;
6
7
  }
package/hooks/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { useTreeViewApiRef } from './useTreeViewApiRef';
2
2
  export { useTreeItemUtils } from './useTreeItemUtils';
3
+ export { useTreeItemModel } from './useTreeItemModel';
package/hooks/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { useTreeViewApiRef } from "./useTreeViewApiRef.js";
2
- export { useTreeItemUtils } from "./useTreeItemUtils/index.js";
2
+ export { useTreeItemUtils } from "./useTreeItemUtils/index.js";
3
+ export { useTreeItemModel } from "./useTreeItemModel.js";
@@ -0,0 +1,2 @@
1
+ import { TreeViewBaseItem, TreeViewDefaultItemModelProperties, TreeViewItemId } from '../models';
2
+ export declare const useTreeItemModel: <R extends {} = TreeViewDefaultItemModelProperties>(itemId: TreeViewItemId) => TreeViewBaseItem<R> | null;
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+
3
+ import { useTreeViewContext } from "../internals/TreeViewProvider/index.js";
4
+ import { useSelector } from "../internals/hooks/useSelector.js";
5
+ import { selectorItemModel } from "../internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js";
6
+ export const useTreeItemModel = itemId => {
7
+ const {
8
+ store
9
+ } = useTreeViewContext();
10
+ return useSelector(store, selectorItemModel, itemId);
11
+ };
@@ -35,8 +35,9 @@ interface UseTreeItemUtilsReturnValue<TSignatures extends UseTreeItemUtilsMinima
35
35
  */
36
36
  publicAPI: TreeViewPublicAPI<TSignatures, TOptionalSignatures>;
37
37
  }
38
+ export declare const isItemExpandable: (reactChildren: React.ReactNode) => boolean;
38
39
  export declare const useTreeItemUtils: <TSignatures extends UseTreeItemUtilsMinimalPlugins = UseTreeItemUtilsMinimalPlugins, TOptionalSignatures extends UseTreeItemUtilsOptionalPlugins = UseTreeItemUtilsOptionalPlugins>({ itemId, children, }: {
39
40
  itemId: string;
40
- children: React.ReactNode;
41
+ children?: React.ReactNode;
41
42
  }) => UseTreeItemUtilsReturnValue<TSignatures, TOptionalSignatures>;
42
43
  export {};
@@ -3,6 +3,12 @@
3
3
  import { useTreeViewContext } from "../../internals/TreeViewProvider/index.js";
4
4
  import { useTreeViewLabel } from "../../internals/plugins/useTreeViewLabel/index.js";
5
5
  import { hasPlugin } from "../../internals/utils/plugins.js";
6
+ import { useSelector } from "../../internals/hooks/useSelector.js";
7
+ import { selectorIsItemExpanded } from "../../internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js";
8
+ import { selectorIsItemFocused } from "../../internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js";
9
+ import { selectorIsItemDisabled } from "../../internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js";
10
+ import { selectorIsItemSelected } from "../../internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js";
11
+ import { selectorIsItemBeingEdited, selectorIsItemEditable } from "../../internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js";
6
12
 
7
13
  /**
8
14
  * Plugins that need to be present in the Tree View in order for `useTreeItemUtils` to work correctly.
@@ -12,7 +18,7 @@ import { hasPlugin } from "../../internals/utils/plugins.js";
12
18
  * Plugins that `useTreeItemUtils` can use if they are present, but are not required.
13
19
  */
14
20
 
15
- const isItemExpandable = reactChildren => {
21
+ export const isItemExpandable = reactChildren => {
16
22
  if (Array.isArray(reactChildren)) {
17
23
  return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
18
24
  }
@@ -24,19 +30,30 @@ export const useTreeItemUtils = ({
24
30
  }) => {
25
31
  const {
26
32
  instance,
33
+ label,
34
+ store,
27
35
  selection: {
28
36
  multiSelect
29
37
  },
30
38
  publicAPI
31
39
  } = useTreeViewContext();
40
+ const isExpanded = useSelector(store, selectorIsItemExpanded, itemId);
41
+ const isFocused = useSelector(store, selectorIsItemFocused, itemId);
42
+ const isSelected = useSelector(store, selectorIsItemSelected, itemId);
43
+ const isDisabled = useSelector(store, selectorIsItemDisabled, itemId);
44
+ const isEditing = useSelector(store, state => label == null ? false : selectorIsItemBeingEdited(state, itemId));
45
+ const isEditable = useSelector(store, state => label == null ? false : selectorIsItemEditable(state, {
46
+ itemId,
47
+ isItemEditable: label.isItemEditable
48
+ }));
32
49
  const status = {
33
50
  expandable: isItemExpandable(children),
34
- expanded: instance.isItemExpanded(itemId),
35
- focused: instance.isItemFocused(itemId),
36
- selected: instance.isItemSelected(itemId),
37
- disabled: instance.isItemDisabled(itemId),
38
- editing: instance?.isItemBeingEdited ? instance?.isItemBeingEdited(itemId) : false,
39
- editable: instance.isItemEditable ? instance.isItemEditable(itemId) : false
51
+ expanded: isExpanded,
52
+ focused: isFocused,
53
+ selected: isSelected,
54
+ disabled: isDisabled,
55
+ editing: isEditing,
56
+ editable: isEditable
40
57
  };
41
58
  const handleExpansion = event => {
42
59
  if (status.disabled) {
@@ -48,7 +65,7 @@ export const useTreeItemUtils = ({
48
65
  const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
49
66
 
50
67
  // If already expanded and trying to toggle selection don't close
51
- if (status.expandable && !(multiple && instance.isItemExpanded(itemId))) {
68
+ if (status.expandable && !(multiple && selectorIsItemExpanded(store.value, itemId))) {
52
69
  instance.toggleItemExpansion(event, itemId);
53
70
  }
54
71
  };
@@ -95,15 +112,15 @@ export const useTreeItemUtils = ({
95
112
  if (!hasPlugin(instance, useTreeViewLabel)) {
96
113
  return;
97
114
  }
98
- if (instance.isItemEditable(itemId)) {
99
- if (instance.isItemBeingEdited(itemId)) {
115
+ if (isEditable) {
116
+ if (isEditing) {
100
117
  instance.setEditedItemId(null);
101
118
  } else {
102
119
  instance.setEditedItemId(itemId);
103
120
  }
104
121
  }
105
122
  };
106
- const handleSaveItemLabel = (event, label) => {
123
+ const handleSaveItemLabel = (event, newLabel) => {
107
124
  if (!hasPlugin(instance, useTreeViewLabel)) {
108
125
  return;
109
126
  }
@@ -111,9 +128,8 @@ export const useTreeItemUtils = ({
111
128
  // As a side effect of `instance.focusItem` called here and in `handleCancelItemLabelEditing` the `labelInput` is blurred
112
129
  // The `onBlur` event is triggered, which calls `handleSaveItemLabel` again.
113
130
  // To avoid creating an unwanted behavior we need to check if the item is being edited before calling `updateItemLabel`
114
- // using `instance.isItemBeingEditedRef` instead of `instance.isItemBeingEdited` since the state is not yet updated in this point
115
- if (instance.isItemBeingEditedRef(itemId)) {
116
- instance.updateItemLabel(itemId, label);
131
+ if (selectorIsItemBeingEdited(store.value, itemId)) {
132
+ instance.updateItemLabel(itemId, newLabel);
117
133
  toggleItemEditing();
118
134
  instance.focusItem(event, itemId);
119
135
  }
@@ -122,7 +138,7 @@ export const useTreeItemUtils = ({
122
138
  if (!hasPlugin(instance, useTreeViewLabel)) {
123
139
  return;
124
140
  }
125
- if (instance.isItemBeingEditedRef(itemId)) {
141
+ if (selectorIsItemBeingEdited(store.value, itemId)) {
126
142
  toggleItemEditing();
127
143
  instance.focusItem(event, itemId);
128
144
  }
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { TreeViewAnyPluginSignature, TreeViewPublicAPI } from '../internals/models';
3
+ import { RichTreeViewPluginSignatures } from '../RichTreeView/RichTreeView.plugins';
3
4
  /**
4
5
  * Hook that instantiates a [[TreeViewApiRef]].
5
6
  */
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v8.0.0-alpha.0
2
+ * @mui/x-tree-view v8.0.0-alpha.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,3 +1,5 @@
1
1
  import * as React from 'react';
2
2
  import { TreeViewItemId } from '../../models';
3
- export declare const TreeViewItemDepthContext: React.Context<number | ((itemId: TreeViewItemId) => number)>;
3
+ import { TreeViewState } from '../models';
4
+ import type { UseTreeViewItemsSignature } from '../plugins/useTreeViewItems';
5
+ export declare const TreeViewItemDepthContext: React.Context<number | ((state: TreeViewState<[UseTreeViewItemsSignature]>, itemId: TreeViewItemId) => number)>;
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
2
  export declare const TreeViewChildrenItemContext: React.Context<TreeViewChildrenItemContextValue | null>;
3
3
  interface TreeViewChildrenItemProviderProps {
4
- itemId?: string;
4
+ itemId: string | null;
5
+ idAttribute: string | null;
5
6
  children: React.ReactNode;
6
7
  }
7
8
  export declare function TreeViewChildrenItemProvider(props: TreeViewChildrenItemProviderProps): React.JSX.Element;
@@ -2,7 +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
+ import { selectorItemOrderedChildrenIds } from "../plugins/useTreeViewItems/useTreeViewItems.selectors.js";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
7
  export const TreeViewChildrenItemContext = /*#__PURE__*/React.createContext(null);
8
8
  if (process.env.NODE_ENV !== 'production') {
@@ -11,11 +11,12 @@ if (process.env.NODE_ENV !== 'production') {
11
11
  export function TreeViewChildrenItemProvider(props) {
12
12
  const {
13
13
  children,
14
- itemId = null
14
+ itemId = null,
15
+ idAttribute
15
16
  } = props;
16
17
  const {
17
18
  instance,
18
- treeId,
19
+ store,
19
20
  rootRef
20
21
  } = useTreeViewContext();
21
22
  const childrenIdAttrToIdRef = React.useRef(new Map());
@@ -23,25 +24,8 @@ export function TreeViewChildrenItemProvider(props) {
23
24
  if (!rootRef.current) {
24
25
  return;
25
26
  }
26
- let idAttr = null;
27
- if (itemId == null) {
28
- idAttr = rootRef.current.id;
29
- } else {
30
- // Undefined during 1st render
31
- const itemMeta = instance.getItemMeta(itemId);
32
- if (itemMeta !== undefined) {
33
- idAttr = generateTreeItemIdAttribute({
34
- itemId,
35
- treeId,
36
- id: itemMeta.idAttribute
37
- });
38
- }
39
- }
40
- if (idAttr == null) {
41
- return;
42
- }
43
- const previousChildrenIds = instance.getItemOrderedChildrenIds(itemId ?? null) ?? [];
44
- const escapedIdAttr = escapeOperandAttributeSelector(idAttr);
27
+ const previousChildrenIds = selectorItemOrderedChildrenIds(store.value, itemId ?? null) ?? [];
28
+ const escapedIdAttr = escapeOperandAttributeSelector(idAttribute ?? rootRef.current.id);
45
29
  const childrenElements = rootRef.current.querySelectorAll(`${itemId == null ? '' : `*[id="${escapedIdAttr}"] `}[role="treeitem"]:not(*[id="${escapedIdAttr}"] [role="treeitem"] [role="treeitem"])`);
46
30
  const childrenIds = Array.from(childrenElements).map(child => childrenIdAttrToIdRef.current.get(child.id));
47
31
  const hasChanged = childrenIds.length !== previousChildrenIds.length || childrenIds.some((childId, index) => childId !== previousChildrenIds[index]);
@@ -14,8 +14,7 @@ export function TreeViewProvider(props) {
14
14
  return /*#__PURE__*/_jsx(TreeViewContext.Provider, {
15
15
  value: value,
16
16
  children: value.wrapRoot({
17
- children,
18
- instance: value.instance
17
+ children
19
18
  })
20
19
  });
21
20
  }
@@ -1,14 +1,16 @@
1
1
  import * as React from 'react';
2
2
  import { MergeSignaturesProperty, TreeItemWrapper, TreeRootWrapper, TreeViewAnyPluginSignature, TreeViewInstance, TreeViewItemPluginResponse, TreeViewPublicAPI } from '../models';
3
+ import { TreeViewStore } from '../utils/TreeViewStore';
3
4
  import { TreeViewCorePluginSignatures } from '../corePlugins';
4
- import type { TreeItemProps } from '../../TreeItem';
5
+ import type { TreeItemProps } from '../../TreeItem/TreeItem.types';
5
6
  export type TreeViewItemPluginsRunner = (props: TreeItemProps) => Required<TreeViewItemPluginResponse>;
6
7
  export type TreeViewContextValue<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'contextValue'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'contextValue'>> & {
7
8
  instance: TreeViewInstance<TSignatures, TOptionalSignatures>;
8
9
  publicAPI: TreeViewPublicAPI<TSignatures, TOptionalSignatures>;
10
+ store: TreeViewStore<TSignatures>;
9
11
  rootRef: React.RefObject<HTMLUListElement>;
10
12
  wrapItem: TreeItemWrapper<TSignatures>;
11
- wrapRoot: TreeRootWrapper<TSignatures>;
13
+ wrapRoot: TreeRootWrapper;
12
14
  runItemPlugins: TreeViewItemPluginsRunner;
13
15
  };
14
16
  export interface TreeViewProviderProps<TSignatures extends readonly TreeViewAnyPluginSignature[]> {
@@ -1,15 +1,15 @@
1
1
  import * as React from 'react';
2
- import { SlotComponentProps } from '@mui/utils';
2
+ import { SlotComponentProps } from '@mui/utils/types';
3
3
  import { TreeItem, TreeItemProps } from '../../TreeItem';
4
4
  import { TreeViewItemId } from '../../models';
5
- import { TreeViewItemToRenderProps } from '../plugins/useTreeViewItems';
5
+ export declare function RichTreeViewItems(props: RichTreeViewItemsProps): React.JSX.Element;
6
6
  interface RichTreeViewItemsOwnerState {
7
7
  itemId: TreeViewItemId;
8
8
  label: string;
9
9
  }
10
10
  export interface RichTreeViewItemsSlots {
11
11
  /**
12
- * Custom component for the item.
12
+ * Custom component to render a Tree Item.
13
13
  * @default TreeItem.
14
14
  */
15
15
  item?: React.JSXElementConstructor<TreeItemProps>;
@@ -18,7 +18,6 @@ export interface RichTreeViewItemsSlotProps {
18
18
  item?: SlotComponentProps<typeof TreeItem, {}, RichTreeViewItemsOwnerState>;
19
19
  }
20
20
  export interface RichTreeViewItemsProps {
21
- itemsToRender: TreeViewItemToRenderProps[];
22
21
  /**
23
22
  * Overridable component slots.
24
23
  * @default {}
@@ -30,5 +29,4 @@ export interface RichTreeViewItemsProps {
30
29
  */
31
30
  slotProps?: RichTreeViewItemsSlotProps;
32
31
  }
33
- export declare function RichTreeViewItems(props: RichTreeViewItemsProps): React.JSX.Element;
34
32
  export {};
@@ -3,54 +3,66 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["ownerState"];
4
4
  import * as React from 'react';
5
5
  import useSlotProps from '@mui/utils/useSlotProps';
6
+ import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
6
7
  import { TreeItem } from "../../TreeItem/index.js";
8
+ import { useSelector } from "../hooks/useSelector.js";
9
+ import { selectorItemMeta, selectorItemOrderedChildrenIds } from "../plugins/useTreeViewItems/useTreeViewItems.selectors.js";
10
+ import { useTreeViewContext } from "../TreeViewProvider/index.js";
7
11
  import { jsx as _jsx } from "react/jsx-runtime";
8
- function WrappedTreeItem({
9
- slots,
10
- slotProps,
11
- label,
12
- id,
13
- itemId,
14
- itemsToRender
12
+ const RichTreeViewItemsContext = /*#__PURE__*/React.createContext(null);
13
+ if (process.env.NODE_ENV !== 'production') {
14
+ RichTreeViewItemsContext.displayName = 'RichTreeViewItemsProvider';
15
+ }
16
+ const WrappedTreeItem = /*#__PURE__*/React.memo(function WrappedTreeItem({
17
+ itemSlot,
18
+ itemSlotProps,
19
+ itemId
15
20
  }) {
16
- const Item = slots?.item ?? TreeItem;
21
+ const renderItemForRichTreeView = React.useContext(RichTreeViewItemsContext);
22
+ const {
23
+ store
24
+ } = useTreeViewContext();
25
+ const itemMeta = useSelector(store, selectorItemMeta, itemId);
26
+ const children = useSelector(store, selectorItemOrderedChildrenIds, itemId);
27
+ const Item = itemSlot ?? TreeItem;
17
28
  const _useSlotProps = useSlotProps({
18
29
  elementType: Item,
19
- externalSlotProps: slotProps?.item,
30
+ externalSlotProps: itemSlotProps,
20
31
  additionalProps: {
21
- itemId,
22
- id,
23
- label
32
+ label: itemMeta?.label,
33
+ id: itemMeta?.idAttribute,
34
+ itemId
24
35
  },
25
36
  ownerState: {
26
37
  itemId,
27
- label
38
+ label: itemMeta?.label
28
39
  }
29
40
  }),
30
41
  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
42
  return /*#__PURE__*/_jsx(Item, _extends({}, itemProps, {
37
- children: children
43
+ children: children?.map(renderItemForRichTreeView)
38
44
  }));
39
- }
45
+ }, fastObjectShallowCompare);
40
46
  export function RichTreeViewItems(props) {
41
47
  const {
42
- itemsToRender,
43
48
  slots,
44
49
  slotProps
45
50
  } = 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))
51
+ const {
52
+ store
53
+ } = useTreeViewContext();
54
+ const itemSlot = slots?.item;
55
+ const itemSlotProps = slotProps?.item;
56
+ const items = useSelector(store, selectorItemOrderedChildrenIds, null);
57
+ const renderItem = React.useCallback(itemId => {
58
+ return /*#__PURE__*/_jsx(WrappedTreeItem, {
59
+ itemSlot: itemSlot,
60
+ itemSlotProps: itemSlotProps,
61
+ itemId: itemId
62
+ }, itemId);
63
+ }, [itemSlot, itemSlotProps]);
64
+ return /*#__PURE__*/_jsx(RichTreeViewItemsContext.Provider, {
65
+ value: renderItem,
66
+ children: items.map(renderItem)
55
67
  });
56
68
  }