GitHub
Core
Glass
Brutal
Humanist

OTP Input

OTP inputs allow users to enter verification codes with individual character slots. They support configurable lengths, visual separators, masking, and completion callbacks.

OTP Input Playground

OTP Input Playground
Preview
Code
-
Controls
Length:
4
6
Size:
Default
Large
Separator:
Mask:
Disabled:

Installation

You can add the otp input component to your project manually:

1

Install the following dependencies:

npm install class-variance-authority clsx tailwind-merge
2

Copy and paste the following code into your project.

Loading source code...
3

Update the import paths to match your project setup.

Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.

Basic Usage

import { OTPInput } from '@versaui/ui/components/OTPInput';

<OTPInput
  length={6}
  onComplete={(code) => verify(code)}
/>

Length Variants

Supports 4-digit PINs or 6-digit verification codes:

// 4-digit PIN
<OTPInput length={4} />

// 6-digit code (default)
<OTPInput length={6} />

With Separator

Add a visual dash between groups of digits:

// 6-digit with separator after 3rd slot: XXX-XXX
<OTPInput length={6} separator={3} />

// 4-digit with separator after 2nd slot: XX-XX
<OTPInput length={4} separator={2} />

Size Variants

<OTPInput size="default" />
<OTPInput size="large" />

Masked Input

Hide entered characters for sensitive codes:

<OTPInput length={6} mask />

Error State

Show validation errors with an optional message:

// Boolean error
<OTPInput length={6} error />

// With error message
<OTPInput length={6} error="Invalid verification code" />

Controlled Usage

const [otp, setOtp] = useState('');

<OTPInput
  length={6}
  value={otp}
  onChange={(value) => setOtp(value)}
  onComplete={(code) => submitVerification(code)}
/>

Accessibility

  • Each input slot is individually focusable
  • Auto-advances focus on character input
  • Backspace navigates to previous slot
  • Arrow keys, Home, End for slot navigation
  • Full paste support for code entry
  • Error state announced to screen readers via aria-label

OTPInput Props

PropTypeDefaultDescription
length4 | 66Number of OTP digit slots.
separatornumberPosition to show separator (e.g. 3 for XXX-XXX).
size'default' | 'large''default'Input slot size.
valuestringControlled input value.
defaultValuestring''Initial value for uncontrolled usage.
inputMode'numeric' | 'text''numeric'Input keyboard type.
maskbooleanfalseMask entered characters.
disabledbooleanfalsePrevents interaction.
readOnlybooleanfalseRead-only state.
errorboolean | stringfalseError state or message.
autoFocusbooleanfalseFocus first slot on mount.
onChange(value: string) => voidCalled on each character input.
onComplete(value: string) => voidCalled when all slots are filled.
aria-labelstring'Verification code'Accessible label for screen readers.
classNamestring''Additional CSS classes.

On this page