@mui/x-tree-view 7.8.0 → 7.10.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 +140 -0
- package/RichTreeView/RichTreeView.js +9 -5
- package/SimpleTreeView/SimpleTreeView.js +9 -5
- package/TreeItem/useTreeItemState.js +16 -3
- package/TreeView/TreeView.js +9 -5
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +16 -3
- package/index.js +1 -1
- package/internals/corePlugins/corePlugins.d.ts +1 -1
- package/internals/corePlugins/corePlugins.js +2 -1
- package/internals/corePlugins/useTreeViewOptionalPlugins/index.d.ts +2 -0
- package/internals/corePlugins/useTreeViewOptionalPlugins/index.js +1 -0
- package/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.d.ts +3 -0
- package/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.js +12 -0
- package/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.types.d.ts +8 -0
- package/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.types.js +1 -0
- package/internals/models/plugin.d.ts +1 -0
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +7 -7
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -2
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +2 -2
- package/internals/plugins/useTreeViewItems/useTreeViewItems.js +28 -3
- package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +20 -9
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +15 -5
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +12 -4
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +25 -16
- package/internals/useTreeView/useTreeView.js +2 -1
- package/internals/utils/plugins.d.ts +2 -0
- package/internals/utils/plugins.js +4 -0
- package/modern/RichTreeView/RichTreeView.js +9 -5
- package/modern/SimpleTreeView/SimpleTreeView.js +9 -5
- package/modern/TreeItem/useTreeItemState.js +16 -3
- package/modern/TreeView/TreeView.js +9 -5
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +16 -3
- package/modern/index.js +1 -1
- package/modern/internals/corePlugins/corePlugins.js +2 -1
- package/modern/internals/corePlugins/useTreeViewOptionalPlugins/index.js +1 -0
- package/modern/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.js +12 -0
- package/modern/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.types.js +1 -0
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -2
- package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +28 -3
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +15 -5
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +12 -4
- package/modern/internals/useTreeView/useTreeView.js +2 -1
- package/modern/internals/utils/plugins.js +4 -0
- package/node/RichTreeView/RichTreeView.js +9 -5
- package/node/SimpleTreeView/SimpleTreeView.js +9 -5
- package/node/TreeItem/useTreeItemState.js +16 -3
- package/node/TreeView/TreeView.js +9 -5
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +16 -3
- package/node/index.js +1 -1
- package/node/internals/corePlugins/corePlugins.js +2 -1
- package/node/internals/corePlugins/useTreeViewOptionalPlugins/index.js +12 -0
- package/node/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.js +19 -0
- package/node/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.types.js +5 -0
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -2
- package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +28 -3
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +15 -5
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +12 -4
- package/node/internals/useTreeView/useTreeView.js +2 -1
- package/node/internals/utils/plugins.js +11 -0
- package/package.json +3 -3
|
@@ -74,10 +74,13 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
74
74
|
event.preventDefault();
|
|
75
75
|
if (params.multiSelect && event.shiftKey) {
|
|
76
76
|
instance.expandSelectionRange(event, itemId);
|
|
77
|
-
} else if (params.multiSelect) {
|
|
78
|
-
instance.selectItem(event, itemId, true);
|
|
79
77
|
} else {
|
|
80
|
-
instance.selectItem(
|
|
78
|
+
instance.selectItem({
|
|
79
|
+
event,
|
|
80
|
+
itemId,
|
|
81
|
+
keepExistingSelection: params.multiSelect,
|
|
82
|
+
shouldBeSelected: params.multiSelect ? undefined : true
|
|
83
|
+
});
|
|
81
84
|
}
|
|
82
85
|
break;
|
|
83
86
|
}
|
|
@@ -92,9 +95,16 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
92
95
|
} else if (canToggleItemSelection(itemId)) {
|
|
93
96
|
if (params.multiSelect) {
|
|
94
97
|
event.preventDefault();
|
|
95
|
-
instance.selectItem(
|
|
98
|
+
instance.selectItem({
|
|
99
|
+
event,
|
|
100
|
+
itemId,
|
|
101
|
+
keepExistingSelection: true
|
|
102
|
+
});
|
|
96
103
|
} else if (!instance.isItemSelected(itemId)) {
|
|
97
|
-
instance.selectItem(
|
|
104
|
+
instance.selectItem({
|
|
105
|
+
event,
|
|
106
|
+
itemId
|
|
107
|
+
});
|
|
98
108
|
event.preventDefault();
|
|
99
109
|
}
|
|
100
110
|
}
|
|
@@ -46,7 +46,12 @@ export const useTreeViewSelection = ({
|
|
|
46
46
|
models.selectedItems.setControlledValue(newSelectedItems);
|
|
47
47
|
};
|
|
48
48
|
const isItemSelected = itemId => selectedItemsMap.has(itemId);
|
|
49
|
-
const selectItem = (
|
|
49
|
+
const selectItem = ({
|
|
50
|
+
event,
|
|
51
|
+
itemId,
|
|
52
|
+
keepExistingSelection = false,
|
|
53
|
+
shouldBeSelected
|
|
54
|
+
}) => {
|
|
50
55
|
if (params.disableSelection) {
|
|
51
56
|
return;
|
|
52
57
|
}
|
|
@@ -54,16 +59,16 @@ export const useTreeViewSelection = ({
|
|
|
54
59
|
if (keepExistingSelection) {
|
|
55
60
|
const cleanSelectedItems = convertSelectedItemsToArray(models.selectedItems.value);
|
|
56
61
|
const isSelectedBefore = instance.isItemSelected(itemId);
|
|
57
|
-
if (isSelectedBefore && (
|
|
62
|
+
if (isSelectedBefore && (shouldBeSelected === false || shouldBeSelected == null)) {
|
|
58
63
|
newSelected = cleanSelectedItems.filter(id => id !== itemId);
|
|
59
|
-
} else if (!isSelectedBefore && (
|
|
64
|
+
} else if (!isSelectedBefore && (shouldBeSelected === true || shouldBeSelected == null)) {
|
|
60
65
|
newSelected = [itemId].concat(cleanSelectedItems);
|
|
61
66
|
} else {
|
|
62
67
|
newSelected = cleanSelectedItems;
|
|
63
68
|
}
|
|
64
69
|
} else {
|
|
65
70
|
// eslint-disable-next-line no-lonely-if
|
|
66
|
-
if (
|
|
71
|
+
if (shouldBeSelected === false || shouldBeSelected == null && instance.isItemSelected(itemId)) {
|
|
67
72
|
newSelected = params.multiSelect ? [] : null;
|
|
68
73
|
} else {
|
|
69
74
|
newSelected = params.multiSelect ? [itemId] : itemId;
|
|
@@ -142,6 +147,9 @@ export const useTreeViewSelection = ({
|
|
|
142
147
|
getRootProps: () => ({
|
|
143
148
|
'aria-multiselectable': params.multiSelect
|
|
144
149
|
}),
|
|
150
|
+
publicAPI: {
|
|
151
|
+
selectItem
|
|
152
|
+
},
|
|
145
153
|
instance: {
|
|
146
154
|
isItemSelected,
|
|
147
155
|
selectItem,
|
|
@@ -2,47 +2,55 @@ import * as React from 'react';
|
|
|
2
2
|
import type { DefaultizedProps, TreeViewPluginSignature } from '../../models';
|
|
3
3
|
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
4
4
|
import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
|
|
5
|
-
export interface
|
|
5
|
+
export interface UseTreeViewSelectionPublicAPI {
|
|
6
|
+
/**
|
|
7
|
+
* Select or deselect an item.
|
|
8
|
+
* @param {object} params The params of the method.
|
|
9
|
+
* @param {React.SyntheticEvent} params.event The DOM event that triggered the change.
|
|
10
|
+
* @param {string} params.itemId The id of the item to select or deselect.
|
|
11
|
+
* @param {boolean} params.keepExistingSelection If `true`, the other already selected items will remain selected, otherwise, they will be deselected. This parameter is only relevant when `multiSelect` is `true`
|
|
12
|
+
* @param {boolean | undefined} params.shouldBeSelected If `true` the item will be selected. If `false` the item will be deselected. If not defined, the item's new selection status will be the opposite of its current one.
|
|
13
|
+
*/
|
|
14
|
+
selectItem: (params: {
|
|
15
|
+
event: React.SyntheticEvent;
|
|
16
|
+
itemId: string;
|
|
17
|
+
keepExistingSelection?: boolean;
|
|
18
|
+
shouldBeSelected?: boolean;
|
|
19
|
+
}) => void;
|
|
20
|
+
}
|
|
21
|
+
export interface UseTreeViewSelectionInstance extends UseTreeViewSelectionPublicAPI {
|
|
6
22
|
/**
|
|
7
23
|
* Check if an item is selected.
|
|
8
24
|
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
9
25
|
* @returns {boolean} `true` if the item is selected, `false` otherwise.
|
|
10
26
|
*/
|
|
11
27
|
isItemSelected: (itemId: string) => boolean;
|
|
12
|
-
/**
|
|
13
|
-
* Select or deselect an item.
|
|
14
|
-
* @param {React.SyntheticEvent} event The event source of the callback.
|
|
15
|
-
* @param {string} itemId The id of the item to select or deselect.
|
|
16
|
-
* @param {boolean} keepExistingSelection If `true`, don't remove the other selected items.
|
|
17
|
-
* @param {boolean | undefined} newValue The new selection status of the item. If not defined, the new state will be the opposite of the current state.
|
|
18
|
-
*/
|
|
19
|
-
selectItem: (event: React.SyntheticEvent, itemId: string, keepExistingSelection: boolean, newValue?: boolean) => void;
|
|
20
28
|
/**
|
|
21
29
|
* Select all the navigable items in the tree.
|
|
22
|
-
* @param {React.SyntheticEvent} event The event
|
|
30
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
23
31
|
*/
|
|
24
32
|
selectAllNavigableItems: (event: React.SyntheticEvent) => void;
|
|
25
33
|
/**
|
|
26
34
|
* Expand the current selection range up to the given item.
|
|
27
|
-
* @param {React.SyntheticEvent} event The event
|
|
35
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
28
36
|
* @param {string} itemId The id of the item to expand the selection to.
|
|
29
37
|
*/
|
|
30
38
|
expandSelectionRange: (event: React.SyntheticEvent, itemId: string) => void;
|
|
31
39
|
/**
|
|
32
40
|
* Expand the current selection range from the first navigable item to the given item.
|
|
33
|
-
* @param {React.SyntheticEvent} event The event
|
|
41
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
34
42
|
* @param {string} itemId The id of the item up to which the selection range should be expanded.
|
|
35
43
|
*/
|
|
36
44
|
selectRangeFromStartToItem: (event: React.SyntheticEvent, itemId: string) => void;
|
|
37
45
|
/**
|
|
38
46
|
* Expand the current selection range from the given item to the last navigable item.
|
|
39
|
-
* @param {React.SyntheticEvent} event The event
|
|
47
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
40
48
|
* @param {string} itemId The id of the item from which the selection range should be expanded.
|
|
41
49
|
*/
|
|
42
50
|
selectRangeFromItemToEnd: (event: React.SyntheticEvent, itemId: string) => void;
|
|
43
51
|
/**
|
|
44
52
|
* Update the selection when navigating with ArrowUp / ArrowDown keys.
|
|
45
|
-
* @param {React.SyntheticEvent} event The event
|
|
53
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
46
54
|
* @param {string} currentItemId The id of the active item before the keyboard navigation.
|
|
47
55
|
* @param {string} nextItemId The id of the active item after the keyboard navigation.
|
|
48
56
|
*/
|
|
@@ -78,14 +86,14 @@ export interface UseTreeViewSelectionParameters<Multiple extends boolean | undef
|
|
|
78
86
|
checkboxSelection?: boolean;
|
|
79
87
|
/**
|
|
80
88
|
* Callback fired when tree items are selected/deselected.
|
|
81
|
-
* @param {React.SyntheticEvent} event The event
|
|
89
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
82
90
|
* @param {string[] | string} itemIds The ids of the selected items.
|
|
83
91
|
* When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
|
|
84
92
|
*/
|
|
85
93
|
onSelectedItemsChange?: (event: React.SyntheticEvent, itemIds: TreeViewSelectionValue<Multiple>) => void;
|
|
86
94
|
/**
|
|
87
95
|
* Callback fired when a tree item is selected or deselected.
|
|
88
|
-
* @param {React.SyntheticEvent} event The event
|
|
96
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
89
97
|
* @param {array} itemId The itemId of the modified item.
|
|
90
98
|
* @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
|
|
91
99
|
*/
|
|
@@ -99,6 +107,7 @@ export type UseTreeViewSelectionSignature = TreeViewPluginSignature<{
|
|
|
99
107
|
params: UseTreeViewSelectionParameters<any>;
|
|
100
108
|
defaultizedParams: UseTreeViewSelectionDefaultizedParameters<any>;
|
|
101
109
|
instance: UseTreeViewSelectionInstance;
|
|
110
|
+
publicAPI: UseTreeViewSelectionPublicAPI;
|
|
102
111
|
contextValue: UseTreeViewSelectionContextValue;
|
|
103
112
|
modelNames: 'selectedItems';
|
|
104
113
|
dependencies: [
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { TreeViewAnyPluginSignature, TreeViewInstance, TreeViewPlugin } from '../models';
|
|
2
|
+
export declare const hasPlugin: <TSignature extends TreeViewAnyPluginSignature, TInstance extends TreeViewInstance<[], [TSignature]>>(instance: TInstance, plugin: TreeViewPlugin<TSignature>) => instance is Omit<TInstance, keyof TSignature["instance"]> & TSignature["instance"];
|
|
@@ -137,6 +137,10 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
137
137
|
current: PropTypes.shape({
|
|
138
138
|
focusItem: PropTypes.func.isRequired,
|
|
139
139
|
getItem: PropTypes.func.isRequired,
|
|
140
|
+
getItemDOMElement: PropTypes.func.isRequired,
|
|
141
|
+
getItemOrderedChildrenIds: PropTypes.func.isRequired,
|
|
142
|
+
getItemTree: PropTypes.func.isRequired,
|
|
143
|
+
selectItem: PropTypes.func.isRequired,
|
|
140
144
|
setItemExpansion: PropTypes.func.isRequired
|
|
141
145
|
})
|
|
142
146
|
}),
|
|
@@ -234,34 +238,34 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
234
238
|
multiSelect: PropTypes.bool,
|
|
235
239
|
/**
|
|
236
240
|
* Callback fired when tree items are expanded/collapsed.
|
|
237
|
-
* @param {React.SyntheticEvent} event The event
|
|
241
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
238
242
|
* @param {array} itemIds The ids of the expanded items.
|
|
239
243
|
*/
|
|
240
244
|
onExpandedItemsChange: PropTypes.func,
|
|
241
245
|
/**
|
|
242
246
|
* Callback fired when a tree item is expanded or collapsed.
|
|
243
|
-
* @param {React.SyntheticEvent} event The event
|
|
247
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
244
248
|
* @param {array} itemId The itemId of the modified item.
|
|
245
249
|
* @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
|
|
246
250
|
*/
|
|
247
251
|
onItemExpansionToggle: PropTypes.func,
|
|
248
252
|
/**
|
|
249
253
|
* Callback fired when tree items are focused.
|
|
250
|
-
* @param {React.SyntheticEvent} event The event
|
|
254
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
|
|
251
255
|
* @param {string} itemId The id of the focused item.
|
|
252
256
|
* @param {string} value of the focused item.
|
|
253
257
|
*/
|
|
254
258
|
onItemFocus: PropTypes.func,
|
|
255
259
|
/**
|
|
256
260
|
* Callback fired when a tree item is selected or deselected.
|
|
257
|
-
* @param {React.SyntheticEvent} event The event
|
|
261
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
258
262
|
* @param {array} itemId The itemId of the modified item.
|
|
259
263
|
* @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
|
|
260
264
|
*/
|
|
261
265
|
onItemSelectionToggle: PropTypes.func,
|
|
262
266
|
/**
|
|
263
267
|
* Callback fired when tree items are selected/deselected.
|
|
264
|
-
* @param {React.SyntheticEvent} event The event
|
|
268
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
265
269
|
* @param {string[] | string} itemIds The ids of the selected items.
|
|
266
270
|
* When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
|
|
267
271
|
*/
|
|
@@ -95,6 +95,10 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
|
|
|
95
95
|
current: PropTypes.shape({
|
|
96
96
|
focusItem: PropTypes.func.isRequired,
|
|
97
97
|
getItem: PropTypes.func.isRequired,
|
|
98
|
+
getItemDOMElement: PropTypes.func.isRequired,
|
|
99
|
+
getItemOrderedChildrenIds: PropTypes.func.isRequired,
|
|
100
|
+
getItemTree: PropTypes.func.isRequired,
|
|
101
|
+
selectItem: PropTypes.func.isRequired,
|
|
98
102
|
setItemExpansion: PropTypes.func.isRequired
|
|
99
103
|
})
|
|
100
104
|
}),
|
|
@@ -170,34 +174,34 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
|
|
|
170
174
|
multiSelect: PropTypes.bool,
|
|
171
175
|
/**
|
|
172
176
|
* Callback fired when tree items are expanded/collapsed.
|
|
173
|
-
* @param {React.SyntheticEvent} event The event
|
|
177
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
174
178
|
* @param {array} itemIds The ids of the expanded items.
|
|
175
179
|
*/
|
|
176
180
|
onExpandedItemsChange: PropTypes.func,
|
|
177
181
|
/**
|
|
178
182
|
* Callback fired when a tree item is expanded or collapsed.
|
|
179
|
-
* @param {React.SyntheticEvent} event The event
|
|
183
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
180
184
|
* @param {array} itemId The itemId of the modified item.
|
|
181
185
|
* @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
|
|
182
186
|
*/
|
|
183
187
|
onItemExpansionToggle: PropTypes.func,
|
|
184
188
|
/**
|
|
185
189
|
* Callback fired when tree items are focused.
|
|
186
|
-
* @param {React.SyntheticEvent} event The event
|
|
190
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
|
|
187
191
|
* @param {string} itemId The id of the focused item.
|
|
188
192
|
* @param {string} value of the focused item.
|
|
189
193
|
*/
|
|
190
194
|
onItemFocus: PropTypes.func,
|
|
191
195
|
/**
|
|
192
196
|
* Callback fired when a tree item is selected or deselected.
|
|
193
|
-
* @param {React.SyntheticEvent} event The event
|
|
197
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
194
198
|
* @param {array} itemId The itemId of the modified item.
|
|
195
199
|
* @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
|
|
196
200
|
*/
|
|
197
201
|
onItemSelectionToggle: PropTypes.func,
|
|
198
202
|
/**
|
|
199
203
|
* Callback fired when tree items are selected/deselected.
|
|
200
|
-
* @param {React.SyntheticEvent} event The event
|
|
204
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
201
205
|
* @param {string[] | string} itemIds The ids of the selected items.
|
|
202
206
|
* When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
|
|
203
207
|
*/
|
|
@@ -39,10 +39,18 @@ export function useTreeItemState(itemId) {
|
|
|
39
39
|
if (event.shiftKey) {
|
|
40
40
|
instance.expandSelectionRange(event, itemId);
|
|
41
41
|
} else {
|
|
42
|
-
instance.selectItem(
|
|
42
|
+
instance.selectItem({
|
|
43
|
+
event,
|
|
44
|
+
itemId,
|
|
45
|
+
keepExistingSelection: true
|
|
46
|
+
});
|
|
43
47
|
}
|
|
44
48
|
} else {
|
|
45
|
-
instance.selectItem(
|
|
49
|
+
instance.selectItem({
|
|
50
|
+
event,
|
|
51
|
+
itemId,
|
|
52
|
+
shouldBeSelected: true
|
|
53
|
+
});
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
};
|
|
@@ -54,7 +62,12 @@ export function useTreeItemState(itemId) {
|
|
|
54
62
|
if (multiSelect && hasShift) {
|
|
55
63
|
instance.expandSelectionRange(event, itemId);
|
|
56
64
|
} else {
|
|
57
|
-
instance.selectItem(
|
|
65
|
+
instance.selectItem({
|
|
66
|
+
event,
|
|
67
|
+
itemId,
|
|
68
|
+
keepExistingSelection: multiSelect,
|
|
69
|
+
shouldBeSelected: event.target.checked
|
|
70
|
+
});
|
|
58
71
|
}
|
|
59
72
|
};
|
|
60
73
|
const preventSelection = event => {
|
|
@@ -72,6 +72,10 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
|
|
|
72
72
|
current: PropTypes.shape({
|
|
73
73
|
focusItem: PropTypes.func.isRequired,
|
|
74
74
|
getItem: PropTypes.func.isRequired,
|
|
75
|
+
getItemDOMElement: PropTypes.func.isRequired,
|
|
76
|
+
getItemOrderedChildrenIds: PropTypes.func.isRequired,
|
|
77
|
+
getItemTree: PropTypes.func.isRequired,
|
|
78
|
+
selectItem: PropTypes.func.isRequired,
|
|
75
79
|
setItemExpansion: PropTypes.func.isRequired
|
|
76
80
|
})
|
|
77
81
|
}),
|
|
@@ -147,34 +151,34 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
|
|
|
147
151
|
multiSelect: PropTypes.bool,
|
|
148
152
|
/**
|
|
149
153
|
* Callback fired when tree items are expanded/collapsed.
|
|
150
|
-
* @param {React.SyntheticEvent} event The event
|
|
154
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
151
155
|
* @param {array} itemIds The ids of the expanded items.
|
|
152
156
|
*/
|
|
153
157
|
onExpandedItemsChange: PropTypes.func,
|
|
154
158
|
/**
|
|
155
159
|
* Callback fired when a tree item is expanded or collapsed.
|
|
156
|
-
* @param {React.SyntheticEvent} event The event
|
|
160
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
157
161
|
* @param {array} itemId The itemId of the modified item.
|
|
158
162
|
* @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
|
|
159
163
|
*/
|
|
160
164
|
onItemExpansionToggle: PropTypes.func,
|
|
161
165
|
/**
|
|
162
166
|
* Callback fired when tree items are focused.
|
|
163
|
-
* @param {React.SyntheticEvent} event The event
|
|
167
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event.
|
|
164
168
|
* @param {string} itemId The id of the focused item.
|
|
165
169
|
* @param {string} value of the focused item.
|
|
166
170
|
*/
|
|
167
171
|
onItemFocus: PropTypes.func,
|
|
168
172
|
/**
|
|
169
173
|
* Callback fired when a tree item is selected or deselected.
|
|
170
|
-
* @param {React.SyntheticEvent} event The event
|
|
174
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
171
175
|
* @param {array} itemId The itemId of the modified item.
|
|
172
176
|
* @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
|
|
173
177
|
*/
|
|
174
178
|
onItemSelectionToggle: PropTypes.func,
|
|
175
179
|
/**
|
|
176
180
|
* Callback fired when tree items are selected/deselected.
|
|
177
|
-
* @param {React.SyntheticEvent} event The event
|
|
181
|
+
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
178
182
|
* @param {string[] | string} itemIds The ids of the selected items.
|
|
179
183
|
* When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
|
|
180
184
|
*/
|
|
@@ -57,10 +57,18 @@ export const useTreeItem2Utils = ({
|
|
|
57
57
|
if (event.shiftKey) {
|
|
58
58
|
instance.expandSelectionRange(event, itemId);
|
|
59
59
|
} else {
|
|
60
|
-
instance.selectItem(
|
|
60
|
+
instance.selectItem({
|
|
61
|
+
event,
|
|
62
|
+
itemId,
|
|
63
|
+
keepExistingSelection: true
|
|
64
|
+
});
|
|
61
65
|
}
|
|
62
66
|
} else {
|
|
63
|
-
instance.selectItem(
|
|
67
|
+
instance.selectItem({
|
|
68
|
+
event,
|
|
69
|
+
itemId,
|
|
70
|
+
shouldBeSelected: true
|
|
71
|
+
});
|
|
64
72
|
}
|
|
65
73
|
};
|
|
66
74
|
const handleCheckboxSelection = event => {
|
|
@@ -68,7 +76,12 @@ export const useTreeItem2Utils = ({
|
|
|
68
76
|
if (multiSelect && hasShift) {
|
|
69
77
|
instance.expandSelectionRange(event, itemId);
|
|
70
78
|
} else {
|
|
71
|
-
instance.selectItem(
|
|
79
|
+
instance.selectItem({
|
|
80
|
+
event,
|
|
81
|
+
itemId,
|
|
82
|
+
keepExistingSelection: multiSelect,
|
|
83
|
+
shouldBeSelected: event.target.checked
|
|
84
|
+
});
|
|
72
85
|
}
|
|
73
86
|
};
|
|
74
87
|
const interactions = {
|
package/modern/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useTreeViewInstanceEvents } from './useTreeViewInstanceEvents';
|
|
2
|
+
import { useTreeViewOptionalPlugins } from './useTreeViewOptionalPlugins';
|
|
2
3
|
import { useTreeViewId } from './useTreeViewId';
|
|
3
4
|
/**
|
|
4
5
|
* Internal plugins that create the tools used by the other plugins.
|
|
5
6
|
* These plugins are used by the tree view components.
|
|
6
7
|
*/
|
|
7
|
-
export const TREE_VIEW_CORE_PLUGINS = [useTreeViewInstanceEvents, useTreeViewId];
|
|
8
|
+
export const TREE_VIEW_CORE_PLUGINS = [useTreeViewInstanceEvents, useTreeViewOptionalPlugins, useTreeViewId];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useTreeViewOptionalPlugins } from './useTreeViewOptionalPlugins';
|
package/modern/internals/corePlugins/useTreeViewOptionalPlugins/useTreeViewOptionalPlugins.types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -43,8 +43,7 @@ export const useTreeViewFocus = ({
|
|
|
43
43
|
return itemMeta && (itemMeta.parentId == null || instance.isItemExpanded(itemMeta.parentId));
|
|
44
44
|
};
|
|
45
45
|
const innerFocusItem = (event, itemId) => {
|
|
46
|
-
const
|
|
47
|
-
const itemElement = document.getElementById(instance.getTreeItemIdAttribute(itemId, itemMeta.idAttribute));
|
|
46
|
+
const itemElement = instance.getItemDOMElement(itemId);
|
|
48
47
|
if (itemElement) {
|
|
49
48
|
itemElement.focus();
|
|
50
49
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
+
const _excluded = ["children"];
|
|
2
4
|
import * as React from 'react';
|
|
3
5
|
import { publishTreeViewEvent } from '../../utils/publishTreeViewEvent';
|
|
4
6
|
import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './useTreeViewItems.utils';
|
|
@@ -37,7 +39,6 @@ const updateItemsState = ({
|
|
|
37
39
|
depth
|
|
38
40
|
};
|
|
39
41
|
itemMap[id] = item;
|
|
40
|
-
itemOrderedChildrenIds[id] = [];
|
|
41
42
|
const parentIdWithDefault = parentId ?? TREE_VIEW_ROOT_PARENT_ID;
|
|
42
43
|
if (!itemOrderedChildrenIds[parentIdWithDefault]) {
|
|
43
44
|
itemOrderedChildrenIds[parentIdWithDefault] = [];
|
|
@@ -66,6 +67,18 @@ export const useTreeViewItems = ({
|
|
|
66
67
|
}) => {
|
|
67
68
|
const getItemMeta = React.useCallback(itemId => state.items.itemMetaMap[itemId], [state.items.itemMetaMap]);
|
|
68
69
|
const getItem = React.useCallback(itemId => state.items.itemMap[itemId], [state.items.itemMap]);
|
|
70
|
+
const getItemTree = React.useCallback(() => {
|
|
71
|
+
const getItemFromItemId = id => {
|
|
72
|
+
const _state$items$itemMap$ = state.items.itemMap[id],
|
|
73
|
+
item = _objectWithoutPropertiesLoose(_state$items$itemMap$, _excluded);
|
|
74
|
+
const newChildren = state.items.itemOrderedChildrenIds[id];
|
|
75
|
+
if (newChildren) {
|
|
76
|
+
item.children = newChildren.map(getItemFromItemId);
|
|
77
|
+
}
|
|
78
|
+
return item;
|
|
79
|
+
};
|
|
80
|
+
return state.items.itemOrderedChildrenIds[TREE_VIEW_ROOT_PARENT_ID].map(getItemFromItemId);
|
|
81
|
+
}, [state.items.itemMap, state.items.itemOrderedChildrenIds]);
|
|
69
82
|
const isItemDisabled = React.useCallback(itemId => {
|
|
70
83
|
if (itemId == null) {
|
|
71
84
|
return false;
|
|
@@ -92,6 +105,13 @@ export const useTreeViewItems = ({
|
|
|
92
105
|
return state.items.itemChildrenIndexes[parentId][itemId];
|
|
93
106
|
}, [instance, state.items.itemChildrenIndexes]);
|
|
94
107
|
const getItemOrderedChildrenIds = React.useCallback(itemId => state.items.itemOrderedChildrenIds[itemId ?? TREE_VIEW_ROOT_PARENT_ID] ?? [], [state.items.itemOrderedChildrenIds]);
|
|
108
|
+
const getItemDOMElement = itemId => {
|
|
109
|
+
const itemMeta = instance.getItemMeta(itemId);
|
|
110
|
+
if (itemMeta == null) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
return document.getElementById(instance.getTreeItemIdAttribute(itemId, itemMeta.idAttribute));
|
|
114
|
+
};
|
|
95
115
|
const isItemNavigable = itemId => {
|
|
96
116
|
if (params.disabledItemsFocusable) {
|
|
97
117
|
return true;
|
|
@@ -133,7 +153,7 @@ export const useTreeViewItems = ({
|
|
|
133
153
|
label: item.label,
|
|
134
154
|
itemId: item.id,
|
|
135
155
|
id: item.idAttribute,
|
|
136
|
-
children: state.items.itemOrderedChildrenIds[id]
|
|
156
|
+
children: state.items.itemOrderedChildrenIds[id]?.map(getPropsFromItemId)
|
|
137
157
|
};
|
|
138
158
|
};
|
|
139
159
|
return state.items.itemOrderedChildrenIds[TREE_VIEW_ROOT_PARENT_ID].map(getPropsFromItemId);
|
|
@@ -145,13 +165,18 @@ export const useTreeViewItems = ({
|
|
|
145
165
|
}
|
|
146
166
|
}),
|
|
147
167
|
publicAPI: {
|
|
148
|
-
getItem
|
|
168
|
+
getItem,
|
|
169
|
+
getItemDOMElement,
|
|
170
|
+
getItemTree,
|
|
171
|
+
getItemOrderedChildrenIds
|
|
149
172
|
},
|
|
150
173
|
instance: {
|
|
151
174
|
getItemMeta,
|
|
152
175
|
getItem,
|
|
176
|
+
getItemTree,
|
|
153
177
|
getItemsToRender,
|
|
154
178
|
getItemIndex,
|
|
179
|
+
getItemDOMElement,
|
|
155
180
|
getItemOrderedChildrenIds,
|
|
156
181
|
isItemDisabled,
|
|
157
182
|
isItemNavigable,
|
package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js
CHANGED
|
@@ -74,10 +74,13 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
74
74
|
event.preventDefault();
|
|
75
75
|
if (params.multiSelect && event.shiftKey) {
|
|
76
76
|
instance.expandSelectionRange(event, itemId);
|
|
77
|
-
} else if (params.multiSelect) {
|
|
78
|
-
instance.selectItem(event, itemId, true);
|
|
79
77
|
} else {
|
|
80
|
-
instance.selectItem(
|
|
78
|
+
instance.selectItem({
|
|
79
|
+
event,
|
|
80
|
+
itemId,
|
|
81
|
+
keepExistingSelection: params.multiSelect,
|
|
82
|
+
shouldBeSelected: params.multiSelect ? undefined : true
|
|
83
|
+
});
|
|
81
84
|
}
|
|
82
85
|
break;
|
|
83
86
|
}
|
|
@@ -92,9 +95,16 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
92
95
|
} else if (canToggleItemSelection(itemId)) {
|
|
93
96
|
if (params.multiSelect) {
|
|
94
97
|
event.preventDefault();
|
|
95
|
-
instance.selectItem(
|
|
98
|
+
instance.selectItem({
|
|
99
|
+
event,
|
|
100
|
+
itemId,
|
|
101
|
+
keepExistingSelection: true
|
|
102
|
+
});
|
|
96
103
|
} else if (!instance.isItemSelected(itemId)) {
|
|
97
|
-
instance.selectItem(
|
|
104
|
+
instance.selectItem({
|
|
105
|
+
event,
|
|
106
|
+
itemId
|
|
107
|
+
});
|
|
98
108
|
event.preventDefault();
|
|
99
109
|
}
|
|
100
110
|
}
|
|
@@ -46,7 +46,12 @@ export const useTreeViewSelection = ({
|
|
|
46
46
|
models.selectedItems.setControlledValue(newSelectedItems);
|
|
47
47
|
};
|
|
48
48
|
const isItemSelected = itemId => selectedItemsMap.has(itemId);
|
|
49
|
-
const selectItem = (
|
|
49
|
+
const selectItem = ({
|
|
50
|
+
event,
|
|
51
|
+
itemId,
|
|
52
|
+
keepExistingSelection = false,
|
|
53
|
+
shouldBeSelected
|
|
54
|
+
}) => {
|
|
50
55
|
if (params.disableSelection) {
|
|
51
56
|
return;
|
|
52
57
|
}
|
|
@@ -54,16 +59,16 @@ export const useTreeViewSelection = ({
|
|
|
54
59
|
if (keepExistingSelection) {
|
|
55
60
|
const cleanSelectedItems = convertSelectedItemsToArray(models.selectedItems.value);
|
|
56
61
|
const isSelectedBefore = instance.isItemSelected(itemId);
|
|
57
|
-
if (isSelectedBefore && (
|
|
62
|
+
if (isSelectedBefore && (shouldBeSelected === false || shouldBeSelected == null)) {
|
|
58
63
|
newSelected = cleanSelectedItems.filter(id => id !== itemId);
|
|
59
|
-
} else if (!isSelectedBefore && (
|
|
64
|
+
} else if (!isSelectedBefore && (shouldBeSelected === true || shouldBeSelected == null)) {
|
|
60
65
|
newSelected = [itemId].concat(cleanSelectedItems);
|
|
61
66
|
} else {
|
|
62
67
|
newSelected = cleanSelectedItems;
|
|
63
68
|
}
|
|
64
69
|
} else {
|
|
65
70
|
// eslint-disable-next-line no-lonely-if
|
|
66
|
-
if (
|
|
71
|
+
if (shouldBeSelected === false || shouldBeSelected == null && instance.isItemSelected(itemId)) {
|
|
67
72
|
newSelected = params.multiSelect ? [] : null;
|
|
68
73
|
} else {
|
|
69
74
|
newSelected = params.multiSelect ? [itemId] : itemId;
|
|
@@ -142,6 +147,9 @@ export const useTreeViewSelection = ({
|
|
|
142
147
|
getRootProps: () => ({
|
|
143
148
|
'aria-multiselectable': params.multiSelect
|
|
144
149
|
}),
|
|
150
|
+
publicAPI: {
|
|
151
|
+
selectItem
|
|
152
|
+
},
|
|
145
153
|
instance: {
|
|
146
154
|
isItemSelected,
|
|
147
155
|
selectItem,
|