Shadcn.io is not affiliated with official shadcn/ui
Shadcn Dropdown Menu React dropdown menu component for actions, navigation, and settings. Built with TypeScript and Tailwind CSS for Next.js applications using Radix UI.
Ever built an interface where users couldn't find the "Export" action? Or watched someone click every toolbar button looking for settings? Yeah, cramming every possible action into your main UI makes everything feel cluttered and overwhelming. This shadcn/ui dropdown menu organizes actions exactly where users expect them in your React apps.
Contextual actions that stay organized and discoverable:
"use client" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" export default function DropdownMenuDemo() { return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline">Open</Button> </DropdownMenuTrigger> <DropdownMenuContent align="start" className="w-56"> <DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuGroup> <DropdownMenuItem> Profile <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut> </DropdownMenuItem> <DropdownMenuItem> Billing <DropdownMenuShortcut>⌘B</DropdownMenuShortcut> </DropdownMenuItem> <DropdownMenuItem> Settings <DropdownMenuShortcut>⌘S</DropdownMenuShortcut> </DropdownMenuItem> <DropdownMenuItem> Keyboard shortcuts <DropdownMenuShortcut>⌘K</DropdownMenuShortcut> </DropdownMenuItem> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuGroup> <DropdownMenuItem>Team</DropdownMenuItem> <DropdownMenuSub> <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger> <DropdownMenuPortal> <DropdownMenuSubContent> <DropdownMenuItem>Email</DropdownMenuItem> <DropdownMenuItem>Message</DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuItem>More...</DropdownMenuItem> </DropdownMenuSubContent> </DropdownMenuPortal> </DropdownMenuSub> <DropdownMenuItem> New Team <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut> </DropdownMenuItem> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuItem>GitHub</DropdownMenuItem> <DropdownMenuItem>Support</DropdownMenuItem> <DropdownMenuItem disabled>API</DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuItem> Log out <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut> </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> ) }
Built on Radix UI Dropdown Menu with full keyboard navigation, screen reader support, and smart collision detection. Styled with Tailwind CSS so it matches your design system instead of looking like a generic system menu.
npx shadcn@latest add dropdown-menu
Here's the thing—users don't want to see every possible action all the time. They want relevant actions when they need them, organized in a way that makes sense. A toolbar with 20 buttons is overwhelming. A clean interface with contextual dropdown menus is intuitive.
Think about how you use your browser's right-click menu or your phone's share sheet. Related actions are grouped together. Common actions appear first. Everything has a logical place. That's the power of well-designed dropdown menus.
This free shadcn dropdown menu handles the complex parts—keyboard navigation, focus management, positioning logic, accessibility—while you focus on organizing your app's functionality. Whether you're building admin panels, content editors, or productivity tools in your Next.js applications, dropdown menus that make sense keep users productive in your JavaScript projects.
Basic dropdown for common actions:
"use client" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" export default function DropdownMenuSimple() { return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline">Open</Button> </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuSeparator /> <DropdownMenuItem>Profile</DropdownMenuItem> <DropdownMenuItem>Billing</DropdownMenuItem> <DropdownMenuItem>Team</DropdownMenuItem> <DropdownMenuItem>Subscription</DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> ) }
Perfect for settings and view options:
"use client" import * as React from "react" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" type Checked = boolean | "indeterminate" export default function DropdownMenuCheckboxes() { const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true) const [showActivityBar, setShowActivityBar] = React.useState<Checked>(false) const [showPanel, setShowPanel] = React.useState<Checked>(false) return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline">View Options</Button> </DropdownMenuTrigger> <DropdownMenuContent className="w-56"> <DropdownMenuLabel>Appearance</DropdownMenuLabel> <DropdownMenuSeparator /> <DropdownMenuCheckboxItem checked={showStatusBar} onCheckedChange={setShowStatusBar}> Status Bar </DropdownMenuCheckboxItem> <DropdownMenuCheckboxItem checked={showActivityBar} disabled onCheckedChange={setShowActivityBar} > Activity Bar </DropdownMenuCheckboxItem> <DropdownMenuCheckboxItem checked={showPanel} onCheckedChange={setShowPanel}> Panel </DropdownMenuCheckboxItem> </DropdownMenuContent> </DropdownMenu> ) }
Single-choice options like themes or layouts:
"use client" import * as React from "react" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" export default function DropdownMenuRadioGroupDemo() { const [position, setPosition] = React.useState("bottom") return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline">Panel Position</Button> </DropdownMenuTrigger> <DropdownMenuContent className="w-56"> <DropdownMenuLabel>Panel Position</DropdownMenuLabel> <DropdownMenuSeparator /> <DropdownMenuRadioGroup onValueChange={setPosition} value={position}> <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem> <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem> <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem> </DropdownMenuRadioGroup> </DropdownMenuContent> </DropdownMenu> ) }
Visual cues make options easier to scan:
"use client" import { Cloud, CreditCard, Github, Keyboard, LifeBuoy, LogOut, Mail, MessageSquare, Plus, PlusCircle, Settings, User, UserPlus, Users, } from "lucide-react" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" export default function DropdownMenuWithIcons() { return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline"> <User className="mr-2 h-4 w-4" /> Account </Button> </DropdownMenuTrigger> <DropdownMenuContent className="w-56"> <DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuSeparator /> <DropdownMenuGroup> <DropdownMenuItem> <User className="mr-2 h-4 w-4" /> <span>Profile</span> <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut> </DropdownMenuItem> <DropdownMenuItem> <CreditCard className="mr-2 h-4 w-4" /> <span>Billing</span> <DropdownMenuShortcut>⌘B</DropdownMenuShortcut> </DropdownMenuItem> <DropdownMenuItem> <Settings className="mr-2 h-4 w-4" /> <span>Settings</span> <DropdownMenuShortcut>⌘S</DropdownMenuShortcut> </DropdownMenuItem> <DropdownMenuItem> <Keyboard className="mr-2 h-4 w-4" /> <span>Keyboard shortcuts</span> <DropdownMenuShortcut>⌘K</DropdownMenuShortcut> </DropdownMenuItem> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuGroup> <DropdownMenuItem> <Users className="mr-2 h-4 w-4" /> <span>Team</span> </DropdownMenuItem> <DropdownMenuSub> <DropdownMenuSubTrigger> <UserPlus className="mr-2 h-4 w-4" /> <span>Invite users</span> </DropdownMenuSubTrigger> <DropdownMenuPortal> <DropdownMenuSubContent> <DropdownMenuItem> <Mail className="mr-2 h-4 w-4" /> <span>Email</span> </DropdownMenuItem> <DropdownMenuItem> <MessageSquare className="mr-2 h-4 w-4" /> <span>Message</span> </DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuItem> <PlusCircle className="mr-2 h-4 w-4" /> <span>More...</span> </DropdownMenuItem> </DropdownMenuSubContent> </DropdownMenuPortal> </DropdownMenuSub> <DropdownMenuItem> <Plus className="mr-2 h-4 w-4" /> <span>New Team</span> <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut> </DropdownMenuItem> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuItem> <Github className="mr-2 h-4 w-4" /> <span>GitHub</span> </DropdownMenuItem> <DropdownMenuItem> <LifeBuoy className="mr-2 h-4 w-4" /> <span>Support</span> </DropdownMenuItem> <DropdownMenuItem disabled> <Cloud className="mr-2 h-4 w-4" /> <span>API</span> </DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuItem> <LogOut className="mr-2 h-4 w-4" /> <span>Log out</span> <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut> </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> ) }
Organize complex hierarchies without overwhelming users:
"use client" import { Button } from "~/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu" export default function DropdownMenuSubmenu() { return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="outline">File Menu</Button> </DropdownMenuTrigger> <DropdownMenuContent className="w-56"> <DropdownMenuLabel>File</DropdownMenuLabel> <DropdownMenuSeparator /> <DropdownMenuGroup> <DropdownMenuItem>New File</DropdownMenuItem> <DropdownMenuItem>Open File</DropdownMenuItem> <DropdownMenuSub> <DropdownMenuSubTrigger>Recent Files</DropdownMenuSubTrigger> <DropdownMenuPortal> <DropdownMenuSubContent> <DropdownMenuItem>project-1.tsx</DropdownMenuItem> <DropdownMenuItem>component.tsx</DropdownMenuItem> <DropdownMenuItem>styles.css</DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuItem>Clear Recent</DropdownMenuItem> </DropdownMenuSubContent> </DropdownMenuPortal> </DropdownMenuSub> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuGroup> <DropdownMenuItem>Save</DropdownMenuItem> <DropdownMenuItem>Save As...</DropdownMenuItem> <DropdownMenuSub> <DropdownMenuSubTrigger>Export</DropdownMenuSubTrigger> <DropdownMenuPortal> <DropdownMenuSubContent> <DropdownMenuItem>Export as PDF</DropdownMenuItem> <DropdownMenuItem>Export as PNG</DropdownMenuItem> <DropdownMenuItem>Export as SVG</DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuSub> <DropdownMenuSubTrigger>More formats</DropdownMenuSubTrigger> <DropdownMenuPortal> <DropdownMenuSubContent> <DropdownMenuItem>JPEG</DropdownMenuItem> <DropdownMenuItem>WEBP</DropdownMenuItem> <DropdownMenuItem>GIF</DropdownMenuItem> </DropdownMenuSubContent> </DropdownMenuPortal> </DropdownMenuSub> </DropdownMenuSubContent> </DropdownMenuPortal> </DropdownMenuSub> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuItem>Print</DropdownMenuItem> <DropdownMenuItem>Close</DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> ) }
This free open source dropdown menu component includes everything you need:
TypeScript-first - Full type safety with proper event types and state management
Radix UI powered - Battle-tested accessibility and keyboard navigation
Smart positioning - Collision detection keeps menus within viewport bounds
Tailwind CSS styled - Customize with utilities, not fighting component CSS
Keyboard navigable - Arrow keys, Enter, Escape, and typeahead search
Screen reader friendly - Proper ARIA roles and focus announcements
Flexible structure - Groups, separators, checkboxes, radio buttons, submenus
Touch optimized - Appropriate target sizes for mobile interactions
Component Purpose Key Props DropdownMenuRoot container open, onOpenChange, defaultOpenDropdownMenuTriggerButton that opens asChild for custom triggersDropdownMenuContentMenu container align, side, sideOffsetDropdownMenuItemBasic menu action onSelect, disabledDropdownMenuLabelSection headers Non-interactive labels DropdownMenuSeparatorVisual dividers Organize menu sections
Component Purpose Key Props DropdownMenuCheckboxItemToggle options checked, onCheckedChangeDropdownMenuRadioGroupSingle choice group Wraps radio items DropdownMenuRadioItemRadio option value for selectionDropdownMenuSubNested submenu open, onOpenChangeDropdownMenuShortcutKeyboard hints Display shortcuts like ⌘K
Key Action Space/EnterOpen menu or select item Arrow KeysNavigate between items Home/EndJump to first/last item EscapeClose menu A-ZTypeahead search
Organize actions logically. This free shadcn/ui dropdown menu supports groups and separators—use them. Put common actions first, group related actions together, separate destructive actions at the bottom. Your React component provides the structure—you provide the organization that matches user mental models.
Keep menus scannable. Long dropdown menus overwhelm users. If you need more than 10-12 items, consider submenus or multiple dropdowns. This TypeScript component handles nested menus beautifully, but cognitive load matters more than technical capability in your Next.js applications.
Make touch targets finger-friendly. Mobile users tap with thumbs, not precise mouse cursors. Ensure adequate spacing and sizing for touch interactions. This open source shadcn component is responsive, but test on real devices with real fingers.
Handle disabled states clearly. Show unavailable actions but make it obvious they're disabled. Use consistent disabled styling and consider explaining why actions aren't available. Your JavaScript dropdown should guide users, not confuse them.
Use keyboard shortcuts wisely. Power users love shortcuts, but don't show them for everything. Include shortcuts for common actions, display them with DropdownMenuShortcut, but keep the visual hierarchy clean. This Tailwind CSS component supports shortcuts—use them strategically.
Dropdown menus naturally work with Button components as triggers for consistent styling in your React applications. Use Avatar components inside menu items for user account menus or team member selection.
For complex interfaces, combine dropdown menus with ContextMenu components—dropdown for explicit actions, context menu for right-click workflows. Badge components work well for showing status or counts next to menu options. This open source pattern keeps your interface consistent.
When building navigation systems, pair dropdown menus with NavigationMenu components for hierarchical site structure. Separator components help organize complex dropdown content into logical sections.
For data-heavy applications, use dropdown menus with Command components for searchable action lists. Your JavaScript application can combine these patterns while maintaining clear interaction models.