import { Meta, ArgTypes, Canvas, Story } from "@storybook/addon-docs/blocks";
import { Button } from "./Button";
import * as ButtonStories from "./Button.stories";

<Meta of={ButtonStories} />

# Button

Buttons allow users to perform actions like submitting form or move forward in a flow.

## Install

```bash
yarn add @simplybusiness/mobius
```

## Usage

```js
import { Button } from "@simplybusiness/mobius";
```

## Examples

### Default

<Canvas of={ButtonStories.Default} />

### Secondary

<Canvas of={ButtonStories.Secondary} />

### Ghost

<Canvas of={ButtonStories.Ghost} />

### Basic

<Canvas of={ButtonStories.Basic} />

### Large

<Canvas of={ButtonStories.Large} />

### As Link Element

<Canvas of={ButtonStories.AsLinkElement} />

### With Link Styles

<Canvas of={ButtonStories.WithLinkStyles} />

### Loading

<Canvas of={ButtonStories.Loading} />

### Success

<Canvas of={ButtonStories.Success} />

### Disabled

<Canvas of={ButtonStories.Disabled} />

### With Icon On The Left

<Story of={ButtonStories.WithIconOnTheLeft} />

**IMPORTANT:** as of `@simplybusiness/mobius` 4.0.0 `<Button>` no longer supports `icon` or `iconPosition` props:

❌ This will no longer work 🙅‍♂️

{/* prettier-ignore */}
```jsx
import { Button } from "@simplybusiness/mobius";

<Button variant="secondary" icon="arrowLeft" iconPosition="left">
  Back
</Button>
```

With component now being lighter, the following example demonstrates how to add an icon to it:

✅ This will work 🎉

{/* prettier-ignore */}
```jsx
import { Button, Icon } from "@simplybusiness/mobius";
import { arrowLeft } from "@simplybusiness/icons";
import styled from "@emotion/styled";

const StyledButton = styled(Button)`
  // Add spacing between the icon and the text
  display: inline-flex;
  gap: var(--size-xs);
`;

<StyledButton variant="secondary">
  <Icon icon={arrowLeft} />
  Back
</StyledButton>
```

### With Icon On The Right

<Story of={ButtonStories.WithIconOnTheRight} />

**IMPORTANT:** as of `@simplybusiness/mobius` 4.0.0 `<Button>` no longer supports `icon` or `iconPosition` props:

❌ This will no longer work 🙅‍♂️

{/* prettier-ignore */}
```jsx
import { Button } from "@simplybusiness/mobius";

<Button icon="menu" iconPosition="right">
  Menu
</Button>
```

With component now being lighter, the following example demonstrates how to add an icon to it:

✅ This will work 🎉

{/* prettier-ignore */}
```jsx
import { Button, Icon } from "@simplybusiness/mobius";
import { menu } from "@simplybusiness/icons";
import styled from "@emotion/styled";

const StyledButton = styled(Button)`
  // Add spacing between the icon and the text
  display: inline-flex;
  gap: var(--size-xs);
`;

<StyledButton>
  Menu
  <Icon icon={menu} />
</StyledButton>
```

## Themed

<Story of={ButtonStories.Themed} />

{/* prettier-ignore */}
```jsx
import { Button } from "@simplybusiness/mobius";
import styled from "@emotion/styled";

const StyledButton = styled(Button)`
  background-color: red;
`;

<StyledButton>Sample Text</StyledButton>
```

## Accessibility

When the button contains no text content (eg. when it only shows an icon), a value must be provided to the `aria-label` prop.

## Events

Button can be interacted with via keyboard, mouse and touch gestures. All these interactions are handled by the `onPress` prop.

```tsx
const Counter = () => {
  const [count, setCount] = useState(0);
  return (
    <Button onPress={() => setCount(c => c + 1)}>Pressed {count} times</Button>
  );
};
```

<ButtonStories.Counter />

```tsx
const PressButton = () => {
  const [pressLogs, setPressLogs] = useState([]);
  const log = e => {
    setPressLogs(pressLogs => [...pressLogs.slice(-5), e]);
  };
  return (
    <div>
      <Button onPress={() => log("onPress")}>Press me</Button>
      <ul>
        {pressLogs.map((pressLog, i) => (
          <li key={i}>{pressLog}</li>
        ))}
      </ul>
    </div>
  );
};
```

<ButtonStories.PressButton />

## Props

<ArgTypes of={Button} />

## Component HTML Structure and Class names

The following example HTML is rendered for a `<Button>`:

```html
<button class="mobius-button --variant-primary --size-md">Text</button>
```

And this for a `<Button>` with an icon:

```html
<button class="mobius-button --variant-primary --size-md">
  Text
  <svg class="mobius-icon svg-inline--mobius-icon" role="img" focusable="false">
    (icon)
  </svg>
</button>
```

Class names are augmented with the following flags if true:

- \--is-disabled
- \--is-loading
- \--is-success
- \--size-sm
- \--size-md
- \--size-lg
- \--variant-primary
- \--variant-secondary
- \--variant-ghost
- \--variant-basic
