---
id: menu
category: overlay
title: Menu
package: '@chakra-ui/menu'
description:
  An accessible dropdown menu for the common dropdown menu button design
  pattern. Menu uses roving tabIndex for focus management.
video: 'https://youtu.be/Q-AMFseuFrk'
---

## Import

Chakra UI exports 8 components for rendering menus:

- `Menu`: The wrapper component provides context, state, and focus management.
- `MenuList`: The wrapper for the menu items. Must be a direct child of `Menu`.
- `MenuButton`: The trigger for the menu list. Must be a direct child of `Menu`.
- `MenuItem`: The trigger that handles menu selection. Must be a direct child of
  a `MenuList`.
- `MenuGroup`: A wrapper to group related menu items.
- `MenuDivider`: A visual separator for menu items and groups.
- `MenuOptionGroup`: A wrapper for checkable menu items (radio and checkbox).
- `MenuItemOption`: The checkable menu item, to be used with `MenuOptionGroup`.

```js
import {
  Menu,
  MenuButton,
  MenuList,
  MenuItem,
  MenuItemOption,
  MenuGroup,
  MenuOptionGroup,
  MenuDivider,
} from '@chakra-ui/react'
```

## Usage

```jsx
<Menu>
  <MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
    Actions
  </MenuButton>
  <MenuList>
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
    <MenuItem>Delete</MenuItem>
    <MenuItem>Attend a Workshop</MenuItem>
  </MenuList>
</Menu>
```

### Accessing the internal state

To access the internal state of the `Menu`, use a function as `children`
(commonly known as a render prop). You'll get access to the internal state
`isOpen` and method `onClose`.

```jsx
<Menu>
  {({ isOpen }) => (
    <>
      <MenuButton isActive={isOpen} as={Button} rightIcon={<ChevronDownIcon />}>
        {isOpen ? 'Close' : 'Open'}
      </MenuButton>
      <MenuList>
        <MenuItem>Download</MenuItem>
        <MenuItem onClick={() => alert('Kagebunshin')}>Create a Copy</MenuItem>
      </MenuList>
    </>
  )}
</Menu>
```

### Customizing the button

The default `MenuButton` can be styled using the usual styled-system props, but
it starts off plainly styled.

Using the `as` prop of the `MenuButton`, you can render a custom component
instead of the default `MenuButton`. For instance, you can use Chakra's `Button`
component, or your own custom component.

> If you decide to pass your own component to `MenuButton`, it needs to accept a
> `ref` so that the `MenuList` can be positioned correctly. You can use Chakra's
> `forwardRef` to supply the `ref` along with being able to use Chakra props.
> Without a `ref`, the `MenuList` will render in an undefined position.

See the documentation on setting up the
[forwardRef](/docs/components/recipes/as-prop#option-1-using-forwardref-from-chakra-uireact)
with your custom component.

### Letter Navigation

When focus is on the `MenuButton` or within the `MenuList` and you type a letter
key, a search begins. Focus will move to the first `MenuItem` that starts with
the letter you typed.

> Open the menu, try and type any letter, (say "S") to see the focus movement.

```jsx
<Menu>
  <MenuButton
    px={4}
    py={2}
    transition='all 0.2s'
    borderRadius='md'
    borderWidth='1px'
    _hover={{ bg: 'gray.400' }}
    _expanded={{ bg: 'blue.400' }}
    _focus={{ boxShadow: 'outline' }}
  >
    File <ChevronDownIcon />
  </MenuButton>
  <MenuList>
    <MenuItem>New File</MenuItem>
    <MenuItem>New Window</MenuItem>
    <MenuDivider />
    <MenuItem>Open...</MenuItem>
    <MenuItem>Save File</MenuItem>
  </MenuList>
</Menu>
```

### Just another example

```jsx
<Menu>
  <MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
    Your Cats
  </MenuButton>
  <MenuList>
    <MenuItem minH='48px'>
      <Image
        boxSize='2rem'
        borderRadius='full'
        src='https://placekitten.com/100/100'
        alt='Fluffybuns the destroyer'
        mr='12px'
      />
      <span>Fluffybuns the Destroyer</span>
    </MenuItem>
    <MenuItem minH='40px'>
      <Image
        boxSize='2rem'
        borderRadius='full'
        src='https://placekitten.com/120/120'
        alt='Simon the pensive'
        mr='12px'
      />
      <span>Simon the pensive</span>
    </MenuItem>
  </MenuList>
</Menu>
```

### Adding icons and commands

You can add icon to each `MenuItem` by passing the `icon` prop. To add a
commands (or hotkeys) to menu items, you can use the `command` prop.

```jsx
<Menu>
  <MenuButton
    as={IconButton}
    aria-label='Options'
    icon={<HamburgerIcon />}
    variant='outline'
  />
  <MenuList>
    <MenuItem icon={<AddIcon />} command='⌘T'>
      New Tab
    </MenuItem>
    <MenuItem icon={<ExternalLinkIcon />} command='⌘N'>
      New Window
    </MenuItem>
    <MenuItem icon={<RepeatIcon />} command='⌘⇧N'>
      Open Closed Tab
    </MenuItem>
    <MenuItem icon={<EditIcon />} command='⌘O'>
      Open File...
    </MenuItem>
  </MenuList>
</Menu>
```

### Lazily mounting MenuItem

By default, the `Menu` component renders all children of `MenuList` to the DOM,
meaning that invisible menu items are still rendered but are hidden by styles.

If you want to defer rendering of each children of `MenuList` until that menu is
open, you can use the `isLazy` prop. This is useful if your `Menu` needs to be
extra performant, or make network calls on mount that should only happen when
the component is displayed.

```jsx
<Menu isLazy>
  <MenuButton>Open menu</MenuButton>
  <MenuList>
    {/* MenuItems are not rendered unless Menu is open */}
    <MenuItem>New Window</MenuItem>
    <MenuItem>Open Closed Tab</MenuItem>
    <MenuItem>Open File</MenuItem>
  </MenuList>
</Menu>
```

### Rendering menu in a portal

To render menus in a portal, import the `Portal` component and wrap the
`MenuList` within the `Portal`.

```jsx
<Menu>
  <MenuButton>Open menu</MenuButton>
  <Portal>
    <MenuList>
      <MenuItem>Menu 1</MenuItem>
      <MenuItem>New Window</MenuItem>
      <MenuItem>Open Closed Tab</MenuItem>
      <MenuItem>Open File</MenuItem>
    </MenuList>
  </Portal>
</Menu>
```

### MenuGroup

To group related `MenuItem`s, use the `MenuGroup` component and pass it a
`title` for the group name.

```jsx
<Menu>
  <MenuButton as={Button} colorScheme='pink'>
    Profile
  </MenuButton>
  <MenuList>
    <MenuGroup title='Profile'>
      <MenuItem>My Account</MenuItem>
      <MenuItem>Payments </MenuItem>
    </MenuGroup>
    <MenuDivider />
    <MenuGroup title='Help'>
      <MenuItem>Docs</MenuItem>
      <MenuItem>FAQ</MenuItem>
    </MenuGroup>
  </MenuList>
</Menu>
```

### MenuItem as a link

To render a `MenuItem` as a link, use the attributes `as` and `href`.

```jsx
<Menu>
  <MenuButton>Open menu</MenuButton>
  <MenuList>
    <MenuItem as='a' href='#'>
      Link 1
    </MenuItem>
    <MenuItem as='a' href='#'>
      Link 2
    </MenuItem>
  </MenuList>
</Menu>
```

## Menu option groups

You can compose a menu for table headers to help with sorting and filtering
options. Use the `MenuOptionGroup` and `MenuItemOption` components.

```jsx
<Menu closeOnSelect={false}>
  <MenuButton as={Button} colorScheme='blue'>
    MenuItem
  </MenuButton>
  <MenuList minWidth='240px'>
    <MenuOptionGroup defaultValue='asc' title='Order' type='radio'>
      <MenuItemOption value='asc'>Ascending</MenuItemOption>
      <MenuItemOption value='desc'>Descending</MenuItemOption>
    </MenuOptionGroup>
    <MenuDivider />
    <MenuOptionGroup title='Country' type='checkbox'>
      <MenuItemOption value='email'>Email</MenuItemOption>
      <MenuItemOption value='phone'>Phone</MenuItemOption>
      <MenuItemOption value='country'>Country</MenuItemOption>
    </MenuOptionGroup>
  </MenuList>
</Menu>
```

## Accessibility

### Keyboard Interaction

| Key                | Action                                                                                                                                  |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `Enter` or `Space` | When `MenuButton` receives focus, opens the menu and places focus on the first menu item.                                               |
| `ArrowDown`        | When `MenuButton` receives focus, opens the menu and moves focus to the first menu item.                                                |
| `ArrowUp`          | When `MenuButton` receives focus, opens the menu and moves focus to the last menu item.                                                 |
| `Escape`           | When the menu is open, closes the menu and sets focus to the `MenuButton`.                                                              |
| `Tab`              | no effect                                                                                                                               |
| `Home`             | When the menu is open, moves focus to the first item.                                                                                   |
| `End`              | When the menu is open, moves focus to the last item.                                                                                    |
| `A-Z` or `a-z`     | When the menu is open, moves focus to the next menu item with a label that starts with the typed character if such an menu item exists. |

### ARIA roles

**For `MenuButton`:**

- `role` is set to `button`.
- `aria-haspopup` is set to `menu`.
- When the menu is displayed, `aria-expanded` is set to `true`.
- `aria-controls` is set to the `id` of the `MenuList`.

**For `MenuList`:**

- `role` is set to `menu`.
- `aria-orientation` is set to `vertical`.

**For `MenuItem`:**

- `role` is set to `menuitem`.
- Gets one of these roles `menuitem`/`menuitemradio`/ `menuitemcheckbox`.
