Skip to main content

Menu

Dropdown menus with nested submenus and keyboard navigation.

Usage

<w-menu>
<w-slot trigger><button>Actions</button></w-slot>
<w-slot body>
<div>
<w-slot item name="edit"><button>Edit</button></w-slot>
<w-slot item name="duplicate"><button>Duplicate</button></w-slot>
<w-slot item name="delete"><button>Delete</button></w-slot>
</div>
</w-slot>
</w-menu>

Props

PropTypeDefaultDescription
openbooleanfalseWhether the menu is open
placementstring"bottom-start"Menu position relative to trigger
persistentbooleanfalsePrevent closing via Escape or outside click
closeOnSelectbooleantrueClose menu when item is selected
portalbooleantrueTeleport content to body for z-index safety

Slots

SlotElementDescription
triggerButtonElement that opens the menu
contentContainerMenu container
itemButtonMenu item (optionally with name attribute)
submenuContainerNested submenu content

Events

EventDetailDescription
open-Fired when menu opens
close-Fired when menu closes
select{ item, element }Fired when an item is selected

Methods

MethodDescription
show()Open the menu
hide()Close the menu
toggle(force?)Toggle open state

Keyboard

KeyAction
Enter / Space / ArrowDownOpen menu (on trigger)
ArrowUpOpen menu and focus last item
ArrowDownFocus next item
ArrowUpFocus previous item
ArrowRightOpen submenu
ArrowLeftClose submenu, return to parent
HomeFocus first item
EndFocus last item
EscapeClose menu
TabClose menu

Examples

With Submenus

<w-menu>
<w-slot trigger><button>File</button></w-slot>
<w-slot body>
<div>
<w-slot item name="new"><button>New</button></w-slot>
<w-slot item name="open"><button>Open</button></w-slot>

<w-slot item name="recent">
<div>
Recent Files
<w-slot sub>
<div>
<w-slot item name="file1"><button>Document.pdf</button></w-slot>
<w-slot item name="file2"><button>Image.png</button></w-slot>
</div>
</w-slot>
</div>
</w-slot>

<w-slot item name="save"><button>Save</button></w-slot>
</div>
</w-slot>
</w-menu>

Custom Placement

<w-menu placement="right-start">
<w-slot trigger><button>Options</button></w-slot>
<w-slot body><div>...</div></w-slot>
</w-menu>

Available placements:

  • top, top-start, top-end
  • bottom, bottom-start, bottom-end
  • left, left-start, left-end
  • right, right-start, right-end

Keep Open on Select

<w-menu closeOnSelect="false">
<!-- Menu stays open after selecting items -->
</w-menu>

Persistent Menu

A persistent menu cannot be dismissed by pressing Escape or clicking outside.

<w-menu persistent>
<w-slot trigger><button>Options</button></w-slot>
<w-slot body>
<div>
<w-slot item name="done"><button>Done</button></w-slot>
</div>
</w-slot>
</w-menu>

CSS Transitions

.menu-enter { }
.menu-enter-from { opacity: 0; transform: translateY(-4px); }
.menu-enter-to { opacity: 1; transform: translateY(0); }

.menu-leave { }
.menu-leave-from { opacity: 1; }
.menu-leave-to { opacity: 0; }

Accessibility

  • Trigger has aria-haspopup="menu" and aria-expanded
  • Content has role="menu"
  • Items have role="menuitem"
  • Submenus linked with aria-controls
  • Roving tabindex for navigation
  • Auto-positioned to stay in viewport