InputOTP
Accessible one-time-code input built on Base UI OTP Field.
Quick Preview
Enter the code sent to your phone.
Usage
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@giddaa-housing/ui/input-otp";
<InputOTP length={4} name="code">
<InputOTPGroup>
<InputOTPSlot aria-label="Digit 1 of 4" />
<InputOTPSlot aria-label="Digit 2 of 4" />
<InputOTPSlot aria-label="Digit 3 of 4" />
<InputOTPSlot aria-label="Digit 4 of 4" />
</InputOTPGroup>
</InputOTP>InputOTPSlot uses its render order; unlike input-otp-based implementations, it does not require an index prop. Render exactly the number of slots passed to length.
Examples
Sizes
Use size on InputOTP to scale every slot. The value also inherits from InputSizeProvider when size is omitted.
Props
| Prop/API | Type | Default | Description |
|---|---|---|---|
length | number | required | Number of slots and maximum code length. |
size | `"sm" | "md" | "lg" |
validationType | `"numeric" | "alpha" | "alphanumeric" |
value / defaultValue | string | - | Controlled or initial uncontrolled value. |
onValueChange | (value, eventDetails) => void | - | Runs when the normalized code changes. |
onValueComplete | (value, eventDetails) => void | - | Runs after every slot is filled. |
InputOTPGroup | div props | - | Joins adjacent slots into a rounded group. |
InputOTPSlot | Base UI OTP input props | - | A native input for one character. |
InputOTPSeparator | Base UI separator props | - | Visual and semantic separator between groups. |
Accessibility
- Associate the first slot with a visible label by passing
idtoInputOTPand matching it withhtmlForon the label. - Add an
aria-labelto every remaining slot, including its position and total count. - Keep
autoComplete="one-time-code"enabled unless the field is not used for a one-time code. - Base UI provides keyboard navigation, paste distribution, validation, and native form integration.