---
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>GitHub</DropdownMenuItem>
<DropdownMenuItem>Support</DropdownMenuItem>
<DropdownMenuItem disabled>API</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Installation
npx shadcn@latest add @fulldev/dropdown-menu
Usage
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
<DropdownMenu>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuItem>Subscription</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
DropdownMenuTrigger is a plain button: style it with buttonVariants.
DropdownMenuItem renders an a when you pass href.
Composition
DropdownMenu
├── DropdownMenuTrigger
└── DropdownMenuContent
├── DropdownMenuGroup
│ ├── DropdownMenuLabel
│ ├── DropdownMenuItem
│ │ └── DropdownMenuShortcut
│ └── DropdownMenuItem
├── DropdownMenuSeparator
├── DropdownMenuGroup
│ ├── DropdownMenuLabel
│ ├── DropdownMenuCheckboxItem
│ └── DropdownMenuCheckboxItem
├── DropdownMenuSeparator
└── DropdownMenuGroup
├── DropdownMenuLabel
├── DropdownMenuRadioItem
└── DropdownMenuRadioItem
The Astro component has no submenu parts (DropdownMenuSub), so the official
Demo, Submenu, Complex, and RTL examples are in the
React Dropdown Menu docs only.
Shortcuts
Add DropdownMenuShortcut to show keyboard hints.
---
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem>
Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Billing
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Settings
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
Log out
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Icons
Combine icons with labels for quick scanning.
---
import CreditCardIcon from "@lucide/astro/icons/credit-card"
import LogOutIcon from "@lucide/astro/icons/log-out"
import SettingsIcon from "@lucide/astro/icons/settings"
import UserIcon from "@lucide/astro/icons/user"
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<UserIcon />
Profile
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCardIcon />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<SettingsIcon />
Settings
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<LogOutIcon />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Checkboxes
Use DropdownMenuCheckboxItem with a unique value. Set the checked items with
defaultValues on DropdownMenu, and closeOnSelect={false} to keep the menu
open while toggling.
---
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu defaultValues={["status-bar"]} closeOnSelect={false}>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Open
</DropdownMenuTrigger>
<DropdownMenuContent class="w-40">
<DropdownMenuGroup>
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuCheckboxItem value="status-bar">
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem value="activity-bar" disabled>
Activity Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem value="panel">Panel</DropdownMenuCheckboxItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>Checkboxes Icons
Add icons to checkbox items.
---
import BellIcon from "@lucide/astro/icons/bell"
import MailIcon from "@lucide/astro/icons/mail"
import MessageSquareIcon from "@lucide/astro/icons/message-square"
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu defaultValues={["email", "push"]} closeOnSelect={false}>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Notifications
</DropdownMenuTrigger>
<DropdownMenuContent class="w-48">
<DropdownMenuGroup>
<DropdownMenuLabel>Notification Preferences</DropdownMenuLabel>
<DropdownMenuCheckboxItem value="email">
<MailIcon />
Email notifications
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem value="sms">
<MessageSquareIcon />
SMS notifications
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem value="push">
<BellIcon />
Push notifications
</DropdownMenuCheckboxItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>Radio Group
Use DropdownMenuRadioItem for exclusive choices. A menu holds one radio
value, set with defaultValue on DropdownMenu.
---
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu defaultValue="bottom" closeOnSelect={false}>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Open
</DropdownMenuTrigger>
<DropdownMenuContent class="w-32">
<DropdownMenuGroup>
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>Radio Icons
Show radio options with icons.
---
import BuildingComplexIcon from "@lucide/astro/icons/building-complex"
import CreditCardIcon from "@lucide/astro/icons/credit-card"
import WalletIcon from "@lucide/astro/icons/wallet"
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu defaultValue="card" closeOnSelect={false}>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Payment Method
</DropdownMenuTrigger>
<DropdownMenuContent class="min-w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>Select Payment Method</DropdownMenuLabel>
<DropdownMenuRadioItem value="card">
<CreditCardIcon />
Credit Card
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="paypal">
<WalletIcon />
PayPal
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bank">
<BuildingComplexIcon />
Bank Transfer
</DropdownMenuRadioItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>Destructive
Use variant="destructive" for irreversible actions.
---
import PencilIcon from "@lucide/astro/icons/pencil"
import ShareIcon from "@lucide/astro/icons/share"
import TrashIcon from "@lucide/astro/icons/trash"
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu>
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
Actions
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>
<PencilIcon />
Edit
</DropdownMenuItem>
<DropdownMenuItem>
<ShareIcon />
Share
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
<TrashIcon />
Delete
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>Avatar
An account switcher dropdown triggered by an avatar.
---
import BadgeCheckIcon from "@lucide/astro/icons/badge-check"
import BellIcon from "@lucide/astro/icons/bell"
import CreditCardIcon from "@lucide/astro/icons/credit-card"
import LogOutIcon from "@lucide/astro/icons/log-out"
import { cn } from "@/lib/utils"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
---
<DropdownMenu>
<DropdownMenuTrigger
class={cn(
buttonVariants({ variant: "ghost", size: "icon" }),
"rounded-full"
)}
>
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="shadcn" />
<AvatarFallback>LR</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuGroup>
<DropdownMenuItem>
<BadgeCheckIcon />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCardIcon />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<BellIcon />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOutIcon />
Sign Out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>API Reference
Source: src/components/ui/dropdown-menu
DropdownMenu
| Prop | Type | Default |
|---|---|---|
defaultOpen | boolean | false |
defaultValue | string | null | |
defaultValues | string[] | |
closeOnClickOutside | boolean | true |
closeOnEscape | boolean | true |
closeOnSelect | boolean | true |
highlightItemOnHover | boolean | true |
side | "top" | "right" | "bottom" | "left" | "bottom" |
align | "start" | "center" | "end" | "start" |
sideOffset | number | 4 |
alignOffset | number | 0 |
avoidCollisions | boolean | true |
collisionPadding | number | 8 |
lockScroll | boolean | true |
DropdownMenuContent takes the placement props too and overrides the root.
DropdownMenuItem takes href, disabled, variant ("default" or
"destructive"), and inset. DropdownMenuCheckboxItem and
DropdownMenuRadioItem require value and take defaultChecked, disabled,
variant, and inset; root defaults win over defaultChecked.
DropdownMenuLabel takes inset.
The root emits dropdown-menu:open-change with { open },
dropdown-menu:select with { value, itemType, checked },
dropdown-menu:value-change with { value } for radio items, and
dropdown-menu:values-change with { values } for checkbox items. Dispatch
dropdown-menu:set with { open?, value?, values? } to change it from client
code. See the
Data Slot dropdown menu docs
for keyboard and controller details.