@mui/x-tree-view 7.3.1 → 7.5.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 (54) hide show
  1. package/CHANGELOG.md +234 -5
  2. package/RichTreeView/RichTreeView.js +6 -1
  3. package/SimpleTreeView/SimpleTreeView.js +6 -1
  4. package/TreeItem/TreeItem.js +7 -2
  5. package/TreeItem/TreeItemContent.d.ts +2 -0
  6. package/TreeItem/TreeItemContent.js +18 -1
  7. package/TreeItem/treeItemClasses.d.ts +2 -0
  8. package/TreeItem/treeItemClasses.js +1 -1
  9. package/TreeItem/useTreeItemState.d.ts +4 -1
  10. package/TreeItem/useTreeItemState.js +18 -2
  11. package/TreeItem2/TreeItem2.d.ts +4 -0
  12. package/TreeItem2/TreeItem2.js +34 -4
  13. package/TreeItem2/TreeItem2.types.d.ts +6 -0
  14. package/TreeItem2/index.d.ts +1 -1
  15. package/TreeItem2/index.js +1 -1
  16. package/TreeView/TreeView.js +6 -1
  17. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +1 -0
  18. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +11 -2
  19. package/index.js +1 -1
  20. package/internals/models/plugin.d.ts +0 -6
  21. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +3 -3
  22. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +18 -6
  23. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +16 -4
  24. package/modern/RichTreeView/RichTreeView.js +6 -1
  25. package/modern/SimpleTreeView/SimpleTreeView.js +6 -1
  26. package/modern/TreeItem/TreeItem.js +7 -2
  27. package/modern/TreeItem/TreeItemContent.js +18 -1
  28. package/modern/TreeItem/treeItemClasses.js +1 -1
  29. package/modern/TreeItem/useTreeItemState.js +18 -2
  30. package/modern/TreeItem2/TreeItem2.js +34 -4
  31. package/modern/TreeItem2/index.js +1 -1
  32. package/modern/TreeView/TreeView.js +6 -1
  33. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +11 -2
  34. package/modern/index.js +1 -1
  35. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +3 -3
  36. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +18 -6
  37. package/modern/useTreeItem2/useTreeItem2.js +35 -6
  38. package/node/RichTreeView/RichTreeView.js +6 -1
  39. package/node/SimpleTreeView/SimpleTreeView.js +6 -1
  40. package/node/TreeItem/TreeItem.js +7 -2
  41. package/node/TreeItem/TreeItemContent.js +18 -1
  42. package/node/TreeItem/treeItemClasses.js +1 -1
  43. package/node/TreeItem/useTreeItemState.js +18 -2
  44. package/node/TreeItem2/TreeItem2.js +35 -5
  45. package/node/TreeItem2/index.js +6 -0
  46. package/node/TreeView/TreeView.js +6 -1
  47. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +11 -2
  48. package/node/index.js +1 -1
  49. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +3 -3
  50. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +18 -6
  51. package/node/useTreeItem2/useTreeItem2.js +37 -6
  52. package/package.json +3 -3
  53. package/useTreeItem2/useTreeItem2.js +35 -6
  54. package/useTreeItem2/useTreeItem2.types.d.ts +15 -0
@@ -1,4 +1,5 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
2
3
  import { extractEventHandlers } from '@mui/base/utils';
3
4
  import useForkRef from '@mui/utils/useForkRef';
4
5
  import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext';
@@ -7,7 +8,9 @@ export const useTreeItem2 = parameters => {
7
8
  const {
8
9
  runItemPlugins,
9
10
  selection: {
10
- multiSelect
11
+ multiSelect,
12
+ disableSelection,
13
+ checkboxSelection
11
14
  },
12
15
  disabledItemsFocusable,
13
16
  instance,
@@ -33,6 +36,7 @@ export const useTreeItem2 = parameters => {
33
36
  });
34
37
  const idAttribute = instance.getTreeItemIdAttribute(itemId, id);
35
38
  const handleRootRef = useForkRef(rootRef, pluginRootRef);
39
+ const checkboxRef = React.useRef(null);
36
40
  const createRootHandleFocus = otherHandlers => event => {
37
41
  otherHandlers.onFocus?.(event);
38
42
  if (event.defaultMuiPrevented) {
@@ -59,11 +63,13 @@ export const useTreeItem2 = parameters => {
59
63
  };
60
64
  const createContentHandleClick = otherHandlers => event => {
61
65
  otherHandlers.onClick?.(event);
62
- if (event.defaultMuiPrevented) {
66
+ if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) {
63
67
  return;
64
68
  }
65
69
  interactions.handleExpansion(event);
66
- interactions.handleSelection(event);
70
+ if (!checkboxSelection) {
71
+ interactions.handleSelection(event);
72
+ }
67
73
  };
68
74
  const createContentHandleMouseDown = otherHandlers => event => {
69
75
  otherHandlers.onMouseDown?.(event);
@@ -76,6 +82,16 @@ export const useTreeItem2 = parameters => {
76
82
  event.preventDefault();
77
83
  }
78
84
  };
85
+ const createCheckboxHandleChange = otherHandlers => event => {
86
+ otherHandlers.onChange?.(event);
87
+ if (event.defaultMuiPrevented) {
88
+ return;
89
+ }
90
+ if (disableSelection || status.disabled) {
91
+ return;
92
+ }
93
+ interactions.handleCheckboxSelection(event);
94
+ };
79
95
  const getRootProps = (externalProps = {}) => {
80
96
  const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
81
97
  let ariaSelected;
@@ -105,7 +121,7 @@ export const useTreeItem2 = parameters => {
105
121
  });
106
122
  };
107
123
  const getContentProps = (externalProps = {}) => {
108
- const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
124
+ const externalEventHandlers = extractEventHandlers(externalProps);
109
125
  return _extends({}, externalEventHandlers, externalProps, {
110
126
  ref: contentRef,
111
127
  onClick: createContentHandleClick(externalEventHandlers),
@@ -113,6 +129,18 @@ export const useTreeItem2 = parameters => {
113
129
  status
114
130
  });
115
131
  };
132
+ const getCheckboxProps = (externalProps = {}) => {
133
+ const externalEventHandlers = extractEventHandlers(externalProps);
134
+ return _extends({}, externalEventHandlers, {
135
+ visible: checkboxSelection,
136
+ ref: checkboxRef,
137
+ checked: status.selected,
138
+ disabled: disableSelection || status.disabled,
139
+ tabIndex: -1
140
+ }, externalProps, {
141
+ onChange: createCheckboxHandleChange(externalEventHandlers)
142
+ });
143
+ };
116
144
  const getLabelProps = (externalProps = {}) => {
117
145
  const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
118
146
  return _extends({}, externalEventHandlers, {
@@ -120,11 +148,11 @@ export const useTreeItem2 = parameters => {
120
148
  }, externalProps);
121
149
  };
122
150
  const getIconContainerProps = (externalProps = {}) => {
123
- const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
151
+ const externalEventHandlers = extractEventHandlers(externalProps);
124
152
  return _extends({}, externalEventHandlers, externalProps);
125
153
  };
126
154
  const getGroupTransitionProps = (externalProps = {}) => {
127
- const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
155
+ const externalEventHandlers = extractEventHandlers(externalProps);
128
156
  return _extends({}, externalEventHandlers, {
129
157
  unmountOnExit: true,
130
158
  component: 'ul',
@@ -138,6 +166,7 @@ export const useTreeItem2 = parameters => {
138
166
  getContentProps,
139
167
  getGroupTransitionProps,
140
168
  getIconContainerProps,
169
+ getCheckboxProps,
141
170
  getLabelProps,
142
171
  rootRef: handleRootRef,
143
172
  status,
@@ -152,6 +152,11 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
152
152
  setItemExpansion: _propTypes.default.func.isRequired
153
153
  })
154
154
  }),
155
+ /**
156
+ * If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
157
+ * @default false
158
+ */
159
+ checkboxSelection: _propTypes.default.bool,
155
160
  /**
156
161
  * Override or extend the styles applied to the component.
157
162
  */
@@ -216,7 +221,7 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
216
221
  isItemDisabled: _propTypes.default.func,
217
222
  items: _propTypes.default.array.isRequired,
218
223
  /**
219
- * If true `ctrl` and `shift` will trigger multiselect.
224
+ * If `true`, `ctrl` and `shift` will trigger multiselect.
220
225
  * @default false
221
226
  */
222
227
  multiSelect: _propTypes.default.bool,
@@ -110,6 +110,11 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
110
110
  setItemExpansion: _propTypes.default.func.isRequired
111
111
  })
112
112
  }),
113
+ /**
114
+ * If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
115
+ * @default false
116
+ */
117
+ checkboxSelection: _propTypes.default.bool,
113
118
  /**
114
119
  * The content of the component.
115
120
  */
@@ -152,7 +157,7 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
152
157
  */
153
158
  id: _propTypes.default.string,
154
159
  /**
155
- * If true `ctrl` and `shift` will trigger multiselect.
160
+ * If `true`, `ctrl` and `shift` will trigger multiselect.
156
161
  * @default false
157
162
  */
158
163
  multiSelect: _propTypes.default.bool,
@@ -41,6 +41,7 @@ const useUtilityClasses = ownerState => {
41
41
  focused: ['focused'],
42
42
  disabled: ['disabled'],
43
43
  iconContainer: ['iconContainer'],
44
+ checkbox: ['checkbox'],
44
45
  label: ['label'],
45
46
  groupTransition: ['groupTransition']
46
47
  };
@@ -122,7 +123,10 @@ const StyledTreeItemContent = (0, _styles.styled)(_TreeItemContent.TreeItemConte
122
123
  // fixes overflow - see https://github.com/mui/material-ui/issues/27372
123
124
  minWidth: 0,
124
125
  position: 'relative'
125
- }, theme.typography.body1)
126
+ }, theme.typography.body1),
127
+ [`& .${_treeItemClasses.treeItemClasses.checkbox}`]: {
128
+ padding: 0
129
+ }
126
130
  }));
127
131
  const TreeItemGroup = (0, _styles.styled)(_Collapse.default, {
128
132
  name: 'MuiTreeItem',
@@ -305,7 +309,8 @@ const TreeItem = exports.TreeItem = /*#__PURE__*/React.forwardRef(function TreeI
305
309
  focused: classes.focused,
306
310
  disabled: classes.disabled,
307
311
  iconContainer: classes.iconContainer,
308
- label: classes.label
312
+ label: classes.label,
313
+ checkbox: classes.checkbox
309
314
  },
310
315
  label: label,
311
316
  itemId: itemId,
@@ -10,6 +10,7 @@ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runt
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _propTypes = _interopRequireDefault(require("prop-types"));
12
12
  var _clsx = _interopRequireDefault(require("clsx"));
13
+ var _Checkbox = _interopRequireDefault(require("@mui/material/Checkbox"));
13
14
  var _useTreeItemState = require("./useTreeItemState");
14
15
  var _jsxRuntime = require("react/jsx-runtime");
15
16
  const _excluded = ["classes", "className", "displayIcon", "expansionIcon", "icon", "label", "itemId", "onClick", "onMouseDown"];
@@ -36,11 +37,15 @@ const TreeItemContent = exports.TreeItemContent = /*#__PURE__*/React.forwardRef(
36
37
  expanded,
37
38
  selected,
38
39
  focused,
40
+ disableSelection,
41
+ checkboxSelection,
39
42
  handleExpansion,
40
43
  handleSelection,
44
+ handleCheckboxSelection,
41
45
  preventSelection
42
46
  } = (0, _useTreeItemState.useTreeItemState)(itemId);
43
47
  const icon = iconProp || expansionIcon || displayIcon;
48
+ const checkboxRef = React.useRef(null);
44
49
  const handleMouseDown = event => {
45
50
  preventSelection(event);
46
51
  if (onMouseDown) {
@@ -48,8 +53,13 @@ const TreeItemContent = exports.TreeItemContent = /*#__PURE__*/React.forwardRef(
48
53
  }
49
54
  };
50
55
  const handleClick = event => {
56
+ if (checkboxRef.current?.contains(event.target)) {
57
+ return;
58
+ }
51
59
  handleExpansion(event);
52
- handleSelection(event);
60
+ if (!checkboxSelection) {
61
+ handleSelection(event);
62
+ }
53
63
  if (onClick) {
54
64
  onClick(event);
55
65
  }
@@ -65,6 +75,13 @@ const TreeItemContent = exports.TreeItemContent = /*#__PURE__*/React.forwardRef(
65
75
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
66
76
  className: classes.iconContainer,
67
77
  children: icon
78
+ }), checkboxSelection && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Checkbox.default, {
79
+ className: classes.checkbox,
80
+ checked: selected,
81
+ onChange: handleCheckboxSelection,
82
+ disabled: disabled || disableSelection,
83
+ ref: checkboxRef,
84
+ tabIndex: -1
68
85
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
69
86
  className: classes.label,
70
87
  children: label
@@ -11,4 +11,4 @@ var _generateUtilityClasses = _interopRequireDefault(require("@mui/utils/generat
11
11
  function getTreeItemUtilityClass(slot) {
12
12
  return (0, _generateUtilityClass.default)('MuiTreeItem', slot);
13
13
  }
14
- const treeItemClasses = exports.treeItemClasses = (0, _generateUtilityClasses.default)('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label']);
14
+ const treeItemClasses = exports.treeItemClasses = (0, _generateUtilityClasses.default)('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label', 'checkbox']);
@@ -9,7 +9,9 @@ function useTreeItemState(itemId) {
9
9
  const {
10
10
  instance,
11
11
  selection: {
12
- multiSelect
12
+ multiSelect,
13
+ checkboxSelection,
14
+ disableSelection
13
15
  }
14
16
  } = (0, _useTreeViewContext.useTreeViewContext)();
15
17
  const expandable = instance.isItemExpandable(itemId);
@@ -43,10 +45,21 @@ function useTreeItemState(itemId) {
43
45
  instance.selectItem(event, itemId, true);
44
46
  }
45
47
  } else {
46
- instance.selectItem(event, itemId);
48
+ instance.selectItem(event, itemId, false);
47
49
  }
48
50
  }
49
51
  };
52
+ const handleCheckboxSelection = event => {
53
+ if (disableSelection || disabled) {
54
+ return;
55
+ }
56
+ const hasShift = event.nativeEvent.shiftKey;
57
+ if (multiSelect && hasShift) {
58
+ instance.expandSelectionRange(event, itemId);
59
+ } else {
60
+ instance.selectItem(event, itemId, multiSelect, event.target.checked);
61
+ }
62
+ };
50
63
  const preventSelection = event => {
51
64
  if (event.shiftKey || event.ctrlKey || event.metaKey || disabled) {
52
65
  // Prevent text selection
@@ -58,8 +71,11 @@ function useTreeItemState(itemId) {
58
71
  expanded,
59
72
  selected,
60
73
  focused,
74
+ disableSelection,
75
+ checkboxSelection,
61
76
  handleExpansion,
62
77
  handleSelection,
78
+ handleCheckboxSelection,
63
79
  preventSelection
64
80
  };
65
81
  }
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.TreeItem2Root = exports.TreeItem2Label = exports.TreeItem2IconContainer = exports.TreeItem2GroupTransition = exports.TreeItem2Content = exports.TreeItem2 = void 0;
7
+ exports.TreeItem2Root = exports.TreeItem2Label = exports.TreeItem2IconContainer = exports.TreeItem2GroupTransition = exports.TreeItem2Content = exports.TreeItem2Checkbox = exports.TreeItem2 = void 0;
8
8
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var React = _interopRequireWildcard(require("react"));
@@ -13,6 +13,7 @@ var _clsx = _interopRequireDefault(require("clsx"));
13
13
  var _unsupportedProp = _interopRequireDefault(require("@mui/utils/unsupportedProp"));
14
14
  var _styles = require("@mui/material/styles");
15
15
  var _Collapse = _interopRequireDefault(require("@mui/material/Collapse"));
16
+ var _Checkbox = _interopRequireDefault(require("@mui/material/Checkbox"));
16
17
  var _utils = require("@mui/base/utils");
17
18
  var _system = require("@mui/system");
18
19
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
@@ -21,7 +22,8 @@ var _TreeItem = require("../TreeItem");
21
22
  var _TreeItem2Icon = require("../TreeItem2Icon");
22
23
  var _TreeItem2Provider = require("../TreeItem2Provider");
23
24
  var _jsxRuntime = require("react/jsx-runtime");
24
- const _excluded = ["id", "itemId", "label", "disabled", "children", "slots", "slotProps"];
25
+ const _excluded = ["visible"],
26
+ _excluded2 = ["id", "itemId", "label", "disabled", "children", "slots", "slotProps"];
25
27
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
26
28
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
27
29
  const TreeItem2Root = exports.TreeItem2Root = (0, _styles.styled)('li', {
@@ -130,7 +132,7 @@ const TreeItem2IconContainer = exports.TreeItem2IconContainer = (0, _styles.styl
130
132
  }
131
133
  });
132
134
  const TreeItem2GroupTransition = exports.TreeItem2GroupTransition = (0, _styles.styled)(_Collapse.default, {
133
- name: 'MuiTreeItem2GroupTransition',
135
+ name: 'MuiTreeItem2',
134
136
  slot: 'GroupTransition',
135
137
  overridesResolver: (props, styles) => styles.groupTransition
136
138
  })({
@@ -138,6 +140,24 @@ const TreeItem2GroupTransition = exports.TreeItem2GroupTransition = (0, _styles.
138
140
  padding: 0,
139
141
  paddingLeft: 12
140
142
  });
143
+ const TreeItem2Checkbox = exports.TreeItem2Checkbox = (0, _styles.styled)( /*#__PURE__*/React.forwardRef((props, ref) => {
144
+ const {
145
+ visible
146
+ } = props,
147
+ other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
148
+ if (!visible) {
149
+ return null;
150
+ }
151
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Checkbox.default, (0, _extends2.default)({}, other, {
152
+ ref: ref
153
+ }));
154
+ }), {
155
+ name: 'MuiTreeItem2',
156
+ slot: 'Checkbox',
157
+ overridesResolver: (props, styles) => styles.checkbox
158
+ })({
159
+ padding: 0
160
+ });
141
161
  const useUtilityClasses = ownerState => {
142
162
  const {
143
163
  classes
@@ -150,6 +170,7 @@ const useUtilityClasses = ownerState => {
150
170
  focused: ['focused'],
151
171
  disabled: ['disabled'],
152
172
  iconContainer: ['iconContainer'],
173
+ checkbox: ['checkbox'],
153
174
  label: ['label'],
154
175
  groupTransition: ['groupTransition']
155
176
  };
@@ -179,11 +200,12 @@ const TreeItem2 = exports.TreeItem2 = /*#__PURE__*/React.forwardRef(function Tre
179
200
  slots = {},
180
201
  slotProps = {}
181
202
  } = props,
182
- other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
203
+ other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded2);
183
204
  const {
184
205
  getRootProps,
185
206
  getContentProps,
186
207
  getIconContainerProps,
208
+ getCheckboxProps,
187
209
  getLabelProps,
188
210
  getGroupTransitionProps,
189
211
  status
@@ -232,6 +254,14 @@ const TreeItem2 = exports.TreeItem2 = /*#__PURE__*/React.forwardRef(function Tre
232
254
  ownerState: {},
233
255
  className: classes.label
234
256
  });
257
+ const Checkbox = slots.checkbox ?? TreeItem2Checkbox;
258
+ const checkboxProps = (0, _utils.useSlotProps)({
259
+ elementType: Checkbox,
260
+ getSlotProps: getCheckboxProps,
261
+ externalSlotProps: slotProps.checkbox,
262
+ ownerState: {},
263
+ className: classes.checkbox
264
+ });
235
265
  const GroupTransition = slots.groupTransition ?? undefined;
236
266
  const groupTransitionProps = (0, _utils.useSlotProps)({
237
267
  elementType: GroupTransition,
@@ -250,7 +280,7 @@ const TreeItem2 = exports.TreeItem2 = /*#__PURE__*/React.forwardRef(function Tre
250
280
  slots: slots,
251
281
  slotProps: slotProps
252
282
  })
253
- })), /*#__PURE__*/(0, _jsxRuntime.jsx)(Label, (0, _extends2.default)({}, labelProps))]
283
+ })), /*#__PURE__*/(0, _jsxRuntime.jsx)(Checkbox, (0, _extends2.default)({}, checkboxProps)), /*#__PURE__*/(0, _jsxRuntime.jsx)(Label, (0, _extends2.default)({}, labelProps))]
254
284
  })), children && /*#__PURE__*/(0, _jsxRuntime.jsx)(TreeItem2GroupTransition, (0, _extends2.default)({
255
285
  as: GroupTransition
256
286
  }, groupTransitionProps))]
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "TreeItem2", {
9
9
  return _TreeItem.TreeItem2;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "TreeItem2Checkbox", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _TreeItem.TreeItem2Checkbox;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "TreeItem2Content", {
13
19
  enumerable: true,
14
20
  get: function () {
@@ -83,6 +83,11 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
83
83
  setItemExpansion: _propTypes.default.func.isRequired
84
84
  })
85
85
  }),
86
+ /**
87
+ * If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
88
+ * @default false
89
+ */
90
+ checkboxSelection: _propTypes.default.bool,
86
91
  /**
87
92
  * The content of the component.
88
93
  */
@@ -125,7 +130,7 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
125
130
  */
126
131
  id: _propTypes.default.string,
127
132
  /**
128
- * If true `ctrl` and `shift` will trigger multiselect.
133
+ * If `true`, `ctrl` and `shift` will trigger multiselect.
129
134
  * @default false
130
135
  */
131
136
  multiSelect: _propTypes.default.bool,
@@ -51,12 +51,21 @@ const useTreeItem2Utils = ({
51
51
  instance.selectItem(event, itemId, true);
52
52
  }
53
53
  } else {
54
- instance.selectItem(event, itemId);
54
+ instance.selectItem(event, itemId, false);
55
+ }
56
+ };
57
+ const handleCheckboxSelection = event => {
58
+ const hasShift = event.nativeEvent.shiftKey;
59
+ if (multiSelect && hasShift) {
60
+ instance.expandSelectionRange(event, itemId);
61
+ } else {
62
+ instance.selectItem(event, itemId, multiSelect, event.target.checked);
55
63
  }
56
64
  };
57
65
  const interactions = {
58
66
  handleExpansion,
59
- handleSelection
67
+ handleSelection,
68
+ handleCheckboxSelection
60
69
  };
61
70
  return {
62
71
  interactions,
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.3.1
2
+ * @mui/x-tree-view v7.5.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -70,7 +70,7 @@ const useTreeViewKeyboardNavigation = ({
70
70
  if (event.defaultMuiPrevented) {
71
71
  return;
72
72
  }
73
- if (event.altKey || event.currentTarget !== event.target) {
73
+ if (event.altKey || event.currentTarget !== event.target.closest('*[role="treeitem"]')) {
74
74
  return;
75
75
  }
76
76
  const ctrlPressed = event.ctrlKey || event.metaKey;
@@ -87,7 +87,7 @@ const useTreeViewKeyboardNavigation = ({
87
87
  } else if (params.multiSelect) {
88
88
  instance.selectItem(event, itemId, true);
89
89
  } else {
90
- instance.selectItem(event, itemId);
90
+ instance.selectItem(event, itemId, false);
91
91
  }
92
92
  break;
93
93
  }
@@ -104,7 +104,7 @@ const useTreeViewKeyboardNavigation = ({
104
104
  event.preventDefault();
105
105
  instance.selectItem(event, itemId, true);
106
106
  } else if (!instance.isItemSelected(itemId)) {
107
- instance.selectItem(event, itemId);
107
+ instance.selectItem(event, itemId, false);
108
108
  event.preventDefault();
109
109
  }
110
110
  }
@@ -55,20 +55,28 @@ const useTreeViewSelection = ({
55
55
  models.selectedItems.setControlledValue(newSelectedItems);
56
56
  };
57
57
  const isItemSelected = itemId => selectedItemsMap.has(itemId);
58
- const selectItem = (event, itemId, multiple = false) => {
58
+ const selectItem = (event, itemId, keepExistingSelection, newValue) => {
59
59
  if (params.disableSelection) {
60
60
  return;
61
61
  }
62
62
  let newSelected;
63
- if (multiple) {
63
+ if (keepExistingSelection) {
64
64
  const cleanSelectedItems = (0, _useTreeViewSelection.convertSelectedItemsToArray)(models.selectedItems.value);
65
- if (instance.isItemSelected(itemId)) {
65
+ const isSelectedBefore = instance.isItemSelected(itemId);
66
+ if (isSelectedBefore && (newValue === false || newValue == null)) {
66
67
  newSelected = cleanSelectedItems.filter(id => id !== itemId);
67
- } else {
68
+ } else if (!isSelectedBefore && (newValue === true || newValue == null)) {
68
69
  newSelected = [itemId].concat(cleanSelectedItems);
70
+ } else {
71
+ newSelected = cleanSelectedItems;
69
72
  }
70
73
  } else {
71
- newSelected = params.multiSelect ? [itemId] : itemId;
74
+ // eslint-disable-next-line no-lonely-if
75
+ if (newValue === false) {
76
+ newSelected = params.multiSelect ? [] : null;
77
+ } else {
78
+ newSelected = params.multiSelect ? [itemId] : itemId;
79
+ }
72
80
  }
73
81
  setSelectedItems(event, newSelected);
74
82
  lastSelectedItem.current = itemId;
@@ -154,7 +162,9 @@ const useTreeViewSelection = ({
154
162
  },
155
163
  contextValue: {
156
164
  selection: {
157
- multiSelect: params.multiSelect
165
+ multiSelect: params.multiSelect,
166
+ checkboxSelection: params.checkboxSelection,
167
+ disableSelection: params.disableSelection
158
168
  }
159
169
  }
160
170
  };
@@ -169,11 +179,13 @@ const DEFAULT_SELECTED_ITEMS = [];
169
179
  useTreeViewSelection.getDefaultizedParams = params => (0, _extends2.default)({}, params, {
170
180
  disableSelection: params.disableSelection ?? false,
171
181
  multiSelect: params.multiSelect ?? false,
182
+ checkboxSelection: params.checkboxSelection ?? false,
172
183
  defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_ITEMS : null)
173
184
  });
174
185
  useTreeViewSelection.params = {
175
186
  disableSelection: true,
176
187
  multiSelect: true,
188
+ checkboxSelection: true,
177
189
  defaultSelectedItems: true,
178
190
  selectedItems: true,
179
191
  onSelectedItemsChange: true,
@@ -6,15 +6,20 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.useTreeItem2 = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var React = _interopRequireWildcard(require("react"));
9
10
  var _utils = require("@mui/base/utils");
10
11
  var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
11
12
  var _useTreeViewContext = require("../internals/TreeViewProvider/useTreeViewContext");
12
13
  var _useTreeItem2Utils = require("../hooks/useTreeItem2Utils");
14
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
16
  const useTreeItem2 = parameters => {
14
17
  const {
15
18
  runItemPlugins,
16
19
  selection: {
17
- multiSelect
20
+ multiSelect,
21
+ disableSelection,
22
+ checkboxSelection
18
23
  },
19
24
  disabledItemsFocusable,
20
25
  instance,
@@ -40,6 +45,7 @@ const useTreeItem2 = parameters => {
40
45
  });
41
46
  const idAttribute = instance.getTreeItemIdAttribute(itemId, id);
42
47
  const handleRootRef = (0, _useForkRef.default)(rootRef, pluginRootRef);
48
+ const checkboxRef = React.useRef(null);
43
49
  const createRootHandleFocus = otherHandlers => event => {
44
50
  otherHandlers.onFocus?.(event);
45
51
  if (event.defaultMuiPrevented) {
@@ -66,11 +72,13 @@ const useTreeItem2 = parameters => {
66
72
  };
67
73
  const createContentHandleClick = otherHandlers => event => {
68
74
  otherHandlers.onClick?.(event);
69
- if (event.defaultMuiPrevented) {
75
+ if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) {
70
76
  return;
71
77
  }
72
78
  interactions.handleExpansion(event);
73
- interactions.handleSelection(event);
79
+ if (!checkboxSelection) {
80
+ interactions.handleSelection(event);
81
+ }
74
82
  };
75
83
  const createContentHandleMouseDown = otherHandlers => event => {
76
84
  otherHandlers.onMouseDown?.(event);
@@ -83,6 +91,16 @@ const useTreeItem2 = parameters => {
83
91
  event.preventDefault();
84
92
  }
85
93
  };
94
+ const createCheckboxHandleChange = otherHandlers => event => {
95
+ otherHandlers.onChange?.(event);
96
+ if (event.defaultMuiPrevented) {
97
+ return;
98
+ }
99
+ if (disableSelection || status.disabled) {
100
+ return;
101
+ }
102
+ interactions.handleCheckboxSelection(event);
103
+ };
86
104
  const getRootProps = (externalProps = {}) => {
87
105
  const externalEventHandlers = (0, _extends2.default)({}, (0, _utils.extractEventHandlers)(parameters), (0, _utils.extractEventHandlers)(externalProps));
88
106
  let ariaSelected;
@@ -112,7 +130,7 @@ const useTreeItem2 = parameters => {
112
130
  });
113
131
  };
114
132
  const getContentProps = (externalProps = {}) => {
115
- const externalEventHandlers = (0, _extends2.default)({}, (0, _utils.extractEventHandlers)(parameters), (0, _utils.extractEventHandlers)(externalProps));
133
+ const externalEventHandlers = (0, _utils.extractEventHandlers)(externalProps);
116
134
  return (0, _extends2.default)({}, externalEventHandlers, externalProps, {
117
135
  ref: contentRef,
118
136
  onClick: createContentHandleClick(externalEventHandlers),
@@ -120,6 +138,18 @@ const useTreeItem2 = parameters => {
120
138
  status
121
139
  });
122
140
  };
141
+ const getCheckboxProps = (externalProps = {}) => {
142
+ const externalEventHandlers = (0, _utils.extractEventHandlers)(externalProps);
143
+ return (0, _extends2.default)({}, externalEventHandlers, {
144
+ visible: checkboxSelection,
145
+ ref: checkboxRef,
146
+ checked: status.selected,
147
+ disabled: disableSelection || status.disabled,
148
+ tabIndex: -1
149
+ }, externalProps, {
150
+ onChange: createCheckboxHandleChange(externalEventHandlers)
151
+ });
152
+ };
123
153
  const getLabelProps = (externalProps = {}) => {
124
154
  const externalEventHandlers = (0, _extends2.default)({}, (0, _utils.extractEventHandlers)(parameters), (0, _utils.extractEventHandlers)(externalProps));
125
155
  return (0, _extends2.default)({}, externalEventHandlers, {
@@ -127,11 +157,11 @@ const useTreeItem2 = parameters => {
127
157
  }, externalProps);
128
158
  };
129
159
  const getIconContainerProps = (externalProps = {}) => {
130
- const externalEventHandlers = (0, _extends2.default)({}, (0, _utils.extractEventHandlers)(parameters), (0, _utils.extractEventHandlers)(externalProps));
160
+ const externalEventHandlers = (0, _utils.extractEventHandlers)(externalProps);
131
161
  return (0, _extends2.default)({}, externalEventHandlers, externalProps);
132
162
  };
133
163
  const getGroupTransitionProps = (externalProps = {}) => {
134
- const externalEventHandlers = (0, _extends2.default)({}, (0, _utils.extractEventHandlers)(parameters), (0, _utils.extractEventHandlers)(externalProps));
164
+ const externalEventHandlers = (0, _utils.extractEventHandlers)(externalProps);
135
165
  return (0, _extends2.default)({}, externalEventHandlers, {
136
166
  unmountOnExit: true,
137
167
  component: 'ul',
@@ -145,6 +175,7 @@ const useTreeItem2 = parameters => {
145
175
  getContentProps,
146
176
  getGroupTransitionProps,
147
177
  getIconContainerProps,
178
+ getCheckboxProps,
148
179
  getLabelProps,
149
180
  rootRef: handleRootRef,
150
181
  status,