Primitives
Primitive

OTP Field

One-time password input with individual character slots, powered by Base UI

An OTP field splits a one-time passcode across individual character slots, with paste and auto-advance handled for you. Use it for two-factor codes, email verification, or recovery codes.

Preview

Enter the 6-character code we sent to your device.

Installation

Usage

Composition

Examples

Alphanumeric

Set validationType="alphanumeric" to accept letters and numbers for recovery or backup codes.

Accept letters and numbers for backup codes such as A7C9XZ.

Grouped

Wrap inputs in OTPFieldGroup and place an OTPFieldSeparator between groups.

Placeholder Hints

Set placeholder on each OTPFieldInput to show a hint that hides when the slot is focused.

Placeholder hints stay visible until the active slot is focused.

Custom Sanitization

Restrict input to specific characters, with shake feedback on invalid input via the bundled useInvalidFeedback hook.

Digits 0-3 only.

Masked Entry

Set mask on OTPField to obscure entered characters for shared screens.

Use mask to obscure the code on shared screens.

Elevated Variant

On a Card, Dialog, or popover surface, the opaque default slots collapse into the parent. Use variant="elevated" on each OTPFieldInput for a translucent overlay that adapts to the substrate. See the Surfaces docs.

On a Card surface
Use variant="elevated" on OTPFieldInput when the field sits inside a Card, Dialog, or popover.
VariantDescription
defaultOpaque bg-input slots for page-level surfaces.
elevatedTranslucent slots for use inside Card, Dialog, or popover.

Form Integration

Use Field for labeling and form participation. See the Forms guide for more patterns.

Enter the 6-character code we sent to your device.

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, normalizeValue, and onValueInvalid.

OTPFieldInput

Individual character input slot. Wraps Base UI's OTPField.Input. Renders an <input>.

Prop

OTPFieldSeparator

Visual separator between input groups. Wraps Base UI's Separator. Renders a <div>.

Prop

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
Prop
Returns
PropertyTypeDescription
handleValueChange() => voidClears invalid feedback. Wire to OTPField's onValueChange.
handleValueInvalid(value: string) => voidTriggers shake animation and status message. Wire to OTPField's onValueInvalid.
getInvalidClassName(index: number) => string | undefinedReturns the shake animation className for the active invalid slot, or undefined.
setFocusedIndex(index: number) => voidTracks which slot is focused. Wire to each input's onFocus.
statusMessagestringScreen reader announcement. Render inside an aria-live="polite" region.