Input OTP
Accessible fixed-length code entry — each character gets its own cell, with copy/paste and caret tracking handled for you. Reach for it when the value is a short, known-length token: a 2FA/OTP code, an email verification PIN, or an invite key. For free-length or formatted text (phone, card number, anything the user can't predict the length of) use Input instead. Pair InputOTPGroup + InputOTPSeparator to chunk longer codes (e.g. 3-3) for readability. Slots sit at the canonical md control size (32px) so they line up with md Input and Button in a form.
Default (6-digit)
"use client";
import * as React from "react";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@liquidai/react";
export function Example() {
const [value, setValue] = React.useState("");
return (
<InputOTP maxLength={6} value={value} onChange={setValue}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
);
}With separator
<InputOTP maxLength={6} value={value} onChange={setValue}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>Props
| Component | Notable props |
|---|---|
| InputOTP | maxLength (required), value, onChange, disabled, pattern (e.g. REGEXP_ONLY_DIGITS from input-otp), containerClassName |
| InputOTPGroup | wraps a run of slots; first/last get outer radii automatically |
| InputOTPSlot | index (required) — reads char / caret / active state from OTPInputContext |
| InputOTPSeparator | decorative dash between groups; role="separator" |
Source
packages/react/src/components/input-otp.tsx · built on input-otp