Skip to content
UI

Search docs

Search components and documentation

New
Menu

Input OTP

An accessible one-time-password input with individual character slots.

Installation

npx logic2b@latest add input-otp

Usage

import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from "@/components/ui/input-otp"

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

Built on input-otp.

API

Prop Type Default
maxLength (InputOTP) number
value / onChange (InputOTP) string / (value: string) => void
pattern (InputOTP) string — regex allow-list (e.g. REGEXP_ONLY_DIGITS)
onComplete (InputOTP) (value: string) => void — fired when all slots fill
disabled (InputOTP) boolean false
index (InputOTPSlot) number — which slot to render

Examples

Digits Only

Pass a pattern to restrict input — REGEXP_ONLY_DIGITS is re-exported by input-otp.

Controlled

Enter your PIN

Accessibility

  • Renders a single real <input> behind the slots, so browser and password manager autofill of one-time codes (autocomplete="one-time-code") works and the field is announced normally by screen readers.
  • Fully keyboard operable: typing advances through slots, Backspace moves back, and arrow keys plus paste are handled by the underlying input-otp primitive.
  • Invalid state is driven by aria-invalid, which styles the active slot with the destructive ring.