One-time code entry for 2FA sign-in, SMS verification, customer-portal email codes and payment confirmation. One real input underneath — screen readers, SMS autofill, password managers and paste all see a single field — with visual slots drawn over it.
We sent a 6-digit code to +90 532 ••• 41 07.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { Field, InputOTP } from "@vamos-ui/react";
<Field label="Verification code">
<InputOTP name="code" groups={[3, 3]} onComplete={verify} />
</Field>autocomplete="one-time-code" lets iOS and Android offer the code from the SMS; paste fills every slot.
Without a Field label the input is named from the dictionary (“Verification code, 6 digits”).
Slots are always left-to-right, also on RTL pages.
Examples
Groups, patterns and masking
groups={[3, 3]} reads as 123–456. pattern="alphanumeric" for backup codes; mask shows dots for PINs. size="lg" for sign-in pages.
Letters and numbers, from the list you saved when you turned on 2FA.
Masked — the characters are never shown.
Verify on complete (payments)
onComplete fires when every slot is filled. loading shows a spinner and makes the input read-only; a Field error shakes the slots once (not under reduced motion).
Enter the code your bank sent. Hint: 246810.
API
InputOTP
| Prop | Type | Default |
|---|---|---|
lengthNumber of characters. | number | 6 |
groupsSlot grouping, e.g. [3, 3]. Must add up to length. | number[] | — |
value / defaultValueThe code (controlled / uncontrolled). | string | "" |
onValueChangeCalled on every change. | (value: string) => void | — |
onCompleteCalled once all slots are filled. | (value: string) => void | — |
patternAllowed characters; digits also sets inputMode=numeric. | "digits" | "alphanumeric" | RegExp | "digits" |
maskShow dots instead of characters. | boolean | false |
sizeSlot size from --control-h. | "md" | "lg" | "md" |
loadingVerifying: spinner with status text, input read-only, aria-busy. | boolean | false |
invalidDanger slots + aria-invalid. Set by Field error. | boolean | — |
name / disabled / autoFocusNative input props; name submits the code. | string / boolean | — |
labelslabel (“Verification code, {length} digits”), labelCharacters, verifying. | Partial<InputOTPLabels> | — |
InputOTPRoot · InputOTPGroup · InputOTPSlot · InputOTPSeparator
| Prop | Type | Default |
|---|---|---|
maxLengthInputOTPRoot: required. Takes every InputOTP prop except length/groups. | number | — |
indexInputOTPSlot: which character the slot shows. | number | — |
containerClassNameInputOTPRoot: classes for the slot container. | string | — |