Input OTP
A one-time passcode input with split slots, paste support, and SMS autofill.
Features
- One-time passcodes
- Controlled or uncontrolled
- Paste and SMS autofill
- Split slot layouts
onCompletecallback
Installation
npm install @ariaui/input-otp
Examples
Six evenly spaced slots for one-time codes—paste fills across slots; SMS OTP autofill works when the field is named appropriately. Compose Root, Group, and Slot, adding Separator only when the layout needs grouped segments.
Styling uses semantic tokens (border-input, bg-background, dark:bg-input/30, etc.), matching the Figma spacing variant.
Verification code
A split-slot one-time passcode input with numeric entry and SMS autofill support.
No preview output yet.
Framer Motion
Use Slot asChild to render Framer Motion slots with a blinking waiting caret.
No preview output yet.
Anatomy
import * as InputOTP from "@ariaui/input-otp";
export default function Example() {
return (
<InputOTP.Root>
<InputOTP.Group>
<InputOTP.Slot />
</InputOTP.Group>
<InputOTP.Separator />
</InputOTP.Root>
);
}
API Reference
Root
Context provider and container. Renders a visually-hidden native input and distributes characters across Slot children.
| Prop | Type | Default |
|---|---|---|
maxLength* | number | — |
value | string | — |
defaultValue | string | '' |
onChange | (value: string) => void | — |
onComplete | (value: string) => void | — |
disabled | boolean | false |
autoFocus | boolean | false |
Group
A visual grouping of slots. Useful for splitting OTP codes into sections separated by a Separator.
Slot
A single character cell. Displays the character at its index within the OTP value; shows a caret when active and empty.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
| Attribute | Values |
|---|---|
| [data-active] | true when focused at this slot index |
Separator
Decorative separator between groups of slots.
| Attribute | Values |
|---|---|
| role | separator |
Keyboard
| Shortcut | Action |
|---|---|
| 0-9 | Enter a digit at the current slot and advance. |
| Backspace | Delete the focused value. From the next empty slot, focus the previous filled slot and delete it. |
| ← | Move the caret to the previous slot. |
| → | Move the caret to the next slot. |
| Home | Move the caret to the first slot. |
| End | Move the caret to the last filled slot. |
| Ctrl+V/⌘+V | Paste an OTP code; characters fill from the first slot up to maxLength. |
| Tab | Move focus out of the OTP input. |
Accessibility
Input OTP uses a single visually hidden native <input> so browser autofill and assistive technology work as expected:
inputMode="numeric"andpattern="[0-9]*"can surface the numeric keypad on mobile.autocomplete="one-time-code"lets platforms offer SMS passcode autofill.- Always label the field with a visible
<label>oraria-label. - Use
aria-describedbyfor help text, error text, or instructions. - Slots and separators are presentational; focus stays on the hidden input.