OTP Input
A multi-field numeric input for one-time passwords, verification codes, and other short security codes.
Import OTP Input
Import OtpInput from Tavix:
import { OtpInput } from "tavix";Component API
<OtpInput
length={6}
value
defaultValue=""
onChange
onComplete
disabled={false}
error={false}
autoFocus={true}
size="md"
className
{...props}
/>Props
length: Number of individual input fields. Defaults to6.value: Controlled code value.defaultValue: Initial code value for uncontrolled usage. Defaults to an empty string.onChange: Callback called when the code changes.onComplete: Callback called when all fields contain digits. Receives the complete code.disabled: Prevents editing and interaction whentrue. Defaults tofalse.error: Applies the error state whentrue. Defaults tofalse.autoFocus: Focuses the first field when the component mounts. Defaults totrue.size: Controls the input size. Defaults tomd.className: Additional classes applied to the wrapper....props: Additional input attributes and event handlers.
Behavior
- Renders one input field for each position in the code.
- Accepts numeric digits only.
- Automatically advances to the next field after a digit is entered.
- Moves to the previous field when Backspace or Delete is pressed.
- Supports Arrow Left and Arrow Right navigation between fields.
- Supports pasting a complete code into the focused field.
- Calls
onChangewhenever the code changes. - Calls
onCompletewhen every field contains a digit. - Focuses the first field automatically when
autoFocusistrue. - Prevents editing when
disabledistrue. - Applies the error styling when
erroristrue. - Exposes the wrapper as a group and gives each field a digit-specific accessible label.
Examples
Basic verification code
<OtpInput
length={6}
autoFocus
onChange={setCode}
onComplete={(code) => verifyCode(code)}
/>Controlled value
const [code, setCode] = useState("");
<OtpInput
length={6}
value={code}
onChange={setCode}
onComplete={(completeCode) => {
verifyCode(completeCode);
}}
/>;Uncontrolled value
Use defaultValue when the component should manage its own value after an initial code:
<OtpInput
length={6}
defaultValue="123"
onComplete={(code) => verifyCode(code)}
/>;Custom length and size
<OtpInput
length={4}
size="lg"
autoFocus
onComplete={(code) => confirmPin(code)}
/>;Error and disabled states
<OtpInput
length={6}
error
onChange={setCode}
/>;
<OtpInput
length={6}
value="123456"
disabled
/>;Code changes
Use onChange to track partial input and onComplete to respond only when the code is full:
<OtpInput
length={6}
onChange={(code) => {
setCode(code);
}}
onComplete={(code) => {
submitCode(code);
}}
/>;onComplete receives the complete code as a string. Use the length prop to determine when the code is complete.
Accessibility
- The wrapper exposes the fields as a group.
- Each field provides a digit-specific accessible label.
- Keep surrounding text clear about what the code is used for.
- Use the
errorstate to communicate that the entered code is invalid. - Use
disabledwhen the code cannot currently be edited. - Keep
autoFocusenabled only when moving focus automatically is appropriate for the surrounding workflow.
Notes
- OTP Input accepts digits and ignores non-numeric characters.
- Values are represented as strings so leading zeroes are preserved.
- Use
valuewithonChangefor controlled usage. - Use
defaultValuefor uncontrolled usage with an initial code. - Paste, Backspace, Delete, and arrow navigation work across the individual fields.