@mui/x-tree-view 8.0.0-alpha.0 → 8.0.0-alpha.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 +429 -5
- package/README.md +2 -2
- package/RichTreeView/RichTreeView.js +2 -4
- package/RichTreeView/RichTreeView.types.d.ts +3 -16
- package/TreeItem/TreeItem.js +4 -4
- package/TreeItem/TreeItem.types.d.ts +3 -1
- package/TreeItemProvider/TreeItemProvider.js +16 -3
- package/TreeItemProvider/TreeItemProvider.types.d.ts +1 -0
- package/hooks/index.d.ts +1 -0
- package/hooks/index.js +2 -1
- package/hooks/useTreeItemModel.d.ts +2 -0
- package/hooks/useTreeItemModel.js +11 -0
- package/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +2 -1
- package/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
- package/index.js +1 -1
- package/internals/TreeViewItemDepthContext/TreeViewItemDepthContext.d.ts +3 -1
- package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +2 -1
- package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
- package/internals/TreeViewProvider/TreeViewProvider.js +1 -2
- package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +4 -2
- package/internals/components/RichTreeViewItems.d.ts +2 -4
- package/internals/components/RichTreeViewItems.js +42 -30
- package/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
- package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.d.ts +36 -0
- package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
- package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +1 -5
- package/internals/hooks/useSelector.d.ts +4 -0
- package/internals/hooks/useSelector.js +6 -0
- package/internals/index.d.ts +6 -1
- package/internals/index.js +5 -1
- package/internals/models/itemPlugin.d.ts +4 -4
- package/internals/models/plugin.d.ts +19 -7
- package/internals/models/treeView.d.ts +6 -0
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +124 -0
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -14
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.d.ts +1 -0
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.d.ts +182 -0
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +4 -16
- package/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
- package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
- package/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
- package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +718 -0
- package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
- package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +15 -52
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +74 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +7 -24
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +32 -0
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +6 -6
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
- package/internals/useTreeView/useTreeView.js +30 -17
- package/internals/useTreeView/useTreeView.types.d.ts +1 -2
- package/internals/useTreeView/useTreeViewBuildContext.d.ts +3 -1
- package/internals/useTreeView/useTreeViewBuildContext.js +24 -18
- package/internals/utils/TreeViewStore.d.ts +12 -0
- package/internals/utils/TreeViewStore.js +24 -0
- package/internals/utils/selectors.d.ts +9 -0
- package/internals/utils/selectors.js +37 -0
- package/internals/utils/tree.d.ts +8 -8
- package/internals/utils/tree.js +51 -43
- package/models/items.d.ts +3 -2
- package/modern/RichTreeView/RichTreeView.js +2 -4
- package/modern/TreeItem/TreeItem.js +4 -4
- package/modern/TreeItemProvider/TreeItemProvider.js +16 -3
- package/modern/hooks/index.js +2 -1
- package/modern/hooks/useTreeItemModel.js +11 -0
- package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
- package/modern/index.js +1 -1
- package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
- package/modern/internals/TreeViewProvider/TreeViewProvider.js +1 -2
- package/modern/internals/components/RichTreeViewItems.js +42 -30
- package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
- package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
- package/modern/internals/hooks/useSelector.js +6 -0
- package/modern/internals/index.js +5 -1
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
- package/modern/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
- package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
- package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
- package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
- package/modern/internals/useTreeView/useTreeView.js +30 -17
- package/modern/internals/useTreeView/useTreeViewBuildContext.js +24 -18
- package/modern/internals/utils/TreeViewStore.js +24 -0
- package/modern/internals/utils/selectors.js +37 -0
- package/modern/internals/utils/tree.js +51 -43
- package/modern/useTreeItem/useTreeItem.js +26 -11
- package/node/RichTreeView/RichTreeView.js +2 -4
- package/node/TreeItem/TreeItem.js +4 -4
- package/node/TreeItemProvider/TreeItemProvider.js +16 -3
- package/node/hooks/index.js +8 -1
- package/node/hooks/useTreeItemModel.js +17 -0
- package/node/hooks/useTreeItemUtils/useTreeItemUtils.js +32 -15
- package/node/index.js +1 -1
- package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
- package/node/internals/TreeViewProvider/TreeViewProvider.js +1 -2
- package/node/internals/components/RichTreeViewItems.js +42 -30
- package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +12 -13
- package/node/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +15 -0
- package/node/internals/hooks/useSelector.js +13 -0
- package/node/internals/index.js +47 -1
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +23 -0
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +14 -0
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +40 -0
- package/node/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +16 -13
- package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -100
- package/node/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +109 -0
- package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +30 -27
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +32 -0
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +46 -35
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +15 -0
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +24 -14
- package/node/internals/useTreeView/useTreeView.js +30 -17
- package/node/internals/useTreeView/useTreeViewBuildContext.js +25 -18
- package/node/internals/utils/TreeViewStore.js +31 -0
- package/node/internals/utils/selectors.js +44 -0
- package/node/internals/utils/tree.js +51 -43
- package/node/useTreeItem/useTreeItem.js +26 -11
- package/package.json +6 -4
- package/useTreeItem/useTreeItem.js +26 -11
- package/useTreeItem/useTreeItem.types.d.ts +9 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { UseTreeViewFocusSignature } from './useTreeViewFocus.types';
|
|
2
|
+
import { TreeViewRootSelector } from '../../utils/selectors';
|
|
3
|
+
/**
|
|
4
|
+
* Get the item that should be sequentially focusable (usually with the Tab key).
|
|
5
|
+
* At any point in time, there is a single item that can be sequentially focused in the Tree View.
|
|
6
|
+
* This item is the first selected item (that is both visible and navigable), if any, or the first navigable item if no item is selected.
|
|
7
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
8
|
+
* @returns {TreeViewItemId | null} The id of the item that should be sequentially focusable.
|
|
9
|
+
*/
|
|
10
|
+
export declare const selectorDefaultFocusableItemId: ((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
|
|
11
|
+
cacheKey: import("../../models").TreeViewStateCacheKey;
|
|
12
|
+
}) => string | null) & {
|
|
13
|
+
clearCache: () => void;
|
|
14
|
+
resultsCount: () => number;
|
|
15
|
+
resetResultsCount: () => void;
|
|
16
|
+
} & {
|
|
17
|
+
resultFunc: (resultFuncArgs_0: {
|
|
18
|
+
focusedItemId: string | null;
|
|
19
|
+
defaultFocusableItemId: string | null;
|
|
20
|
+
}) => string | null;
|
|
21
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
22
|
+
focusedItemId: string | null;
|
|
23
|
+
defaultFocusableItemId: string | null;
|
|
24
|
+
}) => string | null) & {
|
|
25
|
+
clearCache: () => void;
|
|
26
|
+
resultsCount: () => number;
|
|
27
|
+
resetResultsCount: () => void;
|
|
28
|
+
};
|
|
29
|
+
lastResult: () => string | null;
|
|
30
|
+
dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
|
|
31
|
+
recomputations: () => number;
|
|
32
|
+
resetRecomputations: () => void;
|
|
33
|
+
dependencyRecomputations: () => number;
|
|
34
|
+
resetDependencyRecomputations: () => void;
|
|
35
|
+
} & {
|
|
36
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
37
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Check if an item is the default focusable item.
|
|
41
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
42
|
+
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
43
|
+
* @returns {boolean} `true` if the item is the default focusable item, `false` otherwise.
|
|
44
|
+
*/
|
|
45
|
+
export declare const selectorIsItemTheDefaultFocusableItem: ((state: any, itemId: string) => boolean) & {
|
|
46
|
+
clearCache: () => void;
|
|
47
|
+
resultsCount: () => number;
|
|
48
|
+
resetResultsCount: () => void;
|
|
49
|
+
} & {
|
|
50
|
+
resultFunc: (resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean;
|
|
51
|
+
memoizedResultFunc: ((resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean) & {
|
|
52
|
+
clearCache: () => void;
|
|
53
|
+
resultsCount: () => number;
|
|
54
|
+
resetResultsCount: () => void;
|
|
55
|
+
};
|
|
56
|
+
lastResult: () => boolean;
|
|
57
|
+
dependencies: [((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
|
|
58
|
+
cacheKey: import("../../models").TreeViewStateCacheKey;
|
|
59
|
+
}) => string | null) & {
|
|
60
|
+
clearCache: () => void;
|
|
61
|
+
resultsCount: () => number;
|
|
62
|
+
resetResultsCount: () => void;
|
|
63
|
+
} & {
|
|
64
|
+
resultFunc: (resultFuncArgs_0: {
|
|
65
|
+
focusedItemId: string | null;
|
|
66
|
+
defaultFocusableItemId: string | null;
|
|
67
|
+
}) => string | null;
|
|
68
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
69
|
+
focusedItemId: string | null;
|
|
70
|
+
defaultFocusableItemId: string | null;
|
|
71
|
+
}) => string | null) & {
|
|
72
|
+
clearCache: () => void;
|
|
73
|
+
resultsCount: () => number;
|
|
74
|
+
resetResultsCount: () => void;
|
|
75
|
+
};
|
|
76
|
+
lastResult: () => string | null;
|
|
77
|
+
dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
|
|
78
|
+
recomputations: () => number;
|
|
79
|
+
resetRecomputations: () => void;
|
|
80
|
+
dependencyRecomputations: () => number;
|
|
81
|
+
resetDependencyRecomputations: () => void;
|
|
82
|
+
} & {
|
|
83
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
84
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
85
|
+
}, (_: any, itemId: string) => string];
|
|
86
|
+
recomputations: () => number;
|
|
87
|
+
resetRecomputations: () => void;
|
|
88
|
+
dependencyRecomputations: () => number;
|
|
89
|
+
resetDependencyRecomputations: () => void;
|
|
90
|
+
} & {
|
|
91
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
92
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Get the id of the item that is currently focused.
|
|
96
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
97
|
+
* @returns {TreeViewItemId | null} The id of the item that is currently focused.
|
|
98
|
+
*/
|
|
99
|
+
export declare const selectorFocusedItemId: ((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
|
|
100
|
+
cacheKey: import("../../models").TreeViewStateCacheKey;
|
|
101
|
+
}) => string | null) & {
|
|
102
|
+
clearCache: () => void;
|
|
103
|
+
resultsCount: () => number;
|
|
104
|
+
resetResultsCount: () => void;
|
|
105
|
+
} & {
|
|
106
|
+
resultFunc: (resultFuncArgs_0: {
|
|
107
|
+
focusedItemId: string | null;
|
|
108
|
+
defaultFocusableItemId: string | null;
|
|
109
|
+
}) => string | null;
|
|
110
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
111
|
+
focusedItemId: string | null;
|
|
112
|
+
defaultFocusableItemId: string | null;
|
|
113
|
+
}) => string | null) & {
|
|
114
|
+
clearCache: () => void;
|
|
115
|
+
resultsCount: () => number;
|
|
116
|
+
resetResultsCount: () => void;
|
|
117
|
+
};
|
|
118
|
+
lastResult: () => string | null;
|
|
119
|
+
dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
|
|
120
|
+
recomputations: () => number;
|
|
121
|
+
resetRecomputations: () => void;
|
|
122
|
+
dependencyRecomputations: () => number;
|
|
123
|
+
resetDependencyRecomputations: () => void;
|
|
124
|
+
} & {
|
|
125
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
126
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Check if an item is focused.
|
|
130
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
131
|
+
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
132
|
+
* @returns {boolean} `true` if the item is focused, `false` otherwise.
|
|
133
|
+
*/
|
|
134
|
+
export declare const selectorIsItemFocused: ((state: any, itemId: string) => boolean) & {
|
|
135
|
+
clearCache: () => void;
|
|
136
|
+
resultsCount: () => number;
|
|
137
|
+
resetResultsCount: () => void;
|
|
138
|
+
} & {
|
|
139
|
+
resultFunc: (resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean;
|
|
140
|
+
memoizedResultFunc: ((resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean) & {
|
|
141
|
+
clearCache: () => void;
|
|
142
|
+
resultsCount: () => number;
|
|
143
|
+
resetResultsCount: () => void;
|
|
144
|
+
};
|
|
145
|
+
lastResult: () => boolean;
|
|
146
|
+
dependencies: [((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
|
|
147
|
+
cacheKey: import("../../models").TreeViewStateCacheKey;
|
|
148
|
+
}) => string | null) & {
|
|
149
|
+
clearCache: () => void;
|
|
150
|
+
resultsCount: () => number;
|
|
151
|
+
resetResultsCount: () => void;
|
|
152
|
+
} & {
|
|
153
|
+
resultFunc: (resultFuncArgs_0: {
|
|
154
|
+
focusedItemId: string | null;
|
|
155
|
+
defaultFocusableItemId: string | null;
|
|
156
|
+
}) => string | null;
|
|
157
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
158
|
+
focusedItemId: string | null;
|
|
159
|
+
defaultFocusableItemId: string | null;
|
|
160
|
+
}) => string | null) & {
|
|
161
|
+
clearCache: () => void;
|
|
162
|
+
resultsCount: () => number;
|
|
163
|
+
resetResultsCount: () => void;
|
|
164
|
+
};
|
|
165
|
+
lastResult: () => string | null;
|
|
166
|
+
dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
|
|
167
|
+
recomputations: () => number;
|
|
168
|
+
resetRecomputations: () => void;
|
|
169
|
+
dependencyRecomputations: () => number;
|
|
170
|
+
resetDependencyRecomputations: () => void;
|
|
171
|
+
} & {
|
|
172
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
173
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
174
|
+
}, (_: any, itemId: string) => string];
|
|
175
|
+
recomputations: () => number;
|
|
176
|
+
resetRecomputations: () => void;
|
|
177
|
+
dependencyRecomputations: () => number;
|
|
178
|
+
resetDependencyRecomputations: () => void;
|
|
179
|
+
} & {
|
|
180
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
181
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
182
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createSelector } from "../../utils/selectors.js";
|
|
2
|
+
const selectorTreeViewFocusState = state => state.focus;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get the item that should be sequentially focusable (usually with the Tab key).
|
|
6
|
+
* At any point in time, there is a single item that can be sequentially focused in the Tree View.
|
|
7
|
+
* This item is the first selected item (that is both visible and navigable), if any, or the first navigable item if no item is selected.
|
|
8
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
9
|
+
* @returns {TreeViewItemId | null} The id of the item that should be sequentially focusable.
|
|
10
|
+
*/
|
|
11
|
+
export const selectorDefaultFocusableItemId = createSelector(selectorTreeViewFocusState, focus => focus.defaultFocusableItemId);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check if an item is the default focusable item.
|
|
15
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
16
|
+
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
17
|
+
* @returns {boolean} `true` if the item is the default focusable item, `false` otherwise.
|
|
18
|
+
*/
|
|
19
|
+
export const selectorIsItemTheDefaultFocusableItem = createSelector([selectorDefaultFocusableItemId, (_, itemId) => itemId], (defaultFocusableItemId, itemId) => defaultFocusableItemId === itemId);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get the id of the item that is currently focused.
|
|
23
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
24
|
+
* @returns {TreeViewItemId | null} The id of the item that is currently focused.
|
|
25
|
+
*/
|
|
26
|
+
export const selectorFocusedItemId = createSelector(selectorTreeViewFocusState, focus => focus.focusedItemId);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if an item is focused.
|
|
30
|
+
* @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
|
|
31
|
+
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
32
|
+
* @returns {boolean} `true` if the item is focused, `false` otherwise.
|
|
33
|
+
*/
|
|
34
|
+
export const selectorIsItemFocused = createSelector([selectorFocusedItemId, (_, itemId) => itemId], (focusedItemId, itemId) => focusedItemId === itemId);
|
|
@@ -3,7 +3,6 @@ import { TreeViewPluginSignature } from '../../models';
|
|
|
3
3
|
import type { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
4
4
|
import type { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
|
|
5
5
|
import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
|
|
6
|
-
import { TreeViewItemId } from '../../../models';
|
|
7
6
|
export interface UseTreeViewFocusPublicAPI {
|
|
8
7
|
/**
|
|
9
8
|
* Focus the item with the given id.
|
|
@@ -16,20 +15,6 @@ export interface UseTreeViewFocusPublicAPI {
|
|
|
16
15
|
focusItem: (event: React.SyntheticEvent, itemId: string) => void;
|
|
17
16
|
}
|
|
18
17
|
export interface UseTreeViewFocusInstance extends UseTreeViewFocusPublicAPI {
|
|
19
|
-
/**
|
|
20
|
-
* Check if an item is the currently focused item.
|
|
21
|
-
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
22
|
-
* @returns {boolean} `true` if the item is focused, `false` otherwise.
|
|
23
|
-
*/
|
|
24
|
-
isItemFocused: (itemId: TreeViewItemId) => boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Check if an item should be sequentially focusable (usually with the Tab key).
|
|
27
|
-
* At any point in time, there is a single item that can be sequentially focused in the Tree View.
|
|
28
|
-
* This item is the first selected item (that is both visible and navigable), if any, or the first navigable item if no item is selected.
|
|
29
|
-
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
30
|
-
* @returns {boolean} `true` if the item can be sequentially focusable, `false` otherwise.
|
|
31
|
-
*/
|
|
32
|
-
canItemBeTabbed: (itemId: TreeViewItemId) => boolean;
|
|
33
18
|
/**
|
|
34
19
|
* Remove the focus from the currently focused item (both from the internal state and the DOM).
|
|
35
20
|
*/
|
|
@@ -45,7 +30,10 @@ export interface UseTreeViewFocusParameters {
|
|
|
45
30
|
}
|
|
46
31
|
export type UseTreeViewFocusDefaultizedParameters = UseTreeViewFocusParameters;
|
|
47
32
|
export interface UseTreeViewFocusState {
|
|
48
|
-
|
|
33
|
+
focus: {
|
|
34
|
+
focusedItemId: string | null;
|
|
35
|
+
defaultFocusableItemId: string | null;
|
|
36
|
+
};
|
|
49
37
|
}
|
|
50
38
|
export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
|
|
51
39
|
params: UseTreeViewFocusParameters;
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
1
2
|
export const useTreeViewIcons = ({
|
|
2
3
|
slots,
|
|
3
4
|
slotProps
|
|
4
5
|
}) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
endIcon: slotProps.endIcon
|
|
17
|
-
}
|
|
6
|
+
const pluginContextValue = React.useMemo(() => ({
|
|
7
|
+
icons: {
|
|
8
|
+
slots: {
|
|
9
|
+
collapseIcon: slots.collapseIcon,
|
|
10
|
+
expandIcon: slots.expandIcon,
|
|
11
|
+
endIcon: slots.endIcon
|
|
12
|
+
},
|
|
13
|
+
slotProps: {
|
|
14
|
+
collapseIcon: slotProps.collapseIcon,
|
|
15
|
+
expandIcon: slotProps.expandIcon,
|
|
16
|
+
endIcon: slotProps.endIcon
|
|
18
17
|
}
|
|
19
18
|
}
|
|
19
|
+
}), [slots.collapseIcon, slots.expandIcon, slots.endIcon, slotProps.collapseIcon, slotProps.expandIcon, slotProps.endIcon]);
|
|
20
|
+
return {
|
|
21
|
+
contextValue: pluginContextValue
|
|
20
22
|
};
|
|
21
23
|
};
|
|
22
24
|
useTreeViewIcons.params = {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { useTreeViewItems } from './useTreeViewItems';
|
|
2
|
-
export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, UseTreeViewItemsState,
|
|
2
|
+
export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, UseTreeViewItemsState, } from './useTreeViewItems.types';
|
|
3
3
|
export { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './useTreeViewItems.utils';
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
-
const _excluded = ["children"];
|
|
4
2
|
import * as React from 'react';
|
|
3
|
+
import useEventCallback from '@mui/utils/useEventCallback';
|
|
5
4
|
import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js";
|
|
6
5
|
import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "./useTreeViewItems.utils.js";
|
|
7
6
|
import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js";
|
|
7
|
+
import { selectorItemMeta, selectorItemOrderedChildrenIds, selectorItemModel, selectorItemDepth } from "./useTreeViewItems.selectors.js";
|
|
8
|
+
import { selectorTreeViewId } from "../../corePlugins/useTreeViewId/useTreeViewId.selectors.js";
|
|
8
9
|
import { generateTreeItemIdAttribute } from "../../corePlugins/useTreeViewId/useTreeViewId.utils.js";
|
|
9
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
11
|
const updateItemsState = ({
|
|
12
|
+
disabledItemsFocusable,
|
|
11
13
|
items,
|
|
12
14
|
isItemDisabled,
|
|
13
15
|
getItemLabel,
|
|
14
16
|
getItemId
|
|
15
17
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
18
|
+
const itemMetaLookup = {};
|
|
19
|
+
const itemModelLookup = {};
|
|
20
|
+
const itemOrderedChildrenIdsLookup = {
|
|
19
21
|
[TREE_VIEW_ROOT_PARENT_ID]: []
|
|
20
22
|
};
|
|
21
23
|
const processItem = (item, depth, parentId) => {
|
|
@@ -23,14 +25,14 @@ const updateItemsState = ({
|
|
|
23
25
|
if (id == null) {
|
|
24
26
|
throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', 'An item was provided without id in the `items` prop:', JSON.stringify(item)].join('\n'));
|
|
25
27
|
}
|
|
26
|
-
if (
|
|
28
|
+
if (itemMetaLookup[id] != null) {
|
|
27
29
|
throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', `Two items were provided with the same id in the \`items\` prop: "${id}"`].join('\n'));
|
|
28
30
|
}
|
|
29
31
|
const label = getItemLabel ? getItemLabel(item) : item.label;
|
|
30
32
|
if (label == null) {
|
|
31
33
|
throw new Error(['MUI X: The Tree View component requires all items to have a `label` property.', 'Alternatively, you can use the `getItemLabel` prop to specify a custom label for each item.', 'An item was provided without label in the `items` prop:', JSON.stringify(item)].join('\n'));
|
|
32
34
|
}
|
|
33
|
-
|
|
35
|
+
itemMetaLookup[id] = {
|
|
34
36
|
id,
|
|
35
37
|
label,
|
|
36
38
|
parentId,
|
|
@@ -39,88 +41,58 @@ const updateItemsState = ({
|
|
|
39
41
|
disabled: isItemDisabled ? isItemDisabled(item) : false,
|
|
40
42
|
depth
|
|
41
43
|
};
|
|
42
|
-
|
|
44
|
+
itemModelLookup[id] = item;
|
|
43
45
|
const parentIdWithDefault = parentId ?? TREE_VIEW_ROOT_PARENT_ID;
|
|
44
|
-
if (!
|
|
45
|
-
|
|
46
|
+
if (!itemOrderedChildrenIdsLookup[parentIdWithDefault]) {
|
|
47
|
+
itemOrderedChildrenIdsLookup[parentIdWithDefault] = [];
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
itemOrderedChildrenIdsLookup[parentIdWithDefault].push(id);
|
|
48
50
|
item.children?.forEach(child => processItem(child, depth + 1, id));
|
|
49
51
|
};
|
|
50
52
|
items.forEach(item => processItem(item, 0, null));
|
|
51
|
-
const
|
|
52
|
-
Object.keys(
|
|
53
|
-
|
|
53
|
+
const itemChildrenIndexesLookup = {};
|
|
54
|
+
Object.keys(itemOrderedChildrenIdsLookup).forEach(parentId => {
|
|
55
|
+
itemChildrenIndexesLookup[parentId] = buildSiblingIndexes(itemOrderedChildrenIdsLookup[parentId]);
|
|
54
56
|
});
|
|
55
57
|
return {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
disabledItemsFocusable,
|
|
59
|
+
itemMetaLookup,
|
|
60
|
+
itemModelLookup,
|
|
61
|
+
itemOrderedChildrenIdsLookup,
|
|
62
|
+
itemChildrenIndexesLookup
|
|
60
63
|
};
|
|
61
64
|
};
|
|
62
65
|
export const useTreeViewItems = ({
|
|
63
66
|
instance,
|
|
64
67
|
params,
|
|
65
|
-
|
|
66
|
-
setState
|
|
68
|
+
store
|
|
67
69
|
}) => {
|
|
68
|
-
const
|
|
69
|
-
const getItem = React.useCallback(itemId => state.items.itemMap[itemId], [state.items.itemMap]);
|
|
70
|
+
const getItem = React.useCallback(itemId => selectorItemModel(store.value, itemId), [store]);
|
|
70
71
|
const getItemTree = React.useCallback(() => {
|
|
71
|
-
const getItemFromItemId =
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (newChildren) {
|
|
72
|
+
const getItemFromItemId = itemId => {
|
|
73
|
+
const item = selectorItemModel(store.value, itemId);
|
|
74
|
+
const newChildren = selectorItemOrderedChildrenIds(store.value, itemId);
|
|
75
|
+
if (newChildren.length > 0) {
|
|
76
76
|
item.children = newChildren.map(getItemFromItemId);
|
|
77
|
+
} else {
|
|
78
|
+
delete item.children;
|
|
77
79
|
}
|
|
78
80
|
return item;
|
|
79
81
|
};
|
|
80
|
-
return
|
|
81
|
-
}, [
|
|
82
|
-
const
|
|
83
|
-
if (itemId == null) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
let itemMeta = instance.getItemMeta(itemId);
|
|
87
|
-
|
|
88
|
-
// This can be called before the item has been added to the item map.
|
|
89
|
-
if (!itemMeta) {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
if (itemMeta.disabled) {
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
while (itemMeta.parentId != null) {
|
|
96
|
-
itemMeta = instance.getItemMeta(itemMeta.parentId);
|
|
97
|
-
if (itemMeta.disabled) {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
}, [instance]);
|
|
103
|
-
const getItemIndex = React.useCallback(itemId => {
|
|
104
|
-
const parentId = instance.getItemMeta(itemId).parentId ?? TREE_VIEW_ROOT_PARENT_ID;
|
|
105
|
-
return state.items.itemChildrenIndexes[parentId][itemId];
|
|
106
|
-
}, [instance, state.items.itemChildrenIndexes]);
|
|
107
|
-
const getItemOrderedChildrenIds = React.useCallback(itemId => state.items.itemOrderedChildrenIds[itemId ?? TREE_VIEW_ROOT_PARENT_ID] ?? [], [state.items.itemOrderedChildrenIds]);
|
|
82
|
+
return selectorItemOrderedChildrenIds(store.value, null).map(getItemFromItemId);
|
|
83
|
+
}, [store]);
|
|
84
|
+
const getItemOrderedChildrenIds = React.useCallback(itemId => selectorItemOrderedChildrenIds(store.value, itemId), [store]);
|
|
108
85
|
const getItemDOMElement = itemId => {
|
|
109
|
-
const itemMeta =
|
|
86
|
+
const itemMeta = selectorItemMeta(store.value, itemId);
|
|
110
87
|
if (itemMeta == null) {
|
|
111
88
|
return null;
|
|
112
89
|
}
|
|
113
|
-
|
|
114
|
-
treeId:
|
|
90
|
+
const idAttribute = generateTreeItemIdAttribute({
|
|
91
|
+
treeId: selectorTreeViewId(store.value),
|
|
115
92
|
itemId,
|
|
116
93
|
id: itemMeta.idAttribute
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
const isItemNavigable = itemId => {
|
|
120
|
-
if (params.disabledItemsFocusable) {
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
return !instance.isItemDisabled(itemId);
|
|
94
|
+
});
|
|
95
|
+
return document.getElementById(idAttribute);
|
|
124
96
|
};
|
|
125
97
|
const areItemUpdatesPreventedRef = React.useRef(false);
|
|
126
98
|
const preventItemUpdates = React.useCallback(() => {
|
|
@@ -131,15 +103,16 @@ export const useTreeViewItems = ({
|
|
|
131
103
|
if (instance.areItemUpdatesPrevented()) {
|
|
132
104
|
return;
|
|
133
105
|
}
|
|
134
|
-
|
|
106
|
+
store.update(prevState => {
|
|
135
107
|
const newState = updateItemsState({
|
|
108
|
+
disabledItemsFocusable: params.disabledItemsFocusable,
|
|
136
109
|
items: params.items,
|
|
137
110
|
isItemDisabled: params.isItemDisabled,
|
|
138
111
|
getItemId: params.getItemId,
|
|
139
112
|
getItemLabel: params.getItemLabel
|
|
140
113
|
});
|
|
141
|
-
Object.values(prevState.items.
|
|
142
|
-
if (!newState.
|
|
114
|
+
Object.values(prevState.items.itemMetaLookup).forEach(item => {
|
|
115
|
+
if (!newState.itemMetaLookup[item.id]) {
|
|
143
116
|
publishTreeViewEvent(instance, 'removeItem', {
|
|
144
117
|
id: item.id
|
|
145
118
|
});
|
|
@@ -149,19 +122,19 @@ export const useTreeViewItems = ({
|
|
|
149
122
|
items: newState
|
|
150
123
|
});
|
|
151
124
|
});
|
|
152
|
-
}, [instance,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
};
|
|
125
|
+
}, [instance, store, params.items, params.disabledItemsFocusable, params.isItemDisabled, params.getItemId, params.getItemLabel]);
|
|
126
|
+
|
|
127
|
+
// Wrap `props.onItemClick` with `useEventCallback` to prevent unneeded context updates.
|
|
128
|
+
const handleItemClick = useEventCallback((event, itemId) => {
|
|
129
|
+
if (params.onItemClick) {
|
|
130
|
+
params.onItemClick(event, itemId);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
const pluginContextValue = React.useMemo(() => ({
|
|
134
|
+
items: {
|
|
135
|
+
onItemClick: handleItemClick
|
|
136
|
+
}
|
|
137
|
+
}), [handleItemClick]);
|
|
165
138
|
return {
|
|
166
139
|
getRootProps: () => ({
|
|
167
140
|
style: {
|
|
@@ -175,28 +148,16 @@ export const useTreeViewItems = ({
|
|
|
175
148
|
getItemOrderedChildrenIds
|
|
176
149
|
},
|
|
177
150
|
instance: {
|
|
178
|
-
getItemMeta,
|
|
179
|
-
getItem,
|
|
180
|
-
getItemTree,
|
|
181
|
-
getItemsToRender,
|
|
182
|
-
getItemIndex,
|
|
183
151
|
getItemDOMElement,
|
|
184
|
-
getItemOrderedChildrenIds,
|
|
185
|
-
isItemDisabled,
|
|
186
|
-
isItemNavigable,
|
|
187
152
|
preventItemUpdates,
|
|
188
153
|
areItemUpdatesPrevented
|
|
189
154
|
},
|
|
190
|
-
contextValue:
|
|
191
|
-
items: {
|
|
192
|
-
onItemClick: params.onItemClick,
|
|
193
|
-
disabledItemsFocusable: params.disabledItemsFocusable
|
|
194
|
-
}
|
|
195
|
-
}
|
|
155
|
+
contextValue: pluginContextValue
|
|
196
156
|
};
|
|
197
157
|
};
|
|
198
158
|
useTreeViewItems.getInitialState = params => ({
|
|
199
159
|
items: updateItemsState({
|
|
160
|
+
disabledItemsFocusable: params.disabledItemsFocusable,
|
|
200
161
|
items: params.items,
|
|
201
162
|
isItemDisabled: params.isItemDisabled,
|
|
202
163
|
getItemId: params.getItemId,
|
|
@@ -210,11 +171,10 @@ useTreeViewItems.getDefaultizedParams = ({
|
|
|
210
171
|
itemChildrenIndentation: params.itemChildrenIndentation ?? '12px'
|
|
211
172
|
});
|
|
212
173
|
useTreeViewItems.wrapRoot = ({
|
|
213
|
-
children
|
|
214
|
-
instance
|
|
174
|
+
children
|
|
215
175
|
}) => {
|
|
216
176
|
return /*#__PURE__*/_jsx(TreeViewItemDepthContext.Provider, {
|
|
217
|
-
value:
|
|
177
|
+
value: selectorItemDepth,
|
|
218
178
|
children: children
|
|
219
179
|
});
|
|
220
180
|
};
|