Menu
Usage
import React from 'react';import { Menu, MenuItem, MenuLabel, Divider, Text } from '@mantine/core';function Demo() {return (<Menu><Menu.Label>Application</Menu.Label><Menu.Item icon={<GearIcon />}>Settings</Menu.Item><Menu.Item icon={<ChatBubbleIcon />}>Messages</Menu.Item><Menu.Item icon={<ImageIcon />}>Gallery</Menu.Item><Menu.Itemicon={<MagnifyingGlassIcon />}rightSection={<Text size="xs" color="gray">⌘K</Text>}>Search</Menu.Item><Divider /><Menu.Label>Danger zone</Menu.Label><Menu.Item icon={<PinRightIcon />}>Transfer my data</Menu.Item>,<Menu.Item color="red" icon={<TrashIcon />}>Delete my account</Menu.Item></Menu>);}
Controlled
To control component opened state provide opened, onClose and onOpen props:
import { useState } from 'react';import { Menu } from '@mantine/core';function Demo() {const [opened, setOpened] = useState(false);return (<Menu opened={opened} onOpen={() => setOpened(true)} onClose={() => setOpened(false)}>{/* Menu items... */}</Menu>);}
Show menu on hover
To show menu on hover set props:
triggerto hoverdelayto number in ms (defaults to 0)
In this case menu will use onMouseEnter and onFocus events instead of onClick:
<Menu trigger="hover" delay={500} closeOnScroll={false}>{/* ... menu items */}</Menu>
Menu.Item component
You can use Divider (renders horizontal line) and Menu.Item components inside Menu. Menu.Item renders button and accepts props:
- icon – icon on the left
- children – item label
- rightSection – any element, rendered on the right, for example, Badge or keyboard shortcut
- ...others – Menu.Item produces button element, all other props will be spread to it, for example,
onClick,style,className
<Menu.Itemicon={<GearIcon />}onClick={() => console.log('Hello')}rightSection={<Text size="sm" color="gray">⌘K</Text>}>Label</Menu.Item>
Custom control
By default menu button uses ActionIcon with horizontal dots.
You can change it by setting control and controlRefProp props:
<Menucontrol={<button type="button">Button control</button>}controlRefProp="ref">{/* Menu items */}</Menu><Menu control={<Button>Mantine Button</Button>}>{/* Menu items */}</Menu>
controlRefProp is the prop name with which element ref can be accessed.
It defaults to elementRef as all interactive Mantine components use it to get ref.
For regular html element it will be controlRefProp="ref"
Change menu position
Menu is rendered inside Portal and its position is controlled with the following props:
position– left, right, bottom, topplacement– start, center, endgutter– spacing between menu body and target element in pxwithArrow– displays arrow, arrow position is calculated bypositionandplacementprops
Note that in most cases you will need to change Transition to match your position:
<Menu>{/* Menu items */}</Menu>
Change transition
Menu is built with Transition component. You can customize transition, timing function and duration:
<Menutransition="rotate-right"transitionDuration={100}transitionTimingFunction="ease">{/* Menu items */}</Menu>
Size and shadow
You can use predefined shadows defined in theme.shadows or your own:
<Menu shadow="sm" /> // -> predefined small shadow<Menu shadow="1px 1px 3px rgba(0, 0, 0, .1)" /> // -> custom shadow
<Menu>{/* Menu items */}</Menu>
Menu has predefined sizes: xs, sm, md, lg, xl. Size prop controls menu width. You can also use number value to set width in px:
<Menu size="sm" /> // -> predefined small width<Menu size={200} /> // -> 200px width
You can get predefined menu sizes by importing MENU_SIZES:
import { MENU_SIZES } from '@mantine/core';
| Prop value | Menu width |
|---|---|
| xs | 120px |
| sm | 160px |
| md | 200px |
| lg | 240px |
| xl | 300px |
Custom component as Menu.Item
By default menu items render as button, to change that set component prop on Menu.Item component:
// Regular anchor as Menu.Item root element<Menu.Item component="a" href="https://mantine/dev" target="_blank" />// React router link as Menu.Item root element<Menu.Item component={Link} to="/hello" />
<Menu><Menu.Item component="a" href="https://mantine.dev">Mantine website</Menu.Item><Menu.Itemicon={<ExternalLinkIcon />}component="a"href="https://mantine.dev"target="_blank">External link</Menu.Item></Menu>
Menu.Item as Next.js Link
Next Link component requires ref prop usage, however all Mantine components use elementRef,
to make Menu.Item and other similar components work with Next Link, create wrapper component in your components folder:
// This component can be reused in every Mantine component which supports component pass throughimport React, { forwardRef } from 'react';import Link from 'next/link';export const NextLink = forwardRef(({ href, ...others }: React.ComponentPropsWithoutRef<typeof Link>,ref: React.ForwardedRef<HTMLAnchorElement>) => (<Link href={href}>{/* eslint-disable-next-line jsx-a11y/anchor-has-content */}<a {...others} ref={ref} /></Link>));
And then pass it to Menu.Item or other component:
<Menu.Item component={NextLink} href="/hello">Next Link menu item</Menu.Item>
Customize behavior
You can control menu behavior with following props:
trapFocus– traps focus inside menu when it is openedcloseOnScroll– closes menu when page is scrolled
By default both options are true to ensure better accessibility, to turn them off set to false:
<Menu trapFocus={false} closeOnScroll={false} />
Store items separately
Menu does not support fragments, the following example will not work:
// Won't work, will not render itemsconst items = (<><Menu.Item>First</Menu.Item><Menu.Item>Second</Menu.Item></>);<Menu>{items}</Menu>;
In case you want to store items separately use array instead of fragment:
// Works as expectedconst items = [<Menu.Item>First</Menu.Item><Menu.Item>Second</Menu.Item>];<Menu>{items}</Menu>;
Add your styles with styles API
You can customize add styles to any part of Menu with Styles API, for example, change hovered item color:
import { Menu, createStyles } from '@mantine/core';const useStyles = createStyles((theme) => ({itemHovered: {backgroundColor: theme.colors[theme.primaryColor][7],color: theme.white,},}));function Demo() {const classes = useStyles();return (<Menu classNames={classes}>{/* Menu items... */}</Menu>);}
Get element ref
You can get menu control ref by passing elementRef prop to Menu component:
import { useRef } from 'react';import { Menu } from '@mantine/core';function Demo() {const menuControlRef = useRef();return <Menu elementRef={menuControlRef} />;}
Server side rendering
Component uses use-id hook to generate unique ids and aria- attributes,
provide static menuId prop to prevent props mismatch:
<Menu /> // -> random id generated both on client and server, props mismatch warning<Menu menuId="my-menu" /> // -> id is static, no mismatches
Accessibility and usability
To make component more accessible for users with screen readers set menuButtonLabel prop.
Use it in case you chose control which does not include text, for example, default ActionIcon with horizontal dots icon.
Component behavior and properties:
- When menu is opened focus is trapped inside
- When menu is closed focus is moved back to menu control
- Focus inside menu is controlled with up and down arrows, tab key has no effect
- By default when menu item is clicked, menu closes, change it with
closeOnItemClickprop - Menu is closed when user clicks outside ot presses escape
- Menu control has
aria-haspopup,aria-expanded,aria-controlsandaria-labelattributes,aria-labelis defined bymenuButtonLabelprop - Menu body has
menurole,aria-orientationis always set tovertical - Menu item has
menuitemrole