Search for a command to run...
A one-time-passcode input split into per-character slots. Independent rounded chips with the same bordered chrome as `Input`; the active slot picks up the brand-tinted focus ring. Use for verification codes — auth flows, 2FA, magic-link confirmations.
InputOTP wraps input-otp and forwards every prop. Render one <InputOTPSlot index={i} /> per character — the wrapper handles keyboard, paste, and focus shifting automatically.
InputOTPThe root. Forwards every input-otp OTPInput prop (maxLength, value, onChange, pattern, autoFocus, …).
| Prop | Type | Default | Description |
|---|---|---|---|
maxLength | number | — | Required. Number of slots. Must match the count of <InputOTPSlot> children. |
value | string | — | Controlled value. |
onChange | (value: string) => void | — | Fires on every keystroke. |
pattern | string | — | Restrict accepted characters (REGEXP_ONLY_DIGITS from input-otp is the common pick). |
containerClassName | string | — | Override the default flex items-center gap-2. |
className | string | — | Applied to the hidden underlying <input>. |
InputOTPGroupLayout wrapper for the run of slots.
InputOTPSlotOne character cell. Renders as a responsive square chip (size-10 on mobile / size-12 on sm / size-14 on md+) with border-sand-7 and a blinking caret when focused. Override className for a fixed size on dense surfaces.
| Prop | Type | Default | Description |
|---|---|---|---|
index | number | — | Required. The slot's position in the code (0-indexed). |
Active state (the currently-typed slot) lights up with border-ring + the brand-tinted ring. Pass aria-invalid on the wrapping form field to flip all slots to the destructive border + ring.
Restrict to digits with pattern={REGEXP_ONLY_DIGITS} (from input-otp) when the code is
numeric. The pattern blocks letters / symbols and trims pasted content automatically.
Mark the code length with maxLength and match it to the slot count. Mismatches lead to silent
"code accepted but nothing happens" bugs.
Use InputOTP for free-form text. It's a fixed-length per-character primitive — use Input for
anything other than codes.
Auto-submit on the last keystroke without showing what was entered. Always confirm visually before firing the verification request.