# MenuButton

> Slug: `menu-button` · Category: Navigation

## When to use
- A button-style trigger that opens a popup menu (commands, sort, filter, overflow).
- When you need a button with a caret, an icon-only trigger, or a filter-chip trigger that opens a `Menu`.

## When NOT to use
- For a form-field-style dropdown with a label and validation — use `MenuDropdown`.
- For navigation between top-level pages — use `Tabs`/`Subnavigation`.
- For a single yes/no toggle — use `Toggle` or `Button`.

## Variants & decision tree
`variant` chooses the trigger appearance:

- **`'button'`** → standard caret-down menu button. Supports `size`, `monochrome`, `optionalBody` (subtitle text below the trigger).
- **`'icon-button'`** → icon-only trigger via `IconButton`. Pass `icon` and `variantIconButtonBackground` (`'none' | 'secondary' | 'primary'`).
- **`'filter-chip'`** → chip-style trigger via `FilterChip`. Pass `chipType` (`'filter'` | `'sort'`), optional `leadingIcon`, and `selectedItem` to display the current selection.

Use `menuAlignment` (`'leading'` | `'trailing'`) and `menuPlacement` (`'below'` | `'above'`) to position the popup. Pass the menu body via `renderMenu` (typically a `<Menu>`).

## States
- `showMenu` — controls `aria-expanded` on the trigger.
- `disabled` — `aria-disabled`.
- `inverse` — dark-background styling.
- Force-state props (`hover`, `focused`, `pressed`) for visual testing.

## Props
| Prop | Type | Default | Description |
|---|---|---|---|
| `id` | `string` | — | Required; derives `aria-controls` (`{id}-menu`). |
| `label` | `string` | — | Visible label (or `aria-label` for icon-button). |
| `variant` | `'button' \| 'icon-button' \| 'filter-chip'` | — | Trigger style. |
| `size` | `'large' \| 'small'` | `'large'` | Trigger size. |
| `showMenu` | `boolean` | `false` | Maps to `aria-expanded`. |
| `hasPopUp` | `boolean` | — | Sets `aria-haspopup="true"`. |
| `menuAlignment` | `'leading' \| 'trailing'` | `'leading'` | Horizontal align. |
| `menuPlacement` | `'below' \| 'above'` | `'below'` | Vertical placement. |
| `optionalBody` | `string` | — | Subtitle (button variant). |
| `icon` | `ReactNode` | — | Icon (icon-button variant). |
| `selectedItem` | `{ id; text }` | — | Filter-chip selection. |
| `renderMenu` | `ReactNode` | — | Popup contents. |
| `disabled`, `inverse`, `monochrome` | booleans | — | State/styling. |

## Usage examples
```tsx
<MenuButton
  id="sort"
  label="Sort"
  variant="button"
  showMenu={open}
  hasPopUp
  renderMenu={
    <Menu role="menu" behavior="Single select" a11yLabelledBy="sort"
          items={sortOptions} />
  }
/>
```

## Composition
Compose with `Menu` inside `renderMenu`. Manage `showMenu`, outside-click, and item-select externally — these are wrappers, not behavioral.

## Accessibility
- Provide `id` so `aria-controls` resolves to the menu.
- Set `hasPopUp` and toggle `showMenu` so screen readers announce open/close.
- For `icon-button` variant, `label` becomes the `aria-label`.

## Do / Don't
- Do reuse the same `id` on the menu (`{id}-menu`) for `aria-controls` to resolve.
- Don't put a `MenuButton` inside another button.
- Don't use the `'filter-chip'` variant outside filter/sort UIs.
