import { useState } from 'react';
import { action } from '@storybook/addon-actions';
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs';
import { Box } from '../Box/Box';
import { RadioGroup } from './RadioGroup';

<Meta
  title="Components/RadioGroup/Overview"
  component={RadioGroup}
  parameters={{
    controls: { hideNoControlsWarning: true },
  }}
/>

# RadioGroup

Use a RadioGroup when a user is required to select one of five or fewer options. It is ideal for this scenario because the options are displayed without having to interact. If there are more than five options, use the [SelectInput](?path=/docs/components-selectinput-overview--default-story) instead.

## Props

<ArgsTable of={RadioGroup} />

## Default

All that is required to render a basic version of the RadioGroup is the group's `name`, an onchange event handler passed to the `onChange` prop, and a list of options passed to the `options` prop. Each option must include a unique `id`, a `value`, and a `label`.

<Canvas isExpanded>
  <Story name="Default">
    {() => {
      const [value, setValue] = useState('chocolate');
      const options = [
        {
          id: 'chocolate',
          value: 'chocolate',
          label: 'Chocolate',
        },
        {
          id: 'strawberry',
          value: 'strawberry',
          label: 'Strawberry',
        },
        {
          id: 'vanilla',
          value: 'vanilla',
          label: 'Vanilla',
        },
      ];
      return (
        <RadioGroup
          name="noTitleOrDescription"
          value={value}
          onChange={event => setValue(event.target.value)}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Title

Use the `title` prop to add a title.

<Canvas>
  <Story name="Title">
    {() => {
      const [value, setValue] = useState('purple');
      const options = [
        {
          id: 'purple',
          value: 'purple',
          label: 'Purple',
        },
        {
          id: 'green',
          value: 'green',
          label: 'Green',
        },
        {
          id: 'blue',
          value: 'blue',
          label: 'Blue',
        },
      ];
      return (
        <RadioGroup
          title="Title"
          name="withTitle"
          onChange={event => setValue(event.target.value)}
          value={value}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Title and Description

Use the `title` and `description` props to add a title and description.

<Canvas>
  <Story name="Title and Description">
    {() => {
      const [value, setValue] = useState('light');
      const options = [
        {
          id: 'light',
          value: 'light',
          label: 'Light',
        },
        {
          id: 'dark',
          value: 'dark',
          label: 'Dark',
        },
      ];
      return (
        <RadioGroup
          title="Title"
          description="Description"
          name="withTitleAndDescription"
          onChange={event => setValue(event.target.value)}
          value={value}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Required

Use the `isRequired` prop to mark the group as requiring at least one selection. To avoid confusion as to whether a radio button group is required or not, authors are encouraged to specify the attribute on all the radio buttons in a group. We recommend to avoid having radio button groups that do not have any initially checked controls in the first place, because this is a state that the user cannot return to.

<Canvas>
  <Story name="Required">
    {() => {
      const [value, setValue] = useState('cat');
      const options = [
        {
          id: 'cat',
          value: 'cat',
          label: 'Cat',
        },
        {
          id: 'dog',
          value: 'dog',
          label: 'Dog',
        },
      ];
      return (
        <RadioGroup
          title="Title"
          name="required"
          onChange={event => setValue(event.target.value)}
          value={value}
          isRequired
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

You can remove or customize the required indicator using the `requiredIndicator` prop.

<Canvas>
  <Story name="Custom Required Indicator">
    {() => {
      const [value, setValue] = useState(false);
      const [value2, setValue2] = useState(false);
      const options = [
        {
          id: 'cat',
          value: 'cat',
          label: 'Cat',
        },
        {
          id: 'dog',
          value: 'dog',
          label: 'Dog',
        },
      ];
      return (
        <Box gap="md">
          <RadioGroup
            title="Required Without Indicator"
            name="withoutIndicator"
            onChange={event => setValue(event.target.value)}
            value={value}
            isRequired
            options={options}
            requiredIndicator={null}
          />
          <RadioGroup
            title="Required Custom Indicator"
            name="customIndicator"
            onChange={event => setValue2(event.target.value)}
            value={value2}
            isRequired
            options={options}
            requiredIndicator=" (required)"
          />
        </Box>
      );
    }}
  </Story>
</Canvas>

## Pre-Selected Option

Use the `value` prop to pre-select an option.

<Canvas>
  <Story name="Pre-Selected Option">
    {() => {
      const options = [
        {
          id: 'car',
          value: 'car',
          label: 'Car',
        },
        {
          id: 'truck',
          value: 'truck',
          label: 'Truck',
        },
        {
          id: 'motorcycle',
          value: 'motorcycle',
          label: 'Motorcycle',
        },
      ];
      const [value, setValue] = useState(options[1].value);
      return (
        <RadioGroup
          title="Title"
          name="prevalue"
          onChange={event => setValue(event.target.value)}
          value={value}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Disabled Option

An individual option, or multiple options can be disabled by marking them as disabled in the list of options.

<Canvas>
  <Story name="Disabled Option">
    {() => {
      const [value, setValue] = useState('short');
      const options = [
        {
          id: 'short',
          value: 'short',
          label: 'Short',
        },
        {
          id: 'tall',
          value: 'tall',
          label: 'Tall',
        },
        {
          id: 'gigantic',
          value: 'gigantic',
          label: 'Gigantic',
          disabled: true,
        },
      ];
      return (
        <RadioGroup
          title="Title"
          name="disabledOption"
          onChange={event => setValue(event.target.value)}
          value={value}
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Disabled Group

A group can be fully disabled by using the `isDisabled` prop.

<Canvas>
  <Story name="Disabled Group">
    {() => {
      const [value, setValue] = useState('react');
      const options = [
        {
          id: 'react',
          value: 'react',
          label: 'React',
        },
        {
          id: 'angular',
          value: 'angular',
          label: 'Angular',
        },
        {
          id: 'vue',
          value: 'vue',
          label: 'Vue',
          disabled: true,
        },
      ];
      return (
        <RadioGroup
          title="Title"
          name="disabledGroup"
          onChange={event => setValue(event.target.value)}
          value={value}
          isDisabled
          options={options}
        />
      );
    }}
  </Story>
</Canvas>

## Error

Use the `error` prop to mark the input as invalid. `error` accepts a `boolean`, `string`, or `node`. If either a `string` or `node` is passed, a validation message is displayed below it.

<Canvas>
  <Story name="Error">
    {() => {
      const [value, setValue] = useState('apple');
      const options = [
        {
          id: 'apple',
          value: 'apple',
          label: 'Apple',
        },
        {
          id: 'orange',
          value: 'orange',
          label: 'Orange',
        },
        {
          id: 'banana',
          value: 'banana',
          label: 'Banana',
          disabled: true,
        },
      ];
      return (
        <RadioGroup
          title="Title"
          name="error"
          onChange={event => setValue(event.target.value)}
          value={value}
          options={options}
          isRequired
          error="Helpful validation message"
        />
      );
    }}
  </Story>
</Canvas>

## Sizes

Use the `size` prop to render differently sized radio icons.

<Canvas>
  <Story name="Sizes">
    {() => {
      const [state, setState] = useState({
        sm: null,
        md: null,
        lg: null,
        responsive: null,
      });
      const options = id => [
        { id: `purple__${id}`, value: 'purple', label: 'Purple' },
        { id: `green__${id}`, value: 'green', label: 'Green' },
      ];
      const handleChange = (event, key) => {
        const value = event.target.value;
        setState(prevState => ({ ...prevState, [key]: value }));
      };
      return (
        <Box gap="lg">
          <RadioGroup
            title="Small"
            name="smallRadio"
            onChange={event => handleChange(event, 'sm')}
            value={state.sm}
            options={options('sm')}
            size="sm"
          />
          <RadioGroup
            title="Medium"
            name="mediumRadio"
            onChange={event => handleChange(event, 'md')}
            value={state.md}
            options={options('md')}
            size="md"
          />
          <RadioGroup
            title="Large"
            name="largeRadio"
            onChange={event => handleChange(event, 'lg')}
            value={state.lg}
            options={options('lg')}
            size="lg"
          />
          <RadioGroup
            title="Responsive"
            name="responsiveRadio"
            onChange={event => handleChange(event, 'responsive')}
            value={state.responsive}
            options={options('responsive')}
            size={{ base: 'sm', tablet: 'md', desktop: 'lg', hd: 'sm' }}
          />
        </Box>
      );
    }}
  </Story>
</Canvas>

## Horizontally Aligned

Use the `direction` prop change the alignment of the radio inputs.

<Canvas>
  <Story name="Row">
    {() => {
      const [value, setValue] = useState('one');
      const options = [
        {
          id: 'one',
          value: 'one',
          label: 'One',
        },
        {
          id: 'two',
          value: 'two',
          label: 'Two',
        },
        {
          id: 'three',
          value: 'three',
          label: 'Three',
        },
      ];
      return (
        <RadioGroup
          title="Horizontal"
          direction="row"
          name="horizontal"
          onChange={event => setValue(event.target.value)}
          value={value}
          options={options}
          isRequired
        />
      );
    }}
  </Story>
</Canvas>
