react-lite-otp
v0.1.1
Published
A lightweight React OTP input component.
Downloads
233
Readme
otp-package
A lightweight React OTP input component for numeric one-time passcodes.
Features
- controlled component API
- numeric-only input
- one character per OTP field
- arrow key navigation
- backspace behavior for filled and empty slots
- paste support from any focused slot
- optional completion callback
- optional masking
- ESM build with TypeScript declarations
Installation
npm install react-lite-otpUsage
import { useState } from "react";
import { OTPInput } from "otp-package";
export function VerificationForm() {
const [code, setCode] = useState("");
return (
<OTPInput
autoFocus
maxLength={6}
onChange={setCode}
onComplete={(value) => {
console.log("Completed OTP:", value);
}}
value={code}
/>
);
}Props
| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| maxLength | number | Yes | Total number of OTP fields. Must be a positive integer. |
| value | string | Yes | Controlled OTP value. Non-digits are ignored and values longer than maxLength are clamped internally. |
| onChange | (value: string) => void | Yes | Called whenever the normalized OTP value changes. |
| onComplete | (value: string) => void | No | Called when the resulting value contains exactly maxLength digits. |
| autoFocus | boolean | No | Focuses the first OTP field on mount. |
| masked | boolean | No | Masks digits when true. Defaults to false. |
| className | string | No | Class name applied to the OTP container. |
| inputClassName | string | No | Class name applied to each OTP field. |
Behavior
Typing
- Each OTP field accepts exactly one digit.
- Typing a valid digit overwrites the focused field.
- After a valid digit is entered, focus moves to the next field when one exists.
- Non-digit input is ignored.
Backspace
- If the focused field contains a digit, backspace clears that field and keeps focus there.
- If the focused field is empty and it is not the first field, backspace clears the previous field and moves focus there.
- If the first field is empty, backspace does nothing.
Navigation
ArrowLeftmoves focus to the previous field.ArrowRightmoves focus to the next field.- Users can click any field and edit it directly.
Paste
- Pasted content is sanitized to digits only.
- Paste starts from the currently focused field.
- Digits fill forward from the focused field.
- Overflow digits are truncated.
- Focus lands on the last filled field after paste.
Accessibility
- The container renders as a grouped OTP input.
- Each field gets an internal label such as
OTP digit 1 of 6. - Inputs use
inputMode="numeric"andautoComplete="one-time-code".
Styling
The component ships with minimal built-in inline styles so it is usable out of the box.
Use className and inputClassName to integrate it with your own design system.
