# OtpInput

> A six-cell one-time code entry with paste, auto-advance and onComplete.

Category: Forms. Docs page: https://rime.mjsons.net/components/otp-input

## Installation

```bash
npx shadcn@latest add KezLahd/rime/otp-input
```

OtpInput is one real input per cell with roving focus. Pasting a full code fills every cell and fires onComplete.

## Usage

```tsx
import { OtpInput } from "@/components/ui";

<OtpInput aria-label="Authenticator code" value={code} onChange={setCode} onComplete={verify} />
```

## Props: OtpInput

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` (required) | `string` |  |  |
| `onChange` (required) | `(value: string) => void` |  |  |
| `onComplete` | `(value: string) => void` |  | Fires once when every box holds a digit, e.g. to auto-submit. |
| `length` | `number` | `6` |  |
| `invalid` | `boolean` |  |  |
| `disabled` | `boolean` |  |  |
| `autoFocus` | `boolean` |  |  |
| `aria-label` | `string` |  | Required when not inside a <Field group>. |
| `className` | `string` |  |  |

## Examples

### Default

```tsx
<OtpInput value={code} onChange={setCode} aria-label="Authenticator code" />
```

## Theme tokens

Per-component tokens. Undeclared by default: the default below is the fallback the CSS uses. Set any of them at :root or on a wrapper to restyle every instance.

| Token | Default |
| --- | --- |
| `--field-focus-border` | `rgba(var(--rgb-brand), 0.75)` |
| `--field-focus-ring` | `var(--focus-halo)` |
| `--field-focus-ring-invalid` | `0 0 0 4px rgba(var(--rgb-danger), 0.14)` |
| `--field-hover-border` | `rgba(var(--rgb-brand-deep), 0.3)` |

System tokens it reads: `--brand`, `--danger-base`, `--dur`, `--ease`, `--focus-halo`, `--font-mono`, `--ink-disabled`, `--ink-heading`, `--line-input`, `--r-md`, `--rgb-brand`, `--rgb-brand-deep`, `--rgb-danger`, `--shadow-input`, `--surface-solid`, `--surface-sunken`.

## Accessibility

- autocomplete="one-time-code" on the first cell lets phones offer the SMS code.

## Do

- Verify on onComplete; don't make users press a button too.

## Don't

- Don't clear the code on a wrong attempt without saying why.
