Menu
Action menu built on React Aria, with sections, submenus, selection, and keyboard shortcuts.
import { Menu } from "@pockets-ui/components"
import { button } from "@/styled-system/recipes"Anatomy
| Part | Role |
|---|---|
Menu.Root | Wires the trigger to the popover. |
Menu.Trigger | The button that opens the menu. |
Menu.Content | The popover menu. Owns selectionMode and disabledKeys. |
Menu.Item | One action, keyed by id. |
Menu.Shortcut | Right-aligned keyboard hint inside an item. |
Menu.Section | Groups items under a heading. |
Menu.SectionHeader | That heading. |
Menu.SubmenuTrigger | Wraps a parent item plus its nested Menu.Content. |
Menu.Separator | Divider between items or sections. |
Menu.Trigger renders its own element rather than wrapping a
Button, so these examples style it with the button
recipe — button({ variant: "outline" }) gives the same classes the
component uses.
Basic
Menu.Shortcut only displays the hint; register the actual key handler
yourself.
Code
import { Menu } from "@pockets-ui/components"
import { button } from "@/styled-system/recipes"
// Menu.Trigger renders its own element, so style it with the button recipe.
const trigger = button({ variant: "outline" })
export default function MenuBasic() {
return (
<Menu.Root>
<Menu.Trigger className={trigger}>Actions</Menu.Trigger>
<Menu.Content aria-label="Actions">
<Menu.Item id="open">
Open <Menu.Shortcut>⌘O</Menu.Shortcut>
</Menu.Item>
<Menu.Item id="rename">
Rename <Menu.Shortcut>⌘R</Menu.Shortcut>
</Menu.Item>
<Menu.Item id="duplicate">Duplicate</Menu.Item>
<Menu.Separator />
<Menu.Item id="delete">
Delete <Menu.Shortcut>⌘⌫</Menu.Shortcut>
</Menu.Item>
</Menu.Content>
</Menu.Root>
)
}Sections
Code
import { Menu } from "@pockets-ui/components"
import { button } from "@/styled-system/recipes"
const trigger = button({ variant: "outline" })
export default function MenuSections() {
return (
<Menu.Root>
<Menu.Trigger className={trigger}>Open recent</Menu.Trigger>
<Menu.Content aria-label="Open recent">
<Menu.Section>
<Menu.SectionHeader>Today</Menu.SectionHeader>
<Menu.Item id="report">Report.pdf</Menu.Item>
<Menu.Item id="notes">Notes.md</Menu.Item>
</Menu.Section>
<Menu.Separator />
<Menu.Section>
<Menu.SectionHeader>Last week</Menu.SectionHeader>
<Menu.Item id="budget">Budget.xlsx</Menu.Item>
<Menu.Item id="deck">Deck.key</Menu.Item>
</Menu.Section>
</Menu.Content>
</Menu.Root>
)
}Single selection
With selectionMode, items become checkable state rather than one-shot actions
— use it for view options, not for commands.
Code
import { Menu } from "@pockets-ui/components"
import { button } from "@/styled-system/recipes"
const trigger = button({ variant: "outline" })
export default function MenuSingleSelection() {
return (
<Menu.Root>
<Menu.Trigger className={trigger}>View</Menu.Trigger>
<Menu.Content
aria-label="View"
selectionMode="single"
defaultSelectedKeys={["list"]}
>
<Menu.Item id="list">List</Menu.Item>
<Menu.Item id="grid">Grid</Menu.Item>
<Menu.Item id="columns">Columns</Menu.Item>
</Menu.Content>
</Menu.Root>
)
}Submenu
Code
import { Menu } from "@pockets-ui/components"
import { button } from "@/styled-system/recipes"
const trigger = button({ variant: "outline" })
export default function MenuSubmenu() {
return (
<Menu.Root>
<Menu.Trigger className={trigger}>More</Menu.Trigger>
<Menu.Content aria-label="More">
<Menu.Item id="copy">Copy link</Menu.Item>
{/* SubmenuTrigger takes the parent item and the nested Content. */}
<Menu.SubmenuTrigger>
<Menu.Item id="share">Share</Menu.Item>
<Menu.Content aria-label="Share">
<Menu.Item id="email">Email</Menu.Item>
<Menu.Item id="message">Message</Menu.Item>
<Menu.Item id="airdrop">AirDrop</Menu.Item>
</Menu.Content>
</Menu.SubmenuTrigger>
<Menu.Separator />
<Menu.Item id="report">Report an issue</Menu.Item>
</Menu.Content>
</Menu.Root>
)
}Disabled items
Code
import { Menu } from "@pockets-ui/components"
import { button } from "@/styled-system/recipes"
const trigger = button({ variant: "outline" })
export default function MenuDisabledItems() {
return (
<Menu.Root>
<Menu.Trigger className={trigger}>Edit</Menu.Trigger>
<Menu.Content aria-label="Edit" disabledKeys={["paste"]}>
<Menu.Item id="cut">
Cut <Menu.Shortcut>⌘X</Menu.Shortcut>
</Menu.Item>
<Menu.Item id="copy">
Copy <Menu.Shortcut>⌘C</Menu.Shortcut>
</Menu.Item>
<Menu.Item id="paste">
Paste <Menu.Shortcut>⌘V</Menu.Shortcut>
</Menu.Item>
</Menu.Content>
</Menu.Root>
)
}