import { ArgsTable, Meta, Story } from "@storybook/addon-docs";
import { Avatar } from "@components/avatar";
import { Button, IconButton } from "@components/button";
import { ComponentInfo, Preview, Tagline } from "@stories/components";
import { DisclosureArrow } from "@components/disclosure";
import { Divider, InnerDivider } from "@components/divider";
import { PlaceholderMajorIcon, IconList, VerticalDotsMajorIcon, UfoMajorIcon, TelescopeMajorIcon, RocketMajorIcon } from "@components/icons";
import { InnerItem, InnerSection, Item, Section } from "@components/collection";
import { InnerMenu, InnerMenuItem, InnerMenuSection, InnerMenuTrigger, Menu, MenuTrigger } from "@components/menu";
import { Text } from "@components/typography";
import { Tooltip, TooltipTrigger } from "@components/tooltip";

<Meta
    title="Components/Menu"
    id="menu"
/>

# Menu

<Tagline>A menu offers a list of choices to the user, such as a set of actions or functions.</Tagline>

<ComponentInfo
    usage={"import { MenuTrigger, Menu, Item, Section, Divider, MenuTriggerContext, useMenuTriggerContext } from \"@sharegate/orbit-ui\";"}
    ariaPath="menu"
    githubPath="/packages/components/src/menu/src"
/>

## Usage

A menu accepts exactly two children: the element which trigger the opening of the menu and the menu items. A trigger can be any component which accepts a `ref` and any other props passed from menu.

### Default

A default menu.

<Preview>
    <Story name="default">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">Launch...</Item>
                <Item key="eject">Eject...</Item>
                <Item key="land">Land...</Item>
                <Item key="help">Help</Item>
                <Item key="exit">Exit</Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Sections

A menu items can be group by sections.

<Preview>
    <Story name="sections">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Section title="Actions">
                    <Item key="launch">Launch...</Item>
                    <Item key="eject">Eject...</Item>
                    <Item key="land">Land...</Item>
                </Section>
                <Section title="Others">
                    <Item key="help">Help</Item>
                    <Item key="exit">Exit</Item>
                </Section>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Dividers

A menu items can be separated by dividers.

<Preview>
    <Story name="dividers">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">Launch...</Item>
                <Item key="eject">Eject...</Item>
                <Item key="land">Land...</Item>
                <Divider />
                <Item key="help">Help</Item>
                <Item key="exit">Exit</Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Item icon

A menu item can have [icons](?path=/docs/icon-gallery--page).

<Preview>
    <Story name="item icon">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">
                    <PlaceholderMajorIcon />
                    <Text>Launch...</Text>
                </Item>
                <Item key="eject">
                    <PlaceholderMajorIcon />
                    <Text>Eject...</Text>
                </Item>
                <Item key="land">
                    <PlaceholderMajorIcon />
                    <Text>Land...</Text>
                </Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Item end icon

A select item can have *non standard* end [icons](?path=/docs/icon-gallery--page) can be provided to handle special cases like displaying a list of icons. However, think twice before adding *end* icons, *start* icons should be your go to.

<Preview>
    <Story name="item end icon">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">
                    <Text>Launch...</Text>
                    <IconList slot="end-icon">
                        <UfoMajorIcon />
                        <TelescopeMajorIcon />
                        <RocketMajorIcon />
                    </IconList>
                </Item>
                <Item key="eject">
                    <Text>Eject...</Text>
                    <PlaceholderMajorIcon slot="end-icon" />
                </Item>
                <Item key="land">
                    <Text>Land...</Text>
                    <IconList slot="end-icon">
                        <UfoMajorIcon />
                        <TelescopeMajorIcon />
                        <RocketMajorIcon />
                    </IconList>
                </Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Item description

A menu item can have a **single line** description.

<Preview>
    <Story name="item description">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">
                    <Text>Launch...</Text>
                    <Text slot="description">Launch...</Text>
                </Item>
                <Item key="eject">
                    <Text>Eject...</Text>
                    <Text slot="description">Eject...</Text>
                </Item>
                <Item key="land">
                    <Text>Land...</Text>
                    <Text slot="description">Land on Of Course I Still Love You</Text>
                </Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

A description can be paired with an [icon](?path=/docs/icon-gallery--page).

<Preview>
    <Story name="item description + icon">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">
                    <PlaceholderMajorIcon />
                    <Text>Launch...</Text>
                    <Text slot="description">Launch...</Text>
                </Item>
                <Item key="eject">
                    <PlaceholderMajorIcon />
                    <Text>Eject...</Text>
                    <Text slot="description">Eject...</Text>
                </Item>
                <Item key="land">
                    <PlaceholderMajorIcon />
                    <Text>Land...</Text>
                    <Text slot="description">Land on Of Course I Still Love You</Text>
                </Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

A description can also be paired with an [avatar](?path=/docs/avatar--default-story)

<Preview>
    <Story name="item description + avatar">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">
                    <Avatar name="Sally Ride" />
                    <Text>Sally Ride</Text>
                    <Text slot="description">First American woman to go into space</Text>
                </Item>
                <Item key="eject">
                    <Avatar name="Alan Shepard" />
                    <Text>Alan Shepard</Text>
                    <Text slot="description">American astronaut, naval aviator, test pilot, and businessman</Text>
                </Item>
                <Item key="land">
                    <Avatar name="Chris Hadfield" />
                    <Text>Chris Hadfield</Text>
                    <Text slot="description">First Canadian Astronaut to walk in space</Text>
                </Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Item tooltip

A menu item can have a basic tooltip.

<Preview>
    <Story name="item tooltip">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item key="launch">Launch...</Item>
                <Item key="eject">Eject...</Item>
                <TooltipTrigger>
                    <Item key="land">Land...</Item>
                    <Tooltip>Land on Of Course I Still Love You</Tooltip>
                </TooltipTrigger>
                <Item key="help">Help</Item>
                <Item key="exit">Exit</Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Disabled item

A menu item can be disabled.

<Preview>
    <Story name="disabled item">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                <Item disabled key="launch">Launch...</Item>
                <Item key="eject">Eject...</Item>
                <Item disabled key="land">Land...</Item>
                <Item key="help">Help</Item>
                <Item key="exit">Exit</Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Validation

A menu can display a validation state to communicate to the user whether the current value is valid or invalid. Implement your own validation logic in your app and pass either `"valid"` or `"invalid"` to the menu via the `validationState` prop.

<Preview>
    <Story name="validation">
        <Menu validationState="invalid" defaultSelectedKeys={["land"]} selectionMode="single" aria-label="View tasks">
            <Item key="launch">Launch...</Item>
            <Item key="eject">Eject...</Item>
            <Item key="land">Land...</Item>
            <Item key="help">Help</Item>
            <Item key="exit">Exit</Item>
        </Menu>
    </Story>
</Preview>

### Selection

A menu supports multiple selection modes. By default, selection is disabled, however this can be changed by settings the `selectionMode` property to `"single"` or `"multiple"`.

> When using selection with a `<Menu>` component wraped inside a `<MenuTrigger>`, you must handled the selected keys in controlled mode with the `selectedKeys` property otherwise the selected keys won't be persisted through openings.

<Preview filePath="/menu/docs/Selection" />

### Custom trigger

A menu trigger can update is appareance based on the `isOpen` value by using `useMenuTriggerContext`.

Any trigger would work as long as it accepts a `ref` and any other props provided by the menu.

<Preview filePath="/menu/docs/CustomTrigger" />

### Disclosure arrow

You can use a [disclosure arrow](?path=/docs/disclosure-arrow--context) component to hint that activating the button will display additional content.

<Preview>
    <Story name="disclosure arrow">
        <MenuTrigger>
            <Button variant="secondary">
                <Text>Trigger</Text>
                <DisclosureArrow slot="end-icon" />
            </Button>
            <Menu>
                <Item key="launch">Launch...</Item>
                <Item key="eject">Eject...</Item>
                <Item key="land">Land...</Item>
                <Item key="help">Help</Item>
                <Item key="exit">Exit</Item>
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Dynamic items

A menu items can be rendered dynamically.

<Preview>
    <Story name="dynamic items">
        <MenuTrigger>
            <IconButton variant="secondary" aria-label="View tasks">
                <VerticalDotsMajorIcon />
            </IconButton>
            <Menu>
                {["Launch", "Eject", "Land", "Help", "Exit"].map(x => (
                    <Item key={x.toLowerCase()}>{x}</Item>
                ))}
            </Menu>
        </MenuTrigger>
    </Story>
</Preview>

### Controlled

The `selectedKey` and `open` state can be handled in controlled mode.

<Preview filePath="/menu/docs/ControlledMenu" />

### Opening a modal

A `ModalTrigger` component won't work with a menu item. Still, it can be done with a [custom modal trigger](?path=/docs/modal--default-story#custom-trigger).

<Preview filePath="/menu/docs/Modal" />

## API

### MenuTrigger

<ComponentInfo
    usage={"import { MenuTrigger } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerMenuTrigger.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerMenuTrigger} sort="alpha" />

### Menu

<ComponentInfo
    usage={"import { Menu } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerMenu.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerMenu} sort="alpha" />

### Item

<ComponentInfo
    usage={"import { Item } from \"@sharegate/orbit-ui\";"}
    slots={["icon", "text", "description", "end-icon"]}
    compact
/>

<ArgsTable of={InnerItem} sort="alpha" />

### Section

<ComponentInfo
    usage={"import { Section } from \"@sharegate/orbit-ui\";"}
    compact
/>

<ArgsTable of={InnerSection} sort="alpha" />

### Divider

<ComponentInfo
    usage={"import { Divider } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerDivider.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerDivider} sort="alpha" />

### MenuItem

<ComponentInfo
    usage={"import { MenuItem } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerMenuItem.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerMenuItem} sort="alpha" />

### MenuSection

<ComponentInfo
    usage={"import { MenuSection } from \"@sharegate/orbit-ui\";"}
    inherits={[InnerMenuSection.defaultElement, "styled-component"]}
    compact
/>

<ArgsTable of={InnerMenuSection} sort="alpha" />


