Dropdown Menu
A menu of actions opened from a trigger, built on Base UI. Supports checkbox and radio items, nested submenus and four density sizes.
Playground
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline" />}>
Open Menu
</DropdownMenuTrigger>
<DropdownMenuContent className="w-48">
<DropdownMenuItem>
<User />
Profile
</DropdownMenuItem>
<DropdownMenuItem>
<Settings />
Settings
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<LogOut />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Preview
DropdownMenuTrigger opens the menu – pass your button via the Base UI render prop. DropdownMenuContent positions the popup and items compose icons, text and DropdownMenuShortcut hints.
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline" />}>
Open Menu
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem>
<User />
Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Settings />
Settings
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<LogOut />
Log out
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Installation
npx shadcn@latest add https://espresso-base-ui.vercel.app/r/dropdown-menu.jsonUsage
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline" />}>
Open Menu
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Option One</DropdownMenuItem>
<DropdownMenuItem>Option Two</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Sizes
size on DropdownMenuContent sets the item density for the whole menu via context – xs, sm (default), md and lg. Submenus inherit it, and individual items can override it with their own size prop.
<DropdownMenuContent size="xs">...</DropdownMenuContent>
<DropdownMenuContent size="sm">...</DropdownMenuContent>
<DropdownMenuContent size="md">...</DropdownMenuContent>
<DropdownMenuContent size="lg">...</DropdownMenuContent>Checkbox and radio items
DropdownMenuCheckboxItem toggles independent options and DropdownMenuRadioGroup with DropdownMenuRadioItem picks one of a set – both show a trailing check indicator.
const [showStatusBar, setShowStatusBar] = React.useState(true)
const [position, setPosition] = React.useState("bottom")
<DropdownMenuCheckboxItem
checked={showStatusBar}
onCheckedChange={setShowStatusBar}
>
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>API reference
DropdownMenu is the Base UI Menu root and accepts its props – open, defaultOpen, onOpenChange and modal. The trigger supports the Base UI render prop; pass nativeButton={false} when the rendered element is not a native button.
DropdownMenuContent
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "xs" | "sm" | "md" | "lg" | "sm" | Item density for the whole menu, provided to items and submenus via context (reflected as data-size). |
| side | "top" | "right" | "bottom" | "left" | "bottom" | Which side of the trigger the menu opens on. |
| sideOffset | number | 4 | Gap between the trigger and the menu. |
| align | "start" | "center" | "end" | "start" | Alignment against the trigger. |
| alignOffset | number | 0 | Offset along the alignment axis. |
DropdownMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "destructive" | "default" | Destructive items render in the destructive color, including their icon and shortcut. |
| size | "xs" | "sm" | "md" | "lg" | inherited | Per-item override of the size inherited from DropdownMenuContent. |
| inset | boolean | – | Indent the item to line up with items that have a leading indicator. |
| disabled | boolean | false | Dims the item and removes it from navigation. |
DropdownMenuCheckboxItem
| Prop | Type | Default | Description |
|---|---|---|---|
| checked / onCheckedChange | boolean / (checked) => void | – | Controlled checked state with a trailing check indicator. |
| inset | boolean | – | Indent to align with inset items. |
DropdownMenuRadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| value / onValueChange | string / (value) => void | – | Selected DropdownMenuRadioItem value and its change handler. |
DropdownMenuSubContent
| Prop | Type | Default | Description |
|---|---|---|---|
| side | "top" | "right" | "bottom" | "left" | "right" | Side of the sub-trigger the submenu opens on. |
| alignOffset | number | -3 | Alignment offset tuned so submenu items line up with the parent item. |
| Component | Description |
|---|---|
| DropdownMenuTrigger | Opens the menu (data-slot="dropdown-menu-trigger"); compose your button via the render prop. |
| DropdownMenuContent | Portalled popup (data-slot="dropdown-menu-content") with slide/zoom animations and data-size. |
| DropdownMenuGroup / DropdownMenuLabel | Logical item group (data-slot="dropdown-menu-group") with a small heading (data-slot="dropdown-menu-label", supports inset). |
| DropdownMenuItem | Action row (data-slot="dropdown-menu-item") reflecting data-variant, data-size and data-inset. |
| DropdownMenuCheckboxItem / DropdownMenuRadioItem | Selectable items (data-slot="dropdown-menu-checkbox-item" / "dropdown-menu-radio-item") with trailing check indicators. |
| DropdownMenuShortcut | Right-aligned keyboard hint span (data-slot="dropdown-menu-shortcut"). |
| DropdownMenuSeparator | Thin divider between groups (data-slot="dropdown-menu-separator"). |
| DropdownMenuSub / DropdownMenuSubTrigger / DropdownMenuSubContent | Nested submenu: root (data-slot="dropdown-menu-sub"), trigger with auto chevron (data-slot="dropdown-menu-sub-trigger") and side-opening popup (data-slot="dropdown-menu-sub-content"). |
| DropdownMenuPortal | Portals menu parts to the document body (data-slot="dropdown-menu-portal"); used internally by DropdownMenuContent. |
Accessibility & styling hooks
Base UI renders the popup with role="menu" and items as menuitem / menuitemcheckbox / menuitemradio, with full keyboard support – arrows move the highlight, typeahead jumps to items, Enter activates and Escape closes. Every part exposes a data-slot attribute, and items reflect state as data-highlighted, data-disabled, data-inset, data-variant and data-size – target these from CSS for app-level overrides.