Usage#
import { useInputOtp } from '@primereact/headless/inputotp';const { rootProps, getTextProps } = useInputOtp();
<div {...rootProps}>
<input {...getTextProps(0)} />
<input {...getTextProps(1)} />
<input {...getTextProps(2)} />
<input {...getTextProps(3)} />
</div>;useInputOtp manages OTP value state, per-input focus navigation, and keyboard/paste handling. See Primitive for a component-based API.
Features#
- Per-slot prop getter —
getTextProps(index)returns the props for each OTP slot, including refs and handlers - Auto focus flow — advances focus on input, retreats on backspace, and supports left/right arrow navigation
- Paste distribution — spreads clipboard content across the remaining slots in a single operation
- Masking and numeric modes —
maskswitches totype="password",integerOnlyrestricts to digits withinputMode="numeric" - Controlled or uncontrolled — value driven via
value/onValueChangeor tracked internally fromdefaultValue
Working with callbacks#
Controlled value#
Pass value and onValueChange when the OTP should live in outside state — for form integration or async verification.
const [code, setCode] = React.useState('');
useInputOtp({
value: code,
onValueChange: (e) => setCode(e.value)
});Numeric-only codes#
Enable integerOnly to restrict input to digits and signal numeric keyboards on mobile.
useInputOtp({ integerOnly: true });Masked entry#
Set mask to render each slot as a password field — useful for sensitive tokens.
useInputOtp({ mask: true });Auto-submit on completion#
Combine controlled value with a length check to trigger submission once all slots are filled.
const [code, setCode] = React.useState('');
useInputOtp({
value: code,
onValueChange: (e) => {
setCode(e.value);
if (e.value.length === 6) verify(e.value);
}
});Styling with data attributes#
The root element includes data-scope="inputotp" and data-part="root". Each input includes data-scope="inputotp" and data-part="input".
[data-scope='inputotp'][data-part='root'] {
display: flex;
gap: 0.5rem;
}
[data-scope='inputotp'][data-part='input'] {
width: 2.5rem;
text-align: center;
}
[data-scope='inputotp'][data-part='input']:focus {
border-color: var(--p-primary-color);
}API#
useInputOtp#
| Name | Type | Default |
|---|---|---|
value | string | — |
| Specifies whether a inputotp should be checked or not. | ||
defaultValue | string | — |
| Specifies whether a inputotp should be checked or not. | ||
integerOnly | boolean | false |
| When present, it specifies that only integers are allowed. | ||
mask | boolean | false |
| Mask pattern. | ||
disabled | boolean | undefined |
| When present, it specifies that the component should be disabled. | ||
onValueChange | (event: useInputOtpValueChangeEvent) => void | — |
| Callback to invoke when value changes. | ||
Accessibility#
Arrow keys move between slots, Backspace clears the current slot and moves left, and paste distributes characters across all slots. See Primitive for full WAI-ARIA compliance details.