InputOTP

stable
Since 1.2
One-time-code field with grouped slots, platform autofill, paste distribution, and progress announced as you type.
Forms
primitive
Form Control
Needs State Matrix
import { InputOTP } from '@ivim/native/components';

When to use

Use when
Someone is entering a short numeric code sent by SMS, email, or an authenticator.
The code has a known fixed length.
Don't use when
The value is a password or any secret the user chose — use a secure Input.
The length varies — use a plain Input, since fixed slots imply a fixed length.

Playground

Adjust the controls to preview live prop combinations. The code snippet updates to match the current selection.
Verification code
size
size
Masked
isSecure
Invalid
isInvalid
Disabled
isDisabled
<InputOTP />

Example

States
Empty
Verification code
Partly entered
Verification code
1
2
3
Grouped (3 + 3)
Verification code
1
2
3
4
5
6
Four digits
PIN
1
2
Masked
PIN
With a description
Verification code
We sent a code to the number ending 0100.
Invalid
Verification code
1
2
3
4
5
6
Disabled
Verification code
1
2
3
4
5
6
Small and large
Small
1
2

Anatomy

The parts that compose this component.
1
Hidden input
The real control. Carries the accessible name, autofill, and paste handling.
2
Cells
Visual mirrors of the value, hidden from assistive tech so the code is not read out digit by digit.
3
Separator
Optional divider between groups.
4
Error
Announced as an alert and appended to the field’s name.

Guidelines

Do
Use onComplete to submit automatically — retyping a code and then reaching for a button is a needless extra step.
Do
Use groupSize for longer codes, so 6 digits read as two groups of three rather than an undifferentiated row.
Do
Show a clear error and let the code be re-entered, rather than clearing it silently on failure.
Don't
Turn on isSecure by default — a one-time code is short-lived and typed once, so masking mostly stops people checking their own typing.

Props

Public props for this component. Required props are marked; defaults reflect the component implementation.
length
number
default: 6
Number of slots.
value / defaultValue
string
Controlled and uncontrolled code.
onChangeText / onComplete
(value: string) => void
Fires on every change, and once when the final slot is filled.
groupSize
number
Splits the slots into groups with a separator between them.
separator
ReactNode
Custom divider between groups. Defaults to a dash.
isSecure
boolean
default: false
Masks entered characters. Off by default — a one-time code is short-lived and typed once.
isDisabled / isInvalid / isRequired
boolean
default: false
Field state; invalid also reaches the accessible name.
label / description / errorMessage
ReactNode
Field anatomy.
aria-label
string
Accessible name when there is no visible label, or when the label is not plain text.
size
'sm' | 'md' | 'lg'
default: 'md'
Cell dimensions and digit scale.

Accessibility

Roles and screen-reader behavior this component provides, plus keyboard interactions.
One hidden input backs every cell, so it has a single accessible name that reports progress: "Verification code, 3 of 6 entered".
The cells are hidden from the accessibility tree — announcing them too would read the code back digit by digit on top of the field’s own name.
The previous implementation put a label on both the wrapper and the input, so the field announced twice.
autoComplete="one-time-code" and textContentType="oneTimeCode" let the platform offer the code from SMS.
Non-digits are stripped from a paste, so a copied "123-456" still fills correctly.
Tab
Moves focus to the field.
Digits
Fill the slots left to right.
Backspace
Removes the last digit, moving back a slot.
Paste
Distributes a full code across the slots.

Platform & RTL

Behavior that differs across the platforms this component runs on.
Web
Paste fills every slot; the browser may offer a saved code.
iOS
The keyboard offers a code from Messages via the one-time-code content type.
Android
Autofill offers an SMS code where the platform supports it.
RTL
Slots stay in logical order — a code is read left to right regardless of writing direction.

State coverage

Interaction and visual states this component supports.
default
focus
error
disabled
selected

Token references

Semantic design tokens this component page exercises. Tap one to edit it live.