1
ComponentsOverlays

Menu

Menu presents grouped actions, choices, links, and submenus from a trigger button.

Purpose

Menu presents grouped actions, choices, links, and submenus from a trigger. Use form controls such as Select, Checkbox, or Switch when the value belongs to a form field.

Action menu

import { Menu, MenuItem, MenuPopup, MenuTrigger } from "@/components/ui/menu";
import { Button } from "@/components/ui/button";

export function Example() {
  return (
    <Menu>
      <MenuTrigger render={<Button variant="outline" />}>Actions</MenuTrigger>
      <MenuPopup><MenuItem>Duplicate</MenuItem></MenuPopup>
    </Menu>
  );
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/menu

Import

import { Menu, MenuCheckboxItem, MenuCreateHandle, MenuGroup, MenuGroupLabel, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, MenuSub, MenuSubPopup, MenuSubTrigger, MenuTrigger } from "@/components/ui/menu";

Need the machine-readable source metadata? View registry JSON.

Usage

Use Menu for action lists and lightweight selection behind a trigger. Use Select for form values.

import { Menu, MenuItem, MenuPopup, MenuTrigger } from "@/components/ui/menu";
import { Button } from "@/components/ui/button";

export function Example() {
  return (
    <Menu>
      <MenuTrigger render={<Button variant="outline" />}>Actions</MenuTrigger>
      <MenuPopup><MenuItem>Duplicate</MenuItem></MenuPopup>
    </Menu>
  );
}

Examples

Icons, shortcuts, groups, selection items, link items, submenus and popup width are props and compositions of the same primitive.

With icons and shortcuts

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>File</MenuTrigger>
  <MenuPopup aria-label="File actions">
    <MenuItem>
      <CopyIcon />
      Copy
      <MenuShortcut>⌘C</MenuShortcut>
    </MenuItem>
    <MenuItem>
      <ShareIcon />
      Share
      <MenuShortcut>⌘S</MenuShortcut>
    </MenuItem>
    <MenuItem disabled>
      <DownloadIcon />
      Export
      <MenuShortcut>⌘E</MenuShortcut>
    </MenuItem>
  </MenuPopup>
</Menu>

Grouped

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>Manage</MenuTrigger>
  <MenuPopup aria-label="Manage workspace">
    <MenuGroup>
      <MenuGroupLabel>Workspace</MenuGroupLabel>
      <MenuItem>Invite people</MenuItem>
      <MenuItem>Settings</MenuItem>
    </MenuGroup>
    <MenuSeparator />
    <MenuGroup>
      <MenuGroupLabel>Account</MenuGroupLabel>
      <MenuItem>Switch workspace</MenuItem>
    </MenuGroup>
  </MenuPopup>
</Menu>

Destructive item

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>Edit</MenuTrigger>
  <MenuPopup aria-label="Edit record">
    <MenuItem>
      <PencilIcon />
      Rename
    </MenuItem>
    <MenuItem>
      <CopyIcon />
      Duplicate
    </MenuItem>
    <MenuSeparator />
    <MenuItem variant="destructive">
      <Trash2Icon />
      Delete
    </MenuItem>
  </MenuPopup>
</Menu>

Selection items

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>View</MenuTrigger>
  <MenuPopup>
    <MenuCheckboxItem defaultChecked>Show archived</MenuCheckboxItem>
    <MenuRadioGroup defaultValue="week">
      <MenuRadioItem value="week">Week</MenuRadioItem>
      <MenuRadioItem value="month">Month</MenuRadioItem>
    </MenuRadioGroup>
  </MenuPopup>
</Menu>

Switch items

variant="switch" stays a semantic checkbox item; the size prop scales the switch thumb.

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>Preferences</MenuTrigger>
  <MenuPopup aria-label="Editor preferences">
    <MenuCheckboxItem defaultChecked variant="switch">
      Auto save
    </MenuCheckboxItem>
    <MenuCheckboxItem variant="switch">Show preview</MenuCheckboxItem>
  </MenuPopup>
</Menu>

Inset items

inset aligns plain items with items that carry a leading icon.

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>Record</MenuTrigger>
  <MenuPopup aria-label="Record actions">
    <MenuItem>
      <PencilIcon />
      Rename
    </MenuItem>
    <MenuItem inset>Duplicate</MenuItem>
    <MenuItem inset>Archive</MenuItem>
  </MenuPopup>
</Menu>

Account menu

<Menu>
  <MenuTrigger render={<Button variant="outline" />}>
    <UserIcon />
    Account
  </MenuTrigger>
  <MenuPopup aria-label="Account">
    <MenuGroup>
      <MenuGroupLabel>m@ui.siteplane.io</MenuGroupLabel>
      <MenuItem>
        <UserIcon />
        Profile
        <MenuShortcut>⇧⌘P</MenuShortcut>
      </MenuItem>
      <MenuItem>
        <CreditCardIcon />
        Billing
      </MenuItem>
      <MenuItem>
        <SettingsIcon />
        Settings
      </MenuItem>
    </MenuGroup>
    <MenuSeparator />
    <MenuItem>
      <LogOutIcon />
      Sign out
    </MenuItem>
  </MenuPopup>
</Menu>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • MenuPopup side accepts top, right, bottom, left, inline-start, and inline-end and defaults to bottom.
  • align accepts start, center, or end and defaults to center. sideOffset defaults to 4; alignOffset adjusts the cross-axis position.
  • anchor attaches the popup to another element or virtual anchor.
  • width accepts "auto", "trigger", "content", or "at-least-trigger".
  • Use inset on items, group labels, and submenu triggers to align rows without leading icons.
  • MenuCheckboxItem size accepts "sm", "default", "lg", and "xl".
  • All item, selection, label, separator, and submenu rows inherit the provider controlSize; repeated rows use the compact menu geometry from the global size contract rather than the 56px XL CTA height.
  • MenuLinkItem closeOnClick defaults to true; use false only when the menu should remain open after navigation.
  • MenuCreateHandle supports detached triggers and imperative opening.
  • Use disabled for unavailable items and the native icon slot treatment for leading icons.

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Popup and submenu placement, scale, fade, and reduced-motion behavior are native.
  • Active items, selection items, and submenu triggers use a pointer cursor.
  • Do not wrap the popup in a second animation.

Accessibility

  • Give every trigger visible text or an accessible label.
  • Give a popup without visible context an accessible menu label.
  • Preserve Arrow key navigation, focus, Escape, outside click, and focus restoration.
  • Keep disabled items unavailable and visibly distinct.
  • Checkbox and radio items retain their selection indicators; shortcuts are supporting text only.

Implementation Guidance

  • Use Menu for actions and menu choices, not ordinary form fields.
  • Do not render raw items outside Menu and MenuPopup.
  • Use placement, anchor, width, inset, size, link, disabled, and handle APIs instead of local menu implementations.
  • Preserve native item, submenu, selection, cursor, focus, and motion behavior.

On This Page