---
title: Menu
description: A list of actions behind a button.
---

```tsx
import { Button, Menu } from "@openperf/deft";

import { Preview } from "../../src/Preview";

export default function MenuBasic() {
  return (
    <Preview overlay={true}>
      <Menu.Root>
        <Menu.Trigger render={<Button.Root />}>Open menu</Menu.Trigger>
        <Menu.Content>
          {Array.from({ length: 3 }, (_, index) => (
            <Menu.Item key={index}>Item {index + 1}</Menu.Item>
          ))}
        </Menu.Content>
      </Menu.Root>
    </Preview>
  );
}
```

- Use a menu for secondary actions that don't fit in a toolbar. To pick a value for a form, use a [Select](/deft/components/select).
- Separate groups of ordinary actions with `Menu.Separator`.
- Put the destructive action last and set `tone="danger"` on it.
- In menus opened from the [action bar](/deft/components/action-bar), set `size="sm"` on every item to match its smaller buttons.
- `Menu.CheckboxItem` keeps the menu open on click, so several options can be toggled in a row.

## Item content

```tsx
import { Button, Menu } from "@openperf/deft";
import { IconPlus } from "@tabler/icons-react";

import { Preview } from "../../src/Preview";

export default function MenuItemContent() {
  return (
    <Preview overlay={true}>
      <Menu.Root>
        <Menu.Trigger render={<Button.Root />}>Open menu</Menu.Trigger>
        <Menu.Content>
          <Menu.Item>
            <IconPlus />
            Item 1
          </Menu.Item>
          <Menu.Item description="Description">Item 2</Menu.Item>
          <Menu.Item trailing="12">Item 3</Menu.Item>
        </Menu.Content>
      </Menu.Root>
    </Preview>
  );
}
```

Render an icon as the first child to make a familiar action easier to scan, and add a `description` only when the action needs more context. Put a keyboard shortcut or a count in `trailing`, kept secondary to the label. Icons take the item tone, including `danger`.

## Radio groups

```tsx
import { Button, Menu } from "@openperf/deft";

import { Preview } from "../../src/Preview";

export default function MenuRadioGroups() {
  return (
    <Preview overlay={true}>
      <Menu.Root>
        <Menu.Trigger render={<Button.Root />}>Open menu</Menu.Trigger>
        <Menu.Content>
          <Menu.RadioGroup defaultValue="option-1">
            <Menu.GroupLabel>Label</Menu.GroupLabel>
            {Array.from({ length: 3 }, (_, index) => (
              <Menu.RadioItem key={index} value={`option-${index + 1}`}>
                Option {index + 1}
              </Menu.RadioItem>
            ))}
          </Menu.RadioGroup>
        </Menu.Content>
      </Menu.Root>
    </Preview>
  );
}
```

Use `Menu.RadioGroup` for mutually exclusive choices; the selected item shows a check on the right. `Menu.GroupLabel` names the choice set, such as **Sort by**. Use separators rather than labels for groups of ordinary actions.

## API

| Prop | Type | Default | Description |
| - | - | - | - |
| `align?` | `"start" \| "center" \| "end"` | `"start"` | On Content. |
| `side?` | `"top" \| "bottom" \| "left" \| "right" \| "inline-start" \| "inline-end"` | `"bottom"` | On Content. |
| `sideOffset?` | `number` | `4` | On Content. |
| `tone?` | `"default" \| "danger"` | `"default"` | On Item. |
| `size?` | `"sm" \| "md"` | `"md"` | On Item, CheckboxItem and RadioItem. |
| `description?` | `ReactNode` | - | On Item, CheckboxItem, RadioItem and SubmenuTrigger. A second line in muted text. |
| `trailing?` | `ReactNode` | - | On Item and CheckboxItem. A shortcut or count on the right. |
| `closeOnClick?` | `boolean` | `false` | On CheckboxItem. |

Parts: `Root`, `CheckboxItem`, `Content`, `Footer`, `GroupLabel`, `Item`, `RadioItem`, `Separator`, `SubmenuTrigger`, plus the other Base UI Menu parts, such as `Trigger`, `RadioGroup`, `Group` and `SubmenuRoot`. `Content` wraps `Portal`, `Positioner` and `Popup`; `Footer` passes its props to the native `div`. Built on Base UI [Menu](https://base-ui.com/react/components/menu).
