Skip to content

Menu

An action dropdown triggered by any slotted element. Presents a list of ore-menu-item actions in a floating panel using viewport-aware positioning. Supports full keyboard navigation and accessibility semantics.

Placement

Control which side of the trigger the panel opens on. The menu automatically flips to avoid viewport clipping.

PreviewCode
RTL
html
<ore-menu placement="bottom-start">
  <ore-button slot="trigger" variant="outline" size="sm"
    >Bottom Start <ore-icon name="arrow-down-left" size="16"></ore-icon
  ></ore-button>
  <ore-menu-item value="a">Option A</ore-menu-item>
  <ore-menu-item value="b">Option B</ore-menu-item>
</ore-menu>

<ore-menu placement="bottom-end">
  <ore-button slot="trigger" variant="outline" size="sm"
    >Bottom End <ore-icon name="arrow-down-right" size="16"></ore-icon
  ></ore-button>
  <ore-menu-item value="a">Option A</ore-menu-item>
  <ore-menu-item value="b">Option B</ore-menu-item>
</ore-menu>

<ore-menu placement="top-start">
  <ore-button slot="trigger" variant="outline" size="sm"
    >Top Start <ore-icon name="arrow-up-left" size="16"></ore-icon
  ></ore-button>
  <ore-menu-item value="a">Option A</ore-menu-item>
  <ore-menu-item value="b">Option B</ore-menu-item>
</ore-menu>

Items with Icons

Use the icon named slot on each ore-menu-item for leading icons.

Icons

These examples use inline SVG slot content so they stay framework and icon-library agnostic.

PreviewCode
RTL
html
<ore-menu>
  <ore-button slot="trigger">File</ore-button>
  <ore-menu-item value="new">
    <ore-icon slot="icon" name="file" size="18"></ore-icon>
    New File
  </ore-menu-item>
  <ore-menu-item value="open">
    <ore-icon slot="icon" name="folder" size="18"></ore-icon>
    Open…
  </ore-menu-item>
  <ore-menu-item value="save">
    <ore-icon slot="icon" name="save" size="18"></ore-icon>
    Save
  </ore-menu-item>
  <ore-menu-item value="delete" disabled>
    <ore-icon slot="icon" name="trash-2" size="18"></ore-icon>
    Delete (disabled)
  </ore-menu-item>
</ore-menu>

Disabled Items

Set disabled on a ore-menu-item to prevent selection. The item is still visible but non-interactive. Use disabled for permissions that might change rather than removing the item entirely, to signal that the action exists but is unavailable.

PreviewCode
RTL
html
<ore-menu>
  <ore-button slot="trigger" variant="flat">More options</ore-button>
  <ore-menu-item value="view">View details</ore-menu-item>
  <ore-menu-item value="export">Export</ore-menu-item>
  <ore-menu-item value="archive" disabled>Archive (no permission)</ore-menu-item>
  <ore-menu-item value="delete" disabled>Delete (no permission)</ore-menu-item>
</ore-menu>

Disabled Menu

Set disabled on the ore-menu element to prevent the panel from opening at all.

PreviewCode
RTL
html
<ore-menu disabled>
  <ore-button slot="trigger" disabled>Disabled menu</ore-button>
  <ore-menu-item value="a">Option A</ore-menu-item>
</ore-menu>

Listening to Events

html
<ore-menu id="action-menu">
  <ore-button slot="trigger">Actions</ore-button>
  <ore-menu-item value="rename">Rename</ore-menu-item>
  <ore-menu-item value="move">Move to folder</ore-menu-item>
  <ore-menu-item value="delete">Delete</ore-menu-item>
</ore-menu>

<script type="module">
  import '@vielzeug/refine/menu';
  import '@vielzeug/refine/button';

  const menu = document.getElementById('action-menu');

  // Fired when a menu item is selected
  menu.addEventListener('select', (e) => {
    console.log('selected:', e.detail.value, 'checked:', e.detail.checked);
    switch (e.detail.value) {
      case 'rename':
        openRenameDialog();
        break;
      case 'move':
        openMoveDialog();
        break;
      case 'delete':
        confirmDelete();
        break;
    }
  });

  // Fired when the panel opens
  menu.addEventListener('open', (e) => {
    console.log('menu opened via:', e.detail.reason); // 'programmatic' or 'trigger'
  });

  // Fired when the panel closes
  menu.addEventListener('close', (e) => {
    console.log('menu closed via:', e.detail.reason); // 'escape', 'outside-click', 'programmatic', or 'trigger'
  });
</script>

Use value on each item to handle selection in a single select listener rather than per-item click handlers. Keep menu items short and action-oriented (verb + noun: "Edit post", "Delete file").

Trigger with an Icon Button

Any element works as the trigger — including icon-only buttons. Always provide a visible label or aria-label on an icon-only trigger button so the purpose is clear to screen reader users.

PreviewCode
RTL
html
<ore-menu>
  <ore-button slot="trigger" variant="ghost" size="sm" aria-label="More options">
    <ore-icon name="ellipsis" size="18"></ore-icon>
  </ore-button>
  <ore-menu-item value="edit">Edit</ore-menu-item>
  <ore-menu-item value="copy">Copy link</ore-menu-item>
  <ore-menu-item value="report">Report</ore-menu-item>
</ore-menu>

Separator

Use ore-menu-separator to add a horizontal divider between groups of related items.

PreviewCode
RTL
html
<ore-menu>
  <ore-button slot="trigger">File</ore-button>
  <ore-menu-item value="new">New File</ore-menu-item>
  <ore-menu-item value="open">Open…</ore-menu-item>
  <ore-menu-separator></ore-menu-separator>
  <ore-menu-item value="save">Save</ore-menu-item>
  <ore-menu-item value="save-as">Save As…</ore-menu-item>
  <ore-menu-separator></ore-menu-separator>
  <ore-menu-item value="delete" disabled>Delete</ore-menu-item>
</ore-menu>

Checkable Items

Checkbox Items

Set type="checkbox" on a ore-menu-item to make it toggleable. Clicking or pressing Enter/Space toggles the checked attribute and emits select with checked in the event detail. The menu stays open when a checkbox item is activated.

PreviewCode
RTL
html
<ore-menu id="view-menu">
  <ore-button slot="trigger">View</ore-button>
  <ore-menu-item value="sidebar" type="checkbox" checked>Show Sidebar</ore-menu-item>
  <ore-menu-item value="toolbar" type="checkbox">Show Toolbar</ore-menu-item>
  <ore-menu-item value="statusbar" type="checkbox" checked>Show Status Bar</ore-menu-item>
</ore-menu>

<script>
  document.getElementById('view-menu').addEventListener('select', (e) => {
    console.log(e.detail.value, 'checked:', e.detail.checked);
  });
</script>

Radio Items

Set type="radio" to create a group where only one item can be checked at a time. Selecting a radio item automatically unchecks all other type="radio" siblings.

PreviewCode
RTL
html
<ore-menu id="sort-menu">
  <ore-button slot="trigger">Sort By</ore-button>
  <ore-menu-item value="name" type="radio" checked>Name</ore-menu-item>
  <ore-menu-item value="date" type="radio">Date Modified</ore-menu-item>
  <ore-menu-item value="size" type="radio">File Size</ore-menu-item>
</ore-menu>

API Reference

ore-menu Attributes

AttributeTypeDefaultDescription
placement'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end''bottom-start'Preferred panel placement (auto-flips near viewport edges)
color'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'Color theme
size'sm' | 'md' | 'lg''md'Size theme
disabledbooleanfalsePrevent the menu from opening

ore-menu Slots

SlotDescription
triggerThe element that opens/closes the menu panel
(default)ore-menu-item elements to display as menu options

ore-menu-item Attributes

AttributeTypeDefaultDescription
valuestring''Value emitted in the select event detail
type'checkbox' | 'radio'Makes the item checkable; radio items are mutually exclusive
checkedbooleanfalseWhether a checkable item is currently checked
disabledbooleanfalsePrevent the item from being selected

ore-menu-item Slots

SlotDescription
iconOptional leading icon or decoration
(default)Item label text

Events

EventDetailDescription
select{ value: string, checked?: boolean }Emitted when a menu item is selected. checked is present for type="checkbox" and type="radio" items
open{ reason: 'programmatic' | 'trigger' }Emitted when the panel opens.
close{ reason: 'escape' | 'outside-click' | 'programmatic' | 'trigger' }Emitted when the panel closes.

CSS Custom Properties (ore-menu)

PropertyDescriptionDefault
--menu-panel-min-widthMinimum width of the panel10rem
--menu-panel-radiusBorder radius of the panelvar(--rounded-lg)
--menu-panel-shadowBox shadow of the panelvar(--shadow-xl)
--menu-panel-bgPanel background surfaceTheme-dependent
--menu-panel-border-colorPanel border colorTheme-dependent
--menu-panel-blurPanel backdrop blur amountvar(--blur-md)
--menu-item-hover-bgItem background on hoverTheme-dependent
--menu-item-focus-colorItem text color when keyboard-focusedTheme-dependent
--menu-item-focus-bgItem background when keyboard-focusedTheme-dependent
--menu-item-selection-bgBackground for checkbox/radio items (unselected)Theme-dependent
--menu-item-checked-colorItem text color when checkedTheme-dependent
--menu-item-checked-bgItem background when checkedTheme-dependent

Accessibility

The menu component follows WAI-ARIA Menu Button Pattern best practices.

Arrow keys move focus between items; Enter / Space activates the focused item; Escape closes the panel and returns focus to the trigger. Home / End jump to the first or last item. Outside clicks and Tab also close the menu and restore focus to the trigger.

The panel has role="menu" and aria-orientation="vertical". The trigger element receives aria-haspopup="menu", aria-expanded, and aria-controls pointing to the menu panel. Each item has role="menuitem" and aria-disabled when disabled. Checkable items automatically switch to role="menuitemcheckbox" or role="menuitemradio" with the appropriate aria-checked value.