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

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

# TextInput

Use TextInput to render a single-line text input. Masks can also be applied to custom format the input; currently supported masks include Credit Card and Phone.

<Canvas isExpanded>
  <TextInput id="demo" label="TextInput Label" />
</Canvas>

## Props

<ArgsTable of={TextInput} />

## Examples

All that is required to render a basic version of the TextInput is a unique `id`, `label`, `value`, and an onchange event handler passed to the `onChange` prop.

<Canvas>
  <Story
    name="Default"
    parameters={{
      design: {
        type: 'figma',
        url: 'https://www.figma.com/file/k1kOsplTGXvSSMQQCzhCND/Palmetto-Design-System?node-id=403%3A0',
      },
    }}
  >
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="default"
          value={value}
          label="TextInput Label"
          onChange={event => setValue(event.target.value)}
        />
      );
    }}
  </Story>
</Canvas>

## Required

Use the `isRequired` prop to set the `required` and `aria-required` on the underlying input element.

<Canvas>
  <Story name="Required">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="required"
          value={value}
          label="Required Text Input"
          onChange={event => setValue(event.target.value)}
          isRequired
        />
      );
    }}
  </Story>
</Canvas>

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

<Canvas>
  <Story name="Custom Required Indicator">
    {() => {
      const [value, setValue] = useState('');
      const [value2, setValue2] = useState('');
      return (
        <Box gap="md">
          <TextInput
            id="requiredWithoutIndicator"
            label="Required Without Indicator"
            value={value}
            onChange={event => setValue(event.target.value)}
            isRequired
            requiredIndicator={null}
          />
          <TextInput
            id="requiredCustomIndicator"
            label="Required Custom Indicator"
            value={value2}
            onChange={event => setValue2(event.target.value)}
            isRequired
            requiredIndicator=" (required)"
          />
        </Box>
      );
    }}
  </Story>
</Canvas>

## With Help Text

Use the `helpText` prop to add clarifying text beneath the input label.

<Canvas>
  <Story name="Help Text">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="helpText"
          value={value}
          label="Mobile Phone"
          helpText="We willl use this phone number to contact you via text"
          onChange={event => setValue(event.target.value)}
        />
      );
    }}
  </Story>
</Canvas>

## Placeholder

Use the `placeholder` prop to add a custom placeholder.

<Canvas>
  <Story name="Placeholder">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="placeholder"
          value={value}
          label="TextInput with placeholder"
          onChange={event => setValue(event.target.value)}
          placeholder="Custom placeholder..."
        />
      );
    }}
  </Story>
</Canvas>

## Autofocus

Use the `autoFocus` prop to autofocus the input.

<Canvas>
  <Story name="Autofocus">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="autofocus"
          value={value}
          label="Label"
          onChange={event => setValue(event.target.value)}
          autoFocus
        />
      );
    }}
  </Story>
</Canvas>

## Hidden Label

Use the `hideLabel` prop to not render the label.

<Canvas>
  <Story name="Hidden Label">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="hiddenLabel"
          value={value}
          label="Hidden Label"
          onChange={event => setValue(event.target.value)}
          hideLabel
        />
      );
    }}
  </Story>
</Canvas>

## Prefix and Suffix

All that is required to render a basic version of the TextInput is a unique `id`, `label`, `value`, and an onchange event handler passed to the `onChange` prop.

<Canvas>
  <Story name="With Prefix and Suffix">
    {() => {
      const [prefixValue1, setPrefixValue1] = useState('palmettosolar');
      const [prefixValue2, setPrefixValue2] = useState('49');
      const [prefixValue3, setPrefixValue3] = useState('');
      const [prefixValue4, setPrefixValue4] = useState('Pre-populated Value');
      return (
        <Box gap="md">
          <TextInput
            id="prefixSuffix1"
            value={prefixValue1}
            label="Prefix"
            onChange={event => setPrefixValue1(event.target.value)}
            prefix="@"
          />
          <TextInput
            id="prefixSuffix2"
            value={prefixValue2}
            label="Prefix and Suffix"
            onChange={event => setPrefixValue2(event.target.value)}
            prefix="$"
            suffix="per watt"
          />
          <TextInput
            id="prefixSuffix3"
            value={prefixValue3}
            label="Suffix"
            placeholder="Contact name"
            onChange={event => setPrefixValue3(event.target.value)}
            suffix={<Icon name="book" />}
          />
          <TextInput
            id="prefixSuffix4"
            value={prefixValue4}
            label="Suffix with Clear"
            placeholder="Contact name"
            onChange={event => setPrefixValue4(event.target.value)}
            onClear={event => setPrefixValue4('')}
            suffix={<Icon name="search" />}
          />
        </Box>
      );
    }}
  </Story>
</Canvas>

## Disabled

Use the `isDisabled` prop to mark the input as disabled.

<Canvas>
  <Story name="Disabled with Value">
    {() => {
      const [value, setValue] = useState('Preset value');
      return (
        <TextInput
          id="disabledWithValue"
          value={value}
          label="Label"
          onChange={event => setValue(event.target.value)}
          isDisabled
        />
      );
    }}
  </Story>
</Canvas>

## Clearable

Use the `onClear` prop to display a clear icon (x) when the input has a value. `onClear` will fire
a callback function when the clear icon is clicked, which can then be handled to clear the value.

<Canvas>
  <Story name="Clearable">
    {() => {
      const [value, setValue] = useState('clear me');
      return (
        <TextInput
          id="required"
          value={value}
          label="Label"
          onChange={event => setValue(event.target.value)}
          onClear={event => setValue('')}
          isRequired
        />
      );
    }}
  </Story>
</Canvas>

## Sizes

Set the `size` of the input to `sm`, `md` or `lg`. The `size` prop is also a `ResponsiveProp`, so it can be sized differently at each [breakpoint](?path=/docs/design-tokens-design-tokens--page#breakpoints) by passing an object.

<Canvas>
  <Story name="Size">
    {() => {
      const [value, setValue] = useState('');
      const [value1, setValue1] = useState('');
      const [value2, setValue2] = useState('');
      const [valueResponsive, setValueResponsive] = useState('');
      return (
        <Box
          direction={{
            base: 'column',
          }}
          gap={{
            base: 'sm',
            tablet: 'md',
            desktop: 'lg',
            hd: 'lg',
          }}
          width="100%"
        >
          <TextInput
            id="sizeSmall"
            value={value}
            label="Small Size"
            size="sm"
            onChange={event => setValue(event.target.value)}
          />
          <TextInput
            id="sizeMedium"
            value={value1}
            label="Medium Size"
            onChange={event => setValue1(event.target.value)}
          />
          <TextInput
            id="sizeLarge"
            value={value2}
            label="Large Size"
            size="lg"
            onChange={event => setValue2(event.target.value)}
          />
          <TextInput
            id="responsiveSize"
            value={valueResponsive}
            label="Responsive Size"
            size={{ base: 'sm', tablet: 'md', desktop: 'lg' }}
            onChange={event => setValueResponsive(event.target.value)}
          />
        </Box>
      );
    }}
  </Story>
</Canvas>

## With Phone Mask

Use the `type` prop to mark the input type as "tel". Use the `inputMask` prop to set the mask as "phone".

<Canvas>
  <Story name="With Phone Mask">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="withPhoneMask"
          value={value}
          label="Label"
          onChange={event => setValue(event.target.value)}
          type="tel"
          inputMask="phone"
        />
      );
    }}
  </Story>
</Canvas>

## With Credit Card Mask

Use the `type` prop to mark the input type as "tel". Use the `inputMask` prop to set the mask as "creditCard".

<Canvas>
  <Story name="With Credit Card Mask">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="withCreditCardMask"
          value={value}
          label="Label"
          onChange={event => setValue(event.target.value)}
          type="tel"
          inputMask="creditCard"
        />
      );
    }}
  </Story>
</Canvas>

## With Date Mask

Use the `type` prop to mark the input type as "tel". Use the `inputMask` prop to set the mask as "date".

<Canvas>
  <Story name="With Date Mask">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="withDateMask"
          value={value}
          label="Date of Birth"
          onChange={event => setValue(event.target.value)}
          inputMask="date"
          type="tel"
          placeholder="MM-DD-YYYY"
        />
      );
    }}
  </Story>
</Canvas>

## Max Length

Use the `maxLength` prop to limit the number of characters that can be entered into an input.

<Canvas>
  <Story name="Max Length">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="maxLength"
          value={value}
          label="Label"
          maxLength="5"
          onChange={event => setValue(event.target.value)}
          placeholder="Can't enter more than 5 characters..."
        />
      );
    }}
  </Story>
</Canvas>

## Validation Error

Use the `error` prop to mark the input as invalid. `error` accepts a `boolean`, `string`, or `node`.

<Canvas>
  <Story name="Required with Error and Validation Message">
    {() => {
      const [value, setValue] = useState('');
      return (
        <TextInput
          id="requiredWithValidationMessage"
          value={value}
          label="Label"
          onChange={event => setValue(event.target.value)}
          isRequired
          error="Helpful validation message"
        />
      );
    }}
  </Story>
</Canvas>
