# or
yarn add @zag-js/menu @zag-js/react
```

## Anatomy

To set up the menu correctly, you'll need to understand its anatomy and how we
name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.



## Usage

First, import the menu package into your project

```jsx
import * as menu from "@zag-js/menu"
```

The menu package exports two key functions:

- `machine` â The state machine logic for the menu widget.
- `connect` â The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll need to provide a unique `id` to the `useMachine` hook. This is used to
> ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
menu machine in your project ð¥

- Destructure the machine's **service** returned from the `useMachine` hook.
- Use the exposed `setParent` and `setChild` functions provided by the menu's
  connect function to assign the parent and child menus respectively.
- Create trigger item's using the `api.getTriggerItemProps(...)` function.

When building nested menus, you'll need to use:

- `setParent(...)` â Function to register a parent menu's machine in the child
  menu's context.
- `setChild(...)` â Function to register a child menu's machine in the parent
  menu's context.

```tsx
import * as menu from "@zag-js/menu"
import { useMachine, normalizeProps, Portal } from "@zag-js/react"
import { useEffect } from "react"

export function NestedMenu() {
  // Level 1 - File Menu
  const fileMenuService = useMachine(menu.machine, {
    id: "1",
    "aria-label": "File",
  })

  const fileMenu = menu.connect(fileMenuService, normalizeProps)

  // Level 2 - Share Menu
  const shareMenuService = useMachine(menu.machine, {
    id: "2",
    "aria-label": "Share",
  })

  const shareMenu = menu.connect(shareMenuService, normalizeProps)

  useEffect(() => {
    setTimeout(() => {
      fileMenu.setChild(shareMenuService)
      shareMenu.setParent(fileMenuService)
    })
  }, [])

  // Share menu trigger
  const shareMenuTriggerProps = fileMenu.getTriggerItemProps(shareMenu)

  return (
    <>
      <button {...fileMenu.getTriggerProps()}>Click me</button>

      <Portal>
        <div {...fileMenu.getPositionerProps()}>
          <ul {...fileMenu.getContentProps()}>
            <li {...fileMenu.getItemProps({ value: "new-tab" })}>New tab</li>
            <li {...fileMenu.getItemProps({ value: "new-win" })}>New window</li>
            <li {...shareMenuTriggerProps}>Share</li>
            <li {...fileMenu.getItemProps({ value: "print" })}>Print...</li>
            <li {...fileMenu.getItemProps({ value: "help" })}>Help</li>
          </ul>
        </div>
      </Portal>

      <Portal>
        <div {...shareMenu.getPositionerProps()}>
          <ul {...shareMenu.getContentProps()}>
            <li {...shareMenu.getItemProps({ value: "messages" })}>Messages</li>
            <li {...shareMenu.getItemProps({ value: "airdrop" })}>Airdrop</li>
            <li {...shareMenu.getItemProps({ value: "whatsapp" })}>WhatsApp</li>
          </ul>
        </div>
      </Portal>
    </>
  )
}
```

## Styling guide

Earlier, we mentioned that each menu part has a `data-part` attribute added to
them to select and style them in the DOM.

### Highlighted item state

When an item is highlighted, via keyboard navigation or pointer, it is given a
`data-highlighted` attribute.

```css
[data-part="item"][data-highlighted] {
  /* styles for highlighted state */
}

[data-part="item"][data-type="radio|checkbox"][data-highlighted] {
  /* styles for highlighted state */
}
```

### Disabled item state

When an item or an option item is disabled, it is given a `data-disabled`
attribute.

```css
[data-part="item"][data-disabled] {
  /* styles for disabled state */
}

[data-part="item"][data-type="radio|checkbox"][data-disabled] {
  /* styles for disabled state */
}
```

### Using arrows

When using arrows within the menu, you can style it using css variables.

```css
[data-part="arrow"] {
  --arrow-size: 20px;
  --arrow-background: red;
}
```

### Checked option item state

When an option item is checked, it is given a `data-state` attribute.

```css
[data-part="item"][data-type="radio|checkbox"][data-state="checked"] {
  /* styles for checked state */
}
```

## Methods and Properties

### Machine Context

The menu machine exposes the following context properties:

<ContextTable name="menu" />

### Machine API

The menu `api` exposes the following methods:

<ApiTable name="menu" />

### Data Attributes

<DataAttrTable name="menu" />

### CSS Variables

<CssVarTable name="menu" />

## Accessibility

Uses
[aria-activedescendant](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-actions-active-descendant/)
pattern to manage focus movement among menu items.

### Keyboard Interactions

**`Space`**
Description: Opens/closes the nested menu.

**`Enter`**
Description: Opens/closes the nested menu.

**`ArrowDown`**
Description: Moves focus to the next item.

**`ArrowUp`**
Description: Moves focus to the previous item.

**`ArrowRight`**
Description: Opens the nested menu.

**`ArrowLeft`**
Description: Closes the nested menu.

**`Esc`**
Description: Closes the nested menu and moves focus to the parent menu item.
An accessible dropdown and context menu that is used to display a list of
actions or options that a user can choose when a trigger element is
right-clicked or long pressed.

## Resources


[Latest version: v1.33.1](https://www.npmjs.com/package/@zag-js/menu)
[Logic Visualizer](https://zag-visualizer.vercel.app/menu)
[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/menu)



**Features**

- Support for items, labels, groups of items
- Focus is fully managed using `aria-activedescendant` pattern
- Typeahead to allow focusing items by typing text
- Keyboard navigation support including arrow keys, home/end, page up/down

## Installation

To use the menu machine in your project, run the following command in your
command line:

```bash
npm install @zag-js/menu @zag-js/react