# Field: OTP Input (category: special)

URL: https://docs.forms.saastro.io/docs/otp

<FieldPreview name="otp" description="Interactive demo of OTP input field" />

## Overview

The OTP (One-Time Password) field provides a series of input boxes for entering verification codes. It's commonly used for 2FA, phone verification, and email confirmation flows.

## Usage

### Basic OTP Input

```tsx

const config = FormBuilder.create('verification')
  .addField('code', (f) =>
    f
      .type('otp')
      .label('Verification Code')
      .helperText('Enter the 6-digit code sent to your email')
      .required('Verification code is required'),
  )
  .addStep('main', ['code'])
  .build();
```

### With Custom Length

The default OTP length is 6 digits. Use `.otpLength()` to change the number of input boxes:

```tsx
.addField('pin', (f) =>
  f.type('otp')
    .label('PIN')
    .otpLength(4)
    .required('PIN is required'),
)
```

In JSON configuration, set the `length` prop directly:

```json
{
  "type": "otp",
  "label": "PIN",
  "length": 4,
  "schema": { "required": true }
}
```

### JSON Configuration

```json
{
  "type": "otp",
  "label": "Verification Code",
  "helperText": "Enter the 6-digit code sent to your phone",
  "schema": { "required": true }
}
```

## Props

| Prop         | Type                                                  | Default | Description                |
| ------------ | ----------------------------------------------------- | ------- | -------------------------- |
| `type`       | `'otp'`                                               | -       | Field type (required)      |
| `label`      | `string`                                              | -       | Label text                 |
| `length`     | `number`                                              | `6`     | Number of digit boxes (builder: `.otpLength(n)`) |
| `helperText` | `string`                                              | -       | Help text below input      |
| `columns`    | `Partial<Record<Breakpoint, number>>`                 | -       | Grid columns by breakpoint |
| `disabled`   | `boolean \| function \| ConditionGroup`               | `false` | Disable the field          |
| `hidden`     | `boolean \| function \| ConditionGroup \| Responsive` | `false` | Hide the field             |

## Validation

### Required Code

```tsx
.addField('verificationCode', (f) =>
  f.type('otp')
    .label('Enter Code')
    .required('Please enter the verification code')
)
```

### With Pattern Validation

```tsx
.addField('pin', (f) =>
  f.type('otp')
    .label('PIN')
    .required()
    .regex('^[0-9]{6}$', 'PIN must be 6 digits')
)
```

## Features

- **Auto-focus**: Automatically focuses the first empty box
- **Auto-advance**: Moves to next box after input
- **Paste support**: Handles pasted codes correctly
- **Backspace handling**: Moves back on delete

## Use Cases

1. **Email verification**: Confirm email ownership
2. **Phone verification**: SMS code entry
3. **Two-factor authentication**: TOTP codes
4. **Payment confirmation**: Transaction PINs

## Styling

### Custom Classes

```tsx
.addField('code', (f) =>
  f.type('otp')
    .label('Verification Code')
    .required()
    .classNames({
      wrapper: 'bg-muted/30 p-6 rounded-lg text-center',
      input: 'border-2 border-primary/20',
      label: 'text-lg font-semibold',
      helper: 'text-muted-foreground text-sm',
      error: 'text-destructive text-sm',
    })
)
```

### Responsive Layout

```tsx
.addField('pin', (f) =>
  f.type('otp')
    .label('PIN')
    .columns({ default: 12, md: 6 })
)
```

### JSON Styling

```json
{
  "type": "otp",
  "label": "Verification Code",
  "wrapper_className": "bg-muted/30 p-6 rounded-lg text-center",
  "input_className": "border-2 border-primary/20",
  "label_className": "text-lg font-semibold",
  "columns": { "default": 12, "md": 6 }
}
```

## Accessibility

- Renders your injected `InputOTP` components (shadcn/ui's are built on the input-otp library)
- Keyboard navigation between boxes
- Screen reader support
- Focus visible states
- Proper ARIA labels
