import {
  Meta,
  Preview,
  Props,
  Story,
  SourceState,
} from "@storybook/addon-docs/blocks";
import { ComponentHeading } from "../../storybook-components";
import { JUSTIFY } from "../../types";
import { Box } from "../Box";
import { Button, BUTTON_VARIANT } from "../Button";
import { Stack } from "../Stack";
import { ICON_TYPE } from "../Icon";
import { Menu } from "./Menu";

<Meta title="Components/Popovers/Menu" component={Menu} />

<ComponentHeading
  componentName="Menu"
  description="Create a dropdown menu from a given trigger element"
  sourcePath="src/components/Menu/Menu.tsx"
/>

```jsx
import { Menu } from "@aptible/arrow-ds";
```

<Preview>
  <Story name="Menu">
    <Box className="pb-20 inline-block">
      <Menu
        trigger={(triggerProps, { isOpen }) => (
          <Button {...triggerProps}>{isOpen ? "Close" : "Open"}</Button>
        )}
      >
        <Menu.Item>First item</Menu.Item>
        <Menu.Item>Second item</Menu.Item>
        <Menu.Item>Third item</Menu.Item>
      </Menu>
    </Box>
  </Story>
</Preview>

`Menu` uses [`MenuRenderer`](/?path=/docs/components-menurenderer--menu-renderer).
It can be used to create menus with different kinds of buttons. However, the
menu list UI will always remain the same.

If you need a custom designed menu, create a custom implementation of
`MenuRenderer`.

## Props

`Menu` uses the same props provided by [`MenuRenderer`](/?path=/docs/components-menurenderer--menu-renderer)
and has no custom props of its own.

<Props of={Menu} />

## Demos

### Open by default

The menu list / options can be open by default.

<Preview withSource={SourceState.OPEN}>
  <Story name="Menu button open default">
    <Box className="pb-20 inline-block">
      <Menu
        isOpen
        trigger={(triggerProps, { isOpen }) => {
          return <Button {...triggerProps}>{isOpen ? "Close" : "Open"}</Button>;
        }}
      >
        <Menu.Item>First item</Menu.Item>
        <Menu.Item>Second item</Menu.Item>
        <Menu.Item>Third item</Menu.Item>
      </Menu>
    </Box>
  </Story>
</Preview>

### Focus the first option

The first option can have focus when the menu list appears.

<Preview withSource={SourceState.OPEN}>
  <Story name="Menu button autoFocus">
    <Box className="pb-20 inline-block">
      <Menu
        autoFocus
        trigger={(triggerProps, { isOpen }) => {
          return <Button {...triggerProps}>{isOpen ? "Close" : "Open"}</Button>;
        }}
      >
        <Menu.Item>First item</Menu.Item>
        <Menu.Item>Second item</Menu.Item>
        <Menu.Item>Third item</Menu.Item>
      </Menu>
    </Box>
  </Story>
</Preview>

### With portal

The menu list / options will be rendered inside of a portal. This scenario is
useful when dealing with competing z-index values.

<Preview withSource={SourceState.OPEN}>
  <Story name="Menu button portal">
    <Box className="pb-20 inline-block">
      <Menu
        hasPortal
        trigger={(triggerProps, { isOpen }) => {
          return <Button {...triggerProps}>{isOpen ? "Close" : "Open"}</Button>;
        }}
      >
        <Menu.Item onClick={() => console.log("First item was clicked")}>
          First item
        </Menu.Item>
        <Menu.Item onClick={() => console.log("Second item was clicked")}>
          Second item
        </Menu.Item>
        <Menu.Item onClick={() => console.log("Third item was clicked")}>
          Third item
        </Menu.Item>
      </Menu>
    </Box>
  </Story>
</Preview>

### Split-button example

<Preview withSource={SourceState.OPEN}>
  <Story name="Menu split button">
    <Stack className="pb-20">
      <Menu
        placement="bottom-start"
        trigger={(triggerProps, { isOpen, onClose }) => (
          <Button.Group isSegmented>
            <Button
              variant={BUTTON_VARIANT.SECONDARY}
              onClick={() => {
                console.log("Primary Action");
                onClose();
              }}
            >
              Primary Action
            </Button>
            <Button
              variant={BUTTON_VARIANT.SECONDARY}
              icon={isOpen ? ICON_TYPE.CARET_UP : ICON_TYPE.CARET_DOWN}
              depressed={isOpen}
              {...triggerProps}
            />
          </Button.Group>
        )}
      >
        <Menu.Item>First item</Menu.Item>
        <Menu.Item>Second item</Menu.Item>
        <Menu.Item>Third item</Menu.Item>
      </Menu>
    </Stack>
  </Story>
</Preview>

### Split-button right-aligned example

<Preview withSource={SourceState.OPEN}>
  <Story name="Menu split button right aligned">
    <Stack className="pb-20" justify={JUSTIFY.END}>
      <Menu
        placement="bottom-end"
        trigger={(triggerProps, { isOpen, onClose }) => (
          <Button.Group isSegmented>
            <Button
              variant={BUTTON_VARIANT.SECONDARY}
              onClick={() => {
                console.log("Primary Action");
                onClose();
              }}
            >
              Primary Action
            </Button>
            <Button
              variant={BUTTON_VARIANT.SECONDARY}
              icon={isOpen ? ICON_TYPE.CARET_UP : ICON_TYPE.CARET_DOWN}
              depressed={isOpen}
              {...triggerProps}
            />
          </Button.Group>
        )}
      >
        <Menu.Item>First item</Menu.Item>
        <Menu.Item>Second item</Menu.Item>
        <Menu.Item>Third item</Menu.Item>
      </Menu>
    </Stack>
  </Story>
</Preview>

### Overflow menu example

<Preview withSource={SourceState.OPEN}>
  <Story name="Overflow menu">
    <Stack className="pb-20">
      <Menu
        placement="bottom-start"
        trigger={(triggerProps) => (
          <Button
            className="text-brandGreen-400"
            variant={BUTTON_VARIANT.MINIMAL}
            icon={ICON_TYPE.ELLIPSIS_V}
            {...triggerProps}
          />
        )}
      >
        <Menu.Item>First item</Menu.Item>
        <Menu.Item>Second item</Menu.Item>
        <Menu.Item>Third item</Menu.Item>
      </Menu>
    </Stack>
  </Story>
</Preview>
