# 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).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.usegravity.app/gravity-web/components/form.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
