Overview
Many modern applications use One-Time Passcodes (OTPs) for secure authentication. This challenge requires you to build a robust and accessible OTPInput component for a fictional digital wallet app, 'VaultPay'. The goal is to create a seamless user experience for entering multi-digit passcodes, focusing on input handling, focus management, and accessibility best practices.
What you need to do / Task
Your primary task is to create a reusable OTPInput component in React that meets the following requirements:
- The component should accept
length (number of digits), value (current OTP string), onChange (callback for value changes), and disabled props.
- Render
length individual input fields for each digit.
- Implement automatic focus advancement to the next input field upon typing a digit.
- Implement automatic focus movement to the previous input field and deletion of the digit upon pressing
Backspace.
- Handle pasting a full OTP string into any of the input fields, distributing the digits correctly across all fields.
- Ensure that only numeric input is accepted.
- Manage focus and selection states for a smooth user experience.
UI/UX expectations
- Layout: The input fields should be displayed horizontally, appearing as a sequence of distinct boxes.
- Focus: A clear visual indicator (e.g., border color, box-shadow) should highlight the currently focused input field.
- Interaction: Typing a digit should automatically move focus to the next empty box. Pressing
Backspace should clear the current box and move focus to the previous box if not already at the first.
- Accessibility: The component should be navigable and usable with a keyboard. Individual input fields should have appropriate
aria-label attributes to convey their purpose (e.g., "OTP digit 1 of 6").
Acceptance criteria
- The
OTPInput component renders length distinct input fields.
- Typing a digit into an input field populates it and automatically moves focus to the next available field.
- Pressing
Backspace in an input field clears its value and moves focus to the previous field.
- Pasting a string of digits into any input field correctly populates the subsequent fields up to the
length limit.
- The
onChange callback is invoked with the complete OTP string whenever the value changes.
- Only numeric digits (0-9) are accepted as input; non-digit characters are ignored or cleared.
- The component correctly handles the
disabled prop, making all input fields uneditable.
- Keyboard navigation (Tab, Shift+Tab) works as expected between the input fields.
- Each input field has an appropriate
aria-label for screen reader users.
Clarifications
- Q: What should happen if a user types a non-digit character?
- A: The component should ignore or clear non-digit characters, maintaining only numeric input.
- Q: How should pasting a string longer than the OTP length be handled?
- A: Only the first
length digits of the pasted string should be used to populate the fields.
- Q: Should the component support different character types (e.g., alphanumeric)?
- A: No, for this problem, assume OTPs are always numeric digits (0-9).
- Q: Is any specific styling library required?
- A: No, use plain CSS or inline styles. Basic visual representation is sufficient.