vael-ui v0.3.10

Navigation & Menus

Menu

A dropdown list of actions opened from a trigger, with full keyboard navigation.

Install

import { Menu } from 'vael-ui'

Playground

import { Menu } from 'vael-ui'

<Menu side="bottom" align="start" :sideOffset="8" :alignOffset="0" closeOnEsc closeOnOutside :forceMount="false" scrollFade :items="items">Menu</Menu>

Props

NameTypeDefaultDescription
itemsreadonly MenuEntry<T>[] | undefinedData-driven rows. Ignored when the default slot renders custom markup instead.
triggerElTriggerRefExternal ref for a trigger that can't live in the #trigger slot.
side"top" | "right" | "bottom" | "left""bottom"Which side of the trigger the panel opens on.
align"start" | "end" | "center""start"How the panel aligns against the trigger along that side.
sideOffsetnumber | undefined8Gap between the trigger and the panel, in pixels.
alignOffsetnumber | undefined0Shifts the panel along the alignment axis, in pixels.
closeOnEscboolean | undefinedtrueEscape key closes the panel.
closeOnOutsideboolean | undefinedtrueClicking outside the panel closes it.
beforeClose((done: () => void) => void) | undefinedCustom exit animation; call `done()` when it's complete. Delays the actual close/unmount until then.
forceMountboolean | undefinedfalseWhen true, presence is v-show-driven and owned by the consumer (e.g. AnimatePresence).
teleportTostring | HTMLElement | undefined"body"CSS selector or an actual DOM element — same contract as Vue's own Teleport `to`.
scrollFadeboolean | undefinedtrueMasks the panel's top/bottom edge as its content scrolls under it, signaling there's more.
maxPanelHeightnumber | undefinedCaps the panel's height at this many pixels even when the viewport has room for more — the item list scrolls internally past it instead of the panel growing indefinitely. Omitted keeps today's behavior (only the viewport limits it).
uiPartial<{ positioner: UiPartValue; panel: UiPartValue; header: UiPartValue; footer: UiPartValue; }> | undefinedPer-instance part-class/style overrides.
openboolean | undefinedfalseWhether the menu is open.

Slots

NameTypeDescription
trigger{ open: boolean; }Co-located trigger markup — Menu wires the click and anchors to it; render just the button.
headeranyAbove the item list, outside its scroll region — stays put while `items` scrolls underneath.
item{ item: T; }Override one data-driven row's content while keeping its behavior.
default{ close: () => void; open: boolean; isClosing: boolean; cancelClose: () => void; panelEl: HTMLElement | null; placement: string; maxHeight: number | null; }Fully custom menu content — render your own role="menuitem" markup; `items` is ignored.
footeranyBelow the item list, outside its scroll region — stays put while `items` scrolls above it.

Events

NameTypeDescription
open-change[value: boolean, details: PopoverOpenChangeDetails]
select[item: T]
collapse[]
active[value: boolean]
update:open[value: boolean]

Exposed

NameTypeDescription
panelElunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
positionerElunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
listElunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
placementunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
positionerStyleunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
isClosingunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
openunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
toggleunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
closeunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.
cancelCloseunknownType inference unavailable — vue-component-meta cannot resolve defineExpose on this generic component.