OTPInput

A one-time password input composed of individual single-character cells. Supports keyboard navigation, auto-advance, and paste.

Installation

npx dafink-ui add otp-input

Demo

Enter the 6-digit code from your email.

This code has expired.

Props

NameTypeDefaultDescription
lengthnumber6Number of cells.
valuestring''Controlled value. Each character maps to a cell by index.
onChange(value: string) => void-Called with the full updated string on any change.
labelstring-Visible label above the cells.
errorstring-Error message; all cells enter the error state.
hintstring-Helper text shown below the cells.
disabledbooleanfalseDisables all cells.

Accessibility

Every cell is a real, independently focusable <input> in native tab order (not roving tabindex): Tab steps through all cells one by one like any other multi-field form. Each cell carries aria-label="Character N of M", and the cells are grouped under role="group" with aria-labelledby/aria-describedby pointing at the visible label and hint/error text. The native caret is hidden (caret-transparent) and replaced with a decorative, aria-hidden blinking-line cursor that respects prefers-reduced-motion. Only the first cell carries autoComplete="one-time-code", enabling SMS/browser autofill.

KeyFunction
character keyFills the focused cell (filtered by the charset prop) and advances focus to the next cell.
backspaceClears the focused cell if it has a value; if already empty, clears and moves focus to the previous cell.
left arrowMoves focus to the previous cell.
right arrowMoves focus to the next cell.
cmd+vPasting anywhere fills every cell from the start with the first N filtered characters and moves focus to the last filled cell.