> For the complete documentation index, see [llms.txt](https://docs.usegravity.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.usegravity.app/gravity-web/components/form.md).

# Form

You will never experience the pain of coding another HTML form again. The `Form` component is a self-validating form that accepts an object for inputs. It supports various input types, validation, and can handle file uploads and Stripe payments.

### Preview

<div align="left"><figure><img src="/files/JP7ixWuazAzB8xfp2knD" alt="Gravity form component" width="375"><figcaption></figcaption></figure></div>

### Usage

```javascript
import { Form } from 'components/lib';

function MyComponent({ ...props }){

  return (
    <Form 
      inputs={
        name: {
          type: 'text',
          label: 'Name',
          required: true,
        },
        email: {
          type: 'email',
          label: 'Email',
          required: true,
        },
      }
      url='/api/user'
      method='PATCH'
      buttonText='Save'
      callback={(res) => console.log(res)}
    />
  );
}
```

### Props

| Prop           | Description                                  | Required | Value                                                               |
| -------------- | -------------------------------------------- | -------- | ------------------------------------------------------------------- |
| buttonText     | submit button tet                            | optional | string                                                              |
| callback       | function executed on successful submit       | optional | function                                                            |
| cancel         | cancel callback (also shows a cancel button) | optional | function                                                            |
| className      | custom styling                               | optional | SCSS or Tailwind                                                    |
| destructive    | set submit button color to red               | optional | boolean                                                             |
| inputs         | inputs object                                | required | [object](/gravity-web/components/form.md#inputs-object) (see below) |
| method         | HTTP request type                            | optional | string                                                              |
| onChange       | callback function executed on input change   | optional | function                                                            |
| redirect       | url to redirect to after a successful submit | optional | string                                                              |
| submitOnChange | submit the form on each input change         | optional | boolean                                                             |
| url            | url to post the form to                      | optional | string                                                              |

### Inputs Object

When constructing a form object, each outer key represents an input name and is associated with an object containing various input properties.

```javascript
formData = {
 name: {
  label: 'Your name',
  type: 'text',
  required: true,
  placeholder: 'Jon Smith',
  errorMessage: 'Please enter your name',
 }
}
```

## Input Types

The following input types are available.

* card (creditcard input)
* checkbox
* date
* email
* file
* hidden
* number
* password
* phone
* radio
* select
* switch
* text
* textarea
* url
* otp (one-time password)

## Input Props

Props are passed to the input by the form. A full list of props for the inputs can be found below.

| Prop             | Description                                       | Required | Value                  |
| ---------------- | ------------------------------------------------- | -------- | ---------------------- |
| aria-describedby | id of the element that describes the input        | optional | string                 |
| aria-invalid     | determines if the input is valid                  | required | boolean                |
| className        | custom style                                      | optional | SCSS or Tailwind style |
| defaultValue     | default value                                     | optional | string                 |
| disabled         | disable the input                                 | optional | boolean                |
| id               | html id for the input                             | optional | string                 |
| name             | input name                                        | required | string                 |
| onChange         | callback function executed on change              | required | function               |
| placeholder      | placeholder text                                  | optional | string                 |
| required         | determines if a value is required                 | optional | boolean                |
| value            | current value                                     | optional | string                 |
| min              | minimum value                                     | optional | integer                |
| minLength        | minimum length                                    | optional | integer                |
| max              | maximum value                                     | optional | integer                |
| maxLength        | maximum length                                    | optional | integer                |
| options          | array of options for a radio, checkbox, or select | optional | array                  |

### Form Validation

The form will validate the standard input types, as defined in the form/input/map.js file. Here you can extend the validation and add your own custom validation rules.

```javascript
// default phone validation
phone: {
 component: Input,
  showIcon: true,
  showLabel: true,
  validation: {
    default: /^\+?(?:[0-9] ?){6,14}[0-9]$/
  }
}

// custom validation rule
password: {
  component: Input,
  showIcon: true,
  showLabel: true,
  validation: {
    complex:  /^(?=.*[!@#$%^&*(),.?":{}|<>]).*$/
  }
},

// usage
<Form inputs={{
  password: {
  label: t('auth.signup.account.form.password.label'),
  type: 'password',
  required: true,
  validation: { complex: true }
},
```

### Form Submission

When your form is submitted, Gravity will optimise the request and only send the name/value pairs. On the server, you can access a submitted value using:

```javascript
req.body.email
```

### Form Errors

To show an error on a specific form input, throw an error on the server with an `inputError` key and the input name.

```javascript
throw ({ inputError: 'email', message: `You're already registered` });
```

## Payment Form

To create a Stripe payment form, use the `<PaymentForm>` component. This is a standard form (as above) wrapped in a Stripe provider.

### Example

```javascript
import { Form } from 'components/lib';

function Example({ ...props }){

  return (
    <Form 
      inputs={{
        name: {
         label: 'Your name',
         type: 'text',
         required: true,
         description: 'Your full name',
         placeholder: 'Jon Smith',
         errorMessage: 'Please enter your name',
        },
        email: {
         label: 'Email address',
         type: 'email',
         required: true,
        },
        age: {
         label: 'Age',
         type: 'number',
         min: 18,
         max: 65,
         required: false,
        },
        gender: {
         label: 'Gender',
         type: 'radio',
         options: ['male', 'female'],
         required: true,
        },
        plan: {
         label: 'Billing Plan',
         type: 'select',
         options: [
          { value: 'plan_startup', label: 'Startup' },
          { value: 'plan_enterprise', label: 'Enterprise' }
         ],
         defaultValue: 'plan_startup',
         required: true,
       } 
      }
      url='/api/user'
      method='PATCH'
      buttonText='Submit'
      callback={(res) => console.log(res)}
    />
  );
}
```

### Notes

* The `Form` component uses the `useForm` and `Controller` from `react-hook-form` for form management and validation.
* The `inputs` prop defines the form inputs and their configurations.
* The `buttonText` prop specifies the text for the submit button.
* The `callback` prop is a function executed on successful form submission.
* The `destructive` prop sets the submit button color to red.
* The `submitOnChange` prop submits the form on each change.
* The `url` and `method` props define the endpoint and HTTP method for form submission.
* The `Form` component also includes support for Stripe payments through the `PaymentForm` component.
* For more details, refer to the [Shadcn Form documentation](https://ui.shadcn.com/docs/components/form).
