diff --git a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js index 59a5bffe36ab..d7a4285c49c2 100644 --- a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js +++ b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js @@ -1,18 +1,14 @@ import * as React from 'react'; -import { useThemeProps } from '@mui/material/styles'; -import { useSlotProps } from '@mui/base/utils'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; -import { RichTreeViewRoot } from '@mui/x-tree-view/RichTreeView'; -import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { - DEFAULT_TREE_VIEW_PLUGINS, - extractPluginParamsFromProps, - useTreeView, - TreeViewProvider, -} from '@mui/x-tree-view/internals'; + RichTreeViewRoot, + RICH_TREE_VIEW_PLUGINS, +} from '@mui/x-tree-view/RichTreeView'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; +import { useTreeView, TreeViewProvider } from '@mui/x-tree-view/internals'; const useTreeViewLogExpanded = ({ params, models }) => { const expandedStr = JSON.stringify(models.expandedItems.value); @@ -37,25 +33,12 @@ useTreeViewLogExpanded.params = { logMessage: true, }; -const TREE_VIEW_PLUGINS = [...DEFAULT_TREE_VIEW_PLUGINS, useTreeViewLogExpanded]; - -function TreeView(inProps) { - const themeProps = useThemeProps({ props: inProps, name: 'HeadlessTreeView' }); - const ownerState = themeProps; +const TREE_VIEW_PLUGINS = [...RICH_TREE_VIEW_PLUGINS, useTreeViewLogExpanded]; - const { pluginParams, otherProps } = extractPluginParamsFromProps({ - props: themeProps, +function TreeView(props) { + const { getRootProps, contextValue, instance } = useTreeView({ plugins: TREE_VIEW_PLUGINS, - }); - - const { getRootProps, contextValue, instance } = useTreeView(pluginParams); - - const rootProps = useSlotProps({ - elementType: RichTreeViewRoot, - externalSlotProps: {}, - externalForwardedProps: otherProps, - getSlotProps: getRootProps, - ownerState, + props, }); const itemsToRender = instance.getItemsToRender(); @@ -70,7 +53,7 @@ function TreeView(inProps) { return ( - + {itemsToRender.map(renderItem)} diff --git a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx index c1a70f335c0e..7a45a2b3e0cd 100644 --- a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx +++ b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx @@ -1,6 +1,4 @@ import * as React from 'react'; -import { useThemeProps } from '@mui/material/styles'; -import { useSlotProps } from '@mui/base/utils'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; @@ -8,17 +6,16 @@ import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { RichTreeViewPropsBase, RichTreeViewRoot, + RICH_TREE_VIEW_PLUGINS, + RichTreeViewPluginParameters, + RichTreeViewPluginSlots, + RichTreeViewPluginSlotProps, } from '@mui/x-tree-view/RichTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { UseTreeViewExpansionSignature, TreeViewPlugin, TreeViewPluginSignature, - DefaultTreeViewPluginParameters, - DefaultTreeViewPluginSlotProps, - DefaultTreeViewPluginSlots, - DEFAULT_TREE_VIEW_PLUGINS, - extractPluginParamsFromProps, useTreeView, TreeViewProvider, ConvertPluginsIntoSignatures, @@ -70,42 +67,31 @@ useTreeViewLogExpanded.params = { }; export interface TreeViewProps - extends DefaultTreeViewPluginParameters, + extends RichTreeViewPluginParameters, TreeViewLogExpandedParameters, RichTreeViewPropsBase { - slots?: DefaultTreeViewPluginSlots; - slotProps?: DefaultTreeViewPluginSlotProps; + slots?: RichTreeViewPluginSlots; + slotProps?: RichTreeViewPluginSlotProps; } const TREE_VIEW_PLUGINS = [ - ...DEFAULT_TREE_VIEW_PLUGINS, + ...RICH_TREE_VIEW_PLUGINS, useTreeViewLogExpanded, ] as const; +type TreeViewPluginSignatures = ConvertPluginsIntoSignatures< + typeof TREE_VIEW_PLUGINS +>; + function TreeView( - inProps: TreeViewProps, + props: TreeViewProps, ) { - const themeProps = useThemeProps({ props: inProps, name: 'HeadlessTreeView' }); - const ownerState = themeProps as TreeViewProps; - - const { pluginParams, otherProps } = extractPluginParamsFromProps< - ConvertPluginsIntoSignatures, - DefaultTreeViewPluginSlots, - DefaultTreeViewPluginSlotProps, - TreeViewProps + const { getRootProps, contextValue, instance } = useTreeView< + TreeViewPluginSignatures, + typeof props >({ - props: themeProps, plugins: TREE_VIEW_PLUGINS, - }); - - const { getRootProps, contextValue, instance } = useTreeView(pluginParams); - - const rootProps = useSlotProps({ - elementType: RichTreeViewRoot, - externalSlotProps: {}, - externalForwardedProps: otherProps, - getSlotProps: getRootProps, - ownerState, + props, }); const itemsToRender = instance.getItemsToRender(); @@ -123,7 +109,7 @@ function TreeView( return ( - + {itemsToRender.map(renderItem)} diff --git a/packages/x-tree-view-pro/src/internals/plugins/defaultPlugins.ts b/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.plugins.ts similarity index 63% rename from packages/x-tree-view-pro/src/internals/plugins/defaultPlugins.ts rename to packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.plugins.ts index d720b6087266..cbd7f1ea9741 100644 --- a/packages/x-tree-view-pro/src/internals/plugins/defaultPlugins.ts +++ b/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.plugins.ts @@ -16,7 +16,7 @@ import { MergeSignaturesProperty, } from '@mui/x-tree-view/internals'; -export const DEFAULT_TREE_VIEW_PRO_PLUGINS = [ +export const RICH_TREE_VIEW_PRO_PLUGINS = [ useTreeViewId, useTreeViewItems, useTreeViewExpansion, @@ -26,25 +26,23 @@ export const DEFAULT_TREE_VIEW_PRO_PLUGINS = [ useTreeViewIcons, ] as const; -export type DefaultTreeViewProPluginSignatures = ConvertPluginsIntoSignatures< - typeof DEFAULT_TREE_VIEW_PRO_PLUGINS +export type RichTreeViewProPluginSignatures = ConvertPluginsIntoSignatures< + typeof RICH_TREE_VIEW_PRO_PLUGINS >; -export type DefaultTreeViewProPluginSlots = MergeSignaturesProperty< - DefaultTreeViewProPluginSignatures, +export type RichTreeViewProPluginSlots = MergeSignaturesProperty< + RichTreeViewProPluginSignatures, 'slots' >; -export type DefaultTreeViewProPluginSlotProps = MergeSignaturesProperty< - DefaultTreeViewProPluginSignatures, +export type RichTreeViewProPluginSlotProps = MergeSignaturesProperty< + RichTreeViewProPluginSignatures, 'slotProps' >; // We can't infer this type from the plugin, otherwise we would lose the generics. -export interface DefaultTreeViewProPluginParameters< - R extends {}, - Multiple extends boolean | undefined, -> extends UseTreeViewIdParameters, +export interface RichTreeViewProPluginParameters + extends UseTreeViewIdParameters, UseTreeViewItemsParameters, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, diff --git a/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.tsx b/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.tsx index 4294bc362a34..3eee6b03f115 100644 --- a/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.tsx +++ b/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.tsx @@ -3,23 +3,14 @@ import composeClasses from '@mui/utils/composeClasses'; import { useLicenseVerifier, Watermark } from '@mui/x-license'; import { useSlotProps } from '@mui/base/utils'; import { TreeItem, TreeItemProps } from '@mui/x-tree-view/TreeItem'; -import { - useTreeView, - TreeViewProvider, - buildWarning, - extractPluginParamsFromProps, -} from '@mui/x-tree-view/internals'; +import { useTreeView, TreeViewProvider, buildWarning } from '@mui/x-tree-view/internals'; import { styled, createUseThemeProps } from '../internals/zero-styled'; import { getRichTreeViewProUtilityClass } from './richTreeViewProClasses'; +import { RichTreeViewProProps } from './RichTreeViewPro.types'; import { - RichTreeViewProProps, - RichTreeViewProSlotProps, - RichTreeViewProSlots, -} from './RichTreeViewPro.types'; -import { - DEFAULT_TREE_VIEW_PRO_PLUGINS, - DefaultTreeViewProPluginSignatures, -} from '../internals/plugins'; + RICH_TREE_VIEW_PRO_PLUGINS, + RichTreeViewProPluginSignatures, +} from './RichTreeViewPro.plugins'; import { getReleaseInfo } from '../internals/utils/releaseInfo'; const useThemeProps = createUseThemeProps('MuiRichTreeViewPro'); @@ -104,26 +95,22 @@ const RichTreeViewPro = React.forwardRef(function RichTreeViewPro< } } - const { pluginParams, slots, slotProps, otherProps } = extractPluginParamsFromProps< - DefaultTreeViewProPluginSignatures, - RichTreeViewProSlots, - RichTreeViewProSlotProps, - RichTreeViewProProps + const { getRootProps, contextValue, instance } = useTreeView< + RichTreeViewProPluginSignatures, + typeof props >({ - props, - plugins: DEFAULT_TREE_VIEW_PRO_PLUGINS, + plugins: RICH_TREE_VIEW_PRO_PLUGINS, rootRef: ref, + props, }); - const { getRootProps, contextValue, instance } = useTreeView(pluginParams); - + const { slots, slotProps } = props; const classes = useUtilityClasses(props); const Root = slots?.root ?? RichTreeViewProRoot; const rootProps = useSlotProps({ elementType: Root, externalSlotProps: slotProps?.root, - externalForwardedProps: otherProps, className: classes.root, getSlotProps: getRootProps, ownerState: props as RichTreeViewProProps, diff --git a/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.types.ts b/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.types.ts index c0df5ad46263..2f882e8dc922 100644 --- a/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.types.ts +++ b/packages/x-tree-view-pro/src/RichTreeViewPro/RichTreeViewPro.types.ts @@ -8,18 +8,18 @@ import { TreeViewItemId } from '@mui/x-tree-view/models'; import { TreeViewPublicAPI, TreeViewExperimentalFeatures } from '@mui/x-tree-view/internals'; import { RichTreeViewProClasses } from './richTreeViewProClasses'; import { - DefaultTreeViewProPluginParameters, - DefaultTreeViewProPluginSlotProps, - DefaultTreeViewProPluginSlots, - DefaultTreeViewProPluginSignatures, -} from '../internals/plugins/defaultPlugins'; + RichTreeViewProPluginParameters, + RichTreeViewProPluginSlotProps, + RichTreeViewProPluginSlots, + RichTreeViewProPluginSignatures, +} from './RichTreeViewPro.plugins'; interface RichTreeViewItemProSlotOwnerState { itemId: TreeViewItemId; label: string; } -export interface RichTreeViewProSlots extends DefaultTreeViewProPluginSlots { +export interface RichTreeViewProSlots extends RichTreeViewProPluginSlots { /** * Element rendered at the root. * @default RichTreeViewProRoot @@ -33,13 +33,13 @@ export interface RichTreeViewProSlots extends DefaultTreeViewProPluginSlots { } export interface RichTreeViewProSlotProps - extends DefaultTreeViewProPluginSlotProps { + extends RichTreeViewProPluginSlotProps { root?: SlotComponentProps<'ul', {}, RichTreeViewProProps>; item?: SlotComponentProps; } export type RichTreeViewProApiRef = React.MutableRefObject< - TreeViewPublicAPI | undefined + TreeViewPublicAPI | undefined >; export interface RichTreeViewProPropsBase extends React.HTMLAttributes { @@ -55,7 +55,7 @@ export interface RichTreeViewProPropsBase extends React.HTMLAttributes - extends DefaultTreeViewProPluginParameters, + extends RichTreeViewProPluginParameters, RichTreeViewProPropsBase { /** * Overridable component slots. @@ -76,5 +76,5 @@ export interface RichTreeViewProProps; + experimentalFeatures?: TreeViewExperimentalFeatures; } diff --git a/packages/x-tree-view-pro/src/internals/plugins/index.ts b/packages/x-tree-view-pro/src/internals/plugins/index.ts deleted file mode 100644 index 96523fc22814..000000000000 --- a/packages/x-tree-view-pro/src/internals/plugins/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { DEFAULT_TREE_VIEW_PRO_PLUGINS } from './defaultPlugins'; -export type { DefaultTreeViewProPluginSignatures } from './defaultPlugins'; diff --git a/packages/x-tree-view/src/RichTreeView/RichTreeView.plugins.ts b/packages/x-tree-view/src/RichTreeView/RichTreeView.plugins.ts new file mode 100644 index 000000000000..4c42b098f2e0 --- /dev/null +++ b/packages/x-tree-view/src/RichTreeView/RichTreeView.plugins.ts @@ -0,0 +1,56 @@ +import { useTreeViewId, UseTreeViewIdParameters } from '../internals/plugins/useTreeViewId'; +import { + useTreeViewItems, + UseTreeViewItemsParameters, +} from '../internals/plugins/useTreeViewItems'; +import { + useTreeViewExpansion, + UseTreeViewExpansionParameters, +} from '../internals/plugins/useTreeViewExpansion'; +import { + useTreeViewSelection, + UseTreeViewSelectionParameters, +} from '../internals/plugins/useTreeViewSelection'; +import { + useTreeViewFocus, + UseTreeViewFocusParameters, +} from '../internals/plugins/useTreeViewFocus'; +import { useTreeViewKeyboardNavigation } from '../internals/plugins/useTreeViewKeyboardNavigation'; +import { + useTreeViewIcons, + UseTreeViewIconsParameters, +} from '../internals/plugins/useTreeViewIcons'; +import { ConvertPluginsIntoSignatures, MergeSignaturesProperty } from '../internals/models'; + +export const RICH_TREE_VIEW_PLUGINS = [ + useTreeViewId, + useTreeViewItems, + useTreeViewExpansion, + useTreeViewSelection, + useTreeViewFocus, + useTreeViewKeyboardNavigation, + useTreeViewIcons, +] as const; + +export type RichTreeViewPluginSignatures = ConvertPluginsIntoSignatures< + typeof RICH_TREE_VIEW_PLUGINS +>; + +export type RichTreeViewPluginSlots = MergeSignaturesProperty< + RichTreeViewPluginSignatures, + 'slots' +>; + +export type RichTreeViewPluginSlotProps = MergeSignaturesProperty< + RichTreeViewPluginSignatures, + 'slotProps' +>; + +// We can't infer this type from the plugin, otherwise we would lose the generics. +export interface RichTreeViewPluginParameters + extends UseTreeViewIdParameters, + UseTreeViewItemsParameters, + UseTreeViewExpansionParameters, + UseTreeViewFocusParameters, + UseTreeViewSelectionParameters, + UseTreeViewIconsParameters {} diff --git a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx index 53f7f2257588..5f94c0db2be7 100644 --- a/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx +++ b/packages/x-tree-view/src/RichTreeView/RichTreeView.tsx @@ -3,14 +3,13 @@ import PropTypes from 'prop-types'; import composeClasses from '@mui/utils/composeClasses'; import { useSlotProps } from '@mui/base/utils'; import { getRichTreeViewUtilityClass } from './richTreeViewClasses'; -import { RichTreeViewProps, RichTreeViewSlotProps, RichTreeViewSlots } from './RichTreeView.types'; +import { RichTreeViewProps } from './RichTreeView.types'; import { styled, createUseThemeProps } from '../internals/zero-styled'; import { useTreeView } from '../internals/useTreeView'; import { TreeViewProvider } from '../internals/TreeViewProvider'; -import { DEFAULT_TREE_VIEW_PLUGINS, DefaultTreeViewPluginSignatures } from '../internals/plugins'; +import { RICH_TREE_VIEW_PLUGINS, RichTreeViewPluginSignatures } from './RichTreeView.plugins'; import { TreeItem, TreeItemProps } from '../TreeItem'; import { buildWarning } from '../internals/utils/warning'; -import { extractPluginParamsFromProps } from '../internals/utils/extractPluginParamsFromProps'; const useThemeProps = createUseThemeProps('MuiRichTreeView'); @@ -30,7 +29,7 @@ export const RichTreeViewRoot = styled('ul', { name: 'MuiRichTreeView', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: RichTreeViewProps }>({ +})({ padding: 0, margin: 0, listStyle: 'none', @@ -90,26 +89,22 @@ const RichTreeView = React.forwardRef(function RichTreeView< } } - const { pluginParams, slots, slotProps, otherProps } = extractPluginParamsFromProps< - DefaultTreeViewPluginSignatures, - RichTreeViewSlots, - RichTreeViewSlotProps, - RichTreeViewProps + const { getRootProps, contextValue, instance } = useTreeView< + RichTreeViewPluginSignatures, + typeof props >({ - props, - plugins: DEFAULT_TREE_VIEW_PLUGINS, + plugins: RICH_TREE_VIEW_PLUGINS, rootRef: ref, + props, }); - const { getRootProps, contextValue, instance } = useTreeView(pluginParams); - + const { slots, slotProps } = props; const classes = useUtilityClasses(props); const Root = slots?.root ?? RichTreeViewRoot; const rootProps = useSlotProps({ elementType: Root, externalSlotProps: slotProps?.root, - externalForwardedProps: otherProps, className: classes.root, getSlotProps: getRootProps, ownerState: props as RichTreeViewProps, diff --git a/packages/x-tree-view/src/RichTreeView/RichTreeView.types.ts b/packages/x-tree-view/src/RichTreeView/RichTreeView.types.ts index 9b71ae3c7a57..a1102b3f64e0 100644 --- a/packages/x-tree-view/src/RichTreeView/RichTreeView.types.ts +++ b/packages/x-tree-view/src/RichTreeView/RichTreeView.types.ts @@ -4,11 +4,11 @@ import { SxProps } from '@mui/system'; import { SlotComponentProps } from '@mui/base/utils'; import { RichTreeViewClasses } from './richTreeViewClasses'; import { - DefaultTreeViewPluginParameters, - DefaultTreeViewPluginSlotProps, - DefaultTreeViewPluginSlots, - DefaultTreeViewPluginSignatures, -} from '../internals/plugins/defaultPlugins'; + RichTreeViewPluginParameters, + RichTreeViewPluginSlotProps, + RichTreeViewPluginSlots, + RichTreeViewPluginSignatures, +} from './RichTreeView.plugins'; import { TreeItemProps } from '../TreeItem'; import { TreeItem2Props } from '../TreeItem2'; import { TreeViewItemId } from '../models'; @@ -23,7 +23,7 @@ interface RichTreeViewItemSlotOwnerState { label: string; } -export interface RichTreeViewSlots extends DefaultTreeViewPluginSlots { +export interface RichTreeViewSlots extends RichTreeViewPluginSlots { /** * Element rendered at the root. * @default RichTreeViewRoot @@ -37,7 +37,7 @@ export interface RichTreeViewSlots extends DefaultTreeViewPluginSlots { } export interface RichTreeViewSlotProps - extends DefaultTreeViewPluginSlotProps { + extends RichTreeViewPluginSlotProps { root?: SlotComponentProps<'ul', {}, RichTreeViewProps>; item?: SlotComponentPropsFromProps< TreeItemProps | TreeItem2Props, @@ -47,7 +47,7 @@ export interface RichTreeViewSlotProps | undefined + TreeViewPublicAPI | undefined >; export interface RichTreeViewPropsBase extends React.HTMLAttributes { @@ -63,7 +63,7 @@ export interface RichTreeViewPropsBase extends React.HTMLAttributes - extends DefaultTreeViewPluginParameters, + extends RichTreeViewPluginParameters, RichTreeViewPropsBase { /** * Overridable component slots. @@ -84,5 +84,5 @@ export interface RichTreeViewProps; + experimentalFeatures?: TreeViewExperimentalFeatures; } diff --git a/packages/x-tree-view/src/RichTreeView/index.ts b/packages/x-tree-view/src/RichTreeView/index.ts index 5707c81a04ed..a451bc2e1018 100644 --- a/packages/x-tree-view/src/RichTreeView/index.ts +++ b/packages/x-tree-view/src/RichTreeView/index.ts @@ -6,3 +6,10 @@ export type { RichTreeViewSlots, RichTreeViewSlotProps, } from './RichTreeView.types'; + +export { RICH_TREE_VIEW_PLUGINS } from './RichTreeView.plugins'; +export type { + RichTreeViewPluginSlots, + RichTreeViewPluginSlotProps, + RichTreeViewPluginParameters, +} from './RichTreeView.plugins'; diff --git a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts index f380f55d4cda..d943982322c2 100644 --- a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts +++ b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.plugins.ts @@ -1,14 +1,36 @@ +import { useTreeViewId, UseTreeViewIdParameters } from '../internals/plugins/useTreeViewId'; import { - DEFAULT_TREE_VIEW_PLUGINS, - DefaultTreeViewPluginParameters, - DefaultTreeViewPluginSlotProps, - DefaultTreeViewPluginSlots, -} from '../internals/plugins/defaultPlugins'; + useTreeViewItems, + UseTreeViewItemsParameters, +} from '../internals/plugins/useTreeViewItems'; +import { + useTreeViewExpansion, + UseTreeViewExpansionParameters, +} from '../internals/plugins/useTreeViewExpansion'; +import { + useTreeViewSelection, + UseTreeViewSelectionParameters, +} from '../internals/plugins/useTreeViewSelection'; +import { + useTreeViewFocus, + UseTreeViewFocusParameters, +} from '../internals/plugins/useTreeViewFocus'; +import { useTreeViewKeyboardNavigation } from '../internals/plugins/useTreeViewKeyboardNavigation'; +import { + useTreeViewIcons, + UseTreeViewIconsParameters, +} from '../internals/plugins/useTreeViewIcons'; import { useTreeViewJSXItems } from '../internals/plugins/useTreeViewJSXItems'; -import { ConvertPluginsIntoSignatures } from '../internals/models'; +import { ConvertPluginsIntoSignatures, MergeSignaturesProperty } from '../internals/models'; export const SIMPLE_TREE_VIEW_PLUGINS = [ - ...DEFAULT_TREE_VIEW_PLUGINS, + useTreeViewId, + useTreeViewItems, + useTreeViewExpansion, + useTreeViewSelection, + useTreeViewFocus, + useTreeViewKeyboardNavigation, + useTreeViewIcons, useTreeViewJSXItems, ] as const; @@ -16,13 +38,24 @@ export type SimpleTreeViewPluginSignatures = ConvertPluginsIntoSignatures< typeof SIMPLE_TREE_VIEW_PLUGINS >; -export type SimpleTreeViewPluginSlots = DefaultTreeViewPluginSlots; +export type SimpleTreeViewPluginSlots = MergeSignaturesProperty< + SimpleTreeViewPluginSignatures, + 'slots' +>; -export type SimpleTreeViewPluginSlotProps = DefaultTreeViewPluginSlotProps; +export type SimpleTreeViewPluginSlotProps = MergeSignaturesProperty< + SimpleTreeViewPluginSignatures, + 'slotProps' +>; // We can't infer this type from the plugin, otherwise we would lose the generics. export interface SimpleTreeViewPluginParameters - extends Omit< - DefaultTreeViewPluginParameters, - 'items' | 'isItemDisabled' | 'getItemLabel' | 'getItemId' - > {} + extends UseTreeViewIdParameters, + Omit< + UseTreeViewItemsParameters, + 'items' | 'isItemDisabled' | 'getItemLabel' | 'getItemId' + >, + UseTreeViewExpansionParameters, + UseTreeViewFocusParameters, + UseTreeViewSelectionParameters, + UseTreeViewIconsParameters {} diff --git a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.tsx b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.tsx index 7a159b1eda55..472bf6208f58 100644 --- a/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.tsx +++ b/packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.tsx @@ -4,16 +4,11 @@ import composeClasses from '@mui/utils/composeClasses'; import { useSlotProps } from '@mui/base/utils'; import { styled, createUseThemeProps } from '../internals/zero-styled'; import { getSimpleTreeViewUtilityClass } from './simpleTreeViewClasses'; -import { - SimpleTreeViewProps, - SimpleTreeViewSlots, - SimpleTreeViewSlotProps, -} from './SimpleTreeView.types'; +import { SimpleTreeViewProps } from './SimpleTreeView.types'; import { useTreeView } from '../internals/useTreeView'; import { TreeViewProvider } from '../internals/TreeViewProvider'; import { SIMPLE_TREE_VIEW_PLUGINS, SimpleTreeViewPluginSignatures } from './SimpleTreeView.plugins'; import { buildWarning } from '../internals/utils/warning'; -import { extractPluginParamsFromProps } from '../internals/utils/extractPluginParamsFromProps'; const useThemeProps = createUseThemeProps('MuiSimpleTreeView'); @@ -75,26 +70,22 @@ const SimpleTreeView = React.forwardRef(function SimpleTreeView< } } - const { pluginParams, slots, slotProps, otherProps } = extractPluginParamsFromProps< + const { getRootProps, contextValue } = useTreeView< SimpleTreeViewPluginSignatures, - SimpleTreeViewSlots, - SimpleTreeViewSlotProps, - SimpleTreeViewProps & { items: any } + typeof props & { items: any[] } >({ - props: { ...props, items: EMPTY_ITEMS }, plugins: SIMPLE_TREE_VIEW_PLUGINS, rootRef: ref, + props: { ...props, items: EMPTY_ITEMS }, }); - const { getRootProps, contextValue } = useTreeView(pluginParams); - + const { slots, slotProps } = props; const classes = useUtilityClasses(props); const Root = slots?.root ?? SimpleTreeViewRoot; const rootProps = useSlotProps({ elementType: Root, externalSlotProps: slotProps?.root, - externalForwardedProps: otherProps, className: classes.root, getSlotProps: getRootProps, ownerState, diff --git a/packages/x-tree-view/src/TreeItem/TreeItem.tsx b/packages/x-tree-view/src/TreeItem/TreeItem.tsx index 7f6a19725ab9..f4224825ec58 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItem.tsx +++ b/packages/x-tree-view/src/TreeItem/TreeItem.tsx @@ -13,9 +13,8 @@ import { unstable_composeClasses as composeClasses } from '@mui/base'; import { styled, createUseThemeProps } from '../internals/zero-styled'; import { TreeItemContent } from './TreeItemContent'; import { treeItemClasses, getTreeItemUtilityClass } from './treeItemClasses'; -import { TreeItemOwnerState, TreeItemProps } from './TreeItem.types'; +import { TreeItemMinimalPlugins, TreeItemOwnerState, TreeItemProps } from './TreeItem.types'; import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext'; -import { DefaultTreeViewPluginSignatures } from '../internals/plugins'; import { TreeViewCollapseIcon, TreeViewExpandIcon } from '../icons'; import { TreeItem2Provider } from '../TreeItem2Provider'; import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext'; @@ -186,7 +185,7 @@ export const TreeItem = React.forwardRef(function TreeItem( disabledItemsFocusable, indentationAtItemLevel, instance, - } = useTreeViewContext(); + } = useTreeViewContext(); const depthContext = React.useContext(TreeViewItemDepthContext); const props = useThemeProps({ props: inProps, name: 'MuiTreeItem' }); diff --git a/packages/x-tree-view/src/TreeItem/TreeItem.types.ts b/packages/x-tree-view/src/TreeItem/TreeItem.types.ts index b9fa0319a12e..54df7cbef8da 100644 --- a/packages/x-tree-view/src/TreeItem/TreeItem.types.ts +++ b/packages/x-tree-view/src/TreeItem/TreeItem.types.ts @@ -8,6 +8,13 @@ import { TreeItemClasses } from './treeItemClasses'; import { TreeViewItemId } from '../models'; import { SlotComponentPropsFromProps } from '../internals/models'; import { MuiCancellableEventHandler } from '../internals/models/MuiCancellableEvent'; +import { UseTreeViewIconsSignature } from '../internals/plugins/useTreeViewIcons'; +import { UseTreeViewSelectionSignature } from '../internals/plugins/useTreeViewSelection'; +import { UseTreeViewItemsSignature } from '../internals/plugins/useTreeViewItems'; +import { UseTreeViewFocusSignature } from '../internals/plugins/useTreeViewFocus'; +import { UseTreeViewExpansionSignature } from '../internals/plugins/useTreeViewExpansion'; +import { UseTreeViewKeyboardNavigationSignature } from '../internals/plugins/useTreeViewKeyboardNavigation'; +import { UseTreeViewIdSignature } from '../internals/plugins/useTreeViewId'; export interface TreeItemSlots { /** @@ -105,3 +112,13 @@ export interface TreeItemOwnerState extends TreeItemProps { disabled: boolean; indentationAtItemLevel: boolean; } + +export type TreeItemMinimalPlugins = readonly [ + UseTreeViewIconsSignature, + UseTreeViewSelectionSignature, + UseTreeViewItemsSignature, + UseTreeViewFocusSignature, + UseTreeViewExpansionSignature, + UseTreeViewKeyboardNavigationSignature, + UseTreeViewIdSignature, +]; diff --git a/packages/x-tree-view/src/TreeItem/useTreeItemState.ts b/packages/x-tree-view/src/TreeItem/useTreeItemState.ts index 0da618865f95..fea40a777a0f 100644 --- a/packages/x-tree-view/src/TreeItem/useTreeItemState.ts +++ b/packages/x-tree-view/src/TreeItem/useTreeItemState.ts @@ -1,12 +1,22 @@ import * as React from 'react'; import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext'; -import { DefaultTreeViewPluginSignatures } from '../internals/plugins'; +import { UseTreeViewSelectionSignature } from '../internals/plugins/useTreeViewSelection'; +import { UseTreeViewExpansionSignature } from '../internals/plugins/useTreeViewExpansion'; +import { UseTreeViewFocusSignature } from '../internals/plugins/useTreeViewFocus'; +import { UseTreeViewItemsSignature } from '../internals/plugins/useTreeViewItems'; + +type UseTreeItemStateMinimalPlugins = readonly [ + UseTreeViewSelectionSignature, + UseTreeViewExpansionSignature, + UseTreeViewFocusSignature, + UseTreeViewItemsSignature, +]; export function useTreeItemState(itemId: string) { const { instance, selection: { multiSelect, checkboxSelection, disableSelection }, - } = useTreeViewContext(); + } = useTreeViewContext(); const expandable = instance.isItemExpandable(itemId); const expanded = instance.isItemExpanded(itemId); diff --git a/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx b/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx index deff0a1d89e5..09e188c73e75 100644 --- a/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx +++ b/packages/x-tree-view/src/hooks/useTreeItem2Utils/useTreeItem2Utils.tsx @@ -1,6 +1,9 @@ import * as React from 'react'; import { useTreeViewContext } from '../../internals/TreeViewProvider/useTreeViewContext'; -import { DefaultTreeViewPluginSignatures } from '../../internals/plugins'; +import { UseTreeViewSelectionSignature } from '../../internals/plugins/useTreeViewSelection'; +import { UseTreeViewExpansionSignature } from '../../internals/plugins/useTreeViewExpansion'; +import { UseTreeViewItemsSignature } from '../../internals/plugins/useTreeViewItems'; +import { UseTreeViewFocusSignature } from '../../internals/plugins/useTreeViewFocus'; import type { UseTreeItem2Status } from '../../useTreeItem2'; interface UseTreeItem2Interactions { @@ -21,6 +24,13 @@ const isItemExpandable = (reactChildren: React.ReactNode) => { return Boolean(reactChildren); }; +type UseTreeItem2UtilsMinimalPlugins = readonly [ + UseTreeViewSelectionSignature, + UseTreeViewExpansionSignature, + UseTreeViewItemsSignature, + UseTreeViewFocusSignature, +]; + export const useTreeItem2Utils = ({ itemId, children, @@ -31,7 +41,7 @@ export const useTreeItem2Utils = ({ const { instance, selection: { multiSelect }, - } = useTreeViewContext(); + } = useTreeViewContext(); const status: UseTreeItem2Status = { expandable: isItemExpandable(children), diff --git a/packages/x-tree-view/src/hooks/useTreeViewApiRef.tsx b/packages/x-tree-view/src/hooks/useTreeViewApiRef.tsx index b27410f75737..6a62287d93a4 100644 --- a/packages/x-tree-view/src/hooks/useTreeViewApiRef.tsx +++ b/packages/x-tree-view/src/hooks/useTreeViewApiRef.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; import { TreeViewAnyPluginSignature, TreeViewPublicAPI } from '../internals/models'; -import { DefaultTreeViewPluginSignatures } from '../internals'; +import { RichTreeViewPluginSignatures } from '../RichTreeView/RichTreeView.plugins'; /** * Hook that instantiates a [[TreeViewApiRef]]. */ export const useTreeViewApiRef = < - TSignatures extends readonly TreeViewAnyPluginSignature[] = DefaultTreeViewPluginSignatures, + TSignatures extends readonly TreeViewAnyPluginSignature[] = RichTreeViewPluginSignatures, >() => React.useRef(undefined) as React.MutableRefObject | undefined>; diff --git a/packages/x-tree-view/src/internals/index.ts b/packages/x-tree-view/src/internals/index.ts index 752818a77fa0..67e9f4307740 100644 --- a/packages/x-tree-view/src/internals/index.ts +++ b/packages/x-tree-view/src/internals/index.ts @@ -13,13 +13,6 @@ export type { } from './models'; // Plugins -export { DEFAULT_TREE_VIEW_PLUGINS } from './plugins/defaultPlugins'; -export type { - DefaultTreeViewPluginSignatures, - DefaultTreeViewPluginSlots, - DefaultTreeViewPluginSlotProps, -} from './plugins/defaultPlugins'; -export type { DefaultTreeViewPluginParameters } from './plugins/defaultPlugins'; export { useTreeViewExpansion } from './plugins/useTreeViewExpansion'; export type { UseTreeViewExpansionSignature, @@ -56,4 +49,3 @@ export type { } from './plugins/useTreeViewJSXItems'; export { buildWarning } from './utils/warning'; -export { extractPluginParamsFromProps } from './utils/extractPluginParamsFromProps'; diff --git a/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts b/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts deleted file mode 100644 index c6b376aac744..000000000000 --- a/packages/x-tree-view/src/internals/plugins/defaultPlugins.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { useTreeViewId, UseTreeViewIdParameters } from './useTreeViewId'; -import { useTreeViewItems, UseTreeViewItemsParameters } from './useTreeViewItems'; -import { useTreeViewExpansion, UseTreeViewExpansionParameters } from './useTreeViewExpansion'; -import { useTreeViewSelection, UseTreeViewSelectionParameters } from './useTreeViewSelection'; -import { useTreeViewFocus, UseTreeViewFocusParameters } from './useTreeViewFocus'; -import { useTreeViewKeyboardNavigation } from './useTreeViewKeyboardNavigation'; -import { useTreeViewIcons, UseTreeViewIconsParameters } from './useTreeViewIcons'; -import { ConvertPluginsIntoSignatures, MergeSignaturesProperty } from '../models'; - -export const DEFAULT_TREE_VIEW_PLUGINS = [ - useTreeViewId, - useTreeViewItems, - useTreeViewExpansion, - useTreeViewSelection, - useTreeViewFocus, - useTreeViewKeyboardNavigation, - useTreeViewIcons, -] as const; - -export type DefaultTreeViewPluginSignatures = ConvertPluginsIntoSignatures< - typeof DEFAULT_TREE_VIEW_PLUGINS ->; - -export type DefaultTreeViewPluginSlots = MergeSignaturesProperty< - DefaultTreeViewPluginSignatures, - 'slots' ->; - -export type DefaultTreeViewPluginSlotProps = MergeSignaturesProperty< - DefaultTreeViewPluginSignatures, - 'slotProps' ->; - -// We can't infer this type from the plugin, otherwise we would lose the generics. -export interface DefaultTreeViewPluginParameters - extends UseTreeViewIdParameters, - UseTreeViewItemsParameters, - UseTreeViewExpansionParameters, - UseTreeViewFocusParameters, - UseTreeViewSelectionParameters, - UseTreeViewIconsParameters {} diff --git a/packages/x-tree-view/src/internals/plugins/index.ts b/packages/x-tree-view/src/internals/plugins/index.ts deleted file mode 100644 index 75445ff5057c..000000000000 --- a/packages/x-tree-view/src/internals/plugins/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { DEFAULT_TREE_VIEW_PLUGINS } from './defaultPlugins'; -export type { DefaultTreeViewPluginSignatures } from './defaultPlugins'; diff --git a/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts b/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts new file mode 100644 index 000000000000..d91f18fe1b4d --- /dev/null +++ b/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts @@ -0,0 +1,76 @@ +import { + ConvertSignaturesIntoPlugins, + MergeSignaturesProperty, + TreeViewAnyPluginSignature, + TreeViewPlugin, + TreeViewPluginSignature, +} from '../models'; +import { UseTreeViewBaseProps } from './useTreeView.types'; +import { TreeViewCorePluginSignatures } from '../corePlugins'; + +interface ExtractPluginParamsFromPropsParameters< + TSignatures extends readonly TreeViewAnyPluginSignature[], + TProps extends Partial>, +> { + plugins: ConvertSignaturesIntoPlugins; + props: TProps; +} + +interface ExtractPluginParamsFromPropsReturnValue< + TSignatures extends readonly TreeViewAnyPluginSignature[], + TProps extends Partial>, +> extends UseTreeViewBaseProps { + pluginParams: MergeSignaturesProperty; + forwardedProps: Omit>; +} + +export const extractPluginParamsFromProps = < + TSignatures extends readonly TreeViewPluginSignature[], + TProps extends Partial>, +>({ + props: { slots, slotProps, apiRef, experimentalFeatures, ...props }, + plugins, +}: ExtractPluginParamsFromPropsParameters< + TSignatures, + TProps +>): ExtractPluginParamsFromPropsReturnValue => { + type PluginParams = MergeSignaturesProperty; + + const paramsLookup = {} as Record; + plugins.forEach((plugin) => { + Object.assign(paramsLookup, plugin.params); + }); + + const pluginParams = {} as PluginParams; + const forwardedProps = {} as Omit; + + Object.keys(props).forEach((propName) => { + const prop = props[propName as keyof typeof props] as any; + + if (paramsLookup[propName as keyof PluginParams]) { + pluginParams[propName as keyof PluginParams] = prop; + } else { + forwardedProps[propName as keyof typeof forwardedProps] = prop; + } + }); + + const defaultizedPluginParams = plugins.reduce( + (acc, plugin: TreeViewPlugin) => { + if (plugin.getDefaultizedParams) { + return plugin.getDefaultizedParams(acc); + } + + return acc; + }, + pluginParams, + ) as unknown as MergeSignaturesProperty; + + return { + apiRef, + forwardedProps, + pluginParams: defaultizedPluginParams, + slots: slots ?? ({} as any), + slotProps: slotProps ?? ({} as any), + experimentalFeatures: experimentalFeatures ?? {}, + }; +}; diff --git a/packages/x-tree-view/src/internals/useTreeView/index.ts b/packages/x-tree-view/src/internals/useTreeView/index.ts index 34c13feb963d..a5af56b16433 100644 --- a/packages/x-tree-view/src/internals/useTreeView/index.ts +++ b/packages/x-tree-view/src/internals/useTreeView/index.ts @@ -1,2 +1 @@ export { useTreeView } from './useTreeView'; -export type { UseTreeViewParameters, UseTreeViewDefaultizedParameters } from './useTreeView.types'; diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts index 1bc1b6ed2279..2742cda627d8 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeView.ts @@ -12,7 +12,7 @@ import { ConvertSignaturesIntoPlugins, } from '../models'; import { - UseTreeViewDefaultizedParameters, + UseTreeViewBaseProps, UseTreeViewParameters, UseTreeViewReturnValue, UseTreeViewRootSlotProps, @@ -20,9 +20,10 @@ import { import { useTreeViewModels } from './useTreeViewModels'; import { TreeViewContextValue, TreeViewItemPluginsRunner } from '../TreeViewProvider'; import { TREE_VIEW_CORE_PLUGINS, TreeViewCorePluginSignatures } from '../corePlugins'; +import { extractPluginParamsFromProps } from './extractPluginParamsFromProps'; export function useTreeViewApiInitialization( - inputApiRef: React.MutableRefObject | undefined, + inputApiRef: React.MutableRefObject | undefined, ): T { const fallbackPublicApiRef = React.useRef({}) as React.MutableRefObject; @@ -36,43 +37,43 @@ export function useTreeViewApiInitialization( return fallbackPublicApiRef.current; } -export const useTreeView = ( - inParams: UseTreeViewParameters, -): UseTreeViewReturnValue => { +export const useTreeView = < + TSignatures extends readonly TreeViewAnyPluginSignature[], + TProps extends Partial>, +>({ + plugins: inPlugins, + rootRef, + props, +}: UseTreeViewParameters): UseTreeViewReturnValue => { type TSignaturesWithCorePluginSignatures = readonly [ ...TreeViewCorePluginSignatures, ...TSignatures, ]; const plugins = [ ...TREE_VIEW_CORE_PLUGINS, - ...inParams.plugins, + ...inPlugins, ] as unknown as ConvertSignaturesIntoPlugins; - const params = plugins.reduce((acc, plugin) => { - if (plugin.getDefaultizedParams) { - return plugin.getDefaultizedParams(acc) as typeof acc; - } - - return acc; - }, inParams) as unknown as UseTreeViewDefaultizedParameters; + const { pluginParams, forwardedProps, apiRef, experimentalFeatures, slots, slotProps } = + extractPluginParamsFromProps({ + plugins, + props, + }); - const models = useTreeViewModels(plugins, params); + const models = useTreeViewModels(plugins, pluginParams); const instanceRef = React.useRef({} as TreeViewInstance); const instance = instanceRef.current as TreeViewInstance; - const publicAPI = useTreeViewApiInitialization>(inParams.apiRef); + const publicAPI = useTreeViewApiInitialization>(apiRef); const innerRootRef: React.RefObject = React.useRef(null); - const handleRootRef = useForkRef(innerRootRef, inParams.rootRef); + const handleRootRef = useForkRef(innerRootRef, rootRef); const [state, setState] = React.useState(() => { const temp = {} as MergeSignaturesProperty; plugins.forEach((plugin) => { if (plugin.getInitialState) { - Object.assign( - temp, - plugin.getInitialState(params as UseTreeViewDefaultizedParameters), - ); + Object.assign(temp, plugin.getInitialState(pluginParams)); } }); @@ -148,10 +149,10 @@ export const useTreeView = ) => { const pluginResponse = plugin({ instance, - params, - slots: params.slots, - slotProps: params.slotProps, - experimentalFeatures: params.experimentalFeatures, + params: pluginParams, + slots, + slotProps, + experimentalFeatures, state, setState, rootRef: innerRootRef, @@ -182,6 +183,7 @@ export const useTreeView = { const rootProps: UseTreeViewRootSlotProps = { role: 'tree', + ...forwardedProps, ...otherHandlers, ref: handleRootRef, }; diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeView.types.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeView.types.ts index e01053f06b07..e3ab5a0cf4e6 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeView.types.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeView.types.ts @@ -9,28 +9,23 @@ import { TreeViewPublicAPI, TreeViewExperimentalFeatures, } from '../models'; -import { TreeViewCorePluginSignatures } from '../corePlugins'; -export type UseTreeViewParameters = - UseTreeViewBaseParameters & - Omit, keyof UseTreeViewBaseParameters>; - -export interface UseTreeViewBaseParameters< +export interface UseTreeViewParameters< TSignatures extends readonly TreeViewAnyPluginSignature[], + TProps extends Partial>, > { - apiRef: React.MutableRefObject> | undefined; - rootRef?: React.Ref | undefined; plugins: ConvertSignaturesIntoPlugins; + rootRef?: React.Ref | undefined; + props: TProps; // Omit, keyof UseTreeViewBaseParameters> +} + +export interface UseTreeViewBaseProps { + apiRef: React.MutableRefObject | undefined> | undefined; slots: MergeSignaturesProperty; slotProps: MergeSignaturesProperty; experimentalFeatures: TreeViewExperimentalFeatures; } -export type UseTreeViewDefaultizedParameters< - TSignatures extends readonly TreeViewAnyPluginSignature[], -> = UseTreeViewBaseParameters & - MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'defaultizedParams'>; - export interface UseTreeViewRootSlotProps extends Pick< React.HTMLAttributes, diff --git a/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts b/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts index 42d861fb7fa2..7c30b4d90cbf 100644 --- a/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts +++ b/packages/x-tree-view/src/internals/useTreeView/useTreeViewModels.ts @@ -3,14 +3,16 @@ import { TreeViewAnyPluginSignature, ConvertSignaturesIntoPlugins, MergeSignaturesProperty, + TreeViewPlugin, } from '../models'; +import { TreeViewCorePluginSignatures } from '../corePlugins'; /** * Implements the same behavior as `useControlled` but for several models. * The controlled models are never stored in the state, and the state is only updated if the model is not controlled. */ export const useTreeViewModels = ( - plugins: ConvertSignaturesIntoPlugins, + plugins: ConvertSignaturesIntoPlugins, props: MergeSignaturesProperty, ) => { type DefaultizedParams = MergeSignaturesProperty; @@ -25,7 +27,7 @@ export const useTreeViewModels = (() => { const initialState: { [modelName: string]: any } = {}; - plugins.forEach((plugin) => { + plugins.forEach((plugin: TreeViewPlugin) => { if (plugin.models) { Object.entries(plugin.models).forEach(([modelName, modelInitializer]) => { modelsRef.current[modelName] = { diff --git a/packages/x-tree-view/src/internals/utils/extractPluginParamsFromProps.ts b/packages/x-tree-view/src/internals/utils/extractPluginParamsFromProps.ts deleted file mode 100644 index facfbd3bc3d0..000000000000 --- a/packages/x-tree-view/src/internals/utils/extractPluginParamsFromProps.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as React from 'react'; -import { - ConvertSignaturesIntoPlugins, - MergeSignaturesProperty, - TreeViewAnyPluginSignature, - TreeViewExperimentalFeatures, - TreeViewPublicAPI, -} from '../models'; -import { UseTreeViewBaseParameters } from '../useTreeView/useTreeView.types'; - -export const extractPluginParamsFromProps = < - TSignatures extends readonly TreeViewAnyPluginSignature[], - TSlots extends MergeSignaturesProperty, - TSlotProps extends MergeSignaturesProperty, - TProps extends { - slots?: TSlots; - slotProps?: TSlotProps; - apiRef?: React.MutableRefObject | undefined>; - experimentalFeatures?: TreeViewExperimentalFeatures; - }, ->({ - props: { slots, slotProps, apiRef, experimentalFeatures, ...props }, - plugins, - rootRef, -}: { - props: TProps; - plugins: ConvertSignaturesIntoPlugins; - rootRef?: React.Ref; -}) => { - type PluginParams = MergeSignaturesProperty; - - const paramsLookup = {} as Record; - plugins.forEach((plugin) => { - Object.assign(paramsLookup, plugin.params); - }); - - const pluginParams = { - plugins, - rootRef, - slots: slots ?? {}, - slotProps: slotProps ?? {}, - experimentalFeatures: experimentalFeatures ?? {}, - apiRef, - } as UseTreeViewBaseParameters & PluginParams; - const otherProps = {} as Omit; - - Object.keys(props).forEach((propName) => { - const prop = props[propName as keyof typeof props] as any; - - if (paramsLookup[propName as keyof PluginParams]) { - pluginParams[propName as keyof PluginParams] = prop; - } else { - otherProps[propName as keyof typeof otherProps] = prop; - } - }); - - return { pluginParams, slots, slotProps, otherProps }; -}; diff --git a/packages/x-tree-view/src/useTreeItem2/useTreeItem2.ts b/packages/x-tree-view/src/useTreeItem2/useTreeItem2.ts index 479e022efa9c..72fd74f6d23c 100644 --- a/packages/x-tree-view/src/useTreeItem2/useTreeItem2.ts +++ b/packages/x-tree-view/src/useTreeItem2/useTreeItem2.ts @@ -10,15 +10,15 @@ import { UseTreeItem2LabelSlotProps, UseTreeItemIconContainerSlotProps, UseTreeItem2CheckboxSlotProps, + UseTreeItem2MinimalPlugins, } from './useTreeItem2.types'; import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext'; -import { DefaultTreeViewPluginSignatures } from '../internals/plugins/defaultPlugins'; import { MuiCancellableEvent } from '../internals/models/MuiCancellableEvent'; import { useTreeItem2Utils } from '../hooks/useTreeItem2Utils'; import { TreeViewItemDepthContext } from '../internals/TreeViewItemDepthContext'; export const useTreeItem2 = < - TSignatures extends DefaultTreeViewPluginSignatures = DefaultTreeViewPluginSignatures, + TSignatures extends UseTreeItem2MinimalPlugins = UseTreeItem2MinimalPlugins, >( parameters: UseTreeItem2Parameters, ): UseTreeItem2ReturnValue => { diff --git a/packages/x-tree-view/src/useTreeItem2/useTreeItem2.types.ts b/packages/x-tree-view/src/useTreeItem2/useTreeItem2.types.ts index 530c0db1ec4d..08651b015ad3 100644 --- a/packages/x-tree-view/src/useTreeItem2/useTreeItem2.types.ts +++ b/packages/x-tree-view/src/useTreeItem2/useTreeItem2.types.ts @@ -2,6 +2,11 @@ import * as React from 'react'; import { TreeViewItemId } from '../models'; import { MuiCancellableEventHandler } from '../internals/models/MuiCancellableEvent'; import { TreeViewAnyPluginSignature, TreeViewPublicAPI } from '../internals/models'; +import { UseTreeViewSelectionSignature } from '../internals/plugins/useTreeViewSelection'; +import { UseTreeViewItemsSignature } from '../internals/plugins/useTreeViewItems'; +import { UseTreeViewIdSignature } from '../internals/plugins/useTreeViewId'; +import { UseTreeViewFocusSignature } from '../internals/plugins/useTreeViewFocus'; +import { UseTreeViewKeyboardNavigationSignature } from '../internals/plugins/useTreeViewKeyboardNavigation'; export interface UseTreeItem2Parameters { /** @@ -174,3 +179,11 @@ export interface UseTreeItem2ReturnValue< */ publicAPI: TreeViewPublicAPI; } + +export type UseTreeItem2MinimalPlugins = readonly [ + UseTreeViewSelectionSignature, + UseTreeViewItemsSignature, + UseTreeViewIdSignature, + UseTreeViewFocusSignature, + UseTreeViewKeyboardNavigationSignature, +]; diff --git a/scripts/x-tree-view.exports.json b/scripts/x-tree-view.exports.json index aba988ecc233..ee24f7972ee1 100644 --- a/scripts/x-tree-view.exports.json +++ b/scripts/x-tree-view.exports.json @@ -4,10 +4,14 @@ { "name": "getTreeItemUtilityClass", "kind": "Function" }, { "name": "getTreeViewUtilityClass", "kind": "Function" }, { "name": "MultiSelectTreeViewProps", "kind": "TypeAlias" }, + { "name": "RICH_TREE_VIEW_PLUGINS", "kind": "Variable" }, { "name": "RichTreeView", "kind": "Variable" }, { "name": "richTreeViewClasses", "kind": "Variable" }, { "name": "RichTreeViewClasses", "kind": "Interface" }, { "name": "RichTreeViewClassKey", "kind": "TypeAlias" }, + { "name": "RichTreeViewPluginParameters", "kind": "Interface" }, + { "name": "RichTreeViewPluginSlotProps", "kind": "TypeAlias" }, + { "name": "RichTreeViewPluginSlots", "kind": "TypeAlias" }, { "name": "RichTreeViewProps", "kind": "Interface" }, { "name": "RichTreeViewPropsBase", "kind": "Interface" }, { "name": "RichTreeViewRoot", "kind": "Variable" },