> For the complete documentation index, see [llms.txt](https://analog.groupthought.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://analog.groupthought.com/reference/alpine/menu.md).

# x-menu

Directives and a magic for dropdown menus that follow the ARIA menu-button pattern: arrow-key focus, type-ahead, and disabled items.

Directives and a magic for dropdown menus that follow the ARIA menu-button pattern: arrow-key focus, type-ahead, and disabled items.

| Directive / magic | What it does                                                                                                                 |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `x-menu`          | The root. Builds on `x-popup` for the open state                                                                             |
| `x-menu:button`   | Toggles the menu (`aria-haspopup="menu"`). ArrowDown opens and focuses the first item; ArrowUp opens and focuses the last    |
| `x-menu:popup`    | The floating panel around the menu. Modifiers are `x-float` positioning modifiers (default `bottom-start.flip.update.shift`) |
| `x-menu:menu`     | The list (`role="menu"`). Handles arrow-key navigation and type-ahead                                                        |
| `x-menu:item`     | A menu item (`role="menuitem"`)                                                                                              |
| `$menu`           | Everything on `$popup`, plus `bindButton(el)`                                                                                |

ArrowUp and ArrowDown move through enabled items and wrap at the ends. Typing a character focuses the next matching item. Escape closes the menu and returns focus to the button. A click or focus outside also closes it. The menu uses the button as its accessible name and skips items with `aria-disabled="true"`.

Analog doesn't currently use `x-menu`. Its dropdowns use selects and popovers.

## Examples

### A basic menu

Use `x-menu:button`, `x-menu:menu`, and `x-menu:item` to build a dropdown of actions:

```html
<div x-menu>
  <button x-menu:button>Actions</button>
  <div x-menu:popup x-cloak>
    <ul x-menu:menu>
      <li><button x-menu:item @click="duplicate()">Duplicate</button></li>
      <li><button x-menu:item @click="remove()">Delete</button></li>
    </ul>
  </div>
</div>
```

Menu items act; they do not hold a selection. For picking one value out of a list, use [x-select](/reference/alpine/select.md) instead.

### Disabled items

Use `aria-disabled="true"` to keep an item visible but out of keyboard navigation:

```html
<li><button x-menu:item aria-disabled="true">Delete</button></li>
```

Arrow keys and type-ahead skip disabled items. Style them through the attribute, for example `aria-disabled:opacity-50`.

### Positioning the menu

Pass `x-float` modifiers on `x-menu:popup` to pick the side and offset:

```html
<div x-menu:popup.top-end.offset.8px.flip.shift x-cloak>…</div>
```

Passing any modifier replaces the whole default string. The full modifier list lives on the [x-float](/reference/alpine/float.md) page.

### A detached button

Use `$menu.bindButton(el)` when the button cannot live inside the `x-menu` element:

```html
<div x-data>
  <button x-ref="menuButton">Actions</button>

  <div x-menu x-init="$menu.bindButton($refs.menuButton)">
    <div x-menu:popup x-cloak>
      <ul x-menu:menu>…</ul>
    </div>
  </div>
</div>
```

`bindButton` gives the outside element the click toggle, ArrowDown/ArrowUp behavior, and ARIA attributes from `x-menu:button`.

## Options

The root takes no options object. The open state and auto-close behavior come from [x-popup](/reference/alpine/popup.md), and the panel's positioning modifiers pass to [x-float](/reference/alpine/float.md). Submenus are not supported.
