Dropdown Menu
Contextual action menu primitive with keyboard support.
npx shadcn@latest add @aavya/ui-dropdown-menu
One-time setup — add the @aavya registry to your components.json so branded dependencies resolve to Aavya (not stock shadcn):
"registries": { "@aavya": "https://registry-dev.aavya.com/r/{name}.json" }Or install by full URL: npx shadcn@latest add https://registry-dev.aavya.com/r/ui-dropdown-menu.json
| Part | Prop | Type | Default |
|---|---|---|---|
| DropdownMenuItem | inset? | boolean | — |
| DropdownMenuItem | variant? | 'default' | 'destructive' | 'default' |
| DropdownMenuLabel | inset? | boolean | — |
| DropdownMenuSubTrigger | inset? | boolean | — |
DropdownMenu forwards remaining props to DropdownMenuPrimitive.Root props.
Do
- Use it for a set of actions triggered from one control; group related actions with a separator.
- Give an icon-only trigger an aria-label so it has an accessible name.
- Use DropdownMenuLabel for a non-interactive section heading.
Don’t
- Don't use a dropdown menu to pick a value or for form input — use Select instead.
- Don't nest more than one level of submenus; flatten the structure.
- Don't put primary page navigation here — use the Navigation Menu.
Role
menu / menuitem (handled by Radix).
Keyboard
Arrow keys move between items, Enter/Space activate, Esc closes, and typeahead jumps to matching items. (handled)
Screen reader
The trigger announces expanded/collapsed state; items announce their label. An icon-only trigger needs an aria-label — you provide this.
Focus
Focus moves into the menu on open and returns to the trigger on close. (handled)
Gotcha
Menu items aren't links. For navigation, render the item asChild wrapping a Link so it's a real anchor.
import { DropdownMenu } from '@/components/ui/dropdown-menu'
export default function Example() {
return (
<div className="p-6">
<DropdownMenu />
</div>
)
}
'use client'
import * as React from 'react'
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react'
import { cn } from '@/lib/utils'
function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
return <DropdownMenuPrimitive.Root data-slot='dropdown-menu' {...props} />
}
function DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
return <DropdownMenuPrimitive.Portal data-slot='dropdown-menu-portal' {...props} />
}
function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
return <DropdownMenuPrimitive.Trigger data-slot='dropdown-menu-trigger' {...props} />
}
function DropdownMenuContent({
className,
sideOffset = 4,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
return (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
data-slot='dropdown-menu-content'
sideOffset={sideOffset}
className={cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from