Examples
When to use
Use DropdownMenu for a short, focused list of actions or settings that belongs to one trigger. Use a select for a form value, tabs for peer views that should remain visible, and a dialog when the task needs explanation or several fields.
View options, export actions, or a compact set of related commands.
Do not hide essential navigation, long forms, or a single obvious action in a menu.
Usage
The live preview and this copied example use the same group, checkbox, radio, submenu, disabled item, and state model:
"use client";
import { ChevronDown } from "@phuctech/ui/icons";
import { Button } from "@phuctech/ui/components/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@phuctech/ui/components/dropdown-menu";
export function Example() {
return (
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button variant="outline">
View options
<ChevronDown aria-hidden="true" />
</Button>
}
/>
<DropdownMenuContent align="start">
<DropdownMenuItem>Show archived</DropdownMenuItem>
<DropdownMenuItem>Compact density</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
Composition
Start with DropdownMenu and a DropdownMenuTrigger. Render the trigger as the existing Button, then place the menu items inside DropdownMenuContent. The content wrapper portals automatically so a nearby overflow boundary cannot clip it. Use labels and separators to create small groups; reserve submenus for a second level that is genuinely related to the parent action.
DropdownMenuItemis for an immediate action.DropdownMenuCheckboxItemis for an independent toggle.DropdownMenuRadioGroupandDropdownMenuRadioItemare for one choice from a set.DropdownMenuSubgroups a second level without creating a separate page.- Use
disabledfor unavailable actions and a visible explanation when needed.
Variants and states
DropdownMenu does not add a visual variant or size enum: the trigger composes Button, while the menu surface uses the shared popover tokens. The meaningful states are open/closed, disabled, checkbox selection, radio selection, and nested submenu open/closed. Choose controlled state only when the surrounding feature needs to coordinate the menu.
Icons
Use a decorative PhucTech cue such as ChevronDown beside a visible trigger label and mark it aria-hidden="true". An icon-only trigger is allowed only when it has a concise accessible name and the surrounding context makes the menu action clear.
API
The package wrapper in packages/ui/src/components/dropdown-menu.tsx exposes Base UI menu primitives with PhucTech visual classes. It keeps Base UI's behavior and uses render for composition; there is no asChild prop.
Tokens
Accessibility
- Focus the trigger and press Enter or Space to open the menu.
- Use Arrow Down and Arrow Up to move through items; Base UI handles type-ahead.
- Press Enter or Space to select an item. Arrow Right opens a submenu and Arrow Left returns to its parent.
- Press Escape to close the menu and return focus to the trigger. Verify this after any custom close behavior.
- Give the trigger a visible label; do not place essential instructions only inside a hover state.
Do and don’t
Keep items short, group related actions, and test portal positioning at both viewport edges.
Put a long form, essential navigation, or a destructive action without confirmation inside a casual menu.
Related
- Button is the recommended trigger composition.
- Elevation documents the surface and portal hierarchy.
- Accessibility documents focus and keyboard review.