# Menu

URL: https://ark-ui.com/docs/components/menu
LLM: https://ark-ui.com/llms.txt/components/menu

A list of options that appears when a user interacts with a button.

---



## Anatomy



```tsx
<Menu.Root>
  <Menu.Trigger>
    <Menu.Indicator />
  </Menu.Trigger>
  <Menu.Positioner>
    <Menu.Content>
      <Menu.Arrow>
        <Menu.ArrowTip />
      </Menu.Arrow>
      <Menu.Item />
      <Menu.ItemGroup>
        <Menu.ItemGroupLabel />
        <Menu.Item />
      </Menu.ItemGroup>
      <Menu.Separator />
    </Menu.Content>
  </Menu.Positioner>
</Menu.Root>
```

## Examples

```tsx
import { Menu } from '@ark-ui/react/menu'
import { ChevronDownIcon } from 'lucide-react'
import styles from 'styles/menu.module.css'

export const Basic = () => (
  <Menu.Root>
    <Menu.Trigger className={styles.Trigger}>
      File
      <Menu.Indicator className={styles.Indicator}>
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content className={styles.Content}>
        <Menu.Arrow className={styles.Arrow}>
          <Menu.ArrowTip className={styles.ArrowTip} />
        </Menu.Arrow>
        <Menu.Item className={styles.Item} value="new-file">
          New File
        </Menu.Item>
        <Menu.Item className={styles.Item} value="open">
          Open...
        </Menu.Item>
        <Menu.Item className={styles.Item} value="save">
          Save
        </Menu.Item>
        <Menu.Item className={styles.Item} value="save-as">
          Save As...
        </Menu.Item>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
)
```

### Item Selection

Use `onSelect` to handle item selection. The callback receives the item's `id`.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { ChevronDownIcon } from 'lucide-react'
import { useState } from 'react'
import button from 'styles/button.module.css'
import styles from 'styles/menu.module.css'

export const Controlled = () => {
  const [open, setOpen] = useState(false)

  return (
    <div className="stack">
      <button type="button" className={button.Root} onClick={() => setOpen(!open)}>
        Toggle
      </button>
      <Menu.Root open={open} onOpenChange={(e) => setOpen(e.open)}>
        <Menu.Trigger className={styles.Trigger}>
          Actions
          <Menu.Indicator className={styles.Indicator}>
            <ChevronDownIcon />
          </Menu.Indicator>
        </Menu.Trigger>
        <Menu.Positioner>
          <Menu.Content className={styles.Content}>
            <Menu.Item className={styles.Item} value="edit">
              Edit
            </Menu.Item>
            <Menu.Item className={styles.Item} value="duplicate">
              Duplicate
            </Menu.Item>
            <Menu.Item className={styles.Item} value="archive">
              Archive
            </Menu.Item>
            <Menu.Item className={styles.Item} value="delete">
              Delete
            </Menu.Item>
          </Menu.Content>
        </Menu.Positioner>
      </Menu.Root>
    </div>
  )
}
```

### Root Provider

An alternative way to control the menu is to use the `RootProvider` component and the `useMenu` hook. This way you can
access the state and methods from outside the component.

```tsx
import { Menu, useMenu } from '@ark-ui/react/menu'
import { ChevronDownIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/menu.module.css'

export const RootProvider = () => {
  const menu = useMenu()

  return (
    <div className="stack">
      <button className={button.Root} onClick={() => menu.api.setHighlightedValue('copy')}>
        Highlight Copy
      </button>
      <Menu.RootProvider value={menu}>
        <Menu.Trigger className={styles.Trigger}>
          Edit
          <Menu.Indicator className={styles.Indicator}>
            <ChevronDownIcon />
          </Menu.Indicator>
        </Menu.Trigger>
        <Menu.Positioner>
          <Menu.Content className={styles.Content}>
            <Menu.Item className={styles.Item} value="cut">
              Cut
            </Menu.Item>
            <Menu.Item className={styles.Item} value="copy">
              Copy
            </Menu.Item>
            <Menu.Item className={styles.Item} value="paste">
              Paste
            </Menu.Item>
            <Menu.Item className={styles.Item} value="delete">
              Delete
            </Menu.Item>
          </Menu.Content>
        </Menu.Positioner>
      </Menu.RootProvider>
    </div>
  )
}
```

### Grouping

Use `Menu.ItemGroup` and `Menu.ItemGroupLabel` to organize related menu items.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { ChevronDownIcon } from 'lucide-react'
import styles from 'styles/menu.module.css'

export const Group = () => (
  <Menu.Root>
    <Menu.Trigger className={styles.Trigger}>
      Edit
      <Menu.Indicator className={styles.Indicator}>
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content className={styles.Content}>
        <Menu.ItemGroup className={styles.ItemGroup}>
          <Menu.ItemGroupLabel className={styles.ItemGroupLabel}>Clipboard</Menu.ItemGroupLabel>
          <Menu.Item className={styles.Item} value="cut">
            Cut
          </Menu.Item>
          <Menu.Item className={styles.Item} value="copy">
            Copy
          </Menu.Item>
          <Menu.Item className={styles.Item} value="paste">
            Paste
          </Menu.Item>
        </Menu.ItemGroup>
        <Menu.ItemGroup className={styles.ItemGroup}>
          <Menu.ItemGroupLabel className={styles.ItemGroupLabel}>Selection</Menu.ItemGroupLabel>
          <Menu.Item className={styles.Item} value="select-all">
            Select All
          </Menu.Item>
          <Menu.Item className={styles.Item} value="deselect">
            Deselect
          </Menu.Item>
        </Menu.ItemGroup>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
)
```

### Links

To render menu items as links, use the `asChild` prop to replace the default element with an anchor tag.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { ChevronDownIcon } from 'lucide-react'
import styles from 'styles/menu.module.css'

export const Links = () => (
  <Menu.Root>
    <Menu.Trigger className={styles.Trigger}>
      Help
      <Menu.Indicator className={styles.Indicator}>
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content className={styles.Content}>
        <Menu.Item className={styles.Item} value="docs" asChild>
          <a href="https://ark-ui.com">Documentation</a>
        </Menu.Item>
        <Menu.Item className={styles.Item} value="github" asChild>
          <a href="https://github.com/chakra-ui/ark">GitHub</a>
        </Menu.Item>
        <Menu.Separator className={styles.Separator} />
        <Menu.Item className={styles.Item} value="changelog" asChild>
          <a href="https://github.com/chakra-ui/ark/releases">Changelog</a>
        </Menu.Item>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
)
```

### Checkbox

To add a checkbox to a menu item, use the `Menu.Checkbox` component.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { CheckIcon, ChevronDownIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/menu.module.css'

export const CheckboxItems = () => {
  const [showToolbar, setShowToolbar] = useState(true)
  const [showStatusBar, setShowStatusBar] = useState(false)

  return (
    <Menu.Root>
      <Menu.Trigger className={styles.Trigger}>
        View
        <Menu.Indicator className={styles.Indicator}>
          <ChevronDownIcon />
        </Menu.Indicator>
      </Menu.Trigger>
      <Menu.Positioner>
        <Menu.Content className={styles.Content}>
          <Menu.CheckboxItem
            className={styles.CheckboxItem}
            checked={showToolbar}
            onCheckedChange={setShowToolbar}
            value="toolbar"
          >
            <Menu.ItemIndicator className={styles.ItemIndicator}>
              <CheckIcon />
            </Menu.ItemIndicator>
            <Menu.ItemText className={styles.ItemText}>Show Toolbar</Menu.ItemText>
          </Menu.CheckboxItem>
          <Menu.CheckboxItem
            className={styles.CheckboxItem}
            checked={showStatusBar}
            onCheckedChange={setShowStatusBar}
            value="status-bar"
          >
            <Menu.ItemIndicator className={styles.ItemIndicator}>
              <CheckIcon />
            </Menu.ItemIndicator>
            <Menu.ItemText className={styles.ItemText}>Show Status Bar</Menu.ItemText>
          </Menu.CheckboxItem>
        </Menu.Content>
      </Menu.Positioner>
    </Menu.Root>
  )
}
```

### Radio Group

To group radio option items, use the `Menu.RadioGroup` component.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { CheckIcon, ChevronDownIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/menu.module.css'

export const RadioItems = () => {
  const [sortBy, setSortBy] = useState('date')

  return (
    <Menu.Root>
      <Menu.Trigger className={styles.Trigger}>
        Sort
        <Menu.Indicator className={styles.Indicator}>
          <ChevronDownIcon />
        </Menu.Indicator>
      </Menu.Trigger>
      <Menu.Positioner>
        <Menu.Content className={styles.Content}>
          <Menu.RadioItemGroup className={styles.ItemGroup} value={sortBy} onValueChange={(e) => setSortBy(e.value)}>
            <Menu.ItemGroupLabel className={styles.ItemGroupLabel}>Sort By</Menu.ItemGroupLabel>
            <Menu.RadioItem className={styles.RadioItem} value="name">
              <Menu.ItemIndicator className={styles.ItemIndicator}>
                <CheckIcon />
              </Menu.ItemIndicator>
              <Menu.ItemText className={styles.ItemText}>Name</Menu.ItemText>
            </Menu.RadioItem>
            <Menu.RadioItem className={styles.RadioItem} value="date">
              <Menu.ItemIndicator className={styles.ItemIndicator}>
                <CheckIcon />
              </Menu.ItemIndicator>
              <Menu.ItemText className={styles.ItemText}>Date Modified</Menu.ItemText>
            </Menu.RadioItem>
            <Menu.RadioItem className={styles.RadioItem} value="size">
              <Menu.ItemIndicator className={styles.ItemIndicator}>
                <CheckIcon />
              </Menu.ItemIndicator>
              <Menu.ItemText className={styles.ItemText}>Size</Menu.ItemText>
            </Menu.RadioItem>
            <Menu.RadioItem className={styles.RadioItem} value="type">
              <Menu.ItemIndicator className={styles.ItemIndicator}>
                <CheckIcon />
              </Menu.ItemIndicator>
              <Menu.ItemText className={styles.ItemText}>Type</Menu.ItemText>
            </Menu.RadioItem>
          </Menu.RadioItemGroup>
        </Menu.Content>
      </Menu.Positioner>
    </Menu.Root>
  )
}
```

### Context Menu

To show the menu when a trigger element is right-clicked, use the `Menu.ContextTrigger` component.

Context menus are also opened during a long-press of roughly `700ms` when the pointer is pen or touch.

```tsx
import { Menu } from '@ark-ui/react/menu'
import styles from 'styles/menu.module.css'

export const Context = () => (
  <Menu.Root>
    <Menu.ContextTrigger className={styles.ContextTrigger}>Right click here</Menu.ContextTrigger>
    <Menu.Positioner>
      <Menu.Content className={styles.Content}>
        <Menu.Item className={styles.Item} value="cut">
          Cut
        </Menu.Item>
        <Menu.Item className={styles.Item} value="copy">
          Copy
        </Menu.Item>
        <Menu.Item className={styles.Item} value="paste">
          Paste
        </Menu.Item>
        <Menu.Separator className={styles.Separator} />
        <Menu.Item className={styles.Item} value="delete">
          Delete
        </Menu.Item>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
)
```

### Nested

To show a nested menu, render another `Menu` component and use the `Menu.TriggerItem` component to open the submenu.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { Portal } from '@ark-ui/react/portal'
import { ChevronDownIcon } from 'lucide-react'
import styles from 'styles/menu.module.css'

export const Nested = () => (
  <Menu.Root>
    <Menu.Trigger className={styles.Trigger}>
      File
      <Menu.Indicator className={styles.Indicator}>
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Portal>
      <Menu.Positioner>
        <Menu.Content className={styles.Content}>
          <Menu.Item className={styles.Item} value="new">
            New File
          </Menu.Item>
          <Menu.Item className={styles.Item} value="open">
            Open...
          </Menu.Item>
          <Menu.Separator className={styles.Separator} />
          <Menu.Root>
            <Menu.TriggerItem className={styles.TriggerItem}>Share</Menu.TriggerItem>
            <Portal>
              <Menu.Positioner>
                <Menu.Content className={styles.Content}>
                  <Menu.Item className={styles.Item} value="email">
                    Email
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="message">
                    Message
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="airdrop">
                    AirDrop
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test1">
                    Test1
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test2">
                    Test2
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test3">
                    Test3
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test4">
                    Test4
                  </Menu.Item>
                </Menu.Content>
              </Menu.Positioner>
            </Portal>
          </Menu.Root>
          <Menu.Root>
            <Menu.TriggerItem className={styles.TriggerItem}>Export</Menu.TriggerItem>
            <Portal>
              <Menu.Positioner>
                <Menu.Content className={styles.Content}>
                  <Menu.Item className={styles.Item} value="pdf">
                    PDF
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="png">
                    PNG
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="svg">
                    SVG
                  </Menu.Item>
                </Menu.Content>
              </Menu.Positioner>
            </Portal>
          </Menu.Root>
          <Menu.Root>
            <Menu.TriggerItem className={styles.TriggerItem}>Share</Menu.TriggerItem>
            <Portal>
              <Menu.Positioner>
                <Menu.Content className={styles.Content}>
                  <Menu.Item className={styles.Item} value="email">
                    Email
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="message">
                    Message
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="airdrop">
                    AirDrop
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test1">
                    Test1
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test2">
                    Test2
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test3">
                    Test3
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test4">
                    Test4
                  </Menu.Item>
                </Menu.Content>
              </Menu.Positioner>
            </Portal>
          </Menu.Root>
          <Menu.Root>
            <Menu.TriggerItem className={styles.TriggerItem}>Share</Menu.TriggerItem>
            <Portal>
              <Menu.Positioner>
                <Menu.Content className={styles.Content}>
                  <Menu.Item className={styles.Item} value="email">
                    Email
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="message">
                    Message
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="airdrop">
                    AirDrop
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test1">
                    Test1
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test2">
                    Test2
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test3">
                    Test3
                  </Menu.Item>
                  <Menu.Item className={styles.Item} value="test4">
                    Test4
                  </Menu.Item>
                </Menu.Content>
              </Menu.Positioner>
            </Portal>
          </Menu.Root>
          <Menu.Separator className={styles.Separator} />
          <Menu.Item className={styles.Item} value="print">
            Print...
          </Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Portal>
  </Menu.Root>
)
```

### Menu in Dialog

When rendering a menu inside a dialog, use `lazyMount` and `unmountOnExit` to ensure proper cleanup when the dialog
closes.

```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Menu } from '@ark-ui/react/menu'
import { Portal } from '@ark-ui/react/portal'
import { ChevronDownIcon, XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import dialog from 'styles/dialog.module.css'
import styles from 'styles/menu.module.css'

export const MenuInDialog = () => (
  <Dialog.Root>
    <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={dialog.Backdrop} />
      <Dialog.Positioner className={dialog.Positioner}>
        <Dialog.Content className={dialog.Content}>
          <Dialog.Title className={dialog.Title}>Settings</Dialog.Title>
          <Dialog.Description className={dialog.Description}>Configure your preferences below.</Dialog.Description>
          <Dialog.CloseTrigger className={dialog.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <div className={dialog.Body}>
            <Menu.Root lazyMount unmountOnExit>
              <Menu.Trigger className={styles.Trigger}>
                Select theme
                <Menu.Indicator className={styles.Indicator}>
                  <ChevronDownIcon />
                </Menu.Indicator>
              </Menu.Trigger>
              <Portal>
                <Menu.Positioner>
                  <Menu.Content className={styles.Content}>
                    <Menu.Arrow className={styles.Arrow}>
                      <Menu.ArrowTip className={styles.ArrowTip} />
                    </Menu.Arrow>
                    <Menu.Item className={styles.Item} value="light">
                      Light
                    </Menu.Item>
                    <Menu.Item className={styles.Item} value="dark">
                      Dark
                    </Menu.Item>
                    <Menu.Item className={styles.Item} value="system">
                      System
                    </Menu.Item>
                  </Menu.Content>
                </Menu.Positioner>
              </Portal>
            </Menu.Root>
          </div>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)
```

### Menu Item Dialog

Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require
user confirmation.

```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Menu } from '@ark-ui/react/menu'
import { Portal } from '@ark-ui/react/portal'
import { ChevronDownIcon, XIcon } from 'lucide-react'
import { useState } from 'react'
import button from 'styles/button.module.css'
import dialog from 'styles/dialog.module.css'
import styles from 'styles/menu.module.css'

export const MenuItemDialog = () => {
  const [dialogOpen, setDialogOpen] = useState(false)

  return (
    <>
      <Menu.Root>
        <Menu.Trigger className={styles.Trigger}>
          Actions
          <Menu.Indicator className={styles.Indicator}>
            <ChevronDownIcon />
          </Menu.Indicator>
        </Menu.Trigger>
        <Portal>
          <Menu.Positioner>
            <Menu.Content className={styles.Content}>
              <Menu.Item className={styles.Item} value="edit">
                Edit
              </Menu.Item>
              <Menu.Item className={styles.Item} value="duplicate">
                Duplicate
              </Menu.Item>
              <Menu.Separator className={styles.Separator} />
              <Menu.Item className={styles.Item} value="delete" onClick={() => setDialogOpen(true)}>
                Delete...
              </Menu.Item>
            </Menu.Content>
          </Menu.Positioner>
        </Portal>
      </Menu.Root>

      <Dialog.Root open={dialogOpen} onOpenChange={(e) => setDialogOpen(e.open)} role="alertdialog">
        <Portal>
          <Dialog.Backdrop className={dialog.Backdrop} />
          <Dialog.Positioner className={dialog.Positioner}>
            <Dialog.Content className={dialog.Content}>
              <Dialog.Title className={dialog.Title}>Confirm Delete</Dialog.Title>
              <Dialog.Description className={dialog.Description}>
                Are you sure you want to delete this item? This action cannot be undone.
              </Dialog.Description>
              <Dialog.CloseTrigger className={dialog.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <div className={dialog.Actions}>
                <button className={button.Root} onClick={() => setDialogOpen(false)}>
                  Cancel
                </button>
                <button className={button.Root} data-variant="solid" onClick={() => setDialogOpen(false)}>
                  Delete
                </button>
              </div>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.Root>
    </>
  )
}
```

### Multiple Triggers

Share a single menu across multiple trigger elements. Pass a `value` to each `Menu.Trigger` — the menu repositions to
whichever trigger is activated.

```tsx
import { Menu } from '@ark-ui/react/menu'
import { Portal } from '@ark-ui/react/portal'
import { EllipsisVerticalIcon } from 'lucide-react'
import styles from 'styles/menu.module.css'

interface Message {
  id: string
  sender: string
  preview: string
}

const messages: Message[] = [
  { id: '1', sender: 'Alice Johnson', preview: 'Hey, can you review the latest PR?' },
  { id: '2', sender: 'Bob Smith', preview: 'Meeting notes from today are attached.' },
  { id: '3', sender: 'Carol Davis', preview: 'The deploy finished successfully!' },
]

export const MultipleTriggers = () => (
  <Menu.Root positioning={{ placement: 'right-start' }}>
    <div className={styles.MessageList}>
      {messages.map((msg) => (
        <div key={msg.id} className={styles.MessageItem}>
          <div className={styles.MessageContent}>
            <div className={styles.MessageSender}>{msg.sender}</div>
            <div className={styles.MessagePreview}>{msg.preview}</div>
          </div>
          <Menu.Trigger value={msg.id} className={styles.MessageAction}>
            <EllipsisVerticalIcon />
          </Menu.Trigger>
        </div>
      ))}
    </div>
    <Portal>
      <Menu.Positioner className={styles.Positioner}>
        <Menu.Content className={styles.Content}>
          <Menu.Item className={styles.Item} value="reply">
            Reply
          </Menu.Item>
          <Menu.Item className={styles.Item} value="forward">
            Forward
          </Menu.Item>
          <Menu.Item className={styles.Item} value="archive">
            Archive
          </Menu.Item>
          <Menu.Separator className={styles.Separator} />
          <Menu.Item className={styles.Item} value="delete">
            Delete
          </Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Portal>
  </Menu.Root>
)
```

## Guides

### Custom IDs

Ark UI autogenerates ids for menu items internally. Passing a custom `id` prop breaks the internal `getElementById`
functionality used by the component.

```tsx
// ❌ Don't do this
<Menu.Item id="custom-id" value="custom-value">
  Custom Item
</Menu.Item>

// ✅ Do this
<Menu.Item value="custom-value">
  Custom Item
</Menu.Item>
```

### Links

To render a menu item as a link, render the link as the menu item itself using the `asChild` prop, not as a child of the
menu item.

> This pattern ensures the link element receives the correct ARIA attributes and keyboard interactions from the menu
> item.

Here's an example of a reusable `MenuItemLink` component:

```tsx
interface MenuItemLinkProps extends Menu.ItemProps {
  href?: string
  target?: string
}

export const MenuItemLink = (props: MenuItemLinkProps) => {
  const { href, target, children, ...rest } = props
  return (
    <Menu.Item {...rest} asChild>
      <a href={href} target={target}>
        {children}
      </a>
    </Menu.Item>
  )
}
```

## API Reference

### Props

### Root

#### Props

**`anchorPoint`**
Type: `Point`
Required: false
Default Value: `undefined`
Description: The positioning point for the menu. Can be set by the context menu trigger or the button trigger.

**`aria-label`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The accessibility label for the menu

**`closeOnSelect`**
Type: `boolean`
Required: false
Default Value: `true`
Description: Whether to close the menu when an option is selected

**`composite`**
Type: `boolean`
Required: false
Default Value: `true`
Description: Whether the menu is a composed with other composite widgets like a combobox or tabs

**`defaultHighlightedValue`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The initial highlighted value of the menu item when rendered.
Use when you don't need to control the highlighted value of the menu item.

**`defaultOpen`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: The initial open state of the menu when rendered.
Use when you don't need to control the open state of the menu.

**`defaultTriggerValue`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The initial trigger value when rendered.
Use when you don't need to control the trigger value.

**`hideMode`**
Type: `HideMode`
Required: false
Default Value: `'display-none'`
Description: How to hide content when mounted but not present.
- `'display-none'`: HTML `hidden` attribute. Effects stay alive.
- `'activity'`: React 19 `<Activity mode="hidden">`. Effects pause. Requires React 19+.

**`highlightedValue`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The controlled highlighted value of the menu item.

**`id`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The unique identifier of the machine.

**`ids`**
Type: `Partial<{
  trigger: string | ((value?: string | undefined) => string)
  contextTrigger: string | ((value?: string | undefined) => string)
  content: string
  groupLabel: (id: string) => string
  group: (id: string) => string
  positioner: string
  arrow: string
}>`
Required: false
Default Value: `undefined`
Description: The ids of the elements in the menu. Useful for composition.

**`immediate`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether to synchronize the present change immediately or defer it to the next frame

**`lazyMount`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to enable lazy mounting

**`loopFocus`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to loop the keyboard navigation.

**`navigate`**
Type: `(details: NavigateDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to navigate to the selected item if it's an anchor element

**`onEscapeKeyDown`**
Type: `(event: KeyboardEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when the escape key is pressed

**`onExitComplete`**
Type: `VoidFunction`
Required: false
Default Value: `undefined`
Description: Function called when the animation ends in the closed state

**`onFocusOutside`**
Type: `(event: FocusOutsideEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when the focus is moved outside the component

**`onHighlightChange`**
Type: `(details: HighlightChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function called when the highlighted menu item changes.

**`onInteractOutside`**
Type: `(event: InteractOutsideEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when an interaction happens outside the component

**`onOpenChange`**
Type: `(details: OpenChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function called when the menu opens or closes

**`onPointerDownOutside`**
Type: `(event: PointerDownOutsideEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when the pointer is pressed down outside the component

**`onRequestDismiss`**
Type: `(event: LayerDismissEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when this layer is closed due to a parent layer being closed

**`onSelect`**
Type: `(details: SelectionDetails) => void`
Required: false
Default Value: `undefined`
Description: Function called when a menu item is selected.

**`onTriggerValueChange`**
Type: `(details: TriggerValueChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function called when the trigger value changes.

**`open`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: The controlled open state of the menu

**`positioning`**
Type: `PositioningOptions`
Required: false
Default Value: `undefined`
Description: The options used to dynamically position the menu

**`present`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the node is present (controlled by the user)

**`skipAnimationOnMount`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to allow the initial presence animation.

**`triggerValue`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The controlled trigger value

**`typeahead`**
Type: `boolean`
Required: false
Default Value: `true`
Description: Whether the pressing printable characters should trigger typeahead navigation

**`unmountOnExit`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to unmount on exit.

### Arrow

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### ArrowTip

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### CheckboxItem

#### Props

**`checked`**
Type: `boolean`
Required: true
Default Value: `undefined`
Description: Whether the option is checked

**`value`**
Type: `string`
Required: true
Default Value: `undefined`
Description: The value of the option

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`closeOnSelect`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the menu should be closed when the option is selected.

**`disabled`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the menu item is disabled

**`onCheckedChange`**
Type: `(checked: boolean) => void`
Required: false
Default Value: `undefined`
Description: Function called when the option state is changed

**`valueText`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The textual value of the option. Used in typeahead navigation of the menu.
If not provided, the text content of the menu item will be used.

### Content

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: content
**`data-state`**: "open" | "closed"
**`data-nested`**: menu
**`data-has-nested`**: menu
**`data-placement`**: The placement of the content
**`data-side`**: The side of the trigger that the content is positioned on

### ContextTrigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: context-trigger
**`data-value`**: The value of the item
**`data-current`**: Present when current
**`data-state`**: "open" | "closed"

### Indicator

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: indicator
**`data-state`**: "open" | "closed"

### ItemGroupLabel

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### ItemGroup

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### ItemIndicator

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: item-indicator
**`data-disabled`**: Present when disabled
**`data-highlighted`**: Present when highlighted
**`data-state`**: "checked"

### Item

#### Props

**`value`**
Type: `string`
Required: true
Default Value: `undefined`
Description: The unique value of the menu item option.

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`closeOnSelect`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the menu should be closed when the option is selected.

**`disabled`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the menu item is disabled

**`onSelect`**
Type: `VoidFunction`
Required: false
Default Value: `undefined`
Description: The function to call when the item is selected

**`valueText`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The textual value of the option. Used in typeahead navigation of the menu.
If not provided, the text content of the menu item will be used.

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: item
**`data-disabled`**: Present when disabled
**`data-highlighted`**: Present when highlighted
**`data-value`**: The value of the item
**`data-valuetext`**: The human-readable value

### ItemText

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: item-text
**`data-disabled`**: Present when disabled
**`data-highlighted`**: Present when highlighted
**`data-state`**: "checked"

### Positioner

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### RadioItemGroup

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`onValueChange`**
Type: `(e: ValueChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: undefined

**`value`**
Type: `string`
Required: false
Default Value: `undefined`
Description: undefined

### RadioItem

#### Props

**`value`**
Type: `string`
Required: true
Default Value: `undefined`
Description: The value of the option

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`closeOnSelect`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the menu should be closed when the option is selected.

**`disabled`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the menu item is disabled

**`valueText`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The textual value of the option. Used in typeahead navigation of the menu.
If not provided, the text content of the menu item will be used.

### RootProvider

#### Props

**`value`**
Type: `UseMenuReturn`
Required: true
Default Value: `undefined`
Description: undefined

**`hideMode`**
Type: `HideMode`
Required: false
Default Value: `'display-none'`
Description: How to hide content when mounted but not present.
- `'display-none'`: HTML `hidden` attribute. Effects stay alive.
- `'activity'`: React 19 `<Activity mode="hidden">`. Effects pause. Requires React 19+.

**`immediate`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether to synchronize the present change immediately or defer it to the next frame

**`lazyMount`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to enable lazy mounting

**`onExitComplete`**
Type: `VoidFunction`
Required: false
Default Value: `undefined`
Description: Function called when the animation ends in the closed state

**`present`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the node is present (controlled by the user)

**`skipAnimationOnMount`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to allow the initial presence animation.

**`unmountOnExit`**
Type: `boolean`
Required: false
Default Value: `false`
Description: Whether to unmount on exit.

### Separator

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### TriggerItem

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Trigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`value`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The value that identifies this specific trigger

#### Data Attributes

**`data-scope`**: menu
**`data-part`**: trigger
**`data-placement`**: The placement of the trigger
**`data-side`**: The side of the trigger that the trigger is positioned on
**`data-value`**: The value of the item
**`data-current`**: Present when current
**`data-controls`**: 
**`data-state`**: "open" | "closed"

### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `open` | `boolean` | Whether the menu is open |
| `setOpen` | `(open: boolean) => void` | Function to open or close the menu |
| `triggerValue` | `string | null` | The trigger value |
| `setTriggerValue` | `(value: string | null) => void` | Function to set the trigger value |
| `highlightedValue` | `string | null` | The id of the currently highlighted menuitem |
| `setHighlightedValue` | `(value: string) => void` | Function to set the highlighted menuitem |
| `setParent` | `(parent: MenuService) => void` | Function to register a parent menu. This is used for submenus |
| `setChild` | `(child: MenuService) => void` | Function to register a child menu. This is used for submenus |
| `reposition` | `(options?: Partial<PositioningOptions>) => void` | Function to reposition the popover |
| `getOptionItemState` | `(props: OptionItemProps) => OptionItemState` | Returns the state of the option item |
| `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the menu item |
| `addItemListener` | `(props: ItemListenerProps) => VoidFunction | undefined` | Setup the custom event listener for item selection event |


## Accessibility

Complies with the [Menu WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/).

### Keyboard Support

**`Space`**
Description: Activates/Selects the highlighted item

**`Enter`**
Description: Activates/Selects the highlighted item

**`ArrowDown`**
Description: Highlights the next item in the menu

**`ArrowUp`**
Description: Highlights the previous item in the menu

**`ArrowRight + ArrowLeft`**
Description: <span>When focus is on trigger, opens or closes the submenu depending on reading direction.</span>

**`Esc`**
Description: Closes the menu and moves focus to the trigger