Dropdown Menu

A menu of actions and options, opened from a trigger.

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuItem,
  DropdownMenuCheckboxItem,
  DropdownMenuShortcut,
} from '@/components/ui/dropdown-menu'
import { Button } from '@/components/ui/button'

export default function DropdownMenuDemo() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger render={<Button variant="outline">Open menu</Button>} />
      <DropdownMenuContent>
        <DropdownMenuLabel>My account</DropdownMenuLabel>
        <DropdownMenuSeparator />
        <DropdownMenuItem>
          Profile
          <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuItem>
          Billing
          <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuCheckboxItem defaultChecked>Show status bar</DropdownMenuCheckboxItem>
        <DropdownMenuCheckboxItem>Show activity log</DropdownMenuCheckboxItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem>
          Log out
          <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Built on Base UI

Installation

pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/dropdown-menu.json

Needs a React + Tailwind project set up with shadcn. Copies the component source straight into your project, so you can edit it.

Dropdown Menu imports cn() from lib/utils.ts — add it too if you don't have it yet:

import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Usage

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuLabel,
} from '@/components/ui/dropdown-menu'
import { Button } from '@/components/ui/button'

<DropdownMenu>
  <DropdownMenuTrigger render={<Button variant="outline">Open menu</Button>} />
  <DropdownMenuContent>
    <DropdownMenuLabel>My account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Profile</DropdownMenuItem>
    <DropdownMenuItem>Billing</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Examples

With a submenu

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuSub,
  DropdownMenuSubTrigger,
  DropdownMenuSubContent,
} from '@/components/ui/dropdown-menu'
import { Button } from '@/components/ui/button'

export default function DropdownMenuSubmenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger render={<Button variant="outline">Actions</Button>} />
      <DropdownMenuContent>
        <DropdownMenuItem>Add to Library</DropdownMenuItem>
        <DropdownMenuSub>
          <DropdownMenuSubTrigger>Add to Playlist</DropdownMenuSubTrigger>
          <DropdownMenuSubContent>
            <DropdownMenuItem>Get Up!</DropdownMenuItem>
            <DropdownMenuItem>Inside Out</DropdownMenuItem>
            <DropdownMenuItem>Night Beats</DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem>New playlist…</DropdownMenuItem>
          </DropdownMenuSubContent>
        </DropdownMenuSub>
        <DropdownMenuSeparator />
        <DropdownMenuItem>Share</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

API Reference

NameTypeDefaultDescription
open / onOpenChangeboolean / (open: boolean) => void—Control the open state from outside (set on DropdownMenu).
DropdownMenuItem disabledbooleanfalseIgnores user interaction.
DropdownMenuCheckboxItem checked / onCheckedChangeboolean / (checked: boolean) => void—Controlled ticked state of a checkbox item.
DropdownMenuContent align'start' | 'center' | 'end''start'Alignment of the menu relative to the trigger.
DropdownMenuSub / SubTrigger / SubContent——Nests a submenu inside an item, opened on hover or by keyboard.