Overlaysreadycomponentready
Dropdown Menu
A menu overlay primitive for grouped commands, submenus, checkable items, radio choices, and app-owned cross-component actions.
Import
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from 'radcn/dropdown-menu'Live package example
Render the four upstream Dropdown Menu examples through RadCN primitives and app-owned composition.
Example Parity
Render the four upstream Dropdown Menu examples through RadCN primitives and app-owned composition.
Checkbox persistence is app-owned state.
import { Dialog, DialogContent, DialogHeader, DialogTitle } from 'radcn/dialog'
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger } from 'radcn/dropdown-menu'
export function DropdownMenuExamples() {
return (
<>
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Profile</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<DropdownMenuCheckboxItem checked>Status Bar</DropdownMenuCheckboxItem>
<DropdownMenuRadioGroup value="bottom">
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
<Dialog>
<DialogContent><DialogHeader><DialogTitle>Create New File</DialogTitle></DialogHeader></DialogContent>
</Dialog>
</>
)
}Installation
Intended future install command. RadCN is private and not published to npm yet, so this snippet documents the target user-facing API rather than something external consumers can run today.
pnpm add radcn # intended future package
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from 'radcn/dropdown-menu'Theming
RadCN tokens read the resolved theme from the document. Store the user's preference separately, then resolve system preferences to a concrete light or dark theme before setting package tokens.
<html data-radcn-theme-mode="system" data-radcn-theme="dark">
...
</html>Accessibility
- DropdownMenuTrigger receives aria-haspopup, aria-controls, aria-expanded, and keyboard opening behavior during enhancement.
- DropdownMenuContent renders role="menu", with menuitem, menuitemcheckbox, and menuitemradio roles on interactive items.
- Keyboard behavior covers Enter, Space, Arrow keys, Home, End, Escape, Tab, typeahead, submenu navigation, and disabled item skipping.
- Dropdown Menu is non-modal in RadCN and does not lock body scroll; Dialog composition owns modal focus and scroll behavior separately.
Customization
- DropdownMenu exposes public data-radcn-dropdown-menu hooks for root, trigger, portal, content, labels, groups, items, shortcuts, separators, checkbox items, radio groups, and submenus.
- Checkbox and radio persistence, menu-to-dialog effects, and form values remain app-owned state rather than package-global callbacks.
- Dialog, Field, Input, Textarea, Label, Button, and icon presentation remain separate composition surfaces.
- Tailwind width, padding, flex, and alignment utilities map to RadCN classes, class, style, CSS variables, or small dependency-free browser enhancement.
Remix 3 Notes
- React useState, onCheckedChange, onValueChange, and onSelect map to explicit RadCN props, server/route state, or app-owned browser enhancement.
- modal={false} maps to RadCN Dropdown Menu non-modal behavior; Dialog remains the modal owner when composed from a menu item.
- Button asChild maps to explicit DropdownMenuTrigger styling and composition rather than React Slot semantics.
- lucide-react icons are app-owned presentation; Radix primitive types are read-only upstream evidence and not RadCN dependencies.
- className maps to class, data-slot maps to data-radcn-* hooks, and vendor source remains read-only evidence.
