import { createElement, useState } from 'react';
import {
  ArgsTable,
  Canvas,
  Meta,
  Source,
  Story
} from '@storybook/addon-docs/blocks';
import TextInput from 'components/TextInput';
import CWBTheme, { ThemeProvider } from 'styles/CWBTheme';
import Checkmark from 'images/checkmark_circle.svg';
import EyeOpen from 'images/eye_open.svg';
import EyeClosed from 'images/eye_closed.svg';

<Meta title="Components API/TextInput" component={TextInput} />

# TextInput

Allows the user to input text data.

<Canvas>
  <Story name="TextInput">
    <TextInput placeholder="Enter Details" />
  </Story>
</Canvas>

<Source code="import { TextInput } from 'cwb-react';" />

## Usage

You can choose to display a label for the input. Click on labels focus the input. Required inputs display a "\*" at the end of their label.

<ThemeProvider theme={CWBTheme}>
  <Canvas style={{ marginBottom: '0' }}>
    <TextInput label="With Label" placeholder="Click label to focus!" />
    <TextInput
      label="Required Input"
      required
      placeholder="Must not be empty!"
    />
  </Canvas>
  <div style={{ marginTop: '-20px' }}>
    <Source
      code={
        '<TextInput label="With Label" placeholder="Click label to focus!" />\n' +
        '<TextInput\n' +
        '  label="Required Input"\n' +
        '  required\n' +
        '  placeholder="Must not be empty!"\n' +
        '/>'
      }
    />
  </div>
</ThemeProvider>

Form validation is a commonly seen feature. To help you implement error handling, TextInput comes with a predefined style for an error state. The error state consists of a red border and red error message, which can be toggled with the `error` prop and `errorMessage` prop, respectively.

<ThemeProvider theme={CWBTheme}>
  <Canvas style={{ marginBottom: '0' }}>
    <div style={{ display: 'flex', alignItems: 'flex-start' }}>
      <TextInput
        error
        label="Error State without Message"
        placeholder="Enter Details"
      />
      <TextInput
        style={{ marginLeft: '20px' }}
        error
        errorMessage="Error message goes here."
        label="Error State with Message"
        placeholder="Enter Details"
      />
    </div>
  </Canvas>
  <div style={{ marginTop: '-20px' }}>
    <Source
      code={
        '<TextInput\n' +
        '  error\n' +
        '  label="Error State without Message"\n' +
        '  placeholder="Enter Details"\n' +
        '/>\n' +
        '<TextInput\n' +
        '  error\n' +
        '  errorMessage="Error message goes here."\n' +
        '  label="Error State with Message"\n' +
        '  placeholder="Enter Details"\n' +
        '/>'
      }
    />
  </div>
</ThemeProvider>

A node passed into `startAdornment` will be rendered at the beginning of the TextInput. You can use this for displaying icons, icon buttons, etc. Likewise, passing an `endAdornment` renders the passed node at the end of the TextInput.

<ThemeProvider theme={CWBTheme}>
  <Canvas style={{ marginBottom: '0' }}>
    <div style={{ display: 'flex', alignItems: 'flex-start' }}>
      <TextInput
        label="Username"
        placeholder="Enter Details"
        startAdornment={<img src={Checkmark} />}
      />
      <TextInput
        style={{ marginLeft: '20px' }}
        endAdornment={<img src={Checkmark} />}
        label="Username"
        placeholder="Enter Details"
      />
    </div>
  </Canvas>
  <div style={{ marginTop: '-20px' }}>
    <Source
      code={
        `import Checkmark from 'images/checkmark_circle.svg';\n` +
        '\n' +
        '<TextInput\n' +
        '  label="Username"\n' +
        '  placeholder="Enter Details"\n' +
        '  startAdornment={<img src={Checkmark} />}\n' +
        '/>\n' +
        '<TextInput\n' +
        '  endAdornment={<img src={Checkmark} />}\n' +
        '  label="Username"\n' +
        '  placeholder="Enter Details"\n' +
        '/>'
      }
    />
  </div>
</ThemeProvider>

You can combine the use of `endAdornment` and `type` prop to create a password input.

<ThemeProvider theme={CWBTheme}>
  <Canvas style={{ marginBottom: '0' }}>
    {createElement(() => {
      const [show, setShow] = useState(false);
      return (
        <TextInput
          label="Password"
          type={show ? 'text' : 'password'}
          endAdornment={
            <img
              style={{ cursor: 'pointer' }}
              src={show ? EyeOpen : EyeClosed}
              onClick={() => setShow((show) => !show)}
              onMouseDown={(e) => e.preventDefault()}
            />
          }
        />
      );
    })}
  </Canvas>
  <div style={{ marginTop: '-20px' }}>
    <Source
      code={
        `import EyeOpen from 'images/eye_open.svg';\n` +
        `import EyeClosed from 'images/eye_closed.svg';\n` +
        '\n' +
        'const [show, setShow] = useState(false);\n' +
        '\n' +
        'return (\n' +
        '  <TextInput\n' +
        '    label="Password"\n' +
        `    type={show ? 'text' : 'password'}\n` +
        '    endAdornment={\n' +
        '      <img\n' +
        `        style={{ cursor: 'pointer' }}\n` +
        '        src={show ? EyeOpen : EyeClosed}\n' +
        '        onClick={() => setShow((show) => !show)}\n' +
        '        // `preventDefault` is called so that focus remains on the input\n' +
        '        onMouseDown={(e) => e.preventDefault()}\n' +
        '      />\n' +
        '    }\n' +
        '  />\n' +
        ');'
      }
    />
  </div>
</ThemeProvider>

## Props

In addition to the native props that can be passed to an `<input type="text" />`, the following props can also be passed:

<ArgsTable />
