@mui/x-tree-view 7.7.0 → 7.8.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 (92) hide show
  1. package/CHANGELOG.md +181 -0
  2. package/RichTreeView/RichTreeView.js +5 -0
  3. package/RichTreeView/RichTreeView.plugins.d.ts +3 -3
  4. package/RichTreeView/RichTreeView.plugins.js +1 -2
  5. package/SimpleTreeView/SimpleTreeView.js +5 -0
  6. package/SimpleTreeView/SimpleTreeView.plugins.d.ts +3 -3
  7. package/SimpleTreeView/SimpleTreeView.plugins.js +1 -2
  8. package/TreeItem/TreeItem.js +19 -4
  9. package/TreeItem/TreeItem.types.d.ts +8 -3
  10. package/TreeItem/TreeItemContent.js +5 -2
  11. package/TreeItem/useTreeItemState.d.ts +1 -0
  12. package/TreeItem/useTreeItemState.js +5 -1
  13. package/TreeItem2/TreeItem2.d.ts +3 -3
  14. package/TreeItem2Provider/TreeItem2Provider.d.ts +0 -1
  15. package/TreeView/TreeView.js +5 -0
  16. package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +4 -0
  17. package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +9 -0
  18. package/hooks/useTreeViewApiRef.d.ts +1 -1
  19. package/index.js +1 -1
  20. package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +3 -1
  21. package/internals/TreeViewProvider/TreeViewContext.d.ts +2 -8
  22. package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +3 -3
  23. package/internals/TreeViewProvider/useTreeViewContext.d.ts +1 -1
  24. package/internals/corePlugins/corePlugins.d.ts +4 -1
  25. package/internals/corePlugins/corePlugins.js +2 -1
  26. package/internals/corePlugins/index.d.ts +1 -1
  27. package/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.types.d.ts +0 -4
  28. package/internals/hooks/useInstanceEventHandler.d.ts +2 -2
  29. package/internals/index.d.ts +1 -2
  30. package/internals/index.js +3 -1
  31. package/internals/models/plugin.d.ts +27 -17
  32. package/internals/models/treeView.d.ts +3 -5
  33. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +13 -1
  34. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +11 -1
  35. package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +1 -3
  36. package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +1 -1
  37. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +1 -1
  38. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +1 -1
  39. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +1 -1
  40. package/internals/useTreeView/useTreeViewModels.d.ts +1 -1
  41. package/internals/utils/cleanupTracking/TimerBasedCleanupTracking.d.ts +0 -1
  42. package/internals/utils/publishTreeViewEvent.d.ts +1 -1
  43. package/internals/utils/utils.d.ts +1 -0
  44. package/internals/utils/utils.js +7 -1
  45. package/internals/utils/warning.d.ts +1 -1
  46. package/modern/RichTreeView/RichTreeView.js +5 -0
  47. package/modern/RichTreeView/RichTreeView.plugins.js +1 -2
  48. package/modern/SimpleTreeView/SimpleTreeView.js +5 -0
  49. package/modern/SimpleTreeView/SimpleTreeView.plugins.js +1 -2
  50. package/modern/TreeItem/TreeItem.js +19 -4
  51. package/modern/TreeItem/TreeItemContent.js +5 -2
  52. package/modern/TreeItem/useTreeItemState.js +5 -1
  53. package/modern/TreeView/TreeView.js +5 -0
  54. package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +9 -0
  55. package/modern/index.js +1 -1
  56. package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +3 -1
  57. package/modern/internals/corePlugins/corePlugins.js +2 -1
  58. package/modern/internals/index.js +3 -1
  59. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +13 -1
  60. package/modern/internals/utils/utils.js +7 -1
  61. package/modern/useTreeItem2/useTreeItem2.js +18 -2
  62. package/node/RichTreeView/RichTreeView.js +5 -0
  63. package/node/RichTreeView/RichTreeView.plugins.js +1 -2
  64. package/node/SimpleTreeView/SimpleTreeView.js +5 -0
  65. package/node/SimpleTreeView/SimpleTreeView.plugins.js +1 -2
  66. package/node/TreeItem/TreeItem.js +19 -4
  67. package/node/TreeItem/TreeItemContent.js +5 -2
  68. package/node/TreeItem/useTreeItemState.js +5 -1
  69. package/node/TreeView/TreeView.js +5 -0
  70. package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +9 -0
  71. package/node/index.js +1 -1
  72. package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +3 -1
  73. package/node/internals/corePlugins/corePlugins.js +2 -1
  74. package/node/internals/index.js +0 -7
  75. package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +13 -1
  76. package/node/internals/utils/utils.js +8 -1
  77. package/node/useTreeItem2/useTreeItem2.js +18 -2
  78. package/package.json +3 -3
  79. package/useTreeItem2/useTreeItem2.d.ts +2 -2
  80. package/useTreeItem2/useTreeItem2.js +18 -2
  81. package/useTreeItem2/useTreeItem2.types.d.ts +13 -5
  82. /package/internals/{plugins → corePlugins}/useTreeViewId/index.d.ts +0 -0
  83. /package/internals/{plugins → corePlugins}/useTreeViewId/index.js +0 -0
  84. /package/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.d.ts +0 -0
  85. /package/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.js +0 -0
  86. /package/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.types.js +0 -0
  87. /package/modern/internals/{plugins → corePlugins}/useTreeViewId/index.js +0 -0
  88. /package/modern/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.js +0 -0
  89. /package/modern/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.types.js +0 -0
  90. /package/node/internals/{plugins → corePlugins}/useTreeViewId/index.js +0 -0
  91. /package/node/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.js +0 -0
  92. /package/node/internals/{plugins → corePlugins}/useTreeViewId/useTreeViewId.types.js +0 -0
@@ -1,2 +1,2 @@
1
1
  export { TREE_VIEW_CORE_PLUGINS } from './corePlugins';
2
- export type { TreeViewCorePluginSignatures } from './corePlugins';
2
+ export type { TreeViewCorePluginSignatures, TreeViewCorePluginParameters } from './corePlugins';
@@ -19,12 +19,8 @@ export interface UseTreeViewIdParameters {
19
19
  id?: string;
20
20
  }
21
21
  export type UseTreeViewIdDefaultizedParameters = UseTreeViewIdParameters;
22
- export interface UseTreeViewIdState {
23
- focusedItemId: string | null;
24
- }
25
22
  export type UseTreeViewIdSignature = TreeViewPluginSignature<{
26
23
  params: UseTreeViewIdParameters;
27
24
  defaultizedParams: UseTreeViewIdDefaultizedParameters;
28
25
  instance: UseTreeViewIdInstance;
29
- state: UseTreeViewIdState;
30
26
  }>;
@@ -7,9 +7,9 @@ interface RegistryContainer {
7
7
  }
8
8
  export declare function createUseInstanceEventHandler(registryContainer: RegistryContainer): <Instance extends UseTreeViewInstanceEventsInstance & {
9
9
  $$signature: TreeViewAnyPluginSignature;
10
- }, E extends keyof Instance["$$signature"]["events"] | keyof import("../models").MergeSignaturesProperty<[import("../corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types").UseTreeViewInstanceEventsSignature, ...Instance["$$signature"]["dependantPlugins"]], "events">>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance['$$signature']>[E]>) => void;
10
+ }, E extends keyof TreeViewUsedEvents<Instance["$$signature"]>>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance["$$signature"]>[E]>) => void;
11
11
  export declare const unstable_resetCleanupTracking: () => void;
12
12
  export declare const useInstanceEventHandler: <Instance extends UseTreeViewInstanceEventsInstance & {
13
13
  $$signature: TreeViewAnyPluginSignature;
14
- }, E extends keyof Instance["$$signature"]["events"] | keyof import("../models").MergeSignaturesProperty<[import("../corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types").UseTreeViewInstanceEventsSignature, ...Instance["$$signature"]["dependantPlugins"]], "events">>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance['$$signature']>[E]>) => void;
14
+ }, E extends keyof TreeViewUsedEvents<Instance["$$signature"]>>(instance: Instance, eventName: E, handler: TreeViewEventListener<TreeViewUsedEvents<Instance["$$signature"]>[E]>) => void;
15
15
  export {};
@@ -2,6 +2,7 @@ export { useTreeView } from './useTreeView';
2
2
  export { TreeViewProvider } from './TreeViewProvider';
3
3
  export { unstable_resetCleanupTracking } from './hooks/useInstanceEventHandler';
4
4
  export type { TreeViewPlugin, TreeViewPluginSignature, ConvertPluginsIntoSignatures, MergeSignaturesProperty, TreeViewPublicAPI, TreeViewExperimentalFeatures, } from './models';
5
+ export type { TreeViewCorePluginParameters } from './corePlugins';
5
6
  export { useTreeViewExpansion } from './plugins/useTreeViewExpansion';
6
7
  export type { UseTreeViewExpansionSignature, UseTreeViewExpansionParameters, } from './plugins/useTreeViewExpansion';
7
8
  export { useTreeViewSelection } from './plugins/useTreeViewSelection';
@@ -10,8 +11,6 @@ export { useTreeViewFocus } from './plugins/useTreeViewFocus';
10
11
  export type { UseTreeViewFocusSignature, UseTreeViewFocusParameters, } from './plugins/useTreeViewFocus';
11
12
  export { useTreeViewKeyboardNavigation } from './plugins/useTreeViewKeyboardNavigation';
12
13
  export type { UseTreeViewKeyboardNavigationSignature } from './plugins/useTreeViewKeyboardNavigation';
13
- export { useTreeViewId } from './plugins/useTreeViewId';
14
- export type { UseTreeViewIdSignature, UseTreeViewIdParameters } from './plugins/useTreeViewId';
15
14
  export { useTreeViewIcons } from './plugins/useTreeViewIcons';
16
15
  export type { UseTreeViewIconsSignature, UseTreeViewIconsParameters, } from './plugins/useTreeViewIcons';
17
16
  export { useTreeViewItems } from './plugins/useTreeViewItems';
@@ -1,12 +1,14 @@
1
1
  export { useTreeView } from './useTreeView';
2
2
  export { TreeViewProvider } from './TreeViewProvider';
3
3
  export { unstable_resetCleanupTracking } from './hooks/useInstanceEventHandler';
4
+
5
+ // Core plugins
6
+
4
7
  // Plugins
5
8
  export { useTreeViewExpansion } from './plugins/useTreeViewExpansion';
6
9
  export { useTreeViewSelection } from './plugins/useTreeViewSelection';
7
10
  export { useTreeViewFocus } from './plugins/useTreeViewFocus';
8
11
  export { useTreeViewKeyboardNavigation } from './plugins/useTreeViewKeyboardNavigation';
9
- export { useTreeViewId } from './plugins/useTreeViewId';
10
12
  export { useTreeViewIcons } from './plugins/useTreeViewIcons';
11
13
  export { useTreeViewItems } from './plugins/useTreeViewItems';
12
14
  export { useTreeViewJSXItems } from './plugins/useTreeViewJSXItems';
@@ -42,7 +42,8 @@ export type TreeViewPluginSignature<T extends {
42
42
  };
43
43
  modelNames?: keyof T['defaultizedParams'];
44
44
  experimentalFeatures?: string;
45
- dependantPlugins?: readonly TreeViewAnyPluginSignature[];
45
+ dependencies?: readonly TreeViewAnyPluginSignature[];
46
+ optionalDependencies?: readonly TreeViewAnyPluginSignature[];
46
47
  }> = {
47
48
  params: T extends {
48
49
  params: {};
@@ -77,17 +78,25 @@ export type TreeViewPluginSignature<T extends {
77
78
  } ? {
78
79
  [TControlled in T['modelNames']]-?: TreeViewModel<Exclude<T['defaultizedParams'][TControlled], undefined>>;
79
80
  } : {};
80
- experimentalFeatures: T['experimentalFeatures'];
81
- dependantPlugins: T extends {
82
- dependantPlugins: Array<any>;
83
- } ? T['dependantPlugins'] : [];
81
+ experimentalFeatures: T extends {
82
+ experimentalFeatures: string;
83
+ } ? {
84
+ [key in T['experimentalFeatures']]?: boolean;
85
+ } : {};
86
+ dependencies: T extends {
87
+ dependencies: Array<any>;
88
+ } ? T['dependencies'] : [];
89
+ optionalDependencies: T extends {
90
+ optionalDependencies: Array<any>;
91
+ } ? T['optionalDependencies'] : [];
84
92
  };
85
93
  export type TreeViewAnyPluginSignature = {
86
94
  state: any;
87
95
  instance: any;
88
96
  params: any;
89
97
  defaultizedParams: any;
90
- dependantPlugins: any;
98
+ dependencies: any;
99
+ optionalDependencies: any;
91
100
  events: any;
92
101
  contextValue: any;
93
102
  slots: any;
@@ -96,25 +105,26 @@ export type TreeViewAnyPluginSignature = {
96
105
  experimentalFeatures: any;
97
106
  publicAPI: any;
98
107
  };
99
- type TreeViewUsedPlugins<TSignature extends TreeViewAnyPluginSignature> = [
108
+ type TreeViewRequiredPlugins<TSignature extends TreeViewAnyPluginSignature> = [
100
109
  ...TreeViewCorePluginSignatures,
101
- ...TSignature['dependantPlugins']
110
+ ...TSignature['dependencies']
102
111
  ];
103
- export type TreeViewUsedParams<TSignature extends TreeViewAnyPluginSignature> = TSignature['params'] & MergeSignaturesProperty<TreeViewUsedPlugins<TSignature>, 'params'>;
104
- type TreeViewUsedDefaultizedParams<TSignature extends TreeViewAnyPluginSignature> = TSignature['defaultizedParams'] & MergeSignaturesProperty<TreeViewUsedPlugins<TSignature>, 'defaultizedParams'>;
105
- export type TreeViewUsedInstance<TSignature extends TreeViewAnyPluginSignature> = TSignature['instance'] & MergeSignaturesProperty<TreeViewUsedPlugins<TSignature>, 'instance'> & {
112
+ type PluginPropertyWithDependencies<TSignature extends TreeViewAnyPluginSignature, TProperty extends keyof TreeViewAnyPluginSignature> = TSignature[TProperty] & MergeSignaturesProperty<TreeViewRequiredPlugins<TSignature>, TProperty> & Partial<MergeSignaturesProperty<TSignature['optionalDependencies'], TProperty>>;
113
+ export type TreeViewUsedParams<TSignature extends TreeViewAnyPluginSignature> = PluginPropertyWithDependencies<TSignature, 'params'>;
114
+ type TreeViewUsedDefaultizedParams<TSignature extends TreeViewAnyPluginSignature> = PluginPropertyWithDependencies<TSignature, 'defaultizedParams'>;
115
+ export type TreeViewUsedInstance<TSignature extends TreeViewAnyPluginSignature> = PluginPropertyWithDependencies<TSignature, 'instance'> & {
106
116
  /**
107
117
  * Private property only defined in TypeScript to be able to access the plugin signature from the instance object.
108
118
  */
109
119
  $$signature: TSignature;
110
120
  };
111
- type TreeViewUsedState<TSignature extends TreeViewAnyPluginSignature> = TSignature['state'] & MergeSignaturesProperty<TreeViewUsedPlugins<TSignature>, 'state'>;
112
- type TreeViewUsedExperimentalFeatures<TSignature extends TreeViewAnyPluginSignature> = TreeViewExperimentalFeatures<[TSignature, ...TSignature['dependantPlugins']]>;
121
+ type TreeViewUsedState<TSignature extends TreeViewAnyPluginSignature> = PluginPropertyWithDependencies<TSignature, 'state'>;
122
+ type TreeViewUsedExperimentalFeatures<TSignature extends TreeViewAnyPluginSignature> = TreeViewExperimentalFeatures<[TSignature, ...TSignature['dependencies']]>;
113
123
  type RemoveSetValue<Models extends Record<string, TreeViewModel<any>>> = {
114
124
  [K in keyof Models]: Omit<Models[K], 'setValue'>;
115
125
  };
116
- export type TreeViewUsedModels<TSignature extends TreeViewAnyPluginSignature> = TSignature['models'] & RemoveSetValue<MergeSignaturesProperty<TreeViewUsedPlugins<TSignature>, 'models'>>;
117
- export type TreeViewUsedEvents<TSignature extends TreeViewAnyPluginSignature> = TSignature['events'] & MergeSignaturesProperty<TreeViewUsedPlugins<TSignature>, 'events'>;
126
+ export type TreeViewUsedModels<TSignature extends TreeViewAnyPluginSignature> = TSignature['models'] & RemoveSetValue<MergeSignaturesProperty<TreeViewRequiredPlugins<TSignature>, 'models'>>;
127
+ export type TreeViewUsedEvents<TSignature extends TreeViewAnyPluginSignature> = TSignature['events'] & MergeSignaturesProperty<TreeViewRequiredPlugins<TSignature>, 'events'>;
118
128
  export interface TreeViewItemPluginOptions<TProps extends {}> extends TreeViewItemPluginResponse {
119
129
  props: TProps;
120
130
  }
@@ -150,12 +160,12 @@ export type TreeViewPlugin<TSignature extends TreeViewAnyPluginSignature> = {
150
160
  * @param {{ nodeId: TreeViewItemId; children: React.ReactNode; }} params The params of the item.
151
161
  * @returns {React.ReactNode} The wrapped item.
152
162
  */
153
- wrapItem?: TreeItemWrapper<[TSignature, ...TSignature['dependantPlugins']]>;
163
+ wrapItem?: TreeItemWrapper<[TSignature, ...TSignature['dependencies']]>;
154
164
  /**
155
165
  * Render function used to add React wrappers around the TreeView.
156
166
  * @param {{ children: React.ReactNode; }} params The params of the root.
157
167
  * @returns {React.ReactNode} The wrapped root.
158
168
  */
159
- wrapRoot?: TreeRootWrapper<[TSignature, ...TSignature['dependantPlugins']]>;
169
+ wrapRoot?: TreeRootWrapper<[TSignature, ...TSignature['dependencies']]>;
160
170
  };
161
171
  export {};
@@ -21,8 +21,6 @@ export interface TreeViewModel<TValue> {
21
21
  value: TValue;
22
22
  setControlledValue: (value: TValue | ((prevValue: TValue) => TValue)) => void;
23
23
  }
24
- export type TreeViewInstance<TSignatures extends readonly TreeViewAnyPluginSignature[]> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'instance'>;
25
- export type TreeViewPublicAPI<TSignatures extends readonly TreeViewAnyPluginSignature[]> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'publicAPI'>;
26
- export type TreeViewExperimentalFeatures<TSignatures extends readonly TreeViewAnyPluginSignature[]> = {
27
- [key in MergeSignaturesProperty<TSignatures, 'experimentalFeatures'>]?: boolean;
28
- };
24
+ export type TreeViewInstance<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'instance'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'instance'>>;
25
+ export type TreeViewPublicAPI<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'publicAPI'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'instance'>>;
26
+ export type TreeViewExperimentalFeatures<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TSignatures, ...TOptionalSignatures], 'experimentalFeatures'>;
@@ -53,6 +53,12 @@ export const useTreeViewExpansion = ({
53
53
  setExpandedItems(event, newExpanded);
54
54
  }
55
55
  };
56
+ const expansionTrigger = React.useMemo(() => {
57
+ if (params.expansionTrigger) {
58
+ return params.expansionTrigger;
59
+ }
60
+ return 'content';
61
+ }, [params.expansionTrigger]);
56
62
  return {
57
63
  publicAPI: {
58
64
  setItemExpansion
@@ -63,6 +69,11 @@ export const useTreeViewExpansion = ({
63
69
  setItemExpansion,
64
70
  toggleItemExpansion,
65
71
  expandAllSiblings
72
+ },
73
+ contextValue: {
74
+ expansion: {
75
+ expansionTrigger
76
+ }
66
77
  }
67
78
  };
68
79
  };
@@ -79,5 +90,6 @@ useTreeViewExpansion.params = {
79
90
  expandedItems: true,
80
91
  defaultExpandedItems: true,
81
92
  onExpandedItemsChange: true,
82
- onItemExpansionToggle: true
93
+ onItemExpansionToggle: true,
94
+ expansionTrigger: true
83
95
  };
@@ -65,13 +65,23 @@ export interface UseTreeViewExpansionParameters {
65
65
  * @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
66
66
  */
67
67
  onItemExpansionToggle?: (event: React.SyntheticEvent, itemId: string, isExpanded: boolean) => void;
68
+ /**
69
+ * The slot that triggers the item's expansion when clicked.
70
+ * @default 'content'
71
+ */
72
+ expansionTrigger?: 'content' | 'iconContainer';
68
73
  }
69
74
  export type UseTreeViewExpansionDefaultizedParameters = DefaultizedProps<UseTreeViewExpansionParameters, 'defaultExpandedItems'>;
75
+ interface UseTreeViewExpansionContextValue {
76
+ expansion: Pick<UseTreeViewExpansionParameters, 'expansionTrigger'>;
77
+ }
70
78
  export type UseTreeViewExpansionSignature = TreeViewPluginSignature<{
71
79
  params: UseTreeViewExpansionParameters;
72
80
  defaultizedParams: UseTreeViewExpansionDefaultizedParameters;
73
81
  instance: UseTreeViewExpansionInstance;
74
82
  publicAPI: UseTreeViewExpansionPublicAPI;
75
83
  modelNames: 'expandedItems';
76
- dependantPlugins: [UseTreeViewItemsSignature];
84
+ contextValue: UseTreeViewExpansionContextValue;
85
+ dependencies: [UseTreeViewItemsSignature];
77
86
  }>;
87
+ export {};
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react';
2
2
  import { TreeViewPluginSignature } from '../../models';
3
- import { UseTreeViewIdSignature } from '../useTreeViewId/useTreeViewId.types';
4
3
  import type { UseTreeViewItemsSignature } from '../useTreeViewItems';
5
4
  import type { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
6
5
  import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
@@ -55,8 +54,7 @@ export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
55
54
  instance: UseTreeViewFocusInstance;
56
55
  publicAPI: UseTreeViewFocusPublicAPI;
57
56
  state: UseTreeViewFocusState;
58
- dependantPlugins: [
59
- UseTreeViewIdSignature,
57
+ dependencies: [
60
58
  UseTreeViewItemsSignature,
61
59
  UseTreeViewSelectionSignature,
62
60
  UseTreeViewExpansionSignature
@@ -38,6 +38,6 @@ export type UseTreeViewIconsSignature = TreeViewPluginSignature<{
38
38
  contextValue: UseTreeViewIconsContextValue;
39
39
  slots: UseTreeViewIconsSlots;
40
40
  slotProps: UseTreeViewIconsSlotProps;
41
- dependantPlugins: [UseTreeViewItemsSignature, UseTreeViewSelectionSignature];
41
+ dependencies: [UseTreeViewItemsSignature, UseTreeViewSelectionSignature];
42
42
  }>;
43
43
  export {};
@@ -33,5 +33,5 @@ export type UseTreeViewJSXItemsSignature = TreeViewPluginSignature<{
33
33
  params: UseTreeViewJSXItemsParameters;
34
34
  defaultizedParams: UseTreeViewItemsDefaultizedParameters;
35
35
  instance: UseTreeViewItemsInstance;
36
- dependantPlugins: [UseTreeViewItemsSignature, UseTreeViewKeyboardNavigationSignature];
36
+ dependencies: [UseTreeViewItemsSignature, UseTreeViewKeyboardNavigationSignature];
37
37
  }>;
@@ -24,7 +24,7 @@ export interface UseTreeViewKeyboardNavigationInstance {
24
24
  }
25
25
  export type UseTreeViewKeyboardNavigationSignature = TreeViewPluginSignature<{
26
26
  instance: UseTreeViewKeyboardNavigationInstance;
27
- dependantPlugins: [
27
+ dependencies: [
28
28
  UseTreeViewItemsSignature,
29
29
  UseTreeViewSelectionSignature,
30
30
  UseTreeViewFocusSignature,
@@ -101,7 +101,7 @@ export type UseTreeViewSelectionSignature = TreeViewPluginSignature<{
101
101
  instance: UseTreeViewSelectionInstance;
102
102
  contextValue: UseTreeViewSelectionContextValue;
103
103
  modelNames: 'selectedItems';
104
- dependantPlugins: [
104
+ dependencies: [
105
105
  UseTreeViewItemsSignature,
106
106
  UseTreeViewExpansionSignature,
107
107
  UseTreeViewItemsSignature
@@ -4,4 +4,4 @@ import { TreeViewCorePluginSignatures } from '../corePlugins';
4
4
  * Implements the same behavior as `useControlled` but for several models.
5
5
  * The controlled models are never stored in the state, and the state is only updated if the model is not controlled.
6
6
  */
7
- export declare const useTreeViewModels: <TSignatures extends readonly TreeViewAnyPluginSignature[]>(plugins: ConvertSignaturesIntoPlugins<readonly [...TreeViewCorePluginSignatures, ...TSignatures]>, props: MergeSignaturesProperty<TSignatures, 'defaultizedParams'>) => MergeSignaturesProperty<TSignatures, "models">;
7
+ export declare const useTreeViewModels: <TSignatures extends readonly TreeViewAnyPluginSignature[]>(plugins: ConvertSignaturesIntoPlugins<readonly [...TreeViewCorePluginSignatures, ...TSignatures]>, props: MergeSignaturesProperty<TSignatures, "defaultizedParams">) => MergeSignaturesProperty<TSignatures, "models">;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { CleanupTracking, UnregisterToken, UnsubscribeFn } from './CleanupTracking';
3
2
  export declare class TimerBasedCleanupTracking implements CleanupTracking {
4
3
  timeouts?: Map<number, NodeJS.Timeout> | undefined;
@@ -2,4 +2,4 @@ import { UseTreeViewInstanceEventsInstance } from '../corePlugins/useTreeViewIns
2
2
  import { TreeViewAnyPluginSignature, TreeViewUsedEvents } from '../models';
3
3
  export declare const publishTreeViewEvent: <Instance extends UseTreeViewInstanceEventsInstance & {
4
4
  $$signature: TreeViewAnyPluginSignature;
5
- }, E extends keyof Instance["$$signature"]["events"] | keyof import("../models").MergeSignaturesProperty<[import("../corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types").UseTreeViewInstanceEventsSignature, ...Instance["$$signature"]["dependantPlugins"]], "events">>(instance: Instance, eventName: E, params: TreeViewUsedEvents<Instance['$$signature']>[E]['params']) => void;
5
+ }, E extends keyof TreeViewUsedEvents<Instance["$$signature"]>>(instance: Instance, eventName: E, params: TreeViewUsedEvents<Instance["$$signature"]>[E]["params"]) => void;
@@ -1 +1,2 @@
1
1
  export declare const getActiveElement: (root?: Document | ShadowRoot) => Element | null;
2
+ export declare function escapeOperandAttributeSelector(operand: string): string;
@@ -8,4 +8,10 @@ export const getActiveElement = (root = document) => {
8
8
  return getActiveElement(activeEl.shadowRoot);
9
9
  }
10
10
  return activeEl;
11
- };
11
+ };
12
+
13
+ // TODO, eventually replaces this function with CSS.escape, once available in jsdom, either added manually or built in
14
+ // https://github.com/jsdom/jsdom/issues/1550#issuecomment-236734471
15
+ export function escapeOperandAttributeSelector(operand) {
16
+ return operand.replace(/["\\]/g, '\\$&');
17
+ }
@@ -1 +1 @@
1
- export declare const buildWarning: (message: string | string[], gravity?: 'warning' | 'error') => () => void;
1
+ export declare const buildWarning: (message: string | string[], gravity?: "warning" | "error") => () => void;
@@ -177,6 +177,11 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
177
177
  * Used when the item's expansion is controlled.
178
178
  */
179
179
  expandedItems: PropTypes.arrayOf(PropTypes.string),
180
+ /**
181
+ * The slot that triggers the item's expansion when clicked.
182
+ * @default 'content'
183
+ */
184
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
180
185
  /**
181
186
  * Unstable features, breaking changes might be introduced.
182
187
  * For each feature, if the flag is not explicitly set to `true`,
@@ -1,10 +1,9 @@
1
- import { useTreeViewId } from '../internals/plugins/useTreeViewId';
2
1
  import { useTreeViewItems } from '../internals/plugins/useTreeViewItems';
3
2
  import { useTreeViewExpansion } from '../internals/plugins/useTreeViewExpansion';
4
3
  import { useTreeViewSelection } from '../internals/plugins/useTreeViewSelection';
5
4
  import { useTreeViewFocus } from '../internals/plugins/useTreeViewFocus';
6
5
  import { useTreeViewKeyboardNavigation } from '../internals/plugins/useTreeViewKeyboardNavigation';
7
6
  import { useTreeViewIcons } from '../internals/plugins/useTreeViewIcons';
8
- export const RICH_TREE_VIEW_PLUGINS = [useTreeViewId, useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
7
+ export const RICH_TREE_VIEW_PLUGINS = [useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
9
8
 
10
9
  // We can't infer this type from the plugin, otherwise we would lose the generics.
@@ -139,6 +139,11 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
139
139
  * Used when the item's expansion is controlled.
140
140
  */
141
141
  expandedItems: PropTypes.arrayOf(PropTypes.string),
142
+ /**
143
+ * The slot that triggers the item's expansion when clicked.
144
+ * @default 'content'
145
+ */
146
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
142
147
  /**
143
148
  * Unstable features, breaking changes might be introduced.
144
149
  * For each feature, if the flag is not explicitly set to `true`,
@@ -1,4 +1,3 @@
1
- import { useTreeViewId } from '../internals/plugins/useTreeViewId';
2
1
  import { useTreeViewItems } from '../internals/plugins/useTreeViewItems';
3
2
  import { useTreeViewExpansion } from '../internals/plugins/useTreeViewExpansion';
4
3
  import { useTreeViewSelection } from '../internals/plugins/useTreeViewSelection';
@@ -6,6 +5,6 @@ import { useTreeViewFocus } from '../internals/plugins/useTreeViewFocus';
6
5
  import { useTreeViewKeyboardNavigation } from '../internals/plugins/useTreeViewKeyboardNavigation';
7
6
  import { useTreeViewIcons } from '../internals/plugins/useTreeViewIcons';
8
7
  import { useTreeViewJSXItems } from '../internals/plugins/useTreeViewJSXItems';
9
- export const SIMPLE_TREE_VIEW_PLUGINS = [useTreeViewId, useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons, useTreeViewJSXItems];
8
+ export const SIMPLE_TREE_VIEW_PLUGINS = [useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons, useTreeViewJSXItems];
10
9
 
11
10
  // We can't infer this type from the plugin, otherwise we would lose the generics.
@@ -22,6 +22,7 @@ import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewCon
22
22
  import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons';
23
23
  import { TreeItem2Provider } from '../TreeItem2Provider';
24
24
  import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext';
25
+ import { useTreeItemState } from './useTreeItemState';
25
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
26
27
  const useThemeProps = createUseThemeProps('MuiTreeItem');
27
28
  const useUtilityClasses = ownerState => {
@@ -168,6 +169,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
168
169
  selection: {
169
170
  multiSelect
170
171
  },
172
+ expansion: {
173
+ expansionTrigger
174
+ },
171
175
  disabledItemsFocusable,
172
176
  indentationAtItemLevel,
173
177
  instance
@@ -193,6 +197,13 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
193
197
  onKeyDown
194
198
  } = props,
195
199
  other = _objectWithoutPropertiesLoose(props, _excluded);
200
+ const {
201
+ expanded,
202
+ focused,
203
+ selected,
204
+ disabled,
205
+ handleExpansion
206
+ } = useTreeItemState(itemId);
196
207
  const {
197
208
  contentRef,
198
209
  rootRef
@@ -213,10 +224,6 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
213
224
  return Boolean(reactChildren);
214
225
  };
215
226
  const expandable = isExpandable(children);
216
- const expanded = instance.isItemExpanded(itemId);
217
- const focused = instance.isItemFocused(itemId);
218
- const selected = instance.isItemSelected(itemId);
219
- const disabled = instance.isItemDisabled(itemId);
220
227
  const ownerState = _extends({}, props, {
221
228
  expanded,
222
229
  focused,
@@ -240,6 +247,11 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
240
247
  } : {}),
241
248
  className: classes.groupTransition
242
249
  });
250
+ const handleIconContainerClick = event => {
251
+ if (expansionTrigger === 'iconContainer') {
252
+ handleExpansion(event);
253
+ }
254
+ };
243
255
  const ExpansionIcon = expanded ? slots.collapseIcon : slots.expandIcon;
244
256
  const _useSlotProps = useSlotProps({
245
257
  elementType: ExpansionIcon,
@@ -249,6 +261,9 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
249
261
  return _extends({}, resolveComponentProps(contextIcons.slotProps.collapseIcon, tempOwnerState), resolveComponentProps(inSlotProps?.collapseIcon, tempOwnerState));
250
262
  }
251
263
  return _extends({}, resolveComponentProps(contextIcons.slotProps.expandIcon, tempOwnerState), resolveComponentProps(inSlotProps?.expandIcon, tempOwnerState));
264
+ },
265
+ additionalProps: {
266
+ onClick: handleIconContainerClick
252
267
  }
253
268
  }),
254
269
  expansionIconProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded2);
@@ -33,7 +33,8 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
33
33
  handleExpansion,
34
34
  handleSelection,
35
35
  handleCheckboxSelection,
36
- preventSelection
36
+ preventSelection,
37
+ expansionTrigger
37
38
  } = useTreeItemState(itemId);
38
39
  const icon = iconProp || expansionIcon || displayIcon;
39
40
  const checkboxRef = React.useRef(null);
@@ -47,7 +48,9 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
47
48
  if (checkboxRef.current?.contains(event.target)) {
48
49
  return;
49
50
  }
50
- handleExpansion(event);
51
+ if (expansionTrigger === 'content') {
52
+ handleExpansion(event);
53
+ }
51
54
  if (!checkboxSelection) {
52
55
  handleSelection(event);
53
56
  }
@@ -6,6 +6,9 @@ export function useTreeItemState(itemId) {
6
6
  multiSelect,
7
7
  checkboxSelection,
8
8
  disableSelection
9
+ },
10
+ expansion: {
11
+ expansionTrigger
9
12
  }
10
13
  } = useTreeViewContext();
11
14
  const expandable = instance.isItemExpandable(itemId);
@@ -70,6 +73,7 @@ export function useTreeItemState(itemId) {
70
73
  handleExpansion,
71
74
  handleSelection,
72
75
  handleCheckboxSelection,
73
- preventSelection
76
+ preventSelection,
77
+ expansionTrigger
74
78
  };
75
79
  }
@@ -116,6 +116,11 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
116
116
  * Used when the item's expansion is controlled.
117
117
  */
118
118
  expandedItems: PropTypes.arrayOf(PropTypes.string),
119
+ /**
120
+ * The slot that triggers the item's expansion when clicked.
121
+ * @default 'content'
122
+ */
123
+ expansionTrigger: PropTypes.oneOf(['content', 'iconContainer']),
119
124
  /**
120
125
  * Unstable features, breaking changes might be introduced.
121
126
  * For each feature, if the flag is not explicitly set to `true`,
@@ -5,6 +5,15 @@ const isItemExpandable = reactChildren => {
5
5
  }
6
6
  return Boolean(reactChildren);
7
7
  };
8
+
9
+ /**
10
+ * Plugins that need to be present in the Tree View in order for `useTreeItem2Utils` to work correctly.
11
+ */
12
+
13
+ /**
14
+ * Plugins that `useTreeItem2Utils` can use if they are present, but are not required.
15
+ */
16
+
8
17
  export const useTreeItem2Utils = ({
9
18
  itemId,
10
19
  children
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v7.7.0
2
+ * @mui/x-tree-view v7.8.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useTreeViewContext } from './useTreeViewContext';
4
+ import { escapeOperandAttributeSelector } from '../utils/utils';
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  export const TreeViewChildrenItemContext = /*#__PURE__*/React.createContext(null);
6
7
  if (process.env.NODE_ENV !== 'production') {
@@ -34,7 +35,8 @@ export function TreeViewChildrenItemProvider(props) {
34
35
  return;
35
36
  }
36
37
  const previousChildrenIds = instance.getItemOrderedChildrenIds(itemId ?? null) ?? [];
37
- const childrenElements = rootRef.current.querySelectorAll(`${itemId == null ? '' : `*[id="${idAttr}"] `}[role="treeitem"]:not(*[id="${idAttr}"] [role="treeitem"] [role="treeitem"])`);
38
+ const escapedIdAttr = escapeOperandAttributeSelector(idAttr);
39
+ const childrenElements = rootRef.current.querySelectorAll(`${itemId == null ? '' : `*[id="${escapedIdAttr}"] `}[role="treeitem"]:not(*[id="${escapedIdAttr}"] [role="treeitem"] [role="treeitem"])`);
38
40
  const childrenIds = Array.from(childrenElements).map(child => childrenIdAttrToIdRef.current.get(child.id));
39
41
  const hasChanged = childrenIds.length !== previousChildrenIds.length || childrenIds.some((childId, index) => childId !== previousChildrenIds[index]);
40
42
  if (hasChanged) {
@@ -1,6 +1,7 @@
1
1
  import { useTreeViewInstanceEvents } from './useTreeViewInstanceEvents';
2
+ import { useTreeViewId } from './useTreeViewId';
2
3
  /**
3
4
  * Internal plugins that create the tools used by the other plugins.
4
5
  * These plugins are used by the tree view components.
5
6
  */
6
- export const TREE_VIEW_CORE_PLUGINS = [useTreeViewInstanceEvents];
7
+ export const TREE_VIEW_CORE_PLUGINS = [useTreeViewInstanceEvents, useTreeViewId];
@@ -1,12 +1,14 @@
1
1
  export { useTreeView } from './useTreeView';
2
2
  export { TreeViewProvider } from './TreeViewProvider';
3
3
  export { unstable_resetCleanupTracking } from './hooks/useInstanceEventHandler';
4
+
5
+ // Core plugins
6
+
4
7
  // Plugins
5
8
  export { useTreeViewExpansion } from './plugins/useTreeViewExpansion';
6
9
  export { useTreeViewSelection } from './plugins/useTreeViewSelection';
7
10
  export { useTreeViewFocus } from './plugins/useTreeViewFocus';
8
11
  export { useTreeViewKeyboardNavigation } from './plugins/useTreeViewKeyboardNavigation';
9
- export { useTreeViewId } from './plugins/useTreeViewId';
10
12
  export { useTreeViewIcons } from './plugins/useTreeViewIcons';
11
13
  export { useTreeViewItems } from './plugins/useTreeViewItems';
12
14
  export { useTreeViewJSXItems } from './plugins/useTreeViewJSXItems';
@@ -53,6 +53,12 @@ export const useTreeViewExpansion = ({
53
53
  setExpandedItems(event, newExpanded);
54
54
  }
55
55
  };
56
+ const expansionTrigger = React.useMemo(() => {
57
+ if (params.expansionTrigger) {
58
+ return params.expansionTrigger;
59
+ }
60
+ return 'content';
61
+ }, [params.expansionTrigger]);
56
62
  return {
57
63
  publicAPI: {
58
64
  setItemExpansion
@@ -63,6 +69,11 @@ export const useTreeViewExpansion = ({
63
69
  setItemExpansion,
64
70
  toggleItemExpansion,
65
71
  expandAllSiblings
72
+ },
73
+ contextValue: {
74
+ expansion: {
75
+ expansionTrigger
76
+ }
66
77
  }
67
78
  };
68
79
  };
@@ -79,5 +90,6 @@ useTreeViewExpansion.params = {
79
90
  expandedItems: true,
80
91
  defaultExpandedItems: true,
81
92
  onExpandedItemsChange: true,
82
- onItemExpansionToggle: true
93
+ onItemExpansionToggle: true,
94
+ expansionTrigger: true
83
95
  };
@@ -8,4 +8,10 @@ export const getActiveElement = (root = document) => {
8
8
  return getActiveElement(activeEl.shadowRoot);
9
9
  }
10
10
  return activeEl;
11
- };
11
+ };
12
+
13
+ // TODO, eventually replaces this function with CSS.escape, once available in jsdom, either added manually or built in
14
+ // https://github.com/jsdom/jsdom/issues/1550#issuecomment-236734471
15
+ export function escapeOperandAttributeSelector(operand) {
16
+ return operand.replace(/["\\]/g, '\\$&');
17
+ }