suiss/uim · Interaction

Otp Autofill

A one-time code input that fills digit by digit from a suggestion above the keyboard, then verifies and shows the result.

Otp Autofill is an open-source mobile interaction from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Otp Autofill on iOS in light mode

OtpAutofill wraps an InputOTP and runs it through idle, filling, verifying, verified and invalid states. When the input is focused and empty, OtpAutofillSuggestion slides up above the keyboard with the incoming code; pressing it types the code one digit at a time.

When all digits are entered, onVerify runs and the slots dim while it is pending. A valid code turns the slots green and locks the input. An invalid code turns them red and shakes the row, then clears the input and refocuses it. Pasting or a system autofill of several digits plays the same digit-by-digit fill.

Installation

$ pnpm dlx @esuiss/uim@latest add otp-autofill

The CLI also adds what it builds on: Input Otp, Text.

Manual

  1. Install the dependencies:
npx expo install cn react-native-reanimated react-native-safe-area-context react-native-worklets
  1. Add the pieces it builds on: Input Otp, Text, and the primitives components/primitives/keyboard.tsx, components/primitives/portal.tsx.

  2. Copy the source into components/interactions/otp-autofill.tsx:

uniwind/components/interactions/otp-autofill.tsx
import { cn } from "cn"
import * as React from "react"
import { Platform, Pressable, type TextInput, View } from "react-native"
import {
  Easing,
  Keyframe,
  ReduceMotion,
  useAnimatedStyle,
  useSharedValue,
  withSequence,
  withTiming,
} from "react-native-reanimated"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { useKeyboard } from "@/components/primitives/keyboard"
import { Portal } from "@/components/primitives/portal"
import { AnimatedView } from "@/components/ui/animated-view"
  1. Update the import paths to match your project.

Usage

import { OtpAutofill, OtpAutofillInput, OtpAutofillSuggestion } from "@/components/interactions/otp-autofill"
<VerificationExample incoming={CODE} />

Pass maxLength and onVerify, which returns a boolean or a promise of one. Put InputOTPGroup and InputOTPSlots inside OtpAutofillInput, and render an OtpAutofillSuggestion with the code your app received; it hides when code is empty.

The input sets textContentType="oneTimeCode" and the platform's one-time code autoComplete, so the system can also offer the code. useOtpAutofill returns state, value, fill and inputRef for custom controls.

Examples

Wrong code

An incoming code that fails verification, showing the shake and reset.

iOS
Otp Autofill (wrong code) on iOS in light mode

Four digits

A four-digit code with its own suggestion.

iOS
Otp Autofill (four digits) on iOS in light mode

API Reference

OtpAutofill

The root that holds the code and verification state.

ExtendsReact.ComponentProps<typeof View>
PropType
About
Number of digits in the code.
Type
number
Default
required
About
Checks a complete code; return true when it is valid.
Type
(code: string) => Promise<boolean> | boolean
Default
required

OtpAutofillInput

The InputOTP that shows each state and shakes on an invalid code.

ExtendsReact.ComponentProps<typeof InputOTP>
PropType
About
Classes for the animated container around the input.
Type
string
Default
—
Type
React.ReactNode
Default
required

OtpAutofillSuggestion

A bar above the keyboard that fills the suggested code on press.

ExtendsReact.ComponentProps<typeof Pressable>
PropType
About
The code to suggest, or null to hide the bar.
Type
stringnullundefined
Default
required
About
Label above the code. Defaults to From Messages.
Type
React.ReactNode
Default
"From Messages"
About
Name of a portal host to render into.
Type
string
Default
—
Type
string
Default
—

Accessibility

  • accessibilityLabel on OtpAutofillInput is passed to the underlying text input.
  • The suggestion bar has the button role.
  • The input is read-only while filling, verifying and after a valid code.

Notes

  • Invalid slots use border-danger with a bg-danger tint that is stronger in dark mode; verified slots use border-success and bg-success-surface.
  • The suggestion bar uses bg-surface-raised, or bg-surface-secondary in dark mode, and sits on the keyboard or above the bottom safe area.
  • Slide and shake animations respect the system reduce motion setting.