Vize

Dropdown Menu

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