import { Meta, Story, ArgsTable, Canvas } from '@storybook/addon-docs/blocks';
import { Selector } from './selector.component';
import { FlowPropsTable, ExternalReferenceLink } from '../../../utils';

<Meta title="Selector" component={Selector} />

# Selector

Renders a list of fancy `radio` or `checkbox` inputs. The `Selector` supports the following props:

`Selector` props:

- `name`
- `onChange`: the selected option (default) or the field's value (when `stateful = true`)
- `children`: where these should be `SelectorItem` components
- `value` (optional): the predefined value of the field. You must also include `stateful` prop for this to apply
- `stateful` (deprecated): if you want to use the stateful version of the component. Ideal if you don't want to manage your own checked state and want the component to.

Pass in the options as `SelectorItem` children with their values specified, the `onChange` function is called with the selected `value` as the argument.

You may also pass a `SelectorButton` as a child that has an `onClick` event.

`SelectorItem` props:

- `value`: the value of this specific option. When clicked, `onChange` will receive this for stateless
- `checked`: the checked state needs to be provided unless `stateful = true`
- `noInput`: When set (in combination with `disabled`) the actual radio or checkbox selector will be invisible. Use this if you want to make it _really_ clear that the user can't select this option.

## Radio

### Stateless (default)

You need to manage the checked state yourself (i.e. it behaves like a [controlled component](https://reactjs.org/docs/forms.html#controlled-components))

```jsx
<Selector
  name={demoId}
  onChange={(v) => {
    setSelected(v);
    action('onChange')(v);
  }}
>
  <SelectorItem
    id="chocolate"
    label="🍫 Chocolate"
    value="chocolate"
    checked={selected === 'chocolate'}
  />
  <SelectorItem
    id="vanilla"
    label="🍦 Vanilla"
    value="vanilla"
    checked={selected === 'vanilla'}
  />
</Selector>
```

### Stateful

Makes selector act like an [uncontrolled component](https://reactjs.org/docs/uncontrolled-components.html).

> Warning: stateful mode is deprecated and will be dropped in a future release. Please prefer stateless mode.

```jsx
<Selector
  name={demoId}
  onChange={action('onChange')}
  value="option-two"
  stateful
>
  <SelectorItem id="option-one" label="First choice" value="option-one" />
  <SelectorItem id="option-two" label="Second choice" value="option-two" />
</Selector>
```

## Checkbox

### Stateless (default)

Stateless means you manage the checked value yourself. The `onChange` handler will receive the **clicked field** value, e.g. if all 3 are selected and you click `"chocolate"`, you will receive only `"chocolate"`. You need to manage the selected state yourself.

```jsx
<Selector
  name={demoId}
  type="checkbox"
  onChange={(v) => {
    if (selected.includes(v)) {
      const newSelected = remove(selected, (item) => v !== item);
      setSelected(newSelected);
    } else {
      const newSelected = concat(selected, v);
      setSelected(newSelected);
    }

    action('onChange')(Array.isArray(v) ? v.join(', ') : v);
  }}
>
  <SelectorItem
    id="chocolate"
    label="🍫 Chocolate"
    value="chocolate"
    checked={selected.includes('chocolate')}
  />
  <SelectorItem
    id="vanilla"
    label="🍦 Vanilla"
    value="vanilla"
    checked={selected.includes('vanilla')}
  />
  <SelectorItem
    id="strawberry"
    label="🍓 Strawberry"
    value="strawberry"
    checked={selected.includes('strawberry')}
  />
</Selector>
```

### Stateful

Stateful means you pass the `Selector` a value and the `onChange` handler will receive the field value, e.g. if all 3 are selected and you click `"chocolate"`, you will receive `["vanilla", "strawberry"]`, i.e. all of the selected items.

> Warning: stateful mode is deprecated and will be dropped in a future release. Please prefer stateless mode.

```jsx
<Selector
  name={demoId}
  type="checkbox"
  onChange={(v) => {
    action('onChange')(Array.isArray(v) ? v.join(', ') : v);
  }}
  value={['vanilla', 'chocolate']}
  stateful
>
  <SelectorItem
    id="ice-cream-chocolate"
    label="🍫 Chocolate"
    value="chocolate"
  />
  <SelectorItem id="ice-cream-vanilla" label="🍦 Vanilla" value="vanilla" />
  <SelectorItem
    id="ice-cream-strawberry"
    label="🍓 Strawberry"
    value="strawberry"
  />
</Selector>
```

## Stories

### Default

<Canvas>
  <Story id="components-inputs-selector--with-label" />
</Canvas>

### Large, Hidden label

<Canvas>
  <Story id="components-inputs-selector--large-hidden-label" />
</Canvas>

### Disabled, Hidden Label

<Canvas>
  <Story id="components-inputs-selector--disabled-hidden-label" />
</Canvas>

### Custom Item Content

<Canvas>
  <Story id="components-inputs-selector--custom-item-content" />
</Canvas>

### Secondary Labels

<Canvas>
  <Story id="components-inputs-selector--secondary-labels" />
</Canvas>

### Large Amounts of Text

<Canvas>
  <Story id="components-inputs-selector--large-amounts-of-text" />
</Canvas>

### Checkboxes

<Canvas>
  <Story id="components-inputs-selector--checkboxes" />
</Canvas>

### Freeform Text Item

<Canvas>
  <Story id="components-inputs-selector--freeform-text-item" />
</Canvas>

### Freeform Text Item (Error)

<Canvas>
  <Story id="components-inputs-selector--freeform-text-item-error" />
</Canvas>

### Small

<Canvas>
  <Story id="components-inputs-selector--with-label" />
</Canvas>

## Supported Property Mixins

Margin-only spacing:

<Canvas>
  <Story id="components-inputs-selector--mixins-margin-only-spacing" />
</Canvas>

Stackee:

<Canvas>
  <Story id="components-inputs-selector--mixins-stackee" />
</Canvas>

## Props

<FlowPropsTable ofComponent={Selector} />

## External Reference

<ExternalReferenceLink
  src="https://github.com/wealthsimple/patchwork/tree/master/core/forms/selector"
  type="github"
/>
