Make your AI a shadcn expert

Shadcn Dropdown Menu

React dropdown menu for actions, account menus, and settings. Built with TypeScript and Tailwind CSS for Next.js using Base UI — groups, shortcuts, and nested submenus.

A dropdown menu is a list of actions that opens from a button. Click a row and the menu closes. Use it for account menus, overflow toolbars, and settings — not for picking a form value.

Scroll to load preview...

Looking for a neobrutalism version for shadcn?

Same dropdown menu, thicker borders. The NeoBrutalism dropdown menu is the kit if you want that look.

Usage

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
<DropdownMenu>
  <DropdownMenuTrigger render={<Button 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>

Put render={<Button />} on the trigger so the Button is the actual control. sideOffset on content defaults to 4.

Composition

DropdownMenuTrigger
DropdownMenuLabel
DropdownMenuItem
DropdownMenuItem
DropdownMenuSeparator
DropdownMenuSeparator

Basic

Labels, separators, and a disabled item.

Scroll to load preview...

DropdownMenuSub nests a second panel. Keep it one extra level.

Scroll to load preview...

Shortcuts

DropdownMenuShortcut paints ⌘S. It does not bind the key.

Scroll to load preview...

Icons

An icon before the label. variant="destructive" is the red row.

Scroll to load preview...

Checkboxes

DropdownMenuCheckboxItem for options that toggle independently.

Scroll to load preview...

Checkboxes Icons

Same toggles, with an icon in the row.

Scroll to load preview...

Radio Group

DropdownMenuRadioGroup plus DropdownMenuRadioItem when only one value can be on.

Scroll to load preview...

Radio Icons

Exclusive choices with an icon in each row.

Scroll to load preview...

Destructive

variant="destructive" on the row that cannot be undone. Separate it from the rest.

Scroll to load preview...

Avatar

An Avatar as the trigger. Account, billing, sign out.

Scroll to load preview...

Complex

Groups, icons, checkboxes, radios, and nested submenus in one menu.

Scroll to load preview...

RTL

Wrap with DirectionProvider and dir="rtl". Submenus open toward the start.

Scroll to load preview...

API

Prop

Type

Prop

Type

Prop

Type

DropdownMenuCheckboxItem takes checked and onCheckedChange. DropdownMenuRadioGroup takes value and onValueChange. DropdownMenuLabel and DropdownMenuSubTrigger take inset.

Keyboard

KeyAction
Space / EnterOpen from the trigger, or activate the focused item
ArrowDownOpen from the trigger, or move to the next item
ArrowUpMove to the previous item
ArrowRight / ArrowLeftOpen or close a submenu
EscapeClose and return focus to the trigger

Type a letter to jump to the next item that starts with it.

Notes

Shortcuts are labels

DropdownMenuShortcut does not bind a key. Show ⇧⌘P in the row, then listen for the combination yourself.

onSelect dismisses the menu. Call event.preventDefault() if a checkbox should stay open.

With other components

Questions

Was this page helpful?

Sign in to leave feedback.