@mui/x-tree-view 8.0.0-alpha.0 → 8.0.0-alpha.2
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 +651 -6
- package/README.md +2 -2
- package/RichTreeView/RichTreeView.js +2 -4
- package/RichTreeView/RichTreeView.types.d.ts +5 -18
- package/SimpleTreeView/SimpleTreeView.types.d.ts +2 -2
- package/TreeItem/TreeItem.js +4 -4
- package/TreeItem/TreeItem.types.d.ts +4 -2
- package/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
- package/TreeItemIcon/TreeItemIcon.types.d.ts +1 -1
- package/TreeItemProvider/TreeItemProvider.d.ts +2 -4
- package/TreeItemProvider/TreeItemProvider.js +26 -11
- 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/hooks/useTreeViewApiRef.d.ts +1 -0
- 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 +3 -5
- 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 +5 -5
- package/internals/models/plugin.d.ts +20 -8
- 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/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
- 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 +2 -3
- 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/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
- package/modern/TreeItemProvider/TreeItemProvider.js +26 -11
- 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/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +2 -2
- package/node/TreeItemProvider/TreeItemProvider.js +26 -10
- 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,74 @@
|
|
|
1
|
+
import { UseTreeViewLabelSignature } from './useTreeViewLabel.types';
|
|
2
|
+
import { TreeViewRootSelector } from '../../utils/selectors';
|
|
3
|
+
/**
|
|
4
|
+
* Check if an item is editable.
|
|
5
|
+
* @param {TreeViewState<[UseTreeViewItemsSignature]>} state The state of the tree view.
|
|
6
|
+
* @param {object} params The parameters.
|
|
7
|
+
* @param {TreeViewItemId} params.itemId The id of the item to check.
|
|
8
|
+
* @param {((item: any) => boolean) | boolean} params.isItemEditable The function to determine if an item is editable.
|
|
9
|
+
* @returns {boolean} `true` if the item is editable, `false` otherwise.
|
|
10
|
+
*/
|
|
11
|
+
export declare const selectorIsItemEditable: ((state: any, args: any) => boolean) & {
|
|
12
|
+
clearCache: () => void;
|
|
13
|
+
resultsCount: () => number;
|
|
14
|
+
resetResultsCount: () => void;
|
|
15
|
+
} & {
|
|
16
|
+
resultFunc: (resultFuncArgs_0: {
|
|
17
|
+
itemId: string;
|
|
18
|
+
isItemEditable: ((item: any) => boolean) | boolean;
|
|
19
|
+
}, resultFuncArgs_1: import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>) => boolean;
|
|
20
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
21
|
+
itemId: string;
|
|
22
|
+
isItemEditable: ((item: any) => boolean) | boolean;
|
|
23
|
+
}, resultFuncArgs_1: import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>) => boolean) & {
|
|
24
|
+
clearCache: () => void;
|
|
25
|
+
resultsCount: () => number;
|
|
26
|
+
resetResultsCount: () => void;
|
|
27
|
+
};
|
|
28
|
+
lastResult: () => boolean;
|
|
29
|
+
dependencies: [(_: any, args: {
|
|
30
|
+
itemId: string;
|
|
31
|
+
isItemEditable: ((item: any) => boolean) | boolean;
|
|
32
|
+
}) => {
|
|
33
|
+
itemId: string;
|
|
34
|
+
isItemEditable: ((item: any) => boolean) | boolean;
|
|
35
|
+
}, (state: any, args: any) => import("../../..").TreeViewBaseItem<import("../../..").TreeViewDefaultItemModelProperties>];
|
|
36
|
+
recomputations: () => number;
|
|
37
|
+
resetRecomputations: () => void;
|
|
38
|
+
dependencyRecomputations: () => number;
|
|
39
|
+
resetDependencyRecomputations: () => void;
|
|
40
|
+
} & {
|
|
41
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
42
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Check if an item is being edited.
|
|
46
|
+
* @param {TreeViewState<[UseTreeViewLabelSignature]>} state The state of the tree view.
|
|
47
|
+
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
48
|
+
* @returns {boolean} `true` if the item is being edited, `false` otherwise.
|
|
49
|
+
*/
|
|
50
|
+
export declare const selectorIsItemBeingEdited: ((state: any, itemId: string) => boolean) & {
|
|
51
|
+
clearCache: () => void;
|
|
52
|
+
resultsCount: () => number;
|
|
53
|
+
resetResultsCount: () => void;
|
|
54
|
+
} & {
|
|
55
|
+
resultFunc: (resultFuncArgs_0: {
|
|
56
|
+
editedItemId: string | null;
|
|
57
|
+
}, resultFuncArgs_1: string) => boolean;
|
|
58
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
59
|
+
editedItemId: string | null;
|
|
60
|
+
}, resultFuncArgs_1: string) => boolean) & {
|
|
61
|
+
clearCache: () => void;
|
|
62
|
+
resultsCount: () => number;
|
|
63
|
+
resetResultsCount: () => void;
|
|
64
|
+
};
|
|
65
|
+
lastResult: () => boolean;
|
|
66
|
+
dependencies: [TreeViewRootSelector<UseTreeViewLabelSignature>, (_: any, itemId: string) => string];
|
|
67
|
+
recomputations: () => number;
|
|
68
|
+
resetRecomputations: () => void;
|
|
69
|
+
dependencyRecomputations: () => number;
|
|
70
|
+
resetDependencyRecomputations: () => void;
|
|
71
|
+
} & {
|
|
72
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
73
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
74
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createSelector } from "../../utils/selectors.js";
|
|
2
|
+
import { selectorItemModel } from "../useTreeViewItems/useTreeViewItems.selectors.js";
|
|
3
|
+
const selectorTreeViewLabelState = state => state.label;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Check if an item is editable.
|
|
7
|
+
* @param {TreeViewState<[UseTreeViewItemsSignature]>} state The state of the tree view.
|
|
8
|
+
* @param {object} params The parameters.
|
|
9
|
+
* @param {TreeViewItemId} params.itemId The id of the item to check.
|
|
10
|
+
* @param {((item: any) => boolean) | boolean} params.isItemEditable The function to determine if an item is editable.
|
|
11
|
+
* @returns {boolean} `true` if the item is editable, `false` otherwise.
|
|
12
|
+
*/
|
|
13
|
+
export const selectorIsItemEditable = createSelector([(_, args) => args, (state, args) => selectorItemModel(state, args.itemId)], (args, itemModel) => {
|
|
14
|
+
if (!itemModel || !args.isItemEditable) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return typeof args.isItemEditable === 'function' ? args.isItemEditable(itemModel) : true;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Check if an item is being edited.
|
|
22
|
+
* @param {TreeViewState<[UseTreeViewLabelSignature]>} state The state of the tree view.
|
|
23
|
+
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
24
|
+
* @returns {boolean} `true` if the item is being edited, `false` otherwise.
|
|
25
|
+
*/
|
|
26
|
+
export const selectorIsItemBeingEdited = createSelector([selectorTreeViewLabelState, (_, itemId) => itemId], (labelState, itemId) => labelState.editedItemId === itemId);
|
|
@@ -18,29 +18,6 @@ export interface UseTreeViewLabelInstance extends UseTreeViewLabelPublicAPI {
|
|
|
18
18
|
* @returns {void}.
|
|
19
19
|
*/
|
|
20
20
|
setEditedItemId: (itemId: TreeViewItemId | null) => void;
|
|
21
|
-
/**
|
|
22
|
-
* Checks if an item is being edited or not.
|
|
23
|
-
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
24
|
-
* @returns {boolean}.
|
|
25
|
-
*/
|
|
26
|
-
isItemBeingEdited: (itemId: TreeViewItemId) => boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Checks if an item is being edited or not.
|
|
29
|
-
* Purely internal use, used to avoid unnecessarily calling `updateItemLabel` twice.
|
|
30
|
-
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
31
|
-
* @returns {boolean}.
|
|
32
|
-
*/
|
|
33
|
-
isItemBeingEditedRef: (itemId: TreeViewItemId) => boolean;
|
|
34
|
-
/**
|
|
35
|
-
* Determines if a given item is editable.
|
|
36
|
-
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
37
|
-
* @returns {boolean} `true` if the item is editable.
|
|
38
|
-
*/
|
|
39
|
-
isItemEditable: (itemId: TreeViewItemId) => boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Set to `true` if the Tree View is editable.
|
|
42
|
-
*/
|
|
43
|
-
isTreeViewEditable: boolean;
|
|
44
21
|
}
|
|
45
22
|
export interface UseTreeViewLabelParameters<R extends {}> {
|
|
46
23
|
/**
|
|
@@ -62,7 +39,12 @@ export interface UseTreeViewLabelParameters<R extends {}> {
|
|
|
62
39
|
}
|
|
63
40
|
export type UseTreeViewLabelDefaultizedParameters<R extends {}> = DefaultizedProps<UseTreeViewLabelParameters<R>, 'isItemEditable'>;
|
|
64
41
|
export interface UseTreeViewLabelState {
|
|
65
|
-
|
|
42
|
+
label: {
|
|
43
|
+
editedItemId: string | null;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface UseTreeViewLabelContextValue {
|
|
47
|
+
label: Pick<UseTreeViewLabelDefaultizedParameters<any>, 'isItemEditable'>;
|
|
66
48
|
}
|
|
67
49
|
export type UseTreeViewLabelSignature = TreeViewPluginSignature<{
|
|
68
50
|
params: UseTreeViewLabelParameters<any>;
|
|
@@ -70,6 +52,7 @@ export type UseTreeViewLabelSignature = TreeViewPluginSignature<{
|
|
|
70
52
|
publicAPI: UseTreeViewLabelPublicAPI;
|
|
71
53
|
instance: UseTreeViewLabelInstance;
|
|
72
54
|
state: UseTreeViewLabelState;
|
|
55
|
+
contextValue: UseTreeViewLabelContextValue;
|
|
73
56
|
experimentalFeatures: 'labelEditing';
|
|
74
57
|
dependencies: [UseTreeViewItemsSignature];
|
|
75
58
|
}>;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import { useTreeViewContext } from "../../TreeViewProvider/index.js";
|
|
3
|
+
import { selectorItemOrderedChildrenIds } from "../useTreeViewItems/useTreeViewItems.selectors.js";
|
|
4
|
+
import { selectorIsItemSelected } from "./useTreeViewSelection.selectors.js";
|
|
3
5
|
function getCheckboxStatus({
|
|
4
6
|
itemId,
|
|
5
|
-
|
|
7
|
+
store,
|
|
6
8
|
selectionPropagation,
|
|
7
9
|
selected
|
|
8
10
|
}) {
|
|
@@ -12,7 +14,7 @@ function getCheckboxStatus({
|
|
|
12
14
|
checked: true
|
|
13
15
|
};
|
|
14
16
|
}
|
|
15
|
-
const children =
|
|
17
|
+
const children = selectorItemOrderedChildrenIds(store.value, itemId);
|
|
16
18
|
if (children.length === 0) {
|
|
17
19
|
return {
|
|
18
20
|
indeterminate: false,
|
|
@@ -23,13 +25,13 @@ function getCheckboxStatus({
|
|
|
23
25
|
let hasUnSelectedDescendant = false;
|
|
24
26
|
const traverseDescendants = itemToTraverseId => {
|
|
25
27
|
if (itemToTraverseId !== itemId) {
|
|
26
|
-
if (
|
|
28
|
+
if (selectorIsItemSelected(store.value, itemToTraverseId)) {
|
|
27
29
|
hasSelectedDescendant = true;
|
|
28
30
|
} else {
|
|
29
31
|
hasUnSelectedDescendant = true;
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
selectorItemOrderedChildrenIds(store.value, itemToTraverseId).forEach(traverseDescendants);
|
|
33
35
|
};
|
|
34
36
|
traverseDescendants(itemId);
|
|
35
37
|
return {
|
|
@@ -44,7 +46,7 @@ export const useTreeViewSelectionItemPlugin = ({
|
|
|
44
46
|
itemId
|
|
45
47
|
} = props;
|
|
46
48
|
const {
|
|
47
|
-
|
|
49
|
+
store,
|
|
48
50
|
selection: {
|
|
49
51
|
disableSelection,
|
|
50
52
|
checkboxSelection,
|
|
@@ -69,7 +71,7 @@ export const useTreeViewSelectionItemPlugin = ({
|
|
|
69
71
|
interactions.handleCheckboxSelection(event);
|
|
70
72
|
};
|
|
71
73
|
const checkboxStatus = getCheckboxStatus({
|
|
72
|
-
|
|
74
|
+
store,
|
|
73
75
|
itemId,
|
|
74
76
|
selectionPropagation,
|
|
75
77
|
selected: status.selected
|
|
@@ -1,31 +1,29 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
|
|
3
4
|
import { findOrderInTremauxTree, getAllNavigableItems, getFirstNavigableItem, getLastNavigableItem, getNonDisabledItemsInRange } from "../../utils/tree.js";
|
|
4
|
-
import { convertSelectedItemsToArray, propagateSelection, getAddedAndRemovedItems, getLookupFromArray } from "./useTreeViewSelection.utils.js";
|
|
5
|
+
import { convertSelectedItemsToArray, propagateSelection, getAddedAndRemovedItems, getLookupFromArray, createSelectedItemsMap } from "./useTreeViewSelection.utils.js";
|
|
6
|
+
import { selectorIsItemSelected } from "./useTreeViewSelection.selectors.js";
|
|
5
7
|
import { useTreeViewSelectionItemPlugin } from "./useTreeViewSelection.itemPlugin.js";
|
|
6
8
|
export const useTreeViewSelection = ({
|
|
7
|
-
|
|
9
|
+
store,
|
|
8
10
|
params,
|
|
9
11
|
models
|
|
10
12
|
}) => {
|
|
11
13
|
const lastSelectedItem = React.useRef(null);
|
|
12
14
|
const lastSelectedRange = React.useRef({});
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
temp.set(models.selectedItems.value, true);
|
|
21
|
-
}
|
|
22
|
-
return temp;
|
|
23
|
-
}, [models.selectedItems.value]);
|
|
15
|
+
useEnhancedEffect(() => {
|
|
16
|
+
store.update(prevState => _extends({}, prevState, {
|
|
17
|
+
selection: {
|
|
18
|
+
selectedItemsMap: createSelectedItemsMap(models.selectedItems.value)
|
|
19
|
+
}
|
|
20
|
+
}));
|
|
21
|
+
}, [store, models.selectedItems.value]);
|
|
24
22
|
const setSelectedItems = (event, newModel, additionalItemsToPropagate) => {
|
|
25
23
|
let cleanModel;
|
|
26
24
|
if (params.multiSelect && (params.selectionPropagation.descendants || params.selectionPropagation.parents)) {
|
|
27
25
|
cleanModel = propagateSelection({
|
|
28
|
-
|
|
26
|
+
store,
|
|
29
27
|
selectionPropagation: params.selectionPropagation,
|
|
30
28
|
newModel: newModel,
|
|
31
29
|
oldModel: models.selectedItems.value,
|
|
@@ -37,7 +35,7 @@ export const useTreeViewSelection = ({
|
|
|
37
35
|
if (params.onItemSelectionToggle) {
|
|
38
36
|
if (params.multiSelect) {
|
|
39
37
|
const changes = getAddedAndRemovedItems({
|
|
40
|
-
|
|
38
|
+
store,
|
|
41
39
|
newModel: cleanModel,
|
|
42
40
|
oldModel: models.selectedItems.value
|
|
43
41
|
});
|
|
@@ -63,7 +61,6 @@ export const useTreeViewSelection = ({
|
|
|
63
61
|
}
|
|
64
62
|
models.selectedItems.setControlledValue(cleanModel);
|
|
65
63
|
};
|
|
66
|
-
const isItemSelected = itemId => selectedItemsMap.has(itemId);
|
|
67
64
|
const selectItem = ({
|
|
68
65
|
event,
|
|
69
66
|
itemId,
|
|
@@ -76,7 +73,7 @@ export const useTreeViewSelection = ({
|
|
|
76
73
|
let newSelected;
|
|
77
74
|
if (keepExistingSelection) {
|
|
78
75
|
const cleanSelectedItems = convertSelectedItemsToArray(models.selectedItems.value);
|
|
79
|
-
const isSelectedBefore =
|
|
76
|
+
const isSelectedBefore = selectorIsItemSelected(store.value, itemId);
|
|
80
77
|
if (isSelectedBefore && (shouldBeSelected === false || shouldBeSelected == null)) {
|
|
81
78
|
newSelected = cleanSelectedItems.filter(id => id !== itemId);
|
|
82
79
|
} else if (!isSelectedBefore && (shouldBeSelected === true || shouldBeSelected == null)) {
|
|
@@ -86,14 +83,14 @@ export const useTreeViewSelection = ({
|
|
|
86
83
|
}
|
|
87
84
|
} else {
|
|
88
85
|
// eslint-disable-next-line no-lonely-if
|
|
89
|
-
if (shouldBeSelected === false || shouldBeSelected == null &&
|
|
86
|
+
if (shouldBeSelected === false || shouldBeSelected == null && selectorIsItemSelected(store.value, itemId)) {
|
|
90
87
|
newSelected = params.multiSelect ? [] : null;
|
|
91
88
|
} else {
|
|
92
89
|
newSelected = params.multiSelect ? [itemId] : itemId;
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
92
|
setSelectedItems(event, newSelected,
|
|
96
|
-
// If shouldBeSelected ===
|
|
93
|
+
// If shouldBeSelected === selectorIsItemSelected(store, itemId), we still want to propagate the select.
|
|
97
94
|
// This is useful when the element is in an indeterminate state.
|
|
98
95
|
[itemId]);
|
|
99
96
|
lastSelectedItem.current = itemId;
|
|
@@ -113,7 +110,7 @@ export const useTreeViewSelection = ({
|
|
|
113
110
|
|
|
114
111
|
// Add to the model the items that are part of the new range and not already part of the model.
|
|
115
112
|
const selectedItemsLookup = getLookupFromArray(newSelectedItems);
|
|
116
|
-
const range = getNonDisabledItemsInRange(
|
|
113
|
+
const range = getNonDisabledItemsInRange(store.value, start, end);
|
|
117
114
|
const itemsToAddToModel = range.filter(id => !selectedItemsLookup[id]);
|
|
118
115
|
newSelectedItems = newSelectedItems.concat(itemsToAddToModel);
|
|
119
116
|
setSelectedItems(event, newSelectedItems);
|
|
@@ -121,21 +118,21 @@ export const useTreeViewSelection = ({
|
|
|
121
118
|
};
|
|
122
119
|
const expandSelectionRange = (event, itemId) => {
|
|
123
120
|
if (lastSelectedItem.current != null) {
|
|
124
|
-
const [start, end] = findOrderInTremauxTree(
|
|
121
|
+
const [start, end] = findOrderInTremauxTree(store.value, itemId, lastSelectedItem.current);
|
|
125
122
|
selectRange(event, [start, end]);
|
|
126
123
|
}
|
|
127
124
|
};
|
|
128
125
|
const selectRangeFromStartToItem = (event, itemId) => {
|
|
129
|
-
selectRange(event, [getFirstNavigableItem(
|
|
126
|
+
selectRange(event, [getFirstNavigableItem(store.value), itemId]);
|
|
130
127
|
};
|
|
131
128
|
const selectRangeFromItemToEnd = (event, itemId) => {
|
|
132
|
-
selectRange(event, [itemId, getLastNavigableItem(
|
|
129
|
+
selectRange(event, [itemId, getLastNavigableItem(store.value)]);
|
|
133
130
|
};
|
|
134
131
|
const selectAllNavigableItems = event => {
|
|
135
132
|
if (params.disableSelection || !params.multiSelect) {
|
|
136
133
|
return;
|
|
137
134
|
}
|
|
138
|
-
const navigableItems = getAllNavigableItems(
|
|
135
|
+
const navigableItems = getAllNavigableItems(store.value);
|
|
139
136
|
setSelectedItems(event, navigableItems);
|
|
140
137
|
lastSelectedRange.current = getLookupFromArray(navigableItems);
|
|
141
138
|
};
|
|
@@ -164,6 +161,17 @@ export const useTreeViewSelection = ({
|
|
|
164
161
|
}
|
|
165
162
|
setSelectedItems(event, newSelectedItems);
|
|
166
163
|
};
|
|
164
|
+
const pluginContextValue = React.useMemo(() => ({
|
|
165
|
+
selection: {
|
|
166
|
+
multiSelect: params.multiSelect,
|
|
167
|
+
checkboxSelection: params.checkboxSelection,
|
|
168
|
+
disableSelection: params.disableSelection,
|
|
169
|
+
selectionPropagation: {
|
|
170
|
+
descendants: params.selectionPropagation.descendants,
|
|
171
|
+
parents: params.selectionPropagation.parents
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}), [params.multiSelect, params.checkboxSelection, params.disableSelection, params.selectionPropagation.descendants, params.selectionPropagation.parents]);
|
|
167
175
|
return {
|
|
168
176
|
getRootProps: () => ({
|
|
169
177
|
'aria-multiselectable': params.multiSelect
|
|
@@ -172,7 +180,6 @@ export const useTreeViewSelection = ({
|
|
|
172
180
|
selectItem
|
|
173
181
|
},
|
|
174
182
|
instance: {
|
|
175
|
-
isItemSelected,
|
|
176
183
|
selectItem,
|
|
177
184
|
selectAllNavigableItems,
|
|
178
185
|
expandSelectionRange,
|
|
@@ -180,14 +187,7 @@ export const useTreeViewSelection = ({
|
|
|
180
187
|
selectRangeFromItemToEnd,
|
|
181
188
|
selectItemFromArrowNavigation
|
|
182
189
|
},
|
|
183
|
-
contextValue:
|
|
184
|
-
selection: {
|
|
185
|
-
multiSelect: params.multiSelect,
|
|
186
|
-
checkboxSelection: params.checkboxSelection,
|
|
187
|
-
disableSelection: params.disableSelection,
|
|
188
|
-
selectionPropagation: params.selectionPropagation
|
|
189
|
-
}
|
|
190
|
-
}
|
|
190
|
+
contextValue: pluginContextValue
|
|
191
191
|
};
|
|
192
192
|
};
|
|
193
193
|
useTreeViewSelection.itemPlugin = useTreeViewSelectionItemPlugin;
|
|
@@ -197,6 +197,7 @@ useTreeViewSelection.models = {
|
|
|
197
197
|
}
|
|
198
198
|
};
|
|
199
199
|
const DEFAULT_SELECTED_ITEMS = [];
|
|
200
|
+
const EMPTY_SELECTION_PROPAGATION = {};
|
|
200
201
|
useTreeViewSelection.getDefaultizedParams = ({
|
|
201
202
|
params
|
|
202
203
|
}) => _extends({}, params, {
|
|
@@ -204,7 +205,17 @@ useTreeViewSelection.getDefaultizedParams = ({
|
|
|
204
205
|
multiSelect: params.multiSelect ?? false,
|
|
205
206
|
checkboxSelection: params.checkboxSelection ?? false,
|
|
206
207
|
defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_ITEMS : null),
|
|
207
|
-
selectionPropagation: params.selectionPropagation ??
|
|
208
|
+
selectionPropagation: params.selectionPropagation ?? EMPTY_SELECTION_PROPAGATION
|
|
209
|
+
});
|
|
210
|
+
useTreeViewSelection.getInitialState = params => ({
|
|
211
|
+
selection: {
|
|
212
|
+
selectedItemsMap: createSelectedItemsMap(params.selectedItems === undefined ? params.defaultSelectedItems : params.selectedItems)
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
useTreeViewSelection.getInitialState = params => ({
|
|
216
|
+
selection: {
|
|
217
|
+
selectedItemsMap: createSelectedItemsMap(params.selectedItems === undefined ? params.defaultSelectedItems : params.selectedItems)
|
|
218
|
+
}
|
|
208
219
|
});
|
|
209
220
|
useTreeViewSelection.params = {
|
|
210
221
|
disableSelection: true,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TreeViewRootSelector } from '../../utils/selectors';
|
|
2
|
+
import { UseTreeViewSelectionSignature } from './useTreeViewSelection.types';
|
|
3
|
+
/**
|
|
4
|
+
* Check if an item is selected.
|
|
5
|
+
* @param {TreeViewState<[UseTreeViewSelectionSignature]>} state The state of the tree view.
|
|
6
|
+
* @returns {boolean} `true` if the item is selected, `false` otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export declare const selectorIsItemSelected: ((state: any, itemId: string) => boolean) & {
|
|
9
|
+
clearCache: () => void;
|
|
10
|
+
resultsCount: () => number;
|
|
11
|
+
resetResultsCount: () => void;
|
|
12
|
+
} & {
|
|
13
|
+
resultFunc: (resultFuncArgs_0: {
|
|
14
|
+
selectedItemsMap: Map<string, true>;
|
|
15
|
+
}, resultFuncArgs_1: string) => boolean;
|
|
16
|
+
memoizedResultFunc: ((resultFuncArgs_0: {
|
|
17
|
+
selectedItemsMap: Map<string, true>;
|
|
18
|
+
}, resultFuncArgs_1: string) => boolean) & {
|
|
19
|
+
clearCache: () => void;
|
|
20
|
+
resultsCount: () => number;
|
|
21
|
+
resetResultsCount: () => void;
|
|
22
|
+
};
|
|
23
|
+
lastResult: () => boolean;
|
|
24
|
+
dependencies: [TreeViewRootSelector<UseTreeViewSelectionSignature>, (_: any, itemId: string) => string];
|
|
25
|
+
recomputations: () => number;
|
|
26
|
+
resetRecomputations: () => void;
|
|
27
|
+
dependencyRecomputations: () => number;
|
|
28
|
+
resetDependencyRecomputations: () => void;
|
|
29
|
+
} & {
|
|
30
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
31
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
32
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createSelector } from "../../utils/selectors.js";
|
|
2
|
+
const selectorTreeViewSelectionState = state => state.selection;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Check if an item is selected.
|
|
6
|
+
* @param {TreeViewState<[UseTreeViewSelectionSignature]>} state The state of the tree view.
|
|
7
|
+
* @returns {boolean} `true` if the item is selected, `false` otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export const selectorIsItemSelected = createSelector([selectorTreeViewSelectionState, (_, itemId) => itemId], (selectionState, itemId) => selectionState.selectedItemsMap.has(itemId));
|
|
@@ -21,12 +21,6 @@ export interface UseTreeViewSelectionPublicAPI {
|
|
|
21
21
|
}) => void;
|
|
22
22
|
}
|
|
23
23
|
export interface UseTreeViewSelectionInstance extends UseTreeViewSelectionPublicAPI {
|
|
24
|
-
/**
|
|
25
|
-
* Check if an item is selected.
|
|
26
|
-
* @param {TreeViewItemId} itemId The id of the item to check.
|
|
27
|
-
* @returns {boolean} `true` if the item is selected, `false` otherwise.
|
|
28
|
-
*/
|
|
29
|
-
isItemSelected: (itemId: string) => boolean;
|
|
30
24
|
/**
|
|
31
25
|
* Select all the navigable items in the tree.
|
|
32
26
|
* @param {React.SyntheticEvent} event The DOM event that triggered the change.
|
|
@@ -119,6 +113,11 @@ export interface UseTreeViewSelectionParameters<Multiple extends boolean | undef
|
|
|
119
113
|
onItemSelectionToggle?: (event: React.SyntheticEvent, itemId: string, isSelected: boolean) => void;
|
|
120
114
|
}
|
|
121
115
|
export type UseTreeViewSelectionDefaultizedParameters<Multiple extends boolean> = DefaultizedProps<UseTreeViewSelectionParameters<Multiple>, 'disableSelection' | 'defaultSelectedItems' | 'multiSelect' | 'checkboxSelection' | 'selectionPropagation'>;
|
|
116
|
+
export interface UseTreeViewSelectionState {
|
|
117
|
+
selection: {
|
|
118
|
+
selectedItemsMap: Map<string, true>;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
122
121
|
interface UseTreeViewSelectionContextValue {
|
|
123
122
|
selection: Pick<UseTreeViewSelectionDefaultizedParameters<boolean>, 'multiSelect' | 'checkboxSelection' | 'disableSelection' | 'selectionPropagation'>;
|
|
124
123
|
}
|
|
@@ -129,6 +128,7 @@ export type UseTreeViewSelectionSignature = TreeViewPluginSignature<{
|
|
|
129
128
|
publicAPI: UseTreeViewSelectionPublicAPI;
|
|
130
129
|
contextValue: UseTreeViewSelectionContextValue;
|
|
131
130
|
modelNames: 'selectedItems';
|
|
131
|
+
state: UseTreeViewSelectionState;
|
|
132
132
|
dependencies: [
|
|
133
133
|
UseTreeViewItemsSignature,
|
|
134
134
|
UseTreeViewExpansionSignature,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { TreeViewItemId, TreeViewSelectionPropagation } from '../../../models';
|
|
2
|
-
import {
|
|
3
|
-
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
2
|
+
import { TreeViewUsedStore } from '../../models';
|
|
4
3
|
import { UseTreeViewSelectionSignature } from './useTreeViewSelection.types';
|
|
5
4
|
/**
|
|
6
5
|
* Transform the `selectedItems` model to be an array if it was a string or null.
|
|
@@ -8,19 +7,20 @@ import { UseTreeViewSelectionSignature } from './useTreeViewSelection.types';
|
|
|
8
7
|
* @returns {string[]} The converted model.
|
|
9
8
|
*/
|
|
10
9
|
export declare const convertSelectedItemsToArray: (model: string[] | string | null) => string[];
|
|
10
|
+
export declare const createSelectedItemsMap: (selectedItems: string | string[] | null) => Map<string, true>;
|
|
11
11
|
export declare const getLookupFromArray: (array: string[]) => {
|
|
12
12
|
[itemId: string]: true;
|
|
13
13
|
};
|
|
14
|
-
export declare const getAddedAndRemovedItems: ({
|
|
15
|
-
|
|
14
|
+
export declare const getAddedAndRemovedItems: ({ store, oldModel, newModel, }: {
|
|
15
|
+
store: TreeViewUsedStore<UseTreeViewSelectionSignature>;
|
|
16
16
|
oldModel: TreeViewItemId[];
|
|
17
17
|
newModel: TreeViewItemId[];
|
|
18
18
|
}) => {
|
|
19
19
|
added: string[];
|
|
20
20
|
removed: string[];
|
|
21
21
|
};
|
|
22
|
-
export declare const propagateSelection: ({
|
|
23
|
-
|
|
22
|
+
export declare const propagateSelection: ({ store, selectionPropagation, newModel, oldModel, additionalItemsToPropagate, }: {
|
|
23
|
+
store: TreeViewUsedStore<UseTreeViewSelectionSignature>;
|
|
24
24
|
selectionPropagation: TreeViewSelectionPropagation;
|
|
25
25
|
newModel: TreeViewItemId[];
|
|
26
26
|
oldModel: TreeViewItemId[];
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { selectorIsItemSelected } from "./useTreeViewSelection.selectors.js";
|
|
2
|
+
import { selectorItemOrderedChildrenIds, selectorItemParentId } from "../useTreeViewItems/useTreeViewItems.selectors.js";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Transform the `selectedItems` model to be an array if it was a string or null.
|
|
3
6
|
* @param {string[] | string | null} model The raw model.
|
|
@@ -12,6 +15,13 @@ export const convertSelectedItemsToArray = model => {
|
|
|
12
15
|
}
|
|
13
16
|
return [];
|
|
14
17
|
};
|
|
18
|
+
export const createSelectedItemsMap = selectedItems => {
|
|
19
|
+
const selectedItemsMap = new Map();
|
|
20
|
+
convertSelectedItemsToArray(selectedItems).forEach(id => {
|
|
21
|
+
selectedItemsMap.set(id, true);
|
|
22
|
+
});
|
|
23
|
+
return selectedItemsMap;
|
|
24
|
+
};
|
|
15
25
|
export const getLookupFromArray = array => {
|
|
16
26
|
const lookup = {};
|
|
17
27
|
array.forEach(itemId => {
|
|
@@ -20,18 +30,18 @@ export const getLookupFromArray = array => {
|
|
|
20
30
|
return lookup;
|
|
21
31
|
};
|
|
22
32
|
export const getAddedAndRemovedItems = ({
|
|
23
|
-
|
|
33
|
+
store,
|
|
24
34
|
oldModel,
|
|
25
35
|
newModel
|
|
26
36
|
}) => {
|
|
27
|
-
const newModelLookup =
|
|
37
|
+
const newModelLookup = createSelectedItemsMap(newModel);
|
|
28
38
|
return {
|
|
29
|
-
added: newModel.filter(itemId => !
|
|
30
|
-
removed: oldModel.filter(itemId => !newModelLookup
|
|
39
|
+
added: newModel.filter(itemId => !selectorIsItemSelected(store.value, itemId)),
|
|
40
|
+
removed: oldModel.filter(itemId => !newModelLookup.has(itemId))
|
|
31
41
|
};
|
|
32
42
|
};
|
|
33
43
|
export const propagateSelection = ({
|
|
34
|
-
|
|
44
|
+
store,
|
|
35
45
|
selectionPropagation,
|
|
36
46
|
newModel,
|
|
37
47
|
oldModel,
|
|
@@ -43,7 +53,7 @@ export const propagateSelection = ({
|
|
|
43
53
|
let shouldRegenerateModel = false;
|
|
44
54
|
const newModelLookup = getLookupFromArray(newModel);
|
|
45
55
|
const changes = getAddedAndRemovedItems({
|
|
46
|
-
|
|
56
|
+
store,
|
|
47
57
|
newModel,
|
|
48
58
|
oldModel
|
|
49
59
|
});
|
|
@@ -63,7 +73,7 @@ export const propagateSelection = ({
|
|
|
63
73
|
shouldRegenerateModel = true;
|
|
64
74
|
newModelLookup[itemId] = true;
|
|
65
75
|
}
|
|
66
|
-
|
|
76
|
+
selectorItemOrderedChildrenIds(store.value, itemId).forEach(selectDescendants);
|
|
67
77
|
};
|
|
68
78
|
selectDescendants(addedItemId);
|
|
69
79
|
}
|
|
@@ -72,15 +82,15 @@ export const propagateSelection = ({
|
|
|
72
82
|
if (!newModelLookup[itemId]) {
|
|
73
83
|
return false;
|
|
74
84
|
}
|
|
75
|
-
const children =
|
|
85
|
+
const children = selectorItemOrderedChildrenIds(store.value, itemId);
|
|
76
86
|
return children.every(checkAllDescendantsSelected);
|
|
77
87
|
};
|
|
78
88
|
const selectParents = itemId => {
|
|
79
|
-
const parentId =
|
|
89
|
+
const parentId = selectorItemParentId(store.value, itemId);
|
|
80
90
|
if (parentId == null) {
|
|
81
91
|
return;
|
|
82
92
|
}
|
|
83
|
-
const siblings =
|
|
93
|
+
const siblings = selectorItemOrderedChildrenIds(store.value, parentId);
|
|
84
94
|
if (siblings.every(checkAllDescendantsSelected)) {
|
|
85
95
|
shouldRegenerateModel = true;
|
|
86
96
|
newModelLookup[parentId] = true;
|
|
@@ -92,13 +102,13 @@ export const propagateSelection = ({
|
|
|
92
102
|
});
|
|
93
103
|
changes.removed.forEach(removedItemId => {
|
|
94
104
|
if (selectionPropagation.parents) {
|
|
95
|
-
let parentId =
|
|
105
|
+
let parentId = selectorItemParentId(store.value, removedItemId);
|
|
96
106
|
while (parentId != null) {
|
|
97
107
|
if (newModelLookup[parentId]) {
|
|
98
108
|
shouldRegenerateModel = true;
|
|
99
109
|
delete newModelLookup[parentId];
|
|
100
110
|
}
|
|
101
|
-
parentId =
|
|
111
|
+
parentId = selectorItemParentId(store.value, parentId);
|
|
102
112
|
}
|
|
103
113
|
}
|
|
104
114
|
if (selectionPropagation.descendants) {
|
|
@@ -107,7 +117,7 @@ export const propagateSelection = ({
|
|
|
107
117
|
shouldRegenerateModel = true;
|
|
108
118
|
delete newModelLookup[itemId];
|
|
109
119
|
}
|
|
110
|
-
|
|
120
|
+
selectorItemOrderedChildrenIds(store.value, itemId).forEach(deSelectDescendants);
|
|
111
121
|
};
|
|
112
122
|
deSelectDescendants(removedItemId);
|
|
113
123
|
}
|