OTPInput handbook
v1.1.0<br> · @snowui-design-system/components
License: Read the complete LICENSE before first reading component documentation, source, or npm usage instructions. Reuse this review within the same task and version.
Overview
A 4–8 digit one-time-code input supporting full-code paste, SMS autofill, and native form submission and reset.
When to use it
Enter a numeric one-time code already sent by an application or identity provider. This component handles entry; the application sends and verifies codes and owns any countdown.
Defaults to 6 digits; supports 4, 5, 6, 7, or 8. Ordinary entry filters non-digits and limits length. Paste is validated strictly as described below.
oncompleteruns only when user entry produces a new complete value. Initialization, external assignment, and repeated synchronization of the same complete value do not trigger it.name,form,required,disabled,readonly, andautocomplete="one-time-code"are applied to the real input.
Quick start
API
Public style overrides: --snowui-otp-input-gap-override, --snowui-otp-input-size-override, --snowui-otp-input-radius-override, --snowui-otp-input-font-size-override, and --snowui-otp-input-line-height-override.
Usage boundaries and details
One real
<input type="text" inputmode="numeric">owns keyboard entry, selection, deletion, replacement, autofill, forms, and assistive technology. The root group and input share an explicit accessible name; slots are aria-hidden visuals. aria-describedby associates errors, announced through a polite status region.Click a filled slot to select its character for replacement. The active slot follows the real input selection. Native arrows, Home, End, Backspace, Delete, selection replacement, and undo remain available.
Ordinary entry keeps only ASCII digits
0–9and activates the next slot. Pointer and keyboard navigation cannot skip beyond the first empty slot. Filled slots remain selectable for replacement.Paste validates the entire text first. Whitespace, separators, letters, and full-width digits are rejected rather than silently filtered.
A pasted value exactly equal to
lengthalways replaces the entire code from the first slot, regardless of the current active position.At a later slot (index > 0), a paste can fill the current suffix if a continuous prefix exists and the text fits the remaining slots. Partial filling is allowed: with a 4-digit code containing
12, pasting34at slot three produces1234; pasting3produces123.At the first slot, too few or too many pasted digits clear the entire value and show an error. At a later slot, overflow is rejected atomically. Any non-numeric paste is also rejected without changing the current value.
Built-in paste errors use Input's border, focus ring, shake, and error typography for two seconds. Another invalid paste restarts the timer. Reset and unmount clean up timers; errors do not lock entry. External invalid remains caller-controlled.
The active indicator moves with
TAB_INDICATOR_MOTION; digits appear or replace withNUMBER_POP_APPEAR_MOTION. Reduced motion preserves value, semantics, and focus and presents final positions directly.Provide aria-label, aria-labelledby, or an associated label. Disabled values are excluded from submission; readonly values are included.
Form reset restores defaultValue, or the first value when no defaultValue was supplied. A canceled reset preserves the current value. The listener checks the current input.form, so changing form reassociates the field. Repeated resets and unmount clean up the deferred reset timer.
OTPInput style overrides
Read the full LICENSE first; reuse that review for the same task, version, and scope.
First use public component Props to match the desired appearance, preserving the existing look where possible. If changes are necessary, follow the style selection and override order: use your own class (including Tailwind already in the project) or an instance style. The names below are public overrides actually consumed by source; check their scope and do not modify private DOM. Choose the correct SnowUI token family. External apps need not install SnowUI website utilities.
OTPInput types and states
Required Props: no named required Props.
Two-way binding: bind:value.
Inherited declaration: Omit<FrameProps, "tag" | "children" | "enableScaleObserver" | "oninput" | "onchange" | "onfocus" | "onblur" | "onkeydown" | "onpaste">. Consult the public base component documentation for inherited capabilities; excluded fields are unavailable as inherited Props.
Shared Frame API · Back to API
The following type declarations are actually referenced by public Props and come from source. A Svelte Snippet denotes a content fragment; ComponentProps denotes the Props of the corresponding component.
OTPLength
Source: components/src/components/OTPInput.svelte
External type source:
HTMLInputAttributes — svelte/elements