Accessible, unstyled DropdownMenu: a menu button (WAI-ARIA APG) that opens a positioned menu. Items, groups, radio/checkbox items, and submenus are the shared Menu parts re-exported under DropdownMenu names.
|
|
| Package |
@vizejs/ui/dropdown-menu |
| Maturity |
stable |
| Own the source |
vize lib pull dropdown-menu |
| Requires |
menu, collection, context, controllable-state, dismissable-layer, focus-scope, id, inert-outside, pointer-grace, portal, positioner, presence, scroll-lock, typeahead |
| Aliases |
menu button, actions menu, overflow menu, kebab menu |
| Covers |
WAI-ARIA menu button pattern, Radix Dropdown Menu, Reka UI Dropdown Menu |
Usage
import { DropdownMenu, DropdownMenuRoot, DropdownMenuTrigger } from "@vizejs/ui/dropdown-menu";
Or copy the source into your project with vize lib pull dropdown-menu (see Source Distribution).
API
Source: src/families/menus/dropdown-menu/dropdown-menu-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
modal |
boolean |
true |
Make outside content inert and lock document scroll while open. |
dir |
MenuDirection |
undefined |
Reading direction: flips submenu arrow keys and submenu placement. undefined inherits DirectionProvider/LocaleProvider, then "ltr". |
loop |
boolean |
false |
Wrap arrow-key navigation from the last item to the first and back. |
disabled |
boolean |
false |
Prevent opening and close the menu when it becomes disabled. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired with the requested open value (supports v-model:open). |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request with the previous value and native event. |
Slots
| Slot |
Slot props |
Description |
default |
MenuSlotState |
Trigger and content. Receives the menu open state. |
Source: src/families/menus/dropdown-menu/dropdown-menu-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
modal |
boolean |
true |
Make outside content inert and lock document scroll while open. |
dir |
MenuDirection |
undefined |
Reading direction: flips submenu arrow keys and submenu placement. undefined inherits DirectionProvider/LocaleProvider, then "ltr". |
loop |
boolean |
false |
Wrap arrow-key navigation from the last item to the first and back. |
disabled |
boolean |
false |
Prevent opening and close the menu when it becomes disabled. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired with the requested open value (supports v-model:open). |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request with the previous value and native event. |
Slots
| Slot |
Slot props |
Description |
default |
MenuSlotState |
Trigger and content. Receives the menu open state. |
Source: src/families/menus/dropdown-menu/dropdown-menu-trigger.vue
Props
| Prop |
Type |
Default |
Description |
disabled |
boolean |
false |
Remove the trigger from activation and sequential keyboard focus. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
openOn |
"click" | "pointerdown" |
"pointerdown" |
Primary mouse button event that toggles the menu. pointerdown opens on press (native menu feel, press-drag-release selection); click waits for release. |
Events
| Event |
Payload |
Description |
pointerdown |
[nativeEvent: PointerEvent] |
Fired before a primary-button pointer-down toggles the menu; preventable. |
keydown |
[nativeEvent: KeyboardEvent] |
Fired before keyboard handling; call preventDefault() to skip the built-in keys. |
Slots
| Slot |
Slot props |
Description |
default |
MenuSlotState |
Trigger contents. Receives the menu open state. |
Behavior
@vizejs/ui/dropdown-menu is the WAI-ARIA APG menu button built on the shared menu core
(see ../menu/menu.behavior.md). dropdown-menu-root.vue publishes data-menu-kind="dropdown-menu";
dropdown-menu-trigger.vue adds press-to-open pointer semantics. Items, groups, submenus,
and content are the Menu SFCs re-exported under DropdownMenu* names. Every row is proven by
the named test in dropdown-menu.test.ts or dropdown-menu-ssr.test.ts.
| # |
State |
Input |
Outcome |
Proven by |
| D1 |
closed / open |
primary mouse pointer-down |
toggles; opening prevents trigger focus and focuses the content; the same press's click does not toggle again |
mouse pointer-down toggles the menu and focuses the content |
| D2 |
closed |
secondary button, ctrl-press, touch tap |
secondary and ctrl presses are ignored; touch taps toggle on click |
secondary buttons and ctrl-clicks do not toggle; touch taps toggle on click |
| D3 |
openOn="click" |
pointer-down then click |
only the click toggles |
openOn click waits for the click |
| D4 |
closed |
ArrowUp / keyboard or AT click (detail: 0) |
opens with the last or first item focused; Escape returns focus to the trigger |
keyboard and assistive-technology activation focus the first or last item |
| D5 |
closed |
prevented pointerdown / keydown emits |
state is unchanged |
preventable pointerdown and keydown emits keep the menu closed |
| D6 |
disabled trigger |
any activation |
native disabled; nothing opens |
disabled triggers ignore every activation |
| D7 |
open |
keyboard into a submenu and select |
shared menu parts: submenu keyboard entry, selection closes every level and returns focus to the trigger |
items and submenus are the shared menu parts |
| D8 |
SSR |
two requests + hydrate |
byte-identical markup with data-menu-kind="dropdown-menu" and warning-free hydration |
renders identical dropdown markup across SSR requests and hydrates cleanly |