Input OTP

A fixed-length code entry, one box per character. Every box is a real input so autofill can target it, and paste is distributed across all of them.

src/components/ui/input-otp.tsx

About

From the component's own source, where it was written.

A fixed-length code entry, one box per character.

Every box is a real input, so password managers and SMS autofill can target them, and inputMode="numeric" brings up the right keyboard. Paste is handled on any box and distributed across the rest — pasting a code is the common case, and per-box paste would drop all but one character.

Install

npx astralyx-ui add input-otp

Usage

import { InputOTP } from '@/components/ui/input-otp'

<InputOTP length={6} groupAfter={3} onComplete={verify} />

Composer

Change the props and the source below follows.

Props
tsx
<InputOTP
  length={6}
  pattern="numeric"
  groupAfter={3}
  onComplete={verify}
/>

Examples

Six digits, grouped

Four digits

Alphanumeric

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

InputOTP

Extends Omit<ComponentProps<'div'>, 'onChange' | 'defaultValue'>.

PropTypeDefaultDescription
lengthnumber6How many boxes.
valuestring—Controlled and uncontrolled value.
defaultValuestring''Controlled and uncontrolled value.
onValueChange(value: string) => void—Fires on every keystroke.
onComplete(value: string) => void—Fires once the last box is filled.
disabledbooleanfalse—
groupAfternumber—Insert a dash after this many boxes.
pattern'numeric' | 'alphanumeric''numeric'Filters input and picks the mobile keyboard.