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.
Modes
OTP input supports both numeric (numbers only) and alphanumeric (letters and numbers) modes.
<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.
<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.
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"
/>
API Reference
OTPInput
| Prop | Type | Description | Default |
|---|---|---|---|
value? | string | Controlled value of the OTP input. | '' |
length? | 4 | 5 | 6 | 7 | 8 | Number of input fields. | 6 |
mode? | 'numeric' | 'alphanumeric' | Input mode - numeric allows only numbers, alphanumeric allows letters and numbers. | 'numeric' |
autoFocus? | boolean | Auto-focus first input on mount. | false |
onChange? | (value: string) => void | Callback when value changes. | _ |
onComplete? | (value: string) => void | Callback when all fields are filled. | _ |
size? | 'standard' | 'large' | Size of the OTP input fields. | 'standard' |
label | string | Label for the OTP input field group. It will be visually hidden by default. | _ |
errorMessage? | string | Error message to display below the input. | _ |
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"
/>