import { ArgTypes, Markdown, Meta } from '@storybook/addon-docs/blocks';
import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn';
import * as MenuStories from './menu.stories';

<Meta of={MenuStories} /> 

# Menu

[Source code](https://github.com/carbon-design-system/carbon/tree/main/packages/web-components/src/components/Menu)

{/* <!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> */}

- [Overview](#overview)
- [Positioning](#positioning)
- [Subcomponents](#subcomponents)
  - [cds-menu-item](#cds-menu-item)
  - [cds-menu-item-divider](#cds-menu-item-divider)
  - [cds-menu-item-group](#cds-menu-item-group)
  - [cds-menu-item-selectable](#cds-menu-item-selectable)
  - [cds-menu-item-radio-group](#cds-menu-item-radio-group)
- [Feedback](#feedback)

{/* <!-- END doctoc generated TOC please keep comment here to allow auto update --> */}

## Overview

`cds-menu` is a versatile component that can be used in a variety of situations. It
implements the
[menu design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/) defined
in the ARIA Authoring Practices Guide (APG).

The `cds-menu` component's `children` must be a collection of any of these
subcomponents:

- [cds-menu-item](#cds-menu-item)
- [cds-menu-item-divider](#cds-menu-item-divider)
- [cds-menu-item-group](#cds-menu-item-group)
- [cds-menu-item-selectable](#cds-menu-item-selectable)
- [cds-menu-item-radio-group](#cds-menu-item-radio-group)

You can use the events to catch the opening of the menu.

```js
document.addEventListener('cds-menu-opened', (event) => {
  // use values here
});
```

You can use the events to catch the closing of the menu.

```js
document.addEventListener('cds-menu-closed', (event) => {
  // use values here
});
```

## Positioning

You must provide a reference point for the `cds-menu` to position itself at. The
props `x` and `y` either accept a single number each or an array of two numbers.

The latter option is used to specify the trigger boundaries. For example, Carbon
uses this for the
[next version of OverflowMenu](/story/experimental-feature-flags-overflowmenu--overflow-menu)
where we pass `[x, x + width]` and `[y, y + height]` of the trigger button. This
way, the `cds-menu` is able to automatically determine its ideal position on the
screen (which side to open at and in which direction) while always staying
visually attached to the trigger. Each `cds-menu-item` that has `children` and
therfore a submenu uses the same approach under the hood to correctly position
the submenu.

## Subcomponents

### cds-menu-item

A `cds-menu-item` renders a basic menu item with a label an optionally a shortcut
hint (_note: the component only renders this hint and doesn't actually register
the shortcut in the browser_). Each `cds-menu-item` can be clicked unless it's marked
as `disabled`. If it triggers a destructive action, you can pass it
`kind="danger"` to highlight it specially on hover and focus.

```html
<cds-menu @cds-item-opened="${handleMenuOpen}" @cds-item-closed="${handleMenuClose}">
  <cds-menu-item label="Cut" shortcut="⌘X"></cds-menu-item>
  <cds-menu-item label="Copy" shortcut="⌘C"></cds-menu-item>
  <cds-menu-item label="Paste" shortcut="⌘V" disabled></cds-menu-item>
</cds-menu>
```
In order to render an icon for a menu item, you need to pass it as a slot named `render-icon`
to the `cds-menu-item`.

```html
<cds-menu>
  <cds-menu-item label="Cut" shortcut="⌘X">
    ${Cut16({ slot: 'render-icon' })}
    </cds-menu-item>
  <cds-menu-item label="Copy" shortcut="⌘C"></cds-menu-item>
  <cds-menu-item label="Paste" shortcut="⌘V" disabled></cds-menu-item>
</cds-menu>
```
In order to render a submenu, you can pass as a slot named `submenu` inside the  `cds-menu-item`.

```html
<cds-menu>
  <cds-menu-item label="Open"></cds-menu-item>
  <cds-menu-item label="Save"></cds-menu-item>
  <cds-menu-item label="Import">
    <cds-menu-item-radio-group slot="submenu" label="import list">
      <cds-menu-item label="None"></cds-menu-item>
      <cds-menu-item label="Product team"></cds-menu-item>
      <cds-menu-item label="Organization"></cds-menu-item>
      <cds-menu-item label="Company"></cds-menu-item>
    </cds-menu-item-radio-group>
  </cds-menu-item>
</cds-menu>
```

### cds-menu-item-divider

The `cds-menu-item-divider` renders a thin dividing line, visually separating menu
items. Use this to enhance grouping of related items.

```html
<cds-menu>
  <cds-menu-item label="Cut"></cds-menu-item>
  <cds-menu-item label="Copy"></cds-menu-item>
  <cds-menu-item label="Paste"></cds-menu-item>
  <cds-menu-item-divider></cds-menu-item-divider>
  <cds-menu-item label="Delete" kind="danger"></cds-menu-item>
</cds-menu>
```

### cds-menu-item-group

You can logically group multiple menu items by wrapping them inside a
`cds-menu-item-group`. This doesn't affect the visual rendering but can tremendously
improve the experience for assistive technology users. You'll always want to use
a `cds-menu-item-group` if you have multiple
[`cds-menu-item-selectable`](#menuitemselectable) that are relatd to each other.

### cds-menu-item-selectable

`cds-menu-item-selectable` is a checkbox in a menu context. Each `cds-menu-item-selectable`
can be checked and unchecked unrelated to other items. If multiple items are
related to each other, you'll want to wrap them in a `cds-menu-item-group` for
improved accessibility.

```html
<cds-menu>
  <cds-menu-item-group label="Font style">
    <cds-menu-item-selectable label="Bold" selected @cds-item-changed="${handleItemChange}" ></cds-menu-item-selectable>
    <cds-menu-item-selectable label="Italic"></cds-menu-item-selectable>
  </cds-menu-item-group>
</cds-menu>
```
You can use the events to catch the selection change.

```js
document.addEventListener('cds-item-changed', (event) => {
  // use values here
});
```

### cds-menu-item-radio-group

`cds-menu-item-radio-group` is a radio button group in a menu context. Only one item
can be selected at a time. The component automatically wraps itself in a
`cds-menu-item-radio-group`, so you won't have to nest it manually. You need to pass the list of `cds-menu-item` as children to render as radio button items

```html
<cds-menu>
  <cds-menu-item-radio-group label="Font family" @cds-item-changed="${handleItemChange}">
    <cds-menu-item selected="true" label="Sans"></cds-menu-item>
    <cds-menu-item  label="Serif"></cds-menu-item>
    <cds-menu-item label="Mono"></cds-menu-item>
  </cds-menu-item-radio-group>
  <cds-menu-item-divider></cds-menu-item-divider>
   <cds-menu-item-radio-group label="samples" >
      <cds-menu-item label="None"></cds-menu-item>
      <cds-menu-item selected="true" label="Overline"></cds-menu-item>
      <cds-menu-item label="Line-through"></cds-menu-item>
      <cds-menu-item label="Underline"></cds-menu-item>
    </cds-menu-item-radio-group>
</cds-menu>
```
You can use the events to catch the selection change.

```js
document.addEventListener('cds-item-changed', (event) => {
  // use values here
});
```

## Feedback

Help us improve this component by providing feedback, asking questions on Slack,
or updating this file on
[GitHub](https://github.com/carbon-design-system/carbon/edit/main/packages/web-components/src/components/Menu/Menu.mdx).