Skip to content

PinInput

OTP-style code field — raised cells with a lift-on-focus active state, auto-advance, paste / SMS-autofill distribution, and backspace transfer.

  • stable
  • since v0.1.0
  • 2.14 kB
  • forms
  • input

First cell carries autocomplete="one-time-code"; ←/→/Home/End move focus; Backspace transfers to the previous cell.

Preview
Open
tsx

Use length to size the OTP field. 4 cells for short PINs, 6 for typical OTPs.

Preview
Open
tsx

Three sizes are available: sm, md (default), and lg.

Preview
Open
tsx

Set type to "numeric" (default), "alphanumeric", or "alphabetic" to restrict the accepted characters.

Preview
Open
tsx

Set mask to render bullets in place of the entered characters, like a password field.

Preview
Open
tsx
Preview
Open
tsx
PropTypeDefaultDescription
length
number
6
Number of cells to render.
value
string
Controlled value (trimmed to `length`).
defaultValue
string
Uncontrolled initial value.
onChange
((value: string) => void)
Fires on every cell change with the next value.
onComplete
((value: string) => void)
Fires once the user has filled all `length` cells.
type
"numeric"|"alphanumeric"|"alphabetic"
"numeric"
Allowed character class. `numeric` enables the numeric mobile keyboard.
mask
boolean
false
Mask the displayed characters (like a password).
size
"sm"|"md"|"lg"
"md"
Control size.
disabled
boolean
false
Disables every cell.
invalid
boolean
Renders the invalid state on every cell.
autoFocus
boolean
Focuses the first cell on mount.
separator
ReactNode
Visual separator rendered at the midpoint of the cells (e.g. a dash for a `123–456` grouping). Omitted by default.
name
string
Submitted form field name (renders a hidden input carrying the concatenated value).
id
string
aria-label
string
"Verification code"
Accessible label for the group; individual cells append `digit N`.
className
string
style
CSSProperties
  • The cells are wrapped in role="group" with an aria-label (defaults to “Verification code”).
  • Each cell has aria-label="… digit N"; the first carries autoComplete="one-time-code" so platform autofill works.
  • Numeric pins set inputMode="numeric" and pattern="[0-9]*" for mobile keyboards.
  • Arrow Left/Right, Home/End move focus; Backspace deletes and transfers focus to the previous cell.
  • Pasting a code distributes characters across the remaining cells.
  • Paste a full code into any cell — it’s distributed across the cells (non-matching characters like spaces or dashes are skipped). iOS SMS one-time-code autofill is handled the same way.

  • Pass separator (e.g. "–") to visually group the cells into halves.

  • Use onComplete to auto-submit once the user fills all length cells.

  • Set mask for security codes you don’t want shoulder-surfed.

  • Pair with a Resend control and a countdown timer for transactional flows.