@mui/x-tree-view 7.0.0 → 7.1.1
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 +246 -4
- package/README.md +1 -1
- package/RichTreeView/RichTreeView.d.ts +2 -2
- package/RichTreeView/RichTreeView.js +11 -9
- package/SimpleTreeView/SimpleTreeView.js +4 -2
- package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
- package/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/TreeItem/TreeItem.js +4 -4
- package/TreeItem/treeItemClasses.d.ts +1 -1
- package/TreeItem/useTreeItemState.js +9 -9
- package/TreeItem2Icon/TreeItem2Icon.types.d.ts +4 -4
- package/TreeView/TreeView.js +2 -1
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +8 -8
- package/hooks/useTreeViewApiRef.d.ts +1 -1
- package/index.js +1 -1
- package/internals/TreeViewProvider/DescendantProvider.d.ts +1 -1
- package/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/internals/index.d.ts +18 -8
- package/internals/index.js +11 -0
- package/internals/models/plugin.d.ts +1 -1
- package/internals/plugins/defaultPlugins.d.ts +3 -3
- package/internals/plugins/defaultPlugins.js +2 -2
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +32 -18
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +16 -6
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +35 -33
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +17 -9
- package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +6 -6
- package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +1 -1
- package/internals/plugins/useTreeViewItems/index.d.ts +2 -0
- package/internals/plugins/useTreeViewItems/index.js +1 -0
- package/internals/plugins/useTreeViewItems/useTreeViewItems.d.ts +3 -0
- package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +43 -33
- package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +104 -0
- package/internals/plugins/useTreeViewJSXItems/index.d.ts +2 -0
- package/internals/plugins/useTreeViewJSXItems/index.js +1 -0
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.d.ts +3 -0
- package/{modern/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +26 -25
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +18 -0
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +40 -44
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -2
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +34 -34
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +7 -7
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/internals/useTreeView/useTreeView.utils.d.ts +5 -5
- package/internals/useTreeView/useTreeView.utils.js +15 -15
- package/internals/useTreeView/useTreeViewModels.js +2 -2
- package/modern/RichTreeView/RichTreeView.js +11 -9
- package/modern/SimpleTreeView/SimpleTreeView.js +4 -2
- package/modern/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/modern/TreeItem/TreeItem.js +4 -4
- package/modern/TreeItem/useTreeItemState.js +9 -9
- package/modern/TreeView/TreeView.js +2 -1
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +8 -8
- package/modern/index.js +1 -1
- package/modern/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/modern/internals/index.js +11 -0
- package/modern/internals/plugins/defaultPlugins.js +2 -2
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +32 -18
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +35 -33
- package/modern/internals/plugins/useTreeViewItems/index.js +1 -0
- package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +43 -33
- package/modern/internals/plugins/useTreeViewJSXItems/index.js +1 -0
- package/{internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +26 -25
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +40 -44
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +34 -34
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/modern/internals/useTreeView/useTreeView.utils.js +15 -15
- package/modern/internals/useTreeView/useTreeViewModels.js +2 -2
- package/node/RichTreeView/RichTreeView.js +11 -9
- package/node/SimpleTreeView/SimpleTreeView.js +4 -2
- package/node/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/node/TreeItem/TreeItem.js +4 -4
- package/node/TreeItem/useTreeItemState.js +9 -9
- package/node/TreeView/TreeView.js +2 -1
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +8 -8
- package/node/index.js +1 -1
- package/node/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/node/internals/index.js +70 -0
- package/node/internals/plugins/defaultPlugins.js +2 -2
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +31 -17
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +35 -33
- package/node/internals/plugins/useTreeViewItems/index.js +12 -0
- package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +45 -35
- package/node/internals/plugins/useTreeViewJSXItems/index.js +12 -0
- package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.js → useTreeViewJSXItems/useTreeViewJSXItems.js} +28 -27
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +39 -43
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +33 -33
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/node/internals/useTreeView/useTreeView.utils.js +20 -20
- package/node/internals/useTreeView/useTreeViewModels.js +2 -2
- package/package.json +2 -2
- package/useTreeItem2/useTreeItem2.d.ts +1 -1
- package/internals/plugins/useTreeViewJSXNodes/index.d.ts +0 -2
- package/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
- package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.d.ts +0 -3
- package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.d.ts +0 -18
- package/internals/plugins/useTreeViewNodes/index.d.ts +0 -2
- package/internals/plugins/useTreeViewNodes/index.js +0 -1
- package/internals/plugins/useTreeViewNodes/useTreeViewNodes.d.ts +0 -3
- package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.d.ts +0 -88
- package/modern/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
- package/modern/internals/plugins/useTreeViewNodes/index.js +0 -1
- package/node/internals/plugins/useTreeViewJSXNodes/index.js +0 -12
- package/node/internals/plugins/useTreeViewNodes/index.js +0 -12
- /package/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
- /package/modern/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
- /package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { DefaultizedProps, TreeViewItemRange, TreeViewPluginSignature } from '../../models';
|
|
3
|
-
import {
|
|
3
|
+
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
4
4
|
import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
|
|
5
5
|
export interface UseTreeViewSelectionInstance {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
selectRange: (event: React.SyntheticEvent,
|
|
6
|
+
isItemSelected: (itemId: string) => boolean;
|
|
7
|
+
selectItem: (event: React.SyntheticEvent, itemId: string, multiple?: boolean) => void;
|
|
8
|
+
selectRange: (event: React.SyntheticEvent, items: TreeViewItemRange, stacked?: boolean) => void;
|
|
9
9
|
rangeSelectToFirst: (event: React.KeyboardEvent, itemId: string) => void;
|
|
10
10
|
rangeSelectToLast: (event: React.KeyboardEvent, itemId: string) => void;
|
|
11
11
|
}
|
|
@@ -58,9 +58,9 @@ export type UseTreeViewSelectionSignature = TreeViewPluginSignature<{
|
|
|
58
58
|
contextValue: UseTreeViewSelectionContextValue;
|
|
59
59
|
modelNames: 'selectedItems';
|
|
60
60
|
dependantPlugins: [
|
|
61
|
-
|
|
61
|
+
UseTreeViewItemsSignature,
|
|
62
62
|
UseTreeViewExpansionSignature,
|
|
63
|
-
|
|
63
|
+
UseTreeViewItemsSignature
|
|
64
64
|
];
|
|
65
65
|
}>;
|
|
66
66
|
export {};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { TreeViewInstance } from '../../models';
|
|
2
|
-
import {
|
|
2
|
+
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
3
3
|
/**
|
|
4
4
|
* This is used to determine the start and end of a selection range so
|
|
5
|
-
* we can get the
|
|
5
|
+
* we can get the items between the two border items.
|
|
6
6
|
*
|
|
7
|
-
* It finds the
|
|
7
|
+
* It finds the items' common ancestor using
|
|
8
8
|
* a naive implementation of a lowest common ancestor algorithm
|
|
9
9
|
* (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
|
|
10
|
-
* Then compares the ancestor's 2 children that are ancestors of
|
|
11
|
-
* so we can compare their indexes to work out which
|
|
10
|
+
* Then compares the ancestor's 2 children that are ancestors of itemA and ItemB
|
|
11
|
+
* so we can compare their indexes to work out which item comes first in a depth first search.
|
|
12
12
|
* (https://en.wikipedia.org/wiki/Depth-first_search)
|
|
13
13
|
*
|
|
14
|
-
* Another way to put it is which
|
|
14
|
+
* Another way to put it is which item is shallower in a trémaux tree
|
|
15
15
|
* https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
|
|
16
16
|
*/
|
|
17
|
-
export declare const findOrderInTremauxTree: (instance: TreeViewInstance<[
|
|
17
|
+
export declare const findOrderInTremauxTree: (instance: TreeViewInstance<[UseTreeViewItemsSignature]>, nodeAId: string, nodeBId: string) => string[];
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This is used to determine the start and end of a selection range so
|
|
3
|
-
* we can get the
|
|
3
|
+
* we can get the items between the two border items.
|
|
4
4
|
*
|
|
5
|
-
* It finds the
|
|
5
|
+
* It finds the items' common ancestor using
|
|
6
6
|
* a naive implementation of a lowest common ancestor algorithm
|
|
7
7
|
* (https://en.wikipedia.org/wiki/Lowest_common_ancestor).
|
|
8
|
-
* Then compares the ancestor's 2 children that are ancestors of
|
|
9
|
-
* so we can compare their indexes to work out which
|
|
8
|
+
* Then compares the ancestor's 2 children that are ancestors of itemA and ItemB
|
|
9
|
+
* so we can compare their indexes to work out which item comes first in a depth first search.
|
|
10
10
|
* (https://en.wikipedia.org/wiki/Depth-first_search)
|
|
11
11
|
*
|
|
12
|
-
* Another way to put it is which
|
|
12
|
+
* Another way to put it is which item is shallower in a trémaux tree
|
|
13
13
|
* https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree
|
|
14
14
|
*/
|
|
15
15
|
export const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { TreeViewAnyPluginSignature, TreeViewInstance, TreeViewUsedInstance, TreeViewUsedPublicAPI } from '../models';
|
|
2
2
|
import type { UseTreeViewExpansionSignature } from '../plugins/useTreeViewExpansion';
|
|
3
|
-
import type {
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
3
|
+
import type { UseTreeViewItemsSignature } from '../plugins/useTreeViewItems';
|
|
4
|
+
export declare const getPreviousItem: (instance: TreeViewInstance<[UseTreeViewItemsSignature, UseTreeViewExpansionSignature]>, itemId: string) => string | null;
|
|
5
|
+
export declare const getNextItem: (instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewItemsSignature]>, itemId: string) => string | null;
|
|
6
|
+
export declare const getLastItem: (instance: TreeViewInstance<[UseTreeViewExpansionSignature, UseTreeViewItemsSignature]>) => string;
|
|
7
|
+
export declare const getFirstItem: (instance: TreeViewInstance<[UseTreeViewItemsSignature]>) => string;
|
|
8
8
|
export declare const populateInstance: <T extends TreeViewAnyPluginSignature>(instance: TreeViewUsedInstance<T>, methods: T["instance"]) => void;
|
|
9
9
|
export declare const populatePublicAPI: <T extends TreeViewAnyPluginSignature>(publicAPI: TreeViewUsedPublicAPI<T>, methods: T["publicAPI"]) => void;
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
export const
|
|
2
|
-
const
|
|
3
|
-
const siblings = instance.getNavigableChildrenIds(
|
|
1
|
+
export const getPreviousItem = (instance, itemId) => {
|
|
2
|
+
const node = instance.getNode(itemId);
|
|
3
|
+
const siblings = instance.getNavigableChildrenIds(node.parentId);
|
|
4
4
|
const itemIndex = siblings.indexOf(itemId);
|
|
5
5
|
if (itemIndex === 0) {
|
|
6
|
-
return
|
|
6
|
+
return node.parentId;
|
|
7
7
|
}
|
|
8
8
|
let currentItem = siblings[itemIndex - 1];
|
|
9
|
-
while (instance.
|
|
9
|
+
while (instance.isItemExpanded(currentItem) && instance.getNavigableChildrenIds(currentItem).length > 0) {
|
|
10
10
|
currentItem = instance.getNavigableChildrenIds(currentItem).pop();
|
|
11
11
|
}
|
|
12
12
|
return currentItem;
|
|
13
13
|
};
|
|
14
|
-
export const
|
|
14
|
+
export const getNextItem = (instance, itemId) => {
|
|
15
15
|
// If expanded get first child
|
|
16
|
-
if (instance.
|
|
16
|
+
if (instance.isItemExpanded(itemId) && instance.getNavigableChildrenIds(itemId).length > 0) {
|
|
17
17
|
return instance.getNavigableChildrenIds(itemId)[0];
|
|
18
18
|
}
|
|
19
|
-
let
|
|
20
|
-
while (
|
|
19
|
+
let node = instance.getNode(itemId);
|
|
20
|
+
while (node != null) {
|
|
21
21
|
// Try to get next sibling
|
|
22
|
-
const siblings = instance.getNavigableChildrenIds(
|
|
23
|
-
const nextSibling = siblings[siblings.indexOf(
|
|
22
|
+
const siblings = instance.getNavigableChildrenIds(node.parentId);
|
|
23
|
+
const nextSibling = siblings[siblings.indexOf(node.id) + 1];
|
|
24
24
|
if (nextSibling) {
|
|
25
25
|
return nextSibling;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// If the sibling does not exist, go up a level to the parent and try again.
|
|
29
|
-
|
|
29
|
+
node = instance.getNode(node.parentId);
|
|
30
30
|
}
|
|
31
31
|
return null;
|
|
32
32
|
};
|
|
33
|
-
export const
|
|
33
|
+
export const getLastItem = instance => {
|
|
34
34
|
let lastItem = instance.getNavigableChildrenIds(null).pop();
|
|
35
|
-
while (instance.
|
|
35
|
+
while (instance.isItemExpanded(lastItem)) {
|
|
36
36
|
lastItem = instance.getNavigableChildrenIds(lastItem).pop();
|
|
37
37
|
}
|
|
38
38
|
return lastItem;
|
|
39
39
|
};
|
|
40
|
-
export const
|
|
40
|
+
export const getFirstItem = instance => instance.getNavigableChildrenIds(null)[0];
|
|
41
41
|
export const populateInstance = (instance, methods) => {
|
|
42
42
|
Object.assign(instance, methods);
|
|
43
43
|
};
|
|
@@ -22,7 +22,7 @@ export const useTreeViewModels = (plugins, props) => {
|
|
|
22
22
|
return initialState;
|
|
23
23
|
});
|
|
24
24
|
const models = Object.fromEntries(Object.entries(modelsRef.current).map(([modelName, model]) => {
|
|
25
|
-
const value =
|
|
25
|
+
const value = props[modelName] ?? modelsState[modelName];
|
|
26
26
|
return [modelName, {
|
|
27
27
|
value,
|
|
28
28
|
setControlledValue: newValue => {
|
|
@@ -53,7 +53,7 @@ export const useTreeViewModels = (plugins, props) => {
|
|
|
53
53
|
if (!model.isControlled && defaultValue !== newDefaultValue) {
|
|
54
54
|
console.error([`MUI X: A component is changing the default ${modelName} state of an uncontrolled TreeView after being initialized. ` + `To suppress this warning opt to use a controlled TreeView.`].join('\n'));
|
|
55
55
|
}
|
|
56
|
-
}, [JSON.stringify(
|
|
56
|
+
}, [JSON.stringify(newDefaultValue)]);
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
/* eslint-enable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */
|
|
@@ -29,7 +29,8 @@ export const RichTreeViewRoot = styled('ul', {
|
|
|
29
29
|
padding: 0,
|
|
30
30
|
margin: 0,
|
|
31
31
|
listStyle: 'none',
|
|
32
|
-
outline: 0
|
|
32
|
+
outline: 0,
|
|
33
|
+
position: 'relative'
|
|
33
34
|
});
|
|
34
35
|
function WrappedTreeItem({
|
|
35
36
|
slots,
|
|
@@ -104,8 +105,8 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
|
|
|
104
105
|
getSlotProps: getRootProps,
|
|
105
106
|
ownerState: props
|
|
106
107
|
});
|
|
107
|
-
const
|
|
108
|
-
const
|
|
108
|
+
const itemsToRender = instance.getItemsToRender();
|
|
109
|
+
const renderItem = ({
|
|
109
110
|
label,
|
|
110
111
|
itemId,
|
|
111
112
|
id,
|
|
@@ -117,13 +118,13 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
|
|
|
117
118
|
label: label,
|
|
118
119
|
id: id,
|
|
119
120
|
itemId: itemId,
|
|
120
|
-
children: children?.map(
|
|
121
|
+
children: children?.map(renderItem)
|
|
121
122
|
}, itemId);
|
|
122
123
|
};
|
|
123
124
|
return /*#__PURE__*/_jsx(TreeViewProvider, {
|
|
124
125
|
value: contextValue,
|
|
125
126
|
children: /*#__PURE__*/_jsx(Root, _extends({}, rootProps, {
|
|
126
|
-
children:
|
|
127
|
+
children: itemsToRender.map(renderItem)
|
|
127
128
|
}))
|
|
128
129
|
});
|
|
129
130
|
});
|
|
@@ -138,7 +139,8 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
138
139
|
apiRef: PropTypes.shape({
|
|
139
140
|
current: PropTypes.shape({
|
|
140
141
|
focusItem: PropTypes.func.isRequired,
|
|
141
|
-
getItem: PropTypes.func.isRequired
|
|
142
|
+
getItem: PropTypes.func.isRequired,
|
|
143
|
+
setItemExpansion: PropTypes.func.isRequired
|
|
142
144
|
})
|
|
143
145
|
}),
|
|
144
146
|
/**
|
|
@@ -174,12 +176,12 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
174
176
|
*/
|
|
175
177
|
expandedItems: PropTypes.arrayOf(PropTypes.string),
|
|
176
178
|
/**
|
|
177
|
-
* Used to determine the
|
|
179
|
+
* Used to determine the id of a given item.
|
|
178
180
|
*
|
|
179
181
|
* @template R
|
|
180
182
|
* @param {R} item The item to check.
|
|
181
183
|
* @returns {string} The id of the item.
|
|
182
|
-
* @default
|
|
184
|
+
* @default (item) => item.id
|
|
183
185
|
*/
|
|
184
186
|
getItemId: PropTypes.func,
|
|
185
187
|
/**
|
|
@@ -188,7 +190,7 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
188
190
|
* @template R
|
|
189
191
|
* @param {R} item The item to check.
|
|
190
192
|
* @returns {string} The label of the item.
|
|
191
|
-
* @default
|
|
193
|
+
* @default (item) => item.label
|
|
192
194
|
*/
|
|
193
195
|
getItemLabel: PropTypes.func,
|
|
194
196
|
/**
|
|
@@ -28,7 +28,8 @@ export const SimpleTreeViewRoot = styled('ul', {
|
|
|
28
28
|
padding: 0,
|
|
29
29
|
margin: 0,
|
|
30
30
|
listStyle: 'none',
|
|
31
|
-
outline: 0
|
|
31
|
+
outline: 0,
|
|
32
|
+
position: 'relative'
|
|
32
33
|
});
|
|
33
34
|
const EMPTY_ITEMS = [];
|
|
34
35
|
const itemsPropWarning = buildWarning(['MUI X: The `SimpleTreeView` component does not support the `items` prop.', 'If you want to add items, you need to pass them as JSX children.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/simple-tree-view/items/']);
|
|
@@ -96,7 +97,8 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
|
|
|
96
97
|
apiRef: PropTypes.shape({
|
|
97
98
|
current: PropTypes.shape({
|
|
98
99
|
focusItem: PropTypes.func.isRequired,
|
|
99
|
-
getItem: PropTypes.func.isRequired
|
|
100
|
+
getItem: PropTypes.func.isRequired,
|
|
101
|
+
setItemExpansion: PropTypes.func.isRequired
|
|
100
102
|
})
|
|
101
103
|
}),
|
|
102
104
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_TREE_VIEW_PLUGINS } from '../internals/plugins/defaultPlugins';
|
|
2
|
-
import {
|
|
3
|
-
export const SIMPLE_TREE_VIEW_PLUGINS = [...DEFAULT_TREE_VIEW_PLUGINS,
|
|
2
|
+
import { useTreeViewJSXItems } from '../internals/plugins/useTreeViewJSXItems';
|
|
3
|
+
export const SIMPLE_TREE_VIEW_PLUGINS = [...DEFAULT_TREE_VIEW_PLUGINS, useTreeViewJSXItems];
|
|
4
4
|
|
|
5
5
|
// We can't infer this type from the plugin, otherwise we would lose the generics.
|
|
@@ -186,10 +186,10 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
|
|
|
186
186
|
return Boolean(reactChildren);
|
|
187
187
|
};
|
|
188
188
|
const expandable = isExpandable(children);
|
|
189
|
-
const expanded = instance.
|
|
190
|
-
const focused = instance.
|
|
191
|
-
const selected = instance.
|
|
192
|
-
const disabled = instance.
|
|
189
|
+
const expanded = instance.isItemExpanded(itemId);
|
|
190
|
+
const focused = instance.isItemFocused(itemId);
|
|
191
|
+
const selected = instance.isItemSelected(itemId);
|
|
192
|
+
const disabled = instance.isItemDisabled(itemId);
|
|
193
193
|
const ownerState = _extends({}, props, {
|
|
194
194
|
expanded,
|
|
195
195
|
focused,
|
|
@@ -6,11 +6,11 @@ export function useTreeItemState(itemId) {
|
|
|
6
6
|
multiSelect
|
|
7
7
|
}
|
|
8
8
|
} = useTreeViewContext();
|
|
9
|
-
const expandable = instance.
|
|
10
|
-
const expanded = instance.
|
|
11
|
-
const focused = instance.
|
|
12
|
-
const selected = instance.
|
|
13
|
-
const disabled = instance.
|
|
9
|
+
const expandable = instance.isItemExpandable(itemId);
|
|
10
|
+
const expanded = instance.isItemExpanded(itemId);
|
|
11
|
+
const focused = instance.isItemFocused(itemId);
|
|
12
|
+
const selected = instance.isItemSelected(itemId);
|
|
13
|
+
const disabled = instance.isItemDisabled(itemId);
|
|
14
14
|
const handleExpansion = event => {
|
|
15
15
|
if (!disabled) {
|
|
16
16
|
if (!focused) {
|
|
@@ -19,8 +19,8 @@ export function useTreeItemState(itemId) {
|
|
|
19
19
|
const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
|
|
20
20
|
|
|
21
21
|
// If already expanded and trying to toggle selection don't close
|
|
22
|
-
if (expandable && !(multiple && instance.
|
|
23
|
-
instance.
|
|
22
|
+
if (expandable && !(multiple && instance.isItemExpanded(itemId))) {
|
|
23
|
+
instance.toggleItemExpansion(event, itemId);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
};
|
|
@@ -36,10 +36,10 @@ export function useTreeItemState(itemId) {
|
|
|
36
36
|
end: itemId
|
|
37
37
|
});
|
|
38
38
|
} else {
|
|
39
|
-
instance.
|
|
39
|
+
instance.selectItem(event, itemId, true);
|
|
40
40
|
}
|
|
41
41
|
} else {
|
|
42
|
-
instance.
|
|
42
|
+
instance.selectItem(event, itemId);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
};
|
|
@@ -70,7 +70,8 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
|
|
|
70
70
|
apiRef: PropTypes.shape({
|
|
71
71
|
current: PropTypes.shape({
|
|
72
72
|
focusItem: PropTypes.func.isRequired,
|
|
73
|
-
getItem: PropTypes.func.isRequired
|
|
73
|
+
getItem: PropTypes.func.isRequired,
|
|
74
|
+
setItemExpansion: PropTypes.func.isRequired
|
|
74
75
|
})
|
|
75
76
|
}),
|
|
76
77
|
/**
|
|
@@ -11,10 +11,10 @@ export const useTreeItem2Utils = ({
|
|
|
11
11
|
} = useTreeViewContext();
|
|
12
12
|
const status = {
|
|
13
13
|
expandable: Boolean(Array.isArray(children) ? children.length : children),
|
|
14
|
-
expanded: instance.
|
|
15
|
-
focused: instance.
|
|
16
|
-
selected: instance.
|
|
17
|
-
disabled: instance.
|
|
14
|
+
expanded: instance.isItemExpanded(itemId),
|
|
15
|
+
focused: instance.isItemFocused(itemId),
|
|
16
|
+
selected: instance.isItemSelected(itemId),
|
|
17
|
+
disabled: instance.isItemDisabled(itemId)
|
|
18
18
|
};
|
|
19
19
|
const handleExpansion = event => {
|
|
20
20
|
if (status.disabled) {
|
|
@@ -26,8 +26,8 @@ export const useTreeItem2Utils = ({
|
|
|
26
26
|
const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
|
|
27
27
|
|
|
28
28
|
// If already expanded and trying to toggle selection don't close
|
|
29
|
-
if (status.expandable && !(multiple && instance.
|
|
30
|
-
instance.
|
|
29
|
+
if (status.expandable && !(multiple && instance.isItemExpanded(itemId))) {
|
|
30
|
+
instance.toggleItemExpansion(event, itemId);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
const handleSelection = event => {
|
|
@@ -44,10 +44,10 @@ export const useTreeItem2Utils = ({
|
|
|
44
44
|
end: itemId
|
|
45
45
|
});
|
|
46
46
|
} else {
|
|
47
|
-
instance.
|
|
47
|
+
instance.selectItem(event, itemId, true);
|
|
48
48
|
}
|
|
49
49
|
} else {
|
|
50
|
-
instance.
|
|
50
|
+
instance.selectItem(event, itemId);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
const interactions = {
|
package/modern/index.js
CHANGED
|
@@ -46,7 +46,7 @@ const noop = () => {};
|
|
|
46
46
|
* We use this for focus management, keyboard navigation, and typeahead
|
|
47
47
|
* functionality for some components.
|
|
48
48
|
*
|
|
49
|
-
* The hook accepts the element
|
|
49
|
+
* The hook accepts the element item
|
|
50
50
|
*
|
|
51
51
|
* Our main goals with this are:
|
|
52
52
|
* 1) maximum composability,
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export { useTreeView } from './useTreeView';
|
|
2
2
|
export { TreeViewProvider } from './TreeViewProvider';
|
|
3
|
+
export { unstable_resetCleanupTracking } from './hooks/useInstanceEventHandler';
|
|
4
|
+
// Plugins
|
|
3
5
|
export { DEFAULT_TREE_VIEW_PLUGINS } from './plugins/defaultPlugins';
|
|
6
|
+
export { useTreeViewExpansion } from './plugins/useTreeViewExpansion';
|
|
7
|
+
export { useTreeViewSelection } from './plugins/useTreeViewSelection';
|
|
8
|
+
export { useTreeViewFocus } from './plugins/useTreeViewFocus';
|
|
9
|
+
export { useTreeViewKeyboardNavigation } from './plugins/useTreeViewKeyboardNavigation';
|
|
10
|
+
export { useTreeViewId } from './plugins/useTreeViewId';
|
|
11
|
+
export { useTreeViewIcons } from './plugins/useTreeViewIcons';
|
|
12
|
+
export { useTreeViewItems } from './plugins/useTreeViewItems';
|
|
13
|
+
export { useTreeViewJSXItems } from './plugins/useTreeViewJSXItems';
|
|
14
|
+
export { buildWarning } from './utils/warning';
|
|
4
15
|
export { extractPluginParamsFromProps } from './utils/extractPluginParamsFromProps';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useTreeViewId } from './useTreeViewId';
|
|
2
|
-
import {
|
|
2
|
+
import { useTreeViewItems } from './useTreeViewItems';
|
|
3
3
|
import { useTreeViewExpansion } from './useTreeViewExpansion';
|
|
4
4
|
import { useTreeViewSelection } from './useTreeViewSelection';
|
|
5
5
|
import { useTreeViewFocus } from './useTreeViewFocus';
|
|
6
6
|
import { useTreeViewKeyboardNavigation } from './useTreeViewKeyboardNavigation';
|
|
7
7
|
import { useTreeViewIcons } from './useTreeViewIcons';
|
|
8
|
-
export const DEFAULT_TREE_VIEW_PLUGINS = [useTreeViewId,
|
|
8
|
+
export const DEFAULT_TREE_VIEW_PLUGINS = [useTreeViewId, useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
|
|
9
9
|
|
|
10
10
|
// We can't infer this type from the plugin, otherwise we would lose the generics.
|
|
@@ -1,40 +1,50 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import useEventCallback from '@mui/utils/useEventCallback';
|
|
4
|
-
import { populateInstance } from '../../useTreeView/useTreeView.utils';
|
|
4
|
+
import { populateInstance, populatePublicAPI } from '../../useTreeView/useTreeView.utils';
|
|
5
5
|
export const useTreeViewExpansion = ({
|
|
6
6
|
instance,
|
|
7
|
+
publicAPI,
|
|
7
8
|
params,
|
|
8
9
|
models
|
|
9
10
|
}) => {
|
|
11
|
+
const expandedItemsMap = React.useMemo(() => {
|
|
12
|
+
const temp = new Map();
|
|
13
|
+
models.expandedItems.value.forEach(id => {
|
|
14
|
+
temp.set(id, true);
|
|
15
|
+
});
|
|
16
|
+
return temp;
|
|
17
|
+
}, [models.expandedItems.value]);
|
|
10
18
|
const setExpandedItems = (event, value) => {
|
|
11
19
|
params.onExpandedItemsChange?.(event, value);
|
|
12
20
|
models.expandedItems.setControlledValue(value);
|
|
13
21
|
};
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
const isItemExpanded = React.useCallback(itemId => expandedItemsMap.has(itemId), [expandedItemsMap]);
|
|
23
|
+
const isItemExpandable = React.useCallback(itemId => !!instance.getNode(itemId)?.expandable, [instance]);
|
|
24
|
+
const toggleItemExpansion = useEventCallback((event, itemId) => {
|
|
25
|
+
const isExpandedBefore = instance.isItemExpanded(itemId);
|
|
26
|
+
instance.setItemExpansion(event, itemId, !isExpandedBefore);
|
|
27
|
+
});
|
|
28
|
+
const setItemExpansion = useEventCallback((event, itemId, isExpanded) => {
|
|
29
|
+
const isExpandedBefore = instance.isItemExpanded(itemId);
|
|
30
|
+
if (isExpandedBefore === isExpanded) {
|
|
20
31
|
return;
|
|
21
32
|
}
|
|
22
|
-
const isExpandedBefore = models.expandedItems.value.indexOf(itemId) !== -1;
|
|
23
33
|
let newExpanded;
|
|
24
|
-
if (
|
|
25
|
-
newExpanded = models.expandedItems.value.filter(id => id !== itemId);
|
|
26
|
-
} else {
|
|
34
|
+
if (isExpanded) {
|
|
27
35
|
newExpanded = [itemId].concat(models.expandedItems.value);
|
|
36
|
+
} else {
|
|
37
|
+
newExpanded = models.expandedItems.value.filter(id => id !== itemId);
|
|
28
38
|
}
|
|
29
39
|
if (params.onItemExpansionToggle) {
|
|
30
|
-
params.onItemExpansionToggle(event, itemId,
|
|
40
|
+
params.onItemExpansionToggle(event, itemId, isExpanded);
|
|
31
41
|
}
|
|
32
42
|
setExpandedItems(event, newExpanded);
|
|
33
43
|
});
|
|
34
44
|
const expandAllSiblings = (event, itemId) => {
|
|
35
45
|
const node = instance.getNode(itemId);
|
|
36
46
|
const siblings = instance.getChildrenIds(node.parentId);
|
|
37
|
-
const diff = siblings.filter(child => instance.
|
|
47
|
+
const diff = siblings.filter(child => instance.isItemExpandable(child) && !instance.isItemExpanded(child));
|
|
38
48
|
const newExpanded = models.expandedItems.value.concat(diff);
|
|
39
49
|
if (diff.length > 0) {
|
|
40
50
|
if (params.onItemExpansionToggle) {
|
|
@@ -46,20 +56,24 @@ export const useTreeViewExpansion = ({
|
|
|
46
56
|
}
|
|
47
57
|
};
|
|
48
58
|
populateInstance(instance, {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
isItemExpanded,
|
|
60
|
+
isItemExpandable,
|
|
61
|
+
setItemExpansion,
|
|
62
|
+
toggleItemExpansion,
|
|
52
63
|
expandAllSiblings
|
|
53
64
|
});
|
|
65
|
+
populatePublicAPI(publicAPI, {
|
|
66
|
+
setItemExpansion
|
|
67
|
+
});
|
|
54
68
|
};
|
|
55
69
|
useTreeViewExpansion.models = {
|
|
56
70
|
expandedItems: {
|
|
57
71
|
getDefaultValue: params => params.defaultExpandedItems
|
|
58
72
|
}
|
|
59
73
|
};
|
|
60
|
-
const
|
|
74
|
+
const DEFAULT_EXPANDED_ITEMS = [];
|
|
61
75
|
useTreeViewExpansion.getDefaultizedParams = params => _extends({}, params, {
|
|
62
|
-
defaultExpandedItems: params.defaultExpandedItems ??
|
|
76
|
+
defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS
|
|
63
77
|
});
|
|
64
78
|
useTreeViewExpansion.params = {
|
|
65
79
|
expandedItems: true,
|