8.8 KiB
DropdownMenu
(no submodules)
- dropdown-menu.variants — `dropdownMenuContentVarian…-
dropdown-menu.variants —
dropdownMenuContentVariants,dropdownMenuItemVariants,dropdownMenuLabelVariants,dropdownMenuSeparatorVariants… -
dropdown-menu.variants — `dropdownMenuContentVarian…
-
dropdown-menu.variants —
dropdownMenuContentVariants,dropdownMenuItemVariants,dropdownMenuLabelVariants,dropdownMenuSeparatorVariants… -
dropdown-menu.variants — `dropdownMenuContentVarian…
-
dropdown-menu.variants —
dropdownMenuContentVariants,dropdownMenuItemVariants,dropdownMenuLabelVariants,dropdownMenuSeparatorVariants… -
dropdown-menu.variants — `dropdownMenuContentVarian…
-
dropdown-menu.variants —
dropdownMenuContentVariants,dropdownMenuItemVariants,dropdownMenuLabelVariants,dropdownMenuSeparatorVariants… -
dropdown-menu.variants —
dropdownMenuContentVariants,dropdownMenuItemVariants,dropdownMenuLabelVariants,dropdownMenuSeparatorVariants…
Purpose
<DropdownMenu> and its sub-components (<DropdownMenuTrigger>, <DropdownMenuContent>, <DropdownMenuItem>, <DropdownMenuGroup>, <DropdownMenuLabel>, <DropdownMenuSeparator>, <DropdownMenuShortcut>, <DropdownMenuCheckboxItem>, <DropdownMenuRadioGroup>, <DropdownMenuRadioItem>, <DropdownMenuSub>, <DropdownMenuSubTrigger>, <DropdownMenuSubContent>, <DropdownMenuPortal>) are the chassis dropdown-menu primitive built on @radix-ui/react-dropdown-menu. Radix supplies the WAI-ARIA menu semantics (role="menu", role="menuitem", arrow-key roving focus, type-ahead search, Escape closes, focus-trap while open, restore-focus to the trigger on close), and the chassis layers cva slots, theme overrides, and a translated <DropdownMenuShortcut> aria-keyshortcuts attribute on top.
Composition rule (shadcn skill rule): items typically sit inside a <DropdownMenuGroup> so screen-readers announce them as one set. Single ungrouped items at the top level are also acceptable. Sub-menus pair <DropdownMenuSubTrigger> with <DropdownMenuSubContent> inside a <DropdownMenuSub>.
Features
- WAI-ARIA menu semantics from Radix.
- Arrow-key roving focus + type-ahead search.
- Escape closes; click-outside dismisses; restore-focus to the trigger on close.
- Auto-portalled
<DropdownMenuContent>(matches shadcn upstream — consumers do not need to remember<DropdownMenuPortal>). <DropdownMenuShortcut>accepts anariaKeyShortcutsKeytranslation key so the localised shortcut announcement reaches assistive tech.<DropdownMenuCheckboxItem>/<DropdownMenuRadioGroup>/<DropdownMenuRadioItem>with 32-px gutter for the indicator.<DropdownMenuSub>for nested sub-menus with a chevron indicator (RTL-flipped viartl:rotate-180).insetvariant on<DropdownMenuItem>/<DropdownMenuLabel>/<DropdownMenuSubTrigger>aligns with checkbox/radio rows.- All sub-components forward refs to their underlying Radix elements.
Usage: Basic Example
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@suaveplan/react-ui";
export function UserMenu() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open menu</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Sign out</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
}
Usage: Advanced Example
import {
Button,
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@suaveplan/react-ui";
import { useState } from "react";
export function EditorMenu() {
const [showLineNumbers, setShowLineNumbers] = useState(true);
const [theme, setTheme] = useState<"light" | "dark">("light");
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">View</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>Editor</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
Save
<DropdownMenuShortcut ariaKeyShortcutsKey="app.shortcuts.save">
⌘S
</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem
checked={showLineNumbers}
onCheckedChange={(checked) =>
setShowLineNumbers(Boolean(checked))
}
>
Line numbers
</DropdownMenuCheckboxItem>
<DropdownMenuRadioGroup
value={theme}
onValueChange={(v) => setTheme(v as "light" | "dark")}
>
<DropdownMenuRadioItem value="light">
Light theme
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="dark">
Dark theme
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Export</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>PDF</DropdownMenuItem>
<DropdownMenuItem>HTML</DropdownMenuItem>
<DropdownMenuItem>Markdown</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuContent>
</DropdownMenu>
);
}
API Reference
<DropdownMenu>
The Radix Root. Standard Radix Root props (open, defaultOpen, onOpenChange, modal, dir).
<DropdownMenuTrigger>
Wraps the Radix Trigger (renders a <button> or polymorphically the child via asChild).
<DropdownMenuContent>
The floating menu surface. Auto-portalled. Accepts standard Radix Content props (side, align, sideOffset, alignOffset, collisionPadding, etc.).
<DropdownMenuItem>
A single menu item.
| Prop | Type | Default | Description |
|---|---|---|---|
inset |
boolean |
false |
Adds 32-px left gutter. |
disabled |
boolean |
false |
Skips in keyboard nav and ignores activation. |
onSelect |
(event: Event) => void |
none | Fires on activation. |
<DropdownMenuGroup>, <DropdownMenuLabel>, <DropdownMenuSeparator>
Standard menu structure. <DropdownMenuLabel> accepts an inset prop for alignment.
<DropdownMenuShortcut>
Keyboard-shortcut hint pinned at the end of an item.
| Prop | Type | Default | Description |
|---|---|---|---|
ariaKeyShortcutsKey |
TranslationKey |
none | When present, sets aria-keyshortcuts to the translated shortcut. |
<DropdownMenuCheckboxItem>, <DropdownMenuRadioGroup>, <DropdownMenuRadioItem>
Standard Radix props (checked, onCheckedChange, value, onValueChange).
<DropdownMenuSub>, <DropdownMenuSubTrigger>, <DropdownMenuSubContent>
Nested sub-menu. <DropdownMenuSubTrigger> accepts an inset prop and renders a chevron icon (RTL-flipped via rtl:rotate-180).
Implementation Notes
- The chassis NEVER assigns a numeric
z-indexto the menu — Radix portals handle stacking. - The check / dot indicators sit at
start-2(logical property) so they flip correctly in RTL contexts. motion-reduce:animate-nonecollapses the open/close transition forprefers-reduced-motion: reduce.- The
<DropdownMenuShortcut>separates the visible text (passed as children) from the localised announcement (ariaKeyShortcutsKey) so a glyph like⌘Scan be shown to sighted users while screen-readers hear "Command S" or the localised equivalent. - Per the shadcn skill rule, items in groups MUST live inside
<DropdownMenuGroup>for correct screen-reader announcement. <DropdownMenuContent>auto-portals via<DropdownMenuPortal>so consumers do not have to remember to wrap manually — matches shadcn upstream's convention.