Short codes, one cell per character, paste-friendly.
| Prop / event | Type | Notes |
|---|---|---|
| length | number | Number of cells (typically 4–6) |
| onComplete | (code) => void | Fires when every cell is filled |
| mask | boolean | Renders • instead of the character |
| status | error · success | Border colour across all cells |
| type · Backspace | — | Auto-advance; empty Backspace steps back |
| paste | — | Spreads a pasted code across the cells |
Use a Pin Input for a short, fixed-length code. For longer or free-form secrets use a password Input.
Match the cell count to the real code length. Four cells for four digits.
Don't use cells for long inputs. Nine tiny boxes is a password field.
Turn every cell red on a wrong code, then let them retry cleanly.
Don't let focus scatter. Typing and pasting must fill left to right.
Six-digit codes from an authenticator or SMS, auto-submitting.
Masked cells for a private PIN or unlock code.
Alphanumeric access codes, one character per cell.
| Token | Value | Role |
|---|---|---|
| --pin-cell | 44 × 52px | Cell size (38 × 46 small) |
| --pin-gap | 10px | Space between cells |
| --pin-font | 1.2rem mono | Centred character |
| --pin-bg | #0E0F12 | Cell fill |
| --pin-focus | rgba(255,122,0,.14) | 3px warm ring on the active cell |
| --pin-error | #EB4A4F | Wrong-code border on all cells |
<div class="o-pin" role="group" aria-label="Verification code"> <input class="o-pin__cell" inputmode="numeric" maxlength="1" aria-label="Digit 1" /> <input class="o-pin__cell" inputmode="numeric" maxlength="1" aria-label="Digit 2" /> <input class="o-pin__cell" inputmode="numeric" maxlength="1" aria-label="Digit 3" /> <input class="o-pin__cell" inputmode="numeric" maxlength="1" aria-label="Digit 4" /> </div>