# AddressForm

The `AddressForm` component provides a pre-built UI for collecting billing address information. It integrates seamlessly with `react-hook-form` and includes built-in, country-specific validation for fields like postal codes.

This component is designed to be flexible, supporting both full address collection and a simplified version for Stripe postal code verification.

## Props

| Prop              | Type                               | Description                                                                                                                              | Default         |
| ----------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `mode`            | `string`                           | Determines the fields to display. Set to `'required'` to show the complete address form (line 1, city, state, postal code, country).       | `undefined`     |
| `stripe`          | `boolean`                          | If `true`, displays a simplified form with only the postal code and country, typically used for card validation with Stripe.             | `false`         |
| `sx`              | `SxProps`                          | MUI's `sx` prop for custom styling of the root `Stack` component.                                                                        | `{}`            |
| `fieldValidation` | `Record<string, any>`              | An object for providing custom validation rules, such as regex patterns, for specific fields. See the validation section for details. | `{}`            |
| `errorPosition`   | `'right'` \| `'bottom'`             | Specifies where to display validation error messages relative to the input field.                                                      | `'right'`       |

## Usage

`AddressForm` must be used within a `FormProvider` from `react-hook-form` because it relies on its context to register fields and manage state.

### Standard Billing Address

To collect a full billing address, set the `mode` prop to `'required'`. This will render all standard address fields, each with a 'required' validation rule.

```tsx AddressForm with Full Address icon=material-symbols:location-on-outline
import { FormProvider, useForm } from 'react-hook-form';
import { Button, Stack } from '@mui/material';
import AddressForm from './AddressForm'; // Adjust the import path

export default function FullAddressExample() {
  const methods = useForm({
    defaultValues: {
      billing_address: {
        line1: '',
        city: '',
        state: '',
        postal_code: '',
        country: 'US', // Default country
      },
    },
  });

  const onSubmit = (data) => {
    console.log('Form data:', data);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <Stack spacing={2}>
          <AddressForm mode="required" />
          <Button type="submit" variant="contained">
            Submit
          </Button>
        </Stack>
      </form>
    </FormProvider>
  );
}
```

This setup renders input fields for the address line, city, state, and postal code. The country is selected via the integrated [CountrySelect](./components-ui-form-elements-country-select.md) component.

### Stripe Postal Code Verification

When using payment methods like Stripe, you often only need the postal code and country for card verification. Set the `stripe` prop to `true` to render a simplified form containing only these two fields.

```tsx AddressForm for Stripe icon=logos:stripe
import { FormProvider, useForm } from 'react-hook-form';
import { Button, Stack } from '@mui/material';
import AddressForm from './AddressForm'; // Adjust the import path

export default function StripeAddressExample() {
  const methods = useForm({
    defaultValues: {
      billing_address: {
        postal_code: '',
        country: 'US', // Default country
      },
    },
  });

  const onSubmit = (data) => {
    console.log('Form data:', data);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <Stack spacing={2}>
          <AddressForm stripe={true} />
          <Button type="submit" variant="contained">
            Submit
          </Button>
        </Stack>
      </form>
    </FormProvider>
  );
}
```

## Validation

The component includes automatic validation for required fields. The most notable feature is the dynamic postal code validation, which adjusts its rules based on the selected country.

- **Required Fields**: All visible fields are automatically marked as required.
- **Postal Code**: The validation logic uses the `validator/lib/isPostalCode` library. It checks the postal code format against the selected country's standard format (e.g., 5 digits for the US, alphanumeric for Canada). If a country's format is not explicitly supported, a general validation is applied.
- **Custom Validation**: You can pass additional validation rules via the `fieldValidation` prop. For example, to enforce a specific pattern on the `state` field:

```tsx
const customValidation = {
  'billing_address.state': {
    pattern: '^[A-Z]{2}$',
    pattern_message: {
      en: 'State must be a 2-letter code.',
    },
  },
};

<AddressForm mode="required" fieldValidation={customValidation} />;
```

