Menu

Dropdown menu for structured actions with grouped items, submenus, checkbox and radio items, and horizontal layouts.

import {
Menu,
MenuContent,
MenuItem,
MenuLink,
MenuSeparator,
MenuTrigger,
} from "@plexui/vue/components/Menu";

Examples

Overview

Natural sizing

Horizontal (icons only)

size

Horizontal (icons with labels)

size

Grouped items

Checkbox items

indicatorPosition
indicatorVariant

Radio items

indicatorPosition

Item actions

Destructive items

API

Note: Menu prevents Tab from advancing focus. For generic popover content use Popover instead.

Menu (root)

PropTypeDefaultDescription
force-openboolean—Keep menu open (controlled)
modalbooleanfalseWhether menu is modal (focus trap)
@open() => void—Emitted when menu opens
@close() => void—Emitted when menu closes

MenuTrigger: renders its child (e.g. a Button) as the element that toggles the menu. Other attributes and listeners reach the child.

PropTypeDefaultDescription
disabledbooleanfalsePrevent the menu from opening

MenuContent

PropTypeDefaultDescription
widthnumber | "auto""auto"Panel width (numbers are pixels)
min-widthnumber | "auto"300Minimum panel width
max-heightnumber—Maximum panel height, in pixels
side"top" | "right" | "bottom" | "left""bottom"Preferred placement
side-offsetnumber5Distance from the trigger, in pixels
align"start" | "center" | "end""center"Alignment relative to trigger
align-offsetnumber-5Offset from the start or end alignment, in pixels
layout"vertical" | "horizontal""vertical"Layout direction. Use horizontal for icon toolbars
size"sm" | "md" | "lg""md"Size of horizontal menu items (icon size + padding)
@close-auto-focus(event: Event) => void—Emitted before focus returns to the trigger; call event.preventDefault() to keep it from moving there

MenuItem: list item. Listen to @select or @click for actions; without either the item is non-interactive content.

PropTypeDefaultDescription
descriptionstring—Second line under the label (or the description slot). The label turns semibold on its own
disabledbooleanfalseDisable the item
dangerbooleanfalseDestructive action: the item is drawn in the danger color
@select(event: Event) => void—Called when the item is selected; call event.preventDefault() to keep the menu open
@click(event: MouseEvent) => void—Called when the item is clicked; also makes the item interactive

MenuLink: item that navigates. Internal paths render the link component from PlexUIProvider (for example vue-router's RouterLink); absolute http(s) URLs open in a new tab. Pass href or to, disabled (a disabled link does not navigate), danger, as and link attributes.

MenuSeparator: divider between items. No props.

MenuGroup: groups related items. Wraps MenuItem, MenuLink, or MenuLabel. No specific props.

MenuLabel: non-interactive label for a group. Accepts class.

MenuSub / MenuSubTrigger / MenuSubContent: submenu wrapper (with force-open, @open and @close), trigger (with disabled), and content panel (with width, min-width, max-height, side-offset and align-offset).

MenuCheckboxItem

PropTypeDefaultDescription
checked / v-model:checkedboolean | "indeterminate"falseChecked state
@checked-change(checked: boolean) => void—Emitted with update:checked when the checkbox toggles
@select(event: Event) => void—Call event.preventDefault() to keep the menu open
indicator-position"start" | "end""end"Checkbox position
indicator-variant"solid" | "ghost""solid"Indicator style
disabledbooleanfalseDisable the item

MenuRadioGroup / MenuRadioItem: radio group with v-model:value (plus @change) and indicator-position; MenuRadioItem takes value, disabled and @select.

MenuItemActions / MenuItemAction: MenuItemActions wraps hover actions; MenuItemAction emits @click and closes the menu.

Styling

Menu reads these component tokens. Override them at any scope to restyle it:

  • --menu-checkbox-indicator-size: checkbox indicator size (default var(--font-text-lg-size))
  • --menu-font-size: font size (default var(--font-text-sm-size))
  • --menu-gutter: gutter (default spacing(1.5))
  • --menu-item-background-color: item background color (default light-dark(var(--alpha-08), var(--alpha-10)))
  • --menu-item-gap: item gap (default spacing(1.5))
  • --menu-item-padding: item padding (default spacing(1.5) spacing(2))
  • --menu-line-height: line height (default var(--font-text-sm-line-height))
  • --menu-radio-indicator-hole-size: radio indicator hole size (default var(--font-text-3xs-size))
  • --menu-radio-indicator-size: radio indicator size (default var(--font-text-lg-size))
  • --menu-radius: radius (default var(--radius-xl))
  • --menu-separator-background-color: separator background color (default var(--color-border))
  • --menu-separator-gutter: separator gutter (default var(--menu-gutter) calc(-1 * var(--menu-gutter)))
  • --radio-group-indicator-background-color: indicator background color (default var(--color-background-primary-solid))
  • --radio-group-indicator-border-color: indicator border color (default var(--color-border-primary-outline))
  • --radio-group-indicator-border-color-hover: indicator border color hover (default var(--alpha-25))
  • --radio-group-indicator-hole-background-color: indicator hole background color (default var(--color-text-primary-solid))