# OtpInput

A one-time code field shown as equal slots, for email and SMS verification codes. It is one real input with autocomplete one-time-code, not one input per digit, so the platform can fill the code from a message (DECISIONS 2026-10-15). The slots are a visual layer; the input carries the value, the fill and every keyboard behavior. Use Input for free text.

## Cách dùng

### Khi nào dùng

- Enter a short verification code from an email or SMS, checked digit by digit or in full.
- A code the platform can fill from the message, through the single input's autocomplete one-time-code.

### Khi nào không dùng

- A longer identifier the user copies in full, such as an API key or a card number. Use Input.
- A numeric quantity the user adjusts. Use NumberInput.
- Free-form text. Use Input.

## Biến thể

### pattern

numeric accepts digits only (inputmode numeric); alphanumeric also accepts letters.

Giá trị: `numeric`, `alphanumeric`. Mặc định: `numeric`.

### size

Slot size and gap. md by default, lg on touch-first screens, xl for a hero verification step.

Giá trị: `sm`, `md`, `lg`, `xl`. Mặc định: `md`.

## Ví dụ

### Verification code

A six-digit code, verified once complete.

```tsx
const [code, setCode] = React.useState("")
<Field label="Verification code">
  <FieldControl>
    <OtpInput length={6} value={code} onValueChange={setCode} />
  </FieldControl>
</Field>
```

### Rejected code

```tsx
<OtpInput length={6} defaultValue="123456" invalid />
```

### Four digits, touch-first

```tsx
<OtpInput length={4} size="xl" />
```

## Nên và không nên

### Nên

- Use inside Field so the label and error are linked, and set invalid when the server rejects the code.
- Verify in onComplete, and keep the field enabled so the user can correct a rejected code.
- Use lg or xl on touch-first screens; each slot is then 44px or larger.

### Không nên

- Do not build one input per digit; the platform fill from a verification message needs the single input.
- Do not use for identifiers the user copies in full, such as an API key; use Input.
- Do not autofocus on pages where the user must read instructions first.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `length` | `number` |  | `6` | Number of slots. The most common codes are 4 and 6 digits. |
| `pattern` | `enum` | `numeric`, `alphanumeric` | `numeric` | numeric accepts digits only (inputmode numeric); alphanumeric also accepts letters. |
| `value` | `string` |  |  | Controlled code value. Characters outside the pattern and beyond length are filtered. |
| `defaultValue` | `string` |  |  | Initial code for the uncontrolled input. |
| `onValueChange` | `function` |  |  | Called with the filtered code on every change. |
| `onComplete` | `function` |  |  | Called once each time the code reaches full length while the user types, so verification can start. |
| `size` | `enum` | `sm`, `md`, `lg`, `xl` | `md` | Slot size and gap. md by default, lg on touch-first screens, xl for a hero verification step. |
| `disabled` | `boolean` |  | `false` | Disables the input; the slots take the disabled fill and text. |
| `invalid` | `boolean` |  | `false` | Every slot takes the danger border, the input sets aria-invalid. |
| `required` | `boolean` |  | `false` | Standard required attribute on the input. |
| `name` | `string` |  |  | Form field name, submitted by the surrounding form. |

### Slot

| Tên | Bắt buộc | Mô tả |
| --- | --- | --- |
| `value` | không | Controlled or uncontrolled code value, filtered to the pattern and length. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | The strip: a relative flex row that carries the focus ring (has-input-focus-visible) and the size gap. |
| `slot` | One square code cell, sized by size-element so touch sizes apply. Shows the character, or an accent caret bar when it is the next slot to fill while focused. aria-hidden. |
| `caret` | The accent bar in the next slot to fill while focused, in place of the transparent input's caret. |
| `input` | The single text input covering the strip: transparent text and caret over the slots, autocomplete one-time-code, inputmode numeric or text. Carries the value, name, disabled, required and aria-invalid. |

## Khả năng truy cập

Role: `textbox`

| Phím | Hành động |
| --- | --- |
| `0-9 / A-Z` | Fill the next empty slot. Characters outside the pattern are dropped. |
| `Backspace` | Delete the last entered character. |
| `Left / Right` | Move the text caret inside the code, native input behavior. |
| `Paste` | Paste the code; characters outside the pattern are dropped, the rest fill from the start. |

- The slots are aria-hidden; screen readers announce one textbox with the whole code, not one region per digit.
- The platform fill from a verification SMS works because the browser sees a single input with autocomplete one-time-code.
- Use inside Field so the label and error are linked. aria-invalid is set on the input when invalid is true.

## Cài đặt

```bash
npx werewolf-ui add otp-input
```

Chạy `npx werewolf-ui init` một lần trong app trước khi thêm component. Init cài token, thêm CSS import và luật cho agent. Add cài component này cùng các dependency và giữ nguyên theme của bạn. Xem [Cài đặt](https://werewolf-ui.vercel.app/vi/docs/installation.md) để biết yêu cầu và cách cài qua registry.
