Skip to content

Menu

The Menu components provide your users with a list of options on temporary surfaces.

Introduction

The Menu component gives users a list of items in a popup that they can navigate through with a mouse or keyboard. It renders an unordered list (<ul>) by default.

Use the Menu Item to add items to the menu. These are rendered as <li> elements.

Components

Usage

After installation, you can start building with this component collection using the following basic elements:

<span class="token keyword">import</span> Menu <span class="token keyword">from</span> <span class="token string">'@mui/base/Menu'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> MenuItem <span class="token keyword">from</span> <span class="token string">'@mui/base/MenuItem'</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">MyApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">MenuItem</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* item one */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">MenuItem</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">MenuItem</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* item two */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">MenuItem</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Menu</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Basics

The Menu serves as a replacement for the native HTML <ul>, and the Menu Item corresponds to the <li> tag.

The following demo shows how to create and style a Menu component. Click Dashboard to view the menu—notice that it uses the built-in Popper component to visually break out of its parent container:

Anatomy

The Menu component is composed of a root slot that renders a Popper <div> by default. It contains one interior listbox <ul> slot. The Menu Item has a single root <li> slot.

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>MuiMenu-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>MuiMenu-listbox<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>MuiMenuItem-root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>List item<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>

Custom structure

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

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token attr-name">slots</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token string">'nav'</span><span class="token punctuation">,</span> <span class="token literal-property property">listbox</span><span class="token operator">:</span> <span class="token string">'ol'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>

Use the slotProps prop to pass custom props to internal slots. The following code snippet applies a CSS class called my-listbox to the listbox slot:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token attr-name">slotProps</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">listbox</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">className</span><span class="token operator">:</span> <span class="token string">'my-listbox'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>

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:

<span class="token operator">&lt;</span>Menu<span class="token operator">&lt;</span><span class="token keyword">typeof</span> CustomComponent<span class="token operator">></span> slots<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> root<span class="token operator">:</span> CustomComponent <span class="token punctuation">}</span><span class="token punctuation">}</span> customProp <span class="token operator">/</span><span class="token operator">></span>

The same applies for props specific to custom primitive elements:

<span class="token operator">&lt;</span>Menu<span class="token operator">&lt;</span><span class="token string">'button'</span><span class="token operator">></span> slots<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> root<span class="token operator">:</span> <span class="token string">'button'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span>

CSS classes

Menu can set the following class:

  • Mui-expanded - set when the menu is open; this class is set on both Root and Popper slots

Menu Item can set the following classes:

  • Mui-disabled - set when the MenuItem has the disabled prop
  • Mui-focusVisible - set when the MenuItem is highlighted via keyboard navigation. This is a polyfill for the native :focus-visible pseudoclass as it's not available in Safari.

Hooks

<span class="token keyword">import</span> useMenu <span class="token keyword">from</span> <span class="token string">'@mui/base/useMenu'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> useMenuItem <span class="token keyword">from</span> <span class="token string">'@mui/base/useMenuItem'</span><span class="token punctuation">;</span>

The useMenu and useMenuItem hooks let you apply the functionality of the Menu components to fully custom components. They return props to be placed on the custom components, along with fields representing the components' internal states.

Hooks do not support slot props, but they do support customization props.

The following demo shows how to build a menu using hooks:

Components and their corresponding hooks work interchangeably with one another—for example, you can create a Menu component that contains menu items built with the useMenuItem hook.

Customization

Wrapping MenuItems

Menu Item components don't have to be direct children of a Menu component. You can wrap them in any component needed to achieve the desired appearance.

In addition to Menu Item components, the Menu component can also contain non-interactive children, such as helper text.

The following demo shows an example of a menu with items grouped under non-interactive headers, along with helper text that displays the Current zoom level: