ComponentsForms & inputs

Input OTP

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.

input-otp components/input-otp.tsx, styles/forms.csstheme · material · accent · density · font

We sent a 6-digit code to +90 532 ••• 41 07.

Installation

$ pnpm add @vamos-ui/react

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

PropTypeDefault
length
Number of characters.
number6
groups
Slot grouping, e.g. [3, 3]. Must add up to length.
number[]—
value / defaultValue
The code (controlled / uncontrolled).
string""
onValueChange
Called on every change.
(value: string) => void—
onComplete
Called once all slots are filled.
(value: string) => void—
pattern
Allowed characters; digits also sets inputMode=numeric.
"digits" | "alphanumeric" | RegExp"digits"
mask
Show dots instead of characters.
booleanfalse
size
Slot size from --control-h.
"md" | "lg""md"
loading
Verifying: spinner with status text, input read-only, aria-busy.
booleanfalse
invalid
Danger slots + aria-invalid. Set by Field error.
boolean—
name / disabled / autoFocus
Native input props; name submits the code.
string / boolean—
labels
label (“Verification code, {length} digits”), labelCharacters, verifying.
Partial<InputOTPLabels>—

InputOTPRoot · InputOTPGroup · InputOTPSlot · InputOTPSeparator

PropTypeDefault
maxLength
InputOTPRoot: required. Takes every InputOTP prop except length/groups.
number—
index
InputOTPSlot: which character the slot shows.
number—
containerClassName
InputOTPRoot: classes for the slot container.
string—