# Menu

A button that opens a list of actions, such as rename or archive. For choosing a value, use [Dropdown](/components/dropdown.md); for site navigation, use [Navigation menu](/components/navigation-menu.md).

```tsx
// demo.tsx
import {Button, Menu, Stack, Text} from '@earendil-works/elanor-react';
import {useState} from 'react';

export default function MenuDemo() {
  const [action, setAction] = useState('No action selected.');

  return (
    <Stack gap="small">
      <Menu.Root>
        <Menu.Trigger render={<Button hierarchy="secondary" />}>Project actions</Menu.Trigger>
        <Menu.Portal>
          <Menu.Positioner>
            <Menu.Popup>
              <Menu.Item onClick={() => setAction('Selected: Rename.')}>Rename</Menu.Item>
              <Menu.Item onClick={() => setAction('Selected: Duplicate.')}>Duplicate</Menu.Item>
              <Menu.Item onClick={() => setAction('Selected: Archive.')}>Archive</Menu.Item>
            </Menu.Popup>
          </Menu.Positioner>
        </Menu.Portal>
      </Menu.Root>
      <Text role="status">{action}</Text>
    </Stack>
  );
}
```

## Usage

```tsx
import {Menu} from '@earendil-works/elanor-react';

<Menu.Root>
  <Menu.Trigger />
  <Menu.Portal>
    <Menu.Positioner>
      <Menu.Popup>
        <Menu.Item />
      </Menu.Popup>
    </Menu.Positioner>
  </Menu.Portal>
</Menu.Root>;
```

Choosing an item closes the menu. Run the action in the item's `onClick`.

## Icons and links

`icon` adds a decorative icon before the label and `endAdornment` adds one after it. `Menu.LinkItem` navigates to `href` instead of running an action.

```tsx
// icons.tsx
import {ContentCopyIcon, EditIcon, OpenInNewIcon} from '@earendil-works/elanor-icons-react';
import {Button, Menu} from '@earendil-works/elanor-react';

export default function MenuIcons() {
  return (
    <Menu.Root>
      <Menu.Trigger render={<Button hierarchy="secondary" />}>Project actions</Menu.Trigger>
      <Menu.Portal>
        <Menu.Positioner>
          <Menu.Popup>
            <Menu.Item icon={<EditIcon />}>Rename</Menu.Item>
            <Menu.Item icon={<ContentCopyIcon />}>Duplicate</Menu.Item>
            <Menu.LinkItem href="#" endAdornment={<OpenInNewIcon />}>
              Open in new tab
            </Menu.LinkItem>
          </Menu.Popup>
        </Menu.Positioner>
      </Menu.Portal>
    </Menu.Root>
  );
}
```

## Groups

`Group` and `GroupLabel` name related items; `Separator` draws a line between groups.

```tsx
// groups.tsx
import {Button, Menu} from '@earendil-works/elanor-react';

export default function MenuGroups() {
  return (
    <Menu.Root>
      <Menu.Trigger render={<Button hierarchy="secondary" />}>Project actions</Menu.Trigger>
      <Menu.Portal>
        <Menu.Positioner>
          <Menu.Popup>
            <Menu.Group>
              <Menu.GroupLabel>Edit</Menu.GroupLabel>
              <Menu.Item>Rename</Menu.Item>
              <Menu.Item>Duplicate</Menu.Item>
            </Menu.Group>
            <Menu.Separator />
            <Menu.Group>
              <Menu.GroupLabel>Manage</Menu.GroupLabel>
              <Menu.Item>Archive</Menu.Item>
              <Menu.Item>Delete</Menu.Item>
            </Menu.Group>
          </Menu.Popup>
        </Menu.Positioner>
      </Menu.Portal>
    </Menu.Root>
  );
}
```

## API

### `Menu.Root`

Accepts Base UI [`Menu.Root`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Trigger`

Accepts Base UI [`Menu.Trigger`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Portal`

Accepts Base UI [`Menu.Portal`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Positioner`

Accepts Base UI [`Menu.Positioner`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Popup`

Accepts Base UI [`Menu.Popup`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Item`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | - | The item label. |
| `icon` | `ReactNode` | - | Decorative icon before the label. |
| `endAdornment` | `ReactNode` | - | Content after the label, such as an icon. |

Also accepts Base UI [`Menu.Item`](https://base-ui.com/react/components/menu.md) props.

### `Menu.LinkItem`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | - | The item label. |
| `icon` | `ReactNode` | - | Decorative icon before the label. |
| `endAdornment` | `ReactNode` | - | Content after the label, such as an icon. |

Also accepts Base UI [`Menu.LinkItem`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Group`

Accepts Base UI [`Menu.Group`](https://base-ui.com/react/components/menu.md) props.

### `Menu.GroupLabel`

Accepts Base UI [`Menu.GroupLabel`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Separator`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `orientation` | `'horizontal'` | - | Only horizontal is supported. |

Also accepts Base UI [`Menu`](https://base-ui.com/react/components/menu.md) props.

### `Menu.Viewport`

Accepts Base UI [`Menu.Viewport`](https://base-ui.com/react/components/menu.md) props.
