Menu

An accessible dropdown menu for the common dropdown menu button design pattern. Menu uses roving tabIndex for focus management.

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.
import {
Menu,
MenuButton,
MenuList,
MenuItem,
MenuItemOption,
MenuGroup,
MenuOptionGroup,
MenuIcon,
MenuCommand,
MenuDivider,
} from "@chakra-ui/react"

Usage#

Editable Example

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.

Editable Example

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.

Custom components must take a ref prop which is assigned to the React component that triggers the menu opening. This is so that the MenuList popover can be positioned correctly. Without this, the MenuList will render in an undefined position.

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.

Editable Example

Just another example#

Editable Example

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.

Editable Example

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.

Editable Example

Rendering menu in a portal#

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

Editable Example

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

Editable Example

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

Editable Example

Accessibility#

Keyboard Interaction#

KeyAction
Enter or SpaceWhen MenuButton receives focus, opens the menu and places focus on the first menu item.
ArrowDownWhen MenuButton receives focus, opens the menu and moves focus to the first menu item.
ArrowUpWhen MenuButton receives focus, opens the menu and moves focus to the last menu item.
EscapeWhen the menu is open, closes the menu and sets focus to the MenuButton.
Tabno effect
HomeWhen the menu is open, moves focus to the first item.
EndWhen the menu is open, moves focus to the last item.
A-Z or a-zWhen 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.

Props#

NameTypeDescriptionDefault
arrowPaddingnumberThe distance of the arrow to its next border (numeric) E.g. arrowPadding = borderRadius * 2-
arrowShadowColorstring-
arrowSizenumber-
autoSelectbooleanIf `true`, the first enabled menu item will receive focus and be selected when the menu opens.true
closeOnBlurbooleanIf `true`, the menu will close when you click outside the menu listtrue
closeOnSelectbooleanIf `true`, the menu will close when a menu item is clickedtrue
colorScheme"blue" | "cyan" | "gray" | "green" | "orange" | "pink" | "purple" | "red" | "teal" | "yellow" | "whiteAlpha" | "blackAlpha" | "linkedin" | "facebook" | "messenger" | "whatsapp" | "twitter" | "telegram"Color Schemes for Menu are not implemented in the default theme. You can extend the theme to implement them.-
defaultIsOpenboolean-
enabledboolean-
fixedboolean-
flipboolean-
gutternumber-
idstring-
isLazybooleanPerformance 🚀: If `true`, the MenuItem rendering will be deferred until the menu is open.-
isOpenboolean-
matchWidthboolean-
modifiersModifier<string, any>[]-
offset[number, number]-
onClose(() => void)-
onOpen(() => void)-
placement"top" | "right" | "bottom" | "left" | "auto" | "auto-start" | "auto-end" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end"-
preventOverflowboolean-
sizestringSizes for Menu are not implemented in the default theme. You can extend the theme to implement them.-
variantstringVariants for Menu are not implemented in the default theme. You can extend the theme to implement them.-

MenuButton composes Box so you can pass all Box props to change its style.

MenuList composes Box so you can pass all Box props to change its style.

NameTypeDescriptionDefault
commandstringRight-aligned label text content, useful for displaying hotkeys.-
commandSpacingSystemProps["ml"]The spacing between the command and menu item's label.-
iconReact.ReactElementThe icon to render before the menu item's label.-
iconSpacingSystemProps["mr"]The spacing between the icon and menu item's label.-
isDisabledboolean-
isFocusableboolean-

MenuGroup composes Box so you can pass all Box props to change its style.

NameTypeDescriptionDefault
defaultValuestring | string[]-
onChange((value: string | string[]) => void)-
type"checkbox" | "radio"-
valuestring | string[]-

MenuItemOption composes Box so you can pass all box props in addition to these:

NameTypeDescriptionDefault
commandstringRight-aligned label text content, useful for displaying hotkeys.-
commandSpacingSystemProps["ml"]The spacing between the command and menu item's label.-
iconReact.ReactElementThe icon to render before the menu item's label.-
iconSpacingSystemProps["mr"]The spacing between the icon and menu item's label.-
isCheckedboolean-
isDisabledboolean-
isFocusableboolean-
type"checkbox" | "radio"-
valuestring-