InputOTP
A one-time code, one character per cell, advancing as it is typed.
import { InputOTP } from "@glint/components/input-otp.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
in-out property <string> latest-code: "";
VerticalLayout { alignment: center; spacing: 16px; padding: 24px;
HorizontalLayout { alignment: center;
InputOTP { length: 6; completed(code) => { root.latest-code = code; } } }
Text { text: root.latest-code != "" ? "Verified Code: " + root.latest-code : "Enter 6-digit code"; color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } }}Usage
import { InputOTP } from "@glint/components/input-otp.slint";
export component AppWindow inherits Window { VerticalLayout { alignment: center;
InputOTP { length: 6; completed(code) => { // submit verification code } } }}InputOTP renders a segmented row of character cells for one-time verification codes.
Keystrokes fill cells sequentially, Backspace clears and retreats, and completed(string) fires the moment the final cell is filled.
Examples
Input modes
mode restricts allowed characters:
InputOTPMode.numeric: Accepts digits0–9only (ideal for SMS or authenticator codes).InputOTPMode.alphanumeric: Accepts digits and letters (ideal for license keys or mixed promo codes).
import { InputOTP, InputOTPMode } from "@glint/components/input-otp.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 340px; background: Tokens.color-background;
VerticalLayout { alignment: center; spacing: 20px; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { spacing: 16px; alignment: center;
InputOTP { mode: InputOTPMode.numeric; length: 4; }
InputOTP { mode: InputOTPMode.alphanumeric; length: 6; } } } }}Grouping with separators
Set group-size to insert separator rules between cell clusters (for example, group-size: 3 splits 6 cells into two groups of 3).
import { InputOTP } from "@glint/components/input-otp.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
InputOTP { length: 6; group-size: 3; } } }}Validation error state
Set invalid: true to display destructive borders across all cells and announce an invalid state.
import { InputOTP } from "@glint/components/input-otp.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
InputOTP { length: 6; invalid: true; } } }}API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
length | in int | 6 | Number of cells the code is split into (clamped to capacity). |
mode | in InputOTPMode | InputOTPMode.numeric | numeric (default) takes digits only; alphanumeric also takes letters. |
group-size | in int | 0 | Cells per group, with a rule drawn between groups — group-size: 3 on a six-cell field is the canonical 123-456. Zero (the default) lays every cell out in one run. The grouping is presentation like the cells themselves: the rule takes room and nothing else, and the field stays one tab stop with one value. |
enabled | in bool | true | When false, the field dims and stops taking focus and keystrokes. |
invalid | in bool | false | When true, paints the cells in destructive state. |
auto-focus | in bool | false | When true, the field grabs focus on mount. |
value | out string | no default | The combined code — the characters of every filled cell, in order. |
has-focus | out bool | no default | Whether the field currently holds keyboard focus. |
Callbacks
| Callback | Description |
|---|---|
edited(string) | Fired with the combined code whenever it changes. |
completed(string) | Fired with the combined code the moment the last cell is filled. |
accepted(string) | Fired with the combined code when the user presses Enter. |
Functions
| Function | Description |
|---|---|
clear() | Empties every cell — the way to reset the field from the outside, since value is derived and can't be assigned. |
insert(character: string) | One character through the same path a keystroke takes: validated by mode, written to the frontier cell, firing completed when it fills the last one; anything else is ignored. This is the paste seam — Slint has no clipboard access and cannot split a string, so the host reads the clipboard and feeds the code one character at a time. |
Enums
| Enum | Values |
|---|---|
InputOTPMode | numeric, alphanumeric |
Accessibility
- Unified text entry. Assistive technology sees one
text-inputnode withaccessible-valuecontaining the concatenated string, rather than multiple disconnected boxes. invalidannounces the word “Invalid”. Slint 1.17 publishes noaccessible-invalid, so the state rides the description channel ADR-0013 opened. In the current implementation,accessible-descriptionbecomes only"Invalid"; it is not appended to another description. A red border is not the announcement — this is.- Navigation. The entire group acts as a single tab stop.