import { Canvas, Meta } from '@storybook/addon-docs/blocks';

import Button, { ButtonShape, ButtonSize, ButtonVariant } from './Button';

import * as ButtonStories from './Button.stories';

# Buttons

Buttons are clickable UI elements that are used to trigger actions or navigate.

## Configuration

The `Button` component renders a `<button>`, `<a>`, or `<div>` depending on the
given configuration. In addition to the props listed below, buttons support the
props of the corresponding native element as well.

### Basics

These props control the essential functionality of the button.

| Prop        | Type                   | Description                                                                                               |
| ----------- | ---------------------- | --------------------------------------------------------------------------------------------------------- |
| `children`  | `string \| JSX`        | Button label or more elaborate content, such as including an icon                                         |
| `onClick`   | `Function`             | Invoked when the button is clicked. If unset, the button renders as a `<div>`, unless `href` is specified |
| `href`      | `string`               | When set, the button works like a hyperlink and renders as a `<a>` tag                                    |
| `disabled`  | `boolean`              | When set to `true`, the button is not interactable                                                        |
| `icon`      | `IconComponent \| JSX` | Icon displayed next to the content, typically on the left                                                 |
| `iconStart` | `IconComponent \| JSX` | Icon displayed at the "start" of the container, typically the left                                        |
| `iconLeft`  | `IconComponent \| JSX` | Icon displayed to the "end" of the container, typically the right                                         |

The button also supports custom styling. This should be used sparingly to
control things like positioning, margins, and full-width.

| Prop               | Type     | Description                                                                  |
| ------------------ | -------- | ---------------------------------------------------------------------------- |
| `className`        | `string` | CSS classname applied to the outer container (`<button>`, `<a>`, or `<div>`) |
| `contentClassName` | `string` | CSS classname applied to the inner container (`children` wrapper)            |
| `style`            | `Object` | Inline styles applied to the outer container                                 |

### Appearance

These props control what the button looks like.

| Prop           | Type            | Description                                                                                   |
| -------------- | --------------- | --------------------------------------------------------------------------------------------- |
| `variant`      | `ButtonVariant` | Controls the color scheme of the button                                                       |
| `size`         | `ButtonSize`    | Controls the size of the button, including text size and padding                              |
| `shape`        | `ButtonShape`   | Controls the shape of the button, particularly the corner radius                              |
| `active`       | `boolean`       | When set to `true` or `false`, display as a toggleable button                                 |
| `squareAspect` | `boolean`       | When set to `true`, displays with a square aspect ratio (e.g. for circular or square buttons) |

### Advanced customization

The `Aura` button variant supports a background image that animates on hover.

| Prop                            | Type     | Description                                                        |
| ------------------------------- | -------- | ------------------------------------------------------------------ |
| `backgroundImage`               | `string` | Background image of the button when using the `ButtonVariant.Aura` |
| `backgroundHoverAnimationSpeed` | `number` | Speed of the background image movement on hover                    |

## Usage

### Standard

The standard variant is our garden-variety button, used across the app for all
sorts of interactions.

#### Rounded

The rounded rectangle shape is our go-to that we use by default around the app.

<Canvas of={ButtonStories.StandardRounded} />

#### Pill

Pill-shaped buttons have semicircular ends and are used for cases when we want
to be a little fancy, or when buttons with text appear next to circular buttons.

<Canvas of={ButtonStories.StandardPill} />

#### Active/Inactive

The `active` prop can be used when the button is intended to be toggle some
state.

<Canvas of={ButtonStories.StandardActiveInactive} />

### Primary

The primary variant is used in places where there is a prominent call-to-action,
such as a modal, banner, or sidebar takeover.

#### Rounded

We use the typical rounded rectangle shape on primary buttons for buttons that
act as navigation tabs.

<Canvas of={ButtonStories.PrimaryRounded} />

#### Pill

We typically use pill-shaped primary buttons for CTAs, such as in the sidebar or
in modals.

<Canvas of={ButtonStories.PrimaryPill} />

#### Active/Inactive

The `active` prop can be used when the button is intended to be toggle some
state.

We use this when primary buttons are used as navigation tabs.

<Canvas of={ButtonStories.PrimaryActiveInactive} />

### Secondary

#### Rounded

<Canvas of={ButtonStories.SecondaryRounded} />

#### Pill

<Canvas of={ButtonStories.SecondaryPill} />

#### Active/Inactive

The `active` prop can be used when the button is intended to be toggle some
state.

We use this when secondary buttons are used as filters.

<Canvas of={ButtonStories.SecondaryActiveInactive} />

### Tertiary

Typically reserved for icon-only buttons. Most icon-only buttons use a rounded
rectangular shape, but the shape should be set to match any adjacent buttons.

The shape is only actually visible in the hover state. Can you find the circular
button below?

<Canvas of={ButtonStories.Tertiary} />

#### Active/Inactive

Buttons can be used to visualize a toggleable state by specifying `active` as a
boolean.

<Canvas of={ButtonStories.TertiaryActiveInactive} />

### Glass

Glass buttons are used throughout the app in places where buttons overlay an
image, such as the controls on a song card thumbnail.

<Canvas
  of={ButtonStories.GlassMiniRounded}
  parameters={{
    backgrounds: { default: 'Image' },
    values: [{ name: 'Image', value: '#f00' }],
  }}
/>

#### Active/Inactive

<Canvas of={ButtonStories.GlassActiveInactive} />

### Icon-only

Buttons that contain and `icon` and `children` content will be set to a square
aspect ratio automatically. You can create circular buttons using the `Pill`
shape.

These are typically used for media controls, navigation, and groups of actions
in the song row.

Even though we don't display the text, it is best to include an `aria-label` so
that screen readers can indicate what the button actually does.

<Canvas of={ButtonStories.IconOnly} />

#### Image Glass

Image Glass buttons commonly used with round icon-only buttons in places where
buttons overlay content like an image or video, such as in the Hooks feed.

<Canvas of={ButtonStories.IconOnlyImageGlass} />
#### Implementation Note

You can pass an `icon` to the button as rendered JSX or a Component.

A classname to determine the size and color of the icon based on the button's
size and variant configuration will be passed to the Component automatically.

Here's what it looks like when rendering a primary button with an icon Component
passed in:

<Canvas
  of={ButtonStories.IconAsComponent}
  sourceState='shown'
  source={{
    transform: (code) => code.replace('icon={() => {}}', 'icon={ThumbsUpIcon}'),
  }}
/>

There is a subtle but important difference in the behavior when passing an
element directly: the CSS classname is ignored! It's up to the consumer to set
the size and color correctly, which defeats the purpose of the button's logic.

In the example below, the icon is not visible because the icon color defaults to
`text-primary`, which happens to match the Primary variant background color.

<Canvas of={ButtonStories.IconAsElement} sourceState='shown' />

### Aura

There are times we want a button that stands out visually and says "click me to
make something magical happen." This is the purpose of the Aura button.

Aura buttons should have a pill shape and are typically displayed at larger
sizes, such as the "Create" button.

<Canvas of={ButtonStories.Aura} />

#### Customized

Aura buttons accept `backgroundImage` and `backgroundHoverAnimationSpeed` props
to control the background image and hover animation speed.

<Canvas of={ButtonStories.AuraCustom} />

### Light/Dark Primary

Sometimes we will want to use buttons in places where they should not respond to
any app light/dark theme changes, such as when placed on top of an image or
fixed background color as part of some campaign. In those

<Canvas of={ButtonStories.LightDarkPrimary} />
