# Composition

Material UI tries to make composition as easy as possible.

## Wrapping components To provide maximum flexibility and performance, Material UI needs a way to know the nature of the child elements a component receives. To solve this problem, we tag some of the components with a `muiName` static property when needed. You may, however, need to wrap a component in order to enhance it, which can conflict with the `muiName` solution. If you wrap a component, verify if that component has this static property set. If you encounter this issue, you need to use the same tag for your wrapping component that is used with the wrapped component. In addition, you should forward the props, as the parent component may need to control the wrapped components props. Let's see an example: ```jsx const WrappedIcon = (props) => ; WrappedIcon.muiName = Icon.muiName; ``` {{"demo": "Composition.js"}} ### Forwarding slot props Use the `mergeSlotProps` utility function to merge custom props with the slot props. If the arguments are functions then they'll be resolved before merging, and the result from the first argument will override the second. Special properties that merged between the two arguments are listed below: - `className`: values are concatenated rather than overriding one another. In the snippet below, the `custom-tooltip-popper` class is applied to the Tooltip's popper slot. ```jsx import Tooltip, { TooltipProps } from '@mui/material/Tooltip'; import { mergeSlotProps } from '@mui/material/utils'; export const CustomTooltip = (props: TooltipProps) => { const { children, title, sx: sxProps } = props; return ( {title}} slotProps={{ ...props.slotProps, popper: mergeSlotProps(props.slotProps?.popper, { className: 'custom-tooltip-popper', disablePortal: true, placement: 'top', }), }} > {children} ); }; ``` If you added another `className` via the `slotProps` prop on the Custom Tooltip—as shown below—then both would be present on the rendered popper slot: ```js ``` The popper slot in the original example would now have both classes applied to it, in addition to any others that may be present: `"[…] custom-tooltip-popper foo"`. - `style`: object are shallow merged rather than replacing one another. The style keys from the first argument have higher priority. - `sx`: values are concatenated into an array. - `^on[A-Z]` event handlers: these functions are composed between the two arguments. ```js mergeSlotProps(props.slotProps?.popper, { onClick: (event) => {}, // composed with the `slotProps?.popper?.onClick` createPopper: (popperOptions) => {}, // overridden by the `slotProps?.popper?.createPopper` }); ``` ## Component prop Material UI allows you to change the root element that will be rendered via a prop called `component`. For example, by default a `List` component will render a `