OTPInput

The OTPInput component provides a secure way for users to enter one-time passwords (OTP) or verification codes. It creates multiple individual input fields for each digit, providing visual guidance and enhanced user experience for verification workflows. The component supports both numeric and alphanumeric modes, automatic focus management, paste functionality.

Quick Start

Installation
npm install @adaptavant/eds-core
Import
import { OTPInput } from '@adaptavant/eds-core';

Basic usage

A basic OTP input with 6 numeric fields. The component handles auto-advance between fields and provides a completion callback.

<OTPInput
  length={6}
  label="Enter verification code"
/>

Modes

OTP input supports both numeric (numbers only) and alphanumeric (letters and numbers) modes.

Enter OTP Code
Enter Verification Code
<Stack className="gap-4">
  {/* Numeric mode for PIN codes */}
  <Text className="text-body-14">Enter OTP Code</Text>
  <OTPInput
    value="9832"
    length={4}
    mode="numeric"
    label="Enter 4-digit PIN"
  />

  {/* Alphanumeric mode for complex codes */}
  <Text className="text-body-14">Enter Verification Code</Text>
  <OTPInput
    value="a1de4x"
    length={6}
    mode="alphanumeric"
    label="Enter verification code"
  />
</Stack>

Sizes

Customize the size of the OTP input via the size prop, which affects all input fields.

Standard OTPInput
Large OTPInput
<Stack className="gap-4">
  {/* Standard size */}
  <Text className="text-body-14">Standard OTPInput</Text>
  <OTPInput
    length={6}
    size="standard"
    label="Enter OTP"
  />

  {/* Large size */}
  <Text className="text-body-14">Large OTPInput</Text>
  <OTPInput
    length={6}
    size="large"
    label="Enter verification code"
  />
</Stack>

Controlled

Control the OTP input value using the value and onChange props for form integration.

Current value:
const [otpValue, setOtpValue] = React.useState('');

return (
  <Stack className="gap-4">
    <OTPInput
      length={6}
      mode="numeric"
      value={otpValue}
      onChange={setOtpValue}
      label="Enter verification code"
    />
    <Text className="text-body-14">Current value: {otpValue}</Text>
  </Stack>
);

Uncontrolled

Use OTP input in uncontrolled mode by omitting the value prop. The component manages its own state internally.

const [otpValue, setOtpValue] = React.useState("");

return (
  <Stack className="gap-4">
    <OTPInput
      length={6}
      mode="numeric"
      label="Enter verification code"
      onComplete={(value) => {
        setOtpValue(value);
      }}
    />
    {otpValue !== "" && (
      <Text className="text-body-14">OTP onComplete value {otpValue} </Text>
    )}
  </Stack>
);

Error states

Display error states using the errorMessage prop.

<OTPInput
  value="123123"
  length={6}
  mode="numeric"
  errorMessage="Invalid verification code. Please try again."
  label="Enter verification code"
/>

Style API

Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.

Please refer to the Style API documentation for more insights.

Input parts

<OTPInput
  className="bg-caution"
  classNames={{
    input: "bg-positive",
    focusIndicator: "border-accent",
  }}
  value="123123"
  length={6}
  mode="numeric"
  errorMessage="Invalid verification code. Please try again."
  label="Enter verification code"
/>

Field parts

<OTPInput
  classNames={{
    errorTrack: "bg-critical",
    errorIcon: "fill-positive",
    errorMessage: "text-onPrimary",
  }}
  value="123123"
  length={6}
  mode="numeric"
  errorMessage="Invalid verification code. Please try again."
  label="Enter verification code"
/>