Skip to content
GetUrUI

OTP Input

New
.md

A one-time-code field where a focus ring glides between slots and digits roll in; wrong codes shake, right ones draw a check.

otpone-time codeverification2fainputformpaste

Installation

$npx shadcn@latest add @geturui/otp-input
Download source (.zip)

Usage

usage.tsx
1import { OtpInput } from "@/components/ui/otp-input";
2
3export function VerifyEmail() {
4  return (
5    <OtpInput
6      length={6}
7      groupSize={3}
8      onComplete={async (code) => {
9        const res = await fetch("/api/verify", { method: "POST", body: code });
10        return res.ok; // true → success check, false → shake and clear
11      }}
12    />
13  );
14}

Props

PropTypeDefaultDescription
lengthnumber6Number of slots.
valuestring—Controlled value. Empty slots in the middle are spaces.
defaultValuestring""Initial value when uncontrolled.
onChange(value: string) => void—Called on every edit.
onComplete(value: string) => boolean | void | Promise<boolean | void>—Called when every slot is filled. Return true to show success, false to shake and clear, nothing to leave status alone.
status"idle" | "error" | "success"—Controlled status; overrides the result of onComplete.
mode"numeric" | "alphanumeric""numeric"Characters accepted. Letters are upper-cased.
groupSizenumber—Draw a dash after every N slots, e.g. 3 → 123–456.
disabledbooleanfalseDisable every slot.
autoFocusbooleanfalseFocus the first slot on mount.
aria-labelstring"Verification code"Accessible name for the group.
classNamestring—Classes for the wrapper.

Accessibility

  • Each slot is a real input labelled “character n of N” inside a labelled group; the first has autocomplete="one-time-code" for SMS autofill.
  • Backspace clears and steps back, ← → Home End move between slots, Delete clears in place.
  • Pasting a full code fills every slot from the start; partial pastes fill from the focused slot.
  • Checking, success and error are announced through a polite live region and aria-invalid; colour is never the only signal.
  • Under reduced motion digits fade instead of rolling and the error shake is skipped.

Related