@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.
Files changed (159) hide show
  1. package/CHANGELOG.md +651 -6
  2. package/README.md +2 -2
  3. package/RichTreeView/RichTreeView.js +2 -4
  4. package/RichTreeView/RichTreeView.types.d.ts +5 -18
  5. package/SimpleTreeView/SimpleTreeView.types.d.ts +2 -2
  6. package/TreeItem/TreeItem.js +4 -4
  7. package/TreeItem/TreeItem.types.d.ts +4 -2
  8. package/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  9. package/TreeItemIcon/TreeItemIcon.types.d.ts +1 -1
  10. package/TreeItemProvider/TreeItemProvider.d.ts +2 -4
  11. package/TreeItemProvider/TreeItemProvider.js +26 -11
  12. package/TreeItemProvider/TreeItemProvider.types.d.ts +1 -0
  13. package/hooks/index.d.ts +1 -0
  14. package/hooks/index.js +2 -1
  15. package/hooks/useTreeItemModel.d.ts +2 -0
  16. package/hooks/useTreeItemModel.js +11 -0
  17. package/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +2 -1
  18. package/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  19. package/hooks/useTreeViewApiRef.d.ts +1 -0
  20. package/index.js +1 -1
  21. package/internals/TreeViewItemDepthContext/TreeViewItemDepthContext.d.ts +3 -1
  22. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.d.ts +2 -1
  23. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  24. package/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  25. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +4 -2
  26. package/internals/components/RichTreeViewItems.d.ts +3 -5
  27. package/internals/components/RichTreeViewItems.js +42 -30
  28. package/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  29. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.d.ts +36 -0
  30. package/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  31. package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +1 -5
  32. package/internals/hooks/useSelector.d.ts +4 -0
  33. package/internals/hooks/useSelector.js +6 -0
  34. package/internals/index.d.ts +6 -1
  35. package/internals/index.js +5 -1
  36. package/internals/models/itemPlugin.d.ts +5 -5
  37. package/internals/models/plugin.d.ts +20 -8
  38. package/internals/models/treeView.d.ts +6 -0
  39. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  40. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +124 -0
  41. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
  42. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -14
  43. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.d.ts +1 -0
  44. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
  45. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  46. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.d.ts +182 -0
  47. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  48. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +4 -16
  49. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  50. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
  51. package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
  52. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  53. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +718 -0
  54. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  55. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +15 -52
  56. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  57. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  58. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  59. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  60. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.d.ts +74 -0
  61. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  62. package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +7 -24
  63. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  64. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  65. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.d.ts +32 -0
  66. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  67. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
  68. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +6 -6
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  70. package/internals/useTreeView/useTreeView.js +30 -17
  71. package/internals/useTreeView/useTreeView.types.d.ts +2 -3
  72. package/internals/useTreeView/useTreeViewBuildContext.d.ts +3 -1
  73. package/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  74. package/internals/utils/TreeViewStore.d.ts +12 -0
  75. package/internals/utils/TreeViewStore.js +24 -0
  76. package/internals/utils/selectors.d.ts +9 -0
  77. package/internals/utils/selectors.js +37 -0
  78. package/internals/utils/tree.d.ts +8 -8
  79. package/internals/utils/tree.js +51 -43
  80. package/models/items.d.ts +3 -2
  81. package/modern/RichTreeView/RichTreeView.js +2 -4
  82. package/modern/TreeItem/TreeItem.js +4 -4
  83. package/modern/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +1 -1
  84. package/modern/TreeItemProvider/TreeItemProvider.js +26 -11
  85. package/modern/hooks/index.js +2 -1
  86. package/modern/hooks/useTreeItemModel.js +11 -0
  87. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +31 -15
  88. package/modern/index.js +1 -1
  89. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  90. package/modern/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  91. package/modern/internals/components/RichTreeViewItems.js +42 -30
  92. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +10 -11
  93. package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +9 -0
  94. package/modern/internals/hooks/useSelector.js +6 -0
  95. package/modern/internals/index.js +5 -1
  96. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  97. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +17 -0
  98. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +7 -0
  99. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  100. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +34 -0
  101. package/modern/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +15 -13
  102. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +58 -98
  103. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +103 -0
  104. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +29 -26
  105. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  106. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  107. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  108. package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +26 -0
  109. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  110. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +45 -34
  111. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +9 -0
  112. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +23 -13
  113. package/modern/internals/useTreeView/useTreeView.js +30 -17
  114. package/modern/internals/useTreeView/useTreeViewBuildContext.js +24 -18
  115. package/modern/internals/utils/TreeViewStore.js +24 -0
  116. package/modern/internals/utils/selectors.js +37 -0
  117. package/modern/internals/utils/tree.js +51 -43
  118. package/modern/useTreeItem/useTreeItem.js +26 -11
  119. package/node/RichTreeView/RichTreeView.js +2 -4
  120. package/node/TreeItem/TreeItem.js +4 -4
  121. package/node/TreeItemDragAndDropOverlay/TreeItemDragAndDropOverlay.js +2 -2
  122. package/node/TreeItemProvider/TreeItemProvider.js +26 -10
  123. package/node/hooks/index.js +8 -1
  124. package/node/hooks/useTreeItemModel.js +17 -0
  125. package/node/hooks/useTreeItemUtils/useTreeItemUtils.js +32 -15
  126. package/node/index.js +1 -1
  127. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +6 -22
  128. package/node/internals/TreeViewProvider/TreeViewProvider.js +1 -2
  129. package/node/internals/components/RichTreeViewItems.js +42 -30
  130. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +12 -13
  131. package/node/internals/corePlugins/useTreeViewId/useTreeViewId.selectors.js +15 -0
  132. package/node/internals/hooks/useSelector.js +13 -0
  133. package/node/internals/index.js +47 -1
  134. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +36 -24
  135. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js +23 -0
  136. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.utils.js +14 -0
  137. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +62 -40
  138. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js +40 -0
  139. package/node/internals/plugins/useTreeViewIcons/useTreeViewIcons.js +16 -13
  140. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +60 -100
  141. package/node/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +109 -0
  142. package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +30 -27
  143. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +27 -18
  144. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.itemPlugin.js +13 -5
  145. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +19 -30
  146. package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js +32 -0
  147. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.itemPlugin.js +8 -6
  148. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +46 -35
  149. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js +15 -0
  150. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +24 -14
  151. package/node/internals/useTreeView/useTreeView.js +30 -17
  152. package/node/internals/useTreeView/useTreeViewBuildContext.js +25 -18
  153. package/node/internals/utils/TreeViewStore.js +31 -0
  154. package/node/internals/utils/selectors.js +44 -0
  155. package/node/internals/utils/tree.js +51 -43
  156. package/node/useTreeItem/useTreeItem.js +26 -11
  157. package/package.json +6 -4
  158. package/useTreeItem/useTreeItem.js +26 -11
  159. package/useTreeItem/useTreeItem.types.d.ts +9 -0
@@ -1,46 +1,56 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import useEventCallback from '@mui/utils/useEventCallback';
4
- import ownerDocument from '@mui/utils/ownerDocument';
5
4
  import { useInstanceEventHandler } from "../../hooks/useInstanceEventHandler.js";
6
- import { getActiveElement } from "../../utils/utils.js";
7
5
  import { getFirstNavigableItem } from "../../utils/tree.js";
8
6
  import { convertSelectedItemsToArray } from "../useTreeViewSelection/useTreeViewSelection.utils.js";
9
- const useDefaultFocusableItemId = (instance, selectedItems) => {
10
- let tabbableItemId = convertSelectedItemsToArray(selectedItems).find(itemId => {
11
- if (!instance.isItemNavigable(itemId)) {
12
- return false;
13
- }
14
- const itemMeta = instance.getItemMeta(itemId);
15
- return itemMeta && (itemMeta.parentId == null || instance.isItemExpanded(itemMeta.parentId));
16
- });
17
- if (tabbableItemId == null) {
18
- tabbableItemId = getFirstNavigableItem(instance);
19
- }
20
- return tabbableItemId;
21
- };
7
+ import { selectorDefaultFocusableItemId, selectorFocusedItemId } from "./useTreeViewFocus.selectors.js";
8
+ import { selectorIsItemExpanded } from "../useTreeViewExpansion/useTreeViewExpansion.selectors.js";
9
+ import { selectorCanItemBeFocused, selectorItemMeta } from "../useTreeViewItems/useTreeViewItems.selectors.js";
22
10
  export const useTreeViewFocus = ({
23
11
  instance,
24
12
  params,
25
- state,
26
- setState,
27
- models,
28
- rootRef
13
+ store,
14
+ models
29
15
  }) => {
30
- const defaultFocusableItemId = useDefaultFocusableItemId(instance, models.selectedItems.value);
31
- const setFocusedItemId = useEventCallback(itemId => {
32
- const cleanItemId = typeof itemId === 'function' ? itemId(state.focusedItemId) : itemId;
33
- if (state.focusedItemId !== cleanItemId) {
34
- setState(prevState => _extends({}, prevState, {
35
- focusedItemId: cleanItemId
36
- }));
16
+ React.useEffect(() => {
17
+ let defaultFocusableItemId = convertSelectedItemsToArray(models.selectedItems.value).find(itemId => {
18
+ if (!selectorCanItemBeFocused(store.value, itemId)) {
19
+ return false;
20
+ }
21
+ const itemMeta = selectorItemMeta(store.value, itemId);
22
+ return itemMeta && (itemMeta.parentId == null || selectorIsItemExpanded(store.value, itemMeta.parentId));
23
+ });
24
+ if (defaultFocusableItemId == null) {
25
+ defaultFocusableItemId = getFirstNavigableItem(store.value) ?? null;
37
26
  }
27
+ store.update(prevState => {
28
+ if (defaultFocusableItemId === prevState.focus.defaultFocusableItemId) {
29
+ return prevState;
30
+ }
31
+ return _extends({}, prevState, {
32
+ focus: _extends({}, prevState.focus, {
33
+ defaultFocusableItemId
34
+ })
35
+ });
36
+ });
37
+ }, [store, models.selectedItems.value]);
38
+ const setFocusedItemId = useEventCallback(itemId => {
39
+ store.update(prevState => {
40
+ const focusedItemId = selectorFocusedItemId(prevState);
41
+ if (focusedItemId === itemId) {
42
+ return prevState;
43
+ }
44
+ return _extends({}, prevState, {
45
+ focus: _extends({}, prevState.focus, {
46
+ focusedItemId: itemId
47
+ })
48
+ });
49
+ });
38
50
  });
39
- const isTreeViewFocused = React.useCallback(() => !!rootRef.current && rootRef.current.contains(getActiveElement(ownerDocument(rootRef.current))), [rootRef]);
40
- const isItemFocused = React.useCallback(itemId => state.focusedItemId === itemId && isTreeViewFocused(), [state.focusedItemId, isTreeViewFocused]);
41
51
  const isItemVisible = itemId => {
42
- const itemMeta = instance.getItemMeta(itemId);
43
- return itemMeta && (itemMeta.parentId == null || instance.isItemExpanded(itemMeta.parentId));
52
+ const itemMeta = selectorItemMeta(store.value, itemId);
53
+ return itemMeta && (itemMeta.parentId == null || selectorIsItemExpanded(store.value, itemMeta.parentId));
44
54
  };
45
55
  const innerFocusItem = (event, itemId) => {
46
56
  const itemElement = instance.getItemDOMElement(itemId);
@@ -59,23 +69,25 @@ export const useTreeViewFocus = ({
59
69
  }
60
70
  });
61
71
  const removeFocusedItem = useEventCallback(() => {
62
- if (state.focusedItemId == null) {
72
+ const focusedItemId = selectorFocusedItemId(store.value);
73
+ if (focusedItemId == null) {
63
74
  return;
64
75
  }
65
- const itemMeta = instance.getItemMeta(state.focusedItemId);
76
+ const itemMeta = selectorItemMeta(store.value, focusedItemId);
66
77
  if (itemMeta) {
67
- const itemElement = instance.getItemDOMElement(state.focusedItemId);
78
+ const itemElement = instance.getItemDOMElement(focusedItemId);
68
79
  if (itemElement) {
69
80
  itemElement.blur();
70
81
  }
71
82
  }
72
83
  setFocusedItemId(null);
73
84
  });
74
- const canItemBeTabbed = itemId => itemId === defaultFocusableItemId;
75
85
  useInstanceEventHandler(instance, 'removeItem', ({
76
86
  id
77
87
  }) => {
78
- if (state.focusedItemId === id) {
88
+ const focusedItemId = selectorFocusedItemId(store.value);
89
+ const defaultFocusableItemId = selectorDefaultFocusableItemId(store.value);
90
+ if (focusedItemId === id && defaultFocusableItemId != null) {
79
91
  innerFocusItem(null, defaultFocusableItemId);
80
92
  }
81
93
  });
@@ -86,27 +98,37 @@ export const useTreeViewFocus = ({
86
98
  }
87
99
 
88
100
  // if the event bubbled (which is React specific) we don't want to steal focus
89
- if (event.target === event.currentTarget) {
101
+ const defaultFocusableItemId = selectorDefaultFocusableItemId(store.value);
102
+ if (event.target === event.currentTarget && defaultFocusableItemId != null) {
90
103
  innerFocusItem(event, defaultFocusableItemId);
91
104
  }
92
105
  };
106
+ const createRootHandleBlur = otherHandlers => event => {
107
+ otherHandlers.onBlur?.(event);
108
+ if (event.defaultMuiPrevented) {
109
+ return;
110
+ }
111
+ setFocusedItemId(null);
112
+ };
93
113
  return {
94
114
  getRootProps: otherHandlers => ({
95
- onFocus: createRootHandleFocus(otherHandlers)
115
+ onFocus: createRootHandleFocus(otherHandlers),
116
+ onBlur: createRootHandleBlur(otherHandlers)
96
117
  }),
97
118
  publicAPI: {
98
119
  focusItem
99
120
  },
100
121
  instance: {
101
- isItemFocused,
102
- canItemBeTabbed,
103
122
  focusItem,
104
123
  removeFocusedItem
105
124
  }
106
125
  };
107
126
  };
108
127
  useTreeViewFocus.getInitialState = () => ({
109
- focusedItemId: null
128
+ focus: {
129
+ focusedItemId: null,
130
+ defaultFocusableItemId: null
131
+ }
110
132
  });
111
133
  useTreeViewFocus.params = {
112
134
  onItemFocus: true
@@ -0,0 +1,182 @@
1
+ import { UseTreeViewFocusSignature } from './useTreeViewFocus.types';
2
+ import { TreeViewRootSelector } from '../../utils/selectors';
3
+ /**
4
+ * Get the item that should be sequentially focusable (usually with the Tab key).
5
+ * At any point in time, there is a single item that can be sequentially focused in the Tree View.
6
+ * This item is the first selected item (that is both visible and navigable), if any, or the first navigable item if no item is selected.
7
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
8
+ * @returns {TreeViewItemId | null} The id of the item that should be sequentially focusable.
9
+ */
10
+ export declare const selectorDefaultFocusableItemId: ((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
11
+ cacheKey: import("../../models").TreeViewStateCacheKey;
12
+ }) => string | null) & {
13
+ clearCache: () => void;
14
+ resultsCount: () => number;
15
+ resetResultsCount: () => void;
16
+ } & {
17
+ resultFunc: (resultFuncArgs_0: {
18
+ focusedItemId: string | null;
19
+ defaultFocusableItemId: string | null;
20
+ }) => string | null;
21
+ memoizedResultFunc: ((resultFuncArgs_0: {
22
+ focusedItemId: string | null;
23
+ defaultFocusableItemId: string | null;
24
+ }) => string | null) & {
25
+ clearCache: () => void;
26
+ resultsCount: () => number;
27
+ resetResultsCount: () => void;
28
+ };
29
+ lastResult: () => string | null;
30
+ dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
31
+ recomputations: () => number;
32
+ resetRecomputations: () => void;
33
+ dependencyRecomputations: () => number;
34
+ resetDependencyRecomputations: () => void;
35
+ } & {
36
+ argsMemoize: typeof import("reselect").weakMapMemoize;
37
+ memoize: typeof import("reselect").weakMapMemoize;
38
+ };
39
+ /**
40
+ * Check if an item is the default focusable item.
41
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
42
+ * @param {TreeViewItemId} itemId The id of the item to check.
43
+ * @returns {boolean} `true` if the item is the default focusable item, `false` otherwise.
44
+ */
45
+ export declare const selectorIsItemTheDefaultFocusableItem: ((state: any, itemId: string) => boolean) & {
46
+ clearCache: () => void;
47
+ resultsCount: () => number;
48
+ resetResultsCount: () => void;
49
+ } & {
50
+ resultFunc: (resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean;
51
+ memoizedResultFunc: ((resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean) & {
52
+ clearCache: () => void;
53
+ resultsCount: () => number;
54
+ resetResultsCount: () => void;
55
+ };
56
+ lastResult: () => boolean;
57
+ dependencies: [((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
58
+ cacheKey: import("../../models").TreeViewStateCacheKey;
59
+ }) => string | null) & {
60
+ clearCache: () => void;
61
+ resultsCount: () => number;
62
+ resetResultsCount: () => void;
63
+ } & {
64
+ resultFunc: (resultFuncArgs_0: {
65
+ focusedItemId: string | null;
66
+ defaultFocusableItemId: string | null;
67
+ }) => string | null;
68
+ memoizedResultFunc: ((resultFuncArgs_0: {
69
+ focusedItemId: string | null;
70
+ defaultFocusableItemId: string | null;
71
+ }) => string | null) & {
72
+ clearCache: () => void;
73
+ resultsCount: () => number;
74
+ resetResultsCount: () => void;
75
+ };
76
+ lastResult: () => string | null;
77
+ dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
78
+ recomputations: () => number;
79
+ resetRecomputations: () => void;
80
+ dependencyRecomputations: () => number;
81
+ resetDependencyRecomputations: () => void;
82
+ } & {
83
+ argsMemoize: typeof import("reselect").weakMapMemoize;
84
+ memoize: typeof import("reselect").weakMapMemoize;
85
+ }, (_: any, itemId: string) => string];
86
+ recomputations: () => number;
87
+ resetRecomputations: () => void;
88
+ dependencyRecomputations: () => number;
89
+ resetDependencyRecomputations: () => void;
90
+ } & {
91
+ argsMemoize: typeof import("reselect").weakMapMemoize;
92
+ memoize: typeof import("reselect").weakMapMemoize;
93
+ };
94
+ /**
95
+ * Get the id of the item that is currently focused.
96
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
97
+ * @returns {TreeViewItemId | null} The id of the item that is currently focused.
98
+ */
99
+ export declare const selectorFocusedItemId: ((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
100
+ cacheKey: import("../../models").TreeViewStateCacheKey;
101
+ }) => string | null) & {
102
+ clearCache: () => void;
103
+ resultsCount: () => number;
104
+ resetResultsCount: () => void;
105
+ } & {
106
+ resultFunc: (resultFuncArgs_0: {
107
+ focusedItemId: string | null;
108
+ defaultFocusableItemId: string | null;
109
+ }) => string | null;
110
+ memoizedResultFunc: ((resultFuncArgs_0: {
111
+ focusedItemId: string | null;
112
+ defaultFocusableItemId: string | null;
113
+ }) => string | null) & {
114
+ clearCache: () => void;
115
+ resultsCount: () => number;
116
+ resetResultsCount: () => void;
117
+ };
118
+ lastResult: () => string | null;
119
+ dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
120
+ recomputations: () => number;
121
+ resetRecomputations: () => void;
122
+ dependencyRecomputations: () => number;
123
+ resetDependencyRecomputations: () => void;
124
+ } & {
125
+ argsMemoize: typeof import("reselect").weakMapMemoize;
126
+ memoize: typeof import("reselect").weakMapMemoize;
127
+ };
128
+ /**
129
+ * Check if an item is focused.
130
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
131
+ * @param {TreeViewItemId} itemId The id of the item to check.
132
+ * @returns {boolean} `true` if the item is focused, `false` otherwise.
133
+ */
134
+ export declare const selectorIsItemFocused: ((state: any, itemId: string) => boolean) & {
135
+ clearCache: () => void;
136
+ resultsCount: () => number;
137
+ resetResultsCount: () => void;
138
+ } & {
139
+ resultFunc: (resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean;
140
+ memoizedResultFunc: ((resultFuncArgs_0: string | null, resultFuncArgs_1: string) => boolean) & {
141
+ clearCache: () => void;
142
+ resultsCount: () => number;
143
+ resetResultsCount: () => void;
144
+ };
145
+ lastResult: () => boolean;
146
+ dependencies: [((state: import("../../corePlugins/useTreeViewId/useTreeViewId.types").UseTreeViewIdState & import("./useTreeViewFocus.types").UseTreeViewFocusState & Partial<{}> & {
147
+ cacheKey: import("../../models").TreeViewStateCacheKey;
148
+ }) => string | null) & {
149
+ clearCache: () => void;
150
+ resultsCount: () => number;
151
+ resetResultsCount: () => void;
152
+ } & {
153
+ resultFunc: (resultFuncArgs_0: {
154
+ focusedItemId: string | null;
155
+ defaultFocusableItemId: string | null;
156
+ }) => string | null;
157
+ memoizedResultFunc: ((resultFuncArgs_0: {
158
+ focusedItemId: string | null;
159
+ defaultFocusableItemId: string | null;
160
+ }) => string | null) & {
161
+ clearCache: () => void;
162
+ resultsCount: () => number;
163
+ resetResultsCount: () => void;
164
+ };
165
+ lastResult: () => string | null;
166
+ dependencies: [TreeViewRootSelector<UseTreeViewFocusSignature>];
167
+ recomputations: () => number;
168
+ resetRecomputations: () => void;
169
+ dependencyRecomputations: () => number;
170
+ resetDependencyRecomputations: () => void;
171
+ } & {
172
+ argsMemoize: typeof import("reselect").weakMapMemoize;
173
+ memoize: typeof import("reselect").weakMapMemoize;
174
+ }, (_: any, itemId: string) => string];
175
+ recomputations: () => number;
176
+ resetRecomputations: () => void;
177
+ dependencyRecomputations: () => number;
178
+ resetDependencyRecomputations: () => void;
179
+ } & {
180
+ argsMemoize: typeof import("reselect").weakMapMemoize;
181
+ memoize: typeof import("reselect").weakMapMemoize;
182
+ };
@@ -0,0 +1,34 @@
1
+ import { createSelector } from "../../utils/selectors.js";
2
+ const selectorTreeViewFocusState = state => state.focus;
3
+
4
+ /**
5
+ * Get the item that should be sequentially focusable (usually with the Tab key).
6
+ * At any point in time, there is a single item that can be sequentially focused in the Tree View.
7
+ * This item is the first selected item (that is both visible and navigable), if any, or the first navigable item if no item is selected.
8
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
9
+ * @returns {TreeViewItemId | null} The id of the item that should be sequentially focusable.
10
+ */
11
+ export const selectorDefaultFocusableItemId = createSelector(selectorTreeViewFocusState, focus => focus.defaultFocusableItemId);
12
+
13
+ /**
14
+ * Check if an item is the default focusable item.
15
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
16
+ * @param {TreeViewItemId} itemId The id of the item to check.
17
+ * @returns {boolean} `true` if the item is the default focusable item, `false` otherwise.
18
+ */
19
+ export const selectorIsItemTheDefaultFocusableItem = createSelector([selectorDefaultFocusableItemId, (_, itemId) => itemId], (defaultFocusableItemId, itemId) => defaultFocusableItemId === itemId);
20
+
21
+ /**
22
+ * Get the id of the item that is currently focused.
23
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
24
+ * @returns {TreeViewItemId | null} The id of the item that is currently focused.
25
+ */
26
+ export const selectorFocusedItemId = createSelector(selectorTreeViewFocusState, focus => focus.focusedItemId);
27
+
28
+ /**
29
+ * Check if an item is focused.
30
+ * @param {TreeViewState<[UseTreeViewFocusSignature]>} state The state of the tree view.
31
+ * @param {TreeViewItemId} itemId The id of the item to check.
32
+ * @returns {boolean} `true` if the item is focused, `false` otherwise.
33
+ */
34
+ export const selectorIsItemFocused = createSelector([selectorFocusedItemId, (_, itemId) => itemId], (focusedItemId, itemId) => focusedItemId === itemId);
@@ -3,7 +3,6 @@ import { TreeViewPluginSignature } from '../../models';
3
3
  import type { UseTreeViewItemsSignature } from '../useTreeViewItems';
4
4
  import type { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
5
5
  import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
6
- import { TreeViewItemId } from '../../../models';
7
6
  export interface UseTreeViewFocusPublicAPI {
8
7
  /**
9
8
  * Focus the item with the given id.
@@ -16,20 +15,6 @@ export interface UseTreeViewFocusPublicAPI {
16
15
  focusItem: (event: React.SyntheticEvent, itemId: string) => void;
17
16
  }
18
17
  export interface UseTreeViewFocusInstance extends UseTreeViewFocusPublicAPI {
19
- /**
20
- * Check if an item is the currently focused item.
21
- * @param {TreeViewItemId} itemId The id of the item to check.
22
- * @returns {boolean} `true` if the item is focused, `false` otherwise.
23
- */
24
- isItemFocused: (itemId: TreeViewItemId) => boolean;
25
- /**
26
- * Check if an item should be sequentially focusable (usually with the Tab key).
27
- * At any point in time, there is a single item that can be sequentially focused in the Tree View.
28
- * This item is the first selected item (that is both visible and navigable), if any, or the first navigable item if no item is selected.
29
- * @param {TreeViewItemId} itemId The id of the item to check.
30
- * @returns {boolean} `true` if the item can be sequentially focusable, `false` otherwise.
31
- */
32
- canItemBeTabbed: (itemId: TreeViewItemId) => boolean;
33
18
  /**
34
19
  * Remove the focus from the currently focused item (both from the internal state and the DOM).
35
20
  */
@@ -45,7 +30,10 @@ export interface UseTreeViewFocusParameters {
45
30
  }
46
31
  export type UseTreeViewFocusDefaultizedParameters = UseTreeViewFocusParameters;
47
32
  export interface UseTreeViewFocusState {
48
- focusedItemId: string | null;
33
+ focus: {
34
+ focusedItemId: string | null;
35
+ defaultFocusableItemId: string | null;
36
+ };
49
37
  }
50
38
  export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
51
39
  params: UseTreeViewFocusParameters;
@@ -1,22 +1,24 @@
1
+ import * as React from 'react';
1
2
  export const useTreeViewIcons = ({
2
3
  slots,
3
4
  slotProps
4
5
  }) => {
5
- return {
6
- contextValue: {
7
- icons: {
8
- slots: {
9
- collapseIcon: slots.collapseIcon,
10
- expandIcon: slots.expandIcon,
11
- endIcon: slots.endIcon
12
- },
13
- slotProps: {
14
- collapseIcon: slotProps.collapseIcon,
15
- expandIcon: slotProps.expandIcon,
16
- endIcon: slotProps.endIcon
17
- }
6
+ const pluginContextValue = React.useMemo(() => ({
7
+ icons: {
8
+ slots: {
9
+ collapseIcon: slots.collapseIcon,
10
+ expandIcon: slots.expandIcon,
11
+ endIcon: slots.endIcon
12
+ },
13
+ slotProps: {
14
+ collapseIcon: slotProps.collapseIcon,
15
+ expandIcon: slotProps.expandIcon,
16
+ endIcon: slotProps.endIcon
18
17
  }
19
18
  }
19
+ }), [slots.collapseIcon, slots.expandIcon, slots.endIcon, slotProps.collapseIcon, slotProps.expandIcon, slotProps.endIcon]);
20
+ return {
21
+ contextValue: pluginContextValue
20
22
  };
21
23
  };
22
24
  useTreeViewIcons.params = {};
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { SlotComponentProps } from '@mui/utils';
2
+ import { SlotComponentProps } from '@mui/utils/types';
3
3
  import { TreeViewPluginSignature } from '../../models';
4
4
  import { UseTreeViewItemsSignature } from '../useTreeViewItems';
5
5
  import { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
@@ -1,3 +1,3 @@
1
1
  export { useTreeViewItems } from './useTreeViewItems';
2
- export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, UseTreeViewItemsState, TreeViewItemToRenderProps, } from './useTreeViewItems.types';
2
+ export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, UseTreeViewItemsState, } from './useTreeViewItems.types';
3
3
  export { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './useTreeViewItems.utils';