@mui/x-tree-view 7.12.0 → 7.13.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 (87) hide show
  1. package/CHANGELOG.md +151 -2
  2. package/RichTreeView/RichTreeView.js +20 -2
  3. package/RichTreeView/RichTreeView.plugins.d.ts +3 -2
  4. package/RichTreeView/RichTreeView.plugins.js +2 -1
  5. package/TreeItem/TreeItem.js +24 -0
  6. package/TreeItem/TreeItemContent.d.ts +8 -0
  7. package/TreeItem/TreeItemContent.js +48 -8
  8. package/TreeItem/treeItemClasses.d.ts +6 -0
  9. package/TreeItem/treeItemClasses.js +1 -1
  10. package/TreeItem/useTreeItemState.d.ts +6 -0
  11. package/TreeItem/useTreeItemState.js +46 -1
  12. package/TreeItem2/TreeItem2.d.ts +3 -1
  13. package/TreeItem2/TreeItem2.js +29 -5
  14. package/TreeItem2/TreeItem2.types.d.ts +6 -0
  15. package/TreeItem2Icon/TreeItem2Icon.js +2 -0
  16. package/TreeItem2LabelInput/TreeItem2LabelInput.d.ts +2 -0
  17. package/TreeItem2LabelInput/TreeItem2LabelInput.js +20 -0
  18. package/TreeItem2LabelInput/TreeItem2LabelInput.types.d.ts +8 -0
  19. package/TreeItem2LabelInput/TreeItem2LabelInput.types.js +1 -0
  20. package/TreeItem2LabelInput/index.d.ts +2 -0
  21. package/TreeItem2LabelInput/index.js +1 -0
  22. package/TreeItem2LabelInput/package.json +6 -0
  23. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +5 -1
  24. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +45 -2
  25. package/hooks/useTreeViewApiRef.d.ts +1 -1
  26. package/index.js +1 -1
  27. package/internals/index.d.ts +2 -0
  28. package/internals/index.js +1 -0
  29. package/internals/models/itemPlugin.d.ts +2 -1
  30. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +4 -1
  31. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +2 -0
  32. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +5 -1
  33. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -0
  34. package/internals/plugins/useTreeViewLabel/index.d.ts +2 -0
  35. package/internals/plugins/useTreeViewLabel/index.js +1 -0
  36. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.d.ts +3 -0
  37. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.d.ts +3 -0
  38. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +44 -0
  39. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +81 -0
  40. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +75 -0
  41. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.js +1 -0
  42. package/modern/RichTreeView/RichTreeView.js +20 -2
  43. package/modern/RichTreeView/RichTreeView.plugins.js +2 -1
  44. package/modern/TreeItem/TreeItem.js +24 -0
  45. package/modern/TreeItem/TreeItemContent.js +48 -8
  46. package/modern/TreeItem/treeItemClasses.js +1 -1
  47. package/modern/TreeItem/useTreeItemState.js +46 -1
  48. package/modern/TreeItem2/TreeItem2.js +29 -5
  49. package/modern/TreeItem2Icon/TreeItem2Icon.js +2 -0
  50. package/modern/TreeItem2LabelInput/TreeItem2LabelInput.js +20 -0
  51. package/modern/TreeItem2LabelInput/TreeItem2LabelInput.types.js +1 -0
  52. package/modern/TreeItem2LabelInput/index.js +1 -0
  53. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +45 -2
  54. package/modern/index.js +1 -1
  55. package/modern/internals/index.js +1 -0
  56. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +4 -1
  57. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +5 -1
  58. package/modern/internals/plugins/useTreeViewLabel/index.js +1 -0
  59. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +44 -0
  60. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +81 -0
  61. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.js +1 -0
  62. package/modern/useTreeItem2/useTreeItem2.js +65 -4
  63. package/node/RichTreeView/RichTreeView.js +20 -2
  64. package/node/RichTreeView/RichTreeView.plugins.js +2 -1
  65. package/node/TreeItem/TreeItem.js +24 -0
  66. package/node/TreeItem/TreeItemContent.js +48 -8
  67. package/node/TreeItem/treeItemClasses.js +1 -1
  68. package/node/TreeItem/useTreeItemState.js +46 -1
  69. package/node/TreeItem2/TreeItem2.js +29 -5
  70. package/node/TreeItem2Icon/TreeItem2Icon.js +2 -0
  71. package/node/TreeItem2LabelInput/TreeItem2LabelInput.js +26 -0
  72. package/node/TreeItem2LabelInput/TreeItem2LabelInput.types.js +5 -0
  73. package/node/TreeItem2LabelInput/index.js +12 -0
  74. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +45 -2
  75. package/node/index.js +1 -1
  76. package/node/internals/index.js +7 -0
  77. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +4 -1
  78. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +5 -1
  79. package/node/internals/plugins/useTreeViewLabel/index.js +12 -0
  80. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +54 -0
  81. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +91 -0
  82. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.js +5 -0
  83. package/node/useTreeItem2/useTreeItem2.js +65 -4
  84. package/package.json +10 -2
  85. package/useTreeItem2/index.d.ts +1 -1
  86. package/useTreeItem2/useTreeItem2.js +65 -4
  87. package/useTreeItem2/useTreeItem2.types.d.ts +35 -15
package/CHANGELOG.md CHANGED
@@ -3,6 +3,155 @@
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.13.0
7
+
8
+ _Aug 16, 2024_
9
+
10
+ We'd like to offer a big thanks to the 12 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 💫 Allow to [edit the label](https://mui.com/x/react-tree-view/rich-tree-view/editing/) of Tree View's items.
13
+
14
+ <img width="344" src="https://github.com/user-attachments/assets/1a6cf765-2dc8-4906-bd93-139086eed148" alt="Item label editing" />
15
+
16
+ - 🔧 Improve rows accessibility on the Data Grid features "Tree Data" and "Row Grouping". Certain "Row Grouping" accessibility updates will only be applied if experimental feature flag is enabled. See the [documentation](https://mui.com/x/react-data-grid/row-grouping/#accessibility-changes-in-v8) for more information.
17
+ - 🌍 Improve Vietnamese (vi-VN) locale on the Data Grid
18
+ - 🐞 Bugfixes
19
+
20
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
21
+
22
+ ### Data Grid
23
+
24
+ #### `@mui/x-data-grid@7.13.0`
25
+
26
+ - [DataGrid] Fix CSV export for `null` and `undefined` values (#14166) @k-rajat19
27
+ - [DataGrid] Fix error logged during skeleton loading with nested data grid (#14186) @KenanYusuf
28
+ - [DataGrid] Remove needless check in `useGridStateInitialization` (#14181) @k-rajat19
29
+ - [DataGrid] Add recipe for persisting filters in local storage (#14208) @cherniavskii
30
+ - [l10n] Improve Vietnamese (vi-VN) locale (#14216) @hungnd-casso
31
+
32
+ #### `@mui/x-data-grid-pro@7.13.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
33
+
34
+ Same changes as in `@mui/x-data-grid@7.13.0`, plus:
35
+
36
+ - [DataGridPro] Fix Tree Data and Row Grouping rows accessibility (#13623) @arminmeh
37
+
38
+ #### `@mui/x-data-grid-premium@7.13.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
39
+
40
+ Same changes as in `@mui/x-data-grid-pro@7.13.0`.
41
+
42
+ ### Date and Time Pickers
43
+
44
+ #### `@mui/x-date-pickers@7.13.0`
45
+
46
+ - [pickers] Fix date and time merging to retain milliseconds (#14173) @LukasTy
47
+
48
+ #### `@mui/x-date-pickers-pro@7.13.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
49
+
50
+ Same changes as in `@mui/x-date-pickers@7.13.0`.
51
+
52
+ ### Charts
53
+
54
+ #### `@mui/x-charts@7.13.0`
55
+
56
+ - [charts] Add `baseline` property to the `LineChart` `series` (#14153) @JCQuintas
57
+ - [charts] Fix issue where tooltip would disappear on mouse click (#14187) @alexfauquette
58
+ - [charts] Rename `CartesianContextProvider` to `CartesianProvider` (#14102) @JCQuintas
59
+ - [charts] Support axis with the same value for all data points (#14191) @alexfauquette
60
+
61
+ #### `@mui/x-date-charts-pro@7.0.0-alpha.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
62
+
63
+ Same changes as in `@mui/x-charts@7.13.0`.
64
+
65
+ ### Tree View
66
+
67
+ #### `@mui/x-tree-view@7.13.0`
68
+
69
+ - [TreeView] Add label editing feature (#13388) @noraleonte
70
+ - [TreeView] Fix the parameters passed for the `canMoveItemToNewPosition` prop (#14176) @flaviendelangle
71
+
72
+ ### Docs
73
+
74
+ - [docs] Extract dataset in the Line chart docs (#14034) @alexfauquette
75
+ - [docs] Remove redundant encoding in the mock data source server (#14185) @MBilalShafi
76
+ - [docs] Use Netflix financial results to document bar charts (#13991) @alexfauquette
77
+ - [docs] Remove relience of abbreviations (#14226) @oliviertassinari
78
+
79
+ ### Core
80
+
81
+ - [core] Bump monorepo (#14141) @Janpot
82
+ - [core] Fix ESLint issue (#14207) @LukasTy
83
+ - [core] Fix Netlify build cache issue (#14182) @cherniavskii
84
+ - [code-infra] Refactor Netlify `cache-docs` plugin setup (#14105) @LukasTy
85
+ - [internals] Move utils needed for tree view virtualization to shared package (#14202) @flaviendelangle
86
+
87
+ ## 7.12.1
88
+
89
+ _Aug 8, 2024_
90
+
91
+ We'd like to offer a big thanks to the 9 contributors who made this release possible. Here are some highlights ✨:
92
+
93
+ - 🎨 Charts get a new component to display color mapping in the legend
94
+ - 🚀 The `@mui/x-charts-pro` is released in alpha version 🧪. This new package introduces two main features:
95
+ - The Heatmap component
96
+ - The zoom interaction on the bar, line, and scatter charts
97
+ - 🌍 Improve Dutch (nl-NL) locale on the Date and Time Pickers
98
+ - 🐞 Bugfixes
99
+
100
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
101
+
102
+ ### Data Grid
103
+
104
+ #### `@mui/x-data-grid@7.12.1`
105
+
106
+ - [DataGrid] Fix `checkboxSelectionVisibleOnly` behavior with server-side pagination (#14083) @MBilalShafi
107
+ - [DataGrid] Fix `columnHeadersContainerRef` being `undefined` before mount (#14051) @samwato
108
+ - [DataGrid] Support Yarn PnP (#14126) @cherniavskii
109
+
110
+ #### `@mui/x-data-grid-pro@7.12.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
111
+
112
+ Same changes as in `@mui/x-data-grid@7.12.1`.
113
+
114
+ #### `@mui/x-data-grid-premium@7.12.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
115
+
116
+ Same changes as in `@mui/x-data-grid-pro@7.12.1`.
117
+
118
+ ### Date and Time Pickers
119
+
120
+ #### `@mui/x-date-pickers@7.12.1`
121
+
122
+ - [l10n] Improve Dutch (nlNL) locale (pickers) (#14036) @Robin1896
123
+
124
+ #### `@mui/x-date-pickers-pro@7.12.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
125
+
126
+ Same changes as in `@mui/x-date-pickers@7.12.1`.
127
+
128
+ ### Charts
129
+
130
+ #### `@mui/x-charts@7.12.1`
131
+
132
+ - [charts] Fix charts vendor publish config (#14073) @JCQuintas
133
+ - [charts] Move `plugins` to `PluginProvider` (#14056) @JCQuintas
134
+
135
+ #### `@mui/x-date-charts-pro@7.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
136
+
137
+ Same changes as in `@mui/x-charts@7.12.1`, plus:
138
+
139
+ - [charts-pro] Release the pro package in alpha (#13859) @alexfauquette
140
+
141
+ ### Tree View
142
+
143
+ #### `@mui/x-tree-view@7.12.1`
144
+
145
+ ### Docs
146
+
147
+ - [docs] Add a warning to promote the usage of `updateRows` (#14027) @MBilalShafi
148
+ - [docs] Disable ad in `Rich Tree View-Ordering` page (#14123) @oliviertassinari
149
+ - [docs] Redesign Date and Time Pickers overview page (#13241) @noraleonte
150
+
151
+ - [CHANGELOG] Polish details @oliviertassinari
152
+ - [code-infra] Use concurrency 1 in CircleCI (#14110) @JCQuintas
153
+ - [infra] Re-added the removal of `Latest Version` section (#14132) @michelengelen
154
+
6
155
  ## 7.12.0
7
156
 
8
157
  _Aug 1, 2024_
@@ -24,9 +173,9 @@ We'd like to offer a big thanks to the 12 contributors who made this release pos
24
173
 
25
174
  - 🎁 Introduce [item reordering using drag and drop](https://mui.com/x/react-tree-view/rich-tree-view/ordering/) on the `RichTreeViewPro` component
26
175
 
27
- <img width="384" src="https://github.com/user-attachments/assets/78bd83c5-7ce4-4ed7-acf9-be70b2dbce54" alt="Item reordering using drag and drop" />
176
+ <img width="287" src="https://github.com/user-attachments/assets/78bd83c5-7ce4-4ed7-acf9-be70b2dbce54" alt="Item reordering using drag and drop" />
28
177
 
29
- - 📦 Support Common JS bundle out of the box on `@mui/x-charts` by adding vendored D3 dependencies.
178
+ - 📦 Support CommonJS bundle out of the box on `@mui/x-charts` by adding vendored D3 dependencies.
30
179
 
31
180
  - This modifies how the package imports D3.js. It will impact you if you use `d3` packages installed by `@mui/x-charts` and don't have them in your `package.json`. You shouldn't be affected otherwise.
32
181
  - For more context, the initial issue is caused by D3 only exporting ESM.
@@ -140,7 +140,8 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
140
140
  getItemOrderedChildrenIds: PropTypes.func.isRequired,
141
141
  getItemTree: PropTypes.func.isRequired,
142
142
  selectItem: PropTypes.func.isRequired,
143
- setItemExpansion: PropTypes.func.isRequired
143
+ setItemExpansion: PropTypes.func.isRequired,
144
+ updateItemLabel: PropTypes.func.isRequired
144
145
  })
145
146
  }),
146
147
  /**
@@ -191,7 +192,8 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
191
192
  * the feature will be fully disabled and any property / method call will not have any effect.
192
193
  */
193
194
  experimentalFeatures: PropTypes.shape({
194
- indentationAtItemLevel: PropTypes.bool
195
+ indentationAtItemLevel: PropTypes.bool,
196
+ labelEditing: PropTypes.bool
195
197
  }),
196
198
  /**
197
199
  * Used to determine the id of a given item.
@@ -223,6 +225,16 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
223
225
  * @returns {boolean} `true` if the item should be disabled.
224
226
  */
225
227
  isItemDisabled: PropTypes.func,
228
+ /**
229
+ * Determines if a given item is editable or not.
230
+ * Make sure to also enable the `labelEditing` experimental feature:
231
+ * `<RichTreeViewPro experimentalFeatures={{ labelEditing: true }} />`.
232
+ * By default, the items are not editable.
233
+ * @template R
234
+ * @param {R} item The item to check.
235
+ * @returns {boolean} `true` if the item is editable.
236
+ */
237
+ isItemEditable: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
226
238
  /**
227
239
  * Horizontal indentation between an item and its children.
228
240
  * Examples: 24, "24px", "2rem", "2em".
@@ -260,6 +272,12 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
260
272
  * @param {string} itemId The id of the focused item.
261
273
  */
262
274
  onItemFocus: PropTypes.func,
275
+ /**
276
+ * Callback fired when the label of an item changes.
277
+ * @param {TreeViewItemId} itemId The id of the item that was edited.
278
+ * @param {string} newLabel The new label of the items.
279
+ */
280
+ onItemLabelChange: PropTypes.func,
263
281
  /**
264
282
  * Callback fired when a tree item is selected or deselected.
265
283
  * @param {React.SyntheticEvent} event The DOM event that triggered the change.
@@ -5,9 +5,10 @@ import { UseTreeViewSelectionParameters } from '../internals/plugins/useTreeView
5
5
  import { UseTreeViewFocusParameters } from '../internals/plugins/useTreeViewFocus';
6
6
  import { UseTreeViewIconsParameters } from '../internals/plugins/useTreeViewIcons';
7
7
  import { ConvertPluginsIntoSignatures, MergeSignaturesProperty } from '../internals/models';
8
- export declare const RICH_TREE_VIEW_PLUGINS: readonly [import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewItems").UseTreeViewItemsSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewExpansion").UseTreeViewExpansionSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewSelection").UseTreeViewSelectionSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewFocus").UseTreeViewFocusSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewKeyboardNavigation").UseTreeViewKeyboardNavigationSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewIcons").UseTreeViewIconsSignature>];
8
+ import { UseTreeViewLabelParameters } from '../internals/plugins/useTreeViewLabel';
9
+ export declare const RICH_TREE_VIEW_PLUGINS: readonly [import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewItems").UseTreeViewItemsSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewExpansion").UseTreeViewExpansionSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewSelection").UseTreeViewSelectionSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewFocus").UseTreeViewFocusSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewKeyboardNavigation").UseTreeViewKeyboardNavigationSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewIcons").UseTreeViewIconsSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewLabel").UseTreeViewLabelSignature>];
9
10
  export type RichTreeViewPluginSignatures = ConvertPluginsIntoSignatures<typeof RICH_TREE_VIEW_PLUGINS>;
10
11
  export type RichTreeViewPluginSlots = MergeSignaturesProperty<RichTreeViewPluginSignatures, 'slots'>;
11
12
  export type RichTreeViewPluginSlotProps = MergeSignaturesProperty<RichTreeViewPluginSignatures, 'slotProps'>;
12
- export interface RichTreeViewPluginParameters<R extends {}, Multiple extends boolean | undefined> extends TreeViewCorePluginParameters, UseTreeViewItemsParameters<R>, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, UseTreeViewSelectionParameters<Multiple>, UseTreeViewIconsParameters {
13
+ export interface RichTreeViewPluginParameters<R extends {}, Multiple extends boolean | undefined> extends TreeViewCorePluginParameters, UseTreeViewItemsParameters<R>, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, UseTreeViewSelectionParameters<Multiple>, UseTreeViewIconsParameters, UseTreeViewLabelParameters<R> {
13
14
  }
@@ -4,6 +4,7 @@ import { useTreeViewSelection } from '../internals/plugins/useTreeViewSelection'
4
4
  import { useTreeViewFocus } from '../internals/plugins/useTreeViewFocus';
5
5
  import { useTreeViewKeyboardNavigation } from '../internals/plugins/useTreeViewKeyboardNavigation';
6
6
  import { useTreeViewIcons } from '../internals/plugins/useTreeViewIcons';
7
- export const RICH_TREE_VIEW_PLUGINS = [useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
7
+ import { useTreeViewLabel } from '../internals/plugins/useTreeViewLabel';
8
+ export const RICH_TREE_VIEW_PLUGINS = [useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons, useTreeViewLabel];
8
9
 
9
10
  // We can't infer this type from the plugin, otherwise we would lose the generics.
@@ -25,6 +25,7 @@ import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons';
25
25
  import { TreeItem2Provider } from '../TreeItem2Provider';
26
26
  import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext';
27
27
  import { useTreeItemState } from './useTreeItemState';
28
+ import { isTargetInDescendants } from '../internals/utils/tree';
28
29
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
30
  const useThemeProps = createUseThemeProps('MuiTreeItem');
30
31
  const useUtilityClasses = ownerState => {
@@ -41,6 +42,9 @@ const useUtilityClasses = ownerState => {
41
42
  iconContainer: ['iconContainer'],
42
43
  checkbox: ['checkbox'],
43
44
  label: ['label'],
45
+ labelInput: ['labelInput'],
46
+ editing: ['editing'],
47
+ editable: ['editable'],
44
48
  groupTransition: ['groupTransition']
45
49
  };
46
50
  return composeClasses(slots, getTreeItemUtilityClass, classes);
@@ -207,6 +211,7 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
207
211
  focused,
208
212
  selected,
209
213
  disabled,
214
+ editing,
210
215
  handleExpansion
211
216
  } = useTreeItemState(itemId);
212
217
  const {
@@ -317,10 +322,19 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
317
322
  }
318
323
  function handleBlur(event) {
319
324
  onBlur?.(event);
325
+ if (editing ||
326
+ // we can exit the editing state by clicking outside the input (within the tree item) or by pressing Enter or Escape -> we don't want to remove the focused item from the state in these cases
327
+ // we can also exit the editing state by clicking on the root itself -> want to remove the focused item from the state in this case
328
+ event.relatedTarget && isTargetInDescendants(event.relatedTarget, rootRefObject.current) && (event.target && event.target?.dataset?.element === 'labelInput' && isTargetInDescendants(event.target, rootRefObject.current) || event.relatedTarget?.dataset?.element === 'labelInput')) {
329
+ return;
330
+ }
320
331
  instance.removeFocusedItem();
321
332
  }
322
333
  const handleKeyDown = event => {
323
334
  onKeyDown?.(event);
335
+ if (event.target?.dataset?.element === 'labelInput') {
336
+ return;
337
+ }
324
338
  instance.handleItemKeyDown(event, itemId);
325
339
  };
326
340
  const idAttribute = instance.getTreeItemIdAttribute(itemId, id);
@@ -340,6 +354,11 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
340
354
  contentRefObject,
341
355
  externalEventHandlers: {}
342
356
  }) ?? {};
357
+ const enhancedLabelInputProps = propsEnhancers.labelInput?.({
358
+ rootRefObject,
359
+ contentRefObject,
360
+ externalEventHandlers: {}
361
+ }) ?? {};
343
362
  return /*#__PURE__*/_jsx(TreeItem2Provider, {
344
363
  itemId: itemId,
345
364
  children: /*#__PURE__*/_jsxs(TreeItemRoot, _extends({
@@ -368,8 +387,11 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
368
387
  selected: classes.selected,
369
388
  focused: classes.focused,
370
389
  disabled: classes.disabled,
390
+ editable: classes.editable,
391
+ editing: classes.editing,
371
392
  iconContainer: classes.iconContainer,
372
393
  label: classes.label,
394
+ labelInput: classes.labelInput,
373
395
  checkbox: classes.checkbox
374
396
  },
375
397
  label: label,
@@ -382,6 +404,8 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
382
404
  ownerState: ownerState
383
405
  }, ContentProps, enhancedContentProps, enhancedDragAndDropOverlayProps.action == null ? {} : {
384
406
  dragAndDropOverlayProps: enhancedDragAndDropOverlayProps
407
+ }, enhancedLabelInputProps.value == null ? {} : {
408
+ labelInputProps: enhancedLabelInputProps
385
409
  }, {
386
410
  ref: handleContentRef
387
411
  })), children && /*#__PURE__*/_jsx(TreeItemGroup, _extends({
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { TreeItem2DragAndDropOverlayProps } from '../TreeItem2DragAndDropOverlay';
3
+ import { TreeItem2LabelInputProps } from '../TreeItem2LabelInput';
3
4
  export interface TreeItemContentProps extends React.HTMLAttributes<HTMLElement> {
4
5
  className?: string;
5
6
  /**
@@ -22,6 +23,12 @@ export interface TreeItemContentProps extends React.HTMLAttributes<HTMLElement>
22
23
  label: string;
23
24
  /** Styles applied to the checkbox element. */
24
25
  checkbox: string;
26
+ /** Styles applied to the input element that is visible when editing is enabled. */
27
+ labelInput: string;
28
+ /** Styles applied to the content element when editing is enabled. */
29
+ editing: string;
30
+ /** Styles applied to the content of the items that are editable. */
31
+ editable: string;
25
32
  };
26
33
  /**
27
34
  * The tree item label.
@@ -44,6 +51,7 @@ export interface TreeItemContentProps extends React.HTMLAttributes<HTMLElement>
44
51
  */
45
52
  displayIcon?: React.ReactNode;
46
53
  dragAndDropOverlayProps?: TreeItem2DragAndDropOverlayProps;
54
+ labelInputProps?: TreeItem2LabelInputProps;
47
55
  }
48
56
  export type TreeItemContentClassKey = keyof NonNullable<TreeItemContentProps['classes']>;
49
57
  /**
@@ -1,12 +1,13 @@
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", "dragAndDropOverlayProps"];
3
+ const _excluded = ["classes", "className", "displayIcon", "expansionIcon", "icon", "label", "itemId", "onClick", "onMouseDown", "dragAndDropOverlayProps", "labelInputProps"];
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
9
  import { TreeItem2DragAndDropOverlay } from '../TreeItem2DragAndDropOverlay';
10
+ import { TreeItem2LabelInput } from '../TreeItem2LabelInput';
10
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
12
  /**
12
13
  * @ignore - internal component.
@@ -22,7 +23,8 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
22
23
  itemId,
23
24
  onClick,
24
25
  onMouseDown,
25
- dragAndDropOverlayProps
26
+ dragAndDropOverlayProps,
27
+ labelInputProps
26
28
  } = props,
27
29
  other = _objectWithoutPropertiesLoose(props, _excluded);
28
30
  const {
@@ -30,6 +32,8 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
30
32
  expanded,
31
33
  selected,
32
34
  focused,
35
+ editing,
36
+ editable,
33
37
  disableSelection,
34
38
  checkboxSelection,
35
39
  handleExpansion,
@@ -37,7 +41,10 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
37
41
  handleCheckboxSelection,
38
42
  handleContentClick,
39
43
  preventSelection,
40
- expansionTrigger
44
+ expansionTrigger,
45
+ toggleItemEditing,
46
+ handleSaveItemLabel,
47
+ handleCancelItemLabelEditing
41
48
  } = useTreeItemState(itemId);
42
49
  const icon = iconProp || expansionIcon || displayIcon;
43
50
  const checkboxRef = React.useRef(null);
@@ -62,11 +69,36 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
62
69
  onClick(event);
63
70
  }
64
71
  };
72
+ const handleLabelDoubleClick = event => {
73
+ if (event.defaultMuiPrevented) {
74
+ return;
75
+ }
76
+ toggleItemEditing();
77
+ };
78
+ const handleLabelInputBlur = event => {
79
+ if (event.defaultMuiPrevented) {
80
+ return;
81
+ }
82
+ if (event.target.value) {
83
+ handleSaveItemLabel(event, event.target.value);
84
+ }
85
+ };
86
+ const handleLabelInputKeydown = event => {
87
+ if (event.defaultMuiPrevented) {
88
+ return;
89
+ }
90
+ const target = event.target;
91
+ if (event.key === 'Enter' && target.value) {
92
+ handleSaveItemLabel(event, target.value);
93
+ } else if (event.key === 'Escape') {
94
+ handleCancelItemLabelEditing(event);
95
+ }
96
+ };
65
97
  return (
66
98
  /*#__PURE__*/
67
99
  /* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions -- Key event is handled by the TreeView */
68
100
  _jsxs("div", _extends({}, other, {
69
- className: clsx(className, classes.root, expanded && classes.expanded, selected && classes.selected, focused && classes.focused, disabled && classes.disabled),
101
+ className: clsx(className, classes.root, expanded && classes.expanded, selected && classes.selected, focused && classes.focused, disabled && classes.disabled, editing && classes.editing, editable && classes.editable),
70
102
  onClick: handleClick,
71
103
  onMouseDown: handleMouseDown,
72
104
  ref: ref,
@@ -80,10 +112,17 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
80
112
  disabled: disabled || disableSelection,
81
113
  ref: checkboxRef,
82
114
  tabIndex: -1
83
- }), /*#__PURE__*/_jsx("div", {
84
- className: classes.label,
115
+ }), editing ? /*#__PURE__*/_jsx(TreeItem2LabelInput, _extends({}, labelInputProps, {
116
+ className: classes.labelInput,
117
+ onBlur: handleLabelInputBlur,
118
+ onKeyDown: handleLabelInputKeydown
119
+ })) : /*#__PURE__*/_jsx("div", _extends({
120
+ className: classes.label
121
+ }, editable && {
122
+ onDoubleClick: handleLabelDoubleClick
123
+ }, {
85
124
  children: label
86
- }), dragAndDropOverlayProps && /*#__PURE__*/_jsx(TreeItem2DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
125
+ })), dragAndDropOverlayProps && /*#__PURE__*/_jsx(TreeItem2DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
87
126
  }))
88
127
  );
89
128
  });
@@ -120,6 +159,7 @@ process.env.NODE_ENV !== "production" ? TreeItemContent.propTypes = {
120
159
  /**
121
160
  * The tree item label.
122
161
  */
123
- label: PropTypes.node
162
+ label: PropTypes.node,
163
+ labelInputProps: PropTypes.object
124
164
  } : void 0;
125
165
  export { TreeItemContent };
@@ -19,6 +19,12 @@ export interface TreeItemClasses {
19
19
  label: string;
20
20
  /** Styles applied to the checkbox element. */
21
21
  checkbox: string;
22
+ /** Styles applied to the input element that is visible when editing is enabled. */
23
+ labelInput: string;
24
+ /** Styles applied to the content element when editing is enabled. */
25
+ editing: string;
26
+ /** Styles applied to the content of the items that are editable. */
27
+ editable: string;
22
28
  /** Styles applied to the drag and drop overlay. */
23
29
  dragAndDropOverlay: string;
24
30
  }
@@ -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', 'dragAndDropOverlay']);
6
+ export const treeItemClasses = generateUtilityClasses('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label', 'checkbox', 'labelInput', 'editable', 'editing', 'dragAndDropOverlay']);
@@ -1,9 +1,12 @@
1
1
  import * as React from 'react';
2
+ import { MuiCancellableEvent } from '../internals/models/MuiCancellableEvent';
2
3
  export declare function useTreeItemState(itemId: string): {
3
4
  disabled: boolean;
4
5
  expanded: boolean;
5
6
  selected: boolean;
6
7
  focused: boolean;
8
+ editable: boolean;
9
+ editing: boolean;
7
10
  disableSelection: boolean;
8
11
  checkboxSelection: boolean;
9
12
  handleExpansion: (event: React.MouseEvent<HTMLDivElement>) => void;
@@ -12,4 +15,7 @@ export declare function useTreeItemState(itemId: string): {
12
15
  handleContentClick: ((event: React.MouseEvent, itemId: string) => void) | undefined;
13
16
  preventSelection: (event: React.MouseEvent<HTMLDivElement>) => void;
14
17
  expansionTrigger: "content" | "iconContainer" | undefined;
18
+ toggleItemEditing: () => void;
19
+ handleSaveItemLabel: (event: React.SyntheticEvent & MuiCancellableEvent, label: string) => void;
20
+ handleCancelItemLabelEditing: (event: React.SyntheticEvent) => void;
15
21
  };
@@ -1,4 +1,6 @@
1
1
  import { useTreeViewContext } from '../internals/TreeViewProvider';
2
+ import { useTreeViewLabel } from '../internals/plugins/useTreeViewLabel';
3
+ import { hasPlugin } from '../internals/utils/plugins';
2
4
  export function useTreeItemState(itemId) {
3
5
  const {
4
6
  instance,
@@ -19,6 +21,8 @@ export function useTreeItemState(itemId) {
19
21
  const focused = instance.isItemFocused(itemId);
20
22
  const selected = instance.isItemSelected(itemId);
21
23
  const disabled = instance.isItemDisabled(itemId);
24
+ const editing = instance?.isItemBeingEdited ? instance?.isItemBeingEdited(itemId) : false;
25
+ const editable = instance.isItemEditable ? instance.isItemEditable(itemId) : false;
22
26
  const handleExpansion = event => {
23
27
  if (!disabled) {
24
28
  if (!focused) {
@@ -79,11 +83,49 @@ export function useTreeItemState(itemId) {
79
83
  event.preventDefault();
80
84
  }
81
85
  };
86
+ const toggleItemEditing = () => {
87
+ if (!hasPlugin(instance, useTreeViewLabel)) {
88
+ return;
89
+ }
90
+ if (instance.isItemEditable(itemId)) {
91
+ if (instance.isItemBeingEdited(itemId)) {
92
+ instance.setEditedItemId(null);
93
+ } else {
94
+ instance.setEditedItemId(itemId);
95
+ }
96
+ }
97
+ };
98
+ const handleSaveItemLabel = (event, label) => {
99
+ if (!hasPlugin(instance, useTreeViewLabel)) {
100
+ return;
101
+ }
102
+
103
+ // As a side effect of `instance.focusItem` called here and in `handleCancelItemLabelEditing` the `labelInput` is blurred
104
+ // The `onBlur` event is triggered, which calls `handleSaveItemLabel` again.
105
+ // To avoid creating an unwanted behavior we need to check if the item is being edited before calling `updateItemLabel`
106
+ // using `instance.isItemBeingEditedRef` instead of `instance.isItemBeingEdited` since the state is not yet updated in this point
107
+ if (instance.isItemBeingEditedRef(itemId)) {
108
+ instance.updateItemLabel(itemId, label);
109
+ toggleItemEditing();
110
+ instance.focusItem(event, itemId);
111
+ }
112
+ };
113
+ const handleCancelItemLabelEditing = event => {
114
+ if (!hasPlugin(instance, useTreeViewLabel)) {
115
+ return;
116
+ }
117
+ if (instance.isItemBeingEditedRef(itemId)) {
118
+ toggleItemEditing();
119
+ instance.focusItem(event, itemId);
120
+ }
121
+ };
82
122
  return {
83
123
  disabled,
84
124
  expanded,
85
125
  selected,
86
126
  focused,
127
+ editable,
128
+ editing,
87
129
  disableSelection,
88
130
  checkboxSelection,
89
131
  handleExpansion,
@@ -91,6 +133,9 @@ export function useTreeItemState(itemId) {
91
133
  handleCheckboxSelection,
92
134
  handleContentClick: onItemClick,
93
135
  preventSelection,
94
- expansionTrigger
136
+ expansionTrigger,
137
+ toggleItemEditing,
138
+ handleSaveItemLabel,
139
+ handleCancelItemLabelEditing
95
140
  };
96
141
  }
@@ -7,7 +7,9 @@ export declare const TreeItem2Content: import("@emotion/styled").StyledComponent
7
7
  status: UseTreeItem2Status;
8
8
  indentationAtItemLevel?: true;
9
9
  }, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
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>>, {}>;
10
+ export declare const TreeItem2Label: import("@emotion/styled").StyledComponent<import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme> & {
11
+ editable?: boolean;
12
+ }, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
11
13
  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
14
  export declare const TreeItem2GroupTransition: import("@emotion/styled").StyledComponent<import("@mui/material/Collapse").CollapseProps & import("@mui/system/createStyled").MUIStyledCommonProps<import("@mui/material/styles").Theme> & {
13
15
  indentationAtItemLevel?: true;