Menu
A dropdown of actions on Ark UI's Menu — composable parts plus a typesafe data-driven form, with sections, submenus, checkbox / radio items, and a context-menu trigger.
Menu is the kit's dropdown of actions, a styled layer over Ark UI's Menu. Ark owns the open state, positioning, roving focus, type-ahead, and the role="menu" / menuitem ARIA wiring; the kit adds the portaled, animated surface and Mantine-style item props. It ships two APIs from one import — compose the parts for full control, or pass an items array for the common case.
import { Menu } from '@42/ui-react/menu';
<Menu.Root>
<Menu.Trigger asChild>
<Button>Open</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item startSection={<User />} onClick={openProfile}>Profile</Menu.Item>
<Menu.Divider />
<Menu.Item color="red" startSection={<Trash />} onClick={remove}>Delete</Menu.Item>
</Menu.Content>
</Menu.Root>Playground
Menu
Dir
Props
Code
<Menu position="bottom-start" offset={8} closeOnSelect loopFocus={false}/>Basic usage
Menu.Item takes startSection / endSection (RTL-aware, like Mantine's left/right sections) and a color for destructive actions. Menu.Label heads a section and Menu.Divider separates them. The dropdown is portaled (escapes overflow: hidden ancestors) and animated.
Code
<Menu.Root><Menu.Trigger asChild> <Button variant="default" endSlot={<ChevronDown />}>Account</Button></Menu.Trigger><Menu.Content> <Menu.Label>Application</Menu.Label> <Menu.Item startSection={<User />}>Profile</Menu.Item> <Menu.Item startSection={<Settings />} endSection={<span>⌘S</span>}>Settings</Menu.Item> <Menu.Item startSection={<Users />}>Team</Menu.Item> <Menu.Divider /> <Menu.Item startSection={<LogOut />}>Log out</Menu.Item> <Menu.Item color="red" startSection={<Trash2 />}>Delete account</Menu.Item></Menu.Content></Menu.Root>Data-driven
For simple action menus, describe the whole thing as an items array — built on the same parts, the way Autocomplete is built on Combobox. Each item's onClick fires on activation (click and keyboard); a bare string is shorthand for { label, value }, { type: 'divider' } is a separator, and { group, items } is a section. A group takes an optional decorative prefix (the code-themed // leader, off by default; hidden from screen readers and the clipboard). The component is generic over const items, so an item's explicit value narrows the optional top-level onSelect(value).
Code
<Menuitems={[ { label: 'Profile', value: 'profile', startSection: <User /> }, { label: 'Settings', value: 'settings', startSection: <Settings /> }, { type: 'divider' }, { group: 'Danger zone', prefix: '// ', items: [ { label: 'Delete', value: 'delete', color: 'red', startSection: <Trash2 /> }, ]},]}onSelect={(value) => setLast(value)} // value: 'profile' | 'settings' | 'delete'><Button variant="default" endSlot={<ChevronDown />}>Actions</Button></Menu>Submenus
Nest a Menu.Sub and open it from a Menu.SubTrigger; its dropdown is a Menu.SubContent (same surface as Menu.Content). In the data-driven form, an item with both a label and its own items becomes a submenu automatically.
Code
<Menu.Content><Menu.Item startSection={<Copy />}>Copy</Menu.Item><Menu.Item startSection={<Scissors />}>Cut</Menu.Item><Menu.Divider /><Menu.Sub> <Menu.SubTrigger startSection={<Share2 />}>Share</Menu.SubTrigger> <Menu.SubContent> <Menu.Item startSection={<Link />}>Copy link</Menu.Item> <Menu.Item startSection={<Mail />}>Email</Menu.Item> </Menu.SubContent></Menu.Sub></Menu.Content>Checkbox & radio
Menu.CheckboxItem and Menu.RadioGroup / Menu.RadioItem carry selection state. Set closeOnSelect={false} on Menu.Root to keep the dropdown open while toggling several options.
Code
<Menu.Root closeOnSelect={false}><Menu.Trigger asChild><Button variant="default" endSlot={<ChevronDown />}>View</Button></Menu.Trigger><Menu.Content> <Menu.Label>Editor</Menu.Label> <Menu.CheckboxItem value="wrap" checked={wrap} onCheckedChange={setWrap}>Word wrap</Menu.CheckboxItem> <Menu.CheckboxItem value="minimap" checked={minimap} onCheckedChange={setMinimap}>Minimap</Menu.CheckboxItem> <Menu.Divider /> <Menu.Label>Theme</Menu.Label> <Menu.RadioGroup value={theme} onChange={setTheme}> <Menu.RadioItem value="light">Light</Menu.RadioItem> <Menu.RadioItem value="dark">Dark</Menu.RadioItem> <Menu.RadioItem value="system">System</Menu.RadioItem> </Menu.RadioGroup></Menu.Content></Menu.Root>Context menu
Swap Menu.Trigger for Menu.ContextTrigger to open on right-click (and long-press on touch).
Code
<Menu.Root><Menu.ContextTrigger asChild> <div>Right-click here</div></Menu.ContextTrigger><Menu.Content> <Menu.Item startSection={<Copy />}>Copy</Menu.Item> <Menu.Item startSection={<Scissors />}>Cut</Menu.Item> <Menu.Divider /> <Menu.Item color="red" startSection={<Trash2 />}>Delete</Menu.Item></Menu.Content></Menu.Root>Anatomy
Menu.Root— wraps Ark'sMenu.Root; owns open state + positioning.Menu.Trigger— the button that opens the menu; useasChildto wrap your own element.Menu.ContextTriggeropens on right-click instead.Menu.Content— the portaled, animated dropdown.Menu.Item— an action row, withstartSection/endSection/color.Menu.Label/Menu.Divider— a section heading and a separator. For ARIA-grouped sections useMenu.ItemGroup+Menu.ItemGroupLabel. Both headings accept an optional decorativeprefix(e.g."// ", off by default).Menu.CheckboxItem,Menu.RadioGroup/Menu.RadioItem— stateful selection rows.Menu.Sub/Menu.SubTrigger/Menu.SubContent— a nested submenu.
API
Menu.Root props (beyond Ark's Menu.Root):
Prop
Type
Menu.Item props (beyond Ark's Menu.Item):
Prop
Type
<Menu items> (data-driven) props:
Prop
Type