@mui/x-tree-view 7.7.1 → 7.8.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 (42) hide show
  1. package/CHANGELOG.md +100 -1
  2. package/RichTreeView/RichTreeView.js +5 -0
  3. package/SimpleTreeView/SimpleTreeView.js +5 -0
  4. package/TreeItem/TreeItem.js +19 -4
  5. package/TreeItem/TreeItemContent.js +5 -2
  6. package/TreeItem/useTreeItemState.d.ts +1 -0
  7. package/TreeItem/useTreeItemState.js +5 -1
  8. package/TreeItem2/TreeItem2.d.ts +3 -3
  9. package/TreeItem2Provider/TreeItem2Provider.d.ts +0 -1
  10. package/TreeView/TreeView.js +5 -0
  11. package/index.js +1 -1
  12. package/internals/hooks/useInstanceEventHandler.d.ts +2 -2
  13. package/internals/models/plugin.d.ts +5 -1
  14. package/internals/models/treeView.d.ts +1 -3
  15. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +13 -1
  16. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +10 -0
  17. package/internals/useTreeView/useTreeViewModels.d.ts +1 -1
  18. package/internals/utils/cleanupTracking/TimerBasedCleanupTracking.d.ts +0 -1
  19. package/internals/utils/publishTreeViewEvent.d.ts +1 -1
  20. package/internals/utils/warning.d.ts +1 -1
  21. package/modern/RichTreeView/RichTreeView.js +5 -0
  22. package/modern/SimpleTreeView/SimpleTreeView.js +5 -0
  23. package/modern/TreeItem/TreeItem.js +19 -4
  24. package/modern/TreeItem/TreeItemContent.js +5 -2
  25. package/modern/TreeItem/useTreeItemState.js +5 -1
  26. package/modern/TreeView/TreeView.js +5 -0
  27. package/modern/index.js +1 -1
  28. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +13 -1
  29. package/modern/useTreeItem2/useTreeItem2.js +18 -2
  30. package/node/RichTreeView/RichTreeView.js +5 -0
  31. package/node/SimpleTreeView/SimpleTreeView.js +5 -0
  32. package/node/TreeItem/TreeItem.js +19 -4
  33. package/node/TreeItem/TreeItemContent.js +5 -2
  34. package/node/TreeItem/useTreeItemState.js +5 -1
  35. package/node/TreeView/TreeView.js +5 -0
  36. package/node/index.js +1 -1
  37. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +13 -1
  38. package/node/useTreeItem2/useTreeItem2.js +18 -2
  39. package/package.json +1 -1
  40. package/useTreeItem2/useTreeItem2.d.ts +2 -2
  41. package/useTreeItem2/useTreeItem2.js +18 -2
  42. package/useTreeItem2/useTreeItem2.types.d.ts +3 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,105 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 7.8.0
7
+
8
+ _Jun 28, 2024_
9
+
10
+ We'd like to offer a big thanks to the 10 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 🛰 Introduce server-side data source for improved server integration in the Data Grid.
13
+
14
+ Supports server-side pagination, sorting and filtering on plain and tree data, and automatic caching.
15
+
16
+ To enable, provide a `getRows` function to the `unstable_dataSource` prop on the Data Grid component.
17
+
18
+ ```tsx
19
+ const dataSource = {
20
+ getRows: async (params: GridServerGetRowsParams) => {
21
+ const data = await fetch(
22
+ `https://api.example.com/data?${new URLSearchParams({
23
+ page: params.page,
24
+ pageSize: params.pageSize,
25
+ sortModel: JSON.stringify(params.sortModel),
26
+ filterModel: JSON.stringify(params.filterModel),
27
+ }).toString()}`,
28
+ );
29
+ return {
30
+ rows: data.rows,
31
+ totalRows: data.totalRows,
32
+ };
33
+ },
34
+ }
35
+ <DataGridPro
36
+ unstable_dataSource={dataSource}
37
+ {...otherProps}
38
+ />
39
+ ```
40
+
41
+ See [server-side data documentation](https://mui.com/x/react-data-grid/server-side-data/) for more details.
42
+
43
+ - 📈 Support Date data on the BarChart component
44
+ - ↕️ Support custom column sort icons on the Data Grid
45
+ - 🖱️ Support modifying the expansion trigger on the Tree View components
46
+
47
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
48
+
49
+ ### Data Grid
50
+
51
+ #### `@mui/x-data-grid@7.8.0`
52
+
53
+ - [DataGrid] Add `columnHeaderSortIcon` slot (#13563) @arminmeh
54
+ - [DataGrid] Fix dimensions lag issue after autosize (#13587) @MBilalShafi
55
+ - [DataGrid] Fix print export failure when `hideFooter` option is set (#13034) @tarunrajput
56
+
57
+ #### `@mui/x-data-grid-pro@7.8.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
58
+
59
+ Same changes as in `@mui/x-data-grid@7.8.0`, plus:
60
+
61
+ - [DataGridPro] Fix multi-sorting indicator being cut off (#13625) @KenanYusuf
62
+ - [DataGridPro] Server-side tree data support (#12317) @MBilalShafi
63
+
64
+ #### `@mui/x-data-grid-premium@7.8.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
65
+
66
+ Same changes as in `@mui/x-data-grid-pro@7.8.0`.
67
+
68
+ ### Date and Time Pickers
69
+
70
+ #### `@mui/x-date-pickers@7.8.0`
71
+
72
+ - [fields] Fix section clearing behavior on Android (#13652) @LukasTy
73
+
74
+ #### `@mui/x-date-pickers-pro@7.8.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
75
+
76
+ Same changes as in `@mui/x-date-pickers@7.8.0`.
77
+
78
+ ### Charts
79
+
80
+ #### `@mui/x-charts@7.8.0`
81
+
82
+ - [charts] Fix line chart props not passing correct event handlers (#13609) @JCQuintas
83
+ - [charts] Support BarChart with `Date` data (#13471) @alexfauquette
84
+ - [charts] Support RTL for y-axis (#13614) @alexfauquette
85
+ - [charts] Use default values instead of non-null assertion to prevent error being thrown (#13637) @JCQuintas
86
+
87
+ ### Tree View
88
+
89
+ #### `@mui/x-tree-view@7.8.0`
90
+
91
+ - [TreeView] Add `expansionTrigger` prop (#13533) @noraleonte
92
+ - [TreeView] Support experimental features from plugin's dependencies (#13632) @flaviendelangle
93
+
94
+ ### Docs
95
+
96
+ - [docs] Add callout for `Luxon` `throwOnInvalid` support (#13621) @LukasTy
97
+ - [docs] Add "Overlays" section to the Data Grid documentation (#13624) @KenanYusuf
98
+
99
+ ### Core
100
+
101
+ - [core] Add eslint rule to restrict import from `../internals` root (#13633) @JCQuintas
102
+ - [docs-infra] Sync `\_app` folder with monorepo (#13582) @Janpot
103
+ - [license] Allow usage of charts and tree view pro package for old premium licenses (#13619) @flaviendelangle
104
+
6
105
  ## 7.7.1
7
106
 
8
107
  _Jun 21, 2024_
@@ -44,7 +143,7 @@ Same changes as in `@mui/x-data-grid-pro@7.7.1`.
44
143
  - [pickers] Always use the same timezone in the field, the view and the layout components (#13481) @flaviendelangle
45
144
  - [pickers] Fix `AdapterDateFnsV3` generated method types (#13464) @alexey-kozlenkov
46
145
  - [pickers] Fix controlled `view` behavior (#13552) @LukasTy
47
- - [TimePicker] Improves RTL verification for the time pickers default views (#13447) @arthurbalduini
146
+ - [TimePicker] Improves RTL verification for the time pickers default views (#13447) @arthurbalduini
48
147
 
49
148
  #### `@mui/x-date-pickers-pro@7.7.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
50
149
 
@@ -177,6 +177,11 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
177
177
  * Used when the item's expansion is controlled.
178
178
  */
179
179
  expandedItems: PropTypes.arrayOf(PropTypes.string),
180
+ /**
181
+ * The slot that triggers the item's expansion when clicked.
182
+ * @default 'content'
183
+ */
184
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
180
185
  /**
181
186
  * Unstable features, breaking changes might be introduced.
182
187
  * For each feature, if the flag is not explicitly set to `true`,
@@ -139,6 +139,11 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
139
139
  * Used when the item's expansion is controlled.
140
140
  */
141
141
  expandedItems: PropTypes.arrayOf(PropTypes.string),
142
+ /**
143
+ * The slot that triggers the item's expansion when clicked.
144
+ * @default 'content'
145
+ */
146
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
142
147
  /**
143
148
  * Unstable features, breaking changes might be introduced.
144
149
  * For each feature, if the flag is not explicitly set to `true`,
@@ -22,6 +22,7 @@ import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewCon
22
22
  import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons';
23
23
  import { TreeItem2Provider } from '../TreeItem2Provider';
24
24
  import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext';
25
+ import { useTreeItemState } from './useTreeItemState';
25
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
26
27
  const useThemeProps = createUseThemeProps('MuiTreeItem');
27
28
  const useUtilityClasses = ownerState => {
@@ -168,6 +169,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
168
169
  selection: {
169
170
  multiSelect
170
171
  },
172
+ expansion: {
173
+ expansionTrigger
174
+ },
171
175
  disabledItemsFocusable,
172
176
  indentationAtItemLevel,
173
177
  instance
@@ -193,6 +197,13 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
193
197
  onKeyDown
194
198
  } = props,
195
199
  other = _objectWithoutPropertiesLoose(props, _excluded);
200
+ const {
201
+ expanded,
202
+ focused,
203
+ selected,
204
+ disabled,
205
+ handleExpansion
206
+ } = useTreeItemState(itemId);
196
207
  const {
197
208
  contentRef,
198
209
  rootRef
@@ -213,10 +224,6 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
213
224
  return Boolean(reactChildren);
214
225
  };
215
226
  const expandable = isExpandable(children);
216
- const expanded = instance.isItemExpanded(itemId);
217
- const focused = instance.isItemFocused(itemId);
218
- const selected = instance.isItemSelected(itemId);
219
- const disabled = instance.isItemDisabled(itemId);
220
227
  const ownerState = _extends({}, props, {
221
228
  expanded,
222
229
  focused,
@@ -240,6 +247,11 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
240
247
  } : {}),
241
248
  className: classes.groupTransition
242
249
  });
250
+ const handleIconContainerClick = event => {
251
+ if (expansionTrigger === 'iconContainer') {
252
+ handleExpansion(event);
253
+ }
254
+ };
243
255
  const ExpansionIcon = expanded ? slots.collapseIcon : slots.expandIcon;
244
256
  const _useSlotProps = useSlotProps({
245
257
  elementType: ExpansionIcon,
@@ -249,6 +261,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
249
261
  return _extends({}, resolveComponentProps(contextIcons.slotProps.collapseIcon, tempOwnerState), resolveComponentProps(inSlotProps?.collapseIcon, tempOwnerState));
250
262
  }
251
263
  return _extends({}, resolveComponentProps(contextIcons.slotProps.expandIcon, tempOwnerState), resolveComponentProps(inSlotProps?.expandIcon, tempOwnerState));
264
+ },
265
+ additionalProps: {
266
+ onClick: handleIconContainerClick
252
267
  }
253
268
  }),
254
269
  expansionIconProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);
@@ -33,7 +33,8 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
33
33
  handleExpansion,
34
34
  handleSelection,
35
35
  handleCheckboxSelection,
36
- preventSelection
36
+ preventSelection,
37
+ expansionTrigger
37
38
  } = useTreeItemState(itemId);
38
39
  const icon = iconProp || expansionIcon || displayIcon;
39
40
  const checkboxRef = React.useRef(null);
@@ -47,7 +48,9 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
47
48
  if (checkboxRef.current?.contains(event.target)) {
48
49
  return;
49
50
  }
50
- handleExpansion(event);
51
+ if (expansionTrigger === 'content') {
52
+ handleExpansion(event);
53
+ }
51
54
  if (!checkboxSelection) {
52
55
  handleSelection(event);
53
56
  }
@@ -10,4 +10,5 @@ export declare function useTreeItemState(itemId: string): {
10
10
  handleSelection: (event: React.MouseEvent) => void;
11
11
  handleCheckboxSelection: (event: React.ChangeEvent<HTMLInputElement>) => void;
12
12
  preventSelection: (event: React.MouseEvent<HTMLDivElement>) => void;
13
+ expansionTrigger: "content" | "iconContainer" | undefined;
13
14
  };
@@ -6,6 +6,9 @@ export function useTreeItemState(itemId) {
6
6
  multiSelect,
7
7
  checkboxSelection,
8
8
  disableSelection
9
+ },
10
+ expansion: {
11
+ expansionTrigger
9
12
  }
10
13
  } = useTreeViewContext();
11
14
  const expandable = instance.isItemExpandable(itemId);
@@ -70,6 +73,7 @@ export function useTreeItemState(itemId) {
70
73
  handleExpansion,
71
74
  handleSelection,
72
75
  handleCheckboxSelection,
73
- preventSelection
76
+ preventSelection,
77
+ expansionTrigger
74
78
  };
75
79
  }
@@ -5,16 +5,16 @@ import { UseTreeItem2Status } from '../useTreeItem2';
5
5
  export declare const TreeItem2Root: import("@emotion/styled").StyledComponent<import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme>, Pick<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, keyof React.ClassAttributes<HTMLLIElement> | keyof React.LiHTMLAttributes<HTMLLIElement>>, {}>;
6
6
  export declare const TreeItem2Content: import("@emotion/styled").StyledComponent<import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme> & {
7
7
  status: UseTreeItem2Status;
8
- indentationAtItemLevel?: true | undefined;
8
+ indentationAtItemLevel?: true;
9
9
  }, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
10
10
  export declare const TreeItem2Label: import("@emotion/styled").StyledComponent<import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.ClassAttributes<HTMLDivElement> | keyof React.HTMLAttributes<HTMLDivElement>>, {}>;
11
11
  export declare const TreeItem2IconContainer: import("@emotion/styled").StyledComponent<import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.ClassAttributes<HTMLDivElement> | keyof React.HTMLAttributes<HTMLDivElement>>, {}>;
12
12
  export declare const TreeItem2GroupTransition: import("@emotion/styled").StyledComponent<import("@mui/material/Collapse").CollapseProps & import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme> & {
13
- indentationAtItemLevel?: true | undefined;
13
+ indentationAtItemLevel?: true;
14
14
  }, {}, {}>;
15
15
  export declare const TreeItem2Checkbox: import("@emotion/styled").StyledComponent<Pick<Omit<CheckboxProps & {
16
16
  visible: boolean;
17
- }, "ref"> & React.RefAttributes<HTMLButtonElement>, "hidden" | "visible" | "color" | "content" | "size" | "style" | "icon" | "translate" | "disabled" | "form" | "slot" | "title" | "suppressHydrationWarning" | "className" | "id" | "lang" | "name" | "role" | "tabIndex" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "accessKey" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "nonce" | "spellCheck" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "value" | "readOnly" | "required" | "action" | "checked" | "component" | "sx" | "classes" | "onFocusVisible" | "inputRef" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "checkedIcon" | "inputProps" | "indeterminate" | "indeterminateIcon" | keyof React.RefAttributes<HTMLButtonElement>> & import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme>, {}, {}>;
17
+ }, "ref"> & React.RefAttributes<HTMLButtonElement>, "hidden" | "visible" | "color" | "content" | "size" | "style" | "icon" | "translate" | "disabled" | "form" | "slot" | "title" | "suppressHydrationWarning" | "className" | "id" | "lang" | "name" | "role" | "tabIndex" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "accessKey" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "nonce" | "spellCheck" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "value" | "readOnly" | "required" | "action" | "checked" | "component" | "sx" | "classes" | "onFocusVisible" | "inputRef" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "checkedIcon" | "inputProps" | "indeterminate" | "indeterminateIcon" | keyof React.RefAttributes<HTMLButtonElement>> & import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme>, {}, {}>;
18
18
  type TreeItem2Component = ((props: TreeItem2Props & React.RefAttributes<HTMLLIElement>) => React.JSX.Element) & {
19
19
  propTypes?: any;
20
20
  };
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { TreeItem2ProviderProps } from './TreeItem2Provider.types';
3
2
  declare function TreeItem2Provider(props: TreeItem2ProviderProps): import("react").ReactNode;
4
3
  declare namespace TreeItem2Provider {
@@ -116,6 +116,11 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
116
116
  * Used when the item's expansion is controlled.
117
117
  */
118
118
  expandedItems: PropTypes.arrayOf(PropTypes.string),
119
+ /**
120
+ * The slot that triggers the item's expansion when clicked.
121
+ * @default 'content'
122
+ */
123
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
119
124
  /**
120
125
  * Unstable features, breaking changes might be introduced.
121
126
  * For each feature, if the flag is not explicitly set to `true`,
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.7.1
2
+ * @mui/x-tree-view v7.8.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -7,9 +7,9 @@ interface RegistryContainer {
7
7
  }
8
8
  export declare function createUseInstanceEventHandler(registryContainer: RegistryContainer): <Instance extends UseTreeViewInstanceEventsInstance & {
9
9
  $$signature: TreeViewAnyPluginSignature;
10
- }, E extends keyof Instance["$$signature"]["events"] | keyof import("../models").MergeSignaturesProperty<[import("../corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types").UseTreeViewInstanceEventsSignature, import("../corePlugins/useTreeViewId").UseTreeViewIdSignature, ...Instance["$$signature"]["dependencies"]], "events">>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance['$$signature']>[E]>) => void;
10
+ }, E extends keyof TreeViewUsedEvents<Instance["$$signature"]>>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance["$$signature"]>[E]>) => void;
11
11
  export declare const unstable_resetCleanupTracking: () => void;
12
12
  export declare const useInstanceEventHandler: <Instance extends UseTreeViewInstanceEventsInstance & {
13
13
  $$signature: TreeViewAnyPluginSignature;
14
- }, E extends keyof Instance["$$signature"]["events"] | keyof import("../models").MergeSignaturesProperty<[import("../corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types").UseTreeViewInstanceEventsSignature, import("../corePlugins/useTreeViewId").UseTreeViewIdSignature, ...Instance["$$signature"]["dependencies"]], "events">>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance['$$signature']>[E]>) => void;
14
+ }, E extends keyof TreeViewUsedEvents<Instance["$$signature"]>>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance["$$signature"]>[E]>) => void;
15
15
  export {};
@@ -78,7 +78,11 @@ export type TreeViewPluginSignature<T extends {
78
78
  } ? {
79
79
  [TControlled in T['modelNames']]-?: TreeViewModel<Exclude<T['defaultizedParams'][TControlled], undefined>>;
80
80
  } : {};
81
- experimentalFeatures: T['experimentalFeatures'];
81
+ experimentalFeatures: T extends {
82
+ experimentalFeatures: string;
83
+ } ? {
84
+ [key in T['experimentalFeatures']]?: boolean;
85
+ } : {};
82
86
  dependencies: T extends {
83
87
  dependencies: Array<any>;
84
88
  } ? T['dependencies'] : [];
@@ -23,6 +23,4 @@ export interface TreeViewModel<TValue> {
23
23
  }
24
24
  export type TreeViewInstance<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'instance'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'instance'>>;
25
25
  export type TreeViewPublicAPI<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'publicAPI'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'instance'>>;
26
- export type TreeViewExperimentalFeatures<TSignatures extends readonly TreeViewAnyPluginSignature[]> = {
27
- [key in MergeSignaturesProperty<TSignatures, 'experimentalFeatures'>]?: boolean;
28
- };
26
+ export type TreeViewExperimentalFeatures<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TSignatures, ...TOptionalSignatures], 'experimentalFeatures'>;
@@ -53,6 +53,12 @@ export const useTreeViewExpansion = ({
53
53
  setExpandedItems(event, newExpanded);
54
54
  }
55
55
  };
56
+ const expansionTrigger = React.useMemo(() => {
57
+ if (params.expansionTrigger) {
58
+ return params.expansionTrigger;
59
+ }
60
+ return 'content';
61
+ }, [params.expansionTrigger]);
56
62
  return {
57
63
  publicAPI: {
58
64
  setItemExpansion
@@ -63,6 +69,11 @@ export const useTreeViewExpansion = ({
63
69
  setItemExpansion,
64
70
  toggleItemExpansion,
65
71
  expandAllSiblings
72
+ },
73
+ contextValue: {
74
+ expansion: {
75
+ expansionTrigger
76
+ }
66
77
  }
67
78
  };
68
79
  };
@@ -79,5 +90,6 @@ useTreeViewExpansion.params = {
79
90
  expandedItems: true,
80
91
  defaultExpandedItems: true,
81
92
  onExpandedItemsChange: true,
82
- onItemExpansionToggle: true
93
+ onItemExpansionToggle: true,
94
+ expansionTrigger: true
83
95
  };
@@ -65,13 +65,23 @@ export interface UseTreeViewExpansionParameters {
65
65
  * @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
66
66
  */
67
67
  onItemExpansionToggle?: (event: React.SyntheticEvent, itemId: string, isExpanded: boolean) => void;
68
+ /**
69
+ * The slot that triggers the item's expansion when clicked.
70
+ * @default 'content'
71
+ */
72
+ expansionTrigger?: 'content' | 'iconContainer';
68
73
  }
69
74
  export type UseTreeViewExpansionDefaultizedParameters = DefaultizedProps<UseTreeViewExpansionParameters, 'defaultExpandedItems'>;
75
+ interface UseTreeViewExpansionContextValue {
76
+ expansion: Pick<UseTreeViewExpansionParameters, 'expansionTrigger'>;
77
+ }
70
78
  export type UseTreeViewExpansionSignature = TreeViewPluginSignature<{
71
79
  params: UseTreeViewExpansionParameters;
72
80
  defaultizedParams: UseTreeViewExpansionDefaultizedParameters;
73
81
  instance: UseTreeViewExpansionInstance;
74
82
  publicAPI: UseTreeViewExpansionPublicAPI;
75
83
  modelNames: 'expandedItems';
84
+ contextValue: UseTreeViewExpansionContextValue;
76
85
  dependencies: [UseTreeViewItemsSignature];
77
86
  }>;
87
+ export {};
@@ -4,4 +4,4 @@ import { TreeViewCorePluginSignatures } from '../corePlugins';
4
4
  * Implements the same behavior as `useControlled` but for several models.
5
5
  * The controlled models are never stored in the state, and the state is only updated if the model is not controlled.
6
6
  */
7
- export declare const useTreeViewModels: <TSignatures extends readonly TreeViewAnyPluginSignature[]>(plugins: ConvertSignaturesIntoPlugins<readonly [...TreeViewCorePluginSignatures, ...TSignatures]>, props: MergeSignaturesProperty<TSignatures, 'defaultizedParams'>) => MergeSignaturesProperty<TSignatures, "models">;
7
+ export declare const useTreeViewModels: <TSignatures extends readonly TreeViewAnyPluginSignature[]>(plugins: ConvertSignaturesIntoPlugins<readonly [...TreeViewCorePluginSignatures, ...TSignatures]>, props: MergeSignaturesProperty<TSignatures, "defaultizedParams">) => MergeSignaturesProperty<TSignatures, "models">;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { CleanupTracking, UnregisterToken, UnsubscribeFn } from './CleanupTracking';
3
2
  export declare class TimerBasedCleanupTracking implements CleanupTracking {
4
3
  timeouts?: Map<number, NodeJS.Timeout> | undefined;
@@ -2,4 +2,4 @@ import { UseTreeViewInstanceEventsInstance } from '../corePlugins/useTreeViewIns
2
2
  import { TreeViewAnyPluginSignature, TreeViewUsedEvents } from '../models';
3
3
  export declare const publishTreeViewEvent: <Instance extends UseTreeViewInstanceEventsInstance & {
4
4
  $$signature: TreeViewAnyPluginSignature;
5
- }, E extends keyof Instance["$$signature"]["events"] | keyof import("../models").MergeSignaturesProperty<[import("../corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types").UseTreeViewInstanceEventsSignature, import("../corePlugins/useTreeViewId").UseTreeViewIdSignature, ...Instance["$$signature"]["dependencies"]], "events">>(instance: Instance, eventName: E, params: TreeViewUsedEvents<Instance['$$signature']>[E]['params']) => void;
5
+ }, E extends keyof TreeViewUsedEvents<Instance["$$signature"]>>(instance: Instance, eventName: E, params: TreeViewUsedEvents<Instance["$$signature"]>[E]["params"]) => void;
@@ -1 +1 @@
1
- export declare const buildWarning: (message: string | string[], gravity?: 'warning' | 'error') => () => void;
1
+ export declare const buildWarning: (message: string | string[], gravity?: "warning" | "error") => () => void;
@@ -177,6 +177,11 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
177
177
  * Used when the item's expansion is controlled.
178
178
  */
179
179
  expandedItems: PropTypes.arrayOf(PropTypes.string),
180
+ /**
181
+ * The slot that triggers the item's expansion when clicked.
182
+ * @default 'content'
183
+ */
184
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
180
185
  /**
181
186
  * Unstable features, breaking changes might be introduced.
182
187
  * For each feature, if the flag is not explicitly set to `true`,
@@ -139,6 +139,11 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
139
139
  * Used when the item's expansion is controlled.
140
140
  */
141
141
  expandedItems: PropTypes.arrayOf(PropTypes.string),
142
+ /**
143
+ * The slot that triggers the item's expansion when clicked.
144
+ * @default 'content'
145
+ */
146
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
142
147
  /**
143
148
  * Unstable features, breaking changes might be introduced.
144
149
  * For each feature, if the flag is not explicitly set to `true`,
@@ -22,6 +22,7 @@ import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewCon
22
22
  import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons';
23
23
  import { TreeItem2Provider } from '../TreeItem2Provider';
24
24
  import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext';
25
+ import { useTreeItemState } from './useTreeItemState';
25
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
26
27
  const useThemeProps = createUseThemeProps('MuiTreeItem');
27
28
  const useUtilityClasses = ownerState => {
@@ -168,6 +169,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
168
169
  selection: {
169
170
  multiSelect
170
171
  },
172
+ expansion: {
173
+ expansionTrigger
174
+ },
171
175
  disabledItemsFocusable,
172
176
  indentationAtItemLevel,
173
177
  instance
@@ -193,6 +197,13 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
193
197
  onKeyDown
194
198
  } = props,
195
199
  other = _objectWithoutPropertiesLoose(props, _excluded);
200
+ const {
201
+ expanded,
202
+ focused,
203
+ selected,
204
+ disabled,
205
+ handleExpansion
206
+ } = useTreeItemState(itemId);
196
207
  const {
197
208
  contentRef,
198
209
  rootRef
@@ -213,10 +224,6 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
213
224
  return Boolean(reactChildren);
214
225
  };
215
226
  const expandable = isExpandable(children);
216
- const expanded = instance.isItemExpanded(itemId);
217
- const focused = instance.isItemFocused(itemId);
218
- const selected = instance.isItemSelected(itemId);
219
- const disabled = instance.isItemDisabled(itemId);
220
227
  const ownerState = _extends({}, props, {
221
228
  expanded,
222
229
  focused,
@@ -240,6 +247,11 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
240
247
  } : {}),
241
248
  className: classes.groupTransition
242
249
  });
250
+ const handleIconContainerClick = event => {
251
+ if (expansionTrigger === 'iconContainer') {
252
+ handleExpansion(event);
253
+ }
254
+ };
243
255
  const ExpansionIcon = expanded ? slots.collapseIcon : slots.expandIcon;
244
256
  const _useSlotProps = useSlotProps({
245
257
  elementType: ExpansionIcon,
@@ -249,6 +261,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
249
261
  return _extends({}, resolveComponentProps(contextIcons.slotProps.collapseIcon, tempOwnerState), resolveComponentProps(inSlotProps?.collapseIcon, tempOwnerState));
250
262
  }
251
263
  return _extends({}, resolveComponentProps(contextIcons.slotProps.expandIcon, tempOwnerState), resolveComponentProps(inSlotProps?.expandIcon, tempOwnerState));
264
+ },
265
+ additionalProps: {
266
+ onClick: handleIconContainerClick
252
267
  }
253
268
  }),
254
269
  expansionIconProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);
@@ -33,7 +33,8 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
33
33
  handleExpansion,
34
34
  handleSelection,
35
35
  handleCheckboxSelection,
36
- preventSelection
36
+ preventSelection,
37
+ expansionTrigger
37
38
  } = useTreeItemState(itemId);
38
39
  const icon = iconProp || expansionIcon || displayIcon;
39
40
  const checkboxRef = React.useRef(null);
@@ -47,7 +48,9 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
47
48
  if (checkboxRef.current?.contains(event.target)) {
48
49
  return;
49
50
  }
50
- handleExpansion(event);
51
+ if (expansionTrigger === 'content') {
52
+ handleExpansion(event);
53
+ }
51
54
  if (!checkboxSelection) {
52
55
  handleSelection(event);
53
56
  }
@@ -6,6 +6,9 @@ export function useTreeItemState(itemId) {
6
6
  multiSelect,
7
7
  checkboxSelection,
8
8
  disableSelection
9
+ },
10
+ expansion: {
11
+ expansionTrigger
9
12
  }
10
13
  } = useTreeViewContext();
11
14
  const expandable = instance.isItemExpandable(itemId);
@@ -70,6 +73,7 @@ export function useTreeItemState(itemId) {
70
73
  handleExpansion,
71
74
  handleSelection,
72
75
  handleCheckboxSelection,
73
- preventSelection
76
+ preventSelection,
77
+ expansionTrigger
74
78
  };
75
79
  }
@@ -116,6 +116,11 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
116
116
  * Used when the item's expansion is controlled.
117
117
  */
118
118
  expandedItems: PropTypes.arrayOf(PropTypes.string),
119
+ /**
120
+ * The slot that triggers the item's expansion when clicked.
121
+ * @default 'content'
122
+ */
123
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
119
124
  /**
120
125
  * Unstable features, breaking changes might be introduced.
121
126
  * For each feature, if the flag is not explicitly set to `true`,
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.7.1
2
+ * @mui/x-tree-view v7.8.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -53,6 +53,12 @@ export const useTreeViewExpansion = ({
53
53
  setExpandedItems(event, newExpanded);
54
54
  }
55
55
  };
56
+ const expansionTrigger = React.useMemo(() => {
57
+ if (params.expansionTrigger) {
58
+ return params.expansionTrigger;
59
+ }
60
+ return 'content';
61
+ }, [params.expansionTrigger]);
56
62
  return {
57
63
  publicAPI: {
58
64
  setItemExpansion
@@ -63,6 +69,11 @@ export const useTreeViewExpansion = ({
63
69
  setItemExpansion,
64
70
  toggleItemExpansion,
65
71
  expandAllSiblings
72
+ },
73
+ contextValue: {
74
+ expansion: {
75
+ expansionTrigger
76
+ }
66
77
  }
67
78
  };
68
79
  };
@@ -79,5 +90,6 @@ useTreeViewExpansion.params = {
79
90
  expandedItems: true,
80
91
  defaultExpandedItems: true,
81
92
  onExpandedItemsChange: true,
82
- onItemExpansionToggle: true
93
+ onItemExpansionToggle: true,
94
+ expansionTrigger: true
83
95
  };
@@ -13,6 +13,9 @@ export const useTreeItem2 = parameters => {
13
13
  disableSelection,
14
14
  checkboxSelection
15
15
  },
16
+ expansion: {
17
+ expansionTrigger
18
+ },
16
19
  disabledItemsFocusable,
17
20
  indentationAtItemLevel,
18
21
  instance,
@@ -69,7 +72,9 @@ export const useTreeItem2 = parameters => {
69
72
  if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) {
70
73
  return;
71
74
  }
72
- interactions.handleExpansion(event);
75
+ if (expansionTrigger === 'content') {
76
+ interactions.handleExpansion(event);
77
+ }
73
78
  if (!checkboxSelection) {
74
79
  interactions.handleSelection(event);
75
80
  }
@@ -95,6 +100,15 @@ export const useTreeItem2 = parameters => {
95
100
  }
96
101
  interactions.handleCheckboxSelection(event);
97
102
  };
103
+ const createIconContainerHandleClick = otherHandlers => event => {
104
+ otherHandlers.onClick?.(event);
105
+ if (event.defaultMuiPrevented) {
106
+ return;
107
+ }
108
+ if (expansionTrigger === 'iconContainer') {
109
+ interactions.handleExpansion(event);
110
+ }
111
+ };
98
112
  const getRootProps = (externalProps = {}) => {
99
113
  const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
100
114
  let ariaSelected;
@@ -162,7 +176,9 @@ export const useTreeItem2 = parameters => {
162
176
  };
163
177
  const getIconContainerProps = (externalProps = {}) => {
164
178
  const externalEventHandlers = extractEventHandlers(externalProps);
165
- return _extends({}, externalEventHandlers, externalProps);
179
+ return _extends({}, externalEventHandlers, externalProps, {
180
+ onClick: createIconContainerHandleClick(externalEventHandlers)
181
+ });
166
182
  };
167
183
  const getGroupTransitionProps = (externalProps = {}) => {
168
184
  const externalEventHandlers = extractEventHandlers(externalProps);
@@ -186,6 +186,11 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
186
186
  * Used when the item's expansion is controlled.
187
187
  */
188
188
  expandedItems: _propTypes.default.arrayOf(_propTypes.default.string),
189
+ /**
190
+ * The slot that triggers the item's expansion when clicked.
191
+ * @default 'content'
192
+ */
193
+ expansionTrigger: _propTypes.default.oneOf(['content', 'iconContainer']),
189
194
  /**
190
195
  * Unstable features, breaking changes might be introduced.
191
196
  * For each feature, if the flag is not explicitly set to `true`,
@@ -148,6 +148,11 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
148
148
  * Used when the item's expansion is controlled.
149
149
  */
150
150
  expandedItems: _propTypes.default.arrayOf(_propTypes.default.string),
151
+ /**
152
+ * The slot that triggers the item's expansion when clicked.
153
+ * @default 'content'
154
+ */
155
+ expansionTrigger: _propTypes.default.oneOf(['content', 'iconContainer']),
151
156
  /**
152
157
  * Unstable features, breaking changes might be introduced.
153
158
  * For each feature, if the flag is not explicitly set to `true`,
@@ -25,6 +25,7 @@ var _useTreeViewContext = require("../internals/TreeViewProvider/useTreeViewCont
25
25
  var _icons = require("../icons");
26
26
  var _TreeItem2Provider = require("../TreeItem2Provider");
27
27
  var _TreeViewItemDepthContext = require("../internals/TreeViewItemDepthContext");
28
+ var _useTreeItemState = require("./useTreeItemState");
28
29
  var _jsxRuntime = require("react/jsx-runtime");
29
30
  const _excluded = ["children", "className", "slots", "slotProps", "ContentComponent", "ContentProps", "itemId", "id", "label", "onClick", "onMouseDown", "onFocus", "onBlur", "onKeyDown"],
30
31
  _excluded2 = ["ownerState"],
@@ -177,6 +178,9 @@ const TreeItem = exports.TreeItem = /*#__PURE__*/React.forwardRef(function TreeI
177
178
  selection: {
178
179
  multiSelect
179
180
  },
181
+ expansion: {
182
+ expansionTrigger
183
+ },
180
184
  disabledItemsFocusable,
181
185
  indentationAtItemLevel,
182
186
  instance
@@ -202,6 +206,13 @@ const TreeItem = exports.TreeItem = /*#__PURE__*/React.forwardRef(function TreeI
202
206
  onKeyDown
203
207
  } = props,
204
208
  other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
209
+ const {
210
+ expanded,
211
+ focused,
212
+ selected,
213
+ disabled,
214
+ handleExpansion
215
+ } = (0, _useTreeItemState.useTreeItemState)(itemId);
205
216
  const {
206
217
  contentRef,
207
218
  rootRef
@@ -222,10 +233,6 @@ const TreeItem = exports.TreeItem = /*#__PURE__*/React.forwardRef(function TreeI
222
233
  return Boolean(reactChildren);
223
234
  };
224
235
  const expandable = isExpandable(children);
225
- const expanded = instance.isItemExpanded(itemId);
226
- const focused = instance.isItemFocused(itemId);
227
- const selected = instance.isItemSelected(itemId);
228
- const disabled = instance.isItemDisabled(itemId);
229
236
  const ownerState = (0, _extends2.default)({}, props, {
230
237
  expanded,
231
238
  focused,
@@ -249,6 +256,11 @@ const TreeItem = exports.TreeItem = /*#__PURE__*/React.forwardRef(function TreeI
249
256
  } : {}),
250
257
  className: classes.groupTransition
251
258
  });
259
+ const handleIconContainerClick = event => {
260
+ if (expansionTrigger === 'iconContainer') {
261
+ handleExpansion(event);
262
+ }
263
+ };
252
264
  const ExpansionIcon = expanded ? slots.collapseIcon : slots.expandIcon;
253
265
  const _useSlotProps = (0, _utils.useSlotProps)({
254
266
  elementType: ExpansionIcon,
@@ -258,6 +270,9 @@ const TreeItem = exports.TreeItem = /*#__PURE__*/React.forwardRef(function TreeI
258
270
  return (0, _extends2.default)({}, (0, _utils.resolveComponentProps)(contextIcons.slotProps.collapseIcon, tempOwnerState), (0, _utils.resolveComponentProps)(inSlotProps?.collapseIcon, tempOwnerState));
259
271
  }
260
272
  return (0, _extends2.default)({}, (0, _utils.resolveComponentProps)(contextIcons.slotProps.expandIcon, tempOwnerState), (0, _utils.resolveComponentProps)(inSlotProps?.expandIcon, tempOwnerState));
273
+ },
274
+ additionalProps: {
275
+ onClick: handleIconContainerClick
261
276
  }
262
277
  }),
263
278
  expansionIconProps = (0, _objectWithoutPropertiesLoose2.default)(_useSlotProps, _excluded2);
@@ -42,7 +42,8 @@ const TreeItemContent = exports.TreeItemContent = /*#__PURE__*/React.forwardRef(
42
42
  handleExpansion,
43
43
  handleSelection,
44
44
  handleCheckboxSelection,
45
- preventSelection
45
+ preventSelection,
46
+ expansionTrigger
46
47
  } = (0, _useTreeItemState.useTreeItemState)(itemId);
47
48
  const icon = iconProp || expansionIcon || displayIcon;
48
49
  const checkboxRef = React.useRef(null);
@@ -56,7 +57,9 @@ const TreeItemContent = exports.TreeItemContent = /*#__PURE__*/React.forwardRef(
56
57
  if (checkboxRef.current?.contains(event.target)) {
57
58
  return;
58
59
  }
59
- handleExpansion(event);
60
+ if (expansionTrigger === 'content') {
61
+ handleExpansion(event);
62
+ }
60
63
  if (!checkboxSelection) {
61
64
  handleSelection(event);
62
65
  }
@@ -12,6 +12,9 @@ function useTreeItemState(itemId) {
12
12
  multiSelect,
13
13
  checkboxSelection,
14
14
  disableSelection
15
+ },
16
+ expansion: {
17
+ expansionTrigger
15
18
  }
16
19
  } = (0, _useTreeViewContext.useTreeViewContext)();
17
20
  const expandable = instance.isItemExpandable(itemId);
@@ -76,6 +79,7 @@ function useTreeItemState(itemId) {
76
79
  handleExpansion,
77
80
  handleSelection,
78
81
  handleCheckboxSelection,
79
- preventSelection
82
+ preventSelection,
83
+ expansionTrigger
80
84
  };
81
85
  }
@@ -125,6 +125,11 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
125
125
  * Used when the item's expansion is controlled.
126
126
  */
127
127
  expandedItems: _propTypes.default.arrayOf(_propTypes.default.string),
128
+ /**
129
+ * The slot that triggers the item's expansion when clicked.
130
+ * @default 'content'
131
+ */
132
+ expansionTrigger: _propTypes.default.oneOf(['content', 'iconContainer']),
128
133
  /**
129
134
  * Unstable features, breaking changes might be introduced.
130
135
  * For each feature, if the flag is not explicitly set to `true`,
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.7.1
2
+ * @mui/x-tree-view v7.8.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -62,6 +62,12 @@ const useTreeViewExpansion = ({
62
62
  setExpandedItems(event, newExpanded);
63
63
  }
64
64
  };
65
+ const expansionTrigger = React.useMemo(() => {
66
+ if (params.expansionTrigger) {
67
+ return params.expansionTrigger;
68
+ }
69
+ return 'content';
70
+ }, [params.expansionTrigger]);
65
71
  return {
66
72
  publicAPI: {
67
73
  setItemExpansion
@@ -72,6 +78,11 @@ const useTreeViewExpansion = ({
72
78
  setItemExpansion,
73
79
  toggleItemExpansion,
74
80
  expandAllSiblings
81
+ },
82
+ contextValue: {
83
+ expansion: {
84
+ expansionTrigger
85
+ }
75
86
  }
76
87
  };
77
88
  };
@@ -89,5 +100,6 @@ useTreeViewExpansion.params = {
89
100
  expandedItems: true,
90
101
  defaultExpandedItems: true,
91
102
  onExpandedItemsChange: true,
92
- onItemExpansionToggle: true
103
+ onItemExpansionToggle: true,
104
+ expansionTrigger: true
93
105
  };
@@ -22,6 +22,9 @@ const useTreeItem2 = parameters => {
22
22
  disableSelection,
23
23
  checkboxSelection
24
24
  },
25
+ expansion: {
26
+ expansionTrigger
27
+ },
25
28
  disabledItemsFocusable,
26
29
  indentationAtItemLevel,
27
30
  instance,
@@ -78,7 +81,9 @@ const useTreeItem2 = parameters => {
78
81
  if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) {
79
82
  return;
80
83
  }
81
- interactions.handleExpansion(event);
84
+ if (expansionTrigger === 'content') {
85
+ interactions.handleExpansion(event);
86
+ }
82
87
  if (!checkboxSelection) {
83
88
  interactions.handleSelection(event);
84
89
  }
@@ -104,6 +109,15 @@ const useTreeItem2 = parameters => {
104
109
  }
105
110
  interactions.handleCheckboxSelection(event);
106
111
  };
112
+ const createIconContainerHandleClick = otherHandlers => event => {
113
+ otherHandlers.onClick?.(event);
114
+ if (event.defaultMuiPrevented) {
115
+ return;
116
+ }
117
+ if (expansionTrigger === 'iconContainer') {
118
+ interactions.handleExpansion(event);
119
+ }
120
+ };
107
121
  const getRootProps = (externalProps = {}) => {
108
122
  const externalEventHandlers = (0, _extends2.default)({}, (0, _utils.extractEventHandlers)(parameters), (0, _utils.extractEventHandlers)(externalProps));
109
123
  let ariaSelected;
@@ -171,7 +185,9 @@ const useTreeItem2 = parameters => {
171
185
  };
172
186
  const getIconContainerProps = (externalProps = {}) => {
173
187
  const externalEventHandlers = (0, _utils.extractEventHandlers)(externalProps);
174
- return (0, _extends2.default)({}, externalEventHandlers, externalProps);
188
+ return (0, _extends2.default)({}, externalEventHandlers, externalProps, {
189
+ onClick: createIconContainerHandleClick(externalEventHandlers)
190
+ });
175
191
  };
176
192
  const getGroupTransitionProps = (externalProps = {}) => {
177
193
  const externalEventHandlers = (0, _utils.extractEventHandlers)(externalProps);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-tree-view",
3
- "version": "7.7.1",
3
+ "version": "7.8.0",
4
4
  "description": "The community edition of the Tree View components (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./node/index.js",
@@ -1,2 +1,2 @@
1
- import { UseTreeItem2Parameters, UseTreeItem2ReturnValue, UseTreeItem2MinimalPlugins } from './useTreeItem2.types';
2
- export declare const useTreeItem2: <TSignatures extends UseTreeItem2MinimalPlugins = UseTreeItem2MinimalPlugins, TOptionalSignatures extends readonly [] = readonly []>(parameters: UseTreeItem2Parameters) => UseTreeItem2ReturnValue<TSignatures, TOptionalSignatures>;
1
+ import { UseTreeItem2Parameters, UseTreeItem2ReturnValue, UseTreeItem2MinimalPlugins, UseTreeItem2OptionalPlugins } from './useTreeItem2.types';
2
+ export declare const useTreeItem2: <TSignatures extends UseTreeItem2MinimalPlugins = UseTreeItem2MinimalPlugins, TOptionalSignatures extends UseTreeItem2OptionalPlugins = readonly []>(parameters: UseTreeItem2Parameters) => UseTreeItem2ReturnValue<TSignatures, TOptionalSignatures>;
@@ -13,6 +13,9 @@ export const useTreeItem2 = parameters => {
13
13
  disableSelection,
14
14
  checkboxSelection
15
15
  },
16
+ expansion: {
17
+ expansionTrigger
18
+ },
16
19
  disabledItemsFocusable,
17
20
  indentationAtItemLevel,
18
21
  instance,
@@ -69,7 +72,9 @@ export const useTreeItem2 = parameters => {
69
72
  if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) {
70
73
  return;
71
74
  }
72
- interactions.handleExpansion(event);
75
+ if (expansionTrigger === 'content') {
76
+ interactions.handleExpansion(event);
77
+ }
73
78
  if (!checkboxSelection) {
74
79
  interactions.handleSelection(event);
75
80
  }
@@ -95,6 +100,15 @@ export const useTreeItem2 = parameters => {
95
100
  }
96
101
  interactions.handleCheckboxSelection(event);
97
102
  };
103
+ const createIconContainerHandleClick = otherHandlers => event => {
104
+ otherHandlers.onClick?.(event);
105
+ if (event.defaultMuiPrevented) {
106
+ return;
107
+ }
108
+ if (expansionTrigger === 'iconContainer') {
109
+ interactions.handleExpansion(event);
110
+ }
111
+ };
98
112
  const getRootProps = (externalProps = {}) => {
99
113
  const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
100
114
  let ariaSelected;
@@ -162,7 +176,9 @@ export const useTreeItem2 = parameters => {
162
176
  };
163
177
  const getIconContainerProps = (externalProps = {}) => {
164
178
  const externalEventHandlers = extractEventHandlers(externalProps);
165
- return _extends({}, externalEventHandlers, externalProps);
179
+ return _extends({}, externalEventHandlers, externalProps, {
180
+ onClick: createIconContainerHandleClick(externalEventHandlers)
181
+ });
166
182
  };
167
183
  const getGroupTransitionProps = (externalProps = {}) => {
168
184
  const externalEventHandlers = extractEventHandlers(externalProps);
@@ -6,6 +6,7 @@ import { UseTreeViewSelectionSignature } from '../internals/plugins/useTreeViewS
6
6
  import { UseTreeViewItemsSignature } from '../internals/plugins/useTreeViewItems';
7
7
  import { UseTreeViewFocusSignature } from '../internals/plugins/useTreeViewFocus';
8
8
  import { UseTreeViewKeyboardNavigationSignature } from '../internals/plugins/useTreeViewKeyboardNavigation';
9
+ import { UseTreeViewExpansionSignature } from '../internals/plugins/useTreeViewExpansion';
9
10
  export interface UseTreeItem2Parameters {
10
11
  /**
11
12
  * The id attribute of the item. If not provided, it will be generated.
@@ -60,6 +61,7 @@ export interface UseTreeItem2ContentSlotOwnProps {
60
61
  }
61
62
  export type UseTreeItem2ContentSlotProps<ExternalProps = {}> = ExternalProps & UseTreeItem2ContentSlotOwnProps;
62
63
  export interface UseTreeItem2IconContainerSlotOwnProps {
64
+ onClick: MuiCancellableEventHandler<React.MouseEvent>;
63
65
  }
64
66
  export type UseTreeItemIconContainerSlotProps<ExternalProps = {}> = ExternalProps & UseTreeItem2IconContainerSlotOwnProps;
65
67
  export interface UseTreeItem2LabelSlotOwnProps {
@@ -149,6 +151,7 @@ export interface UseTreeItem2ReturnValue<TSignatures extends UseTreeItem2Minimal
149
151
  */
150
152
  export type UseTreeItem2MinimalPlugins = readonly [
151
153
  UseTreeViewSelectionSignature,
154
+ UseTreeViewExpansionSignature,
152
155
  UseTreeViewItemsSignature,
153
156
  UseTreeViewFocusSignature,
154
157
  UseTreeViewKeyboardNavigationSignature