import { FormExamples, MDXLayoutNext } from '@/components';

export const meta = {
  templateTitle: 'Input',
  description: 'Form component | Fluid Design',
  date: '2023-02-01',
  author: 'Oliver Pan',
  tags: [
    'fluid ui',
    'react',
    'framer motion',
    'headless ui',
    'tailwindcss',
    'form',
    'input',
  ],
};

export default (props) => (
  <MDXLayoutNext meta={meta} components={FormExamples} {...props} />
);

# Input

Fluid UI forms offers a simple and flexible way to build forms. It is built on top of <ExternalLink href="https://formik.org/">Formik</ExternalLink>.
Input field is a basic input field that can be used to input text, numbers, and other types of data.
It supports field validation through Formik's API or `Yup` schema.

<CodeFrame title='Input Example'>
  <FormExamples.Input.Demo />
</CodeFrame>

## Basic Example

<CodeFrame title='Basic Example'>
  <FormExamples.Input.Basic />
</CodeFrame>

```jsx
import { Input } from '@fluid-design/fluid-ui';

const Example = () => {
  return (
    <Form
      initialValues={{
        name: '',
      }}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      <Input name='name' placeholder='Enter your name' type='text' />
    </Form>
  );
};
```

## With validation

Fluid UI forms uses Formik under the hood, which means you can use <ExternalLink href='https://formik.org/docs/guides/validation#field-level-validation'>Formik's API</ExternalLink>
and <ExternalLink href='https://github.com/jquense/yup'>Yup</ExternalLink> schema to validate your fields.
You can read more about validation at the [Form Validation](https://formik.org/docs/validation) page.

```jsx
import { Form, Input, SubmitButton } from '@fluid-design/fluid-ui';
import { useState } from 'react';
import * as Yup from 'yup';

const InputExample = () => {
  const [isSubmitted, setIsSubmitted] = useState(false);
  const validationSchema = Yup.object().shape({
    name: Yup.string().required('Name is required'),
    email: Yup.string().email('Email is invalid').required('Email is required'),
    password: Yup.string()
      .required('Password is required')
      .min(8, 'Password must be at least 8 characters'),
  });
  return (
    <div>
      <Form
        initialValues={{
          name: '',
          email: '',
          password: '',
        }}
        validationSchema={validationSchema}
        onSubmit={(values, { setSubmitting }) => {
          setTimeout(() => {
            setSubmitting(false); // change Formik state to false after 2 seconds
            setIsSubmitted(true); // Optional: change state to show form is submitted
            setTimeout(() => {
              setIsSubmitted(false); // Optional: reset the isLoaded state to false after 2 seconds
            }, 2000);
          }, 2000);
        }}
      >
        <Input name='name' label='Name' type='text' />
        <Input name='email' label='Email' type='email' />
        <Input name='password' label='Password' type='password' />
        <SubmitButton
          weight='outline'
          className='w-full'
          isLoaded={isSubmitted}
          loadedOptions={{
            className: 'text-green-500',
          }}
        >
          Submit
        </SubmitButton>
      </Form>
    </div>
  );
};
```

## State tracking

Fluid UI forms tracks all of the fields inside without needing manual state management.
To ensure the values are connected correctly, you'll need to set the `initialValues` keys the same as each of your input field `name` prop.

<CH.Code>

```jsx
import { Form, Input, SubmitButton } from '@fluid-design/fluid-ui';

<Form
  initialValues={{
    // mark[5:10]
    age: 1,
  }}
  onSubmit={(values) => {
    console.log(values);
  }}
>
  {/* Make sure the name is the same as the initialValues key */}
  // mark[10:19]
  <Input name='age' label='Age' type='number' />
  <SubmitButton>Submit</SubmitButton>
</Form>;
```

</CH.Code>

## Component API

| Prop          | Default | Description                                                                                                      |
| ------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `name`        | -       | `String` <Table.D>Input field name</Table.D>                                                                     |
| `label`       |         | `String` <Table.D>Input field label, if not provided, the label will be the same as the name</Table.D>           |
| `placeholder` |         | `String` <Table.D>Input field placeholder, if label is not provided, this will replace the label field</Table.D> |
| `description` |         | `String` <Table.D>Input field description showing under this field</Table.D>                                     |
