import {
  Meta,
  Canvas,
  ArgsTable,
  Story,
  SourceState,
} from "@storybook/blocks";
import {
  Button,
  BUTTON_VARIANT,
  BUTTON_SIZE,
  BUTTON_ICON_POSITION,
} from "./Button";
import { ICON_TYPE } from "../Icon";
import { Link } from "../Link";
import { ORIENTATION, JUSTIFY } from "../../types";
import { Stack } from "../Stack";
import { ComponentHeading, EnumTable } from "../../storybook-components";

<Meta title="Components/Buttons/Button" component={Button} />

<ComponentHeading
  componentName="Button"
  description="Styled HTML button element"
  sourcePath="src/components/Button/Button.tsx"
/>

## Installation

```jsx
import { Button } from "@conveyorhq/arrow-ds";
```

## Basic usage

<Canvas withSource={SourceState.OPEN}>
  <Story name="Button">
    <Button>Button</Button>
  </Story>
</Canvas>

## API

These are the custom props that extend `React.ButtonHTMLAttributes<HTMLButtonElement>`.

<ArgsTable of={Button} />
<EnumTable enums={{ BUTTON_VARIANT, BUTTON_SIZE, BUTTON_ICON_POSITION }} />

## Demos

### Variants

- **Primary:** `primary` buttons serve as a call to action to the user. Generally there should only be one `primary` button in a view and it should be placed to the right of any nearby buttons.
- **Secondary:** `secondary` buttons are used for less important stand-alone actions.
- **Utility:** `utility` buttons are available for repeatable, in-page actions with low visual weight.
- **Danger:** `danger` buttons are used to for destructive actions such as deletion. There should generally only be one `danger` button in a view.
- **Minimal:** `minimal` buttons can be used for primary or secondary actions when the button should have low visual weight.
- **Plain:** `plain` buttons render only a button element with no styles applied; see below for more.

<Canvas>
  <Story name="VariantPrimary">
    <Button variant={BUTTON_VARIANT.PRIMARY}>Primary</Button>
  </Story>
  <Story name="VariantSecondary">
    <Button variant={BUTTON_VARIANT.SECONDARY}>Secondary</Button>
  </Story>
  <Story name="VariantUtility">
    <Button variant={BUTTON_VARIANT.UTILITY}>Utility</Button>
  </Story>
  <Story name="VariantDanger">
    <Button variant={BUTTON_VARIANT.DANGER}>Danger</Button>
  </Story>
  <Story name="VariantMinimal">
    <Button variant={BUTTON_VARIANT.MINIMAL}>Minimal</Button>
  </Story>
</Canvas>

#### Plain variant

There are times when a design requires a button that doesn’t fit the predefined variants. In these cases, use the
`plain` variant to create a button with no predefined styles. Keep in mind, you’ll be responsible for setting all
styles, including hover and focus states.

This provides an alternative to using a `button` element directly.

The following props are ignored when using the `plain` variant:
- `block`
- `depressed`
- `isLoading`
- `icon`
- `iconColor`
- `iconPosition`
- `iconSpin`
- `iconPrefix`
- `size`
- `theme`

<Canvas withSource={SourceState.OPEN}>
  <Story name="VariantPlain">
    <Button variant={BUTTON_VARIANT.PLAIN}>Plain Button</Button>
  </Story>
</Canvas>

### Sizes

The default button size is `medium`.

<Canvas>
  <Story name="SizesPrimary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button size={BUTTON_SIZE.LARGE} variant={BUTTON_VARIANT.PRIMARY}>
        Large
      </Button>
      <Button size={BUTTON_SIZE.MEDIUM} variant={BUTTON_VARIANT.PRIMARY}>
        Medium
      </Button>
      <Button size={BUTTON_SIZE.SMALL} variant={BUTTON_VARIANT.PRIMARY}>
        Small
      </Button>
    </Stack>
  </Story>
  <Story name="SizesSecondary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button size={BUTTON_SIZE.LARGE} variant={BUTTON_VARIANT.SECONDARY}>
        Large
      </Button>
      <Button size={BUTTON_SIZE.MEDIUM} variant={BUTTON_VARIANT.SECONDARY}>
        Medium
      </Button>
      <Button size={BUTTON_SIZE.SMALL} variant={BUTTON_VARIANT.SECONDARY}>
        Small
      </Button>
    </Stack>
  </Story>
  <Story name="SizesUtility">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button size={BUTTON_SIZE.LARGE} variant={BUTTON_VARIANT.UTILITY}>
        Large
      </Button>
      <Button size={BUTTON_SIZE.MEDIUM} variant={BUTTON_VARIANT.UTILITY}>
        Medium
      </Button>
      <Button size={BUTTON_SIZE.SMALL} variant={BUTTON_VARIANT.UTILITY}>
        Small
      </Button>
    </Stack>
  </Story>
  <Story name="SizesDanger">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button size={BUTTON_SIZE.LARGE} variant={BUTTON_VARIANT.DANGER}>
        Large
      </Button>
      <Button size={BUTTON_SIZE.MEDIUM} variant={BUTTON_VARIANT.DANGER}>
        Medium
      </Button>
      <Button size={BUTTON_SIZE.SMALL} variant={BUTTON_VARIANT.DANGER}>
        Small
      </Button>
    </Stack>
  </Story>
  <Story name="SizesMinimal">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button size={BUTTON_SIZE.LARGE} variant={BUTTON_VARIANT.MINIMAL}>
        Large
      </Button>
      <Button size={BUTTON_SIZE.MEDIUM} variant={BUTTON_VARIANT.MINIMAL}>
        Medium
      </Button>
      <Button size={BUTTON_SIZE.SMALL} variant={BUTTON_VARIANT.MINIMAL}>
        Small
      </Button>
    </Stack>
  </Story>
</Canvas>

### With Icon

See [Icon](/?path=/docs/components-icon--default) component for more information. Use the `iconPosition` prop to place the icon to the left or right of content

<Canvas>
  <Story name="WithIconPrimary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.PRIMARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.PRIMARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.PRIMARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.PRIMARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.PRIMARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.PRIMARY}
      >
        Icons
      </Button>
    </Stack>
  </Story>
  <Story name="WithIconSecondary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.SECONDARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.SECONDARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.SECONDARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.SECONDARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.SECONDARY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.SECONDARY}
      >
        Icons
      </Button>
    </Stack>
  </Story>
  <Story name="WithIconUtility">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.UTILITY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.UTILITY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.UTILITY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.UTILITY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.UTILITY}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.UTILITY}
      >
        Icons
      </Button>
    </Stack>
  </Story>
  <Story name="WithIconDanger">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.DANGER}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.DANGER}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.DANGER}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.DANGER}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.DANGER}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.DANGER}
      >
        Icons
      </Button>
    </Stack>
  </Story>
  <Story name="WithIconMinimal">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.MINIMAL}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.MINIMAL}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.MINIMAL}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.MINIMAL}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.MINIMAL}
      >
        Icons
      </Button>
      <Button
        icon={ICON_TYPE.POO_STORM}
        iconPosition={BUTTON_ICON_POSITION.RIGHT}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.MINIMAL}
      >
        Icons
      </Button>
    </Stack>
  </Story>
</Canvas>

### Icon Only

<Canvas>
  <Story name="IconOnlyPrimary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.PRIMARY}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.PRIMARY}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.PRIMARY}
      />
    </Stack>
  </Story>
  <Story name="IconOnlySecondary">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.SECONDARY}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.SECONDARY}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.SECONDARY}
      />
    </Stack>
  </Story>
  <Story name="IconOnlyUtility">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.UTILITY}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.UTILITY}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.UTILITY}
      />
    </Stack>
  </Story>
  <Story name="IconOnlyDanger">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.DANGER}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.DANGER}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.DANGER}
      />
    </Stack>
  </Story>
  <Story name="IconOnlyMinimal">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.LARGE}
        variant={BUTTON_VARIANT.MINIMAL}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.MEDIUM}
        variant={BUTTON_VARIANT.MINIMAL}
      />
      <Button
        icon={ICON_TYPE.POO_STORM}
        size={BUTTON_SIZE.SMALL}
        variant={BUTTON_VARIANT.MINIMAL}
      />
    </Stack>
  </Story>
</Canvas>

### Block

By default, `Button` expands with its content. Block buttons span the full width available to them

<Canvas>
  <Story name="Block">
    <Stack orientation={ORIENTATION.VERTICAL}>
      <Button block variant={BUTTON_VARIANT.PRIMARY}>
        Primary
      </Button>
      <Button block variant={BUTTON_VARIANT.SECONDARY}>
        Secondary
      </Button>
      <Button block variant={BUTTON_VARIANT.UTILITY}>
        Utility
      </Button>
      <Button block variant={BUTTON_VARIANT.DANGER}>
        Danger
      </Button>
      <Button block variant={BUTTON_VARIANT.MINIMAL}>
        Minimal
      </Button>
    </Stack>
  </Story>
</Canvas>

### Depressed

A button may be programmatically set to the active state by using the `depressed` prop.

<Canvas>
  <Story name="DepressedPrimary">
    <Button depressed variant={BUTTON_VARIANT.PRIMARY}>
      Primary
    </Button>
  </Story>
  <Story name="DepressedSecondary">
    <Button depressed variant={BUTTON_VARIANT.SECONDARY}>
      Secondary
    </Button>
  </Story>
  <Story name="DepressedUtility">
    <Button depressed variant={BUTTON_VARIANT.UTILITY}>
      Utility
    </Button>
  </Story>
  <Story name="DepressedDanger">
    <Button depressed variant={BUTTON_VARIANT.DANGER}>
      Danger
    </Button>
  </Story>
  <Story name="DepressedMinimal">
    <Button depressed variant={BUTTON_VARIANT.MINIMAL}>
      Minimal
    </Button>
  </Story>
</Canvas>

### Disabled

<Canvas>
  <Story name="DisabledPrimary">
    <Button disabled variant={BUTTON_VARIANT.PRIMARY}>
      Primary
    </Button>
  </Story>
  <Story name="DisabledSecondary">
    <Button disabled variant={BUTTON_VARIANT.SECONDARY}>
      Secondary
    </Button>
  </Story>
  <Story name="DisabledUtility">
    <Button disabled variant={BUTTON_VARIANT.UTILITY}>
      Utility
    </Button>
  </Story>
  <Story name="DisabledDanger">
    <Button disabled variant={BUTTON_VARIANT.DANGER}>
      Danger
    </Button>
  </Story>
  <Story name="DisabledMinimal">
    <Button disabled variant={BUTTON_VARIANT.MINIMAL}>
      Minimal
    </Button>
  </Story>
</Canvas>

### Loading

Loading buttons are automatically disabled. They should be created by setting the `isLoading` prop instead of composed by manipulating the button icon appearance.

<Canvas>
  <Story name="LoadingPrimary">
    <Button
      isLoading
      size={BUTTON_SIZE.MEDIUM}
      variant={BUTTON_VARIANT.PRIMARY}
    >
      Primary
    </Button>
  </Story>
  <Story name="LoadingSecondary">
    <Button
      isLoading
      size={BUTTON_SIZE.MEDIUM}
      variant={BUTTON_VARIANT.SECONDARY}
    >
      Secondary
    </Button>
  </Story>
  <Story name="LoadingUtility">
    <Button
      isLoading
      size={BUTTON_SIZE.MEDIUM}
      variant={BUTTON_VARIANT.UTILITY}
    >
      Utility
    </Button>
  </Story>
  <Story name="LoadingDanger">
    <Button isLoading size={BUTTON_SIZE.MEDIUM} variant={BUTTON_VARIANT.DANGER}>
      Danger
    </Button>
  </Story>
  <Story name="LoadingMinimal">
    <Button
      isLoading
      size={BUTTON_SIZE.MEDIUM}
      variant={BUTTON_VARIANT.MINIMAL}
    >
      Minimal
    </Button>
  </Story>
</Canvas>

### Links that look like Buttons

Buttons can be rendered as other elements or components in the interest of semantic HTML. This is often used to use a button to trigger a route change by setting the button `as` prop to a router link component.

<Canvas>
  <Story name="LinkPrimary">
    <Button as={Link} href="/link" variant={BUTTON_VARIANT.PRIMARY}>
      Primary
    </Button>
  </Story>
  <Story name="LinkSecondary">
    <Button as={Link} href="/link" variant={BUTTON_VARIANT.SECONDARY}>
      Secondary
    </Button>
  </Story>
  <Story name="LinkUtility">
    <Button as={Link} href="/link" variant={BUTTON_VARIANT.UTILITY}>
      Utility
    </Button>
  </Story>
  <Story name="LinkDanger">
    <Button as={Link} href="/link" variant={BUTTON_VARIANT.DANGER}>
      Danger
    </Button>
  </Story>
  <Story name="LinkMinimal">
    <Button as={Link} href="/link" variant={BUTTON_VARIANT.MINIMAL}>
      Minimal
    </Button>
  </Story>
</Canvas>

### Buttons on backgrounds

<Canvas isColumn>
  <Story name="White">
    <div className="flex items-center justify-between bg-white py-2 px-4">
      White
      <Button.Group>
        <Button variant={BUTTON_VARIANT.PRIMARY}>Primary</Button>
        <Button variant={BUTTON_VARIANT.SECONDARY}>Secondary</Button>
        <Button variant={BUTTON_VARIANT.UTILITY}>Utility</Button>
        <Button variant={BUTTON_VARIANT.DANGER}>Danger</Button>
        <Button variant={BUTTON_VARIANT.MINIMAL}>Minimal</Button>
      </Button.Group>
    </div>
  </Story>
  <Story name="GraysNot1">
    <div className="flex items-center justify-between bg-gray-100 py-2 px-4">
      Gray 100
      <Button.Group>
        <Button variant={BUTTON_VARIANT.PRIMARY}>Primary</Button>
        <Button variant={BUTTON_VARIANT.SECONDARY}>Secondary</Button>
        <Button variant={BUTTON_VARIANT.UTILITY}>Utility</Button>
        <Button variant={BUTTON_VARIANT.DANGER}>Danger</Button>
        <Button variant={BUTTON_VARIANT.MINIMAL}>Minimal</Button>
      </Button.Group>
    </div>
  </Story>
  <Story name="Grays 0">
    <div className="flex items-center justify-between bg-gray-200 py-2 px-4">
      Gray 200
      <Button.Group>
        <Button variant={BUTTON_VARIANT.PRIMARY}>Primary</Button>
        <Button variant={BUTTON_VARIANT.SECONDARY}>Secondary</Button>
        <Button variant={BUTTON_VARIANT.UTILITY}>Utility</Button>
        <Button variant={BUTTON_VARIANT.DANGER}>Danger</Button>
        <Button variant={BUTTON_VARIANT.MINIMAL}>Minimal</Button>
      </Button.Group>
    </div>
  </Story>
  <Story name="Grays 1">
    <div className="flex items-center justify-between bg-gray-400 py-2 px-4">
      Gray 400
      <Button.Group>
        <Button variant={BUTTON_VARIANT.PRIMARY}>Primary</Button>
        <Button variant={BUTTON_VARIANT.SECONDARY}>Secondary</Button>
        <Button variant={BUTTON_VARIANT.UTILITY}>Utility</Button>
        <Button variant={BUTTON_VARIANT.DANGER}>Danger</Button>
        <Button variant={BUTTON_VARIANT.MINIMAL}>Minimal</Button>
      </Button.Group>
    </div>
  </Story>
</Canvas>
