Skip to content

Commit

Permalink
[Menu][base] Drop component prop (mui#37033)
Browse files Browse the repository at this point in the history
  • Loading branch information
hbjORbj authored and binh1298 committed May 17, 2023
1 parent b0b3ab0 commit 8d3098f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 33 deletions.
34 changes: 19 additions & 15 deletions docs/data/base/components/menu/menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,17 @@ The Menu Item has a single root `<li>` slot.
</div>
```

### Slot props
### Custom structure

:::info
The following props are available on all non-utility Base components.
See [Usage](/base/getting-started/usage/) for full details.
:::

Use the `component` prop to override the root slot with a custom element:

```jsx
<MenuItem component="span" />
```

Use the `slots` prop to override any interior slots in addition to the root:
Use the `slots` prop to override the root or any other interior slot:

```jsx
<Menu slots={{ root: 'nav', listbox: 'ol' }} />
```

:::warning
If the root element is customized with both the `component` and `slots` props, then `component` will take precedence.
:::info
The `slots` prop is available on all non-utility Base components.
See [Overriding component structure](/base/guides/overriding-component-structure/) for full details.
:::

Use the `slotProps` prop to pass custom props to internal slots.
Expand All @@ -98,6 +88,20 @@ The following code snippet applies a CSS class called `my-listbox` to the listbo
<Menu slotProps={{ listbox: { className: 'my-listbox' } }} />
```

#### Usage with TypeScript

In TypeScript, you can specify the custom component type used in the `slots.root` as a generic parameter of the unstyled component. This way, you can safely provide the custom root's props directly on the component:

```tsx
<Menu<typeof CustomComponent> slots={{ root: CustomComponent }} customProp />
```

The same applies for props specific to custom primitive elements:

```tsx
<Menu<'button'> slots={{ root: 'button' }} onClick={() => {}} />
```

### CSS classes

Menu can set the following class:
Expand Down
1 change: 0 additions & 1 deletion docs/pages/base/api/menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"description": "HTML element<br>&#124;&nbsp;object<br>&#124;&nbsp;func"
}
},
"component": { "type": { "name": "elementType" } },
"onOpenChange": { "type": { "name": "func" } },
"open": { "type": { "name": "bool" }, "default": "false" },
"slotProps": {
Expand Down
1 change: 0 additions & 1 deletion docs/translations/api-docs-base/menu/menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"propDescriptions": {
"actions": "A ref with imperative actions. It allows to select the first or last menu item.",
"anchorEl": "An HTML element, <a href=\"https://popper.js.org/docs/v2/virtual-elements/\">virtualElement</a>, or a function that returns either. It&#39;s used to set the position of the popper.",
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"onOpenChange": "Triggered when focus leaves the menu and the menu should close.",
"open": "Controls whether the menu is displayed.",
"slotProps": "The props used for each slot inside the Menu.",
Expand Down
34 changes: 27 additions & 7 deletions packages/mui-base/src/Menu/Menu.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,39 @@ const polymorphicComponentTest = () => {
{/* @ts-expect-error */}
<Menu invalidProp={0} />

<Menu component="a" href="#" />
<Menu<'a'>
slots={{
root: 'a',
}}
href="#"
/>

<Menu component={CustomComponent} stringProp="test" numberProp={0} />
{/* @ts-expect-error */}
<Menu component={CustomComponent} />
<Menu<typeof CustomComponent>
slots={{
root: CustomComponent,
}}
stringProp="test"
numberProp={0}
/>

<Menu
component="button"
{/* @ts-expect-error required props not specified */}
<Menu<typeof CustomComponent>
slots={{
root: CustomComponent,
}}
/>

<Menu<'button'>
slots={{
root: 'button',
}}
onClick={(e: React.MouseEvent<HTMLButtonElement>) => e.currentTarget.checkValidity()}
/>

<Menu<'button'>
component="button"
slots={{
root: 'button',
}}
ref={(elem) => {
expectType<HTMLButtonElement | null, typeof elem>(elem);
}}
Expand Down
12 changes: 3 additions & 9 deletions packages/mui-base/src/Menu/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { HTMLElementType, refType } from '@mui/utils';
import { OverridableComponent } from '@mui/types';
import { PolymorphicComponent } from '../utils/PolymorphicComponent';
import { MenuOwnerState, MenuProps, MenuRootSlotProps, MenuTypeMap } from './Menu.types';
import { getMenuUtilityClass } from './menuClasses';
import useMenu from '../useMenu';
Expand Down Expand Up @@ -39,7 +39,6 @@ const Menu = React.forwardRef(function Menu<RootComponentType extends React.Elem
actions,
anchorEl,
children,
component,
defaultOpen,
listboxId,
onOpenChange,
Expand Down Expand Up @@ -68,7 +67,7 @@ const Menu = React.forwardRef(function Menu<RootComponentType extends React.Elem

const classes = useUtilityClasses(ownerState);

const Root = component ?? slots.root ?? Popper;
const Root = slots.root ?? Popper;
const rootProps: WithOptionalOwnerState<MenuRootSlotProps> = useSlotProps({
elementType: Root,
externalForwardedProps: other,
Expand Down Expand Up @@ -100,7 +99,7 @@ const Menu = React.forwardRef(function Menu<RootComponentType extends React.Elem
</Listbox>
</Root>
);
}) as OverridableComponent<MenuTypeMap>;
}) as PolymorphicComponent<MenuTypeMap>;

Menu.propTypes /* remove-proptypes */ = {
// ----------------------------- Warning --------------------------------
Expand All @@ -126,11 +125,6 @@ Menu.propTypes /* remove-proptypes */ = {
* @ignore
*/
children: PropTypes.node,
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
*/
component: PropTypes.elementType,
/**
* @ignore
*/
Expand Down

0 comments on commit 8d3098f

Please sign in to comment.