import { useState, useCallback } from 'react'
import Button from '../Button'
import { createComponentTemplate, createStoryMetaSettings } from '../../../storybook'
import { ArgsTable, Story, Canvas, Meta } from '@storybook/addon-docs'
import { Calendar, Remove, Add, Check } from '../../Icon/Icons'
import {
  BUTTON_GROUP,
  SPLIT_BUTTON,
  TAG,
} from '../../../storybook/components/related-components/component-description-map'
import { MultipleStoryElementsWrapper, Link } from '../../../storybook'
import './button.stories.scss'

export const metaSettings = createStoryMetaSettings({
  component: Button,
  enumPropNamesArray: ['kind', 'size', 'color', 'type'],
  iconPropNamesArray: ['leftIcon', 'rightIcon', 'successIcon'],
  actionPropsArray: ['onClick'],
})

<Meta
  title='Buttons/Button'
  component={Button}
  argTypes={metaSettings.argTypes}
  decorators={metaSettings.decorators}
/>

<!--- Component template -->

export const buttonTemplate = createComponentTemplate(Button)

<!--- Component documentation -->

# Button

- [Overview](#overview)
- [Props](#props)
- [Usage](#usage)
- [Variants](#variants)
- [Do’s and don’ts](#dos-and-donts)
- [Use cases and examples](#use-cases-and-examples)
- [Related components](#related-components)
- [Feedback](#feedback)

## Overview

Buttons allow users to trigger an action or event with a single click.
For example, you can use a button for allowing the functionality of submitting a form, opening a dialog, canceling an action,
or performing a delete operation.

<Canvas>
  <Story name='Overview' args={{ children: 'Button' }}>
    {buttonTemplate.bind({})}
  </Story>
</Canvas>

## Props

<ArgsTable story='Overview' />

## Usage

<UsageGuidelines
  guidelines={[
    'Buttons may contain icon, on the left or the right side',
    'Use 8 px spacing between buttons',
    'Replace text with a loader if action is submitted, but still processing',
    'Button width is set by it’s content, avoid changing it width',
    'Use only one primary button, and any remaining calls to action should be represented as lower emphasis buttons',
  ]}
/>

<Tip>
  If you need to use icon as button with no text, check out{' '}
  <Link href='/?path=/docs/buttons-icon-button--overview' size={Link.sizes.SMALL} withoutSpacing>
    Icon button
  </Link>{' '}
  component
</Tip>

## Variants

### Button kinds

There can be more than one button in a screen, but to create the hierarchy of actions we need to use button kinds.

<Canvas>
  <Story name='Button kinds'>
    <Button>Primary</Button>
    <Button kind={Button.kinds?.SECONDARY}>Secondary</Button>
    <Button kind={Button.kinds?.TERTIARY}>Tertiary</Button>
  </Story>
</Canvas>

### Sizes

<Canvas>
  <Story name='Sizes'>
    <Button size={Button.sizes?.LARGE}>Large</Button>
    <Button size={Button.sizes?.MEDIUM}>Medium</Button>
    <Button size={Button.sizes?.SMALL}>Small</Button>
  </Story>
</Canvas>

### Disabled

Set disable button for something that isn’t usable. Use a tooltip on hover in order to indicate the reason of the disabled action.

<Canvas>
  <Story name='Disabled'>
    <Button disabled>Primary</Button>
    <Button kind={Button.kinds?.SECONDARY} disabled>
      Secondary
    </Button>
    <Button kind={Button.kinds?.TERTIARY} disabled>
      Tertiary
    </Button>
  </Story>
</Canvas>

### States

<Canvas>
  <Story name='States'>
    <Button>Regular</Button>
    <Button active>Active</Button>
  </Story>
</Canvas>

### Error and success

<Canvas>
  <Story name='Error and success'>
    <Button color={Button.colors.POSITIVE}>Positive</Button>
    <Button color={Button.colors.NEGATIVE}>Negative</Button>
  </Story>
</Canvas>

### Icons

<Canvas>
  <Story name='Icons'>
    <Button rightIcon={Calendar}>Right icon</Button>
    <Button leftIcon={Calendar}>Left icon</Button>
  </Story>
</Canvas>

## Do’s and Don’ts

<ComponentRules
  rules={[
    {
      positive: {
        component: <Button>Get started</Button>,
        description:
          'Use 1 or 2 words, no longer than 4 words, with fewer than 20 characters including spaces.',
      },
      negative: {
        component: <Button>Get started and enjoy discount!</Button>,
        description: 'Don’t use punctuation marks such as periods or exclamation points.',
      },
    },
    {
      positive: {
        component: <Button>Get started</Button>,
        description: 'Use sentence-case capitalization.',
      },
      negative: {
        component: [<Button>Get Started</Button>, <Button>GET STARTED</Button>],
        description: 'Don’t use title case captalization or all caps.',
      },
    },
    {
      positive: {
        component: [
          <Button kind={Button.kinds?.TERTIARY}>Cancel</Button>,
          <Button>Get started</Button>,
        ],
        description:
          'Use primary button as the main action , put the tertiary as the second option.',
      },
      negative: {
        component: [
          <Button>Get started</Button>,
          <Button kind={Button.kinds?.SECONDARY}>Cancel</Button>,
        ],
        description: 'Use primary button next to secondary.',
      },
    },
    {
      positive: {
        component: [
          <Button kind={Button.kinds?.TERTIARY}>Cancel</Button>,
          <Button>Get started</Button>,
        ],
        description: 'Use active verbs or phrases that clearly indicate action.',
      },
      negative: {
        component: [<Button kind={Button.kinds?.TERTIARY}>Yes</Button>, <Button>No</Button>],
        description:
          'Use vague and generic labels that make the user read the dialog before taking action.',
      },
    },
  ]}
/>

## Use cases and examples

### Loading state

<Canvas>
  <Story name='Loading state'>
    {() => {
      const [loading, setLoading] = useState(false)
      const onClick = useCallback(() => {
        setLoading(true)
      }, [setLoading])
      return (
        <Button loading={loading} onClick={onClick}>
          Click here for loading
        </Button>
      )
    }}
  </Story>
</Canvas>

### Success state

<Canvas>
  <Story name='Success state'>
    {() => {
      const [success, setSuccess] = useState(false)
      const onClick = useCallback(() => {
        setSuccess(true)
      }, [setSuccess])
      return (
        <Button success={success} onClick={onClick} successIcon={Check} successText='Success'>
          Click here for success
        </Button>
      )
    }}
  </Story>
</Canvas>

### On color state

<Canvas>
  <Story name='On color states'>
    <MultipleStoryElementsWrapper className='l3-storybook-button_on-color-button'>
      <Button color={Button.colors.ON_PRIMARY_COLOR}>Primary on color</Button>
      <Button color={Button.colors.ON_PRIMARY_COLOR} kind={Button.kinds?.SECONDARY}>
        Secondary on color
      </Button>
      <Button color={Button.colors.ON_PRIMARY_COLOR} kind={Button.kinds?.TERTIARY}>
        Tertiary on color
      </Button>
    </MultipleStoryElementsWrapper>
  </Story>
</Canvas>

### Adjacent buttons

<Canvas>
  <Story name='Adjacent buttons'>
    <div>
      <Button
        kind={Button.kinds?.SECONDARY}
        size={Button.sizes?.SMALL}
        ariaLabel='decrease zoom level'
        rightFlat
      >
        <Remove />
      </Button>
      <Button
        kind={Button.kinds?.SECONDARY}
        size={Button.sizes?.SMALL}
        ariaLabel='increase zoom level'
        leftFlat
      >
        <Add />
      </Button>
    </div>
  </Story>
</Canvas>

## Related components

<RelatedComponents componentsNames={[SPLIT_BUTTON, BUTTON_GROUP, TAG]} />
