molecule · stable · app · since 2026-09
OTPField
Purpose
The field of a one-time code: one input, the numeric keyboard, the system’s one-time-code autofill, the digits spaced in the mono face, the length bounded to the digits expected. Field’s props fixed once, so a page cannot forget one.
When to use, when not
Use it on the two-factor page and wherever a code from a message or an authenticator is typed. Not for a password (PasswordField), not for a code the user copies rather than types (CodeBlock).
Anatomy
- Field with the label, the hint, the input in the code face, the error.
Props
| Name | Type | Default | What it does |
|---|---|---|---|
id | string | The control's id; the label's `for` is the same value. | |
label? | string | 'Code de vérification' | The visible label. |
value? | string | undefined | The value, bindable; absent reads as empty. | |
name? | string | The name sent with the form. | |
length? | number | 6 | The number of digits: the longest value accepted. |
required? | boolean | true | Required, which a code always is on its page. |
hint? | string | undefined | A help sentence: where the code comes from, how long it lasts. | |
error? | string | undefined | The error message; its presence alone marks the field invalid. | |
autofocus? | boolean | false | Takes the focus at load: justified on a page that holds this one field and nothing else. |
States
Six digits, seven with a hint, and an error.
code
The numeric keyboard, the system offering the code, six digits spaced in the mono face.
Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured

error
A wrong code: the error tied to the control, the value kept for correction.
Light
Ce code a expiré. Demandez-en un nouveau.
Dark
Ce code a expiré. Demandez-en un nouveau.
320 px, light
Ce code a expiré. Demandez-en un nouveau.
320 px, dark
Ce code a expiré. Demandez-en un nouveau.
216 px, light
Forced colours, captured

seven
A seven-digit code with the hint that says where it comes from.
Light
Le code envoyé par courriel, valable dix minutes.
Dark
Le code envoyé par courriel, valable dix minutes.
320 px, light
Le code envoyé par courriel, valable dix minutes.
320 px, dark
Le code envoyé par courriel, valable dix minutes.
216 px, light
Forced colours, captured

Accessibility contract
- Role and name: the input named by the label, “Code de vérification” by default.
- Keyboard, focus: one Tab stop;
autofocuson a page that holds this field alone; a paste fills the whole code. - Live regions: the error’s, from Field.
Content rules
French. The label is “Code de vérification”; the hint says where the code comes from and how long it lasts; the error says what to do (“Demandez-en un nouveau.”).
Do and don’t
- Do give
autofocuson the page that holds this field and nothing else; nowhere else. - Do keep one input: six boxes are six stops and a paste that lands in the first.
- Do not strip the value on an error; the user corrects one digit.
Examples
<OTPField id="code" name="code" bind:value={form.code} autofocus error={errors.code} hint="Le code de votre application d'authentification." /> Surfaces
- App: the two-factor page.
Related
Field, PasswordField.
Decisions
- 2026-09-26: one input and not one box per digit: the keyboard, the screen reader and the paste all want one field.
Criteria held by construction
- 11.1, Chaque champ de formulaire a-t-il une étiquette ?
Field's label, tied by for and id. - 11.13, La finalité d'un champ de saisie peut-elle être déduite pour faciliter le remplissage automatique des champs avec les données de l'utilisateur ?
autocomplete is one-time-code: the system offers the code it just received, and the user types nothing. - 11.10, Dans chaque formulaire, le contrôle de saisie est-il utilisé de manière pertinente ?
The error and the hint are tied to the control as Field ties them; the value stays for correction.
Tokens it reads
None of its own: the component draws with the base layer alone.