# 导航菜单

## 使用方法

`NavMenu` 是 `role="menu"` 的菜单。`NavMenuItem` 是其中一项，有 `href` 时是链接。`NavDisclosure` 负责触发按钮、定位和关闭：点击、悬停、点击外部和 Escape 都会关掉。ArrowDown 打开并聚焦第一项，ArrowUp 聚焦最后一项。菜单内部方向键移动，单字符会按前缀匹配。

顶栏和溢出列表已经包好了这组零件。需要自己做账号菜单时直接用它们。

挂在侧栏或顶栏标题上的菜单用 `NavHeadingMenu` 和 `NavHeadingMenuItem`。把它放进标题的 `menu` 插槽即可，关闭和打开后的焦点由标题负责。有地址的项是链接，没有地址的项是 `menuitem`。方向键移动，Enter 或 Space 激活当前项。

```vue
<script setup lang="ts">
import { NavDisclosure, NavMenu, NavMenuItem } from '@astryx-vue/core/NavMenu'
</script>

<template>
  <NavDisclosure label="账号">
    <template #trigger="{ isOpen, panelId }">
      <button type="button" :aria-controls="panelId" :aria-expanded="isOpen">
        账号
      </button>
    </template>
    <template #default="{ close, focusRequest }">
      <NavMenu label="账号" :focus-request="focusRequest" @close="close">
        <NavMenuItem href="/profile" label="个人资料" />
      </NavMenu>
    </template>
  </NavDisclosure>
</template>
```

## 最佳实践

| 指引 | 实践 |
| --- | --- |
| 推荐 | 触发按钮写上 <code>aria-expanded</code> 和 <code>aria-controls</code>，插槽已经把状态传出来了。 |
| 推荐 | 选中一项后默认关闭。需要留下菜单时给项设置 <code>keepOpen</code>。 |
| 避免 | 不要把菜单项单独放进抽屉。抽屉里把 <code>isMenuItem</code> 设成 false，避免菜单项脱离菜单。 |

## 示例

### 产品切换

侧栏标题打开产品切换菜单，里面是 Dashboard、Analytics 和 Settings。

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

<template>
  <div style="height: 100px">
    <SideNav>
      <template #header>
        <SideNavHeading heading="Acme Platform">
          <template #icon>
            <span class="i-carbon-grid css-icon css-icon--sm" />
          </template>
          <template #menu>
            <NavHeadingMenu label="Acme Platform" size="lg">
              <NavHeadingMenuItem href="/dashboard" label="Dashboard" />
              <NavHeadingMenuItem href="/analytics" label="Analytics" />
              <NavHeadingMenuItem href="/settings" label="Settings" />
            </NavHeadingMenu>
          </template>
        </SideNavHeading>
      </template>
    </SideNav>
  </div>
</template>
```

## NavMenu Props

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | - | 菜单的无障碍名称。 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 菜单宽度档。 |
| `focusRequest` | `'first' \| 'last' \| null` | `null` | 打开后把焦点放到第一项或最后一项。 |

## NavMenu 事件

| 名称 | 说明 |
| --- | --- |
| `close` | 按下 Escape 时触发。由 `NavDisclosure` 接住并关闭面板。 |

## NavMenuItem Props

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | - | 菜单项文字。 |
| `description` | `string` | - | 显示在文字下面的辅助说明。 |
| `href` | `string` | - | 有地址时渲染成链接。 |
| `as` | `NavLinkComponent` | `'a'` | 链接根组件。 |
| `iconClass` | `string` | - | 图标 CSS class。 |
| `isDisabled` | `boolean` | `false` | 禁用。键盘导航会跳过。 |
| `keepOpen` | `boolean` | `false` | 选中后不关闭菜单。 |
| `isMenuItem` | `boolean` | `true` | 在菜单里是 `menuitem`。抽屉里设为 false。 |

## NavDisclosure Props

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | - | 弹出层的无障碍名称。 |
| `placement` | `'above' \| 'below' \| 'start' \| 'end'` | `'below'` | 相对触发器的位置。 |
| `alignment` | `'start' \| 'center' \| 'end'` | `'start'` | 沿交叉轴的对齐。 |
| `hover` | `boolean` | `false` | 悬停一段时间后打开，离开后关闭。 |
| `showDelay` | `number` | `150` | 悬停打开前的等待，毫秒。 |
| `hideDelay` | `number` | `200` | 指针离开后的关闭等待，毫秒。 |

## NavHeadingMenu Props

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | - | 菜单的无障碍名称。 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 菜单宽度档，也会传给每一项的内边距。 |
| `minWidth` | `number \| string` | - | 覆盖按档位算出的最小宽度。数字按像素。 |
| `focusRequest` | `'first' \| 'last' \| null` | - | 打开后聚焦第一项或最后一项。放在标题菜单插槽里时，标题会传入这个值。 |

## NavHeadingMenu 事件

| 名称 | 说明 |
| --- | --- |
| `close` | 按下 Escape 时触发。 |

## NavHeadingMenuItem Props

| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | - | 主文字。默认插槽优先。 |
| `description` | `string` | - | 主文字下面的辅助说明。 |
| `href` | `string` | - | 有地址时渲染成链接。 |
| `as` | `NavLinkComponent` | `'a'` | 链接根组件。 |
| `iconClass` | `string` | - | 图标 CSS class。 |
| `isDisabled` | `boolean` | `false` | 禁用。方向键和首字母查找会跳过。 |
