@mui/x-tree-view 7.12.1 → 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.
- package/CHANGELOG.md +81 -0
- package/RichTreeView/RichTreeView.js +20 -2
- package/RichTreeView/RichTreeView.plugins.d.ts +3 -2
- package/RichTreeView/RichTreeView.plugins.js +2 -1
- package/TreeItem/TreeItem.js +24 -0
- package/TreeItem/TreeItemContent.d.ts +8 -0
- package/TreeItem/TreeItemContent.js +48 -8
- package/TreeItem/treeItemClasses.d.ts +6 -0
- package/TreeItem/treeItemClasses.js +1 -1
- package/TreeItem/useTreeItemState.d.ts +6 -0
- package/TreeItem/useTreeItemState.js +46 -1
- package/TreeItem2/TreeItem2.d.ts +3 -1
- package/TreeItem2/TreeItem2.js +29 -5
- package/TreeItem2/TreeItem2.types.d.ts +6 -0
- package/TreeItem2Icon/TreeItem2Icon.js +2 -0
- package/TreeItem2LabelInput/TreeItem2LabelInput.d.ts +2 -0
- package/TreeItem2LabelInput/TreeItem2LabelInput.js +20 -0
- package/TreeItem2LabelInput/TreeItem2LabelInput.types.d.ts +8 -0
- package/TreeItem2LabelInput/TreeItem2LabelInput.types.js +1 -0
- package/TreeItem2LabelInput/index.d.ts +2 -0
- package/TreeItem2LabelInput/index.js +1 -0
- package/TreeItem2LabelInput/package.json +6 -0
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +5 -1
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +45 -2
- package/hooks/useTreeViewApiRef.d.ts +1 -1
- package/index.js +1 -1
- package/internals/index.d.ts +2 -0
- package/internals/index.js +1 -0
- package/internals/models/itemPlugin.d.ts +2 -1
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +4 -1
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +2 -0
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +5 -1
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -0
- package/internals/plugins/useTreeViewLabel/index.d.ts +2 -0
- package/internals/plugins/useTreeViewLabel/index.js +1 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.d.ts +3 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.d.ts +3 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +44 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +81 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +75 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.js +1 -0
- package/modern/RichTreeView/RichTreeView.js +20 -2
- package/modern/RichTreeView/RichTreeView.plugins.js +2 -1
- package/modern/TreeItem/TreeItem.js +24 -0
- package/modern/TreeItem/TreeItemContent.js +48 -8
- package/modern/TreeItem/treeItemClasses.js +1 -1
- package/modern/TreeItem/useTreeItemState.js +46 -1
- package/modern/TreeItem2/TreeItem2.js +29 -5
- package/modern/TreeItem2Icon/TreeItem2Icon.js +2 -0
- package/modern/TreeItem2LabelInput/TreeItem2LabelInput.js +20 -0
- package/modern/TreeItem2LabelInput/TreeItem2LabelInput.types.js +1 -0
- package/modern/TreeItem2LabelInput/index.js +1 -0
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +45 -2
- package/modern/index.js +1 -1
- package/modern/internals/index.js +1 -0
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +4 -1
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +5 -1
- package/modern/internals/plugins/useTreeViewLabel/index.js +1 -0
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +44 -0
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +81 -0
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.js +1 -0
- package/modern/useTreeItem2/useTreeItem2.js +65 -4
- package/node/RichTreeView/RichTreeView.js +20 -2
- package/node/RichTreeView/RichTreeView.plugins.js +2 -1
- package/node/TreeItem/TreeItem.js +24 -0
- package/node/TreeItem/TreeItemContent.js +48 -8
- package/node/TreeItem/treeItemClasses.js +1 -1
- package/node/TreeItem/useTreeItemState.js +46 -1
- package/node/TreeItem2/TreeItem2.js +29 -5
- package/node/TreeItem2Icon/TreeItem2Icon.js +2 -0
- package/node/TreeItem2LabelInput/TreeItem2LabelInput.js +26 -0
- package/node/TreeItem2LabelInput/TreeItem2LabelInput.types.js +5 -0
- package/node/TreeItem2LabelInput/index.js +12 -0
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +45 -2
- package/node/index.js +1 -1
- package/node/internals/index.js +7 -0
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +4 -1
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +5 -1
- package/node/internals/plugins/useTreeViewLabel/index.js +12 -0
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +54 -0
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +91 -0
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.js +5 -0
- package/node/useTreeItem2/useTreeItem2.js +65 -4
- package/package.json +2 -2
- package/useTreeItem2/index.d.ts +1 -1
- package/useTreeItem2/useTreeItem2.js +65 -4
- package/useTreeItem2/useTreeItem2.types.d.ts +35 -15
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useTreeItem2Utils = void 0;
|
|
7
7
|
var _TreeViewProvider = require("../../internals/TreeViewProvider");
|
|
8
|
+
var _useTreeViewLabel = require("../../internals/plugins/useTreeViewLabel");
|
|
9
|
+
var _plugins = require("../../internals/utils/plugins");
|
|
8
10
|
const isItemExpandable = reactChildren => {
|
|
9
11
|
if (Array.isArray(reactChildren)) {
|
|
10
12
|
return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
|
|
@@ -35,7 +37,9 @@ const useTreeItem2Utils = ({
|
|
|
35
37
|
expanded: instance.isItemExpanded(itemId),
|
|
36
38
|
focused: instance.isItemFocused(itemId),
|
|
37
39
|
selected: instance.isItemSelected(itemId),
|
|
38
|
-
disabled: instance.isItemDisabled(itemId)
|
|
40
|
+
disabled: instance.isItemDisabled(itemId),
|
|
41
|
+
editing: instance?.isItemBeingEdited ? instance?.isItemBeingEdited(itemId) : false,
|
|
42
|
+
editable: instance.isItemEditable ? instance.isItemEditable(itemId) : false
|
|
39
43
|
};
|
|
40
44
|
const handleExpansion = event => {
|
|
41
45
|
if (status.disabled) {
|
|
@@ -90,10 +94,49 @@ const useTreeItem2Utils = ({
|
|
|
90
94
|
});
|
|
91
95
|
}
|
|
92
96
|
};
|
|
97
|
+
const toggleItemEditing = () => {
|
|
98
|
+
if (!(0, _plugins.hasPlugin)(instance, _useTreeViewLabel.useTreeViewLabel)) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (instance.isItemEditable(itemId)) {
|
|
102
|
+
if (instance.isItemBeingEdited(itemId)) {
|
|
103
|
+
instance.setEditedItemId(null);
|
|
104
|
+
} else {
|
|
105
|
+
instance.setEditedItemId(itemId);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const handleSaveItemLabel = (event, label) => {
|
|
110
|
+
if (!(0, _plugins.hasPlugin)(instance, _useTreeViewLabel.useTreeViewLabel)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// As a side effect of `instance.focusItem` called here and in `handleCancelItemLabelEditing` the `labelInput` is blurred
|
|
115
|
+
// The `onBlur` event is triggered, which calls `handleSaveItemLabel` again.
|
|
116
|
+
// To avoid creating an unwanted behavior we need to check if the item is being edited before calling `updateItemLabel`
|
|
117
|
+
// using `instance.isItemBeingEditedRef` instead of `instance.isItemBeingEdited` since the state is not yet updated in this point
|
|
118
|
+
if (instance.isItemBeingEditedRef(itemId)) {
|
|
119
|
+
instance.updateItemLabel(itemId, label);
|
|
120
|
+
toggleItemEditing();
|
|
121
|
+
instance.focusItem(event, itemId);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const handleCancelItemLabelEditing = event => {
|
|
125
|
+
if (!(0, _plugins.hasPlugin)(instance, _useTreeViewLabel.useTreeViewLabel)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (instance.isItemBeingEditedRef(itemId)) {
|
|
129
|
+
toggleItemEditing();
|
|
130
|
+
instance.focusItem(event, itemId);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
93
133
|
const interactions = {
|
|
94
134
|
handleExpansion,
|
|
95
135
|
handleSelection,
|
|
96
|
-
handleCheckboxSelection
|
|
136
|
+
handleCheckboxSelection,
|
|
137
|
+
toggleItemEditing,
|
|
138
|
+
handleSaveItemLabel,
|
|
139
|
+
handleCancelItemLabelEditing
|
|
97
140
|
};
|
|
98
141
|
return {
|
|
99
142
|
interactions,
|
package/node/index.js
CHANGED
package/node/internals/index.js
CHANGED
|
@@ -81,6 +81,12 @@ Object.defineProperty(exports, "useTreeViewKeyboardNavigation", {
|
|
|
81
81
|
return _useTreeViewKeyboardNavigation.useTreeViewKeyboardNavigation;
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
|
+
Object.defineProperty(exports, "useTreeViewLabel", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return _useTreeViewLabel.useTreeViewLabel;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
84
90
|
Object.defineProperty(exports, "useTreeViewSelection", {
|
|
85
91
|
enumerable: true,
|
|
86
92
|
get: function () {
|
|
@@ -102,6 +108,7 @@ var _useTreeViewFocus = require("./plugins/useTreeViewFocus");
|
|
|
102
108
|
var _useTreeViewKeyboardNavigation = require("./plugins/useTreeViewKeyboardNavigation");
|
|
103
109
|
var _useTreeViewIcons = require("./plugins/useTreeViewIcons");
|
|
104
110
|
var _useTreeViewItems = require("./plugins/useTreeViewItems");
|
|
111
|
+
var _useTreeViewLabel = require("./plugins/useTreeViewLabel");
|
|
105
112
|
var _useTreeViewJSXItems = require("./plugins/useTreeViewJSXItems");
|
|
106
113
|
var _tree = require("./utils/tree");
|
|
107
114
|
var _warning = require("./utils/warning");
|
|
@@ -66,8 +66,11 @@ const useTreeViewExpansion = ({
|
|
|
66
66
|
if (params.expansionTrigger) {
|
|
67
67
|
return params.expansionTrigger;
|
|
68
68
|
}
|
|
69
|
+
if (instance.isTreeViewEditable) {
|
|
70
|
+
return 'iconContainer';
|
|
71
|
+
}
|
|
69
72
|
return 'content';
|
|
70
|
-
}, [params.expansionTrigger]);
|
|
73
|
+
}, [params.expansionTrigger, instance.isTreeViewEditable]);
|
|
71
74
|
return {
|
|
72
75
|
publicAPI: {
|
|
73
76
|
setItemExpansion
|
package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js
CHANGED
|
@@ -9,6 +9,8 @@ var React = _interopRequireWildcard(require("react"));
|
|
|
9
9
|
var _RtlProvider = require("@mui/system/RtlProvider");
|
|
10
10
|
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
|
|
11
11
|
var _tree = require("../../utils/tree");
|
|
12
|
+
var _plugins = require("../../utils/plugins");
|
|
13
|
+
var _useTreeViewLabel = require("../useTreeViewLabel");
|
|
12
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); }
|
|
13
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; }
|
|
14
16
|
function isPrintableCharacter(string) {
|
|
@@ -98,7 +100,9 @@ const useTreeViewKeyboardNavigation = ({
|
|
|
98
100
|
// If the focused item has no children, we select it.
|
|
99
101
|
case key === 'Enter':
|
|
100
102
|
{
|
|
101
|
-
if (
|
|
103
|
+
if ((0, _plugins.hasPlugin)(instance, _useTreeViewLabel.useTreeViewLabel) && instance.isItemEditable(itemId) && !instance.isItemBeingEdited(itemId)) {
|
|
104
|
+
instance.setEditedItemId(itemId);
|
|
105
|
+
} else if (canToggleItemExpansion(itemId)) {
|
|
102
106
|
instance.toggleItemExpansion(event, itemId);
|
|
103
107
|
event.preventDefault();
|
|
104
108
|
} else if (canToggleItemSelection(itemId)) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "useTreeViewLabel", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _useTreeViewLabel.useTreeViewLabel;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _useTreeViewLabel = require("./useTreeViewLabel");
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useTreeViewLabelItemPlugin = exports.isAndroid = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _TreeViewProvider = require("../../TreeViewProvider");
|
|
9
|
+
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); }
|
|
10
|
+
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; }
|
|
11
|
+
const isAndroid = () => navigator.userAgent.toLowerCase().includes('android');
|
|
12
|
+
exports.isAndroid = isAndroid;
|
|
13
|
+
const useTreeViewLabelItemPlugin = ({
|
|
14
|
+
props
|
|
15
|
+
}) => {
|
|
16
|
+
const {
|
|
17
|
+
instance
|
|
18
|
+
} = (0, _TreeViewProvider.useTreeViewContext)();
|
|
19
|
+
const {
|
|
20
|
+
label,
|
|
21
|
+
itemId
|
|
22
|
+
} = props;
|
|
23
|
+
const [labelInputValue, setLabelInputValue] = React.useState(label);
|
|
24
|
+
const isItemBeingEdited = instance.isItemBeingEdited(itemId);
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
if (!isItemBeingEdited) {
|
|
27
|
+
setLabelInputValue(label);
|
|
28
|
+
}
|
|
29
|
+
}, [isItemBeingEdited, label]);
|
|
30
|
+
return {
|
|
31
|
+
propsEnhancers: {
|
|
32
|
+
labelInput: ({
|
|
33
|
+
externalEventHandlers
|
|
34
|
+
}) => {
|
|
35
|
+
const editable = instance.isItemEditable(itemId);
|
|
36
|
+
if (!editable) {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
const handleInputChange = event => {
|
|
40
|
+
externalEventHandlers.onChange?.(event);
|
|
41
|
+
setLabelInputValue(event.target.value);
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
value: labelInputValue ?? '',
|
|
45
|
+
'data-element': 'labelInput',
|
|
46
|
+
onChange: handleInputChange,
|
|
47
|
+
autoFocus: true,
|
|
48
|
+
type: 'text'
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
exports.useTreeViewLabelItemPlugin = useTreeViewLabelItemPlugin;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useTreeViewLabel = void 0;
|
|
8
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
|
+
var React = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _warning = require("../../utils/warning");
|
|
11
|
+
var _useTreeViewLabel = require("./useTreeViewLabel.itemPlugin");
|
|
12
|
+
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); }
|
|
13
|
+
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; }
|
|
14
|
+
const useTreeViewLabel = ({
|
|
15
|
+
instance,
|
|
16
|
+
state,
|
|
17
|
+
setState,
|
|
18
|
+
params,
|
|
19
|
+
experimentalFeatures
|
|
20
|
+
}) => {
|
|
21
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
22
|
+
if (params.isItemEditable && !experimentalFeatures?.labelEditing) {
|
|
23
|
+
(0, _warning.warnOnce)(['MUI X: The label editing feature requires the `labelEditing` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ labelEditing: true}}` to the `RichTreeViewPro` component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/editing/']);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const editedItemRef = React.useRef(state.editedItemId);
|
|
27
|
+
const isItemBeingEditedRef = itemId => editedItemRef.current === itemId;
|
|
28
|
+
const setEditedItemId = editedItemId => {
|
|
29
|
+
setState(prevState => (0, _extends2.default)({}, prevState, {
|
|
30
|
+
editedItemId
|
|
31
|
+
}));
|
|
32
|
+
editedItemRef.current = editedItemId;
|
|
33
|
+
};
|
|
34
|
+
const isItemBeingEdited = itemId => itemId === state.editedItemId;
|
|
35
|
+
const isTreeViewEditable = Boolean(params.isItemEditable) && !!experimentalFeatures.labelEditing;
|
|
36
|
+
const isItemEditable = itemId => {
|
|
37
|
+
if (itemId == null || !isTreeViewEditable) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const item = instance.getItem(itemId);
|
|
41
|
+
if (!item) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return typeof params.isItemEditable === 'function' ? params.isItemEditable(item) : Boolean(params.isItemEditable);
|
|
45
|
+
};
|
|
46
|
+
const updateItemLabel = (itemId, label) => {
|
|
47
|
+
if (!label) {
|
|
48
|
+
throw new Error(['MUI X: The Tree View component requires all items to have a `label` property.', 'The label of an item cannot be empty.', itemId].join('\n'));
|
|
49
|
+
}
|
|
50
|
+
setState(prevState => {
|
|
51
|
+
const item = prevState.items.itemMetaMap[itemId];
|
|
52
|
+
if (item.label !== label) {
|
|
53
|
+
return (0, _extends2.default)({}, prevState, {
|
|
54
|
+
items: (0, _extends2.default)({}, prevState.items, {
|
|
55
|
+
itemMetaMap: (0, _extends2.default)({}, prevState.items.itemMetaMap, {
|
|
56
|
+
[itemId]: (0, _extends2.default)({}, item, {
|
|
57
|
+
label
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return prevState;
|
|
64
|
+
});
|
|
65
|
+
if (params.onItemLabelChange) {
|
|
66
|
+
params.onItemLabelChange(itemId, label);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
instance: {
|
|
71
|
+
setEditedItemId,
|
|
72
|
+
isItemBeingEdited,
|
|
73
|
+
updateItemLabel,
|
|
74
|
+
isItemEditable,
|
|
75
|
+
isTreeViewEditable,
|
|
76
|
+
isItemBeingEditedRef
|
|
77
|
+
},
|
|
78
|
+
publicAPI: {
|
|
79
|
+
updateItemLabel
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
exports.useTreeViewLabel = useTreeViewLabel;
|
|
84
|
+
useTreeViewLabel.itemPlugin = _useTreeViewLabel.useTreeViewLabelItemPlugin;
|
|
85
|
+
useTreeViewLabel.getInitialState = () => ({
|
|
86
|
+
editedItemId: null
|
|
87
|
+
});
|
|
88
|
+
useTreeViewLabel.params = {
|
|
89
|
+
onItemLabelChange: true,
|
|
90
|
+
isItemEditable: true
|
|
91
|
+
};
|
|
@@ -12,6 +12,7 @@ var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
|
|
|
12
12
|
var _TreeViewProvider = require("../internals/TreeViewProvider");
|
|
13
13
|
var _useTreeItem2Utils = require("../hooks/useTreeItem2Utils");
|
|
14
14
|
var _TreeViewItemDepthContext = require("../internals/TreeViewItemDepthContext");
|
|
15
|
+
var _tree = require("../internals/utils/tree");
|
|
15
16
|
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); }
|
|
16
17
|
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; }
|
|
17
18
|
const useTreeItem2 = parameters => {
|
|
@@ -59,6 +60,7 @@ const useTreeItem2 = parameters => {
|
|
|
59
60
|
const handleRootRef = (0, _useForkRef.default)(rootRef, pluginRootRef, rootRefObject);
|
|
60
61
|
const handleContentRef = (0, _useForkRef.default)(contentRef, contentRefObject);
|
|
61
62
|
const checkboxRef = React.useRef(null);
|
|
63
|
+
const rootTabIndex = instance.canItemBeTabbed(itemId) ? 0 : -1;
|
|
62
64
|
const createRootHandleFocus = otherHandlers => event => {
|
|
63
65
|
otherHandlers.onFocus?.(event);
|
|
64
66
|
if (event.defaultMuiPrevented) {
|
|
@@ -74,15 +76,33 @@ const useTreeItem2 = parameters => {
|
|
|
74
76
|
if (event.defaultMuiPrevented) {
|
|
75
77
|
return;
|
|
76
78
|
}
|
|
79
|
+
const rootElement = instance.getItemDOMElement(itemId);
|
|
80
|
+
|
|
81
|
+
// Don't blur the root when switching to editing mode
|
|
82
|
+
// the input that triggers the root blur can be either the relatedTarget (when entering editing state) or the target (when exiting editing state)
|
|
83
|
+
// when we enter the editing state, we focus the input -> we don't want to remove the focused item from the state
|
|
84
|
+
if (status.editing ||
|
|
85
|
+
// 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
|
|
86
|
+
// 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
|
|
87
|
+
event.relatedTarget && (0, _tree.isTargetInDescendants)(event.relatedTarget, rootElement) && (event.target && event.target?.dataset?.element === 'labelInput' && (0, _tree.isTargetInDescendants)(event.target, rootElement) || event.relatedTarget?.dataset?.element === 'labelInput')) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
77
90
|
instance.removeFocusedItem();
|
|
78
91
|
};
|
|
79
92
|
const createRootHandleKeyDown = otherHandlers => event => {
|
|
80
93
|
otherHandlers.onKeyDown?.(event);
|
|
81
|
-
if (event.defaultMuiPrevented) {
|
|
94
|
+
if (event.defaultMuiPrevented || event.target?.dataset?.element === 'labelInput') {
|
|
82
95
|
return;
|
|
83
96
|
}
|
|
84
97
|
instance.handleItemKeyDown(event, itemId);
|
|
85
98
|
};
|
|
99
|
+
const createLabelHandleDoubleClick = otherHandlers => event => {
|
|
100
|
+
otherHandlers.onDoubleClick?.(event);
|
|
101
|
+
if (event.defaultMuiPrevented) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
interactions.toggleItemEditing();
|
|
105
|
+
};
|
|
86
106
|
const createContentHandleClick = otherHandlers => event => {
|
|
87
107
|
otherHandlers.onClick?.(event);
|
|
88
108
|
onItemClick?.(event, itemId);
|
|
@@ -117,6 +137,27 @@ const useTreeItem2 = parameters => {
|
|
|
117
137
|
}
|
|
118
138
|
interactions.handleCheckboxSelection(event);
|
|
119
139
|
};
|
|
140
|
+
const createInputHandleKeydown = otherHandlers => event => {
|
|
141
|
+
otherHandlers.onKeyDown?.(event);
|
|
142
|
+
if (event.defaultMuiPrevented) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const target = event.target;
|
|
146
|
+
if (event.key === 'Enter' && target.value) {
|
|
147
|
+
interactions.handleSaveItemLabel(event, target.value);
|
|
148
|
+
} else if (event.key === 'Escape') {
|
|
149
|
+
interactions.handleCancelItemLabelEditing(event);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const createInputHandleBlur = otherHandlers => event => {
|
|
153
|
+
otherHandlers.onBlur?.(event);
|
|
154
|
+
if (event.defaultMuiPrevented) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (event.target.value) {
|
|
158
|
+
interactions.handleSaveItemLabel(event, event.target.value);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
120
161
|
const createIconContainerHandleClick = otherHandlers => event => {
|
|
121
162
|
otherHandlers.onClick?.(event);
|
|
122
163
|
if (event.defaultMuiPrevented) {
|
|
@@ -143,7 +184,7 @@ const useTreeItem2 = parameters => {
|
|
|
143
184
|
const props = (0, _extends2.default)({}, externalEventHandlers, {
|
|
144
185
|
ref: handleRootRef,
|
|
145
186
|
role: 'treeitem',
|
|
146
|
-
tabIndex:
|
|
187
|
+
tabIndex: rootTabIndex,
|
|
147
188
|
id: idAttribute,
|
|
148
189
|
'aria-expanded': status.expandable ? status.expanded : undefined,
|
|
149
190
|
'aria-selected': ariaSelected,
|
|
@@ -197,9 +238,28 @@ const useTreeItem2 = parameters => {
|
|
|
197
238
|
};
|
|
198
239
|
const getLabelProps = (externalProps = {}) => {
|
|
199
240
|
const externalEventHandlers = (0, _extends2.default)({}, (0, _extractEventHandlers.default)(externalProps));
|
|
200
|
-
|
|
241
|
+
const props = (0, _extends2.default)({}, externalEventHandlers, {
|
|
201
242
|
children: label
|
|
202
|
-
}, externalProps
|
|
243
|
+
}, externalProps, {
|
|
244
|
+
onDoubleClick: createLabelHandleDoubleClick(externalEventHandlers)
|
|
245
|
+
});
|
|
246
|
+
if (instance.isTreeViewEditable) {
|
|
247
|
+
props.editable = status.editable;
|
|
248
|
+
}
|
|
249
|
+
return props;
|
|
250
|
+
};
|
|
251
|
+
const getLabelInputProps = (externalProps = {}) => {
|
|
252
|
+
const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps);
|
|
253
|
+
const props = (0, _extends2.default)({}, externalEventHandlers, externalProps, {
|
|
254
|
+
onKeyDown: createInputHandleKeydown(externalEventHandlers),
|
|
255
|
+
onBlur: createInputHandleBlur(externalEventHandlers)
|
|
256
|
+
});
|
|
257
|
+
const enhancedlabelInputProps = propsEnhancers.labelInput?.({
|
|
258
|
+
rootRefObject,
|
|
259
|
+
contentRefObject,
|
|
260
|
+
externalEventHandlers
|
|
261
|
+
}) ?? {};
|
|
262
|
+
return (0, _extends2.default)({}, props, enhancedlabelInputProps);
|
|
203
263
|
};
|
|
204
264
|
const getIconContainerProps = (externalProps = {}) => {
|
|
205
265
|
const externalEventHandlers = (0, _extractEventHandlers.default)(externalProps);
|
|
@@ -237,6 +297,7 @@ const useTreeItem2 = parameters => {
|
|
|
237
297
|
getIconContainerProps,
|
|
238
298
|
getCheckboxProps,
|
|
239
299
|
getLabelProps,
|
|
300
|
+
getLabelInputProps,
|
|
240
301
|
getDragAndDropOverlayProps,
|
|
241
302
|
rootRef: handleRootRef,
|
|
242
303
|
status,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/x-tree-view",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.13.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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"clsx": "^2.1.1",
|
|
41
41
|
"prop-types": "^15.8.1",
|
|
42
42
|
"react-transition-group": "^4.4.5",
|
|
43
|
-
"@mui/x-internals": "7.
|
|
43
|
+
"@mui/x-internals": "7.13.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@emotion/react": "^11.9.0",
|
package/useTreeItem2/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { useTreeItem2 as unstable_useTreeItem2 } from './useTreeItem2';
|
|
2
|
-
export type { UseTreeItem2Parameters, UseTreeItem2ReturnValue, UseTreeItem2Status, UseTreeItem2RootSlotOwnProps, UseTreeItem2ContentSlotOwnProps, UseTreeItem2LabelSlotOwnProps, UseTreeItem2IconContainerSlotOwnProps, UseTreeItem2GroupTransitionSlotOwnProps, UseTreeItem2DragAndDropOverlaySlotOwnProps, } from './useTreeItem2.types';
|
|
2
|
+
export type { UseTreeItem2Parameters, UseTreeItem2ReturnValue, UseTreeItem2Status, UseTreeItem2RootSlotOwnProps, UseTreeItem2ContentSlotOwnProps, UseTreeItem2LabelInputSlotOwnProps, UseTreeItem2LabelSlotOwnProps, UseTreeItem2IconContainerSlotOwnProps, UseTreeItem2GroupTransitionSlotOwnProps, UseTreeItem2DragAndDropOverlaySlotOwnProps, } from './useTreeItem2.types';
|
|
@@ -5,6 +5,7 @@ import useForkRef from '@mui/utils/useForkRef';
|
|
|
5
5
|
import { useTreeViewContext } from '../internals/TreeViewProvider';
|
|
6
6
|
import { useTreeItem2Utils } from '../hooks/useTreeItem2Utils';
|
|
7
7
|
import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext';
|
|
8
|
+
import { isTargetInDescendants } from '../internals/utils/tree';
|
|
8
9
|
export const useTreeItem2 = parameters => {
|
|
9
10
|
const {
|
|
10
11
|
runItemPlugins,
|
|
@@ -50,6 +51,7 @@ export const useTreeItem2 = parameters => {
|
|
|
50
51
|
const handleRootRef = useForkRef(rootRef, pluginRootRef, rootRefObject);
|
|
51
52
|
const handleContentRef = useForkRef(contentRef, contentRefObject);
|
|
52
53
|
const checkboxRef = React.useRef(null);
|
|
54
|
+
const rootTabIndex = instance.canItemBeTabbed(itemId) ? 0 : -1;
|
|
53
55
|
const createRootHandleFocus = otherHandlers => event => {
|
|
54
56
|
otherHandlers.onFocus?.(event);
|
|
55
57
|
if (event.defaultMuiPrevented) {
|
|
@@ -65,15 +67,33 @@ export const useTreeItem2 = parameters => {
|
|
|
65
67
|
if (event.defaultMuiPrevented) {
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
70
|
+
const rootElement = instance.getItemDOMElement(itemId);
|
|
71
|
+
|
|
72
|
+
// Don't blur the root when switching to editing mode
|
|
73
|
+
// the input that triggers the root blur can be either the relatedTarget (when entering editing state) or the target (when exiting editing state)
|
|
74
|
+
// when we enter the editing state, we focus the input -> we don't want to remove the focused item from the state
|
|
75
|
+
if (status.editing ||
|
|
76
|
+
// 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
|
|
77
|
+
// 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
|
|
78
|
+
event.relatedTarget && isTargetInDescendants(event.relatedTarget, rootElement) && (event.target && event.target?.dataset?.element === 'labelInput' && isTargetInDescendants(event.target, rootElement) || event.relatedTarget?.dataset?.element === 'labelInput')) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
68
81
|
instance.removeFocusedItem();
|
|
69
82
|
};
|
|
70
83
|
const createRootHandleKeyDown = otherHandlers => event => {
|
|
71
84
|
otherHandlers.onKeyDown?.(event);
|
|
72
|
-
if (event.defaultMuiPrevented) {
|
|
85
|
+
if (event.defaultMuiPrevented || event.target?.dataset?.element === 'labelInput') {
|
|
73
86
|
return;
|
|
74
87
|
}
|
|
75
88
|
instance.handleItemKeyDown(event, itemId);
|
|
76
89
|
};
|
|
90
|
+
const createLabelHandleDoubleClick = otherHandlers => event => {
|
|
91
|
+
otherHandlers.onDoubleClick?.(event);
|
|
92
|
+
if (event.defaultMuiPrevented) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
interactions.toggleItemEditing();
|
|
96
|
+
};
|
|
77
97
|
const createContentHandleClick = otherHandlers => event => {
|
|
78
98
|
otherHandlers.onClick?.(event);
|
|
79
99
|
onItemClick?.(event, itemId);
|
|
@@ -108,6 +128,27 @@ export const useTreeItem2 = parameters => {
|
|
|
108
128
|
}
|
|
109
129
|
interactions.handleCheckboxSelection(event);
|
|
110
130
|
};
|
|
131
|
+
const createInputHandleKeydown = otherHandlers => event => {
|
|
132
|
+
otherHandlers.onKeyDown?.(event);
|
|
133
|
+
if (event.defaultMuiPrevented) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const target = event.target;
|
|
137
|
+
if (event.key === 'Enter' && target.value) {
|
|
138
|
+
interactions.handleSaveItemLabel(event, target.value);
|
|
139
|
+
} else if (event.key === 'Escape') {
|
|
140
|
+
interactions.handleCancelItemLabelEditing(event);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const createInputHandleBlur = otherHandlers => event => {
|
|
144
|
+
otherHandlers.onBlur?.(event);
|
|
145
|
+
if (event.defaultMuiPrevented) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (event.target.value) {
|
|
149
|
+
interactions.handleSaveItemLabel(event, event.target.value);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
111
152
|
const createIconContainerHandleClick = otherHandlers => event => {
|
|
112
153
|
otherHandlers.onClick?.(event);
|
|
113
154
|
if (event.defaultMuiPrevented) {
|
|
@@ -134,7 +175,7 @@ export const useTreeItem2 = parameters => {
|
|
|
134
175
|
const props = _extends({}, externalEventHandlers, {
|
|
135
176
|
ref: handleRootRef,
|
|
136
177
|
role: 'treeitem',
|
|
137
|
-
tabIndex:
|
|
178
|
+
tabIndex: rootTabIndex,
|
|
138
179
|
id: idAttribute,
|
|
139
180
|
'aria-expanded': status.expandable ? status.expanded : undefined,
|
|
140
181
|
'aria-selected': ariaSelected,
|
|
@@ -188,9 +229,28 @@ export const useTreeItem2 = parameters => {
|
|
|
188
229
|
};
|
|
189
230
|
const getLabelProps = (externalProps = {}) => {
|
|
190
231
|
const externalEventHandlers = _extends({}, extractEventHandlers(externalProps));
|
|
191
|
-
|
|
232
|
+
const props = _extends({}, externalEventHandlers, {
|
|
192
233
|
children: label
|
|
193
|
-
}, externalProps
|
|
234
|
+
}, externalProps, {
|
|
235
|
+
onDoubleClick: createLabelHandleDoubleClick(externalEventHandlers)
|
|
236
|
+
});
|
|
237
|
+
if (instance.isTreeViewEditable) {
|
|
238
|
+
props.editable = status.editable;
|
|
239
|
+
}
|
|
240
|
+
return props;
|
|
241
|
+
};
|
|
242
|
+
const getLabelInputProps = (externalProps = {}) => {
|
|
243
|
+
const externalEventHandlers = extractEventHandlers(externalProps);
|
|
244
|
+
const props = _extends({}, externalEventHandlers, externalProps, {
|
|
245
|
+
onKeyDown: createInputHandleKeydown(externalEventHandlers),
|
|
246
|
+
onBlur: createInputHandleBlur(externalEventHandlers)
|
|
247
|
+
});
|
|
248
|
+
const enhancedlabelInputProps = propsEnhancers.labelInput?.({
|
|
249
|
+
rootRefObject,
|
|
250
|
+
contentRefObject,
|
|
251
|
+
externalEventHandlers
|
|
252
|
+
}) ?? {};
|
|
253
|
+
return _extends({}, props, enhancedlabelInputProps);
|
|
194
254
|
};
|
|
195
255
|
const getIconContainerProps = (externalProps = {}) => {
|
|
196
256
|
const externalEventHandlers = extractEventHandlers(externalProps);
|
|
@@ -228,6 +288,7 @@ export const useTreeItem2 = parameters => {
|
|
|
228
288
|
getIconContainerProps,
|
|
229
289
|
getCheckboxProps,
|
|
230
290
|
getLabelProps,
|
|
291
|
+
getLabelInputProps,
|
|
231
292
|
getDragAndDropOverlayProps,
|
|
232
293
|
rootRef: handleRootRef,
|
|
233
294
|
status,
|