diff --git a/packages/mui-material/src/Menu/Menu.d.ts b/packages/mui-material/src/Menu/Menu.d.ts index 34b27cb8cca448..96a6adc9d8f80d 100644 --- a/packages/mui-material/src/Menu/Menu.d.ts +++ b/packages/mui-material/src/Menu/Menu.d.ts @@ -7,8 +7,29 @@ import { MenuListProps } from '../MenuList'; import { Theme } from '../styles'; import { TransitionProps } from '../transitions/transition'; import { MenuClasses } from './menuClasses'; +import { CreateSlotsAndSlotProps, SlotProps } from '../utils/types'; -export interface MenuProps extends StandardProps { +export interface MenuSlots { + /** + * The component that renders the transition. + * [Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. + * @default {} + */ + transition?: React.JSXElementConstructor< + TransitionProps & { children: React.ReactElement } + >; +} + +export type MenuSlotsAndSlotProps = CreateSlotsAndSlotProps< + {}, + { + transition: SlotProps, {}, MenuOwnerState>; + } +>; + +export interface MenuProps + extends Omit, 'slots' | 'slotProps'>, + MenuSlotsAndSlotProps { /** * An HTML element, or a function that returns one. * It's used to set the position of the menu. @@ -71,6 +92,7 @@ export interface MenuProps extends StandardProps { * Props applied to the transition element. * By default, the element is based on this [`Transition`](https://reactcommunity.org/react-transition-group/transition/) component. * @default {} + * @deprecated Use `slotProps.transition` instead. This prop will be removed in v7. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/) */ TransitionProps?: TransitionProps; /** @@ -80,6 +102,8 @@ export interface MenuProps extends StandardProps { variant?: 'menu' | 'selectedMenu'; } +export interface MenuOwnerState extends MenuProps {} + export declare const MenuPaper: React.FC; /** diff --git a/packages/mui-material/src/Menu/Menu.js b/packages/mui-material/src/Menu/Menu.js index edf4fe4f7dec34..2ab0cc7f4dee0b 100644 --- a/packages/mui-material/src/Menu/Menu.js +++ b/packages/mui-material/src/Menu/Menu.js @@ -12,6 +12,7 @@ import Popover, { PopoverPaper } from '../Popover'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled, createUseThemeProps } from '../zero-styled'; import { getMenuUtilityClass } from './menuClasses'; +import useSlot from '../utils/useSlot'; const useThemeProps = createUseThemeProps('MuiMenu'); @@ -80,7 +81,7 @@ const Menu = React.forwardRef(function Menu(inProps, ref) { PaperProps = {}, PopoverClasses, transitionDuration = 'auto', - TransitionProps: { onEntering, ...TransitionProps } = {}, + TransitionProps: TransitionPropsProp, variant = 'selectedMenu', slots = {}, slotProps = {}, @@ -89,6 +90,7 @@ const Menu = React.forwardRef(function Menu(inProps, ref) { const isRtl = useRtl(); + const { onEntering, ...TransitionProps } = TransitionPropsProp ?? {}; const ownerState = { ...props, autoFocus, @@ -180,8 +182,26 @@ const Menu = React.forwardRef(function Menu(inProps, ref) { className: classes.paper, }); + // as transitionComponent doesn't exists is this required? or should i be passing it something else, + // I can see its used in the popover component of the popover paper. so perhaps the component isn't needed + const backwardCompatibleSlots = { transition: TransitionComponentProp, ...slots }; + const backwardCompatibleSlotProps = { transition: TransitionPropsProp, ...slotProps }; + + const externalForwardedProps = { + slots: backwardCompatibleSlots, + slotProps: backwardCompatibleSlotProps, + }; + + // am I correct in thinking that this replaces menu as you need to provide it the transitionProps + // or should this wrap the menu component? Because in all other examples there was a pre existing transition component + const [TransitionSlot, transitionProps] = useSlot('transition', { + elementType: MenuRoot, + externalForwardedProps, + ownerState, + }); + return ( - {children} - + ); });