Inputs
OtpInput
A one-time code entered as a row of single character boxes bound to one string. Focus advances as you type, the keyboard edits the code like a single field, and a pasted or SMS-filled code is cleaned up and spread over the boxes. It filters, folds and normalizes what it accepts, reports what it rejects, and carries the busy and error states of the round trip that follows.
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
Label & description
label bound to the first box and names the group of boxes.
Required adds the asterisk and marks every box required.
Type & keyboard
۱۲۳۴۵۶ or ١٢٣٤٥٦.Mask & placeholder
Pattern & casing
Separator
123-456). SeparatorTemplate takes markup, with the index of the
next box as its context. Separators are decoration only: never focused, announced or part of the value.
Variant
Layout
Merged
Autofill, paste & copy
autocomplete="one-time-code", the WebOTP API or a paste - is
cleaned up before it lands: whitespace, invisible characters and whatever Type or
Pattern rejects are dropped. A full-length code starts at the first box wherever it was pasted.
123 456, 12-34-56 or your code is 123456:your code is A1B2C3, do not share it:Binding
null or an empty string clears the boxes.
Events
Public API
Validation & auto submit
EditForm and data annotations like any Blazor input, marking the boxes
aria-invalid on a failing validation. AutoSubmit submits the enclosing form the
moment the code is complete, validation included. Name posts the whole code as one field.
Loading & invalid
aria-busy while the server checks it. Invalid paints the error state a
validator cannot see - an expired or wrong code. While either is on, the Description is
announced through a live region.
Accessibility
group named by Label (or AriaLabel) and described by
Description; each box is announced by position, 1 of 6. InputAriaLabelFormat
localizes it - {0} is the position, {1} the Length.
SingleTabStop makes the whole code one tab stop.
Cascading parameters
Accent
Size
Style & Class
:root or an ancestor restyles every otp input below it, and one on Style restyles
a single instance. The filled pair paints the boxes that hold a character.
RTL
CSS variables
The public custom properties this component reads off its root, for what no parameter covers.
Every variable is read with a fallback and never declared by the component, so it inherits like any other custom property:
set one on :root (or in a [bit-theme] block) to restyle every instance, on any ancestor to restyle the ones inside it,
or on the Style of one instance to restyle that one alone. Leave a variable unset and the component falls back to the theme token beside it.
BitOtpInput CSS variables
| Name | Default value | Description |
|---|---|---|
| --bit-OtpInput-gap | 0.625rem | Room between the inputs. Merged closes it to 0 whatever this holds. |
| --bit-OtpInput-input-size | --bit-siz-ctrl-sm / --bit-siz-ctrl-md / --bit-siz-ctrl-lg, per Size | Width and height of every input, which is a square of the control height of its size class. FullWidth overrides the width alone. |
| --bit-OtpInput-input-width | --bit-OtpInput-input-size | Width of an input on its own, for a box wider than it is tall. |
| --bit-OtpInput-input-height | --bit-OtpInput-input-size | Height of an input on its own. |
| --bit-OtpInput-font-family | --bit-tpg-font-family | Typeface of the whole component, which is where a tabular or monospaced face for the code is set - the one piece of text in a form that is read character by character. |
| --bit-OtpInput-font-size | --bit-tpg-fs-xs / --bit-tpg-fs-sm / --bit-tpg-fs-md, per Size | Size of the code, inherited by the label and the placeholder. |
| --bit-OtpInput-label-font-size | --bit-OtpInput-font-size | Size of the label above the inputs, which follows the size of the code unless it is set on its own. |
| --bit-OtpInput-label-font-weight | --bit-tpg-field-label-font-weight | Weight of the label above the inputs. |
| --bit-OtpInput-description-font-size | --bit-tpg-fs-2xs / --bit-tpg-fs-xs / --bit-tpg-fs-sm, per Size | Size of the helper text under the inputs, one step of the type ramp below the code. |
| --bit-OtpInput-font-weight | --bit-tpg-fw-regular | Weight of the character inside an input. |
| --bit-OtpInput-radius | --bit-shp-radius-control | Corner radius of an input, and of the two ends of every group while Merged is on. The Text variant squares them off whatever this holds. |
| --bit-OtpInput-border-width | --bit-shp-border-width | Thickness of an input's rule, and with it the overlap that glues two Merged inputs together. |
| --bit-OtpInput-color | --bit-clr-fg-pri | Color of the typed character. |
| --bit-OtpInput-background | Per Variant: --bit-clr-bg-pri (Outline), --bit-clr-bg-sec (Fill), transparent (Text) | Input background at rest, and the fallback of the hover and filled backgrounds below. |
| --bit-OtpInput-hover-background | Per Variant: the rest background (Outline, Text), --bit-clr-bg-sec-hover (Fill) | Input background while hovered, on an input that is neither disabled nor read-only. |
| --bit-OtpInput-border-color | Per Variant: --bit-clr-brd-pri (Outline, Text), transparent (Fill) | Input rule at rest, and the fallback of the hover and filled rules below. |
| --bit-OtpInput-hover-border-color | Per Variant: --bit-clr-brd-pri-hover (Outline, Text), the rest rule (Fill) | Input rule while hovered. |
| --bit-OtpInput-filled-background | --bit-OtpInput-background | Background of an input that already holds a character, which is what turns the row into its own progress indicator. It has no parameter behind it. |
| --bit-OtpInput-filled-border-color | --bit-OtpInput-border-color | Rule of an input that already holds a character. |
| --bit-OtpInput-focus-border-color | The Accent role's main color | Input rule while focused. |
| --bit-OtpInput-focus-color | The Accent role's focus color | Color of the keyboard focus ring. |
| --bit-OtpInput-placeholder-color | --bit-clr-fg-ter | Hint character of an empty input. |
| --bit-OtpInput-label-color | --bit-clr-fg-pri | Label above the inputs. |
| --bit-OtpInput-description-color | --bit-clr-fg-sec | Helper text under the inputs, outside the error state. |
| --bit-OtpInput-separator-color | --bit-clr-fg-sec | Text drawn between the groups of the code. |
| --bit-OtpInput-invalid-color | --bit-clr-err | Input rule, helper text and loading bar while Invalid is on or a validation is failing. |
| --bit-OtpInput-invalid-focus-color | --bit-clr-err-focus | Focus ring color in the error state. |
| --bit-OtpInput-disabled-color | --bit-clr-fg-dis | Character, placeholder, label, helper text, separator and loading bar when Disabled is true. |
| --bit-OtpInput-disabled-background | --bit-clr-bg-dis | Input background when Disabled is true. |
| --bit-OtpInput-disabled-border-color | --bit-clr-brd-dis | Input rule when Disabled is true. |
| --bit-OtpInput-loader-color | The Accent role's main color | The sweep of the bar drawn while IsLoading is on. The error and disabled states paint it with their own color instead. |
| --bit-OtpInput-loader-background | --bit-clr-bg-sec | The track the sweep of the loading bar travels along. |
| --bit-OtpInput-loader-height | --bit-siz-track-sm | Thickness of the loading bar. |
API
Every parameter, public member, sub-class and enum this component exposes.
BitOtpInput parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| Accent | BitColor? | null | The color of the focused input's border and focus ring, and of the loading bar. The error state wins over it. |
| AutoFocus | bool | false | Focuses the first empty input on the first render that finds the component enabled. |
| AutoShift | bool | false | Shifts the rest of the code one input back when a character is cleared with Backspace or Delete, instead of leaving a hole. |
| AutoSubmit | bool | false | Submits the enclosing form (a plain form or an EditForm) right after OnFill, the way pressing Enter would: the form still validates first. Nothing happens outside of a form. |
| BlurOnFill | bool | false | Removes the focus from the inputs once the code is complete, which dismisses a phone's virtual keyboard. |
| Classes | BitOtpInputClassStyles? | null | Custom CSS classes for different parts of the BitOtpInput. |
| Description | string? | null | Helper text under the inputs, referenced by the group's aria-describedby. While Invalid or IsLoading is on it is also announced through a live region. |
| DescriptionTemplate | RenderFragment? | null | Custom template for the helper text, taking precedence over Description. It is described the same way but never copied into the live region. |
| FullWidth | bool | false | Stretches the row across its container and shares the width evenly between the inputs. The height stays the one of the Size. |
| InputAriaLabelFormat | string? | null | Composite format of each input's aria-label: {0} is the one based position and {1} the Length. Defaults to "{0} of {1}". |
| InputMode | BitInputMode? | null | The inputmode attribute of the inputs, which picks the virtual keyboard without changing the accepted characters. Defaults to the one the Type implies. |
| Invalid | bool | false | Paints the error state and sets aria-invalid without an EditContext, e.g. for a code the server rejected. A failing validation shows the same state on its own. |
| IsLoading | bool | false | The busy state of a submitted code: draws a progress bar, marks the group aria-busy, announces the Description and holds the code still like ReadOnly. Clear is not blocked by it. |
| Label | string? | null | Label displayed above the inputs, bound to the first input and naming the group of inputs. |
| LabelTemplate | RenderFragment? | null | Custom template for the label displayed above the inputs, taking precedence over Label. |
| Length | int | 5 | The number of inputs, which is the length of the code. Values below 1 are treated as 1. |
| Lowercase | bool | false | Converts every character to lower case before the Pattern is applied. Uppercase wins when both are set. |
| Mask | string? | null | Text shown in place of every filled input's character. The value stays the typed code, and a masked code is kept off the clipboard. |
| Merged | bool | false | Glues the inputs of each group (the ones the Separator makes) into a single field with rounding only at its ends. |
| NormalizeDigits | bool | false | Converts the digits of other numbering systems (Persian, Arabic-Indic, full width, ...) to ASCII before the Type and the Pattern are applied. |
| NoSmsAutoFill | bool | false | Turns off the WebOTP SMS auto fill, the one-time-code autocomplete and the password managers' autofill. |
| OnFill | EventCallback<string?> | Callback for when all of the inputs are filled, raised once per completed code. | |
| OnFocusIn | EventCallback<(FocusEventArgs Event, int Index)> | onfocusin event callback for each input, with the index of the input. | |
| OnFocusOut | EventCallback<(FocusEventArgs Event, int Index)> | onfocusout event callback for each input, with the index of the input. | |
| OnInput | EventCallback<(ChangeEventArgs Event, int Index)> | oninput event callback for each input, with the index of the input. | |
| OnInvalid | EventCallback<(string Value, int Index)> | Callback for when a keystroke, paste or auto fill is rejected in full by the Type, the Pattern or the PasteTransformer, with the rejected text and the index of the input. A paste that only loses some characters does not raise it. | |
| OnKeyDown | EventCallback<(KeyboardEventArgs Event, int Index)> | onkeydown event callback for each input, with the index of the input. | |
| OnPaste | EventCallback<(ClipboardEventArgs Event, int Index)> | onpaste event callback for each input, with the index of the input. | |
| PasteTransformer | Func<string, string>? | null | Applied to a pasted or auto filled chunk before it is filtered, e.g. to pull the code out of the message around it. An empty result rejects the chunk; an exception leaves it untouched. Not applied to a single typed character. |
| Pattern | string? | null | A regular expression every single character has to match. Non-matching characters are rejected when typed and dropped when pasted; an invalid expression is ignored. |
| Placeholder | string? | null | Hint text of the empty inputs. A string exactly Length long is spread one character per input; any other is shown in every input. |
| Reversed | bool | false | Renders the inputs in the opposite order. The arrow keys follow. |
| Separator | string? | null | Text rendered between the groups of inputs. It is hidden from assistive technologies and never part of the value. |
| SeparatorInterval | int | 1 | The number of inputs in each group the Separator is rendered between, e.g. 3 for 123-456. Values below 1 are treated as 1. |
| SeparatorTemplate | RenderFragment<int>? | null | Custom template rendered in place of the Separator text, with the zero based index of the next input as its context. |
| Sequential | bool | false | Keeps the code free of holes: focusing, or pasting into, an input past the first empty one lands on that first empty input instead. A complete code is left editable anywhere. |
| SingleTabStop | bool | false | Makes the whole component a single tab stop: only the first input is reachable with Tab. |
| Size | BitSize? | null | The size of the inputs. |
| Styles | BitOtpInputClassStyles? | null | Custom CSS styles for different parts of the BitOtpInput. |
| Type | BitInputType? | null | Type of the inputs, deciding the accepted characters and the virtual keyboard. Number accepts digits only; Number, Email and Url render as text inputs. |
| Uppercase | bool | false | Converts every character to upper case before the Pattern is applied. |
| Variant | BitVariant? | null | The visual variant of the inputs: Outline (default), Fill or Text (underline only). |
| Vertical | bool | false | Renders the inputs vertically. The arrow keys follow. |
BitOtpInput public members
| Name | Type | Default value | Description |
|---|---|---|---|
| InputElements | ElementReference[] | The ElementReferences to the input elements of the BitOtpInput. The inherited InputElement is the first of them. | |
| BlurAsync | () => ValueTask | Removes the focus from the input that holds it, dismissing a phone's virtual keyboard. Does nothing when the focus is elsewhere on the page. | |
| Clear | () => Task | Clears all of the inputs and the value. Does nothing while the component is disabled or read-only. | |
| FocusAsync | (int index = 0) => ValueTask | Focuses the input at the given index, clamped into range. The inherited FocusAsync() and FocusAsync(bool preventScroll) focus the first input. Does nothing before the first render. |
BitInputBase parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| DefaultValue | TValue? | null | The default value of the input to be used in uncontrolled mode (i.e. when the Value is not bound), typically used alongside the OnChange callback. |
| DisplayName | string? | null | Gets or sets the display name for this field. |
| InputHtmlAttributes | IReadOnlyDictionary<string, object>? | null | Gets or sets a collection of additional attributes that will be applied to the created element. |
| Name | string? | null | Gets or sets the name of the element. Allows access by name from the associated form. |
| NoValidate | bool | false | Disables the validation of the input. |
| OnChange | EventCallback<TValue?> | Callback for when the input value changes. | |
| ReadOnly | bool | false | Makes the input read-only. |
| Required | bool | false | Makes the input required. |
| Value | TValue? | null | Gets or sets the value of the input. This should be used with two-way binding. |
BitInputBase public members
| Name | Type | Default value | Description |
|---|---|---|---|
| InputElement | ElementReference | The ElementReference of the input element. | |
| FocusAsync() | () => ValueTask | Gives focus to the input element. | |
| FocusAsync(bool preventScroll) | (bool preventScroll) => ValueTask | Gives focus to the input element. |
BitComponentBase parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AriaLabel | string? | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | string? | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | BitDir? | null | Gets or sets the text directionality for the component's content. |
| Disabled | bool | false | Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction. |
| ForceAnimation | bool | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | Dictionary<string, object> | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. |
| Id | string? | null | Gets or sets the unique identifier for the component's root element. |
| Style | string? | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | string? | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | BitVisibility | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
BitComponentBase public members
| Name | Type | Default value | Description |
|---|---|---|---|
| UniqueId | Guid | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | ElementReference | Gets the reference to the root HTML element associated with this component. |
BitOtpInputClassStyles properties
| Name | Type | Default value | Description |
|---|---|---|---|
| Root | string? | null | Custom CSS classes/styles for the root element of the otp input. |
| Label | string? | null | Custom CSS classes/styles for the label of the otp input. |
| Description | string? | null | Custom CSS classes/styles for the description (helper text) of the otp input. |
| InputsWrapper | string? | null | Custom CSS classes/styles for the wrapper element of the inputs. |
| Input | string? | null | Custom CSS classes/styles for each input in otp input. |
| Focused | string? | null | Custom CSS classes/styles for the focused input in otp input. |
| Filled | string? | null | Custom CSS classes/styles for each input that already holds a character in otp input. |
| Separator | string? | null | Custom CSS classes/styles for the separator rendered between the inputs of the otp input. |
| Loader | string? | null | Custom CSS classes/styles for the progress bar rendered under the inputs while the otp input is in the loading state. |
BitSize enum
| Name | Value | Description |
|---|---|---|
| Small | 0 | The small size. |
| Medium | 1 | The medium size. |
| Large | 2 | The large size. |
BitInputType enum
| Name | Value | Description |
|---|---|---|
| Text | 0 | The input expects text characters. |
| Password | 1 | The input expects password characters. |
| Number | 2 | The input expects number characters. |
| 3 | The input expects email characters. | |
| Tel | 4 | The input expects tel characters. |
| Url | 5 | The input expects url characters. |
BitInputMode enum
| Name | Value | Description |
|---|---|---|
| None | 0 | No virtual keyboard. For when the page implements its own keyboard input control. |
| Text | 1 | Standard input keyboard for the user's current locale. |
| Decimal | 2 | Fractional numeric input keyboard containing the digits and decimal separator for the user's locale. |
| Numeric | 3 | Numeric input keyboard, but only requires the digits 0–9. |
| Tel | 4 | A telephone keypad input, including the digits 0–9, the asterisk (*), and the pound (#) key. |
| Search | 5 | A virtual keyboard optimized for search input. |
| 6 | A virtual keyboard optimized for entering email addresses. | |
| Url | 7 | A keypad optimized for entering URLs. |
BitVariant enum
| Name | Value | Description |
|---|---|---|
| Fill | 0 | Fill styled variant. |
| Outline | 1 | Outline styled variant. |
| Text | 2 | Text styled variant. |
BitColor enum
| Name | Value | Description |
|---|---|---|
| Primary | 0 | Primary general color. |
| Secondary | 1 | Secondary general color. |
| Tertiary | 2 | Tertiary general color. |
| Info | 3 | Info general color. |
| Success | 4 | Success general color. |
| Warning | 5 | Warning general color. |
| SevereWarning | 6 | SevereWarning general color. |
| Error | 7 | Error general color. |
| PrimaryBackground | 8 | Primary background color. |
| SecondaryBackground | 9 | Secondary background color. |
| TertiaryBackground | 10 | Tertiary background color. |
| PrimaryForeground | 11 | Primary foreground color. |
| SecondaryForeground | 12 | Secondary foreground color. |
| TertiaryForeground | 13 | Tertiary foreground color. |
| PrimaryBorder | 14 | Primary border color. |
| SecondaryBorder | 15 | Secondary border color. |
| TertiaryBorder | 16 | Tertiary border color. |
BitVisibility enum
| Name | Value | Description |
|---|---|---|
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
BitDir enum
| Name | Value | Description |
|---|---|---|
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.