Dropdown Menu
A contextual action menu anchored to a trigger. Supports icons, keyboard shortcuts, labels, separators, submenus, checkbox items, radio groups, and full keyboard navigation (Arrow keys, Home, End, Escape).
Basic with submenu
Compose DropdownItem, DropdownLabel, DropdownSeparator,
and DropdownSub inside DropdownMenu. Hover "Share" to open the nested submenu.
import {
DropdownMenu, DropdownItem, DropdownSeparator,
DropdownLabel, DropdownSub, Button,
} from "@usevyre/react";
<DropdownMenu trigger={<Button variant="secondary">Actions</Button>}>
<DropdownLabel>File</DropdownLabel>
<DropdownItem icon={<EditIcon />} shortcut="⌘E" onSelect={handleEdit}>Edit</DropdownItem>
<DropdownItem icon={<CopyIcon />} shortcut="⌘D" onSelect={handleDuplicate}>Duplicate</DropdownItem>
<DropdownSub trigger="Share" icon={<ShareIcon />}>
<DropdownItem onSelect={handleEmail}>Email</DropdownItem>
<DropdownItem onSelect={handleLink}>Copy link</DropdownItem>
</DropdownSub>
<DropdownSeparator />
<DropdownItem variant="danger" icon={<TrashIcon />} onSelect={handleDelete}>Delete</DropdownItem>
</DropdownMenu> <script setup>
import {
DropdownMenu, DropdownItem, DropdownSeparator,
DropdownLabel, DropdownSub, Button,
} from "@usevyre/vue";
</script>
<template>
<DropdownMenu>
<template #trigger><Button variant="secondary">Actions</Button></template>
<DropdownLabel>File</DropdownLabel>
<DropdownItem shortcut="⌘E" @select="handleEdit">Edit</DropdownItem>
<DropdownItem shortcut="⌘D" @select="handleDuplicate">Duplicate</DropdownItem>
<DropdownSub trigger="Share">
<DropdownItem @select="handleEmail">Email</DropdownItem>
<DropdownItem @select="handleLink">Copy link</DropdownItem>
</DropdownSub>
<DropdownSeparator />
<DropdownItem variant="danger" @select="handleDelete">Delete</DropdownItem>
</DropdownMenu>
</template> Checkbox items
Use DropdownCheckboxItem for toggle options that don't close the menu after selection.
import { DropdownMenu, DropdownCheckboxItem, DropdownLabel, DropdownSeparator } from "@usevyre/react";
const [showToolbar, setShowToolbar] = useState(true);
const [showPanel, setShowPanel] = useState(false);
<DropdownMenu trigger={<Button variant="secondary">View</Button>}>
<DropdownLabel>Toggle panels</DropdownLabel>
<DropdownSeparator />
<DropdownCheckboxItem checked={showToolbar} onCheckedChange={setShowToolbar}>
Toolbar
</DropdownCheckboxItem>
<DropdownCheckboxItem checked={showPanel} onCheckedChange={setShowPanel}>
Side Panel
</DropdownCheckboxItem>
</DropdownMenu> <script setup>
import { DropdownMenu, DropdownCheckboxItem, DropdownLabel, DropdownSeparator } from "@usevyre/vue";
const showToolbar = ref(true);
const showPanel = ref(false);
</script>
<template>
<DropdownMenu>
<template #trigger><Button variant="secondary">View</Button></template>
<DropdownLabel>Toggle panels</DropdownLabel>
<DropdownSeparator />
<DropdownCheckboxItem v-model:checked="showToolbar">Toolbar</DropdownCheckboxItem>
<DropdownCheckboxItem v-model:checked="showPanel">Side Panel</DropdownCheckboxItem>
</DropdownMenu>
</template> Radio group
Wrap DropdownRadioItem inside DropdownRadioGroup for exclusive
single-selection options.
import { DropdownMenu, DropdownRadioGroup, DropdownRadioItem, DropdownLabel } from "@usevyre/react";
const [theme, setTheme] = useState("system");
<DropdownMenu trigger={<Button variant="secondary">Theme: {theme}</Button>}>
<DropdownLabel>Appearance</DropdownLabel>
<DropdownRadioGroup value={theme} onValueChange={setTheme}>
<DropdownRadioItem value="light">Light</DropdownRadioItem>
<DropdownRadioItem value="dark">Dark</DropdownRadioItem>
<DropdownRadioItem value="system">System</DropdownRadioItem>
</DropdownRadioGroup>
</DropdownMenu> <script setup>
import { DropdownMenu, DropdownRadioGroup, DropdownRadioItem } from "@usevyre/vue";
const theme = ref("system");
</script>
<template>
<DropdownMenu>
<template #trigger><Button variant="secondary">Theme: {{ theme }}</Button></template>
<DropdownRadioGroup v-model="theme">
<DropdownRadioItem value="light">Light</DropdownRadioItem>
<DropdownRadioItem value="dark">Dark</DropdownRadioItem>
<DropdownRadioItem value="system">System</DropdownRadioItem>
</DropdownRadioGroup>
</DropdownMenu>
</template> Placement
bottom-start aligns the menu's left edge to the trigger's left edge.
bottom-end aligns to the right edge (useful for menus inside right-aligned toolbars).
<DropdownMenu placement="bottom-start" trigger={<Button>bottom-start</Button>}>...</DropdownMenu>
<DropdownMenu placement="bottom-end" trigger={<Button>bottom-end</Button>}>...</DropdownMenu> <DropdownMenu placement="bottom-end">
<template #trigger><Button>bottom-end</Button></template>
...
</DropdownMenu> DropdownMenu props
Props
| Prop | Type | Default | Description |
|---|---|---|---|
trigger | ReactElement | — | (React) The trigger button. Passed as a prop. |
#trigger slot | slot | — | (Vue) The trigger button. Use the named slot. |
placement | "bottom-start" | "bottom-end" | "top-start" | "top-end" | "bottom-start" | Position relative to the trigger. |
class / className | string | — | Additional CSS class on the menu panel. |
DropdownItem props
Props
| Prop | Type | Default | Description |
|---|---|---|---|
onSelect / @select | () => void | — | Called when item is clicked. Menu closes automatically. |
disabled | boolean | false | Prevents selection and dims the item. |
variant | "default" | "danger" | "default" | Danger variant renders the item in red. |
icon | ReactNode / #icon slot | — | Icon displayed to the left of the label. |
shortcut | string | — | Keyboard hint displayed on the right (e.g. "⌘K"). |
DropdownCheckboxItem props
Props
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | Controlled checked state. |
onCheckedChange / v-model:checked | (v: boolean) => void | — | Called when item is toggled. |
disabled | boolean | false | Prevents interaction. |
shortcut | string | — | Keyboard hint on the right. |
DropdownRadioGroup props
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value / v-model | string | — | Currently selected value. |
onValueChange | (value: string) => void | — | (React) Called when selection changes. |
DropdownSub props
Props
| Prop | Type | Default | Description |
|---|---|---|---|
trigger | ReactNode / string | — | Label shown in the parent menu for the submenu trigger. |
icon | ReactNode | — | Optional icon to the left of the trigger label. |
placement | "right" | "left" | "right" | Which side the submenu opens on. |
disabled | boolean | false | Prevents the submenu from opening. |
Common AI mistakes
- DropdownItem variant="primary"→ Use variant="danger" for destructive items only
Quick examples
<DropdownMenu trigger={<Button variant="secondary">Options</Button>}>
<DropdownItem onSelect={() => handleEdit()}>Edit</DropdownItem>
<DropdownItem onSelect={() => handleDuplicate()}>Duplicate</DropdownItem>
<DropdownSeparator />
<DropdownItem variant="danger" onSelect={() => handleDelete()}>Delete</DropdownItem>
</DropdownMenu>