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 ofMenu
.MenuButton
: The trigger for the menu list. Must be a direct child ofMenu
.MenuItem
: The trigger that handles menu selection. Must be a direct child of aMenuList
.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 withMenuOptionGroup
.
import {Menu,MenuButton,MenuList,MenuItem,MenuItemOption,MenuGroup,MenuOptionGroup,MenuIcon,MenuCommand,MenuDivider,} from "@chakra-ui/react"
Usage#
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
.
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.
Just another example.#
Adding menu commands#
You can add custom menu icons and commands (or hotkeys) for each menu by passing
the command
prop.
<Menu><MenuButton size="sm" colorScheme="teal">Open menu</MenuButton><MenuList><MenuItem command="⌘T">New Tab</MenuItem><MenuItem command="⌘N">New Window</MenuItem><MenuItem command="⌘⇧N">Open Closed Tab</MenuItem><MenuItem 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.
<Menu isLazy><MenuButton size="sm" colorScheme="teal">Open menu</MenuButton><MenuList>{/* initially mounted */}<MenuItem>Menu 1</MenuItem>{/* initially mounted */}<MenuItem>New Window</MenuItem>{/* initially mounted */}<MenuItem>Open Closed Tab</MenuItem>{/* initially mounted */}<MenuItem>Open File</MenuItem></MenuList><MenuList></Menu>
Rendering menu in a portal#
To render menus in a portal, import the Portal
component and wrap the
MenuList
within the Portal
.
<Menu><MenuButton size="sm" colorScheme="teal">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.
Menu option groups#
You can compose a menu for table headers to help with sorting and filtering
options. Use the MenuOptionGroup
and MenuItemOption
components.
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 tobutton
.aria-haspopup
is set tomenu
.- When the menu is displayed,
aria-expanded
is set totrue
. aria-controls
is set to theid
of theMenuList
.
For MenuList
:
role
is set tomenu
.aria-orientation
is set tovertical
.
For MenuItem
:
role
is set tomenuitem
.- Gets one of these roles
menuitem
/menuitenradio
/menuitemcheckbox
.
Props#
Menu Props#
Name | Type | Description | Default |
---|---|---|---|
arrowPadding | number | The distance of the arrow to its next border (numeric) E.g. arrowPadding = borderRadius * 2 | - |
arrowShadowColor | string | - | |
arrowSize | number | - | |
autoSelect | boolean | If `true`, the first enabled menu item will be selected when the menu opens. | true |
closeOnBlur | boolean | If `true`, the menu will close when you click outside the menu list | true |
closeOnSelect | boolean | If `true`, the menu will close when a menu item is clicked | true |
colorScheme | string | - | |
defaultIsOpen | boolean | - | |
fixed | boolean | - | |
flip | boolean | - | |
gutter | number | - | |
id | string | - | |
isLazy | boolean | Performance 🚀: If `true`, the MenuItem rendering will be deferred until the menu is open. | - |
isOpen | boolean | - | |
matchWidth | boolean | - | |
modifiers | Modifier<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" | - | |
preventOverflow | boolean | - | |
size | string | - | |
variant | string | - |
MenuButton Props#
MenuButton
composes Box so you can pass all Box
props to
change its style.
MenuList Props#
MenuList
composes Box so you can pass all Box
props to
change its style.
MenuItem Props#
Name | Type | Description | Default |
---|---|---|---|
command | string | Right-aligned label text content, useful for displaying hotkeys. | - |
icon | React.ReactElement | The icon to render before the menu item's label. | - |
iconSpacing | SystemProps["mr"] | The spacing between the icon and menu item's label | - |
isDisabled | boolean | - | |
isFocusable | boolean | - |
MenuGroup Props#
MenuGroup
composes Box so you can pass all Box
props to
change its style.
MenuOptionGroup Props#
Name | Type | Description | Default |
---|---|---|---|
defaultValue | string | string[] | - | |
onChange | ((value: string | string[]) => void) | - | |
type | "checkbox" | "radio" | - | |
value | string | string[] | - |
MenuItemOption Props#
MenuItemOption
composes Box so you can pass all box props
in addition to these:
Name | Type | Description | Default |
---|---|---|---|
command | string | Right-aligned label text content, useful for displaying hotkeys. | - |
icon | React.ReactElement | The icon to render before the menu item's label. | - |
iconSpacing | SystemProps["mr"] | The spacing between the icon and menu item's label | - |
isChecked | boolean | - | |
isDisabled | boolean | - | |
isFocusable | boolean | - | |
type | "checkbox" | "radio" | - | |
value | string | - |