import * as React from 'react'; import { cn } from '@/lib/utils'; type OtpState = 'idle' | 'loading' | 'success' | 'error'; interface OtpDigitFieldProps { value: string; onChange: (value: string) => void; length?: number; state?: OtpState; disabled?: boolean; autoFocus?: boolean; id?: string; ariaLabel?: string; } export function OtpDigitField({ value, onChange, length = 6, state = 'idle', disabled = false, autoFocus = false, id, ariaLabel = '6-digit verification code', }: OtpDigitFieldProps) { const inputRef = React.useRef(null); const [focused, setFocused] = React.useState(false); React.useEffect(() => { if (autoFocus && inputRef.current && !disabled) inputRef.current.focus(); }, [autoFocus, disabled]); const activeIndex = Math.min(value.length, length - 1); const isSuccess = state === 'success'; const isError = state === 'error'; const isLoading = state === 'loading'; return (
inputRef.current?.focus()} > onChange(e.target.value)} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)} className="absolute inset-0 h-full w-full cursor-text opacity-0" /> {Array.from({ length }).map((_, i) => { const char = value[i] ?? ''; const filled = char !== ''; const isActive = focused && !disabled && i === activeIndex; return (
{char || (isActive ? : null)}
); })}
); }