Input OTP
Accessible one-time password component with copy paste functionality. Perfect for phone verification, 2FA codes, and PIN inputs.
Basic 6-digit OTP
Standard OTP input with 6 digits
Value: ""
Style Variants
Different visual styles for various use cases
Default
Clean border with subtle background
Outline
Bold borders with transparent background
Filled
Subtle filled background, becomes white on focus
Size Variants
Different sizes for different contexts
Small (40×40px)
Medium - Default (48×48px)
Large (56×56px)
With Separators
Group digits with custom separators
Dash Separator
Value: ""
Dot Separator
4-digit PIN
Shorter OTP for PIN codes
Value: ""
Phone Number Verification
Complete verification flow example
Enter the 6-digit code sent to +1 (555) 000-0000
Value: ""
Masked Input
Hide entered digits for security
Actual value: "" (displayed as dots)
Auto Focus
Automatically focus first input on mount
Value: ""
Disabled State
Non-interactive state for display purposes
Disabled with preset value
✨ Interactive Features
- • Auto-advance: Automatically moves to next input when typing
- • Backspace: Moves to previous input and clears digit
- • Arrow keys: Navigate between inputs
- • Paste support: Paste 6-digit codes from clipboard
- • Mobile optimized: Shows numeric keyboard on mobile devices
- • Validation: Only accepts numeric input
Installation
No external dependencies required. This component is built using only Tailwind CSS and React.
Usage
1import InputOTP from '@/app/ui/molecules/InputOTP';2import { useState } from 'react';34export default function InputOTPExample() {5 const [value, setValue] = useState('');67 return (8 <InputOTP9 length={6}10 value={value}11 onValueChange={setValue}12 />13 );14}
API Reference
InputOTP Props
1interface InputOTPProps {2 length?: number;3 value?: string;4 defaultValue?: string;5 disabled?: boolean;6 autoFocus?: boolean;7 mask?: boolean;8 separator?: React.ReactNode;9 separatorIndexes?: number[];10 size?: 'sm' | 'md' | 'lg';11 variant?: 'default' | 'outline' | 'filled';12 onValueChange?: (value: string) => void;13 onComplete?: (value: string) => void;14 className?: string;15}
Examples
Basic Usage
1function BasicInputOTP() {2 const [value, setValue] = useState('');34 return (5 <InputOTP6 length={6}7 value={value}8 onValueChange={setValue}9 />10 );11}
With Separator
1function WithSeparator() {2 const [value, setValue] = useState('');34 return (5 <InputOTP6 length={6}7 value={value}8 onValueChange={setValue}9 separator={<span className="text-neutral-400">-</span>}10 separatorIndexes={[2]}11 />12 );13}
4-Digit PIN
1function FourDigitPIN() {2 const [value, setValue] = useState('');34 return (5 <InputOTP6 length={4}7 value={value}8 onValueChange={setValue}9 />10 );11}
Masked Input
1function MaskedInput() {2 const [value, setValue] = useState('');34 return (5 <InputOTP6 length={4}7 value={value}8 onValueChange={setValue}9 mask={true}10 />11 );12}
Size Variants
1function SizeExamples() {2 const [value, setValue] = useState('');34 return (5 <div className="space-y-4">6 <InputOTP length={4} size="sm" />7 <InputOTP length={4} size="md" />8 <InputOTP length={4} size="lg" />9 </div>10 );11}
Style Variants
1function VariantExamples() {2 const [value, setValue] = useState('');34 return (5 <div className="space-y-4">6 <InputOTP length={4} variant="default" />7 <InputOTP length={4} variant="outline" />8 <InputOTP length={4} variant="filled" />9 </div>10 );11}
Phone Number Verification
1function PhoneVerification() {2 const [value, setValue] = useState('');34 return (5 <div className="space-y-2">6 <p className="text-sm text-neutral-700 dark:text-neutral-300">7 Enter the 6-digit code sent to +1 (555) 000-00008 </p>9 <InputOTP10 length={6}11 value={value}12 onValueChange={setValue}13 separator={<span className="text-neutral-400">-</span>}14 separatorIndexes={[3]}15 />
Disabled State
1function DisabledInputOTP() {2 return (3 <InputOTP4 length={6}5 disabled6 defaultValue="123456"7 />8 );9}
Features
- Accessible - Built with ARIA support and keyboard navigation
- Copy & Paste - Supports copying and pasting OTP codes
- Multiple Variants - Default, outline, and filled styles
- Size Options - Small, medium, and large sizes
- Customizable - Flexible styling with Tailwind CSS
- Auto-focus - Automatically moves focus to the next input
- Masked Input - Option to hide entered digits
- Separators - Add custom separators between input groups
- Dark Mode - Built-in dark mode support
- TypeScript - Full TypeScript support with proper types
- No Dependencies - Built with only React and Tailwind CSS
Implementation
1'use client';23import React, {4 useState,5 useRef,6 useEffect,7 KeyboardEvent,8 ChangeEvent,9} from 'react';10import { cn } from '@/lib/cn';1112interface InputOTPProps {13 length?: number;14 value?: string;15 defaultValue?: string;