Input OTP

A one-time-password input with slotted digits, an active caret, and OS autofill support.

Installation

npx lovdacn@latest add input-otp

(You can also use the shortened lvcn alias, e.g., npx lvcn@latest add input-otp.)

Registry dependencies: text, utils

Usage

InputOTP is controlled — pass value and onChangeText. It renders a transparent TextInput over the slot boxes, so tapping anywhere focuses the field and each keystroke fills the next slot.

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

export function Example() {
  const [value, setValue] = React.useState("")

  return (
    <InputOTP value={value} onChangeText={setValue} 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>
  )
}

Autofill

The overlay input sets textContentType="oneTimeCode" (iOS) and autoComplete="sms-otp" (Android) so the OS can suggest codes received by SMS. keyboardType defaults to number-pad; pass any TextInput prop to override (e.g. keyboardType="default" for alphanumeric codes).

Anatomy

PartDescription
InputOTPControlled root. Props: value, onChangeText, maxLength (default 6), plus any TextInput prop.
InputOTPGroupA row of slots. Use two groups + a separator to split the code.
InputOTPSlotA single digit box. Requires index; shows the active caret when focused.
InputOTPSeparatorA visual divider between groups.

Platform

Targets Expo / React Native with NativeWind or Uniwind. Rather than one TextInput per digit (which is fiddly to keep in sync and to backspace across), it uses a single transparent overlay input with caretHidden and draws its own slots + caret — this keeps paste, autofill, and backspace behaving like a normal field.