Bridge UI

Menu

Anchored floating panel for actions and dropdowns.

Introduction

Menus display a list of choices on a temporary surface. They appear when the user interacts with a trigger—a button, icon button, or other control—and close after a selection or when dismissed.

Menu vs Select: Use Menu for action lists and commands (Edit, Delete, Share) where each item triggers behavior. Use Select for form fields where the user picks one or more values from a predefined set, with label, validation, and controlled value state. Menus close after a typical action; Select stays open for multi-select and integrates with form field chrome.

Compose menu content with a List of ListItem rows inside the panel.

Import

import { Menu } from "@bridge-ui/vue/Components/Menu";
import { Menu } from "@bridge-ui/react/Components/Menu";

Basic usage

Provide a trigger via the trigger slot (Vue) or slots.trigger (React). Put menu content such as a List with ListItem elements inside the panel.

External anchor

Pass anchorEl to position against an element outside the menu instead of using the trigger slot. Control visibility with show / v-model and toggle the opener yourself.

Placement

Use the placement prop to position the panel relative to the trigger. The default is bottom-start. This example uses top-start.

Persistent

When persistent is true, Escape and click-away do not close the menu. Toggle it closed programmatically or via the trigger.

Dismiss behavior

Fine-tune closing with closeOnEscape, closeOnClickAway, and the @close / onClose event. Use rounded and shadow to style the panel.

List, Button, Select

Accessibility

  • Provide the trigger via the trigger slot with a button that has an accessible name.
  • On open, focus moves to the first focusable item unless disableAutoFocus is set.
  • Escape closes the menu when closeOnEscape is true (default).
  • Click-away closes the menu when closeOnClickAway is true (default).
  • Set role="menuitem" on ListItem rows inside the panel for screen reader context.

Anatomy

<div> <!-- Menu root -->
  <button> <!-- trigger slot -->
  <div> <!-- portaled panel -->
    <ul> <!-- List content -->
      <li> <!-- ListItem rows -->
    </ul>
  </div>
</div>

The panel is portaled to teleportTo (default "body") and positioned relative to the trigger or anchorEl.

API

Prop Type Default Description
@close — — Fired when the user dismisses (Escape or click-away). Not fired when the parent sets v-model={false} directly.
@show-change (show: boolean) => void — Equivalent to onShowChange when you prefer events over a callback prop.
v-model boolean — Two-way binding for overlay visibility.
Prop Type Default Description
onClose () => void — Fired when the user dismisses (Escape or click-away). Not fired when the parent sets show={false} directly.
onShowChange (show: boolean) => void — Called when visibility changes.
show boolean — Whether the overlay is visible. Use with onShowChange for controlled state.
Prop Type Default Description
anchorEl HTMLElement | RefObject<HTMLElement | null> | null — External anchor element for positioning.
classes MenuClasses — Class overrides for menu parts.
closeOnClickAway boolean true Whether the menu closes when clicking outside.
closeOnEscape boolean true Whether the menu closes on Escape.
customProps MenuCustomProps — Props forwarded to each menu part.
disableAutoFocus boolean false When true, the menu does not auto-focus the first focusable item on open.
disableScrollLock boolean true When true, body scroll is not locked while the menu is open.
keepMounted boolean false When true, the menu stays mounted after closing (hidden).
matchWidth boolean false When true, the panel width matches the trigger / anchor.
offset number 4 Gap between trigger and panel (px).
persistent boolean false When true, Escape and click-away do not close the menu.
placement PositionPlacement "bottom-start" Preferred placement relative to the anchor.
rounded MenuRounded "md" Border radius of the menu panel.
shadow MenuShadow "md" Shadow applied to the menu panel.
slots MenuSlots — Slot overrides. Use trigger for the opener element.
strategy PositionStrategy "fixed" CSS position strategy for the floating panel.
teleportTo string | false "body" Portal target. Pass false to render in place.