Components

Menu

Open a positioned menu of actions from a trigger.

Example

Requires React 18.2+ or 19 and shared styles. See setup.

Default

Loading preview…

Code
'use client';
import { Button } from '@swiftuijs/ui';
import { Menu } from '@swiftuijs/ui';
export default function Example() {
    return (<Menu trigger={<Button>Options</Button>} items={[
            { label: 'Edit', action: () => alert('Edit clicked') },
            { label: 'Delete', action: () => alert('Delete clicked') },
            { label: 'Share', action: () => alert('Share clicked') },
        ]}></Menu>);
}

SwiftUI Correspondence: Similar to SwiftUI's Menu. Web behavior: The top-level menu follows the menu-button pattern with keyboard opening, roving focus, and Escape/outside-click dismissal. One submenu level is supported with pointer hover and keyboard traversal.

With Icons

Add icons to menu items:

With Disabled Items

Disable specific menu items:

Placement

Control menu placement:

Nested actions can be presented in a submenu:

Grouped Actions

Sections and destructive actions can be expressed inline with the item list:

Usage and limitations

  • Provide trigger and items. Items accept label, optional icon, action, section, disabled, and destructive styling.
  • Placements are top, bottom, left, or right. The menu follows its anchor and stays inside the viewport.
  • Keyboard navigation, Escape and outside-click dismissal are supported. One submenu level is supported.
  • Long action lists scroll within the viewport; keyboard focus brings the selected action into view. Submenus remain outside the scrolling list.
  • Use short, descriptive action names, group related actions, and clearly mark destructive items. Theme/material preferences follow the originating provider.

More examples

With Icons
With Disabled Items
Placement
Submenus
Grouped Actions

API reference

PropTypeRequiredDescription
itemsIMenuItem[]YesMenu items
triggerReactNodeYesTrigger element
placement'top' | 'bottom' | 'left' | 'right'NoMenu placement Default: 'bottom'
isOpenbooleanNoWhether the menu is open (controlled)
onOpenChange(isOpen: boolean) => voidNoOpen state change handler
glassboolean | { enabled?: boolean; intensity?: number; variant?: 'regular' | 'clear' }NoLocal material override. Intensity is clamped to 0–1; zero uses an opaque surface. Default: Inherited from UIProvider; off without a provider

Inherits additional props from IBaseComponent, GlassSurfaceProps.