# Menu
> Component for displaying lists of links or actions that the user can take.

## Import

```js
import { Menu } from '@gemini-suite/vera-react';

// you may also access Menu's context via hook:
// import { useMenuContext } from '@gemini-suite/vera-react';
```

Menu is a compound component that consists of multiple parts to help you create all kinds of menus:

- `Menu.Root`: The wrapper that contains all the parts of a menu and provides context for its children.
- `Menu.Trigger`: The trigger that toggles the menu.
- `Menu.Icon`: The default chevron icon used as an open/close indicator.
- `Menu.ContextTrigger`: A wrapper around the target area that opens the context menu upon right-clicking.
- `Menu.Content`: The container that pops out when the menu is open.
- `Menu.Group`: The container used to group multiple, related menu items.
- `Menu.Label`: The component that renders the label of <InlineCode>Menu.Group</InlineCode>.
- `Menu.Item`: A single item of the menu.
- `Menu.CheckboxItem`: A single item of the menu that acts as a checkbox.
- `Menu.RadioGroup`: A wrapper for a group of mutually exclusive radio menu items.
- `Menu.RadioItem`: A single item of the menu that acts as a radio button and participates in a <InlineCode>Menu.RadioGroup</InlineCode>.
- `Menu.Separator`: The component that renders a horizontal divider between menu items and groups.

## Examples

### Basic

`Menu` works in an uncontrolled way by default, meaning each `Menu` component instance is responsible for managing its own state internally.

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
    {'Open Menu'}
  </Menu.Trigger>
  <Menu.Content>
    <Menu.Item onSelect={event => console.log('First')}>{'First'}</Menu.Item>
    <Menu.Item>{'Second'}</Menu.Item>
    <Menu.Item>{'Third'}</Menu.Item>
  </Menu.Content>
</Menu.Root>
```

### Controlled Menu

You can easily make the menu controlled, by passing your own state to `isOpen` prop. `onIsOpenChange` handler is called when the state of the menu changes, allowing you to sync state.

```jsx
() => {
  const [isOpen, setIsOpen] = React.useState(false);

  return (
    <Menu.Root isOpen={isOpen} onIsOpenChange={setIsOpen}>
      <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
        {isOpen ? 'Close Menu' : 'Open Menu'}
      </Menu.Trigger>
      <Menu.Content>
        <Menu.Item onSelect={event => console.log('First')}>
          {'First'}
        </Menu.Item>
        <Menu.Item>{'Second'}</Menu.Item>
        <Menu.Item>{'Third'}</Menu.Item>
      </Menu.Content>
    </Menu.Root>
  );
};
```

### Menu items

Use the `Menu.Item` component to configure `Menu` options.

By passing the `startElement` prop, you can add icon to each `Menu.Item` to help clarify the intent of the item's action. To add a command (or hotkey) to menu item, you can use the `endElement` prop.

Use `onSelect` handler that is triggered on click and <Kbd>enter</Kbd> + <Kbd>space</Kbd> key down to add interactivity to the `Menu.Item`.

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
    {'Open Menu'}
  </Menu.Trigger>
  <Menu.Content>
    <Menu.Item
      startElement={<SvgIcon iconName="add" />}
      endElement={<Kbd>⌘N</Kbd>}
      onSelect={() => alert('New file')}
    >
      {'New file'}
    </Menu.Item>
    <Menu.Item
      startElement={<SvgIcon iconName="copy" />}
      onSelect={() => alert('Copy file')}
    >
      {'Copy file'}
    </Menu.Item>
    <Menu.Item
      startElement={<SvgIcon iconName="edit" />}
      endElement={<Kbd>⌘E</Kbd>}
      onSelect={() => alert('Edit file')}
    >
      {'Edit file'}
    </Menu.Item>
  </Menu.Content>
</Menu.Root>
```

To prevent the user from interacting with the `Menu.Item`, use `isDisabled` property.
This will make the item unselectable via keyboard navigation, and it will be skipped when pressing the up/down arrows.

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
    {'Open Menu'}
  </Menu.Trigger>
  <Menu.Content>
    <Menu.Item startElement={<SvgIcon iconName="add" />}>
      {'New file'}
    </Menu.Item>
    <Menu.Item
      isDisabled
      startElement={<SvgIcon iconName="copy" />}
      onSelect={() => alert('Copy file')}
    >
      {'Copy file'}
    </Menu.Item>
    <Menu.Item startElement={<SvgIcon iconName="edit" />}>
      {'Edit file'}
    </Menu.Item>
  </Menu.Content>
</Menu.Root>
```

For destructive actions such as deleting something, you can set the menu item's `intent` to `danger`.
When using this feature, you may want to consider providing a confirmation via a [Dialog component](/components/dialog).

```jsx
() => {
  const [isConfirmationOpen, setIsConfirmationOpen] = React.useState(false);
  const toastManager = useToastManager();

  return (
    <React.Fragment>
      <Menu.Root>
        <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
          {'Open Menu'}
        </Menu.Trigger>
        <Menu.Content>
          <Menu.Item startElement={<SvgIcon iconName="add" />}>
            {'New file'}
          </Menu.Item>
          <Menu.Item startElement={<SvgIcon iconName="copy" />}>
            {'Copy file'}
          </Menu.Item>
          <Menu.Item startElement={<SvgIcon iconName="edit" />}>
            {'Edit file'}
          </Menu.Item>
          <Menu.Separator />
          <Menu.Item
            startElement={<SvgIcon iconName="trash" />}
            intent="danger"
            onSelect={() => {
              setIsConfirmationOpen(true);
            }}
          >
            {'Delete file'}
          </Menu.Item>
        </Menu.Content>
      </Menu.Root>
      <Dialog.Root
        isOpen={isConfirmationOpen}
        onIsOpenChange={setIsConfirmationOpen}
      >
        <Dialog.Box width="22rem" css={{ padding: '$spacingM' }}>
          <Flex
            flow="column"
            cross="center"
            paddingTop="spacingL"
            paddingBottom="spacingXl"
          >
            <Box className="iconCircle iconCircle--medium fill-neutral">
              <SvgIcon iconName="help" size="medium" />
            </Box>
            <Dialog.Title className="delta">Delete file?</Dialog.Title>
          </Flex>
          <Flex main="space-between">
            <Dialog.Close as={Button} variant="ghost">
              {'Cancel'}
            </Dialog.Close>
            <Button
              color="danger"
              onClick={() => {
                setIsConfirmationOpen(false);

                toastManager.addToast({
                  message: 'File successfully deleted!',
                  type: 'success'
                });
              }}
            >
              {'Yes, delete'}
            </Button>
          </Flex>
        </Dialog.Box>
      </Dialog.Root>
    </React.Fragment>
  );
};
```

### Groups and labels

Related items can be grouped inside `Menu.Group`. Use `Menu.Label` component, to render an accessible label for the menu group.

<Callout variant="tip">

To visually divide groups of items in the menu, use `Menu.Separator` .

</Callout>

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline">
    {'Complex menu'}
  </Menu.Trigger>
  <Menu.Content>
    <Menu.Item onSelect={event => console.log('Share')}>{'Share'}</Menu.Item>
    <Menu.Item endElement={<Kbd>⌘M</Kbd>}>{'Move'}</Menu.Item>
    <Menu.Item endElement={<Kbd>⌘R</Kbd>}>{'Rename'}</Menu.Item>
    <Menu.Separator />
    <Menu.Group>
      <Menu.Label>Group with icons</Menu.Label>
      <Menu.Item startElement={<SvgIcon iconName="heart" />}>
        {'First item'}
      </Menu.Item>
      <Menu.Item startElement={<SvgIcon iconName="add" />}>
        {'Second Item'}
      </Menu.Item>
      <Menu.Item startElement={<SvgIcon iconName="user" />}>
        {'Third Item'}
      </Menu.Item>
      <Menu.Item startElement={<SvgIcon iconName="download" />}>
        {'Fourth item'}
      </Menu.Item>
    </Menu.Group>
    <Menu.Separator />
    <Menu.Group>
      <Menu.Label>A Group</Menu.Label>
      <Menu.Item>{'Fifth item'}</Menu.Item>
      <Menu.Item isDisabled>{'Sixth Item disabled'}</Menu.Item>
      <Menu.Item>{'Seventh Item'}</Menu.Item>
      <Menu.Item>{'Eight item with longer label'}</Menu.Item>
    </Menu.Group>
    <Menu.Separator />
    <Menu.Item
      startElement={
        <Avatar.Root of="Ulf Sindre" size="small">
          <Avatar.Initials />
        </Avatar.Root>
      }
    >
      {'Item with avatar'}
    </Menu.Item>
  </Menu.Content>
</Menu.Root>
```

### With a custom trigger

You can choose to have a different trigger for the `Menu` depending on the application's context.

```jsx
<Flex>
  <Menu.Root>
    <Menu.Trigger>
      <Avatar.Root of="Fritjof Snorre">
        <Avatar.Initials />
      </Avatar.Root>
    </Menu.Trigger>
    <Menu.Content>
      <Flex paddingY="spacingS" paddingX="spacingM">
        <Avatar.Root of="Fritjof Snorre">
          <Avatar.Initials />
        </Avatar.Root>
        <Box>
          {'Fritjof Snorre'}
          <Text as="div" variant="zeta" color="foregroundNeutralSubtle">
            {'snorre.fritjof@invera-tech.com'}
          </Text>
        </Box>
      </Flex>
      <Menu.Separator />
      <Menu.Item>My Settings</Menu.Item>
      <Menu.Item>System</Menu.Item>
      <Menu.Item>Configurations</Menu.Item>
      <Menu.Separator />
      <Menu.Item>Help & Feedback</Menu.Item>
      <Menu.Separator />
      <Menu.Item
        intent="danger"
        onSelect={() => {
          alert('Log Out');
        }}
      >
        Log Out
      </Menu.Item>
    </Menu.Content>
  </Menu.Root>
  <Menu.Root>
    <Menu.Trigger
      as={Button}
      variant="ghost"
      shape="circle"
      withLoneIcon
      aria-label="Open Menu"
    >
      <SvgIcon iconName="more" />
    </Menu.Trigger>
    <Menu.Content placement="right">
      <Menu.Item
        startElement={<SvgIcon iconName="edit" />}
        onSelect={event => console.log('Edit')}
      >
        {'Edit'}
      </Menu.Item>
      <Menu.Item startElement={<SvgIcon iconName="copy" />}>
        {'Duplicate'}
      </Menu.Item>
      <Menu.Separator />
      <Menu.Item startElement={<SvgIcon iconName="archive" />}>
        {'Archive'}
      </Menu.Item>
      <Menu.Item startElement={<SvgIcon iconName="externalLink" />}>
        {'Move'}
      </Menu.Item>
      <Menu.Separator />
      <Menu.Item
        startElement={<SvgIcon iconName="trash" />}
        endElement={<Kbd>⌘⇧D</Kbd>}
        intent="danger"
      >
        {'Delete'}
      </Menu.Item>
    </Menu.Content>
  </Menu.Root>
</Flex>
```

### Placement

By default the menu will be placed below your trigger if it can fit, but this can be customised via the `placement` prop.
For example, when the trigger is right-aligned within its container, you can set the `placement` to bottom right.

<Callout variant="tip">

`Menu` is using [Positioner](/components/utility/positioner) internally to dynamically position it's content based on the available space. The passed `position` might get overwritten by smart positioning when necessary.

</Callout>

```jsx
<Flex main="space-between">
  <Menu.Root>
    <Menu.Trigger as={Button} variant="outline">
      {'Bottom left menu'}
    </Menu.Trigger>
    <Menu.Content>
      <Menu.Item onSelect={event => console.log('First')}>{'First'}</Menu.Item>
      <Menu.Item>{'Second'}</Menu.Item>
      <Menu.Item>{'Third'}</Menu.Item>
    </Menu.Content>
  </Menu.Root>
  <Menu.Root>
    <Menu.Trigger as={Button} variant="outline">
      {'Bottom right menu'}
    </Menu.Trigger>
    <Menu.Content placement={Placement.BOTTOM_RIGHT}>
      <Menu.Item onSelect={event => console.log('First')}>{'First'}</Menu.Item>
      <Menu.Item>{'Second'}</Menu.Item>
      <Menu.Item>{'Third'}</Menu.Item>
    </Menu.Content>
  </Menu.Root>
</Flex>
```

### Sizes

Use the `size` prop to control the size of the `Menu.Content`. `medium` and `small` sizes are available, with the `medium` size used by default

```jsx
() => {
  const [branch, setBranch] = React.useState('main');

  return (
    <Flex>
      <Menu.Root>
        <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
          {'Actions'}
        </Menu.Trigger>
        <Menu.Content>
          <Menu.Item
            startElement={<SvgIcon iconName="arrowDown" />}
            endElement={<Kbd>⌘P</Kbd>}
          >
            {'Pull'}
          </Menu.Item>
          <Menu.Item
            startElement={<SvgIcon iconName="arrowUp" />}
            endElement={<Kbd>⇧⌘P</Kbd>}
          >
            {'Push'}
          </Menu.Item>
          <Menu.Separator />
          <Menu.Item startElement={<SvgIcon iconName="externalLink" />}>
            {'Open on Github'}
          </Menu.Item>
          <Menu.Separator />
          <Menu.Group>
            <Menu.Label>Branches</Menu.Label>
            <Menu.RadioGroup value={branch} onValueChange={setBranch}>
              <Menu.RadioItem value="main">main</Menu.RadioItem>
              <Menu.RadioItem value="develop">develop</Menu.RadioItem>
            </Menu.RadioGroup>
          </Menu.Group>
          <Menu.Separator />
          <Menu.Item
            startElement={<SvgIcon iconName="trash" />}
            intent="danger"
          >
            {'Delete repo'}
          </Menu.Item>
        </Menu.Content>
      </Menu.Root>
      <Menu.Root>
        <Menu.Trigger
          as={Button}
          variant="outline"
          size="small"
          rightIcon={<Menu.Icon />}
        >
          {'Actions'}
        </Menu.Trigger>
        <Menu.Content size="small">
          <Menu.Item
            startElement={<SvgIcon iconName="arrowDown" />}
            endElement={<Kbd>⌘P</Kbd>}
          >
            {'Pull'}
          </Menu.Item>
          <Menu.Item
            startElement={<SvgIcon iconName="arrowUp" />}
            endElement={<Kbd>⇧⌘P</Kbd>}
          >
            {'Push'}
          </Menu.Item>
          <Menu.Separator />
          <Menu.Item startElement={<SvgIcon iconName="externalLink" />}>
            {'Open on Github'}
          </Menu.Item>
          <Menu.Separator />
          <Menu.Group>
            <Menu.Label>Branches</Menu.Label>
            <Menu.RadioGroup value={branch} onValueChange={setBranch}>
              <Menu.RadioItem value="main">main</Menu.RadioItem>
              <Menu.RadioItem value="develop">develop</Menu.RadioItem>
            </Menu.RadioGroup>
          </Menu.Group>
          <Menu.Separator />
          <Menu.Item
            startElement={<SvgIcon iconName="trash" />}
            intent="danger"
          >
            {'Delete repo'}
          </Menu.Item>
        </Menu.Content>
      </Menu.Root>
    </Flex>
  );
};
```

### Item overflow

When there are many items in a menu it will grow to a maximum height and the overflowing items will be scrollable.

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline">
    {'Tall menu'}
  </Menu.Trigger>
  <Menu.Content>
    {Array.from({ length: 20 }, (_, i) => (
      <Menu.Item key={i}>One of many items</Menu.Item>
    ))}
  </Menu.Content>
</Menu.Root>
```

You can use `css` prop to control the `maxWidth` of the menu content. Long labels will be truncated to avoid blowing out the content.

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline">
    {'Truncated menu'}
  </Menu.Trigger>
  <Menu.Content css={{ maxWidth: '20rem' }}>
    <Menu.Item>
      Very long labels will be truncated when the max width is met
    </Menu.Item>
    <Menu.Item
      startElement={<SvgIcon iconName="user" />}
      endElement={<Kbd>⌘U</Kbd>}
    >
      Very long labels will be truncated when the max width is met
    </Menu.Item>
  </Menu.Content>
</Menu.Root>
```

### Typeahead search

When focus is on the `Menu.Trigger` or within the `Menu.Content` and you type a letter key, a search begins. Focus will move to the first `Menu.Item` that starts with the letter you typed.

<Callout variant="tip">

When user repeats typed character focus cycles among items that starts with the typed character. Try it with following example and repeatedly type character <Kbd>c</Kbd>.

</Callout>

<Callout variant="tip">

If the content of `Menu.Item` is too complex or non-textual, pass the `textValue` property to `Menu.Item` to indicate that the text will be used for typeahead purposes.

</Callout>

```jsx
<Menu.Root>
  <Menu.Trigger as={Button} variant="outline">
    {'Tools'}
  </Menu.Trigger>
  <Menu.Content placement="right">
    <Menu.Item
      startElement={<SvgIcon iconName="edit" />}
      onSelect={event => console.log('Edit')}
    >
      {'Edit'}
    </Menu.Item>
    <Menu.Item startElement={<SvgIcon iconName="copy" />}>{'Copy'}</Menu.Item>
    <Menu.Separator />
    <Menu.Item startElement={<SvgIcon iconName="archive" />}>
      {'Archive'}
    </Menu.Item>
    <Menu.Item startElement={<SvgIcon iconName="externalLink" />}>
      {'Move'}
    </Menu.Item>
    <Menu.Item startElement={<SvgIcon iconName="redo" />}>{'Cut'}</Menu.Item>
    <Menu.Separator />
    <Menu.Item
      startElement={<SvgIcon iconName="trash" />}
      endElement={<Kbd>⌘⇧D</Kbd>}
      intent="danger"
    >
      {'Delete'}
    </Menu.Item>
    <Menu.Separator />
    <Menu.Item textValue="custom">
      <Flex gap="spacingS">
        <Label>Label</Label>
        <Box>Custom item</Box>
      </Flex>
    </Menu.Item>
  </Menu.Content>
</Menu.Root>
```

### Context menu

To display a menu located at the pointer, triggered by a right-click or a long-press, wrap the area that should open the context menu with `Menu.ContextTrigger`.

```jsx
<Menu.Root>
  <Flex main="center">
    <Menu.ContextTrigger>
      <Box
        css={{
          width: '10rem',
          height: '10rem',
          display: 'grid',
          placeItems: 'center',
          border: '2px dashed $borderNeutralSubtle',
          borderRadius: '$m'
        }}
      >
        Right Click me
      </Box>
    </Menu.ContextTrigger>
  </Flex>
  <Menu.Content>
    <Menu.Item startElement={<SvgIcon iconName="edit" />}>{'Edit'}</Menu.Item>
    <Menu.Item startElement={<SvgIcon iconName="type" />}>{'Rename'}</Menu.Item>
    <Menu.Separator />
    <Menu.Item startElement={<SvgIcon iconName="trash" />} intent="danger">
      {'Delete'}
    </Menu.Item>
  </Menu.Content>
</Menu.Root>
```

### Single selection

You can render a list of menu items as radios to allow users to make a single selection.
Menu radio items must be used inside `Menu.RadioGroup`.

<Callout variant="tip">

Consider using specialized [Single Select Menu component](/components/forms/select-menu/single-select-menu) to handle selection.

`Menu` component is carrying accessibility/semantic of a [WAI-ARIA Menu Button
design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/), while [Single Select Menu](/components/forms/select-menu/single-select-menu) follows [WAI ARIA Listbox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/).

</Callout>

```jsx
() => {
  const [sortBy, setSortBy] = React.useState('popular');
  const [order, setOrder] = React.useState('0');

  return (
    <Flex>
      <Menu.Root>
        <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
          {'Sort by'} {sortBy ? <b>{sortBy}</b> : null}
        </Menu.Trigger>
        <Menu.Content>
          <Menu.RadioGroup value={sortBy} onValueChange={setSortBy}>
            <Menu.RadioItem value="popular">Popular</Menu.RadioItem>
            <Menu.RadioItem value="newest">Newest</Menu.RadioItem>
            <Menu.RadioItem value="oldest">Oldest</Menu.RadioItem>
          </Menu.RadioGroup>
        </Menu.Content>
      </Menu.Root>
      <Menu.Root>
        <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
          {'Order'}
        </Menu.Trigger>
        <Menu.Content>
          <Menu.RadioGroup value={order} onValueChange={setOrder}>
            <Menu.RadioItem
              value="1"
              startElement={<SvgIcon iconName="sortAsc" />}
            >
              Ascending
            </Menu.RadioItem>
            <Menu.RadioItem
              value="0"
              startElement={<SvgIcon iconName="sortDesc" />}
            >
              Descending
            </Menu.RadioItem>
          </Menu.RadioGroup>
        </Menu.Content>
      </Menu.Root>
    </Flex>
  );
};
```

### Multiple selection

You can render a list of menu items as checkboxes to allow users to select multiple items at a time.

<Callout variant="tip">

Consider using specialized [Multi Select Menu component](/components/forms/select-menu/multi-select-menu) to handle multi-selection.

</Callout>

```jsx
() => {
  const checkboxItems = [
    { label: 'Email', state: React.useState(false) },
    { label: 'Phone', state: React.useState(true) },
    { label: 'State', state: React.useState(false) },
    { label: 'Country', state: React.useState(false) },
    { label: 'Type', state: React.useState(false), isDisabled: true }
  ];

  return (
    <Menu.Root>
      <Menu.Trigger as={Button} variant="outline" rightIcon={<Menu.Icon />}>
        {'Show'}
      </Menu.Trigger>
      <Menu.Content>
        {checkboxItems.map(
          ({ label, state: [isChecked, setIsChecked], isDisabled }) => (
            <Menu.CheckboxItem
              key={label}
              isChecked={isChecked}
              onIsCheckedChange={setIsChecked}
              isDisabled={isDisabled}
            >
              {label}
            </Menu.CheckboxItem>
          )
        )}
      </Menu.Content>
    </Menu.Root>
  );
};
```

---

## Accessibility

**Menu** implements the [WAI-ARIA Menu Button
design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/).

<ul>
  <li iconName="check">

All relevant ARIA attributes are automatically managed.

  </li>
  <li iconName="check">

Menu trigger can be focused with <Kbd>Tab</Kbd> or <Kbd>Shift + Tab</Kbd>

  </li>
  <li iconName="check">

Mouse click, <Kbd>Space</Kbd>, <Kbd>Enter</Kbd> or <Kbd>↓</Kbd> opens the menu.

  </li>
  <li iconName="check">

After triggering the menu with keyboard, focus is set to the first menu item.

  </li>
  <li iconName="check">

Clicking outside the menu content or pressing <Kbd>ESC</Kbd> closes the menu and sets focus to the menu trigger.

  </li>
  <li iconName="check">

When menu is opened, <Kbd>↓</Kbd> and <Kbd>↑</Kbd> keys move the focus among non-disabled menu items. Focus movement is managed using [roving focus technique](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#x6-6-keyboard-navigation-inside-components).

  </li>
  <li iconName="check">

When menu is opened, <Kbd>Home</Kbd> and <Kbd>Page Up</Kbd> moves focus to the first item.

  </li>
  <li iconName="check">

When menu is opened, <Kbd>End</Kbd> and <Kbd>Page Down</Kbd> moves focus to the last item.

  </li>
  <li iconName="check">

<Kbd>Enter</Kbd> or <Kbd>Space</Kbd> activates the menu item and closes the
menu.

  </li>
  <li iconName="check">

When menu is opened, typing any printable character moves focus to the first menu item that matches the typed character. Typing multiple keys in quick succession results in moving focus to the first item that matches the full string. If the same character is typed in succession, focus cycles among the items starting with that character.

  </li>
  <li iconName="check">

When menu is opened and needs scrolling, scroll behavior is enclosed only to the opened menu.

  </li>
  <li iconName="check">

The menu content is portaled (via [Portal utility](/components/utility/portal)) to the end of `document.body` to break it out of the source order.

  </li>
</ul>

---

## API Reference

### Menu.Root

| Name             | Type                        | Default | Description                                                                                          | Required |
| ---------------- | --------------------------- | ------- | ---------------------------------------------------------------------------------------------------- | -------- |
| `isOpen`         | `boolean`                   | `false` | The controlled open state of the menu. Use in conjunction with `onIsOpenChange`.                     |          |
| `defaultIsOpen`  | `boolean`                   |         | The open state of the menu when it's first rendered. Use when you do not need to control open state. |          |
| `onIsOpenChange` | `(isOpen: boolean) => void` |         | Event handler called when the open state of the menu changes.                                        |          |

### Menu.Trigger

| Name  | Type                                                      | Default  | Description                                                                                                                                                                                                                                                                                  | Required |
| ----- | --------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `button` | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |          | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |

### Menu.ContextTrigger

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                  | Required |
| ----- | --------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `span`  | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |

### Menu.Icon

| Name  | Type          | Default | Description                                                                                                                                                                                                                                   | Required |
| ----- | ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `css` | `StitchesCss` |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants. |          |

### Menu.Content

| Name                   | Type                                                                                                     | Default         | Description                                                                                                                                                                                                                                                                                  | Required |
| ---------------------- | -------------------------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`                   | `keyof JSX.IntrinsicElements \| React.ComponentType<any>`                                                | `div`           | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css`                  | `StitchesCss`                                                                                            |                 | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |
| `placement`            | `"top" \| "top_left" \| "top_right" \| "bottom" \| "bottom_left" \| "bottom_right" \| "left" \| "right"` | `"bottom_left"` | Placement of the menu content. Smart positioning might override this.                                                                                                                                                                                                                        |          |
| `size`                 | `"small" \| "medium"`                                                                                    | `medium`        | The size of the menu content.                                                                                                                                                                                                                                                                |          |
| `anchorOffset`         | `number`                                                                                                 |                 | Distance from the trigger to the menu content.                                                                                                                                                                                                                                               |          |
| `onExitComplete`       | `() => void`                                                                                             | `() => void`    | Event handler called when the menu content has completed animating out.                                                                                                                                                                                                                      |          |
| `onPointerDownOutside` | `(event: Event) => void`                                                                                 |                 | Event handler called when a pointer event occurs outside the bounds of the menu content. It can be prevented with `event.preventDefault`.                                                                                                                                                    |          |
| `loop`                 | `boolean`                                                                                                | `false`         | When `true` keyboard focus will loop from last item to the first item, and vice versa.                                                                                                                                                                                                       |          |

### Menu.Group

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                  | Required |
| ----- | --------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |

### Menu.Label

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                  | Required |
| ----- | --------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |

### Menu.Item

| Name           | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                  | Required |
| -------------- | --------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`           | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css`          | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |
| `isDisabled`   | `boolean`                                                 | `false` | When `true`, the item will be disabled, preventing the user from interacting with it.                                                                                                                                                                                                        |          |
| `textValue`    | `string`                                                  |         | By default the typeahead behavior will use the `.textContent` of the item. When the content is complex or non-textual, this property can be used to specify text for the typeahead search purposes.                                                                                          |          |
| `onSelect`     | `(event: Event) => void`                                  |         | Event handler called when item is selected (via mouse or keyboard). Use this to perform actions. Calling `event.preventDefault` will prevent the menu from closing upon selection.                                                                                                           |          |
| `startElement` | `React.ReactElement`                                      |         | `ReactElement` to render to the left of the item's children.                                                                                                                                                                                                                                 |          |
| `endElement`   | `React.ReactElement`                                      |         | `ReactElement` to render to the right of the item's children.                                                                                                                                                                                                                                |          |
| `intent`       | `"danger"`                                                |         | Sets the visual intent of the item.                                                                                                                                                                                                                                                          |          |

### Menu.CheckboxItem

The `Menu.CheckboxItem` extends all the `Menu.Item` properties and adds the following ones:

| Name                | Type                           | Default | Description                                                                            | Required |
| ------------------- | ------------------------------ | ------- | -------------------------------------------------------------------------------------- | -------- |
| `isChecked`         | `boolean`                      |         | The controlled checked state of the item. Use in conjunction with `onIsCheckedChange`. |          |
| `onIsCheckedChange` | `(isChecked: boolean) => void` |         | Event handler called when the checked state changes.                                   |          |

### Menu.RadioGroup

The `Menu.RadioGroup` extends all the `Menu.Group` properties and adds the following ones:

| Name            | Type                      | Default | Description                                  | Required |
| --------------- | ------------------------- | ------- | -------------------------------------------- | -------- |
| `value`         | `string`                  |         | Value of the radio item.                     |          |
| `onValueChange` | `(value: string) => void` |         | Event handler called when the value changes. |          |

### Menu.RadioItem

The `Menu.RadioItem` extends all the `Menu.Item` properties and adds the following ones:

| Name    | Type     | Default | Description                  | Required |
| ------- | -------- | ------- | ---------------------------- | -------- |
| `value` | `string` |         | The value of the radio item. | Yes      |

### Menu.Separator

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                  | Required |
| ----- | --------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants.                                                |          |
