One-time code field

A fixed-length verification code shown as character slots, backed by one native input and one form value.

<tp-one-time-code-field>
One-time code field
Default density Compact density Restart from the initial state Show the copyable source

Verify your login

Enter the code we sent to maya@northwind.io.

Resend Verify

Usage

The slots are presentation over a single text editor, so typing, deletion, selection, paste and SMS autofill (autocomplete="one-time-code" by default) behave like one input. Screen readers hear one field with one name, and the form receives one value. Wrap it in a Field for the label.

Character types

validation-type filters what can be entered: numeric, alphabetic or the default alphanumeric. Numeric codes also bring up the number keypad on touch devices.

onValueInvalid(detail) and tp-invalid-input report { attemptedValue, reason: 'input' | 'paste', sourceEvent } when normalization removes or changes attempted input. The normalizer removes whitespace, filters, applies normalizeValue, filters again, and truncates by Unicode code point.

Numeric
Default density Compact density Restart from the initial state Show the copyable source

Groups

group-lengths splits the slots into visual groups with a separator between them. The separator never enters the value or the accessibility tree.

Grouped
Default density Compact density Restart from the initial state Show the copyable source

Masking

mask hides the entered characters on screen while the value stays intact. Use it for PINs entered where others can see.

Masked PIN
Default density Compact density Restart from the initial state Show the copyable source

Completion

tp-complete fires once the last slot is filled, which is the moment to verify. Add auto-submit to submit the owning form instead of waiting for a button press.

Programmatic assignments and native resets do not simulate user completion. Completion precedes optional auto-submit.

Verify on completion
Default density Compact density Restart from the initial state Show the copyable source
Waiting for 6 digits

Controlled

Set value to own the code, and accept each edit from tp-value-change by assigning event.detail.value. Your application can then clear or prefill the field directly, for example after requesting a new code.

A controlled owner must publish the accepted value synchronously. Rejection restores the editor, visible slots, selection and caret; it cannot complete or submit. Keep controlled versus uncontrolled ownership stable for the element’s lifetime.

Controlled value
Default density Compact density Restart from the initial state Show the copyable source
Send a new code 0 of 6 digits

States

Disabled and invalid
Default density Compact density Restart from the initial state Show the copyable source

Disabled codes are left out of form data. An invalid Field paints every slot and announces its error once for the whole code.

API Reference

Every element also accepts motion-policy.

Attributes

AttributePropertyTypeDefaultDescriptionlengthlengthnumber | undefined—The number of characters in the code, and so the number of slots.inputmodeinputModestring—The on-screen keyboard to show; a numeric code brings up the number pad by default.default-valuedefaultValuestring | undefined—The code at first render and after a form reset, when the page does not own value.validation-typevalidationTypeCodeValidation'alphanumeric'Which characters the code accepts: digits, letters, both, or whatever characterPredicate allows. Others are filtered out as they are typed or pasted.group-lengthsgroupLengthsreadonly number[][]Splits the slots into visual groups with a separator between them, as a JSON array of group sizes that add up to length; the separator never enters the value.maskmaskbooleanfalseHides the entered characters on screen, for a PIN entered where others can see; the value stays intact.autocompleteautocompletestring'one-time-code'The autofill hint of the native input; the default lets phones offer a code from a text message.no-autofillnoAutofillbooleanfalseOpts the code editor out of host and extension autofill.auto-submitautoSubmitbooleanfalseSubmits the owning form as soon as the last slot is filled.labellabelstring'One-time code'The accessible name of the code when no Field or Label names it.placeholderplaceholderstring''A character shown in each empty slot.

Properties

PropertyTypeDefaultDescriptioncharacterPredicate((character: string) => boolean) | undefined—Decides whether one character is accepted when validationType is predicate.normalizeValue((value: string) => string) | undefined—Rewrites typed or pasted text before filtering, for example to uppercase or to strip dashes.effectiveNoAutofillread-onlyboolean—Whether autofill is off, by the field itself or by the Field or Form around it.onValueChange((event: TpValueChangeEvent<string>) => void) | undefined—Called with each proposed code before it commits; assign value to accept it or cancel the event to reject it.onValueComplete((detail: CodeCompleteDetail) => void) | undefined—Called with the complete code when the last slot is filled.onValueInvalid((detail: CodeInvalidDetail) => void) | undefined—Called when typed or pasted text contained characters the code does not accept.completeread-onlyboolean—Whether every slot is filled.

Events

EventTypeDescriptiontp-value-changeTpValueChangeEvent<string>Cancelable proposal of a new code before it commits; detail.value, detail.previousValue and the detail.reason for the change.tp-field-valueCustomEvent<{ value: string; previousValue: string; reason: ChangeReason; }>After the code commits, with the same value, previousValue and reason; the enclosing Field listens for it.tp-invalid-inputCustomEvent<CodeInvalidDetail>When typed or pasted text contained characters the code does not accept; detail.attemptedValue is the text before filtering and detail.reason says how it arrived.tp-completeCustomEvent<{ value: string; sourceEvent: Event; }>When the last slot is filled; detail.value is the complete code.

CSS parts

PartDescription::part(one-time-code-field)The root that holds the character slots over the native input.::part(one-time-code-field-group)One group of character slots.::part(one-time-code-field-separator)The mark between two groups of slots; never part of the value.::part(one-time-code-field-slot)One character position; shows the active and filled states.

Components, widgets and patterns that use this one.