Digit Input
A digit input component for OTP codes, PIN entry, and verification codes. Supports 4 or 5 digit inputs with automatic focus management.
Basic Usage
import { DigitInput } from '@/components'
<DigitInput onComplete={(code) => console.log('Code:', code)} />Lengths
The component supports 4-digit and 5-digit inputs. The 4-digit variant uses flexible width inputs, while the 5-digit variant uses fixed-width inputs.
5 digits (default)
4 digits
5 digits (default)
<DigitInput length={5} />4 digits
<DigitInput length={4} />States
The component has four visual states: Default (empty), Active (focused), Filled, and Error.
Default (empty)
Filled
Active (click to focus)
Default
Empty input boxes ready for input.
<DigitInput />Filled
Input boxes with digits entered.
<DigitInput defaultValue="12345" />Active
When focused, the active input shows a cursor and blue border.
<DigitInput autoFocus />Error State
Use the error state to indicate validation failures, such as an incorrect code.
Error with message
That code is incorrect. Try again.
4-digit error
That code is incorrect. Try again.
<DigitInput
error
errorMessage="That code is incorrect. Try again."
/>Disabled
Disabled inputs cannot be interacted with.
Disabled
<DigitInput disabled />Controlled
You can control the input value externally using the value and onChange props. The onComplete callback fires when all digits are entered.
(empty)const [value, setValue] = useState('')
<DigitInput
value={value}
onChange={setValue}
onComplete={(code) => {
console.log('Code complete:', code)
// Verify the code...
}}
/>Features
- Auto-focus: Automatically moves focus to the next input when a digit is entered
- Backspace navigation: Pressing backspace moves focus to the previous input
- Paste support: Paste a full code and it will be distributed across inputs
- Keyboard navigation: Arrow keys navigate between inputs
- Numeric only: Only accepts numeric input (0-9)
All States Overview
5-digit input
Default
Filled
Error
That code is incorrect. Try again.
4-digit input
Default
Filled
Error
That code is incorrect. Try again.
Accessibility
- Each input has a descriptive
aria-label(e.g., "Digit 1 of 5") - Inputs use
inputMode="numeric"for mobile keyboards - The container has
role="group"for screen reader grouping - Full keyboard support for navigation and input
API Reference
DigitInput Props
| Prop | Type | Default | Description |
|---|---|---|---|
| length | 4 | 5 | 5 | Number of digit inputs |
| value | string | - | Controlled value |
| defaultValue | string | "" | Default value (uncontrolled) |
| onChange | (value: string) => void | - | Callback when value changes |
| onComplete | (value: string) => void | - | Callback when all digits are entered |
| error | boolean | false | Whether to show error state |
| errorMessage | string | - | Error message to display |
| disabled | boolean | false | Whether the input is disabled |
| autoFocus | boolean | false | Whether to focus the first input on mount |
| className | string | - | Additional CSS classes |