Input OTP
An input that lets users enter a one-time code, one character per slot.
An OTP input takes a short code, such as a one-time password, and shows each character in a slot of its own. A single invisible input covers the slots, so users type, paste and autofill the code as one value. A group joins its slots into one block, and a separator divides two groups.
Usage
Examples
With Separator
Codes are easier to read and compare in short parts, the way they often appear on a receipt or a returns label. Between two groups, an InputOTPSeparator marks where one part ends and the next begins. Users still enter the code in one go, and the separator never becomes part of its value.
Digits Only
One-time codes sent by text message usually consist of digits alone. Restricted to digits through pattern, the input rejects every other character, whether users type it or paste it. Touch devices show a numeric keyboard, the default of inputMode.
Letters and Digits
Some codes combine letters and digits, such as the reference of a return or a stock transfer. Once pattern allows both, users can enter either, and inputMode set to "text" gives touch devices a full keyboard, since the numeric keyboard of the default offers no letters.
Controlled
The application can also take charge of the code, for example to fill in a code it already knows or to clear the code after a failed attempt. Through value and onChange it holds the code, so other parts of the interface can read or reset it as well.
Disabled
Entering a code is sometimes not possible yet, for example while the previous attempt is still being checked. Marked as disabled, the input accepts no characters and exposes its state to assistive technology, while users still see where the code will go.
Invalid
A code that has expired or does not match needs to stand out as wrong before users try again. On the input, aria-invalid reports the error to assistive technology, and on every slot it marks the code as rejected, while the input stays ready for a new attempt.
API Reference
InputOTP
| Prop | maxLength |
|---|---|
| Type | number |
| Default | – |
| Description | Sets the number of characters in the code. The input accepts no more than that, and one InputOTPSlot stands for each of them. The component requires this prop. |
| Prop | value |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the code and makes the input controlled. Update it in onChange. |
| Prop | onChange |
|---|---|
| Type | (newValue: string) => unknown |
| Default | – |
| Description | Runs when users type, delete or paste characters. It receives the code that follows as a string, not a change event. |
| Prop | onComplete |
|---|---|
| Type | (...args: any[]) => unknown |
| Default | – |
| Description | Runs when the code reaches the length of maxLength, whether users type the last character or paste the whole code. It receives the complete code as a string. |
| Prop | pattern |
|---|---|
| Type | string |
| Default | – |
| Description | Sets a regular expression that the input tests the code against on every change. The input rejects a change that doesn't match, whether users type or paste it. Anchor the expression with ^ and $, so that it covers every character. Without it, the input accepts any character. |
| Prop | inputMode |
|---|---|
| Type | "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" |
| Default | "numeric" |
| Description | Sets the on-screen keyboard that touch devices show. Set it to "text" when pattern allows letters. It doesn't restrict the characters that the input accepts. |
| Prop | pasteTransformer |
|---|---|
| Type | (pasted: string) => string |
| Default | – |
| Description | Changes pasted text before the input takes it over, for example to remove the hyphen from 482-913. The result still has to match pattern. |
| Prop | placeholder |
|---|---|
| Type | string |
| Default | – |
| Description | Sets one placeholder character per slot for the empty input. The input exposes the text to assistive technology as aria-placeholder, and render receives each character as placeholderChar. InputOTPSlot doesn't show placeholder characters. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | – |
| Description | Prevents users from entering a code, dims the input and exposes the disabled state to assistive technology. |
| Prop | textAlign |
|---|---|
| Type | "left" | "center" | "right" |
| Default | "left" |
| Description | Sets the text alignment of the invisible input that holds the code. The text of that input is transparent, so the slots look the same with every value. |
| Prop | pushPasswordManagerStrategy |
|---|---|
| Type | "increase-width" | "none" |
| Default | "increase-width" |
| Description | Sets how the input reacts when a password manager places its badge in the field. With "increase-width", the invisible input grows 40 pixels to the right when that space is free, so that the badge sits beside the last slot and doesn't cover it. With "none", the input keeps its width. |
| Prop | containerClassName |
|---|---|
| Type | string |
| Default | – |
| Description | Sets classes on the container that lays out the groups and the separators. className goes to the invisible input instead. |
| Prop | noScriptCSSFallback |
|---|---|
| Type | string | null |
| Default | built-in CSS |
| Description | Sets the CSS that makes the invisible input visible while JavaScript is off, so that users can still enter the code. The built-in CSS gives the input a border and a background. null leaves the fallback out. |
| Prop | nonce |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the nonce of the style element that the input adds to the head of the document. Pass it when a Content Security Policy restricts inline styles. |
| Prop | render |
|---|---|
| Type | (props: RenderProps) => ReactNode |
| Default | – |
| Description | Draws the slots with a function in place of children. The function receives slots, isFocused and isHovering, and each entry of slots holds char, placeholderChar, isActive and hasFakeCaret. InputOTPSlot doesn't work inside the function, because it reads its character from a context that only children receive. |
InputOTPGroup
InputOTPGroup holds a row of slots and joins them into one block. It renders a div and has no props of its own.
InputOTPSlot
| Prop | index |
|---|---|
| Type | number |
| Default | – |
| Description | Sets the position in the code whose character the slot shows, starting at 0. The part requires this prop. |
InputOTPSeparator
InputOTPSeparator places a dash between two groups. It renders a div with the role separator and has no props of its own.