@mui/x-tree-view 7.11.0 → 7.12.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 (111) hide show
  1. package/CHANGELOG.md +194 -4
  2. package/RichTreeView/RichTreeView.js +11 -7
  3. package/RichTreeView/RichTreeView.types.d.ts +1 -1
  4. package/SimpleTreeView/SimpleTreeView.js +11 -7
  5. package/SimpleTreeView/SimpleTreeView.types.d.ts +1 -1
  6. package/TreeItem/TreeItem.js +36 -10
  7. package/TreeItem/TreeItem.types.d.ts +1 -1
  8. package/TreeItem/TreeItemContent.d.ts +2 -0
  9. package/TreeItem/TreeItemContent.js +11 -3
  10. package/TreeItem/treeItemClasses.d.ts +2 -0
  11. package/TreeItem/treeItemClasses.js +1 -1
  12. package/TreeItem/useTreeItemState.d.ts +1 -0
  13. package/TreeItem/useTreeItemState.js +5 -1
  14. package/TreeItem2/TreeItem2.js +15 -3
  15. package/TreeItem2/TreeItem2.types.d.ts +8 -1
  16. package/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.d.ts +4 -0
  17. package/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.js +69 -0
  18. package/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.types.d.ts +6 -0
  19. package/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.types.js +1 -0
  20. package/TreeItem2DragAndDropOverlay/index.d.ts +2 -0
  21. package/TreeItem2DragAndDropOverlay/index.js +1 -0
  22. package/TreeItem2DragAndDropOverlay/package.json +6 -0
  23. package/TreeItem2Icon/TreeItem2Icon.js +3 -2
  24. package/TreeItem2Icon/TreeItem2Icon.types.d.ts +1 -1
  25. package/TreeItem2Provider/TreeItem2Provider.js +1 -1
  26. package/TreeView/TreeView.js +8 -3
  27. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +1 -1
  28. package/index.js +1 -1
  29. package/internals/TreeViewProvider/index.d.ts +1 -0
  30. package/internals/TreeViewProvider/index.js +2 -1
  31. package/internals/index.d.ts +6 -5
  32. package/internals/index.js +4 -3
  33. package/internals/models/index.d.ts +2 -0
  34. package/internals/models/index.js +3 -1
  35. package/internals/models/itemPlugin.d.ts +37 -0
  36. package/internals/models/itemPlugin.js +1 -0
  37. package/internals/models/plugin.d.ts +2 -15
  38. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +2 -3
  39. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
  40. package/internals/plugins/useTreeViewItems/index.d.ts +2 -1
  41. package/internals/plugins/useTreeViewItems/index.js +2 -1
  42. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +6 -2
  43. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +18 -4
  44. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +1 -1
  45. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +2 -2
  46. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +1 -2
  47. package/internals/useTreeView/useTreeView.types.d.ts +1 -1
  48. package/internals/useTreeView/useTreeViewBuildContext.js +23 -1
  49. package/internals/utils/tree.d.ts +8 -0
  50. package/internals/utils/tree.js +11 -0
  51. package/internals/utils/warning.d.ts +2 -1
  52. package/internals/utils/warning.js +19 -12
  53. package/models/items.d.ts +1 -0
  54. package/modern/RichTreeView/RichTreeView.js +11 -7
  55. package/modern/SimpleTreeView/SimpleTreeView.js +11 -7
  56. package/modern/TreeItem/TreeItem.js +36 -10
  57. package/modern/TreeItem/TreeItemContent.js +11 -3
  58. package/modern/TreeItem/treeItemClasses.js +1 -1
  59. package/modern/TreeItem/useTreeItemState.js +5 -1
  60. package/modern/TreeItem2/TreeItem2.js +15 -3
  61. package/modern/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.js +69 -0
  62. package/modern/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.types.js +1 -0
  63. package/modern/TreeItem2DragAndDropOverlay/index.js +1 -0
  64. package/modern/TreeItem2Icon/TreeItem2Icon.js +3 -2
  65. package/modern/TreeItem2Provider/TreeItem2Provider.js +1 -1
  66. package/modern/TreeView/TreeView.js +8 -3
  67. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +1 -1
  68. package/modern/index.js +1 -1
  69. package/modern/internals/TreeViewProvider/index.js +2 -1
  70. package/modern/internals/index.js +4 -3
  71. package/modern/internals/models/index.js +3 -1
  72. package/modern/internals/models/itemPlugin.js +1 -0
  73. package/modern/internals/plugins/useTreeViewItems/index.js +2 -1
  74. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +6 -2
  75. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +1 -1
  76. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +2 -2
  77. package/modern/internals/useTreeView/useTreeViewBuildContext.js +23 -1
  78. package/modern/internals/utils/tree.js +11 -0
  79. package/modern/internals/utils/warning.js +19 -12
  80. package/modern/useTreeItem2/useTreeItem2.js +43 -15
  81. package/node/RichTreeView/RichTreeView.js +12 -8
  82. package/node/SimpleTreeView/SimpleTreeView.js +11 -7
  83. package/node/TreeItem/TreeItem.js +45 -19
  84. package/node/TreeItem/TreeItemContent.js +11 -3
  85. package/node/TreeItem/treeItemClasses.js +1 -1
  86. package/node/TreeItem/useTreeItemState.js +6 -2
  87. package/node/TreeItem2/TreeItem2.js +21 -9
  88. package/node/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.js +77 -0
  89. package/node/TreeItem2DragAndDropOverlay/TreeItem2DragAndDropOverlay.types.js +5 -0
  90. package/node/TreeItem2DragAndDropOverlay/index.js +12 -0
  91. package/node/TreeItem2Icon/TreeItem2Icon.js +6 -5
  92. package/node/TreeItem2Provider/TreeItem2Provider.js +2 -2
  93. package/node/TreeView/TreeView.js +8 -3
  94. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +2 -2
  95. package/node/index.js +1 -1
  96. package/node/internals/TreeViewProvider/index.js +8 -1
  97. package/node/internals/index.js +27 -2
  98. package/node/internals/models/index.js +22 -0
  99. package/node/internals/models/itemPlugin.js +5 -0
  100. package/node/internals/plugins/useTreeViewItems/index.js +14 -1
  101. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +6 -2
  102. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +2 -2
  103. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +1 -1
  104. package/node/internals/useTreeView/useTreeViewBuildContext.js +23 -1
  105. package/node/internals/utils/tree.js +14 -2
  106. package/node/internals/utils/warning.js +21 -14
  107. package/node/useTreeItem2/useTreeItem2.js +49 -21
  108. package/package.json +5 -6
  109. package/useTreeItem2/index.d.ts +1 -1
  110. package/useTreeItem2/useTreeItem2.js +43 -15
  111. package/useTreeItem2/useTreeItem2.types.d.ts +17 -4
@@ -181,4 +181,15 @@ export const getAllNavigableItems = instance => {
181
181
  item = getNextNavigableItem(instance, item);
182
182
  }
183
183
  return navigableItems;
184
+ };
185
+
186
+ /**
187
+ * Checks if the target is in a descendant of this item.
188
+ * This can prevent from firing some logic on the ancestors on the interacted item when the event handler is on the root.
189
+ * @param {HTMLElement} target The target to check
190
+ * @param {HTMLElement | null} itemRoot The root of the item to check if the event target is in its descendants
191
+ * @returns {boolean} Whether the target is in a descendant of this item
192
+ */
193
+ export const isTargetInDescendants = (target, itemRoot) => {
194
+ return itemRoot !== target.closest('*[role="treeitem"]');
184
195
  };
@@ -1 +1,2 @@
1
- export declare const buildWarning: (message: string | string[], gravity?: "warning" | "error") => () => void;
1
+ export declare function warnOnce(message: string | string[], gravity?: 'warning' | 'error'): void;
2
+ export declare function clearWarningsCache(): void;
@@ -1,14 +1,21 @@
1
- export const buildWarning = (message, gravity = 'warning') => {
2
- let alreadyWarned = false;
1
+ const warnedOnceCache = new Set();
2
+
3
+ // TODO move to @mui/x-internals
4
+ // TODO eventually move to @base_ui/internals. Base UI, etc. too need this helper.
5
+ export function warnOnce(message, gravity = 'warning') {
6
+ if (process.env.NODE_ENV === 'production') {
7
+ return;
8
+ }
3
9
  const cleanMessage = Array.isArray(message) ? message.join('\n') : message;
4
- return () => {
5
- if (!alreadyWarned) {
6
- alreadyWarned = true;
7
- if (gravity === 'error') {
8
- console.error(cleanMessage);
9
- } else {
10
- console.warn(cleanMessage);
11
- }
10
+ if (!warnedOnceCache.has(cleanMessage)) {
11
+ warnedOnceCache.add(cleanMessage);
12
+ if (gravity === 'error') {
13
+ console.error(cleanMessage);
14
+ } else {
15
+ console.warn(cleanMessage);
12
16
  }
13
- };
14
- };
17
+ }
18
+ }
19
+ export function clearWarningsCache() {
20
+ warnedOnceCache.clear();
21
+ }
package/models/items.d.ts CHANGED
@@ -5,3 +5,4 @@ export type TreeViewBaseItem<R extends {} = {
5
5
  }> = R & {
6
6
  children?: TreeViewBaseItem<R>[];
7
7
  };
8
+ export type TreeViewItemsReorderingAction = 'reorder-above' | 'reorder-below' | 'make-child' | 'move-to-parent';
@@ -2,14 +2,14 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import composeClasses from '@mui/utils/composeClasses';
5
- import { useSlotProps } from '@mui/base/utils';
5
+ import useSlotProps from '@mui/utils/useSlotProps';
6
6
  import { getRichTreeViewUtilityClass } from './richTreeViewClasses';
7
7
  import { styled, createUseThemeProps } from '../internals/zero-styled';
8
8
  import { useTreeView } from '../internals/useTreeView';
9
9
  import { TreeViewProvider } from '../internals/TreeViewProvider';
10
10
  import { RICH_TREE_VIEW_PLUGINS } from './RichTreeView.plugins';
11
11
  import { TreeItem } from '../TreeItem';
12
- import { buildWarning } from '../internals/utils/warning';
12
+ import { warnOnce } from '../internals/utils/warning';
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  const useThemeProps = createUseThemeProps('MuiRichTreeView');
15
15
  const useUtilityClasses = ownerState => {
@@ -58,7 +58,6 @@ function WrappedTreeItem({
58
58
  children: children
59
59
  }));
60
60
  }
61
- const childrenWarning = buildWarning(['MUI X: The `RichTreeView` component does not support JSX children.', 'If you want to add items, you need to use the `items` prop', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/']);
62
61
 
63
62
  /**
64
63
  *
@@ -77,7 +76,7 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
77
76
  });
78
77
  if (process.env.NODE_ENV !== 'production') {
79
78
  if (props.children != null) {
80
- childrenWarning();
79
+ warnOnce(['MUI X: The `RichTreeView` component does not support JSX children.', 'If you want to add items, you need to use the `items` prop.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/.']);
81
80
  }
82
81
  }
83
82
  const {
@@ -242,6 +241,12 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
242
241
  * @param {array} itemIds The ids of the expanded items.
243
242
  */
244
243
  onExpandedItemsChange: PropTypes.func,
244
+ /**
245
+ * Callback fired when the `content` slot of a given tree item is clicked.
246
+ * @param {React.MouseEvent} event The DOM event that triggered the change.
247
+ * @param {string} itemId The id of the focused item.
248
+ */
249
+ onItemClick: PropTypes.func,
245
250
  /**
246
251
  * Callback fired when a tree item is expanded or collapsed.
247
252
  * @param {React.SyntheticEvent} event The DOM event that triggered the change.
@@ -250,10 +255,9 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
250
255
  */
251
256
  onItemExpansionToggle: PropTypes.func,
252
257
  /**
253
- * Callback fired when tree items are focused.
254
- * @param {React.SyntheticEvent} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
258
+ * Callback fired when a given tree item is focused.
259
+ * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
255
260
  * @param {string} itemId The id of the focused item.
256
- * @param {string} value of the focused item.
257
261
  */
258
262
  onItemFocus: PropTypes.func,
259
263
  /**
@@ -2,13 +2,13 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import composeClasses from '@mui/utils/composeClasses';
5
- import { useSlotProps } from '@mui/base/utils';
5
+ import useSlotProps from '@mui/utils/useSlotProps';
6
6
  import { styled, createUseThemeProps } from '../internals/zero-styled';
7
7
  import { getSimpleTreeViewUtilityClass } from './simpleTreeViewClasses';
8
8
  import { useTreeView } from '../internals/useTreeView';
9
9
  import { TreeViewProvider } from '../internals/TreeViewProvider';
10
10
  import { SIMPLE_TREE_VIEW_PLUGINS } from './SimpleTreeView.plugins';
11
- import { buildWarning } from '../internals/utils/warning';
11
+ import { warnOnce } from '../internals/utils/warning';
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  const useThemeProps = createUseThemeProps('MuiSimpleTreeView');
14
14
  const useUtilityClasses = ownerState => {
@@ -32,7 +32,6 @@ export const SimpleTreeViewRoot = styled('ul', {
32
32
  position: 'relative'
33
33
  });
34
34
  const EMPTY_ITEMS = [];
35
- const itemsPropWarning = buildWarning(['MUI X: The `SimpleTreeView` component does not support the `items` prop.', 'If you want to add items, you need to pass them as JSX children.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/simple-tree-view/items/']);
36
35
 
37
36
  /**
38
37
  *
@@ -52,7 +51,7 @@ const SimpleTreeView = /*#__PURE__*/React.forwardRef(function SimpleTreeView(inP
52
51
  const ownerState = props;
53
52
  if (process.env.NODE_ENV !== 'production') {
54
53
  if (props.items != null) {
55
- itemsPropWarning();
54
+ warnOnce(['MUI X: The `SimpleTreeView` component does not support the `items` prop.', 'If you want to add items, you need to pass them as JSX children.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/simple-tree-view/items/.']);
56
55
  }
57
56
  }
58
57
  const {
@@ -178,6 +177,12 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
178
177
  * @param {array} itemIds The ids of the expanded items.
179
178
  */
180
179
  onExpandedItemsChange: PropTypes.func,
180
+ /**
181
+ * Callback fired when the `content` slot of a given tree item is clicked.
182
+ * @param {React.MouseEvent} event The DOM event that triggered the change.
183
+ * @param {string} itemId The id of the focused item.
184
+ */
185
+ onItemClick: PropTypes.func,
181
186
  /**
182
187
  * Callback fired when a tree item is expanded or collapsed.
183
188
  * @param {React.SyntheticEvent} event The DOM event that triggered the change.
@@ -186,10 +191,9 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
186
191
  */
187
192
  onItemExpansionToggle: PropTypes.func,
188
193
  /**
189
- * Callback fired when tree items are focused.
190
- * @param {React.SyntheticEvent} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
194
+ * Callback fired when a given tree item is focused.
195
+ * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
191
196
  * @param {string} itemId The id of the focused item.
192
- * @param {string} value of the focused item.
193
197
  */
194
198
  onItemFocus: PropTypes.func,
195
199
  /**
@@ -8,17 +8,19 @@ import * as React from 'react';
8
8
  import PropTypes from 'prop-types';
9
9
  import clsx from 'clsx';
10
10
  import Collapse from '@mui/material/Collapse';
11
- import { resolveComponentProps, useSlotProps } from '@mui/base/utils';
12
11
  import useForkRef from '@mui/utils/useForkRef';
13
12
  import { shouldForwardProp } from '@mui/system/createStyled';
14
13
  import { alpha } from '@mui/material/styles';
14
+ import composeClasses from '@mui/utils/composeClasses';
15
+ import extractEventHandlers from '@mui/utils/extractEventHandlers';
16
+ import resolveComponentProps from '@mui/utils/resolveComponentProps';
17
+ import useSlotProps from '@mui/utils/useSlotProps';
15
18
  import unsupportedProp from '@mui/utils/unsupportedProp';
16
19
  import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef';
17
- import { unstable_composeClasses as composeClasses } from '@mui/base';
18
20
  import { styled, createUseThemeProps } from '../internals/zero-styled';
19
21
  import { TreeItemContent } from './TreeItemContent';
20
22
  import { treeItemClasses, getTreeItemUtilityClass } from './treeItemClasses';
21
- import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext';
23
+ import { useTreeViewContext } from '../internals/TreeViewProvider';
22
24
  import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons';
23
25
  import { TreeItem2Provider } from '../TreeItem2Provider';
24
26
  import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext';
@@ -72,6 +74,7 @@ const StyledTreeItemContent = styled(TreeItemContent, {
72
74
  width: '100%',
73
75
  boxSizing: 'border-box',
74
76
  // prevent width + padding to overflow
77
+ position: 'relative',
75
78
  display: 'flex',
76
79
  alignItems: 'center',
77
80
  gap: theme.spacing(1),
@@ -166,14 +169,16 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
166
169
  const {
167
170
  icons: contextIcons,
168
171
  runItemPlugins,
172
+ items: {
173
+ disabledItemsFocusable,
174
+ indentationAtItemLevel
175
+ },
169
176
  selection: {
170
177
  multiSelect
171
178
  },
172
179
  expansion: {
173
180
  expansionTrigger
174
181
  },
175
- disabledItemsFocusable,
176
- indentationAtItemLevel,
177
182
  instance
178
183
  } = useTreeViewContext();
179
184
  const depthContext = React.useContext(TreeViewItemDepthContext);
@@ -206,10 +211,13 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
206
211
  } = useTreeItemState(itemId);
207
212
  const {
208
213
  contentRef,
209
- rootRef
214
+ rootRef,
215
+ propsEnhancers
210
216
  } = runItemPlugins(props);
211
- const handleRootRef = useForkRef(inRef, rootRef);
212
- const handleContentRef = useForkRef(ContentProps?.ref, contentRef);
217
+ const rootRefObject = React.useRef(null);
218
+ const contentRefObject = React.useRef(null);
219
+ const handleRootRef = useForkRef(inRef, rootRef, rootRefObject);
220
+ const handleContentRef = useForkRef(ContentProps?.ref, contentRef, contentRefObject);
213
221
  const slots = {
214
222
  expandIcon: inSlots?.expandIcon ?? contextIcons.slots.expandIcon ?? TreeViewExpandIcon,
215
223
  collapseIcon: inSlots?.collapseIcon ?? contextIcons.slots.collapseIcon ?? TreeViewCollapseIcon,
@@ -317,6 +325,21 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
317
325
  };
318
326
  const idAttribute = instance.getTreeItemIdAttribute(itemId, id);
319
327
  const tabIndex = instance.canItemBeTabbed(itemId) ? 0 : -1;
328
+ const enhancedRootProps = propsEnhancers.root?.({
329
+ rootRefObject,
330
+ contentRefObject,
331
+ externalEventHandlers: extractEventHandlers(other)
332
+ }) ?? {};
333
+ const enhancedContentProps = propsEnhancers.content?.({
334
+ rootRefObject,
335
+ contentRefObject,
336
+ externalEventHandlers: extractEventHandlers(ContentProps)
337
+ }) ?? {};
338
+ const enhancedDragAndDropOverlayProps = propsEnhancers.dragAndDropOverlay?.({
339
+ rootRefObject,
340
+ contentRefObject,
341
+ externalEventHandlers: {}
342
+ }) ?? {};
320
343
  return /*#__PURE__*/_jsx(TreeItem2Provider, {
321
344
  itemId: itemId,
322
345
  children: /*#__PURE__*/_jsxs(TreeItemRoot, _extends({
@@ -335,7 +358,8 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
335
358
  ref: handleRootRef,
336
359
  style: indentationAtItemLevel ? _extends({}, other.style, {
337
360
  '--TreeView-itemDepth': typeof depthContext === 'function' ? depthContext(itemId) : depthContext
338
- }) : other.style,
361
+ }) : other.style
362
+ }, enhancedRootProps, {
339
363
  children: [/*#__PURE__*/_jsx(StyledTreeItemContent, _extends({
340
364
  as: ContentComponent,
341
365
  classes: {
@@ -356,7 +380,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
356
380
  expansionIcon: expansionIcon,
357
381
  displayIcon: displayIcon,
358
382
  ownerState: ownerState
359
- }, ContentProps, {
383
+ }, ContentProps, enhancedContentProps, enhancedDragAndDropOverlayProps.action == null ? {} : {
384
+ dragAndDropOverlayProps: enhancedDragAndDropOverlayProps
385
+ }, {
360
386
  ref: handleContentRef
361
387
  })), children && /*#__PURE__*/_jsx(TreeItemGroup, _extends({
362
388
  as: GroupTransition
@@ -1,11 +1,12 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["classes", "className", "displayIcon", "expansionIcon", "icon", "label", "itemId", "onClick", "onMouseDown"];
3
+ const _excluded = ["classes", "className", "displayIcon", "expansionIcon", "icon", "label", "itemId", "onClick", "onMouseDown", "dragAndDropOverlayProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
7
  import Checkbox from '@mui/material/Checkbox';
8
8
  import { useTreeItemState } from './useTreeItemState';
9
+ import { TreeItem2DragAndDropOverlay } from '../TreeItem2DragAndDropOverlay';
9
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
11
  /**
11
12
  * @ignore - internal component.
@@ -20,7 +21,8 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
20
21
  label,
21
22
  itemId,
22
23
  onClick,
23
- onMouseDown
24
+ onMouseDown,
25
+ dragAndDropOverlayProps
24
26
  } = props,
25
27
  other = _objectWithoutPropertiesLoose(props, _excluded);
26
28
  const {
@@ -33,6 +35,7 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
33
35
  handleExpansion,
34
36
  handleSelection,
35
37
  handleCheckboxSelection,
38
+ handleContentClick,
36
39
  preventSelection,
37
40
  expansionTrigger
38
41
  } = useTreeItemState(itemId);
@@ -45,6 +48,7 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
45
48
  }
46
49
  };
47
50
  const handleClick = event => {
51
+ handleContentClick?.(event, itemId);
48
52
  if (checkboxRef.current?.contains(event.target)) {
49
53
  return;
50
54
  }
@@ -79,7 +83,7 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
79
83
  }), /*#__PURE__*/_jsx("div", {
80
84
  className: classes.label,
81
85
  children: label
82
- })]
86
+ }), dragAndDropOverlayProps && /*#__PURE__*/_jsx(TreeItem2DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
83
87
  }))
84
88
  );
85
89
  });
@@ -97,6 +101,10 @@ process.env.NODE_ENV !== "production" ? TreeItemContent.propTypes = {
97
101
  * The icon to display next to the tree item's label. Either a parent or end icon.
98
102
  */
99
103
  displayIcon: PropTypes.node,
104
+ dragAndDropOverlayProps: PropTypes.shape({
105
+ action: PropTypes.oneOf(['make-child', 'move-to-parent', 'reorder-above', 'reorder-below']),
106
+ style: PropTypes.object
107
+ }),
100
108
  /**
101
109
  * The icon to display next to the tree item's label. Either an expansion or collapse icon.
102
110
  */
@@ -3,4 +3,4 @@ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
3
3
  export function getTreeItemUtilityClass(slot) {
4
4
  return generateUtilityClass('MuiTreeItem', slot);
5
5
  }
6
- export const treeItemClasses = generateUtilityClasses('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label', 'checkbox']);
6
+ export const treeItemClasses = generateUtilityClasses('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label', 'checkbox', 'dragAndDropOverlay']);
@@ -1,7 +1,10 @@
1
- import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext';
1
+ import { useTreeViewContext } from '../internals/TreeViewProvider';
2
2
  export function useTreeItemState(itemId) {
3
3
  const {
4
4
  instance,
5
+ items: {
6
+ onItemClick
7
+ },
5
8
  selection: {
6
9
  multiSelect,
7
10
  checkboxSelection,
@@ -86,6 +89,7 @@ export function useTreeItemState(itemId) {
86
89
  handleExpansion,
87
90
  handleSelection,
88
91
  handleCheckboxSelection,
92
+ handleContentClick: onItemClick,
89
93
  preventSelection,
90
94
  expansionTrigger
91
95
  };
@@ -9,13 +9,14 @@ import unsupportedProp from '@mui/utils/unsupportedProp';
9
9
  import { alpha } from '@mui/material/styles';
10
10
  import Collapse from '@mui/material/Collapse';
11
11
  import MuiCheckbox from '@mui/material/Checkbox';
12
- import { useSlotProps } from '@mui/base/utils';
12
+ import useSlotProps from '@mui/utils/useSlotProps';
13
13
  import { shouldForwardProp } from '@mui/system/createStyled';
14
14
  import composeClasses from '@mui/utils/composeClasses';
15
15
  import { styled, createUseThemeProps } from '../internals/zero-styled';
16
16
  import { unstable_useTreeItem2 as useTreeItem2 } from '../useTreeItem2';
17
17
  import { getTreeItemUtilityClass } from '../TreeItem';
18
18
  import { TreeItem2Icon } from '../TreeItem2Icon';
19
+ import { TreeItem2DragAndDropOverlay } from '../TreeItem2DragAndDropOverlay';
19
20
  import { TreeItem2Provider } from '../TreeItem2Provider';
20
21
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
22
  const useThemeProps = createUseThemeProps('MuiTreeItem2');
@@ -42,6 +43,7 @@ export const TreeItem2Content = styled('div', {
42
43
  width: '100%',
43
44
  boxSizing: 'border-box',
44
45
  // prevent width + padding to overflow
46
+ position: 'relative',
45
47
  display: 'flex',
46
48
  alignItems: 'center',
47
49
  gap: theme.spacing(1),
@@ -176,7 +178,8 @@ const useUtilityClasses = ownerState => {
176
178
  iconContainer: ['iconContainer'],
177
179
  checkbox: ['checkbox'],
178
180
  label: ['label'],
179
- groupTransition: ['groupTransition']
181
+ groupTransition: ['groupTransition'],
182
+ dragAndDropOverlay: ['dragAndDropOverlay']
180
183
  };
181
184
  return composeClasses(slots, getTreeItemUtilityClass, classes);
182
185
  };
@@ -212,6 +215,7 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
212
215
  getCheckboxProps,
213
216
  getLabelProps,
214
217
  getGroupTransitionProps,
218
+ getDragAndDropOverlayProps,
215
219
  status
216
220
  } = useTreeItem2({
217
221
  id,
@@ -274,6 +278,14 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
274
278
  ownerState: {},
275
279
  className: classes.groupTransition
276
280
  });
281
+ const DragAndDropOverlay = slots.dragAndDropOverlay ?? TreeItem2DragAndDropOverlay;
282
+ const dragAndDropOverlayProps = useSlotProps({
283
+ elementType: DragAndDropOverlay,
284
+ getSlotProps: getDragAndDropOverlayProps,
285
+ externalSlotProps: slotProps.dragAndDropOverlay,
286
+ ownerState: {},
287
+ className: classes.dragAndDropOverlay
288
+ });
277
289
  return /*#__PURE__*/_jsx(TreeItem2Provider, {
278
290
  itemId: itemId,
279
291
  children: /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
@@ -284,7 +296,7 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
284
296
  slots: slots,
285
297
  slotProps: slotProps
286
298
  })
287
- })), /*#__PURE__*/_jsx(Checkbox, _extends({}, checkboxProps)), /*#__PURE__*/_jsx(Label, _extends({}, labelProps))]
299
+ })), /*#__PURE__*/_jsx(Checkbox, _extends({}, checkboxProps)), /*#__PURE__*/_jsx(Label, _extends({}, labelProps)), /*#__PURE__*/_jsx(DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
288
300
  })), children && /*#__PURE__*/_jsx(TreeItem2GroupTransition, _extends({
289
301
  as: GroupTransition
290
302
  }, groupTransitionProps))]
@@ -0,0 +1,69 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { alpha } from '@mui/material/styles';
4
+ import { shouldForwardProp } from '@mui/system';
5
+ import { styled } from '../internals/zero-styled';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ const TreeItem2DragAndDropOverlayRoot = styled('div', {
8
+ name: 'MuiTreeItem2DragAndDropOverlay',
9
+ slot: 'Root',
10
+ overridesResolver: (props, styles) => styles.root,
11
+ shouldForwardProp: prop => shouldForwardProp(prop) && prop !== 'action'
12
+ })(({
13
+ theme
14
+ }) => ({
15
+ position: 'absolute',
16
+ left: 0,
17
+ display: 'flex',
18
+ top: 0,
19
+ bottom: 0,
20
+ right: 0,
21
+ pointerEvents: 'none',
22
+ variants: [{
23
+ props: {
24
+ action: 'make-child'
25
+ },
26
+ style: {
27
+ marginLeft: 'calc(var(--TreeView-indentMultiplier) * var(--TreeView-itemDepth))',
28
+ borderRadius: theme.shape.borderRadius,
29
+ backgroundColor: alpha((theme.vars || theme).palette.primary.dark, 0.15)
30
+ }
31
+ }, {
32
+ props: {
33
+ action: 'reorder-above'
34
+ },
35
+ style: _extends({
36
+ marginLeft: 'calc(var(--TreeView-indentMultiplier) * var(--TreeView-itemDepth))',
37
+ borderTop: `1px solid ${alpha((theme.vars || theme).palette.grey[900], 0.6)}`
38
+ }, theme.palette.mode === 'dark' && {
39
+ borderTop: `1px solid ${alpha((theme.vars || theme).palette.grey[100], 0.6)}`
40
+ })
41
+ }, {
42
+ props: {
43
+ action: 'reorder-below'
44
+ },
45
+ style: _extends({
46
+ marginLeft: 'calc(var(--TreeView-indentMultiplier) * var(--TreeView-itemDepth))',
47
+ borderBottom: `1px solid ${alpha((theme.vars || theme).palette.grey[900], 0.6)}`
48
+ }, theme.palette.mode === 'dark' && {
49
+ borderBottom: `1px solid ${alpha((theme.vars || theme).palette.grey[100], 0.6)}`
50
+ })
51
+ }, {
52
+ props: {
53
+ action: 'move-to-parent'
54
+ },
55
+ style: _extends({
56
+ marginLeft: 'calc(var(--TreeView-indentMultiplier) * calc(var(--TreeView-itemDepth) - 1))',
57
+ borderBottom: `1px solid ${alpha((theme.vars || theme).palette.grey[900], 0.6)}`
58
+ }, theme.palette.mode === 'dark' && {
59
+ borderBottom: `1px solid ${alpha((theme.vars || theme).palette.grey[900], 0.6)}`
60
+ })
61
+ }]
62
+ }));
63
+ function TreeItem2DragAndDropOverlay(props) {
64
+ if (props.action == null) {
65
+ return null;
66
+ }
67
+ return /*#__PURE__*/_jsx(TreeItem2DragAndDropOverlayRoot, _extends({}, props));
68
+ }
69
+ export { TreeItem2DragAndDropOverlay };
@@ -0,0 +1 @@
1
+ export { TreeItem2DragAndDropOverlay } from './TreeItem2DragAndDropOverlay';
@@ -1,8 +1,9 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { resolveComponentProps, useSlotProps } from '@mui/base/utils';
5
- import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext';
4
+ import resolveComponentProps from '@mui/utils/resolveComponentProps';
5
+ import useSlotProps from '@mui/utils/useSlotProps';
6
+ import { useTreeViewContext } from '../internals/TreeViewProvider';
6
7
  import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons';
7
8
  import { jsx as _jsx } from "react/jsx-runtime";
8
9
  function TreeItem2Icon(props) {
@@ -1,5 +1,5 @@
1
1
  import PropTypes from 'prop-types';
2
- import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext';
2
+ import { useTreeViewContext } from '../internals/TreeViewProvider';
3
3
  function TreeItem2Provider(props) {
4
4
  const {
5
5
  children,
@@ -155,6 +155,12 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
155
155
  * @param {array} itemIds The ids of the expanded items.
156
156
  */
157
157
  onExpandedItemsChange: PropTypes.func,
158
+ /**
159
+ * Callback fired when the `content` slot of a given tree item is clicked.
160
+ * @param {React.MouseEvent} event The DOM event that triggered the change.
161
+ * @param {string} itemId The id of the focused item.
162
+ */
163
+ onItemClick: PropTypes.func,
158
164
  /**
159
165
  * Callback fired when a tree item is expanded or collapsed.
160
166
  * @param {React.SyntheticEvent} event The DOM event that triggered the change.
@@ -163,10 +169,9 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
163
169
  */
164
170
  onItemExpansionToggle: PropTypes.func,
165
171
  /**
166
- * Callback fired when tree items are focused.
167
- * @param {React.SyntheticEvent} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
172
+ * Callback fired when a given tree item is focused.
173
+ * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
168
174
  * @param {string} itemId The id of the focused item.
169
- * @param {string} value of the focused item.
170
175
  */
171
176
  onItemFocus: PropTypes.func,
172
177
  /**
@@ -1,4 +1,4 @@
1
- import { useTreeViewContext } from '../../internals/TreeViewProvider/useTreeViewContext';
1
+ import { useTreeViewContext } from '../../internals/TreeViewProvider';
2
2
  const isItemExpandable = reactChildren => {
3
3
  if (Array.isArray(reactChildren)) {
4
4
  return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.11.0
2
+ * @mui/x-tree-view v7.12.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1 +1,2 @@
1
- export { TreeViewProvider } from './TreeViewProvider';
1
+ export { TreeViewProvider } from './TreeViewProvider';
2
+ export { useTreeViewContext } from './useTreeViewContext';
@@ -1,5 +1,5 @@
1
1
  export { useTreeView } from './useTreeView';
2
- export { TreeViewProvider } from './TreeViewProvider';
2
+ export { TreeViewProvider, useTreeViewContext } from './TreeViewProvider';
3
3
  export { unstable_resetCleanupTracking } from './hooks/useInstanceEventHandler';
4
4
 
5
5
  // Core plugins
@@ -10,6 +10,7 @@ export { useTreeViewSelection } from './plugins/useTreeViewSelection';
10
10
  export { useTreeViewFocus } from './plugins/useTreeViewFocus';
11
11
  export { useTreeViewKeyboardNavigation } from './plugins/useTreeViewKeyboardNavigation';
12
12
  export { useTreeViewIcons } from './plugins/useTreeViewIcons';
13
- export { useTreeViewItems } from './plugins/useTreeViewItems';
13
+ export { useTreeViewItems, buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './plugins/useTreeViewItems';
14
14
  export { useTreeViewJSXItems } from './plugins/useTreeViewJSXItems';
15
- export { buildWarning } from './utils/warning';
15
+ export { isTargetInDescendants } from './utils/tree';
16
+ export { warnOnce } from './utils/warning';
@@ -1,3 +1,5 @@
1
1
  export * from './helpers';
2
2
  export * from './plugin';
3
- export * from './treeView';
3
+ export * from './itemPlugin';
4
+ export * from './treeView';
5
+ export * from './MuiCancellableEvent';
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1,2 @@
1
- export { useTreeViewItems } from './useTreeViewItems';
1
+ export { useTreeViewItems } from './useTreeViewItems';
2
+ export { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './useTreeViewItems.utils';
@@ -184,8 +184,11 @@ export const useTreeViewItems = ({
184
184
  areItemUpdatesPrevented
185
185
  },
186
186
  contextValue: {
187
- disabledItemsFocusable: params.disabledItemsFocusable,
188
- indentationAtItemLevel: experimentalFeatures.indentationAtItemLevel ?? false
187
+ items: {
188
+ onItemClick: params.onItemClick,
189
+ disabledItemsFocusable: params.disabledItemsFocusable,
190
+ indentationAtItemLevel: experimentalFeatures.indentationAtItemLevel ?? false
191
+ }
189
192
  }
190
193
  };
191
194
  };
@@ -216,5 +219,6 @@ useTreeViewItems.params = {
216
219
  isItemDisabled: true,
217
220
  getItemLabel: true,
218
221
  getItemId: true,
222
+ onItemClick: true,
219
223
  itemChildrenIndentation: true
220
224
  };