ToroUI

Input OTP

A one-time password input with individual character slots, built on input-otp.


A composable OTP (one-time password) input built on the input-otp library. It renders individual character slots grouped together, with optional separators between groups. Supports focus management, fake caret animation, and validation states.

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

export default function InputOtpDemo() {
  return (
    <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>
  )
}

Anatomy

import {
  InputOTP,
  InputOTPGroup,
  InputOTPSlot,
  InputOTPSeparator,
} 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>

Examples

Basic 6-digit OTP

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

With separator

Use InputOTPSeparator to visually divide slot groups, such as a 3-3 pattern.

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

4-digit PIN

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

API Reference

InputOTP

The root input component. Wraps OTPInput from input-otp.

PropTypeDefaultDescription
maxLengthnumberThe total number of OTP characters.
valuestringControlled value.
onChange(value: string) => voidCallback when the value changes.
containerClassNamestringClass name applied to the outer container <div>.
classNamestringClass name applied to the hidden <input> element.

InputOTPGroup

A <div> that groups consecutive InputOTPSlot components with connected borders.

PropTypeDefault
classNamestring
childrenReactNode

InputOTPSlot

A single character slot. Reads its state (character, active, caret) from OTPInputContext using the provided index.

PropTypeDefaultDescription
indexnumberThe zero-based index of this slot within the OTP input.
classNamestring

InputOTPSeparator

A visual separator between slot groups. Renders a dash icon by default.

PropTypeDefault
classNamestring
childrenReactNode