Aurora Input OTP
aurora-dinglebear-ai/aurora-input-otpUnverifiedComponent
Segmented one-time-code input slots with Aurora control styling.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/dinglebear-ai/aurora/main/aurora-input-otp.jsonSource
1"use client"23import * as React from "react"45export interface InputOTPProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {6 length?: number7 value?: string8 defaultValue?: string9 onChange?: (value: string) => void10 /** Render a separator dot after the segment at this 1-based index. */11 separatorAfter?: number12 disabled?: boolean13 autoFocus?: boolean14}1516export function InputOTP({17 length = 6,18 value: valueProp,19 defaultValue = "",20 onChange,21 separatorAfter,22 disabled = false,23 autoFocus = false,24 className,25 style,26 ...props27}: InputOTPProps) {28 const isControlled = valueProp !== undefined29 const [internalValue, setInternalValue] = React.useState(defaultValue)30 const value = isControlled ? valueProp : internalValue31 const inputRefs = React.useRef<Array<HTMLInputElement | null>>([])3233 const chars = value.padEnd(length).slice(0, length).split("")3435 const commit = React.useCallback(36 (next: string) => {37 if (!isControlled) setInternalValue(next)38 onChange?.(next)39 },40 [isControlled, onChange],41 )4243 const focusIndex = React.useCallback((index: number) => {44 const clamped = Math.max(0, Math.min(length - 1, index))45 const next = inputRefs.current[clamped]46 next?.focus()47 next?.select()48 }, [length])4950 const writeChars = React.useCallback(51 (startIndex: number, raw: string) => {52 const sanitized = raw.replace(/\s+/g, "")53 if (!sanitized) return54 const next = chars.slice()55 let cursor = startIndex56 for (const char of sanitized) {57 if (cursor >= length) break58 next[cursor] = char59 cursor += 160 }61 commit(next.join("").trimEnd())62 focusIndex(Math.min(cursor, length - 1))63 },64 [chars, commit, focusIndex, length]65 )6667 return (68 <div69 role="group"70 aria-label="One-time passcode"71 className={["flex items-center", className].filter(Boolean).join(" ")}72 style={{ gap: "12px", ...style }}73 {...props}74 >75 {chars.map((char, index) => {76 const filled = char.trim().length > 077 return (78 <React.Fragment key={index}>79 <input80 aria-label={`Digit ${index + 1}`}81 autoFocus={autoFocus && index === 0}82 autoComplete={index === 0 ? "one-time-code" : undefined}83 disabled={disabled}84 inputMode="numeric"85 maxLength={1}86 value={char.trim()}87// … truncated
What it pulls in
Other registry items
Files it writes
More from aurora
All 176 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aurora Accordionaurora-accordion | aurora | Components | Unverified | 2 deps | |
| Aurora Alert Dialogaurora-alert-dialog | aurora | Components | Unverified | 2 deps | |
| Aurora Aspect Ratioaurora-aspect-ratio | aurora | Components | Unverified | no deps | |
| Aurora Avataraurora-avatar | aurora | Components | Unverified | 1 dep | |
| Aurora Badgeaurora-badge | aurora | Components | Unverified | 2 deps | |
| Aurora Banneraurora-banner | aurora | Components | Unverified | 1 dep | |
| Aurora Breadcrumbaurora-breadcrumb | aurora | Components | Unverified | 2 deps | |
| Aurora Buttonaurora-button | aurora | Components | Unverified | 2 deps |
