OTP Input
NewOne box per digit with paste, autofill, auto-advance and Backspace handling. Shakes on error.
motionutils@soultel/use-reduced-motion-safe
Check your email
We sent a 6 digit code to maya@acme.com
Hint: the code is 424242.
Installation
$ pnpm dlx shadcn@latest add @soultel/otp-inputNo namespace set up? npx shadcn@latest add https://asafefe.dev/r/otp-input.json works too.
Manual installation
- 1. Install the dependencies.
terminal1 lines npm install motion - 2. Copy the source from the Code tab into components/otp-input.tsx.
Usage
import { useState } from "react"
import { OtpInput, type OtpStatus } from "@/components/otp-input"
export function Verify() {
const [status, setStatus] = useState<OtpStatus>("idle")
return (
<OtpInput
autoFocus
status={status}
onChange={() => setStatus("idle")}
onComplete={async (code) => setStatus((await verify(code)) ? "success" : "error")}
/>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| length | number | 6 | Number of boxes. |
| value / defaultValue | string | - | Controlled or initial code. |
| onChange | (value: string) => void | - | Called on every edit. |
| onComplete | (value: string) => void | - | Called once every box is filled. |
| status | "idle" | "error" | "success" | "idle" | Error shakes and turns red, success pops each box. |
| mode | "numeric" | "alphanumeric" | "numeric" | Accepted characters. |
| split | boolean | - | Dash between two halves. On by default for even lengths. |
| message | ReactNode | - | Text under the boxes, announced to screen readers. |
| name | string | - | Adds a hidden input with the full code for forms. |
