PIN Input
One-time-code / PIN entry.
Usage
maxlength is required — it is how many cells there are. Root hands you
a cells array through a snippet, so you render them. Use onComplete to submit rather than making the user hunt for a button after
typing the last digit.
value: (empty)
One input, not six
The cells look like six boxes. They are not six inputs — Bits renders one real input behind them and the cells are purely visual. That is the whole reason to use this instead of rolling your own, and it buys four things a six-input version loses:
- Paste works. Pasting a six-digit code fills every cell at once.
- Mobile SMS autofill works — the input carries
autocomplete="one-time-code", so the OS offers the code from the message. - No tabbing between boxes, and no focus-juggling bugs to write.
- A screen reader announces one field, not six unlabelled ones.
Use pasteTransformer to clean what arrives — stripping hyphens and
spaces means a code copied as 123-456 still lands correctly.
Naming it
<label for> does not work here.
The id you pass lands on the wrapper <div>, and the real input gets a Bits-internal id you cannot
predict — so a for attribute has nothing to point at, and you ship an unnamed
field. Verified against the rendered DOM, and pinned by a test.
Name it from Root instead; the spread reaches the input:
aria-label="Verification code"— simplest.aria-labelledby="my-label-id"— when you want a visible label. Give your own element an id and point at it, as the example above does.
Props
PinInput.Root — value is bindable.
| Prop | Type | Default |
|---|---|---|
value The entered code. Bindable. | string | '' |
class Extra classes merged onto the root. | string | — |
maxlength required Number of cells, and the max length of the real input. | number | — |
onComplete Fires once every cell is filled. Submit from here. | (value: string) => void | — |
onValueChange | (value: string) => void | — |
pasteTransformer Sanitise pasted text — strip hyphens and spaces before they reach the cells. | (text: string) => string | — |
textalign | 'left' | 'center' | 'right' | 'left' |
disabled | boolean | false |
PinInput.Cell takes the cell object from the
snippet plus class.
| Prop | Type | Default |
|---|---|---|
class Extra classes merged onto the cell. | string | — |