OTP Field
One-time password input with individual character slots, powered by Base UI
Preview
Enter the 6-character code we sent to your device.
Installation
Usage
Examples
Alphanumeric
Accept letters and numbers for recovery or backup codes.
Accept letters and numbers for backup codes such as A7C9XZ.
Grouped
Split inputs into visual groups with a separator.
Placeholder Hints
Show placeholder characters that hide when the slot is focused.
Placeholder hints stay visible until the active slot is focused.
Custom Sanitization
Restrict input to specific characters with shake animation feedback on invalid input. Uses the bundled useInvalidFeedback hook.
Digits 0-3 only.
Masked Entry
Obscure entered characters for shared screens.
Use mask to obscure the code on shared screens.
Form Integration
Use Field for labeling and form participation. See the Forms guide for more patterns.
API Reference
The OTP Field is built on top of Base UI's OTP Field. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.
For the complete Base UI API, see the Base UI OTP Field documentation.
Props
OTPField
Groups all OTP field parts and manages their state. Wraps Base UI's OTPField.Root. Renders a <div>.
No custom props — all Base UI Root props are passed through, including length, value, onValueChange, validationType, mask, sanitizeValue, and onValueInvalid.
OTPFieldInput
Individual character input slot. Wraps Base UI's OTPField.Input. Renders an <input>.
No custom props — all Base UI Input props are passed through.
OTPFieldSeparator
Visual separator between input groups. Wraps Base UI's Separator. Renders a <div>.
OTPFieldGroup
Layout wrapper for grouping inputs together. Not a Base UI component — renders a plain <div> with display: flex and gap.
Hooks
useInvalidFeedback
Manages shake animation and screen reader feedback for invalid OTP input. Bundled with the component — installed automatically when you install otp-field.
Wire its handlers to OTPField and its className getter to each OTPFieldInput:
Options
Returns
| Property | Type | Description |
|---|---|---|
handleValueChange | () => void | Clears invalid feedback. Wire to OTPField's onValueChange. |
handleValueInvalid | (value: string) => void | Triggers shake animation and status message. Wire to OTPField's onValueInvalid. |
getInvalidClassName | (index: number) => string | undefined | Returns the shake animation className for the active invalid slot, or undefined. |
setFocusedIndex | (index: number) => void | Tracks which slot is focused. Wire to each input's onFocus. |
statusMessage | string | Screen reader announcement. Render inside an aria-live="polite" region. |