# Nav Heading Menu

## Usage

Accessible menu container and items for nav heading popovers. `NavHeadingMenu` provides `role="menu"` with keyboard navigation; `NavHeadingMenuItem` renders individual selectable items. Pass it to the `menu` slot of `SideNavHeading` or `TopNavHeading`.

```ts
import { NavHeadingMenu } from '@astryx-vue/core/NavMenu'
```

```vue
<script setup lang="ts">
import { NavHeadingMenu, NavHeadingMenuItem } from '@astryx-vue/core/NavMenu'
import { SideNav, SideNavHeading } from '@astryx-vue/core/SideNav'
</script>

<template>
  <SideNav>
    <template #header>
      <SideNavHeading heading="Acme Platform">
        <template #menu>
          <NavHeadingMenu label="Acme Platform" size="lg">
            <NavHeadingMenuItem href="/dashboard" label="Dashboard" />
            <NavHeadingMenuItem href="/analytics" label="Analytics" />
          </NavHeadingMenu>
        </template>
      </SideNavHeading>
    </template>
  </SideNav>
</template>
```

### Anatomy

- **Menu**: Menu container for nav-heading actions, with menu semantics and keyboard navigation.
- **Item**: Selectable action or navigation link inside the Menu.
- **Icon**: Icon-rendered artwork shown before an Item label.
- **Text-rendered item label**: String Item label rendered through Text.
- **Caller-rendered item label**: Non-string Item label content rendered directly by the caller.
- **Item description**: Supporting description rendered through Text.

## NavHeadingMenu Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | — | Accessible name of the menu, written to `aria-label`. Set it when the heading text alone does not say what the menu is. |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Width of the menu, which also sets the padding of each item. |
| `minWidth` | `number \| string` | — | Overrides the minimum width that the size would give. A number is pixels. |
| `focusRequest` | `'first' \| 'last' \| null` | `null` | Moves focus to the first or the last item once the menu opens. The heading's disclosure passes this in, so a keyboard open lands on an item. |

## NavHeadingMenu events

| Name | Description |
| --- | --- |
| `close` | Fired on Escape. `SideNavHeading` and `TopNavHeading` already listen for it and close the popover. |

## NavHeadingMenu slots

| Name | Description |
| --- | --- |
| `default` | The menu items. |

## NavHeadingMenuItem Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | — | Primary text of the item. The default slot renders rich content instead. |
| `description` | `string` | — | Supporting line under the text. |
| `href` | `string` | — | Renders the item as a link when set. |
| `as` | `NavLinkComponent` | `'a'` | Link root, for example `RouterLink`. The item then sets both `href` and `to`. |
| `iconClass` | `string` | — | CSS icon class drawn before the text. |
| `isDisabled` | `boolean` | `false` | Disabled. A click does nothing, and the arrow keys and typeahead skip the item. |

## NavHeadingMenuItem events

| Name | Payload | Description |
| --- | --- | --- |
| `click` | `MouseEvent` | Fired when the item is activated, before the menu closes. |

## NavHeadingMenuItem slots

| Name | Description |
| --- | --- |
| `default` | Rich content replacing the `label` prop. |
| `icon` | Icon content, used ahead of the glyph from `iconClass`. |

The whole menu is one `role="menu"`: arrow keys move between items and wrap at both ends, typing a letter jumps to the next item that starts with it, and Escape closes the popover and returns focus to the heading.
