@mui/x-tree-view 7.0.0-beta.7 → 7.1.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 +266 -12
- package/README.md +1 -1
- package/RichTreeView/RichTreeView.js +15 -17
- package/RichTreeView/RichTreeView.types.d.ts +1 -1
- package/SimpleTreeView/SimpleTreeView.js +3 -4
- package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
- package/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/TreeItem/TreeItem.js +43 -35
- package/TreeItem/TreeItem.types.d.ts +3 -3
- package/TreeItem/TreeItemContent.d.ts +7 -7
- package/TreeItem/TreeItemContent.js +10 -10
- package/TreeItem/treeItemClasses.d.ts +1 -1
- package/TreeItem/useTreeItemState.d.ts +1 -1
- package/TreeItem/useTreeItemState.js +13 -13
- package/TreeItem2/TreeItem2.js +16 -17
- package/TreeItem2Icon/TreeItem2Icon.js +5 -6
- package/TreeItem2Icon/TreeItem2Icon.types.d.ts +4 -4
- package/TreeItem2Provider/TreeItem2Provider.js +3 -3
- package/TreeItem2Provider/TreeItem2Provider.types.d.ts +1 -1
- package/TreeView/TreeView.d.ts +1 -1
- package/TreeView/TreeView.js +1 -1
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +2 -2
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
- package/hooks/useTreeViewApiRef.d.ts +1 -1
- package/index.js +1 -1
- package/internals/TreeViewProvider/DescendantProvider.d.ts +1 -1
- package/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/internals/hooks/useInstanceEventHandler.js +5 -10
- package/internals/index.d.ts +2 -2
- package/internals/models/plugin.d.ts +1 -1
- package/internals/plugins/defaultPlugins.d.ts +3 -3
- package/internals/plugins/defaultPlugins.js +2 -2
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +17 -24
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -6
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +76 -58
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +9 -8
- package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +6 -6
- package/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
- package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +2 -2
- package/internals/plugins/useTreeViewItems/index.d.ts +2 -0
- package/internals/plugins/useTreeViewItems/index.js +1 -0
- package/internals/plugins/useTreeViewItems/useTreeViewItems.d.ts +3 -0
- package/{modern/internals/plugins/useTreeViewNodes/useTreeViewNodes.js → internals/plugins/useTreeViewItems/useTreeViewItems.js} +42 -33
- package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +99 -0
- package/internals/plugins/useTreeViewJSXItems/index.d.ts +2 -0
- package/internals/plugins/useTreeViewJSXItems/index.js +1 -0
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.d.ts +3 -0
- package/{modern/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +41 -40
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +18 -0
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +85 -96
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +6 -3
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +44 -47
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +8 -8
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +7 -7
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/internals/useTreeView/useTreeView.js +5 -6
- package/internals/useTreeView/useTreeView.utils.d.ts +5 -5
- package/internals/useTreeView/useTreeView.utils.js +18 -18
- package/internals/utils/extractPluginParamsFromProps.js +2 -2
- package/internals/utils/utils.js +1 -0
- package/modern/RichTreeView/RichTreeView.js +11 -11
- package/modern/SimpleTreeView/SimpleTreeView.js +1 -1
- package/modern/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/modern/TreeItem/TreeItem.js +31 -22
- package/modern/TreeItem/TreeItemContent.js +10 -10
- package/modern/TreeItem/useTreeItemState.js +13 -13
- package/modern/TreeItem2/TreeItem2.js +11 -11
- package/modern/TreeItem2Provider/TreeItem2Provider.js +3 -3
- package/modern/TreeView/TreeView.js +1 -1
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
- package/modern/index.js +1 -1
- package/modern/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/modern/internals/plugins/defaultPlugins.js +2 -2
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +14 -14
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +74 -53
- package/modern/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
- package/modern/internals/plugins/useTreeViewItems/index.js +1 -0
- package/{internals/plugins/useTreeViewNodes/useTreeViewNodes.js → modern/internals/plugins/useTreeViewItems/useTreeViewItems.js} +46 -41
- package/modern/internals/plugins/useTreeViewJSXItems/index.js +1 -0
- package/{internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +41 -41
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +85 -94
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +40 -40
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/modern/internals/useTreeView/useTreeView.js +3 -4
- package/modern/internals/useTreeView/useTreeView.utils.js +18 -18
- package/modern/internals/utils/utils.js +1 -0
- package/modern/useTreeItem2/useTreeItem2.js +23 -12
- package/node/RichTreeView/RichTreeView.js +11 -11
- package/node/SimpleTreeView/SimpleTreeView.js +1 -1
- package/node/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/node/TreeItem/TreeItem.js +31 -22
- package/node/TreeItem/TreeItemContent.js +10 -10
- package/node/TreeItem/useTreeItemState.js +13 -13
- package/node/TreeItem2/TreeItem2.js +11 -11
- package/node/TreeItem2Provider/TreeItem2Provider.js +3 -3
- package/node/TreeView/TreeView.js +1 -1
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
- package/node/index.js +1 -1
- package/node/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/node/internals/plugins/defaultPlugins.js +2 -2
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +14 -14
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +74 -53
- package/node/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
- package/node/internals/plugins/useTreeViewItems/index.js +12 -0
- package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +44 -35
- package/node/internals/plugins/useTreeViewJSXItems/index.js +12 -0
- package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.js → useTreeViewJSXItems/useTreeViewJSXItems.js} +43 -42
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +84 -93
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +39 -39
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/node/internals/useTreeView/useTreeView.js +3 -4
- package/node/internals/useTreeView/useTreeView.utils.js +23 -23
- package/node/internals/utils/utils.js +1 -0
- package/node/useTreeItem2/useTreeItem2.js +23 -12
- package/package.json +5 -5
- package/useTreeItem2/useTreeItem2.d.ts +1 -1
- package/useTreeItem2/useTreeItem2.js +26 -18
- package/useTreeItem2/useTreeItem2.types.d.ts +9 -7
- package/internals/plugins/useTreeViewJSXNodes/index.d.ts +0 -2
- package/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
- package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.d.ts +0 -3
- package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.d.ts +0 -18
- package/internals/plugins/useTreeViewNodes/index.d.ts +0 -2
- package/internals/plugins/useTreeViewNodes/index.js +0 -1
- package/internals/plugins/useTreeViewNodes/useTreeViewNodes.d.ts +0 -3
- package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.d.ts +0 -88
- package/modern/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
- package/modern/internals/plugins/useTreeViewNodes/index.js +0 -1
- package/node/internals/plugins/useTreeViewJSXNodes/index.js +0 -12
- package/node/internals/plugins/useTreeViewNodes/index.js +0 -12
- /package/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
- /package/modern/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
- /package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useTreeViewContext } from '../../internals/TreeViewProvider/useTreeViewContext';
|
|
2
2
|
export const useTreeItem2Utils = ({
|
|
3
|
-
|
|
3
|
+
itemId,
|
|
4
4
|
children
|
|
5
5
|
}) => {
|
|
6
6
|
const {
|
|
@@ -11,23 +11,23 @@ export const useTreeItem2Utils = ({
|
|
|
11
11
|
} = useTreeViewContext();
|
|
12
12
|
const status = {
|
|
13
13
|
expandable: Boolean(Array.isArray(children) ? children.length : children),
|
|
14
|
-
expanded: instance.
|
|
15
|
-
focused: instance.
|
|
16
|
-
selected: instance.
|
|
17
|
-
disabled: instance.
|
|
14
|
+
expanded: instance.isItemExpanded(itemId),
|
|
15
|
+
focused: instance.isItemFocused(itemId),
|
|
16
|
+
selected: instance.isItemSelected(itemId),
|
|
17
|
+
disabled: instance.isItemDisabled(itemId)
|
|
18
18
|
};
|
|
19
19
|
const handleExpansion = event => {
|
|
20
20
|
if (status.disabled) {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
if (!status.focused) {
|
|
24
|
-
instance.focusItem(event,
|
|
24
|
+
instance.focusItem(event, itemId);
|
|
25
25
|
}
|
|
26
26
|
const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
|
|
27
27
|
|
|
28
28
|
// If already expanded and trying to toggle selection don't close
|
|
29
|
-
if (status.expandable && !(multiple && instance.
|
|
30
|
-
instance.
|
|
29
|
+
if (status.expandable && !(multiple && instance.isItemExpanded(itemId))) {
|
|
30
|
+
instance.toggleItemExpansion(event, itemId);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
const handleSelection = event => {
|
|
@@ -35,19 +35,19 @@ export const useTreeItem2Utils = ({
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
if (!status.focused) {
|
|
38
|
-
instance.focusItem(event,
|
|
38
|
+
instance.focusItem(event, itemId);
|
|
39
39
|
}
|
|
40
40
|
const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
|
|
41
41
|
if (multiple) {
|
|
42
42
|
if (event.shiftKey) {
|
|
43
43
|
instance.selectRange(event, {
|
|
44
|
-
end:
|
|
44
|
+
end: itemId
|
|
45
45
|
});
|
|
46
46
|
} else {
|
|
47
|
-
instance.
|
|
47
|
+
instance.selectItem(event, itemId, true);
|
|
48
48
|
}
|
|
49
49
|
} else {
|
|
50
|
-
instance.
|
|
50
|
+
instance.selectItem(event, itemId);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
const interactions = {
|
|
@@ -3,4 +3,4 @@ import { TreeViewAnyPluginSignature, TreeViewPublicAPI } from '../internals/mode
|
|
|
3
3
|
/**
|
|
4
4
|
* Hook that instantiates a [[TreeViewApiRef]].
|
|
5
5
|
*/
|
|
6
|
-
export declare const useTreeViewApiRef: <TPlugins extends readonly TreeViewAnyPluginSignature[] = [import("../internals").UseTreeViewIdSignature, import("../internals").
|
|
6
|
+
export declare const useTreeViewApiRef: <TPlugins extends readonly TreeViewAnyPluginSignature[] = [import("../internals").UseTreeViewIdSignature, import("../internals").UseTreeViewItemsSignature, import("../internals").UseTreeViewExpansionSignature, import("../internals").UseTreeViewSelectionSignature, import("../internals").UseTreeViewFocusSignature, import("../internals").UseTreeViewKeyboardNavigationSignature, import("../internals").UseTreeViewIconsSignature]>() => React.MutableRefObject<TreeViewPublicAPI<TPlugins> | undefined>;
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
|
|
5
5
|
* We use this for focus management, keyboard navigation, and typeahead
|
|
6
6
|
* functionality for some components.
|
|
7
7
|
*
|
|
8
|
-
* The hook accepts the element
|
|
8
|
+
* The hook accepts the element item
|
|
9
9
|
*
|
|
10
10
|
* Our main goals with this are:
|
|
11
11
|
* 1) maximum composability,
|
|
@@ -46,7 +46,7 @@ const noop = () => {};
|
|
|
46
46
|
* We use this for focus management, keyboard navigation, and typeahead
|
|
47
47
|
* functionality for some components.
|
|
48
48
|
*
|
|
49
|
-
* The hook accepts the element
|
|
49
|
+
* The hook accepts the element item
|
|
50
50
|
*
|
|
51
51
|
* Our main goals with this are:
|
|
52
52
|
* 1) maximum composability,
|
|
@@ -20,8 +20,7 @@ export function createUseInstanceEventHandler(registryContainer) {
|
|
|
20
20
|
if (!subscription.current && handlerRef.current) {
|
|
21
21
|
const enhancedHandler = (params, event) => {
|
|
22
22
|
if (!event.defaultMuiPrevented) {
|
|
23
|
-
|
|
24
|
-
(_handlerRef$current = handlerRef.current) == null || _handlerRef$current.call(handlerRef, params, event);
|
|
23
|
+
handlerRef.current?.(params, event);
|
|
25
24
|
}
|
|
26
25
|
};
|
|
27
26
|
subscription.current = instance.$$subscribeEvent(eventName, enhancedHandler);
|
|
@@ -32,8 +31,7 @@ export function createUseInstanceEventHandler(registryContainer) {
|
|
|
32
31
|
registryContainer.registry.register(objectRetainedByReact,
|
|
33
32
|
// The callback below will be called once this reference stops being retained
|
|
34
33
|
() => {
|
|
35
|
-
|
|
36
|
-
(_subscription$current = subscription.current) == null || _subscription$current.call(subscription);
|
|
34
|
+
subscription.current?.();
|
|
37
35
|
subscription.current = null;
|
|
38
36
|
cleanupTokenRef.current = null;
|
|
39
37
|
}, cleanupTokenRef.current);
|
|
@@ -49,8 +47,7 @@ export function createUseInstanceEventHandler(registryContainer) {
|
|
|
49
47
|
if (!subscription.current && handlerRef.current) {
|
|
50
48
|
const enhancedHandler = (params, event) => {
|
|
51
49
|
if (!event.defaultMuiPrevented) {
|
|
52
|
-
|
|
53
|
-
(_handlerRef$current2 = handlerRef.current) == null || _handlerRef$current2.call(handlerRef, params, event);
|
|
50
|
+
handlerRef.current?.(params, event);
|
|
54
51
|
}
|
|
55
52
|
};
|
|
56
53
|
subscription.current = instance.$$subscribeEvent(eventName, enhancedHandler);
|
|
@@ -62,8 +59,7 @@ export function createUseInstanceEventHandler(registryContainer) {
|
|
|
62
59
|
cleanupTokenRef.current = null;
|
|
63
60
|
}
|
|
64
61
|
return () => {
|
|
65
|
-
|
|
66
|
-
(_subscription$current2 = subscription.current) == null || _subscription$current2.call(subscription);
|
|
62
|
+
subscription.current?.();
|
|
67
63
|
subscription.current = null;
|
|
68
64
|
};
|
|
69
65
|
}, [instance, eventName]);
|
|
@@ -75,8 +71,7 @@ const registryContainer = {
|
|
|
75
71
|
|
|
76
72
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
77
73
|
export const unstable_resetCleanupTracking = () => {
|
|
78
|
-
|
|
79
|
-
(_registryContainer$re = registryContainer.registry) == null || _registryContainer$re.reset();
|
|
74
|
+
registryContainer.registry?.reset();
|
|
80
75
|
registryContainer.registry = null;
|
|
81
76
|
};
|
|
82
77
|
export const useInstanceEventHandler = createUseInstanceEventHandler(registryContainer);
|
package/internals/index.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ export type { UseTreeViewFocusSignature } from './plugins/useTreeViewFocus';
|
|
|
10
10
|
export type { UseTreeViewKeyboardNavigationSignature } from './plugins/useTreeViewKeyboardNavigation';
|
|
11
11
|
export type { UseTreeViewIdSignature } from './plugins/useTreeViewId';
|
|
12
12
|
export type { UseTreeViewIconsSignature } from './plugins/useTreeViewIcons';
|
|
13
|
-
export type {
|
|
14
|
-
export type {
|
|
13
|
+
export type { UseTreeViewItemsSignature } from './plugins/useTreeViewItems';
|
|
14
|
+
export type { UseTreeViewJSXItemsSignature } from './plugins/useTreeViewJSXItems';
|
|
15
15
|
export { extractPluginParamsFromProps } from './utils/extractPluginParamsFromProps';
|
|
@@ -132,7 +132,7 @@ export interface TreeViewItemPluginResponse {
|
|
|
132
132
|
}
|
|
133
133
|
export type TreeViewItemPlugin<TProps extends {}> = (options: TreeViewItemPluginOptions<TProps>) => void | TreeViewItemPluginResponse;
|
|
134
134
|
export type TreeItemWrapper = (params: {
|
|
135
|
-
|
|
135
|
+
itemId: TreeViewItemId;
|
|
136
136
|
children: React.ReactNode;
|
|
137
137
|
}) => React.ReactNode;
|
|
138
138
|
export type TreeViewPlugin<TSignature extends TreeViewAnyPluginSignature> = {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { UseTreeViewIdParameters } from './useTreeViewId';
|
|
2
|
-
import {
|
|
2
|
+
import { UseTreeViewItemsParameters } from './useTreeViewItems';
|
|
3
3
|
import { UseTreeViewExpansionParameters } from './useTreeViewExpansion';
|
|
4
4
|
import { UseTreeViewSelectionParameters } from './useTreeViewSelection';
|
|
5
5
|
import { UseTreeViewFocusParameters } from './useTreeViewFocus';
|
|
6
6
|
import { UseTreeViewIconsParameters } from './useTreeViewIcons';
|
|
7
7
|
import { ConvertPluginsIntoSignatures, MergePluginsProperty } from '../models';
|
|
8
|
-
export declare const DEFAULT_TREE_VIEW_PLUGINS: readonly [import("../models").TreeViewPlugin<import("./useTreeViewId").UseTreeViewIdSignature>, import("../models").TreeViewPlugin<import("./
|
|
8
|
+
export declare const DEFAULT_TREE_VIEW_PLUGINS: readonly [import("../models").TreeViewPlugin<import("./useTreeViewId").UseTreeViewIdSignature>, import("../models").TreeViewPlugin<import("./useTreeViewItems").UseTreeViewItemsSignature>, import("../models").TreeViewPlugin<import("./useTreeViewExpansion").UseTreeViewExpansionSignature>, import("../models").TreeViewPlugin<import("./useTreeViewSelection").UseTreeViewSelectionSignature>, import("../models").TreeViewPlugin<import("./useTreeViewFocus").UseTreeViewFocusSignature>, import("../models").TreeViewPlugin<import("./useTreeViewKeyboardNavigation").UseTreeViewKeyboardNavigationSignature>, import("../models").TreeViewPlugin<import("./useTreeViewIcons").UseTreeViewIconsSignature>];
|
|
9
9
|
export type DefaultTreeViewPlugins = ConvertPluginsIntoSignatures<typeof DEFAULT_TREE_VIEW_PLUGINS>;
|
|
10
10
|
export type DefaultTreeViewPluginSlots = MergePluginsProperty<DefaultTreeViewPlugins, 'slots'>;
|
|
11
11
|
export type DefaultTreeViewPluginSlotProps = MergePluginsProperty<DefaultTreeViewPlugins, 'slotProps'>;
|
|
12
|
-
export interface DefaultTreeViewPluginParameters<R extends {}, Multiple extends boolean | undefined> extends UseTreeViewIdParameters,
|
|
12
|
+
export interface DefaultTreeViewPluginParameters<R extends {}, Multiple extends boolean | undefined> extends UseTreeViewIdParameters, UseTreeViewItemsParameters<R>, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, UseTreeViewSelectionParameters<Multiple>, UseTreeViewIconsParameters {
|
|
13
13
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useTreeViewId } from './useTreeViewId';
|
|
2
|
-
import {
|
|
2
|
+
import { useTreeViewItems } from './useTreeViewItems';
|
|
3
3
|
import { useTreeViewExpansion } from './useTreeViewExpansion';
|
|
4
4
|
import { useTreeViewSelection } from './useTreeViewSelection';
|
|
5
5
|
import { useTreeViewFocus } from './useTreeViewFocus';
|
|
6
6
|
import { useTreeViewKeyboardNavigation } from './useTreeViewKeyboardNavigation';
|
|
7
7
|
import { useTreeViewIcons } from './useTreeViewIcons';
|
|
8
|
-
export const DEFAULT_TREE_VIEW_PLUGINS = [useTreeViewId,
|
|
8
|
+
export const DEFAULT_TREE_VIEW_PLUGINS = [useTreeViewId, useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
|
|
9
9
|
|
|
10
10
|
// We can't infer this type from the plugin, otherwise we would lose the generics.
|
|
@@ -8,18 +8,14 @@ export const useTreeViewExpansion = ({
|
|
|
8
8
|
models
|
|
9
9
|
}) => {
|
|
10
10
|
const setExpandedItems = (event, value) => {
|
|
11
|
-
|
|
12
|
-
(_params$onExpandedIte = params.onExpandedItemsChange) == null || _params$onExpandedIte.call(params, event, value);
|
|
11
|
+
params.onExpandedItemsChange?.(event, value);
|
|
13
12
|
models.expandedItems.setControlledValue(value);
|
|
14
13
|
};
|
|
15
|
-
const
|
|
16
|
-
return Array.isArray(models.expandedItems.value) ? models.expandedItems.value.indexOf(
|
|
14
|
+
const isItemExpanded = React.useCallback(itemId => {
|
|
15
|
+
return Array.isArray(models.expandedItems.value) ? models.expandedItems.value.indexOf(itemId) !== -1 : false;
|
|
17
16
|
}, [models.expandedItems.value]);
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
return !!((_instance$getNode = instance.getNode(nodeId)) != null && _instance$getNode.expandable);
|
|
21
|
-
}, [instance]);
|
|
22
|
-
const toggleNodeExpansion = useEventCallback((event, itemId) => {
|
|
17
|
+
const isItemExpandable = React.useCallback(itemId => !!instance.getNode(itemId)?.expandable, [instance]);
|
|
18
|
+
const toggleItemExpansion = useEventCallback((event, itemId) => {
|
|
23
19
|
if (itemId == null) {
|
|
24
20
|
return;
|
|
25
21
|
}
|
|
@@ -35,24 +31,24 @@ export const useTreeViewExpansion = ({
|
|
|
35
31
|
}
|
|
36
32
|
setExpandedItems(event, newExpanded);
|
|
37
33
|
});
|
|
38
|
-
const expandAllSiblings = (event,
|
|
39
|
-
const node = instance.getNode(
|
|
34
|
+
const expandAllSiblings = (event, itemId) => {
|
|
35
|
+
const node = instance.getNode(itemId);
|
|
40
36
|
const siblings = instance.getChildrenIds(node.parentId);
|
|
41
|
-
const diff = siblings.filter(child => instance.
|
|
37
|
+
const diff = siblings.filter(child => instance.isItemExpandable(child) && !instance.isItemExpanded(child));
|
|
42
38
|
const newExpanded = models.expandedItems.value.concat(diff);
|
|
43
39
|
if (diff.length > 0) {
|
|
44
40
|
if (params.onItemExpansionToggle) {
|
|
45
|
-
diff.forEach(
|
|
46
|
-
params.onItemExpansionToggle(event,
|
|
41
|
+
diff.forEach(newlyExpandedItemId => {
|
|
42
|
+
params.onItemExpansionToggle(event, newlyExpandedItemId, true);
|
|
47
43
|
});
|
|
48
44
|
}
|
|
49
45
|
setExpandedItems(event, newExpanded);
|
|
50
46
|
}
|
|
51
47
|
};
|
|
52
48
|
populateInstance(instance, {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
isItemExpanded,
|
|
50
|
+
isItemExpandable,
|
|
51
|
+
toggleItemExpansion,
|
|
56
52
|
expandAllSiblings
|
|
57
53
|
});
|
|
58
54
|
};
|
|
@@ -61,13 +57,10 @@ useTreeViewExpansion.models = {
|
|
|
61
57
|
getDefaultValue: params => params.defaultExpandedItems
|
|
62
58
|
}
|
|
63
59
|
};
|
|
64
|
-
const
|
|
65
|
-
useTreeViewExpansion.getDefaultizedParams = params => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
defaultExpandedItems: (_params$defaultExpand = params.defaultExpandedItems) != null ? _params$defaultExpand : DEFAULT_EXPANDED_NODES
|
|
69
|
-
});
|
|
70
|
-
};
|
|
60
|
+
const DEFAULT_EXPANDED_ITEMS = [];
|
|
61
|
+
useTreeViewExpansion.getDefaultizedParams = params => _extends({}, params, {
|
|
62
|
+
defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS
|
|
63
|
+
});
|
|
71
64
|
useTreeViewExpansion.params = {
|
|
72
65
|
expandedItems: true,
|
|
73
66
|
defaultExpandedItems: true,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { DefaultizedProps, TreeViewPluginSignature } from '../../models';
|
|
3
|
-
import {
|
|
3
|
+
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
4
4
|
export interface UseTreeViewExpansionInstance {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
expandAllSiblings: (event: React.KeyboardEvent
|
|
5
|
+
isItemExpanded: (itemId: string) => boolean;
|
|
6
|
+
isItemExpandable: (itemId: string) => boolean;
|
|
7
|
+
toggleItemExpansion: (event: React.SyntheticEvent, value: string) => void;
|
|
8
|
+
expandAllSiblings: (event: React.KeyboardEvent, itemId: string) => void;
|
|
9
9
|
}
|
|
10
10
|
export interface UseTreeViewExpansionParameters {
|
|
11
11
|
/**
|
|
@@ -39,5 +39,5 @@ export type UseTreeViewExpansionSignature = TreeViewPluginSignature<{
|
|
|
39
39
|
defaultizedParams: UseTreeViewExpansionDefaultizedParameters;
|
|
40
40
|
instance: UseTreeViewExpansionInstance;
|
|
41
41
|
modelNames: 'expandedItems';
|
|
42
|
-
dependantPlugins: [
|
|
42
|
+
dependantPlugins: [UseTreeViewItemsSignature];
|
|
43
43
|
}>;
|
|
@@ -5,6 +5,22 @@ import ownerDocument from '@mui/utils/ownerDocument';
|
|
|
5
5
|
import { populateInstance, populatePublicAPI } from '../../useTreeView/useTreeView.utils';
|
|
6
6
|
import { useInstanceEventHandler } from '../../hooks/useInstanceEventHandler';
|
|
7
7
|
import { getActiveElement } from '../../utils/utils';
|
|
8
|
+
const useTabbableItemId = (instance, selectedItems) => {
|
|
9
|
+
const isItemVisible = itemId => {
|
|
10
|
+
const node = instance.getNode(itemId);
|
|
11
|
+
return node && (node.parentId == null || instance.isItemExpanded(node.parentId));
|
|
12
|
+
};
|
|
13
|
+
let tabbableItemId;
|
|
14
|
+
if (Array.isArray(selectedItems)) {
|
|
15
|
+
tabbableItemId = selectedItems.find(isItemVisible);
|
|
16
|
+
} else if (selectedItems != null && isItemVisible(selectedItems)) {
|
|
17
|
+
tabbableItemId = selectedItems;
|
|
18
|
+
}
|
|
19
|
+
if (tabbableItemId == null) {
|
|
20
|
+
tabbableItemId = instance.getNavigableChildrenIds(null)[0];
|
|
21
|
+
}
|
|
22
|
+
return tabbableItemId;
|
|
23
|
+
};
|
|
8
24
|
export const useTreeViewFocus = ({
|
|
9
25
|
instance,
|
|
10
26
|
publicAPI,
|
|
@@ -14,97 +30,99 @@ export const useTreeViewFocus = ({
|
|
|
14
30
|
models,
|
|
15
31
|
rootRef
|
|
16
32
|
}) => {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
const tabbableItemId = useTabbableItemId(instance, models.selectedItems.value);
|
|
34
|
+
const setFocusedItemId = useEventCallback(itemId => {
|
|
35
|
+
const cleanItemId = typeof itemId === 'function' ? itemId(state.focusedItemId) : itemId;
|
|
36
|
+
if (state.focusedItemId !== cleanItemId) {
|
|
20
37
|
setState(prevState => _extends({}, prevState, {
|
|
21
|
-
|
|
38
|
+
focusedItemId: cleanItemId
|
|
22
39
|
}));
|
|
23
40
|
}
|
|
24
41
|
});
|
|
25
|
-
const isTreeViewFocused = React.useCallback(() => !!rootRef.current && rootRef.current
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const node = instance.getNode(
|
|
29
|
-
return node && (node.parentId == null || instance.
|
|
42
|
+
const isTreeViewFocused = React.useCallback(() => !!rootRef.current && rootRef.current.contains(getActiveElement(ownerDocument(rootRef.current))), [rootRef]);
|
|
43
|
+
const isItemFocused = React.useCallback(itemId => state.focusedItemId === itemId && isTreeViewFocused(), [state.focusedItemId, isTreeViewFocused]);
|
|
44
|
+
const isItemVisible = itemId => {
|
|
45
|
+
const node = instance.getNode(itemId);
|
|
46
|
+
return node && (node.parentId == null || instance.isItemExpanded(node.parentId));
|
|
30
47
|
};
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
const innerFocusItem = (event, itemId) => {
|
|
49
|
+
const node = instance.getNode(itemId);
|
|
50
|
+
const itemElement = document.getElementById(instance.getTreeItemId(itemId, node.idAttribute));
|
|
51
|
+
if (itemElement) {
|
|
52
|
+
itemElement.focus();
|
|
53
|
+
}
|
|
54
|
+
setFocusedItemId(itemId);
|
|
55
|
+
if (params.onItemFocus) {
|
|
56
|
+
params.onItemFocus(event, itemId);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const focusItem = useEventCallback((event, itemId) => {
|
|
60
|
+
// If we receive an itemId, and it is visible, the focus will be set to it
|
|
61
|
+
if (isItemVisible(itemId)) {
|
|
62
|
+
innerFocusItem(event, itemId);
|
|
41
63
|
}
|
|
42
64
|
});
|
|
43
|
-
const
|
|
44
|
-
let
|
|
65
|
+
const focusDefaultItem = useEventCallback(event => {
|
|
66
|
+
let itemToFocusId;
|
|
45
67
|
if (Array.isArray(models.selectedItems.value)) {
|
|
46
|
-
|
|
47
|
-
} else if (models.selectedItems.value != null &&
|
|
48
|
-
|
|
68
|
+
itemToFocusId = models.selectedItems.value.find(isItemVisible);
|
|
69
|
+
} else if (models.selectedItems.value != null && isItemVisible(models.selectedItems.value)) {
|
|
70
|
+
itemToFocusId = models.selectedItems.value;
|
|
49
71
|
}
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
setFocusedNodeId(nodeToFocusId);
|
|
54
|
-
if (params.onItemFocus) {
|
|
55
|
-
params.onItemFocus(event, nodeToFocusId);
|
|
72
|
+
if (itemToFocusId == null) {
|
|
73
|
+
itemToFocusId = instance.getNavigableChildrenIds(null)[0];
|
|
56
74
|
}
|
|
75
|
+
innerFocusItem(event, itemToFocusId);
|
|
57
76
|
});
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
const removeFocusedItem = useEventCallback(() => {
|
|
78
|
+
if (state.focusedItemId == null) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const node = instance.getNode(state.focusedItemId);
|
|
82
|
+
if (node) {
|
|
83
|
+
const itemElement = document.getElementById(instance.getTreeItemId(state.focusedItemId, node.idAttribute));
|
|
84
|
+
if (itemElement) {
|
|
85
|
+
itemElement.blur();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
setFocusedItemId(null);
|
|
63
89
|
});
|
|
90
|
+
const canItemBeTabbed = itemId => itemId === tabbableItemId;
|
|
64
91
|
populateInstance(instance, {
|
|
65
|
-
|
|
92
|
+
isItemFocused,
|
|
93
|
+
canItemBeTabbed,
|
|
66
94
|
focusItem,
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
focusDefaultItem,
|
|
96
|
+
removeFocusedItem
|
|
69
97
|
});
|
|
70
98
|
populatePublicAPI(publicAPI, {
|
|
71
99
|
focusItem
|
|
72
100
|
});
|
|
73
|
-
useInstanceEventHandler(instance, '
|
|
101
|
+
useInstanceEventHandler(instance, 'removeItem', ({
|
|
74
102
|
id
|
|
75
103
|
}) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
return oldFocusedNodeId;
|
|
81
|
-
});
|
|
104
|
+
if (state.focusedItemId === id) {
|
|
105
|
+
instance.focusDefaultItem(null);
|
|
106
|
+
}
|
|
82
107
|
});
|
|
83
108
|
const createHandleFocus = otherHandlers => event => {
|
|
84
|
-
|
|
85
|
-
(_otherHandlers$onFocu = otherHandlers.onFocus) == null || _otherHandlers$onFocu.call(otherHandlers, event);
|
|
109
|
+
otherHandlers.onFocus?.(event);
|
|
86
110
|
// if the event bubbled (which is React specific) we don't want to steal focus
|
|
87
111
|
if (event.target === event.currentTarget) {
|
|
88
|
-
instance.
|
|
112
|
+
instance.focusDefaultItem(event);
|
|
89
113
|
}
|
|
90
114
|
};
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
(_otherHandlers$onBlur = otherHandlers.onBlur) == null || _otherHandlers$onBlur.call(otherHandlers, event);
|
|
94
|
-
setFocusedNodeId(null);
|
|
95
|
-
};
|
|
96
|
-
const focusedNode = instance.getNode(state.focusedNodeId);
|
|
97
|
-
const activeDescendant = focusedNode ? instance.getTreeItemId(focusedNode.id, focusedNode.idAttribute) : null;
|
|
115
|
+
const focusedItem = instance.getNode(state.focusedItemId);
|
|
116
|
+
const activeDescendant = focusedItem ? instance.getTreeItemId(focusedItem.id, focusedItem.idAttribute) : null;
|
|
98
117
|
return {
|
|
99
118
|
getRootProps: otherHandlers => ({
|
|
100
119
|
onFocus: createHandleFocus(otherHandlers),
|
|
101
|
-
|
|
102
|
-
'aria-activedescendant': activeDescendant != null ? activeDescendant : undefined
|
|
120
|
+
'aria-activedescendant': activeDescendant ?? undefined
|
|
103
121
|
})
|
|
104
122
|
};
|
|
105
123
|
};
|
|
106
124
|
useTreeViewFocus.getInitialState = () => ({
|
|
107
|
-
|
|
125
|
+
focusedItemId: null
|
|
108
126
|
});
|
|
109
127
|
useTreeViewFocus.params = {
|
|
110
128
|
onItemFocus: true
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { TreeViewPluginSignature } from '../../models';
|
|
3
3
|
import { UseTreeViewIdSignature } from '../useTreeViewId/useTreeViewId.types';
|
|
4
|
-
import type {
|
|
4
|
+
import type { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
5
5
|
import type { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
|
|
6
6
|
import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
|
|
7
7
|
export interface UseTreeViewFocusInstance {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
isItemFocused: (itemId: string) => boolean;
|
|
9
|
+
canItemBeTabbed: (itemId: string) => boolean;
|
|
10
|
+
focusItem: (event: React.SyntheticEvent, itemId: string) => void;
|
|
11
|
+
focusDefaultItem: (event: React.SyntheticEvent | null) => void;
|
|
12
|
+
removeFocusedItem: () => void;
|
|
12
13
|
}
|
|
13
14
|
export interface UseTreeViewFocusPublicAPI extends Pick<UseTreeViewFocusInstance, 'focusItem'> {
|
|
14
15
|
}
|
|
@@ -19,11 +20,11 @@ export interface UseTreeViewFocusParameters {
|
|
|
19
20
|
* @param {string} itemId The id of the focused item.
|
|
20
21
|
* @param {string} value of the focused item.
|
|
21
22
|
*/
|
|
22
|
-
onItemFocus?: (event: React.SyntheticEvent, itemId: string) => void;
|
|
23
|
+
onItemFocus?: (event: React.SyntheticEvent | null, itemId: string) => void;
|
|
23
24
|
}
|
|
24
25
|
export type UseTreeViewFocusDefaultizedParameters = UseTreeViewFocusParameters;
|
|
25
26
|
export interface UseTreeViewFocusState {
|
|
26
|
-
|
|
27
|
+
focusedItemId: string | null;
|
|
27
28
|
}
|
|
28
29
|
export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
|
|
29
30
|
params: UseTreeViewFocusParameters;
|
|
@@ -33,7 +34,7 @@ export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
|
|
|
33
34
|
state: UseTreeViewFocusState;
|
|
34
35
|
dependantPlugins: [
|
|
35
36
|
UseTreeViewIdSignature,
|
|
36
|
-
|
|
37
|
+
UseTreeViewItemsSignature,
|
|
37
38
|
UseTreeViewSelectionSignature,
|
|
38
39
|
UseTreeViewExpansionSignature
|
|
39
40
|
];
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { SlotComponentProps } from '@mui/base/utils';
|
|
3
3
|
import { TreeViewPluginSignature } from '../../models';
|
|
4
|
-
import {
|
|
4
|
+
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
5
5
|
import { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
|
|
6
6
|
export interface UseTreeViewIconsParameters {
|
|
7
7
|
}
|
|
8
8
|
export type UseTreeViewIconsDefaultizedParameters = UseTreeViewIconsParameters;
|
|
9
9
|
interface UseTreeViewIconsSlots {
|
|
10
10
|
/**
|
|
11
|
-
* The default icon used to collapse the
|
|
11
|
+
* The default icon used to collapse the item.
|
|
12
12
|
*/
|
|
13
13
|
collapseIcon?: React.ElementType;
|
|
14
14
|
/**
|
|
15
|
-
* The default icon used to expand the
|
|
15
|
+
* The default icon used to expand the item.
|
|
16
16
|
*/
|
|
17
17
|
expandIcon?: React.ElementType;
|
|
18
18
|
/**
|
|
19
|
-
* The default icon displayed next to an end
|
|
20
|
-
* This is applied to all tree
|
|
19
|
+
* The default icon displayed next to an end item.
|
|
20
|
+
* This is applied to all tree items and can be overridden by the TreeItem `icon` slot prop.
|
|
21
21
|
*/
|
|
22
22
|
endIcon?: React.ElementType;
|
|
23
23
|
}
|
|
@@ -38,6 +38,6 @@ export type UseTreeViewIconsSignature = TreeViewPluginSignature<{
|
|
|
38
38
|
contextValue: UseTreeViewIconsContextValue;
|
|
39
39
|
slots: UseTreeViewIconsSlots;
|
|
40
40
|
slotProps: UseTreeViewIconsSlotProps;
|
|
41
|
-
dependantPlugins: [
|
|
41
|
+
dependantPlugins: [UseTreeViewItemsSignature, UseTreeViewSelectionSignature];
|
|
42
42
|
}>;
|
|
43
43
|
export {};
|
|
@@ -6,7 +6,7 @@ export const useTreeViewId = ({
|
|
|
6
6
|
params
|
|
7
7
|
}) => {
|
|
8
8
|
const treeId = useId(params.id);
|
|
9
|
-
const getTreeItemId = React.useCallback((
|
|
9
|
+
const getTreeItemId = React.useCallback((itemId, idAttribute) => idAttribute ?? `${treeId}-${itemId}`, [treeId]);
|
|
10
10
|
populateInstance(instance, {
|
|
11
11
|
getTreeItemId
|
|
12
12
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TreeViewPluginSignature } from '../../models';
|
|
2
2
|
export interface UseTreeViewIdInstance {
|
|
3
|
-
getTreeItemId: (
|
|
3
|
+
getTreeItemId: (itemId: string, idAttribute: string | undefined) => string;
|
|
4
4
|
}
|
|
5
5
|
export interface UseTreeViewIdParameters {
|
|
6
6
|
/**
|
|
@@ -11,7 +11,7 @@ export interface UseTreeViewIdParameters {
|
|
|
11
11
|
}
|
|
12
12
|
export type UseTreeViewIdDefaultizedParameters = UseTreeViewIdParameters;
|
|
13
13
|
export interface UseTreeViewIdState {
|
|
14
|
-
|
|
14
|
+
focusedItemId: string | null;
|
|
15
15
|
}
|
|
16
16
|
export type UseTreeViewIdSignature = TreeViewPluginSignature<{
|
|
17
17
|
params: UseTreeViewIdParameters;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useTreeViewItems } from './useTreeViewItems';
|