diff --git a/docs/data/tree-view/headless/HeadlessTreeView.tsx b/docs/data/tree-view/headless/HeadlessTreeView.tsx index 0d5f611d1374c..1c5b2f6e467b3 100644 --- a/docs/data/tree-view/headless/HeadlessTreeView.tsx +++ b/docs/data/tree-view/headless/HeadlessTreeView.tsx @@ -51,6 +51,8 @@ type TreeViewLogExpandedSignature = TreeViewPluginSignature< {}, // State defined by this plugin: we don't have any {}, + // Context value defined by this plugin: we don't have any + {}, // Models defined by plugin: we don't have any never, // Dependencies of this plugin (we need the expansion plugin to access its model) diff --git a/packages/x-tree-view/src/TreeItem/TreeItem.tsx b/packages/x-tree-view/src/TreeItem/TreeItem.tsx index 617c712b27de4..6a081290c1dc7 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItem.tsx +++ b/packages/x-tree-view/src/TreeItem/TreeItem.tsx @@ -21,6 +21,7 @@ const useUtilityClasses = (ownerState: TreeItemOwnerState) => { expanded: ['expanded'], selected: ['selected'], focused: ['focused'], + interactive: ['interactive'], disabled: ['disabled'], iconContainer: ['iconContainer'], label: ['label'], @@ -61,9 +62,11 @@ const StyledTreeItemContent = styled(TreeItemContent, { boxSizing: 'border-box', // prevent width + padding to overflow display: 'flex', alignItems: 'center', - cursor: 'pointer', + [`&.${treeItemClasses.interactive}`]: { + cursor: 'pointer', + }, WebkitTapHighlightColor: 'transparent', - '&:hover': { + [`&.${treeItemClasses.interactive}:hover`]: { backgroundColor: (theme.vars || theme).palette.action.hover, // Reset on touch devices, it doesn't add specificity '@media (hover: none)': { @@ -77,11 +80,11 @@ const StyledTreeItemContent = styled(TreeItemContent, { [`&.${treeItemClasses.focused}`]: { backgroundColor: (theme.vars || theme).palette.action.focus, }, - [`&.${treeItemClasses.selected}`]: { + [`.${treeItemClasses.selected}`]: { backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - '&:hover': { + [`&.${treeItemClasses.interactive}:hover`]: { backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha( @@ -152,7 +155,7 @@ export const TreeItem = React.forwardRef(function TreeItem( const { icons: contextIcons, runItemPlugins, - multiSelect, + selection: { multiSelect }, disabledItemsFocusable, instance, } = useTreeViewContext(); @@ -260,6 +263,7 @@ export const TreeItem = React.forwardRef(function TreeItem( root: classes.content, expanded: classes.expanded, selected: classes.selected, + interactive: classes.interactive, focused: classes.focused, disabled: classes.disabled, iconContainer: classes.iconContainer, diff --git a/packages/x-tree-view/src/TreeItem/TreeItemContent.tsx b/packages/x-tree-view/src/TreeItem/TreeItemContent.tsx index 906b571977ecc..96c2a8169cf41 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItemContent.tsx +++ b/packages/x-tree-view/src/TreeItem/TreeItemContent.tsx @@ -19,6 +19,8 @@ export interface TreeItemContentProps extends React.HTMLAttributes expanded: string; /** State class applied to the content element when selected and not using the checkbox selection. */ selected: string; + /** State class applied to the content element when clicking it causes an action. */ + interactive: string; /** State class applied to the content element when focused. */ focused: string; /** State class applied to the element when disabled. */ @@ -75,8 +77,10 @@ const TreeItemContent = React.forwardRef(function TreeItemContent( const { disabled, expanded, + expandable, selected, focused, + disableSelection, checkboxSelection, handleExpansion, handleSelection, @@ -121,6 +125,7 @@ const TreeItemContent = React.forwardRef(function TreeItemContent( className={clsx(className, classes.root, { [classes.expanded]: expanded, [classes.selected]: selected && !checkboxSelection, + [classes.interactive]: (!checkboxSelection && !disableSelection) || expandable, [classes.focused]: focused, [classes.disabled]: disabled, })} @@ -130,7 +135,12 @@ const TreeItemContent = React.forwardRef(function TreeItemContent( >
{icon}
{checkboxSelection && ( - + )}
{label}
diff --git a/packages/x-tree-view/src/TreeItem/treeItemClasses.ts b/packages/x-tree-view/src/TreeItem/treeItemClasses.ts index 1578b5c5c9eec..d4d0bcbc216dd 100644 --- a/packages/x-tree-view/src/TreeItem/treeItemClasses.ts +++ b/packages/x-tree-view/src/TreeItem/treeItemClasses.ts @@ -10,8 +10,10 @@ export interface TreeItemClasses { content: string; /** State class applied to the content element when expanded. */ expanded: string; - /** State class applied to the content element when selected. */ + /** State class applied to the content element when selected and not using the checkbox selection. */ selected: string; + /** State class applied to the content element when clicking it causes an action. */ + interactive: string; /** State class applied to the content element when focused. */ focused: string; /** State class applied to the element when disabled. */ @@ -34,6 +36,7 @@ export const treeItemClasses: TreeItemClasses = generateUtilityClasses('MuiTreeI 'content', 'expanded', 'selected', + 'interactive', 'focused', 'disabled', 'iconContainer', diff --git a/packages/x-tree-view/src/TreeItem/useTreeItem.ts b/packages/x-tree-view/src/TreeItem/useTreeItem.ts index 0810438dba919..cea02393692e0 100644 --- a/packages/x-tree-view/src/TreeItem/useTreeItem.ts +++ b/packages/x-tree-view/src/TreeItem/useTreeItem.ts @@ -3,7 +3,10 @@ import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewCon import { DefaultTreeViewPlugins } from '../internals/plugins'; export function useTreeItem(nodeId: string) { - const { instance, multiSelect, checkboxSelection } = useTreeViewContext(); + const { + instance, + selection: { multiSelect, checkboxSelection, disableSelection }, + } = useTreeViewContext(); const expandable = instance.isNodeExpandable(nodeId); const expanded = instance.isNodeExpanded(nodeId); @@ -59,10 +62,12 @@ export function useTreeItem(nodeId: string) { }; return { + expandable, disabled, expanded, selected, focused, + disableSelection, checkboxSelection, handleExpansion, handleSelection, diff --git a/packages/x-tree-view/src/internals/TreeViewProvider/TreeViewProvider.types.ts b/packages/x-tree-view/src/internals/TreeViewProvider/TreeViewProvider.types.ts index 94efc6a2d9d69..0ef0c989b4ba4 100644 --- a/packages/x-tree-view/src/internals/TreeViewProvider/TreeViewProvider.types.ts +++ b/packages/x-tree-view/src/internals/TreeViewProvider/TreeViewProvider.types.ts @@ -1,24 +1,17 @@ import * as React from 'react'; import { + MergePluginsProperty, TreeViewAnyPluginSignature, TreeViewInstance, TreeViewItemPluginOptions, TreeViewItemPluginResponse, } from '../models'; -export interface TreeViewContextValue { - instance: TreeViewInstance; - runItemPlugins: (options: TreeViewItemPluginOptions) => Required; - multiSelect: boolean; - checkboxSelection: boolean; - disabledItemsFocusable: boolean; - icons: { - defaultCollapseIcon: React.ReactNode; - defaultExpandIcon: React.ReactNode; - defaultParentIcon: React.ReactNode; - defaultEndIcon: React.ReactNode; +export type TreeViewContextValue = + MergePluginsProperty & { + instance: TreeViewInstance; + runItemPlugins: (options: TreeViewItemPluginOptions) => Required; }; -} export interface TreeViewProviderProps { value: TreeViewContextValue; diff --git a/packages/x-tree-view/src/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.ts b/packages/x-tree-view/src/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.ts index 495e26e0c0edb..dc7ac193be879 100644 --- a/packages/x-tree-view/src/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.ts +++ b/packages/x-tree-view/src/internals/corePlugins/useTreeViewInstanceEvents/useTreeViewInstanceEvents.types.ts @@ -25,6 +25,7 @@ export type UseTreeViewInstanceEventsSignature = TreeViewPluginSignature< UseTreeViewInstanceEventsInstance, {}, {}, + {}, never, [] >; diff --git a/packages/x-tree-view/src/internals/models/helpers.ts b/packages/x-tree-view/src/internals/models/helpers.ts index d04446baf3a03..115a91d9d21d5 100644 --- a/packages/x-tree-view/src/internals/models/helpers.ts +++ b/packages/x-tree-view/src/internals/models/helpers.ts @@ -1,4 +1,4 @@ -import { TreeViewAnyPluginSignature, TreeViewPlugin } from './plugin'; +import type { TreeViewAnyPluginSignature, TreeViewPlugin } from './plugin'; export type DefaultizedProps< P extends {}, @@ -8,6 +8,10 @@ export type DefaultizedProps< Required> & AdditionalProps; +export type OptionalIfEmpty = keyof B extends never + ? Partial> + : Record; + export type MergePluginsProperty< TPlugins extends readonly any[], TProperty extends keyof TreeViewAnyPluginSignature, @@ -30,6 +34,7 @@ export interface MergePlugins { params: MergePluginsProperty; defaultizedParams: MergePluginsProperty; dependantPlugins: MergePluginsProperty; + contextValue: MergePluginsProperty; events: MergePluginsProperty; models: MergePluginsProperty; } diff --git a/packages/x-tree-view/src/internals/models/plugin.ts b/packages/x-tree-view/src/internals/models/plugin.ts index 366035c79b5f5..ae794f7455e2b 100644 --- a/packages/x-tree-view/src/internals/models/plugin.ts +++ b/packages/x-tree-view/src/internals/models/plugin.ts @@ -1,8 +1,7 @@ import * as React from 'react'; import { EventHandlers } from '@mui/base/utils'; import { TreeViewModel } from './treeView'; -import type { TreeViewContextValue } from '../TreeViewProvider'; -import type { MergePluginsProperty } from './helpers'; +import type { MergePluginsProperty, OptionalIfEmpty } from './helpers'; import { TreeViewEventLookupElement } from './events'; import type { TreeViewCorePluginsSignature } from '../corePlugins'; import type { TreeItemProps } from '../../TreeItem'; @@ -23,12 +22,11 @@ type TreeViewModelsInitializer = }; }; -interface TreeViewResponse { +type TreeViewResponse = { getRootProps?: ( otherHandlers: TOther, ) => React.HTMLAttributes; - contextValue?: TreeViewContextValue; -} +} & OptionalIfEmpty<'contextValue', TSignature['contextValue']>; export type TreeViewPluginSignature< TParams extends {}, @@ -36,6 +34,7 @@ export type TreeViewPluginSignature< TInstance extends {}, TEvents extends { [key in keyof TEvents]: TreeViewEventLookupElement }, TState extends {}, + TContextValue extends {}, TModelNames extends keyof TDefaultizedParams, TDependantPlugins extends readonly TreeViewAnyPluginSignature[], > = { @@ -49,6 +48,7 @@ export type TreeViewPluginSignature< >; }; events: TEvents; + contextValue: TContextValue; dependantPlugins: TDependantPlugins; }; @@ -59,6 +59,7 @@ export type TreeViewAnyPluginSignature = { defaultizedParams: any; dependantPlugins: any; events: any; + contextValue: {}; models: any; }; @@ -119,7 +120,7 @@ export type TreeViewItemPlugin = ( ) => void | TreeViewItemPluginResponse; export type TreeViewPlugin = { - (options: TreeViewPluginOptions): void | TreeViewResponse; + (options: TreeViewPluginOptions): void | TreeViewResponse; getDefaultizedParams?: ( params: TreeViewUsedParams, ) => TSignature['defaultizedParams']; diff --git a/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts b/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts index 5b0637f019466..c050ccad4d01f 100644 --- a/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts +++ b/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts @@ -4,10 +4,7 @@ import { useTreeViewExpansion, UseTreeViewExpansionParameters } from './useTreeV import { useTreeViewSelection, UseTreeViewSelectionParameters } from './useTreeViewSelection'; import { useTreeViewFocus, UseTreeViewFocusParameters } from './useTreeViewFocus'; import { useTreeViewKeyboardNavigation } from './useTreeViewKeyboardNavigation'; -import { - useTreeViewContextValueBuilder, - UseTreeViewContextValueBuilderParameters, -} from './useTreeViewContextValueBuilder'; +import { useTreeViewIcons, UseTreeViewIconsParameters } from './useTreeViewIcons'; import { ConvertPluginsIntoSignatures } from '../models'; export const DEFAULT_TREE_VIEW_PLUGINS = [ @@ -17,7 +14,7 @@ export const DEFAULT_TREE_VIEW_PLUGINS = [ useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, - useTreeViewContextValueBuilder, + useTreeViewIcons, ] as const; export type DefaultTreeViewPlugins = ConvertPluginsIntoSignatures; @@ -29,4 +26,4 @@ export interface DefaultTreeViewPluginParameters, - UseTreeViewContextValueBuilderParameters {} + UseTreeViewIconsParameters {} diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/index.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/index.ts deleted file mode 100644 index 30bfda12c2ad2..0000000000000 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { useTreeViewContextValueBuilder } from './useTreeViewContextValueBuilder'; -export type { - UseTreeViewContextValueBuilderSignature, - UseTreeViewContextValueBuilderParameters, - UseTreeViewContextValueBuilderDefaultizedParameters, -} from './useTreeViewContextValueBuilder.types'; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.ts deleted file mode 100644 index 77af6651093af..0000000000000 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TreeViewInstance, TreeViewPlugin } from '../../models'; -import { UseTreeViewContextValueBuilderSignature } from './useTreeViewContextValueBuilder.types'; - -export const useTreeViewContextValueBuilder: TreeViewPlugin< - UseTreeViewContextValueBuilderSignature -> = ({ instance, params }) => { - return { - contextValue: { - instance: instance as TreeViewInstance, - multiSelect: params.multiSelect, - checkboxSelection: params.checkboxSelection, - runItemPlugins: ({ props, ref }) => ({ props, ref, wrapItem: (children) => children }), - disabledItemsFocusable: params.disabledItemsFocusable, - icons: { - defaultCollapseIcon: params.defaultCollapseIcon, - defaultEndIcon: params.defaultEndIcon, - defaultExpandIcon: params.defaultExpandIcon, - defaultParentIcon: params.defaultParentIcon, - }, - }, - }; -}; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts index 06757c9538203..b9784f6903192 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.ts @@ -51,6 +51,7 @@ export type UseTreeViewExpansionSignature = TreeViewPluginSignature< UseTreeViewExpansionInstance, {}, {}, + {}, 'expandedNodes', [UseTreeViewNodesSignature] >; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts index 8211cf5735a12..cf5a54693a999 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.ts @@ -107,8 +107,3 @@ export const useTreeViewFocus: TreeViewPlugin = ({ }; useTreeViewFocus.getInitialState = () => ({ focusedNodeId: null }); - -useTreeViewFocus.getDefaultizedParams = (params) => ({ - ...params, - disabledItemsFocusable: params.disabledItemsFocusable ?? false, -}); diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts index 81605d985aca7..33a0151a603b2 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.ts @@ -33,6 +33,7 @@ export type UseTreeViewFocusSignature = TreeViewPluginSignature< UseTreeViewFocusInstance, {}, UseTreeViewFocusState, + {}, never, [ UseTreeViewIdSignature, diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/index.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/index.ts new file mode 100644 index 0000000000000..83596f56cfb78 --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/index.ts @@ -0,0 +1,6 @@ +export { useTreeViewIcons } from './useTreeViewIcons'; +export type { + UseTreeViewIconsSignature, + UseTreeViewIconsParameters, + UseTreeViewIconsDefaultizedParameters, +} from './useTreeViewIcons.types'; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.ts new file mode 100644 index 0000000000000..7255872c97022 --- /dev/null +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.ts @@ -0,0 +1,15 @@ +import { TreeViewPlugin } from '../../models'; +import { UseTreeViewIconsSignature } from './useTreeViewIcons.types'; + +export const useTreeViewIcons: TreeViewPlugin = ({ params }) => { + return { + contextValue: { + icons: { + defaultCollapseIcon: params.defaultCollapseIcon, + defaultEndIcon: params.defaultEndIcon, + defaultExpandIcon: params.defaultExpandIcon, + defaultParentIcon: params.defaultParentIcon, + }, + }, + }; +}; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts similarity index 63% rename from packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.ts rename to packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts index 03d9fc3d529a2..2ad068c7ababf 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewContextValueBuilder/useTreeViewContextValueBuilder.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.ts @@ -3,7 +3,7 @@ import { TreeViewPluginSignature } from '../../models'; import { UseTreeViewNodesSignature } from '../useTreeViewNodes'; import { UseTreeViewSelectionSignature } from '../useTreeViewSelection'; -export interface UseTreeViewContextValueBuilderParameters { +export interface UseTreeViewIconsParameters { /** * The default icon used to collapse the node. */ @@ -24,15 +24,24 @@ export interface UseTreeViewContextValueBuilderParameters { defaultParentIcon?: React.ReactNode; } -export type UseTreeViewContextValueBuilderDefaultizedParameters = - UseTreeViewContextValueBuilderParameters; +export type UseTreeViewIconsDefaultizedParameters = UseTreeViewIconsParameters; -export type UseTreeViewContextValueBuilderSignature = TreeViewPluginSignature< - UseTreeViewContextValueBuilderParameters, - UseTreeViewContextValueBuilderDefaultizedParameters, +interface UseTreeViewIconsContextValue { + icons: { + defaultCollapseIcon: React.ReactNode; + defaultExpandIcon: React.ReactNode; + defaultParentIcon: React.ReactNode; + defaultEndIcon: React.ReactNode; + }; +} + +export type UseTreeViewIconsSignature = TreeViewPluginSignature< + UseTreeViewIconsParameters, + UseTreeViewIconsDefaultizedParameters, {}, {}, {}, + UseTreeViewIconsContextValue, never, [UseTreeViewNodesSignature, UseTreeViewSelectionSignature] >; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts index e88c154e54598..c8e1689847648 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewId/useTreeViewId.types.ts @@ -14,16 +14,13 @@ export interface UseTreeViewIdParameters { export type UseTreeViewIdDefaultizedParameters = UseTreeViewIdParameters; -export interface UseTreeViewIdState { - focusedNodeId: string | null; -} - export type UseTreeViewIdSignature = TreeViewPluginSignature< UseTreeViewIdParameters, UseTreeViewIdDefaultizedParameters, UseTreeViewIdInstance, {}, - UseTreeViewIdState, + {}, + {}, never, [] >; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts index 5215094002fe5..98b7807618ff3 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.ts @@ -18,6 +18,7 @@ export type UseTreeViewJSXNodesSignature = TreeViewPluginSignature< UseTreeViewNodesInstance, {}, {}, + {}, never, [UseTreeViewNodesSignature, UseTreeViewKeyboardNavigationSignature] >; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts index fd52915b3f52b..4bd6abe40d1bb 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.ts @@ -14,6 +14,7 @@ export type UseTreeViewKeyboardNavigationSignature = TreeViewPluginSignature< UseTreeViewKeyboardNavigationInstance, {}, {}, + {}, never, [ UseTreeViewNodesSignature, diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts index bdc8bab5e1f86..1a2afdee3df29 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.ts @@ -179,6 +179,10 @@ export const useTreeViewNodes: TreeViewPlugin = ({ getNavigableChildrenIds, isNodeDisabled, }); + + return { + contextValue: { disabledItemsFocusable: params.disabledItemsFocusable }, + }; }; useTreeViewNodes.getInitialState = (params) => @@ -188,3 +192,8 @@ useTreeViewNodes.getInitialState = (params) => getItemId: params.getItemId, getItemLabel: params.getItemLabel, }); + +useTreeViewNodes.getDefaultizedParams = (params) => ({ + ...params, + disabledItemsFocusable: params.disabledItemsFocusable ?? false, +}); diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts index f5578ebac6446..43792f3b33f56 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewNodes/useTreeViewNodes.types.ts @@ -71,12 +71,16 @@ export interface UseTreeViewNodesState { nodeMap: TreeViewNodeMap; } +interface UseTreeViewNodesContextValue + extends Pick, 'disabledItemsFocusable'> {} + export type UseTreeViewNodesSignature = TreeViewPluginSignature< UseTreeViewNodesParameters, UseTreeViewNodesDefaultizedParameters, UseTreeViewNodesInstance, UseTreeViewNodesEventLookup, UseTreeViewNodesState, + UseTreeViewNodesContextValue, never, [] >; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts index 048b822122984..278a33d608149 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts @@ -201,6 +201,13 @@ export const useTreeViewSelection: TreeViewPlugin getRootProps: () => ({ 'aria-multiselectable': params.multiSelect, }), + contextValue: { + selection: { + multiSelect: params.multiSelect, + checkboxSelection: params.checkboxSelection, + disableSelection: params.disableSelection, + }, + }, }; }; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts index a25804fb8b8f2..c3d6f4d996b44 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.ts @@ -70,12 +70,20 @@ export type UseTreeViewSelectionDefaultizedParameters 'disableSelection' | 'defaultSelectedNodes' | 'multiSelect' | 'checkboxSelection' >; +interface UseTreeViewSelectionContextValue { + selection: Pick< + UseTreeViewSelectionDefaultizedParameters, + 'multiSelect' | 'checkboxSelection' | 'disableSelection' + >; +} + export type UseTreeViewSelectionSignature = TreeViewPluginSignature< UseTreeViewSelectionParameters, UseTreeViewSelectionDefaultizedParameters, UseTreeViewSelectionInstance, {}, {}, + UseTreeViewSelectionContextValue, 'selectedNodes', [UseTreeViewNodesSignature, UseTreeViewExpansionSignature, UseTreeViewNodesSignature] >; diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts index cf181b64919f4..2cfd721942411 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts @@ -60,9 +60,9 @@ export const useTreeView = ( otherHandlers: TOther, ) => React.HTMLAttributes)[] = []; - let contextValue = {} as TreeViewContextValue; + const contextValue = {} as TreeViewContextValue; - const runPlugin = (plugin: TreeViewPlugin) => { + const runPlugin = (plugin: TreeViewPlugin) => { const pluginResponse = plugin({ instance, params, state, setState, rootRef: innerRootRef, models }) || {}; @@ -71,12 +71,17 @@ export const useTreeView = , + runItemPlugins: ({ props, ref }) => ({ props, ref, wrapItem: (children) => children }), + }); + contextValue.runItemPlugins = ({ props, ref }) => { let finalProps = props; let finalRef = ref; @@ -130,5 +135,10 @@ export const useTreeView =