Components / Inputs
OtpInput
A six digit verification flow with paste support and keyboard navigation.
Install
npx shadcn@latest add https://irisui.dev/r/otp-input.jsonimport { OtpInput } from "@/components/iris/otp-input/otp-input";Preview
OtpInput
A segmented one-time-code field with paste support, keyboard navigation and a single sliding focus ring.
When to use
- Verifying an email or phone (such as an OpsisID phone check), two-factor sign-in, or confirming a sensitive action with a short code.
- Short fixed-length codes, numeric by default or alphanumeric with
inputMode="text". - Not for passwords or long tokens; use
PasswordStrengthorInput.
Usage
import { OtpInput } from "@/components/iris/otp-input/otp-input";
const [code, setCode] = useState("");
h(OtpInput, {
label: "Verification code",
description: "Code sent to your phone, valid for 10 min.",
value: code,
onChange: (next) => {
setCode(next);
if (next.length === 6) verify(next);
},
autoFocus: true,
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string |
required | Visible label and group name; each slot adds its position ("digit 1 of 6"). |
length |
number |
6 |
Number of slots. |
value |
string |
"" |
Current code (controlled; update from onChange). |
onChange |
(value: string) => void |
– | Full code after every edit or paste. |
description |
string |
– | Helper text below the slots. |
error |
string |
– | Error text; sets aria-invalid and shakes the row once when it changes. |
inputMode |
"numeric" | "text" |
"numeric" |
numeric strips non-digits. |
autoFocus |
boolean |
false |
Focus the first slot on mount. |
disabled |
boolean |
false |
Disables every slot. |
className |
string |
– | Merged onto the field wrapper. |
Notes
- Keyboard: typing fills and advances; arrows move between slots; Backspace on an empty slot clears the previous one; Delete clears the current one; Mod+V pastes across slots.
- The first slot supports
one-time-codeautocomplete so browsers and phones can offer SMS codes. Errors are announced as alerts. - Reduced motion removes the slide, shake and blur in favour of fades.
- The slots sit in a
fieldsetnamed bylabel. Filled slots use anaccentborder overaccent-tint; the focus ring isaccent-ink; errors usered.