PinInput

One-time code and PIN entry with one cell per character. Typing moves forward, Backspace moves back, and pasting or SMS autofill fills every cell.

StableSource

We sent a 6-digit code to your phone.

Typed: —

Import

import { PinInput } from "@meridui/react";

Examples

Length, mask and characters

API reference

Renders a div role="group"; name it with aria-label, aria-labelledby or a Field. The ref goes to the group.

PropTypeDefaultDescription
lengthnumber6Number of cells.
valuestring–Controlled code.
defaultValuestring""Initial code when uncontrolled.
onValueChange(value: string) => void–Called on every change.
onComplete(value: string) => void–Called once every cell is filled.
type"numeric" | "alphanumeric""numeric"Accepted characters; numeric opens the number pad on mobile.
maskbooleanfalseHide characters like a password.
placeholderstring–Placeholder of empty cells.
getCellLabel(index: number, length: number) => stringCharacter {i} of {n}Accessible name of each cell.
size"sm" | "md" | "lg""md"Cell size.
invalid / disabled / requiredboolean–States; inside a Field they come from it.
autoFocusbooleanfalseFocus the first empty cell on mount.
namestring–Hidden input with the whole code.

Styling

ClassElement
.mrd-pin-inputGroup (data-size, data-invalid, data-disabled)
.mrd-pin-input__cellEach <input> (data-filled)

Accessibility

Each cell is a labelled text input ("Character 1 of 6") inside a named group, and the first cell has autocomplete="one-time-code" so browsers can offer the SMS code. Codes never contain gaps: typing past the end of the code writes into the first empty cell.

KeyAction
0–9A–ZFill the cell and move to the next.
BackspaceClear the cell, or the previous one when empty, and move back.
DeleteRemove the character in the cell; later characters shift back.
ArrowLeftArrowRightPrevious / next cell (reversed in RTL).
HomeEndFirst cell / last filled cell.