Get Started
Components
- Alert
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Checkbox Group
- ComboBox
- Command
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Disclosure
- Disclosure Group
- Drawer
- Empty
- Field
- File Trigger
- Form
- Grid List
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- ListBox
- Menu
- Number Field
- Pagination
- Popover
- Progress Bar
- Radio Group
- Range Calendar
- Resizable
- Search Field
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Tag Group
- Text Field
- Textarea
- Time Field
- Toast
- Toggle Button
- Toggle Button Group
- Tooltip
- Tree
- Typography
AI Elements
"use client"
import { SubmenuTrigger } from "react-aria-components"
import { Button } from "@/components/ui/button"
import {
Menu,
MenuItem,
MenuSection,
MenuSeparator,
MenuTrigger,
} from "@/components/ui/menu"
export function MenuDemo() {
return (
<MenuTrigger>
<Button variant="outline">Open</Button>
<Menu placement="bottom start" className="w-56">
<MenuSection title="My Account">
<MenuItem onAction={() => console.log("Profile")}>
Profile
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⇧⌘P
</span>
</MenuItem>
<MenuItem onAction={() => console.log("Billing")}>
Billing
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘B
</span>
</MenuItem>
<MenuItem onAction={() => console.log("Settings")}>
Settings
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘S
</span>
</MenuItem>
<MenuItem onAction={() => console.log("Keyboard shortcuts")}>
Keyboard shortcuts
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘K
</span>
</MenuItem>
</MenuSection>
<MenuSeparator />
<MenuSection>
<MenuItem onAction={() => console.log("Team")}>Team</MenuItem>
<SubmenuTrigger>
<MenuItem>Invite users</MenuItem>
<Menu className="w-56">
<MenuItem onAction={() => console.log("Email")}>Email</MenuItem>
<MenuItem onAction={() => console.log("Message")}>
Message
</MenuItem>
<MenuSeparator />
<MenuItem onAction={() => console.log("More")}>More...</MenuItem>
</Menu>
</SubmenuTrigger>
<MenuItem onAction={() => console.log("New Team")}>
New Team
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘+T
</span>
</MenuItem>
</MenuSection>
<MenuSeparator />
<MenuItem onAction={() => console.log("GitHub")}>GitHub</MenuItem>
<MenuItem onAction={() => console.log("Support")}>Support</MenuItem>
<MenuItem isDisabled>API</MenuItem>
<MenuSeparator />
<MenuItem onAction={() => console.log("Log out")}>
Log out
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⇧⌘Q
</span>
</MenuItem>
</Menu>
</MenuTrigger>
)
}
Installation
CLI
Manual
pnpmnpmyarnbunpnpm dlx shadcn@latest add menu
Usage
import {
Menu,
MenuItem,
MenuSection,
MenuSeparator,
MenuTrigger,
} from "@/components/ui/menu"<MenuTrigger>
<Button variant="outline">Open</Button>
<Menu>
<MenuItem onAction={() => console.log("New")}>New</MenuItem>
<MenuItem onAction={() => console.log("Open")}>Open</MenuItem>
<MenuSeparator />
<MenuItem onAction={() => console.log("Save")}>Save</MenuItem>
</Menu>
</MenuTrigger>Examples
Submenu
"use client"
import { SubmenuTrigger } from "react-aria-components"
import { Button } from "@/components/ui/button"
import {
Menu,
MenuItem,
MenuSeparator,
MenuTrigger,
} from "@/components/ui/menu"
export function MenuSubmenuDemo() {
return (
<MenuTrigger>
<Button variant="outline">Edit</Button>
<Menu className="w-56">
<MenuItem onAction={() => console.log("Undo")}>
Undo
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘Z
</span>
</MenuItem>
<MenuItem onAction={() => console.log("Redo")}>
Redo
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⇧⌘Z
</span>
</MenuItem>
<MenuSeparator />
<MenuItem onAction={() => console.log("Cut")}>
Cut
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘X
</span>
</MenuItem>
<MenuItem onAction={() => console.log("Copy")}>
Copy
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘C
</span>
</MenuItem>
<MenuItem onAction={() => console.log("Paste")}>
Paste
<span className="text-muted-foreground ml-auto text-xs tracking-widest">
⌘V
</span>
</MenuItem>
<MenuSeparator />
<SubmenuTrigger>
<MenuItem>Share</MenuItem>
<Menu className="w-56">
<MenuItem onAction={() => console.log("Email")}>Email</MenuItem>
<MenuItem onAction={() => console.log("Copy Link")}>
Copy Link
</MenuItem>
<MenuSeparator />
<SubmenuTrigger>
<MenuItem>Social Media</MenuItem>
<Menu className="w-56">
<MenuItem onAction={() => console.log("Twitter")}>
Twitter
</MenuItem>
<MenuItem onAction={() => console.log("Facebook")}>
Facebook
</MenuItem>
<MenuItem onAction={() => console.log("LinkedIn")}>
LinkedIn
</MenuItem>
</Menu>
</SubmenuTrigger>
</Menu>
</SubmenuTrigger>
<SubmenuTrigger>
<MenuItem>Export</MenuItem>
<Menu className="w-56">
<MenuItem onAction={() => console.log("PDF")}>PDF</MenuItem>
<MenuItem onAction={() => console.log("PNG")}>PNG</MenuItem>
<MenuItem onAction={() => console.log("SVG")}>SVG</MenuItem>
<MenuSeparator />
<MenuItem onAction={() => console.log("HTML")}>HTML</MenuItem>
<MenuItem onAction={() => console.log("Markdown")}>
Markdown
</MenuItem>
</Menu>
</SubmenuTrigger>
</Menu>
</MenuTrigger>
)
}
Menus support nested submenus. Use the SubmenuTrigger component from react-aria-components to create a submenu.
import { SubmenuTrigger } from "react-aria-components"
import { Menu, MenuItem, MenuTrigger } from "@/components/ui/menu"
<MenuTrigger>
<Button variant="outline">Edit</Button>
<Menu>
<MenuItem>Cut</MenuItem>
<MenuItem>Copy</MenuItem>
<MenuItem>Paste</MenuItem>
<MenuSeparator />
<SubmenuTrigger>
<MenuItem>Share</MenuItem>
<Menu>
<MenuItem>Email</MenuItem>
<MenuItem>Copy Link</MenuItem>
</Menu>
</SubmenuTrigger>
</Menu>
</MenuTrigger>With Command
"use client"
import { SubmenuTrigger } from "react-aria-components"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command"
import {
Menu,
MenuItem,
MenuSeparator,
MenuTrigger,
} from "@/components/ui/menu"
import { Popover } from "../ui/popover"
const TEAM_MEMBERS = [
{
name: "shadcn",
email: "shadcn@example.com",
avatar: "https://github.com/shadcn.png",
},
{
name: "maxleiter",
email: "max@example.com",
avatar: "https://github.com/maxleiter.png",
},
{
name: "evilrabbit",
email: "rabbit@example.com",
avatar: "https://github.com/evilrabbit.png",
},
]
const PROJECTS = [
{ name: "Design System", emoji: "🎨" },
{ name: "Marketing Site", emoji: "📱" },
{ name: "Dashboard", emoji: "📊" },
{ name: "Documentation", emoji: "📚" },
{ name: "API Gateway", emoji: "🔌" },
]
export function MenuCommandDemo() {
return (
<MenuTrigger>
<Button variant="outline">Assign Task</Button>
<Menu className="w-56">
<MenuItem onAction={() => console.log("Assign to me")}>
Assign to me
</MenuItem>
<MenuSeparator />
<SubmenuTrigger>
<MenuItem>Assign to team member</MenuItem>
<Popover>
<Command>
<CommandInput placeholder="Search team members..." autoFocus />
<CommandList
renderEmptyState={() => (
<CommandEmpty>No team member found</CommandEmpty>
)}
>
<CommandGroup>
{TEAM_MEMBERS.map((member) => (
<CommandItem
key={member.email}
id={member.email}
onSelect={() => {
console.log("Assigned to:", member.name)
}}
>
<span className="mr-2 inline-flex h-6 w-6 overflow-hidden rounded-full align-middle">
<img src={member.avatar} alt={member.name} />
</span>
<span className="ml-2">{member.name}</span>
<span className="text-muted-foreground ml-auto text-xs">
{member.email}
</span>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</Popover>
</SubmenuTrigger>
<SubmenuTrigger>
<MenuItem>Move to project</MenuItem>
<Popover>
<Command>
<CommandInput placeholder="Search projects..." autoFocus />
<CommandList
renderEmptyState={() => (
<CommandEmpty>No project found</CommandEmpty>
)}
>
<CommandGroup>
{PROJECTS.map((project) => (
<CommandItem
key={project.name}
id={project.name}
onSelect={() => {
console.log("Moved to:", project.name)
}}
>
<span className="mr-2">{project.emoji}</span>
{project.name}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</Popover>
</SubmenuTrigger>
<MenuSeparator />
<MenuItem onAction={() => console.log("Unassign")}>Unassign</MenuItem>
</Menu>
</MenuTrigger>
)
}
You can combine Menu with Command to create searchable submenus. This is useful when you have a large list of options that need to be filtered.
import { SubmenuTrigger } from "react-aria-components"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command"
import { Menu, MenuItem, MenuTrigger } from "@/components/ui/menu"
<MenuTrigger>
<Button variant="outline">Assign Task</Button>
<Menu>
<MenuItem>Assign to me</MenuItem>
<SubmenuTrigger>
<MenuItem>Assign to team member</MenuItem>
<Menu className="w-72 p-0">
<Command>
<CommandInput placeholder="Search team members..." autoFocus />
<CommandList>
<CommandEmpty>No team member found</CommandEmpty>
<CommandGroup>
{/* Your command items here */}
</CommandGroup>
</CommandList>
</Command>
</Menu>
</SubmenuTrigger>
</Menu>
</MenuTrigger>