A row of cells a one-time confirmation code is typed into — sign-in, account access, confirming a sensitive action.
Overview
InputCode is the field a one-time confirmation code is typed into — to sign in, to reach an account, to confirm a sensitive action. The code is shown one character per cell; the cells fill from left to right, and when the last one is filled the code is checked.
-
1
Unmasked
-
2
Masked
States
Nine states. Standard, Active and Filled follow the focus and the value; the host sets the rest — Validation while it checks the code, then Error or Success, and Disabled, Read only or Skeleton. Disabled and Skeleton are the same for both presets.
Standard
-
1
Cell --surface-on-white — the fill, in every state but Read only. No border.
-
2
Character --text-and-icon-primary — Filled: the code typed, the field without the focus.
-
Figma Rest empty — Standard; Rest filled — Filled.
Active
-
1
Active cell --border-active — the border inside the next cell to fill: the first empty one, the last when all are filled. It is the field's focus — "the active field has no cursor indicator".--sp-100-s2 — its width, inside the cell.
-
2
Helper --text-and-icon-primary — the helper text, when the host turns the helper on.
-
Figma Active empty and Active filled.
Validation
-
1
Shimmer --skeleton-wave — the DS wave runs over each cell while the code is checked, "using the Skeleton WhiteOverlay style". No border; the field takes no input.
-
Figma The frame's state 6, "The validation state uses a shimmer animation" — not a variant of the set. Its colour list names --border-success for the border; the specimen shows none, and neither does the web.
Error
-
1
Border --border-error — every cell, and the row swings once.
-
2
Error text --text-and-icon-error — the warning-filled icon and the text. "Incorrect code. Please try again" by default; the host may set its own.
-
After the swing The code clears, the first cell turns active, and the error text stays until a character is typed.
Success
-
1
Border --border-success — every cell. Then the host moves on to the next view.
-
Figma The Success variant is named Error=on, Success=on — both on; the web reads it as Success.
Disabled
-
1
Character --text-and-icon-disabled — the characters or the dots. The fill stays; no border, no focus.
-
2
Helper --text-and-icon-disabled — the helper text.
-
Figma Disabled (filled) and Disabled (empty).
Read only
-
1
Cell --surface-white-overlay — the fill.
-
2
Border --border-default — every cell.--text-and-icon-primary — the characters stay.
Skeleton
-
1
Placeholder --surface-on-white — the cell, as Figma binds it.--skeleton-on-white — the same values, Day and Night.--skeleton-wave — the DS wave over it. No characters, no helper.
Anatomy
One text field drawn as a row of cells. The input holds the code and the focus; the cells only draw its value — one character per cell, left to right. The helper line under them is optional.
Parts
-
1
Input One native input stretched over the cells and drawn transparent — outlined here. It holds the code, takes the focus, opens the numeric keyboard and receives a paste or the code from an SMS. Required.
-
2
Cell var(--sp-100-s56) — the square each character sits in; four by default, any number.The next one to fill is the active cell while the field has the focus. Required.
-
3
Character Heading/Heading 2 — the character, centred in its cell. Unmasked.
-
4
Helper Body/Compact Body — a line under the cells that says what the field accepts; long text wraps.Optional — off by default.
-
Root Fills the host's width; the cells sit inside it at the alignment. The Figma public master's outer margins belong to its wrapper — on the web they are the host's.
Masked and the error form
-
1
Dot var(--sp-100-s20) — the dot icon in place of each character. Masked.
-
2
Error icon var(--sp-130-s16) — warning-filled, before the text, aligned to its first line.The error form only.
-
3
Error text Body/Compact Body — the helper's text replaced by the error: "Incorrect code. Please try again" by default, or the host's own.
Layout
A row of fixed cells with a line of text under it. Each value takes the SP family Figma binds — the cells, the gaps and the helper's spacing SP/100% ratio (fixed), so only the character and the helper text grow.
General
-
Cell var(--sp-100-s56) × var(--sp-100-s56) — the width is the most; it narrows when the row has no room (Width below).var(--sp-100-s20) — the corner radius.var(--sp-100-s2) — the border, inside the cell.
-
Between Cells var(--sp-100-s4) — the gap.
-
Helper var(--sp-100-s12) — under the cells.
-
Resizing Heading/Heading 2 — the character grows to 130% (cap130, SP/130% ratio).Body/Compact Body — the helper text grows to 150% (full, SP/150% ratio) and wraps.var(--sp-100-sN) — the cells, the dot and the gaps stay.
Helper
-
Error Icon var(--sp-130-s16) — warning-filled, capped at 130% (SP/130% ratio).var(--sp-100-s4) — between the icon and the text.
-
Long Text Shown in full — it wraps to the next line (bottom); the icon stays on the first line.
-
Default Off. Figma: "Helper is false by default". Error shows its text all the same — the line is mounted for it (top: after the swing, the cells cleared).
Width
-
Narrow Host var(--sp-100-s56) — the most a cell takes. When the cells and their gaps exceed the host, every cell narrows by the same amount; the height and the gaps stay.
-
8 Cells and More var(--sp-100-s12) — the corner radius from the eighth cell on (bottom). CSS counts the cells.
-
Length Four to eight cells, four by default — Figma stages them. The frame allows more and the platforms take any length; past eight the cells crowd the row (Usage).
Alignment
-
Start The default (top) — the cells and the helper at the start edge.
-
Center
.input-code--align-center(middle) — both centred; the helper text centred too. -
End
.input-code--align-end(bottom) — both at the end edge. -
Root Outlined — it fills the host; the cells align inside it. Figma has no Alignment property; the frame shows the three as a layout choice of the instance.
RTL
-
1
Code Left to right still — the first character in the leftmost cell: "The sequence of code entry remains LTR. Do not mirror it."
-
2
Next Cell The cells fill left to right, so the active cell moves right — the row itself sits at the right edge: Start is the right edge in RTL, End the left one.
-
3
Helper Aligned right; the error icon after the text, on its right.
-
Web
dir="rtl"on the root or an ancestor. Start is the right edge, End the left one. Figma:RTL=on.
Animation
The cells answer the code: a border shows the next cell, a shimmer runs while the code is checked, and a wrong code swings the row and clears it. Every movement is a token of the motion system, timed by the frame's "Validating process" block and the Figma prototypes.
Border
-
1
Active Cell var(--pattern-color) — the border moves to the next cell as a character lands, 200ms linear.On
box-shadow— the border inside the cell. -
2
Success var(--pattern-color) — the green border appears on every cell, 200ms linear: "A green border appears around the fields (200ms / 0.25, 0.25, 0.75, 0.75)".
-
Also on Color The red border of Error and its return to the empty cells; the tint of Disabled (
color).
Shimmer
-
1
Validation var(--pattern-shimmer) — the DS wave over each cell while the code is checked, 1500ms linear, endless; the characters stay.On
transform— an overlay sweeping across. -
2
Skeleton var(--pattern-shimmer) — the same wave over the placeholders; it runs right to left in RTL, the token played in reverse.
-
Figma The prototype staggers the wave in 400ms ease-out steps; the web runs the DS shimmer the frame names — "using the Skeleton WhiteOverlay style".
Wrong Code
-
1
Cells var(--pattern-shake) — a damped swing, once: right, left, right again, home — four eased legs, 300ms in all.var(--sp-100-s8) — the first two swings.var(--sp-100-s4) — the last.var(--pattern-color) — then the cells clear to empty, 200ms, and the first one turns active.On
transform. The token was added to the DS for this component — Motion 1.8.0. -
2
Error Text No motion — it appears with the error and stays until a character is typed, then the helper text comes back.
-
Figma The prototype swings six times — 25ms linear legs of 16, "The fields move left and right 6 times". It read as a jitter; the web plays the softer swing (owner) — the prototype is the owner's to update.
Live
-
Try It Type 2468 — the shimmer, then the green border; any other code swings the row and clears it. Paste a code, or tap a filled cell to clear it.
-
Entry One digit per cell, left to right; a digit typed with an earlier cell empty lands in the first empty one; Delete clears the one before the active cell, Delete over a full selection clears them all. Only digits are taken.
-
Host The check is the host's — the demo waits 1.2 s for the answer and, after Success, clears the field in 2 s where an app would move on.
-
Reduced Motion Every token above is zeroed at the token: the borders change at once, no shimmer, no swing — the error is the error text and its icon, announced once; the red border passes at once.
Usage
InputCode is the field of a screen or a sheet that asks for a code sent to the person — by SMS, e-mail or a call — or for a secret one they know. A heading over it says what the code is for, and the field opens the numeric keyboard.
-
1
On a Screen A heading says what the code is for, the helper line what the field accepts — "Numbers 0 to 9 allowed". The numeric keyboard opens with the field; an SMS code is offered above it.
-
2
While It Is Checked "When displayed on the screen, hide the keyboard during the validation of the entered code." The shimmer says the check is running.
-
3
In a Bottom Sheet "When placed in a BottomSheet, do not hide the keyboard, but block interactions with elements on the screen during the code validation process."
-
4
A Secret Code Masked — a dot for each digit, "recommended for sensitive data (e.g., card PIN, banking details)".
-
5
✕ A Phone Number or a Password An entry of free length is not a code: a phone number is PhoneField, a password PasswordField. A cell for every character crowds the row — from eight cells they narrow and lose their rounding.
Enter the confirmation code
The code helps make delivery safer
Enter the confirmation code
The code helps make delivery safer
Confirm the payment
We sent a code to your phone
Enter your card PIN
Four digits from your bank
Enter your phone number
We will send you a code
Accessibility
InputCode is one text field drawn as a row of cells. Assistive technology meets the field — named by what the code is for, described by the helper line, with the code as its value — and never the cells. Labels and voiced strings per platform: input-code-a11y.md.
-
1
One Field Named by what the code is for, described by the helper text — "Enter code, Numbers 0 to 9 allowed"; a text field; the code is its value.TalkBack: an edit box,
contentDescription"[Input Description]", the helper as its supporting text — read with the field, not a stop of its own.VoiceOver: the label "[Input Description], [Helper text]", the trait Text field, the hint "Is editing." — and "Slot 1 of 4", the position the next digit goes to. The visible helper line is hidden, its text already in the label.Web: one native<input>over the cells, named byaria-labelledbythe visible heading (aria-label"Enter code" only when there is none) and described by the helper througharia-describedby. It has no slots, so there is no "Slot 1 of 4" — the owner's choice of one field. -
2
Cells Hidden The cells, the characters, the dots and the error icon draw the field's value; they are not elements of their own.TalkBack:
clearAndSetSemantics {}on the drawing. VoiceOver:accessibilityHidden(true).Web:aria-hidden="true"on the cells row and the error icon. -
3
Active Cell Is the Focus --border-active — the border on the next cell to fill is the field's visible focus: 15.69:1 Day, 13.2:1 Night against the cell. The caret is hidden.var(--sp-100-s2) — its width.--border-active — an outline round the row where no cell is active (Validation, Success, Read only), drawn in CSS alone: the focus always shows.Tab reaches the field like any input; with every cell filled, the last one keeps the border.
-
4
Masked A secure field — the digits are not read out.VoiceOver: "Filled, [Helper text], Slot N of 4" and the system's secure-field hint. TalkBack: the count of characters only.Web:
type="password"withautocomplete="off"— screen readers read the count; Edge's reveal control is switched off. Password managers may still offer to save it —autocomplete="off"is a request, not a guarantee. -
5
Error Announced once when it appears — TalkBack reads the field's error, "Error: Incorrect code. Please try again"; VoiceOver needs an announcement posted with the text, since a label that changes on a focused field is not spoken.Web:
aria-invalid="true"on the input, and the error text written into arole="status"element that stays mounted — once; the helper line shows it as the field's description. Error always shows its text, Helper on or off. Both clear when a digit is typed.--text-and-icon-error on --background-primary — the error text: 3.98:1 Day, under the 4.5:1 small-text floor (the DS's status colour, TextField's finding too); 4.91:1 Night — flagged. The icon and the words carry it, not the red alone, and not the shake. -
6
Validation and Success The field takes no input while the code is checked or once it is accepted, and keeps the focus — a Bottom Sheet keeps its keyboard. If the host hides the keyboard on a screen, it gives the focus back to the field after an Error, never to the page.TalkBack and VoiceOver: "Checking the code", then "Code accepted", as polite announcements — unless the host moves on to the next view at once. VoiceOver reads the busy field as "Editing disabled".Web:
readonly, witharia-busy="true"during Validation; the two messages go through the samerole="status"element. Read only isreadonlytoo, with no message. -
7
Disabled The input is
disabled— out of the tab order, not editable. TalkBack "Disabled", VoiceOver "Dimmed"; both still reach it with swipe navigation. -
8
Skeleton Not a field yet — the field is
aria-hidden="true"and its inputdisabled; the screen's own region announces the loading once, the Skeleton contract. -
Numbers Only
inputmode="numeric"opens the numeric keyboard — "Use only a numeric keyboard";pattern="[0-9]*",maxlengththe number of cells, and anything that is not a digit is dropped. Unmasked takesautocomplete="one-time-code"— the platform offers the code from the SMS above the keyboard. Paste comes from the native long-press or context menu; typing or Delete over a full selection replaces or clears the whole code. -
Touch Target var(--sp-100-s56) — the field is one target, the cells' height: above the 44 / 48 minimums. A tap on a filled cell clears it — a real pointer only; a screen reader's activation lands on the field's centre and leaves the digits alone.
-
Contrast --text-and-icon-primary on --surface-on-white — the character: 15.69:1 Day, 13.2:1 Night.--border-error — 3.52:1 Day, 3.8:1 Night, a graphic on the 3:1 floor.--border-success — 2.45:1 Day, under the 3:1 floor; Success hands over to the next view, so the border is not the only outcome — flagged.--surface-on-white on --background-primary — the empty cell: 1.13:1 Day, 1.29:1 Night, no border — TextField's finding too, flagged.
-
RTL and Text Scaling RTL: the field reads in the language's order; the code stays left to right.The character grows to 130%, the helper text to 150% and wraps — Dynamic Type the same.
-
Forced Colours The borders are
box-shadow, which forced colours remove: each cell draws aCanvasTextoutline instead, the active cell and the focus outline aHighlightone. The error form keeps its icon and its words. -
Reduced Motion The border change, the shimmer and the shake are zeroed at the token — the error is the error text and its icon, announced once. The stilled shimmer sits behind the digits.