Components
OTP input
A one-time-code field: a drop of light stretches to the next cell as you type, characters fall into place and a full code sends an iridescent wave across.
Paste it into ChatGPT, Claude, Cursor or v0.
Usage
import { OTPInput } from '@vizzele/react';
const [code, setCode] = useState('');
const [wrong, setWrong] = useState(false);
<OTPInput
value={code}
onValueChange={(v) => {
setCode(v);
setWrong(false);
}}
onComplete={async (v) => setWrong(!(await verify(v)))}
invalid={wrong}
groupSize={3}
autoFocus
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
length | number | 6 | Number of cells. |
value / defaultValue / onValueChange | string | — | Controlled or uncontrolled. |
onComplete | (code: string) => void | — | Fires once, when the last cell is filled. |
type | 'numeric' | 'alphanumeric' | 'numeric' | Allowed characters; letters are uppercased. |
groupSize | number | — | Draw a gap every n cells. |
mask | boolean | — | Show dots instead of characters. |
invalid | boolean | — | Shake once and turn red. |
label | string | 'One-time code' | Accessible name. |
name | string | — | Submitted with forms. |
Accessibility
- One real input underneath the cells — paste, SMS autofill (autocomplete="one-time-code"), the numeric keypad and screen readers all work as with any field.
- Invalid sets aria-invalid. Reduced motion: characters appear without falling and the wave and shake are off.