@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.
Files changed (136) hide show
  1. package/CHANGELOG.md +266 -12
  2. package/README.md +1 -1
  3. package/RichTreeView/RichTreeView.js +15 -17
  4. package/RichTreeView/RichTreeView.types.d.ts +1 -1
  5. package/SimpleTreeView/SimpleTreeView.js +3 -4
  6. package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
  7. package/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
  8. package/TreeItem/TreeItem.js +43 -35
  9. package/TreeItem/TreeItem.types.d.ts +3 -3
  10. package/TreeItem/TreeItemContent.d.ts +7 -7
  11. package/TreeItem/TreeItemContent.js +10 -10
  12. package/TreeItem/treeItemClasses.d.ts +1 -1
  13. package/TreeItem/useTreeItemState.d.ts +1 -1
  14. package/TreeItem/useTreeItemState.js +13 -13
  15. package/TreeItem2/TreeItem2.js +16 -17
  16. package/TreeItem2Icon/TreeItem2Icon.js +5 -6
  17. package/TreeItem2Icon/TreeItem2Icon.types.d.ts +4 -4
  18. package/TreeItem2Provider/TreeItem2Provider.js +3 -3
  19. package/TreeItem2Provider/TreeItem2Provider.types.d.ts +1 -1
  20. package/TreeView/TreeView.d.ts +1 -1
  21. package/TreeView/TreeView.js +1 -1
  22. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +2 -2
  23. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
  24. package/hooks/useTreeViewApiRef.d.ts +1 -1
  25. package/index.js +1 -1
  26. package/internals/TreeViewProvider/DescendantProvider.d.ts +1 -1
  27. package/internals/TreeViewProvider/DescendantProvider.js +1 -1
  28. package/internals/hooks/useInstanceEventHandler.js +5 -10
  29. package/internals/index.d.ts +2 -2
  30. package/internals/models/plugin.d.ts +1 -1
  31. package/internals/plugins/defaultPlugins.d.ts +3 -3
  32. package/internals/plugins/defaultPlugins.js +2 -2
  33. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +17 -24
  34. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +6 -6
  35. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +76 -58
  36. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +9 -8
  37. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +6 -6
  38. package/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  39. package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +2 -2
  40. package/internals/plugins/useTreeViewItems/index.d.ts +2 -0
  41. package/internals/plugins/useTreeViewItems/index.js +1 -0
  42. package/internals/plugins/useTreeViewItems/useTreeViewItems.d.ts +3 -0
  43. package/{modern/internals/plugins/useTreeViewNodes/useTreeViewNodes.js → internals/plugins/useTreeViewItems/useTreeViewItems.js} +42 -33
  44. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +99 -0
  45. package/internals/plugins/useTreeViewJSXItems/index.d.ts +2 -0
  46. package/internals/plugins/useTreeViewJSXItems/index.js +1 -0
  47. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.d.ts +3 -0
  48. package/{modern/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +41 -40
  49. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +18 -0
  50. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +85 -96
  51. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +6 -3
  52. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +44 -47
  53. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +8 -8
  54. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +7 -7
  55. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
  56. package/internals/useTreeView/useTreeView.js +5 -6
  57. package/internals/useTreeView/useTreeView.utils.d.ts +5 -5
  58. package/internals/useTreeView/useTreeView.utils.js +18 -18
  59. package/internals/utils/extractPluginParamsFromProps.js +2 -2
  60. package/internals/utils/utils.js +1 -0
  61. package/modern/RichTreeView/RichTreeView.js +11 -11
  62. package/modern/SimpleTreeView/SimpleTreeView.js +1 -1
  63. package/modern/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
  64. package/modern/TreeItem/TreeItem.js +31 -22
  65. package/modern/TreeItem/TreeItemContent.js +10 -10
  66. package/modern/TreeItem/useTreeItemState.js +13 -13
  67. package/modern/TreeItem2/TreeItem2.js +11 -11
  68. package/modern/TreeItem2Provider/TreeItem2Provider.js +3 -3
  69. package/modern/TreeView/TreeView.js +1 -1
  70. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
  71. package/modern/index.js +1 -1
  72. package/modern/internals/TreeViewProvider/DescendantProvider.js +1 -1
  73. package/modern/internals/plugins/defaultPlugins.js +2 -2
  74. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +14 -14
  75. package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +74 -53
  76. package/modern/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  77. package/modern/internals/plugins/useTreeViewItems/index.js +1 -0
  78. package/{internals/plugins/useTreeViewNodes/useTreeViewNodes.js → modern/internals/plugins/useTreeViewItems/useTreeViewItems.js} +46 -41
  79. package/modern/internals/plugins/useTreeViewJSXItems/index.js +1 -0
  80. package/{internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +41 -41
  81. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +85 -94
  82. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +40 -40
  83. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
  84. package/modern/internals/useTreeView/useTreeView.js +3 -4
  85. package/modern/internals/useTreeView/useTreeView.utils.js +18 -18
  86. package/modern/internals/utils/utils.js +1 -0
  87. package/modern/useTreeItem2/useTreeItem2.js +23 -12
  88. package/node/RichTreeView/RichTreeView.js +11 -11
  89. package/node/SimpleTreeView/SimpleTreeView.js +1 -1
  90. package/node/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
  91. package/node/TreeItem/TreeItem.js +31 -22
  92. package/node/TreeItem/TreeItemContent.js +10 -10
  93. package/node/TreeItem/useTreeItemState.js +13 -13
  94. package/node/TreeItem2/TreeItem2.js +11 -11
  95. package/node/TreeItem2Provider/TreeItem2Provider.js +3 -3
  96. package/node/TreeView/TreeView.js +1 -1
  97. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +12 -12
  98. package/node/index.js +1 -1
  99. package/node/internals/TreeViewProvider/DescendantProvider.js +1 -1
  100. package/node/internals/plugins/defaultPlugins.js +2 -2
  101. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +14 -14
  102. package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +74 -53
  103. package/node/internals/plugins/useTreeViewId/useTreeViewId.js +1 -1
  104. package/node/internals/plugins/useTreeViewItems/index.js +12 -0
  105. package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +44 -35
  106. package/node/internals/plugins/useTreeViewJSXItems/index.js +12 -0
  107. package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.js → useTreeViewJSXItems/useTreeViewJSXItems.js} +43 -42
  108. package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +84 -93
  109. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +39 -39
  110. package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
  111. package/node/internals/useTreeView/useTreeView.js +3 -4
  112. package/node/internals/useTreeView/useTreeView.utils.js +23 -23
  113. package/node/internals/utils/utils.js +1 -0
  114. package/node/useTreeItem2/useTreeItem2.js +23 -12
  115. package/package.json +5 -5
  116. package/useTreeItem2/useTreeItem2.d.ts +1 -1
  117. package/useTreeItem2/useTreeItem2.js +26 -18
  118. package/useTreeItem2/useTreeItem2.types.d.ts +9 -7
  119. package/internals/plugins/useTreeViewJSXNodes/index.d.ts +0 -2
  120. package/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
  121. package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.d.ts +0 -3
  122. package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.d.ts +0 -18
  123. package/internals/plugins/useTreeViewNodes/index.d.ts +0 -2
  124. package/internals/plugins/useTreeViewNodes/index.js +0 -1
  125. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.d.ts +0 -3
  126. package/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.d.ts +0 -88
  127. package/modern/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
  128. package/modern/internals/plugins/useTreeViewNodes/index.js +0 -1
  129. package/node/internals/plugins/useTreeViewJSXNodes/index.js +0 -12
  130. package/node/internals/plugins/useTreeViewNodes/index.js +0 -12
  131. /package/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
  132. /package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
  133. /package/modern/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
  134. /package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
  135. /package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
  136. /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
- nodeId,
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.isNodeExpanded(nodeId),
15
- focused: instance.isNodeFocused(nodeId),
16
- selected: instance.isNodeSelected(nodeId),
17
- disabled: instance.isNodeDisabled(nodeId)
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, nodeId);
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.isNodeExpanded(nodeId))) {
30
- instance.toggleNodeExpansion(event, nodeId);
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, nodeId);
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: nodeId
44
+ end: itemId
45
45
  });
46
46
  } else {
47
- instance.selectNode(event, nodeId, true);
47
+ instance.selectItem(event, itemId, true);
48
48
  }
49
49
  } else {
50
- instance.selectNode(event, nodeId);
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").UseTreeViewNodesSignature, import("../internals").UseTreeViewExpansionSignature, import("../internals").UseTreeViewSelectionSignature, import("../internals").UseTreeViewFocusSignature, import("../internals").UseTreeViewKeyboardNavigationSignature, import("../internals").UseTreeViewIconsSignature]>() => React.MutableRefObject<TreeViewPublicAPI<TPlugins> | undefined>;
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
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.0.0-beta.7
2
+ * @mui/x-tree-view v7.1.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -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 node
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 node
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
- var _handlerRef$current;
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
- var _subscription$current;
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
- var _handlerRef$current2;
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
- var _subscription$current2;
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
- var _registryContainer$re;
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);
@@ -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 { UseTreeViewNodesSignature } from './plugins/useTreeViewNodes';
14
- export type { UseTreeViewJSXNodesSignature } from './plugins/useTreeViewJSXNodes';
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
- nodeId: TreeViewItemId;
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 { UseTreeViewNodesParameters } from './useTreeViewNodes';
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("./useTreeViewNodes").UseTreeViewNodesSignature>, 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>];
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, UseTreeViewNodesParameters<R>, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, UseTreeViewSelectionParameters<Multiple>, UseTreeViewIconsParameters {
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 { useTreeViewNodes } from './useTreeViewNodes';
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, useTreeViewNodes, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
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
- var _params$onExpandedIte;
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 isNodeExpanded = React.useCallback(nodeId => {
16
- return Array.isArray(models.expandedItems.value) ? models.expandedItems.value.indexOf(nodeId) !== -1 : false;
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 isNodeExpandable = React.useCallback(nodeId => {
19
- var _instance$getNode;
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, nodeId) => {
39
- const node = instance.getNode(nodeId);
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.isNodeExpandable(child) && !instance.isNodeExpanded(child));
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(newlyExpandedNodeId => {
46
- params.onItemExpansionToggle(event, newlyExpandedNodeId, true);
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
- isNodeExpanded,
54
- isNodeExpandable,
55
- toggleNodeExpansion,
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 DEFAULT_EXPANDED_NODES = [];
65
- useTreeViewExpansion.getDefaultizedParams = params => {
66
- var _params$defaultExpand;
67
- return _extends({}, params, {
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 { UseTreeViewNodesSignature } from '../useTreeViewNodes';
3
+ import { UseTreeViewItemsSignature } from '../useTreeViewItems';
4
4
  export interface UseTreeViewExpansionInstance {
5
- isNodeExpanded: (nodeId: string) => boolean;
6
- isNodeExpandable: (nodeId: string) => boolean;
7
- toggleNodeExpansion: (event: React.SyntheticEvent, value: string) => void;
8
- expandAllSiblings: (event: React.KeyboardEvent<HTMLUListElement>, nodeId: string) => void;
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: [UseTreeViewNodesSignature];
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 setFocusedNodeId = useEventCallback(nodeId => {
18
- const cleanNodeId = typeof nodeId === 'function' ? nodeId(state.focusedNodeId) : nodeId;
19
- if (state.focusedNodeId !== cleanNodeId) {
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
- focusedNodeId: cleanNodeId
38
+ focusedItemId: cleanItemId
22
39
  }));
23
40
  }
24
41
  });
25
- const isTreeViewFocused = React.useCallback(() => !!rootRef.current && rootRef.current === getActiveElement(ownerDocument(rootRef.current)), [rootRef]);
26
- const isNodeFocused = React.useCallback(nodeId => state.focusedNodeId === nodeId && isTreeViewFocused(), [state.focusedNodeId, isTreeViewFocused]);
27
- const isNodeVisible = nodeId => {
28
- const node = instance.getNode(nodeId);
29
- return node && (node.parentId == null || instance.isNodeExpanded(node.parentId));
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 focusItem = useEventCallback((event, nodeId) => {
32
- // if we receive a nodeId, and it is visible, the focus will be set to it
33
- if (nodeId && isNodeVisible(nodeId)) {
34
- if (!isTreeViewFocused()) {
35
- instance.focusRoot();
36
- }
37
- setFocusedNodeId(nodeId);
38
- if (params.onItemFocus) {
39
- params.onItemFocus(event, nodeId);
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 focusDefaultNode = useEventCallback(event => {
44
- let nodeToFocusId;
65
+ const focusDefaultItem = useEventCallback(event => {
66
+ let itemToFocusId;
45
67
  if (Array.isArray(models.selectedItems.value)) {
46
- nodeToFocusId = models.selectedItems.value.find(isNodeVisible);
47
- } else if (models.selectedItems.value != null && isNodeVisible(models.selectedItems.value)) {
48
- nodeToFocusId = models.selectedItems.value;
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 (nodeToFocusId == null) {
51
- nodeToFocusId = instance.getNavigableChildrenIds(null)[0];
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 focusRoot = useEventCallback(() => {
59
- var _rootRef$current;
60
- (_rootRef$current = rootRef.current) == null || _rootRef$current.focus({
61
- preventScroll: true
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
- isNodeFocused,
92
+ isItemFocused,
93
+ canItemBeTabbed,
66
94
  focusItem,
67
- focusRoot,
68
- focusDefaultNode
95
+ focusDefaultItem,
96
+ removeFocusedItem
69
97
  });
70
98
  populatePublicAPI(publicAPI, {
71
99
  focusItem
72
100
  });
73
- useInstanceEventHandler(instance, 'removeNode', ({
101
+ useInstanceEventHandler(instance, 'removeItem', ({
74
102
  id
75
103
  }) => {
76
- setFocusedNodeId(oldFocusedNodeId => {
77
- if (oldFocusedNodeId === id && rootRef.current === ownerDocument(rootRef.current).activeElement) {
78
- return instance.getChildrenIds(null)[0];
79
- }
80
- return oldFocusedNodeId;
81
- });
104
+ if (state.focusedItemId === id) {
105
+ instance.focusDefaultItem(null);
106
+ }
82
107
  });
83
108
  const createHandleFocus = otherHandlers => event => {
84
- var _otherHandlers$onFocu;
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.focusDefaultNode(event);
112
+ instance.focusDefaultItem(event);
89
113
  }
90
114
  };
91
- const createHandleBlur = otherHandlers => event => {
92
- var _otherHandlers$onBlur;
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
- onBlur: createHandleBlur(otherHandlers),
102
- 'aria-activedescendant': activeDescendant != null ? activeDescendant : undefined
120
+ 'aria-activedescendant': activeDescendant ?? undefined
103
121
  })
104
122
  };
105
123
  };
106
124
  useTreeViewFocus.getInitialState = () => ({
107
- focusedNodeId: null
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 { UseTreeViewNodesSignature } from '../useTreeViewNodes';
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
- isNodeFocused: (nodeId: string) => boolean;
9
- focusItem: (event: React.SyntheticEvent, itemId: string | null) => void;
10
- focusDefaultNode: (event: React.SyntheticEvent) => void;
11
- focusRoot: () => void;
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
- focusedNodeId: string | null;
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
- UseTreeViewNodesSignature,
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 { UseTreeViewNodesSignature } from '../useTreeViewNodes';
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 node.
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 node.
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 node.
20
- * This is applied to all tree nodes and can be overridden by the TreeItem `icon` slot prop.
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: [UseTreeViewNodesSignature, UseTreeViewSelectionSignature];
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((nodeId, idAttribute) => idAttribute != null ? idAttribute : `${treeId}-${nodeId}`, [treeId]);
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: (nodeId: string, idAttribute: string | undefined) => string;
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
- focusedNodeId: string | null;
14
+ focusedItemId: string | null;
15
15
  }
16
16
  export type UseTreeViewIdSignature = TreeViewPluginSignature<{
17
17
  params: UseTreeViewIdParameters;
@@ -0,0 +1,2 @@
1
+ export { useTreeViewItems } from './useTreeViewItems';
2
+ export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, } from './useTreeViewItems.types';
@@ -0,0 +1 @@
1
+ export { useTreeViewItems } from './useTreeViewItems';
@@ -0,0 +1,3 @@
1
+ import { TreeViewPlugin } from '../../models';
2
+ import { UseTreeViewItemsSignature } from './useTreeViewItems.types';
3
+ export declare const useTreeViewItems: TreeViewPlugin<UseTreeViewItemsSignature>;