Inputs
OTPInput
A segmented one-time-code input — one box per character, auto-advancing focus as you type, with full paste support for codes copied from SMS/email.
OTPInputPreview
Paste a 6-digit code to see auto-distribution.
Usage
tsx
import { OTPInput } from "@vesture/react";
function Example() {
const [code, setCode] = useState("");
return (
<OTPInput
length={6}
value={code}
onChange={setCode}
onComplete={(value) => verifyCode(value)}
/>
);
}Behavior
- Typing a valid character in a box auto-advances focus to the next box; Backspace on an already-empty box moves focus back to and clears the previous box, rather than doing nothing.
- ArrowLeft/ArrowRight move focus between boxes without altering any box's content.
- Pasting a code (from any box, not just the first) distributes its characters across all boxes starting from the first — the primary real-world path is copy-pasting a code from SMS or email, not typing each digit by hand.
- type="numeric" (the default) accepts only 0-9; type="alphanumeric" accepts letters and digits. Characters that don't match are rejected outright, including on paste.
- onComplete fires exactly once when every box becomes filled — not on every keystroke afterward — so it's safe to trigger verification directly from it.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| length | number | 6 | Number of character boxes. |
| value / defaultValue / onChange | string | — | Controlled / uncontrolled code value. |
| onComplete | (value: string) => void | — | Fires once when the code reaches length with no empty boxes. |
| type | "numeric" | "alphanumeric" | "numeric" | Restricts which characters each box accepts, including pasted ones. |
| disabled | boolean | — | Disables every box. |