Form input
OTP input
Paste, autofill, edit, and group a code without multi-input focus traps.Anatomy
What sits on screen, and what actually holds the value.
- 1
Label
Above the row, or visually hidden with `labelPlacement="hidden"`.
- 2
Cells
One per character and `aria-hidden`. The active cell shows where the next character lands; entered cells take a tonal container.
- 3
Groups and separator
`groups` splits the cells. A `separator` or the `#separator` slot adds a glyph between groups; without one the gap does the job.
- 4
Native input
Transparent and laid over the whole row. It takes focus, paste, SMS autofill and the caret.
- 5
Message and support
The error message below the row, and `#support` for actions such as resending the code.
Interactive configuration
Change the length, the alphabet and masking, then type or paste a code. The cells only mirror one real input, so paste and autofill fill them all at once.
Length
Match the code the user receives exactly: the row promises that many characters.
Mode
`numeric` opens a digit keypad and drops everything else; `alphanumeric` accepts letters and digits for codes like `A7K29Q`.
Mask
Masked characters are harder to check against the source. Keep it for codes that are secrets, such as a backup PIN.
Custom cells
The `#field`, `#mask` and `#group` slots restyle the cells without touching input: the real input still takes focus, paste and autofill.
States
The cells mirror the one input underneath them.
Where the next character lands
The cell under the caret takes the primary outline.
Entered
An entered character switches its cell to the tonal container.
Rejected code
The cells take the error outline, the message appears below the row, and the input carries `aria-invalid`.
Unavailable
The cells drop to the disabled opacity and the input accepts nothing.
In context
The component is shown in a working composition built from public kit primitives.