# 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.

---

<ComponentPreview id="Menu" />

## Anatomy

<Anatomy id="menu" />

```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

**Example: basic**

#### React

```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>
)

```

#### Solid

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon } from 'lucide-vue-next'
import styles from 'styles/menu.module.css'
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      File
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content :class="styles.Content">
        <Menu.Arrow :class="styles.Arrow">
          <Menu.ArrowTip :class="styles.ArrowTip" />
        </Menu.Arrow>
        <Menu.Item :class="styles.Item" value="new-file">New File</Menu.Item>
        <Menu.Item :class="styles.Item" value="open">Open...</Menu.Item>
        <Menu.Item :class="styles.Item" value="save">Save</Menu.Item>
        <Menu.Item :class="styles.Item" value="save-as">Save As...</Menu.Item>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { ChevronDownIcon } from 'lucide-svelte'
  import styles from 'styles/menu.module.css'
</script>

<Menu.Root>
  <Menu.Trigger class={styles.Trigger}>
    File
    <Menu.Indicator class={styles.Indicator}>
      <ChevronDownIcon />
    </Menu.Indicator>
  </Menu.Trigger>
  <Menu.Positioner>
    <Menu.Content class={styles.Content}>
      <Menu.Arrow class={styles.Arrow}>
        <Menu.ArrowTip class={styles.ArrowTip} />
      </Menu.Arrow>
      <Menu.Item class={styles.Item} value="new-file">New File</Menu.Item>
      <Menu.Item class={styles.Item} value="open">Open...</Menu.Item>
      <Menu.Item class={styles.Item} value="save">Save</Menu.Item>
      <Menu.Item class={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`.

**Example: controlled**

#### React

```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>
  )
}

```

#### Solid

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

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon } from 'lucide-vue-next'
import { ref } from 'vue'
import button from 'styles/button.module.css'
import styles from 'styles/menu.module.css'

const open = ref(false)
</script>

<template>
  <div class="stack">
    <button type="button" :class="button.Root" @click="open = !open">Toggle</button>
    <Menu.Root v-model:open="open">
      <Menu.Trigger :class="styles.Trigger">
        Actions
        <Menu.Indicator :class="styles.Indicator">
          <ChevronDownIcon />
        </Menu.Indicator>
      </Menu.Trigger>
      <Menu.Positioner>
        <Menu.Content :class="styles.Content">
          <Menu.Item :class="styles.Item" value="edit">Edit</Menu.Item>
          <Menu.Item :class="styles.Item" value="duplicate">Duplicate</Menu.Item>
          <Menu.Item :class="styles.Item" value="archive">Archive</Menu.Item>
          <Menu.Item :class="styles.Item" value="delete">Delete</Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Menu.Root>
  </div>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { ChevronDownIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import styles from 'styles/menu.module.css'

  let open = $state(false)
</script>

<div class="stack">
  <button type="button" class={button.Root} onclick={() => (open = !open)}>Toggle</button>
  <Menu.Root bind:open>
    <Menu.Trigger class={styles.Trigger}>
      Actions
      <Menu.Indicator class={styles.Indicator}>
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content class={styles.Content}>
        <Menu.Item class={styles.Item} value="edit">Edit</Menu.Item>
        <Menu.Item class={styles.Item} value="duplicate">Duplicate</Menu.Item>
        <Menu.Item class={styles.Item} value="archive">Archive</Menu.Item>
        <Menu.Item class={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.

**Example: root-provider**

#### React

```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>
  )
}

```

#### Solid

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

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu, useMenu } from '@ark-ui/vue/menu'
import { ChevronDownIcon } from 'lucide-vue-next'
import button from 'styles/button.module.css'
import styles from 'styles/menu.module.css'

const menu = useMenu()
</script>

<template>
  <div class="stack">
    <button :class="button.Root" @click="menu.api.value.setHighlightedValue('copy')">Highlight Copy</button>
    <Menu.RootProvider :value="menu">
      <Menu.Trigger :class="styles.Trigger">
        Edit
        <Menu.Indicator :class="styles.Indicator">
          <ChevronDownIcon />
        </Menu.Indicator>
      </Menu.Trigger>
      <Menu.Positioner>
        <Menu.Content :class="styles.Content">
          <Menu.Item :class="styles.Item" value="cut">Cut</Menu.Item>
          <Menu.Item :class="styles.Item" value="copy">Copy</Menu.Item>
          <Menu.Item :class="styles.Item" value="paste">Paste</Menu.Item>
          <Menu.Item :class="styles.Item" value="delete">Delete</Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Menu.RootProvider>
  </div>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu, useMenu } from '@ark-ui/svelte/menu'
  import { ChevronDownIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import styles from 'styles/menu.module.css'

  const menu = useMenu()
</script>

<div class="stack">
  <button class={button.Root} onclick={() => menu().api.setHighlightedValue('copy')}>Highlight Copy</button>
  <Menu.RootProvider value={menu}>
    <Menu.Trigger class={styles.Trigger}>
      Edit
      <Menu.Indicator class={styles.Indicator}>
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content class={styles.Content}>
        <Menu.Item class={styles.Item} value="cut">Cut</Menu.Item>
        <Menu.Item class={styles.Item} value="copy">Copy</Menu.Item>
        <Menu.Item class={styles.Item} value="paste">Paste</Menu.Item>
        <Menu.Item class={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.

**Example: group**

#### React

```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>
)

```

#### Solid

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon } from 'lucide-vue-next'
import styles from 'styles/menu.module.css'
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      Edit
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content :class="styles.Content">
        <Menu.ItemGroup :class="styles.ItemGroup">
          <Menu.ItemGroupLabel :class="styles.ItemGroupLabel">Clipboard</Menu.ItemGroupLabel>
          <Menu.Item :class="styles.Item" value="cut">Cut</Menu.Item>
          <Menu.Item :class="styles.Item" value="copy">Copy</Menu.Item>
          <Menu.Item :class="styles.Item" value="paste">Paste</Menu.Item>
        </Menu.ItemGroup>
        <Menu.ItemGroup :class="styles.ItemGroup">
          <Menu.ItemGroupLabel :class="styles.ItemGroupLabel">Selection</Menu.ItemGroupLabel>
          <Menu.Item :class="styles.Item" value="select-all">Select All</Menu.Item>
          <Menu.Item :class="styles.Item" value="deselect">Deselect</Menu.Item>
        </Menu.ItemGroup>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { ChevronDownIcon } from 'lucide-svelte'
  import styles from 'styles/menu.module.css'
</script>

<Menu.Root>
  <Menu.Trigger class={styles.Trigger}>
    Edit
    <Menu.Indicator class={styles.Indicator}>
      <ChevronDownIcon />
    </Menu.Indicator>
  </Menu.Trigger>
  <Menu.Positioner>
    <Menu.Content class={styles.Content}>
      <Menu.ItemGroup class={styles.ItemGroup}>
        <Menu.ItemGroupLabel class={styles.ItemGroupLabel}>Clipboard</Menu.ItemGroupLabel>
        <Menu.Item class={styles.Item} value="cut">Cut</Menu.Item>
        <Menu.Item class={styles.Item} value="copy">Copy</Menu.Item>
        <Menu.Item class={styles.Item} value="paste">Paste</Menu.Item>
      </Menu.ItemGroup>
      <Menu.ItemGroup class={styles.ItemGroup}>
        <Menu.ItemGroupLabel class={styles.ItemGroupLabel}>Selection</Menu.ItemGroupLabel>
        <Menu.Item class={styles.Item} value="select-all">Select All</Menu.Item>
        <Menu.Item class={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.

**Example: links**

#### React

```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>
)

```

#### Solid

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon } from 'lucide-vue-next'
import styles from 'styles/menu.module.css'
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      Help
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content :class="styles.Content">
        <Menu.Item :class="styles.Item" value="docs" as-child>
          <a href="https://ark-ui.com">Documentation</a>
        </Menu.Item>
        <Menu.Item :class="styles.Item" value="github" as-child>
          <a href="https://github.com/chakra-ui/ark">GitHub</a>
        </Menu.Item>
        <Menu.Separator :class="styles.Separator" />
        <Menu.Item :class="styles.Item" value="changelog" as-child>
          <a href="https://github.com/chakra-ui/ark/releases">Changelog</a>
        </Menu.Item>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { ChevronDownIcon } from 'lucide-svelte'
  import styles from 'styles/menu.module.css'
</script>

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

```

### Checkbox

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

**Example: checkbox-items**

#### React

```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>
  )
}

```

#### Solid

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

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { CheckIcon, ChevronDownIcon } from 'lucide-vue-next'
import { ref } from 'vue'
import styles from 'styles/menu.module.css'

const showToolbar = ref(true)
const showStatusBar = ref(false)
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      View
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content :class="styles.Content">
        <Menu.CheckboxItem :class="styles.CheckboxItem" v-model:checked="showToolbar" value="toolbar">
          <Menu.ItemIndicator :class="styles.ItemIndicator">
            <CheckIcon />
          </Menu.ItemIndicator>
          <Menu.ItemText :class="styles.ItemText">Show Toolbar</Menu.ItemText>
        </Menu.CheckboxItem>
        <Menu.CheckboxItem :class="styles.CheckboxItem" v-model:checked="showStatusBar" value="status-bar">
          <Menu.ItemIndicator :class="styles.ItemIndicator">
            <CheckIcon />
          </Menu.ItemIndicator>
          <Menu.ItemText :class="styles.ItemText">Show Status Bar</Menu.ItemText>
        </Menu.CheckboxItem>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { CheckIcon, ChevronDownIcon } from 'lucide-svelte'
  import styles from 'styles/menu.module.css'

  let showToolbar = $state(true)
  let showStatusBar = $state(false)
</script>

<Menu.Root>
  <Menu.Trigger class={styles.Trigger}>
    View
    <Menu.Indicator class={styles.Indicator}>
      <ChevronDownIcon />
    </Menu.Indicator>
  </Menu.Trigger>
  <Menu.Positioner>
    <Menu.Content class={styles.Content}>
      <Menu.CheckboxItem class={styles.CheckboxItem} bind:checked={showToolbar} value="toolbar">
        <Menu.ItemIndicator class={styles.ItemIndicator}>
          <CheckIcon />
        </Menu.ItemIndicator>
        <Menu.ItemText class={styles.ItemText}>Show Toolbar</Menu.ItemText>
      </Menu.CheckboxItem>
      <Menu.CheckboxItem class={styles.CheckboxItem} bind:checked={showStatusBar} value="status-bar">
        <Menu.ItemIndicator class={styles.ItemIndicator}>
          <CheckIcon />
        </Menu.ItemIndicator>
        <Menu.ItemText class={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.

**Example: radio-items**

#### React

```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>
  )
}

```

#### Solid

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

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { CheckIcon, ChevronDownIcon } from 'lucide-vue-next'
import { ref } from 'vue'
import styles from 'styles/menu.module.css'

const sortBy = ref('date')
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      Sort
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Menu.Positioner>
      <Menu.Content :class="styles.Content">
        <Menu.RadioItemGroup :class="styles.ItemGroup" v-model="sortBy">
          <Menu.ItemGroupLabel :class="styles.ItemGroupLabel">Sort By</Menu.ItemGroupLabel>
          <Menu.RadioItem :class="styles.RadioItem" value="name">
            <Menu.ItemIndicator :class="styles.ItemIndicator">
              <CheckIcon />
            </Menu.ItemIndicator>
            <Menu.ItemText :class="styles.ItemText">Name</Menu.ItemText>
          </Menu.RadioItem>
          <Menu.RadioItem :class="styles.RadioItem" value="date">
            <Menu.ItemIndicator :class="styles.ItemIndicator">
              <CheckIcon />
            </Menu.ItemIndicator>
            <Menu.ItemText :class="styles.ItemText">Date Modified</Menu.ItemText>
          </Menu.RadioItem>
          <Menu.RadioItem :class="styles.RadioItem" value="size">
            <Menu.ItemIndicator :class="styles.ItemIndicator">
              <CheckIcon />
            </Menu.ItemIndicator>
            <Menu.ItemText :class="styles.ItemText">Size</Menu.ItemText>
          </Menu.RadioItem>
          <Menu.RadioItem :class="styles.RadioItem" value="type">
            <Menu.ItemIndicator :class="styles.ItemIndicator">
              <CheckIcon />
            </Menu.ItemIndicator>
            <Menu.ItemText :class="styles.ItemText">Type</Menu.ItemText>
          </Menu.RadioItem>
        </Menu.RadioItemGroup>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { CheckIcon, ChevronDownIcon } from 'lucide-svelte'
  import styles from 'styles/menu.module.css'

  let sortBy = $state('date')
</script>

<Menu.Root>
  <Menu.Trigger class={styles.Trigger}>
    Sort
    <Menu.Indicator class={styles.Indicator}>
      <ChevronDownIcon />
    </Menu.Indicator>
  </Menu.Trigger>
  <Menu.Positioner>
    <Menu.Content class={styles.Content}>
      <Menu.RadioItemGroup class={styles.ItemGroup} bind:value={sortBy}>
        <Menu.ItemGroupLabel class={styles.ItemGroupLabel}>Sort By</Menu.ItemGroupLabel>
        <Menu.RadioItem class={styles.RadioItem} value="name">
          <Menu.ItemIndicator class={styles.ItemIndicator}>
            <CheckIcon />
          </Menu.ItemIndicator>
          <Menu.ItemText class={styles.ItemText}>Name</Menu.ItemText>
        </Menu.RadioItem>
        <Menu.RadioItem class={styles.RadioItem} value="date">
          <Menu.ItemIndicator class={styles.ItemIndicator}>
            <CheckIcon />
          </Menu.ItemIndicator>
          <Menu.ItemText class={styles.ItemText}>Date Modified</Menu.ItemText>
        </Menu.RadioItem>
        <Menu.RadioItem class={styles.RadioItem} value="size">
          <Menu.ItemIndicator class={styles.ItemIndicator}>
            <CheckIcon />
          </Menu.ItemIndicator>
          <Menu.ItemText class={styles.ItemText}>Size</Menu.ItemText>
        </Menu.RadioItem>
        <Menu.RadioItem class={styles.RadioItem} value="type">
          <Menu.ItemIndicator class={styles.ItemIndicator}>
            <CheckIcon />
          </Menu.ItemIndicator>
          <Menu.ItemText class={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.

**Example: context**

#### React

```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>
)

```

#### Solid

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import styles from 'styles/menu.module.css'
</script>

<template>
  <Menu.Root>
    <Menu.ContextTrigger :class="styles.ContextTrigger">Right click here</Menu.ContextTrigger>
    <Menu.Positioner>
      <Menu.Content :class="styles.Content">
        <Menu.Item :class="styles.Item" value="cut">Cut</Menu.Item>
        <Menu.Item :class="styles.Item" value="copy">Copy</Menu.Item>
        <Menu.Item :class="styles.Item" value="paste">Paste</Menu.Item>
        <Menu.Separator :class="styles.Separator" />
        <Menu.Item :class="styles.Item" value="delete">Delete</Menu.Item>
      </Menu.Content>
    </Menu.Positioner>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import styles from 'styles/menu.module.css'
</script>

<Menu.Root>
  <Menu.ContextTrigger class={styles.ContextTrigger}>Right click here</Menu.ContextTrigger>
  <Menu.Positioner>
    <Menu.Content class={styles.Content}>
      <Menu.Item class={styles.Item} value="cut">Cut</Menu.Item>
      <Menu.Item class={styles.Item} value="copy">Copy</Menu.Item>
      <Menu.Item class={styles.Item} value="paste">Paste</Menu.Item>
      <Menu.Separator class={styles.Separator} />
      <Menu.Item class={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.

**Example: nested**

#### React

```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>
)

```

#### Solid

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

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

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon } from 'lucide-vue-next'
import { Teleport } from 'vue'
import styles from 'styles/menu.module.css'
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      File
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Teleport to="body">
      <Menu.Positioner>
        <Menu.Content :class="styles.Content">
          <Menu.Item :class="styles.Item" value="new">New File</Menu.Item>
          <Menu.Item :class="styles.Item" value="open">Open...</Menu.Item>
          <Menu.Separator :class="styles.Separator" />
          <Menu.Root>
            <Menu.TriggerItem :class="styles.TriggerItem">Share</Menu.TriggerItem>
            <Teleport to="body">
              <Menu.Positioner>
                <Menu.Content :class="styles.Content">
                  <Menu.Item :class="styles.Item" value="email">Email</Menu.Item>
                  <Menu.Item :class="styles.Item" value="message">Message</Menu.Item>
                  <Menu.Item :class="styles.Item" value="airdrop">AirDrop</Menu.Item>
                </Menu.Content>
              </Menu.Positioner>
            </Teleport>
          </Menu.Root>
          <Menu.Root>
            <Menu.TriggerItem :class="styles.TriggerItem">Export</Menu.TriggerItem>
            <Teleport to="body">
              <Menu.Positioner>
                <Menu.Content :class="styles.Content">
                  <Menu.Item :class="styles.Item" value="pdf">PDF</Menu.Item>
                  <Menu.Item :class="styles.Item" value="png">PNG</Menu.Item>
                  <Menu.Item :class="styles.Item" value="svg">SVG</Menu.Item>
                </Menu.Content>
              </Menu.Positioner>
            </Teleport>
          </Menu.Root>
          <Menu.Separator :class="styles.Separator" />
          <Menu.Item :class="styles.Item" value="print">Print...</Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Teleport>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { Portal } from '@ark-ui/svelte/portal'
  import { ChevronDownIcon } from 'lucide-svelte'
  import styles from 'styles/menu.module.css'
</script>

<Menu.Root>
  <Menu.Trigger class={styles.Trigger}>
    File
    <Menu.Indicator class={styles.Indicator}>
      <ChevronDownIcon />
    </Menu.Indicator>
  </Menu.Trigger>
  <Portal>
    <Menu.Positioner>
      <Menu.Content class={styles.Content}>
        <Menu.Item class={styles.Item} value="new">New File</Menu.Item>
        <Menu.Item class={styles.Item} value="open">Open...</Menu.Item>
        <Menu.Separator class={styles.Separator} />
        <Menu.Root>
          <Menu.TriggerItem class={styles.TriggerItem}>Share</Menu.TriggerItem>
          <Portal>
            <Menu.Positioner>
              <Menu.Content class={styles.Content}>
                <Menu.Item class={styles.Item} value="email">Email</Menu.Item>
                <Menu.Item class={styles.Item} value="message">Message</Menu.Item>
                <Menu.Item class={styles.Item} value="airdrop">AirDrop</Menu.Item>
              </Menu.Content>
            </Menu.Positioner>
          </Portal>
        </Menu.Root>
        <Menu.Root>
          <Menu.TriggerItem class={styles.TriggerItem}>Export</Menu.TriggerItem>
          <Portal>
            <Menu.Positioner>
              <Menu.Content class={styles.Content}>
                <Menu.Item class={styles.Item} value="pdf">PDF</Menu.Item>
                <Menu.Item class={styles.Item} value="png">PNG</Menu.Item>
                <Menu.Item class={styles.Item} value="svg">SVG</Menu.Item>
              </Menu.Content>
            </Menu.Positioner>
          </Portal>
        </Menu.Root>
        <Menu.Separator class={styles.Separator} />
        <Menu.Item class={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.

**Example: menu-in-dialog**

#### React

```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>
)

```

#### Solid

```tsx
import { Dialog } from '@ark-ui/solid/dialog'
import { Menu } from '@ark-ui/solid/menu'
import { ChevronDownIcon, XIcon } from 'lucide-solid'
import { Portal } from 'solid-js/web'
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 class={button.Root}>Open Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop class={dialog.Backdrop} />
      <Dialog.Positioner class={dialog.Positioner}>
        <Dialog.Content class={dialog.Content}>
          <Dialog.Title class={dialog.Title}>Settings</Dialog.Title>
          <Dialog.Description class={dialog.Description}>Configure your preferences below.</Dialog.Description>
          <Dialog.CloseTrigger class={dialog.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <div class={dialog.Body}>
            <Menu.Root lazyMount unmountOnExit>
              <Menu.Trigger class={styles.Trigger}>
                Select theme
                <Menu.Indicator class={styles.Indicator}>
                  <ChevronDownIcon />
                </Menu.Indicator>
              </Menu.Trigger>
              <Portal>
                <Menu.Positioner>
                  <Menu.Content class={styles.Content}>
                    <Menu.Arrow class={styles.Arrow}>
                      <Menu.ArrowTip class={styles.ArrowTip} />
                    </Menu.Arrow>
                    <Menu.Item class={styles.Item} value="light">
                      Light
                    </Menu.Item>
                    <Menu.Item class={styles.Item} value="dark">
                      Dark
                    </Menu.Item>
                    <Menu.Item class={styles.Item} value="system">
                      System
                    </Menu.Item>
                  </Menu.Content>
                </Menu.Positioner>
              </Portal>
            </Menu.Root>
          </div>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Dialog } from '@ark-ui/vue/dialog'
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon, XIcon } from 'lucide-vue-next'
import { Teleport } from 'vue'
import button from 'styles/button.module.css'
import dialog from 'styles/dialog.module.css'
import styles from 'styles/menu.module.css'
</script>

<template>
  <Dialog.Root>
    <Dialog.Trigger :class="button.Root">Open Dialog</Dialog.Trigger>
    <Teleport to="body">
      <Dialog.Backdrop :class="dialog.Backdrop" />
      <Dialog.Positioner :class="dialog.Positioner">
        <Dialog.Content :class="dialog.Content">
          <Dialog.Title :class="dialog.Title">Settings</Dialog.Title>
          <Dialog.Description :class="dialog.Description">Configure your preferences below.</Dialog.Description>
          <Dialog.CloseTrigger :class="dialog.CloseTrigger">
            <XIcon />
          </Dialog.CloseTrigger>
          <div :class="dialog.Body">
            <Menu.Root lazy-mount unmount-on-exit>
              <Menu.Trigger :class="styles.Trigger">
                Select theme
                <Menu.Indicator :class="styles.Indicator">
                  <ChevronDownIcon />
                </Menu.Indicator>
              </Menu.Trigger>
              <Teleport to="body">
                <Menu.Positioner>
                  <Menu.Content :class="styles.Content">
                    <Menu.Arrow :class="styles.Arrow">
                      <Menu.ArrowTip :class="styles.ArrowTip" />
                    </Menu.Arrow>
                    <Menu.Item :class="styles.Item" value="light">Light</Menu.Item>
                    <Menu.Item :class="styles.Item" value="dark">Dark</Menu.Item>
                    <Menu.Item :class="styles.Item" value="system">System</Menu.Item>
                  </Menu.Content>
                </Menu.Positioner>
              </Teleport>
            </Menu.Root>
          </div>
        </Dialog.Content>
      </Dialog.Positioner>
    </Teleport>
  </Dialog.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Dialog } from '@ark-ui/svelte/dialog'
  import { Menu } from '@ark-ui/svelte/menu'
  import { Portal } from '@ark-ui/svelte/portal'
  import { ChevronDownIcon, XIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import dialog from 'styles/dialog.module.css'
  import styles from 'styles/menu.module.css'
</script>

<Dialog.Root>
  <Dialog.Trigger class={button.Root}>Open Dialog</Dialog.Trigger>
  <Portal>
    <Dialog.Backdrop class={dialog.Backdrop} />
    <Dialog.Positioner class={dialog.Positioner}>
      <Dialog.Content class={dialog.Content}>
        <Dialog.Title class={dialog.Title}>Settings</Dialog.Title>
        <Dialog.Description class={dialog.Description}>Configure your preferences below.</Dialog.Description>
        <Dialog.CloseTrigger class={dialog.CloseTrigger}>
          <XIcon />
        </Dialog.CloseTrigger>
        <div class={dialog.Body}>
          <Menu.Root lazyMount unmountOnExit>
            <Menu.Trigger class={styles.Trigger}>
              Select theme
              <Menu.Indicator class={styles.Indicator}>
                <ChevronDownIcon />
              </Menu.Indicator>
            </Menu.Trigger>
            <Portal>
              <Menu.Positioner>
                <Menu.Content class={styles.Content}>
                  <Menu.Arrow class={styles.Arrow}>
                    <Menu.ArrowTip class={styles.ArrowTip} />
                  </Menu.Arrow>
                  <Menu.Item class={styles.Item} value="light">Light</Menu.Item>
                  <Menu.Item class={styles.Item} value="dark">Dark</Menu.Item>
                  <Menu.Item class={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.

**Example: menu-item-dialog**

#### React

```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>
    </>
  )
}

```

#### Solid

```tsx
import { Dialog } from '@ark-ui/solid/dialog'
import { Menu } from '@ark-ui/solid/menu'
import { ChevronDownIcon, XIcon } from 'lucide-solid'
import { createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
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] = createSignal(false)

  return (
    <>
      <Menu.Root>
        <Menu.Trigger class={styles.Trigger}>
          Actions
          <Menu.Indicator class={styles.Indicator}>
            <ChevronDownIcon />
          </Menu.Indicator>
        </Menu.Trigger>
        <Portal>
          <Menu.Positioner>
            <Menu.Content class={styles.Content}>
              <Menu.Item class={styles.Item} value="edit">
                Edit
              </Menu.Item>
              <Menu.Item class={styles.Item} value="duplicate">
                Duplicate
              </Menu.Item>
              <Menu.Separator class={styles.Separator} />
              <Menu.Item class={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 class={dialog.Backdrop} />
          <Dialog.Positioner class={dialog.Positioner}>
            <Dialog.Content class={dialog.Content}>
              <Dialog.Title class={dialog.Title}>Confirm Delete</Dialog.Title>
              <Dialog.Description class={dialog.Description}>
                Are you sure you want to delete this item? This action cannot be undone.
              </Dialog.Description>
              <Dialog.CloseTrigger class={dialog.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <div class={dialog.Actions}>
                <button class={button.Root} onClick={() => setDialogOpen(false)}>
                  Cancel
                </button>
                <button class={button.Root} data-variant="solid" onClick={() => setDialogOpen(false)}>
                  Delete
                </button>
              </div>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.Root>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Dialog } from '@ark-ui/vue/dialog'
import { Menu } from '@ark-ui/vue/menu'
import { ChevronDownIcon, XIcon } from 'lucide-vue-next'
import { ref, Teleport } from 'vue'
import button from 'styles/button.module.css'
import dialog from 'styles/dialog.module.css'
import styles from 'styles/menu.module.css'

const dialogOpen = ref(false)
</script>

<template>
  <Menu.Root>
    <Menu.Trigger :class="styles.Trigger">
      Actions
      <Menu.Indicator :class="styles.Indicator">
        <ChevronDownIcon />
      </Menu.Indicator>
    </Menu.Trigger>
    <Teleport to="body">
      <Menu.Positioner>
        <Menu.Content :class="styles.Content">
          <Menu.Item :class="styles.Item" value="edit">Edit</Menu.Item>
          <Menu.Item :class="styles.Item" value="duplicate">Duplicate</Menu.Item>
          <Menu.Separator :class="styles.Separator" />
          <Menu.Item :class="styles.Item" value="delete" @click="dialogOpen = true">Delete...</Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Teleport>
  </Menu.Root>

  <Dialog.Root v-model:open="dialogOpen" role="alertdialog">
    <Teleport to="body">
      <Dialog.Backdrop :class="dialog.Backdrop" />
      <Dialog.Positioner :class="dialog.Positioner">
        <Dialog.Content :class="dialog.Content">
          <Dialog.Title :class="dialog.Title">Confirm Delete</Dialog.Title>
          <Dialog.Description :class="dialog.Description">
            Are you sure you want to delete this item? This action cannot be undone.
          </Dialog.Description>
          <Dialog.CloseTrigger :class="dialog.CloseTrigger">
            <XIcon />
          </Dialog.CloseTrigger>
          <div :class="dialog.Actions">
            <button :class="button.Root" @click="dialogOpen = false">Cancel</button>
            <button :class="button.Root" data-variant="solid" @click="dialogOpen = false">Delete</button>
          </div>
        </Dialog.Content>
      </Dialog.Positioner>
    </Teleport>
  </Dialog.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Dialog } from '@ark-ui/svelte/dialog'
  import { Menu } from '@ark-ui/svelte/menu'
  import { Portal } from '@ark-ui/svelte/portal'
  import { ChevronDownIcon, XIcon } from 'lucide-svelte'
  import button from 'styles/button.module.css'
  import dialog from 'styles/dialog.module.css'
  import styles from 'styles/menu.module.css'

  let dialogOpen = $state(false)
</script>

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

<Dialog.Root bind:open={dialogOpen} role="alertdialog">
  <Portal>
    <Dialog.Backdrop class={dialog.Backdrop} />
    <Dialog.Positioner class={dialog.Positioner}>
      <Dialog.Content class={dialog.Content}>
        <Dialog.Title class={dialog.Title}>Confirm Delete</Dialog.Title>
        <Dialog.Description class={dialog.Description}>
          Are you sure you want to delete this item? This action cannot be undone.
        </Dialog.Description>
        <Dialog.CloseTrigger class={dialog.CloseTrigger}>
          <XIcon />
        </Dialog.CloseTrigger>
        <div class={dialog.Actions}>
          <button class={button.Root} onclick={() => (dialogOpen = false)}>Cancel</button>
          <button class={button.Root} data-variant="solid" onclick={() => (dialogOpen = 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.

**Example: multiple-triggers**

#### React

```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>
)

```

#### Solid

```tsx
import { Menu } from '@ark-ui/solid/menu'
import { Portal } from 'solid-js/web'
import { EllipsisVerticalIcon } from 'lucide-solid'
import { For } from 'solid-js'
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 class={styles.MessageList}>
      <For each={messages}>
        {(msg) => (
          <div class={styles.MessageItem}>
            <div class={styles.MessageContent}>
              <div class={styles.MessageSender}>{msg.sender}</div>
              <div class={styles.MessagePreview}>{msg.preview}</div>
            </div>
            <Menu.Trigger value={msg.id} class={styles.MessageAction}>
              <EllipsisVerticalIcon />
            </Menu.Trigger>
          </div>
        )}
      </For>
    </div>
    <Portal>
      <Menu.Positioner class={styles.Positioner}>
        <Menu.Content class={styles.Content}>
          <Menu.Item class={styles.Item} value="reply">
            Reply
          </Menu.Item>
          <Menu.Item class={styles.Item} value="forward">
            Forward
          </Menu.Item>
          <Menu.Item class={styles.Item} value="archive">
            Archive
          </Menu.Item>
          <Menu.Separator class={styles.Separator} />
          <Menu.Item class={styles.Item} value="delete">
            Delete
          </Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Portal>
  </Menu.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Menu } from '@ark-ui/vue/menu'
import { EllipsisVerticalIcon } from 'lucide-vue-next'
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!' },
]
</script>

<template>
  <Menu.Root :positioning="{ placement: 'right-start' }">
    <div :class="styles.MessageList">
      <div v-for="msg in messages" :key="msg.id" :class="styles.MessageItem">
        <div :class="styles.MessageContent">
          <div :class="styles.MessageSender">{{ msg.sender }}</div>
          <div :class="styles.MessagePreview">{{ msg.preview }}</div>
        </div>
        <Menu.Trigger :value="msg.id" :class="styles.MessageAction">
          <EllipsisVerticalIcon />
        </Menu.Trigger>
      </div>
    </div>
    <Teleport to="body">
      <Menu.Positioner :class="styles.Positioner">
        <Menu.Content :class="styles.Content">
          <Menu.Item :class="styles.Item" value="reply">Reply</Menu.Item>
          <Menu.Item :class="styles.Item" value="forward">Forward</Menu.Item>
          <Menu.Item :class="styles.Item" value="archive">Archive</Menu.Item>
          <Menu.Separator :class="styles.Separator" />
          <Menu.Item :class="styles.Item" value="delete">Delete</Menu.Item>
        </Menu.Content>
      </Menu.Positioner>
    </Teleport>
  </Menu.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Menu } from '@ark-ui/svelte/menu'
  import { Portal } from '@ark-ui/svelte/portal'
  import { EllipsisVerticalIcon } from 'lucide-svelte'
  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!' },
  ]
</script>

<Menu.Root positioning={{ placement: 'right-start' }}>
  <div class={styles.MessageList}>
    {#each messages as msg (msg.id)}
      <div class={styles.MessageItem}>
        <div class={styles.MessageContent}>
          <div class={styles.MessageSender}>{msg.sender}</div>
          <div class={styles.MessagePreview}>{msg.preview}</div>
        </div>
        <Menu.Trigger value={msg.id} class={styles.MessageAction}>
          <EllipsisVerticalIcon />
        </Menu.Trigger>
      </div>
    {/each}
  </div>
  <Portal>
    <Menu.Positioner class={styles.Positioner}>
      <Menu.Content class={styles.Content}>
        <Menu.Item class={styles.Item} value="reply">Reply</Menu.Item>
        <Menu.Item class={styles.Item} value="forward">Forward</Menu.Item>
        <Menu.Item class={styles.Item} value="archive">Archive</Menu.Item>
        <Menu.Separator class={styles.Separator} />
        <Menu.Item class={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

**Component API Reference**

#### React

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. |
| `aria-label` | `string` | No | The accessibility label for the menu |
| `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected |
| `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs |
| `defaultHighlightedValue` | `string` | No | 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` | `boolean` | No | The initial open state of the menu when rendered.
Use when you don't need to control the open state of the menu. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  trigger: string
  contextTrigger: string
  content: string
  groupLabel: (id: string) => string
  group: (id: string) => string
  positioner: string
  arrow: string
}>` | No | The ids of the elements in the menu. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element |
| `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed |
| `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. |
| `open` | `boolean` | No | The controlled open state of the menu |
| `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Arrow Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Arrow CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |


**ArrowTip Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**CheckboxItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `checked` | `boolean` | Yes | Whether the option is checked |
| `value` | `string` | Yes | The value of the option |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested menus |


**ContextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ContextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-indicator |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The unique value of the menu item option. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `onSelect` | `VoidFunction` | No | The function to call when the item is selected |
| `valueText` | `string` | No | 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. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-text |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RadioItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `onValueChange` | `(e: ValueChangeDetails) => void` | No |  |
| `value` | `string` | No |  |


**RadioItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the option |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseMenuReturn` | Yes |  |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Separator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TriggerItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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" |


#### Solid

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. |
| `aria-label` | `string` | No | The accessibility label for the menu |
| `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected |
| `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs |
| `defaultHighlightedValue` | `string` | No | 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` | `boolean` | No | The initial open state of the menu when rendered.
Use when you don't need to control the open state of the menu. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  trigger: string
  contextTrigger: string
  content: string
  groupLabel: (id: string) => string
  group: (id: string) => string
  positioner: string
  arrow: string
}>` | No | The ids of the elements in the menu. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element |
| `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed |
| `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. |
| `open` | `boolean` | No | The controlled open state of the menu |
| `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Arrow Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Arrow CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |


**ArrowTip Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**CheckboxItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `checked` | `boolean` | Yes | Whether the option is checked |
| `value` | `string` | Yes | The value of the option |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested menus |


**ContextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ContextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-indicator |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The unique value of the menu item option. |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `onSelect` | `VoidFunction` | No | The function to call when the item is selected |
| `valueText` | `string` | No | 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. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-text |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RadioItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `onValueChange` | `(e: ValueChangeDetails) => void` | No |  |
| `value` | `string` | No |  |


**RadioItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the option |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseMenuReturn` | Yes |  |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Separator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'hr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TriggerItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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" |


#### Vue

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. |
| `aria-label` | `string` | No | The accessibility label for the menu |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected |
| `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs |
| `defaultHighlightedValue` | `string` | No | 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` | `boolean` | No | The initial open state of the menu when rendered.
Use when you don't need to control the open state of the menu. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  trigger: string
  contextTrigger: string
  content: string
  groupLabel(id: string): string
  group(id: string): string
  positioner: string
  arrow: string
}>` | No | The ids of the elements in the menu. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element |
| `open` | `boolean` | No | The controlled open state of the menu |
| `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu |
| `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Arrow Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Arrow CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |


**ArrowTip Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**CheckboxItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `checked` | `boolean` | Yes | Whether the option is checked |
| `value` | `string` | Yes | The value of the option |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested menus |


**ContextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ContextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `id` | `string` | No | The `id` of the element that provides accessibility label to the option group |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-indicator |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The unique value of the menu item option. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `valueText` | `string` | No | 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. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-text |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RadioItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `id` | `string` | No |  |
| `modelValue` | `string` | No |  |


**RadioItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the option |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseMenuReturn` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Separator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**TriggerItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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" |


#### Svelte

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. |
| `aria-label` | `string` | No | The accessibility label for the menu |
| `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected |
| `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs |
| `defaultHighlightedValue` | `string` | No | 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` | `boolean` | No | The initial open state of the menu when rendered.
Use when you don't need to control the open state of the menu. |
| `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  trigger: string
  contextTrigger: string
  content: string
  groupLabel: (id: string) => string
  group: (id: string) => string
  positioner: string
  arrow: string
}>` | No | The ids of the elements in the menu. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. |
| `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element |
| `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed |
| `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. |
| `open` | `boolean` | No | The controlled open state of the menu |
| `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Arrow Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Arrow CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--arrow-size` | The size of the arrow |
| `--arrow-size-half` | Half the size of the arrow |
| `--arrow-background` | Use this variable to style the arrow background |
| `--arrow-offset` | The offset position of the arrow |


**ArrowTip Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**CheckboxItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `checked` | `boolean` | Yes | Whether the option is checked |
| `value` | `string` | Yes | The value of the option |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed |
| `ref` | `Element` | No |  |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |


**Content CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--layer-index` | The index of the dismissable in the layer stack |
| `--nested-layer-count` | The number of nested menus |


**Context Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseMenuContext]>` | Yes |  |


**ContextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ContextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |


**ItemContext Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseMenuItemContext]>` | Yes |  |


**ItemGroupLabel Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `id` | `string` | No | The `id` of the element that provides accessibility label to the option group |
| `ref` | `Element` | No |  |


**ItemIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemIndicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-indicator |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The unique value of the menu item option. |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `onSelect` | `VoidFunction` | No | The function to call when the item is selected |
| `ref` | `Element` | No |  |
| `valueText` | `string` | No | 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. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemText Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | menu |
| `[data-part]` | item-text |
| `[data-disabled]` | Present when disabled |
| `[data-highlighted]` | Present when highlighted |
| `[data-state]` | "checked" |


**Positioner Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Positioner CSS Variables:**

| Variable | Description |
|----------|-------------|
| `--reference-width` | The width of the reference element |
| `--reference-height` | The height of the root |
| `--available-width` | The available width in viewport |
| `--available-height` | The available height in viewport |
| `--x` | The x position for transform |
| `--y` | The y position for transform |
| `--z-index` | The z-index value |
| `--transform-origin` | The transform origin for animations |


**RadioItemGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `id` | `string` | No |  |
| `onValueChange` | `(e: ValueChangeDetails) => void` | No |  |
| `ref` | `Element` | No |  |
| `value` | `string` | No |  |


**RadioItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `string` | Yes | The value of the option |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. |
| `disabled` | `boolean` | No | Whether the menu item is disabled |
| `ref` | `Element` | No |  |
| `valueText` | `string` | No | 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:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseMenuReturn` | Yes |  |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Separator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**TriggerItem Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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

<KeyBindingsTable id="menu" />