registry:component
Input OTP
v1.0.0ga
One-time-code input primitive with slot rendering.
Registry Endpoint
Open JSONnpx shadcn@latest add @aavya/ui-input-otp
One-time setup — add the @aavya registry to your components.json so branded dependencies resolve to Aavya (not stock shadcn):
"registries": { "@aavya": "https://registry-dev.aavya.com/r/{name}.json" }Or install by full URL: npx shadcn@latest add https://registry-dev.aavya.com/r/ui-input-otp.json
Live Preview
Verification code
1
2
3
4
5
6
Props
| Part | Prop | Type | Default |
|---|---|---|---|
| InputOTP | containerClassName? | string | — |
| InputOTPSlot | index | number | — |
Usage Snippet
import { InputOtp } from '@/components/ui/input-otp'
export default function Example() {
return (
<div className="p-6">
<InputOtp />
</div>
)
}
Source Preview
'use client'
import * as React from 'react'
import { OTPInput, OTPInputContext } from 'input-otp'
import { MinusIcon } from 'lucide-react'
import { cn } from '@/lib/utils'
function InputOTP({
className,
containerClassName,
...props
}: React.ComponentProps<typeof OTPInput> & {
containerClassName?: string
}) {
return (
<OTPInput
data-slot='input-otp'
containerClassName={cn('flex items-center gap-2 has-disabled:opacity-50', containerClassName)}
className={cn('disabled:cursor-not-allowed', className)}
{...props}
/>
)
}
function InputOTPGroup({ className, ...props }: React.ComponentProps<'div'>) {
return <div data-slot='input-otp-group' className={cn('flex items-center', className)} {...props} />
}
function InputOTPSlot({
index,
className,
...props
}: React.ComponentProps<'div'> & {
index: number
}) {
const inputOTPContext = React.useContext(OTPInputContext)
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
return (
<div
data-slot='input-otp-slot'
data-active={isActive}
className={cn(
'data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-i