# Dropdown Menu Submenu

## Usage

A single menu row that reveals a nested flyout of its own items. The row adopts `DropdownMenuItem` semantics (`label` / `icon` / `description` / `isDisabled`); its children become the flyout content. Opens inline-end with viewport auto-flip; Right/Enter/Space opens and focuses the first item, Left/Escape closes and returns focus to the trigger (Right/Left swap in RTL). On a phone (a coarse pointer, decided when the menu opened) the row drills in instead: its rows replace the menu's rows in the same box, led by a Back row named "Back to \<parent\>", and Back, Escape or ArrowLeft return to the row. Host attributes and DOM event handlers (`aria-`, `data-`, `id`) reach the trigger row, the element carrying `role="menuitem"` and `aria-haspopup="menu"`; a caller's handlers run after the row's own, except for the keys that open the flyout (the open arrow, Enter, Space) and a click on a disabled row. For data-driven menus, give a menu item a nested `items` array instead of using this component directly.

```ts
import { DropdownMenuSubMenu } from '@astryx-vue/core/DropdownMenu'
```

```vue
<script setup lang="ts">
import { DropdownMenu, DropdownMenuItem, DropdownMenuSubMenu } from '@astryx-vue/core/DropdownMenu'
</script>

<template>
  <DropdownMenu :button="{ label: 'Actions' }">
    <DropdownMenuItem label="Rename" />
    <DropdownMenuSubMenu label="Move to">
      <DropdownMenuItem label="Projects" />
      <DropdownMenuItem label="Archive" />
      <DropdownMenuItem label="Trash" />
    </DropdownMenuSubMenu>
  </DropdownMenu>
</template>
```

## DropdownMenuSubMenu Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string \| number` | — | The row's text, and the parent name used by the Back row of the next level. |
| `description` | `string \| number` | — | Secondary line under the label. |
| `icon` | `string \| Component` | — | Icon before the label. |
| `isDisabled` | `boolean` | `false` | The row cannot open the next level. |
| `hasSpinner` | `boolean` | `false` | Replaces the caret with a spinner while the next level is loading. The spinner is decorative and does not block opening. |
| `menuWidth` | `number \| string` | — | Width of the flyout. A number is pixels, used as a minimum and capped to the viewport. An intrinsic keyword becomes the preferred width. Unused while drilled in. |
| `presentation` | `'flyout' \| 'drill-in' \| 'adaptive'` | `'adaptive'` | How the next level appears: beside the row, in place of the current rows, or chosen when the menu opens from whether the surface is a compact touch screen. |

## Events

| Name | Payload | Description |
| --- | --- | --- |
| `openChange` | `boolean` | Fired when the flyout or the drilled view opens or closes. |

## Slots

- `default`: the rows of the nested menu — action rows, checkbox rows, radio groups, and deeper submenus.
- `icon`: arbitrary leading content, replacing the `icon` prop.
- `label`: rich content replacing the `label` prop.
- `description`: rich content replacing the `description` prop.

## Row element

The row is the element carrying `role="menuitem"` and `aria-haspopup="menu"`. A row that navigates is not this component: a submenu row always opens the next level, so put the address on the rows inside it.
