---
type: doc
title: Dropdown Menu
description: Displays a menu to the user, such as a set of actions or functions, triggered by a button.
---

> Fulldev UI for Astro. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/styles/{style}/{name}.json`; see [installation](/astro/docs/installation.md).

```astro title="src/components/examples/dropdown-menu/dropdown-menu-basic.astro"
---
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

```bash
npx shadcn@latest add @fulldev/dropdown-menu
```

## Usage

```ts
import { buttonVariants } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
```

```astro
<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

```text
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](/react/components/dropdown-menu/) docs only.

## Shortcuts

Add `DropdownMenuShortcut` to show keyboard hints.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-shortcuts.astro"
---
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.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-icons.astro"
---
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.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-checkboxes.astro"
---
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.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-checkboxes-icons.astro"
---
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`.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-radio-group.astro"
---
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.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-radio-icons.astro"
---
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.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-destructive.astro"
---
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.

```astro title="src/components/examples/dropdown-menu/dropdown-menu-avatar.astro"
---
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`](https://github.com/fulldotdev/ui/tree/main/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](https://github.com/bejamas/data-slot/blob/main/packages/dropdown-menu/README.md)
for keyboard and controller details.

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/dropdown-menu-examples
```
