A one-time code field drawn as slots over one input, so paste, SMS autofill and backspace all work.
Type or paste the 6-digit code.
pnpm dlx shadcn@latest add @latheui/otp-inputPart of Lathe Pro. Set up your project once with your license key: npx latheui init --key <key>. See Lathe Pro.
OTP Input is part of Lathe Pro
The preview is live and free to try. The source, the install and every assembly come with Pro: $79 once, with lifetime updates.
Depends on
Also accepts native input attributes such as name, autoFocus and required. They go to the real input.
| Prop | Type | Default | Description |
|---|---|---|---|
| length | number | 6 | Number of characters. |
| value | string | — | Controlled value. |
| defaultValue | string | "" | Initial value when uncontrolled. |
| onValueChange | (value: string) => void | — | Called on every change. |
| onComplete | (value: string) => void | — | Called once every slot is filled. |
| mode | "numeric" | "alphanumeric" | "numeric" | Accepted characters. Others are dropped, including from pasted text. |
| groupSize | number | — | Adds a divider after every this many slots. |
| mask | boolean | false | Shows dots instead of characters. |
| invalid | boolean | false | Marks the code as wrong. |
| label | string | "Verification code" | Accessible name. |
| disabled | boolean | — | Disables the field. |
<OtpInput length={4} />
<OtpInput length={8} groupSize={4} mode="alphanumeric" />const [code, setCode] = React.useState("")
const [wrong, setWrong] = React.useState(false)
<OtpInput
value={code}
invalid={wrong}
onValueChange={(next) => {
setCode(next)
setWrong(false)
}}
onComplete={async (value) => setWrong(!(await verify(value)))}
/>