Input OTP

One-time code input with paste support, a blinking caret and digits that hop into place.

Playground

Tweak the props, the preview and the code follow.

Props
6
<InputOTP maxLength={6}>
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    <InputOTPSlot index={1} />
    <InputOTPSlot index={2} />
  </InputOTPGroup>
  <InputOTPSeparator />
  <InputOTPGroup>
    <InputOTPSlot index={3} />
    <InputOTPSlot index={4} />
    <InputOTPSlot index={5} />
  </InputOTPGroup>
</InputOTP>

Installation

npx @plumsydev/plum-ui add input-otp

Usage

import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp"
<InputOTP maxLength={6}>
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    <InputOTPSlot index={1} />
    {/* … */}
  </InputOTPGroup>
</InputOTP>

Examples

Verification flow

Restrict to digits with REGEXP_ONLY_DIGITS and react to onComplete.

Enter the code we sent to your phone.

Resend timer

A complete email verification step.

Check your email

We sent a code to lea@acme.com

API Reference

InputOTP

Wraps OTPInput from input-otp.

PropTypeDefault
maxLength*

Number of characters.

number—
value / onChange

Controlled value.

string / (value: string) => void—
onComplete

Called when every slot is filled.

(value: string) => void—
pattern

Regex source used to filter input, e.g. REGEXP_ONLY_DIGITS.

string—
containerClassName

Class for the outer container.

string—

InputOTPSlot

PropTypeDefault
index*

The slot position.

number—