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.
We sent a 6-digit code to your phone.
<Field label="Verification code" description="We sent a 6-digit code to your phone.">
<PinInput value={code} onValueChange={setCode} onComplete={verify} name="otp" />
</Field>Import
import { PinInput } from "@meridui/react";Examples
Length, mask and characters
<PinInput aria-label="PIN" length={4} mask size="lg" />
<PinInput aria-label="Invite code" length={5} type="alphanumeric" placeholder="·" />
<PinInput aria-label="Invalid code" length={4} defaultValue="1234" invalid />API reference
Renders a div role="group"; name it with aria-label, aria-labelledby or a Field. The ref goes to the group.
| Prop | Type | Default | Description |
|---|---|---|---|
length | number | 6 | Number of cells. |
value | string | – | Controlled code. |
defaultValue | string | "" | 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. |
mask | boolean | false | Hide characters like a password. |
placeholder | string | – | Placeholder of empty cells. |
getCellLabel | (index: number, length: number) => string | Character {i} of {n} | Accessible name of each cell. |
size | "sm" | "md" | "lg" | "md" | Cell size. |
invalid / disabled / required | boolean | – | States; inside a Field they come from it. |
autoFocus | boolean | false | Focus the first empty cell on mount. |
name | string | – | Hidden input with the whole code. |
Styling
| Class | Element |
|---|---|
.mrd-pin-input | Group (data-size, data-invalid, data-disabled) |
.mrd-pin-input__cell | Each <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.
| Key | Action |
|---|---|
| 0–9A–Z | Fill the cell and move to the next. |
| Backspace | Clear the cell, or the previous one when empty, and move back. |
| Delete | Remove the character in the cell; later characters shift back. |
| ArrowLeftArrowRight | Previous / next cell (reversed in RTL). |
| HomeEnd | First cell / last filled cell. |
Related
- Input — for codes people copy rather than type.
- Authentication pattern.