Skip to content

Menu

A button that opens a list of actions, such as rename or archive. For choosing a value, use Dropdown; for site navigation, use Navigation menu.

No action selected.

Code
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

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.

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

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

Code
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 props.

Menu.Trigger

Accepts Base UI Menu.Trigger props.

Menu.Portal

Accepts Base UI Menu.Portal props.

Menu.Positioner

Accepts Base UI Menu.Positioner props.

Menu.Popup

Accepts Base UI Menu.Popup props.

Menu.Item

PropTypeDefaultDescription
childrenReactNode-The item label.
iconReactNode-Decorative icon before the label.
endAdornmentReactNode-Content after the label, such as an icon.

Also accepts Base UI Menu.Item props.

Menu.LinkItem

PropTypeDefaultDescription
childrenReactNode-The item label.
iconReactNode-Decorative icon before the label.
endAdornmentReactNode-Content after the label, such as an icon.

Also accepts Base UI Menu.LinkItem props.

Menu.Group

Accepts Base UI Menu.Group props.

Menu.GroupLabel

Accepts Base UI Menu.GroupLabel props.

Menu.Separator

PropTypeDefaultDescription
orientation'horizontal'-Only horizontal is supported.

Also accepts Base UI Menu props.

Menu.Viewport

Accepts Base UI Menu.Viewport props.