Dropdown
Toggleable contextual overlays for displaying lists of links, actions, or custom content. Dropdowns support directional placement, glass styling, split buttons, and dark mode out of the box.
Basic Dropdown
<!-- Basic dropdown -->
<div class="vd-dropdown">
<button class="vd-btn vd-btn-primary vd-dropdown-toggle" data-vd-dropdown-toggle>
Actions <i class="ph ph-caret-down"></i>
</button>
<ul class="vd-dropdown-menu">
<li><a class="vd-dropdown-item" href="#">Edit</a></li>
<li><a class="vd-dropdown-item" href="#">Duplicate</a></li>
<li><a class="vd-dropdown-item" href="#">Archive</a></li>
<li><div class="vd-dropdown-divider"></div></li>
<li><a class="vd-dropdown-item vd-dropdown-item-danger" href="#">Delete</a></li>
</ul>
</div>Split Button & Glass
<!-- Split button: primary action + caret -->
<div class="vd-dropdown vd-dropdown-split">
<button class="vd-btn vd-btn-primary">Save</button>
<button class="vd-btn vd-btn-primary vd-dropdown-toggle" data-vd-dropdown-toggle aria-label="Save options">
<i class="ph ph-caret-down"></i>
</button>
<ul class="vd-dropdown-menu">
<li><a class="vd-dropdown-item" href="#">Save & Publish</a></li>
<li><a class="vd-dropdown-item" href="#">Save as Draft</a></li>
</ul>
</div>
<!-- Glass variant -->
<div class="vd-dropdown vd-dropdown-glass">
<button class="vd-btn vd-btn-outline vd-dropdown-toggle" data-vd-dropdown-toggle>
Glass Menu <i class="ph ph-caret-down"></i>
</button>
<ul class="vd-dropdown-menu">
<li><a class="vd-dropdown-item" href="#">Profile</a></li>
<li><a class="vd-dropdown-item" href="#">Settings</a></li>
</ul>
</div>Placement Variants
<!-- Dropup (opens above) -->
<div class="vd-dropdown vd-dropdown-dropup">
<button class="vd-btn vd-dropdown-toggle" data-vd-dropdown-toggle>Dropup</button>
<ul class="vd-dropdown-menu"><li><a class="vd-dropdown-item" href="#">Item</a></li></ul>
</div>
<!-- Dropright (opens to the right) -->
<div class="vd-dropdown vd-dropdown-dropright">
<button class="vd-btn vd-dropdown-toggle" data-vd-dropdown-toggle>Dropright</button>
<ul class="vd-dropdown-menu"><li><a class="vd-dropdown-item" href="#">Item</a></li></ul>
</div>
<!-- Static alignment override -->
<div class="vd-dropdown">
<button class="vd-btn vd-dropdown-toggle" data-vd-dropdown-toggle>End-aligned</button>
<ul class="vd-dropdown-menu vd-dropdown-menu-end">
<li><a class="vd-dropdown-item" href="#">Item</a></li>
</ul>
</div>Engine wiring
import { ref } from 'vue';
import { useDropdown } from "@vanduo-oss/vd3";
const root = ref<HTMLElement | null>(null);
const dropdown = useDropdown(root); // wires every .vd-dropdown inside root; cleanup on unmount
// Programmatic control via the returned controller
dropdown.open('#my-dropdown'); // pass a selector (resolved inside root) or the elementAPI Reference
Modifier classes
| Class | Description |
|---|---|
.vd-dropdown | Root container. Holds toggle + menu. |
.vd-dropdown-toggle | Clickable trigger (button or anchor). `data-vd-dropdown-toggle` is also accepted. |
.vd-dropdown-menu | The menu element. Visibility toggled via `.is-open`. |
.vd-dropdown-item | A menu item. Disabled variants: `.is-disabled` / `.disabled`. |
.vd-dropdown-divider | Horizontal rule between item groups. |
.vd-dropdown-item-danger | Item styled as destructive action. |
.vd-dropdown-split | Container modifier: split-button variant (action + caret toggle). |
.vd-dropdown-glass | Container modifier: glass-styled menu (uses `--vd-glass-*` tokens). |
.vd-dropdown-dropup | Container modifier: opens upward instead of downward. |
.vd-dropdown-dropright / .vd-dropdown-dropleft | Container modifier: horizontal placement. |
.vd-dropdown-menu-end / .vd-dropdown-menu-start / .vd-dropdown-menu-top | Auto-applied to position the menu; can also be set statically. |
Base classes
| Class | Description |
|---|---|
.vd-dropdown | Container with `position: relative`. Click capture boundary. |
.vd-dropdown-toggle | Button with caret; receives `aria-haspopup="true"` and `aria-expanded` toggling. |
.vd-dropdown-menu | Absolute-positioned menu, hidden by default, fade-in on `.is-open`. |
.vd-dropdown-item | Block-level link/button. Focusable. Hover/focus highlight via `--vd-color-primary-rgb`. |
.vd-dropdown-divider | 1px line via `--vd-border-color`; vertical margin uses Fibonacci scale. |
.vd-dropdown-item-danger | Foreground `--vd-color-red-6` / `--vd-color-red-5`; signals destructive action. |
CSS Variables
| Variable | Default | Description |
|---|---|---|
--vd-dropdown-bg | var(--vd-color-gray-0) | Menu background |
--vd-dropdown-text | var(--vd-color-gray-9) | Menu foreground |
--vd-dropdown-border-color | var(--vd-border-color) | Menu border |
--vd-dropdown-radius | var(--vd-border-radius) | Menu corner radius |
--vd-dropdown-shadow | var(--vd-shadow-md) | Menu elevation shadow |
--vd-dropdown-min-width | 12rem | Menu minimum width |
--vd-dropdown-padding | 0.5rem | Item vertical/horizontal padding |
--vd-dropdown-z-index | 1050 | Stacking above page content |
Accessibility
- Trigger carries
aria-haspopup="true"and togglesaria-expanded. - Menu carries
role="menu"andaria-hiddenmirroring its open state. - Arrow keys cycle items, Home/End jump, Escape closes, typeahead jumps to the first matching label.
- Focus is restored to the trigger when the menu closes.