asafefe.dev

OTP Input

New

One 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-input

No namespace set up? npx shadcn@latest add https://asafefe.dev/r/otp-input.json works too.

Manual installation
  1. 1. Install the dependencies.
    terminal1 lines
    npm install motion
  2. 2. Copy the source from the Code tab into components/otp-input.tsx.

Usage

example.tsx14 lines
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

PropTypeDefaultDescription
lengthnumber6Number of boxes.
value / defaultValuestring-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.
splitboolean-Dash between two halves. On by default for even lengths.
messageReactNode-Text under the boxes, announced to screen readers.
namestring-Adds a hidden input with the full code for forms.