Input OTP
Input for one-time codes, with one slot per character.
- Browsers
- Chrome 123+, Firefox 121+, Safari 17.5+
- Tier
- 2
- Bundle compressed
- 1.69 kB
- Forced layout budget
- 0 ms
- Axe budget
- 0
- SSR compatible
- Yes
- Published contract
- Test harness
Playground
import { InputOTP, InputOTPHiddenInput, InputOTPSlot } from "@gunkin/uiify";
export default function Example() {
return (
<InputOTP id="verification-code" length={6}>
{Array.from({ length: 6 }, (_, index) => (
<InputOTPSlot index={index} key={index} />
))}
<InputOTPHiddenInput />
</InputOTP>
);
}API
InputOTPHiddenInput
| Prop | Type | Default | Description |
|---|---|---|---|
autoFocus | boolean | — | — |
render | (props: Record<string, unknown> & { ref?: Ref<HTMLInputElement>; }, state: { disabled: boolean; }) => ReactElement<unknown, string | JSXElementConstructor<any>> | null | — | — |
as | ElementType | "input" | — |
InputOTP
| Prop | Type | Default | Description |
|---|---|---|---|
autoFocus | boolean | false | — |
defaultValue | string | "" | — |
disabled | boolean | false | — |
id | string | — | — |
length | number | 6 | — |
mask | boolean | false | — |
pattern | string | — | — |
size | ControlSize | — | Sets the control's height and text size; `md` is the default. |
type | InputOTPType | "numeric" | — |
onValueChange | (value: string) => void | — | — |
onComplete | (value: string) => void | — | — |
value | string | — | — |
render | (props: Record<string, unknown> & { ref?: Ref<HTMLElement>; }, state: InputOTPShellOwnProps & InputOTPControlledOwnProps) => ReactElement<...> | null | — | — |
as | ElementType | "div" | — |
InputOTPSlot
| Prop | Type | Default | Description |
|---|---|---|---|
index | number | — | — |
render | (props: Record<string, unknown> & { ref?: Ref<HTMLElement>; }, state: { active: boolean; filled: boolean; }) => ReactElement<unknown, string | JSXElementConstructor<any>> | null | — | — |
as | ElementType | "div" | — |
Keyboard
| Key | Action |
|---|---|
| Type / paste | Fill the slots from the start |
| Backspace | Delete the last character |
Accessibility
One native text input, InputOTPHiddenInput, holds the whole code with autocomplete="one-time-code" and the name "One-time code", so typing, paste and autofill reach the form as one value. The slots are aria-hidden visuals that follow it after hydration. Keep visible instructions next to the slots.
Styling hooks
data-completeroot, every slot filleddata-disableddata-activeslotdata-filledslotdata-indexslot