Menu
Menu
is a component that displays a common dropdown menu.
<Menu.Root>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="naruto">うずまきナルト</Menu.Item>
<Menu.Item value="sasuke">うちはサスケ</Menu.Item>
<Menu.Item value="sakura">春野サクラ</Menu.Item>
</Menu.Content>
</Menu.Root>
Usage
import { Menu } from "@yamada-ui/react"
import { Menu } from "@/components/ui"
import { Menu } from "@workspaces/ui"
<Menu.Root>
<Menu.Trigger />
<Menu.ContextTrigger />
<Menu.Anchor />
<Menu.Content>
<Menu.Header />
<Menu.Group>
<Menu.Item>
<Menu.Label />
<Menu.Indicator />
<Menu.Command />
</Menu.Item>
</Menu.Group>
<Menu.Separator />
<Menu.OptionGroup>
<Menu.OptionItem />
</Menu.OptionGroup>
<Menu.Footer />
</Menu.Content>
</Menu.Root>
Use Items
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
Change Size
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<HStack>
<For each={["sm", "md", "lg"]}>
{(size) => (
<Menu.Root key={size} size={size}>
<Menu.Trigger>
<Button>{toTitleCase(size)}</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)}
</For>
</HStack>
)
Handle Selection Event
To handle selection event, use onSelect
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root onSelect={(value) => console.log("selected", value)}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
Add Dividers
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
{ type: "separator" },
{ label: "大蛇丸", value: "orochimaru" },
{ label: "自來也", value: "pervy-sage" },
{ label: "綱手", value: "tsunade" },
],
[],
)
return (
<HStack>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with items</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with composition</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="naruto">うずまきナルト</Menu.Item>
<Menu.Item value="sasuke">うちはサスケ</Menu.Item>
<Menu.Item value="sakura">春野サクラ</Menu.Item>
<Menu.Separator />
<Menu.Item value="orochimaru">大蛇丸</Menu.Item>
<Menu.Item value="pervy-sage">自來也</Menu.Item>
<Menu.Item value="tsunade">綱手</Menu.Item>
</Menu.Content>
</Menu.Root>
</HStack>
)
Grouping
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{
items: [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
label: "第七班",
},
{
items: [
{ label: "大蛇丸", value: "orochimaru" },
{ label: "自來也", value: "pervy-sage" },
{ label: "綱手", value: "tsunade" },
],
label: "伝説の三忍",
},
],
[],
)
return (
<HStack>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with items</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with composition</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Group label="第七班">
<Menu.Item value="naruto">うずまきナルト</Menu.Item>
<Menu.Item value="sasuke">うちはサスケ</Menu.Item>
<Menu.Item value="sakura">春野サクラ</Menu.Item>
</Menu.Group>
<Menu.Separator />
<Menu.Group label="伝説の三忍">
<Menu.Item value="orochimaru">大蛇丸</Menu.Item>
<Menu.Item value="pervy-sage">自來也</Menu.Item>
<Menu.Item value="tsunade">綱手</Menu.Item>
</Menu.Group>
</Menu.Content>
</Menu.Root>
</HStack>
)
Display Icons
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{
label: (
<>
<Menu.Indicator>
<PlusIcon />
</Menu.Indicator>
New Tab
</>
),
value: "tab",
},
{
label: (
<>
<Menu.Indicator>
<SquareArrowOutUpRightIcon />
</Menu.Indicator>
New Window
</>
),
value: "window",
},
{
label: (
<>
<Menu.Indicator>
<SquarePenIcon />
</Menu.Indicator>
New File
</>
),
value: "file",
},
],
[],
)
return (
<HStack>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with items</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with composition</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="tab">
<Menu.Indicator>
<PlusIcon />
</Menu.Indicator>
New Tab
</Menu.Item>
<Menu.Item value="window">
<Menu.Indicator>
<SquareArrowOutUpRightIcon />
</Menu.Indicator>
New Window
</Menu.Item>
<Menu.Item value="file">
<Menu.Indicator>
<SquarePenIcon />
</Menu.Indicator>
New File
</Menu.Item>
</Menu.Content>
</Menu.Root>
</HStack>
)
Display Commands
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{
label: (
<>
New Tab
<Menu.Command>⌘T</Menu.Command>
</>
),
value: "tab",
},
{
label: (
<>
New Window
<Menu.Command>⌘N</Menu.Command>
</>
),
value: "window",
},
{
label: (
<>
Open File
<Menu.Command>⌘O</Menu.Command>
</>
),
value: "file",
},
],
[],
)
return (
<HStack>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with items</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with composition</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="tab">
New Tab
<Menu.Command>⌘T</Menu.Command>
</Menu.Item>
<Menu.Item value="window">
New Window
<Menu.Command>⌘N</Menu.Command>
</Menu.Item>
<Menu.Item value="file">
Open File
<Menu.Command>⌘O</Menu.Command>
</Menu.Item>
</Menu.Content>
</Menu.Root>
</HStack>
)
Set Selectable Items
const [value, setValue] = useState("naruto")
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{
type: "checkbox",
items: [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
{ label: "はたけカカシ", value: "kakashi", disabled: true },
],
value,
onChange: setValue,
},
],
[value],
)
return (
<HStack>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with items</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
<Menu.Root>
<Menu.Trigger>
<Button>Menu with composition</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.OptionGroup type="checkbox" value={value} onChange={setValue}>
<Menu.OptionItem value="naruto">うずまきナルト</Menu.OptionItem>
<Menu.OptionItem value="sasuke">うちはサスケ</Menu.OptionItem>
<Menu.OptionItem value="sakura">春野サクラ</Menu.OptionItem>
<Menu.OptionItem disabled value="kakashi">
はたけカカシ
</Menu.OptionItem>
</Menu.OptionGroup>
</Menu.Content>
</Menu.Root>
</HStack>
)
Nested Menu
<Menu.Root>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="naruto">うずまきナルト</Menu.Item>
<Menu.Item value="sasuke">うちはサスケ</Menu.Item>
<Menu.Item value="sakura">春野サクラ</Menu.Item>
<Menu.Root>
<Menu.Trigger>
<Menu.Item>Settings</Menu.Item>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="extensions">Extensions</Menu.Item>
<Menu.Item value="theme">Theme</Menu.Item>
<Menu.Item value="tasks">User Tasks</Menu.Item>
</Menu.Content>
</Menu.Root>
</Menu.Content>
</Menu.Root>
Use Context Menu
<Menu.Root>
<Menu.ContextTrigger>
<Center
borderStyle="dashed"
borderWidth="1px"
h="xs"
p="md"
rounded="l2"
w="full"
>
<Text>Right Click Here</Text>
</Center>
</Menu.ContextTrigger>
<Menu.Content>
<Menu.Item value="copy">Copy</Menu.Item>
<Menu.Item value="paste">Paste</Menu.Item>
<Menu.Item value="delete">Delete</Menu.Item>
</Menu.Content>
</Menu.Root>
Display Menu on Different Element
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root>
<HStack>
<Menu.Anchor>
<Center borderWidth="1px" h="10" px="3" rounded="l2">
Here display Popover
</Center>
</Menu.Anchor>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
</HStack>
<Menu.Content items={items} />
</Menu.Root>
)
Disable Close on Select
To disable the close on select, set closeOnSelect
to false
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root closeOnSelect={false}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
Set Initial Focus
To set initial focus, pass a Ref
to initialFocusRef
.
const ref = useRef<HTMLDivElement>(null)
return (
<Menu.Root initialFocusRef={ref}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="status">Set Status</Menu.Item>
<Menu.Item ref={ref} value="profile">
Edit Profile
</Menu.Item>
<Menu.Item value="preferences">Preferences</Menu.Item>
</Menu.Content>
</Menu.Root>
)
"use client"
to the top of the file.Change Placement
To change the display position, set placement
to "start"
, "end-end"
, etc. By default, "end-start"
is set.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<HStack>
<For
each={[
"start",
"start-start",
"start-end",
"end",
"end-start",
"end-end",
]}
>
{(placement) => (
<Menu.Root key={placement} placement={placement}>
<Menu.Trigger>
<Button>{toTitleCase(placement)}</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)}
</For>
</HStack>
)
Change Animation
To change the animation, set animationScheme
to "inline-start"
, "block-end"
, etc. By default, "scale"
is set.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<HStack>
<For
each={["scale", "block-end", "block-start", "inline-start", "inline-end"]}
>
{(animationScheme) => (
<Menu.Root key={animationScheme} animationScheme={animationScheme}>
<Menu.Trigger>
<Button>{toTitleCase(animationScheme)}</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)}
</For>
</HStack>
)
Change Offset
To change the offset, set a value to gutter
or offset
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<HStack>
<Menu.Root gutter={32}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
<Menu.Root offset={[16, 16]}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
</HStack>
)
Change Duration
To change the duration, set a numerical value (seconds) to duration
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root duration={0.4}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
Access Internal State
To access internal state, pass a function to the children
of Menu.Root
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root>
{({ open }) => (
<>
<Menu.Trigger>
<Button>{open ? "Close" : "Open"} Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</>
)}
</Menu.Root>
)
"use client"
to the top of the file.Disable Close on Outside Click
To disable closing when clicking outside, set closeOnBlur
to false
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root closeOnBlur={false}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
Disabling Items
To disable items, set disabled
to true
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke", disabled: true },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
Add Header or Footer
To add header or footer, set ReactNode
to header
or footer
of Menu.Content
.
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
{ label: "大蛇丸", value: "orochimaru" },
{ label: "自來也", value: "pervy-sage" },
{ label: "綱手", value: "tsunade" },
],
[],
)
return (
<Menu.Root>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content
header="キャラクター"
footer="キャラクター"
items={items}
maxH="2xs"
/>
</Menu.Root>
)
Control
const { open, onOpen, onClose } = useDisclosure()
const items = useMemo<Menu.ContentProps["items"]>(
() => [
{ label: "うずまきナルト", value: "naruto" },
{ label: "うちはサスケ", value: "sasuke" },
{ label: "春野サクラ", value: "sakura" },
],
[],
)
return (
<Menu.Root open={open} onOpen={onOpen} onClose={onClose}>
<Menu.Trigger>
<Button>Menu</Button>
</Menu.Trigger>
<Menu.Content items={items} />
</Menu.Root>
)
"use client"
to the top of the file.Props
Accessibility
Currently, this section is being updated due to the migration of v2.