diff --git a/docs/pages/experiments/base/render-props.tsx b/docs/pages/experiments/base/render-props.tsx
new file mode 100644
index 00000000000000..dd30358e6a6cfd
--- /dev/null
+++ b/docs/pages/experiments/base/render-props.tsx
@@ -0,0 +1,91 @@
+import * as React from 'react';
+import { Menu } from '@mui/base/Menu';
+import { MenuItem } from '@mui/base/MenuItem';
+import { MenuButton, MenuButtonRootSlotProps } from '@mui/base/MenuButton';
+import { Dropdown } from '@mui/base/Dropdown';
+import IconButton from '@mui/joy/IconButton';
+import MenuIcon from '@mui/icons-material/Menu';
+import { CssVarsProvider } from '@mui/joy';
+
+function WithRenderProp() {
+ return (
+
+ (
+
+
+
+ )}
+ />
+
+
+ );
+}
+
+function WithSlotsAndSlotProps() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+const MenuIconButton = React.forwardRef(function MenuIconButton(
+ props: MenuButtonRootSlotProps,
+ ref: React.ForwardedRef,
+) {
+ return (
+
+ {props.children}
+
+ );
+});
+
+function WithSlots() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default function RenderProps() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/mui-base/src/MenuButton/MenuButton.tsx b/packages/mui-base/src/MenuButton/MenuButton.tsx
index 74095b9fd09dce..fb7255e17e6752 100644
--- a/packages/mui-base/src/MenuButton/MenuButton.tsx
+++ b/packages/mui-base/src/MenuButton/MenuButton.tsx
@@ -1,8 +1,8 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
-import { MenuButtonOwnerState, MenuButtonProps } from './MenuButton.types';
-import { useSlotProps } from '../utils';
+import { MenuButtonOwnerState, MenuButtonProps, MenuButtonRootSlotProps } from './MenuButton.types';
+import { useSlotProps, WithOptionalOwnerState } from '../utils';
import { useMenuButton } from '../useMenuButton';
import { unstable_composeClasses as composeClasses } from '../composeClasses';
import { useClassNamesOverride } from '../utils/ClassNameConfigurator';
@@ -39,6 +39,7 @@ const MenuButton = React.forwardRef(function MenuButton(
slots = {},
slotProps = {},
focusableWhenDisabled = false,
+ renderRoot,
...other
} = props;
@@ -59,7 +60,7 @@ const MenuButton = React.forwardRef(function MenuButton(
const classes = useUtilityClasses(ownerState);
const Root = slots.root || 'button';
- const rootProps = useSlotProps({
+ const rootProps: WithOptionalOwnerState = useSlotProps({
elementType: Root,
getSlotProps: getRootProps,
externalForwardedProps: other,
@@ -67,12 +68,20 @@ const MenuButton = React.forwardRef(function MenuButton(
additionalProps: {
ref: forwardedRef,
type: 'button',
+ children,
},
ownerState,
className: classes.root,
});
- return {children};
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ const { ownerState: _, ...otherRootProps } = rootProps;
+
+ return renderRoot ? (
+ renderRoot(otherRootProps, ownerState)
+ ) : (
+ {children}
+ );
});
MenuButton.propTypes /* remove-proptypes */ = {
diff --git a/packages/mui-base/src/MenuButton/MenuButton.types.ts b/packages/mui-base/src/MenuButton/MenuButton.types.ts
index 5d1d951824cc39..509605099c2689 100644
--- a/packages/mui-base/src/MenuButton/MenuButton.types.ts
+++ b/packages/mui-base/src/MenuButton/MenuButton.types.ts
@@ -1,3 +1,4 @@
+import { UseMenuButtonRootSlotProps } from '../useMenuButton';
import { SlotComponentProps } from '../utils/types';
export interface MenuButtonRootSlotPropsOverrides {}
@@ -35,6 +36,11 @@ export interface MenuButtonProps {
slotProps?: {
root?: SlotComponentProps<'button', MenuButtonRootSlotPropsOverrides, MenuButtonOwnerState>;
};
+
+ renderRoot?: (
+ props: Omit,
+ ownerState: MenuButtonOwnerState,
+ ) => React.JSX.Element;
}
export interface MenuButtonSlots {
@@ -50,3 +56,8 @@ export type MenuButtonOwnerState = MenuButtonProps & {
focusableWhenDisabled: boolean;
open: boolean;
};
+
+export type MenuButtonRootSlotProps = UseMenuButtonRootSlotProps & {
+ ownerState: MenuButtonOwnerState;
+ children?: React.ReactNode;
+};
diff --git a/packages/mui-base/src/useMenuButton/useMenuButton.types.ts b/packages/mui-base/src/useMenuButton/useMenuButton.types.ts
index 3ae91422c41851..81ac3402b528f7 100644
--- a/packages/mui-base/src/useMenuButton/useMenuButton.types.ts
+++ b/packages/mui-base/src/useMenuButton/useMenuButton.types.ts
@@ -15,7 +15,8 @@ export interface UseMenuButtonParameters {
rootRef?: React.Ref;
}
-type UseMenuButtonRootSlotProps = ExternalProps & UseMenuButtonRootSlotOwnProps;
+export type UseMenuButtonRootSlotProps = ExternalProps &
+ UseMenuButtonRootSlotOwnProps;
interface UseMenuButtonRootSlotOwnProps {
'aria-haspopup': 'menu';