RizzyUI

Input OTP

RzInputOTP is a focused input component for entering one-time passwords (OTP) and verification codes in a clean, user-friendly format. It presents the code as a series of individual character slots, making it easier for users to read, type, and confirm each digit or letter during sign-in, account recovery, or multi-factor authentication flows. The component is designed to improve usability with clear visual states, predictable keyboard input behavior, and a layout that supports fast entry while keeping the overall experience consistent with the rest of your UI system.

Basic Usage

Use six contiguous slots for common SMS verification codes.

Event Viewer
Source
<RzInputOTP Length="6" Name="VerificationCode">
    <InputOTPGroup>
        <InputOTPSlot Index="0" />
        <InputOTPSlot Index="1" />
        <InputOTPSlot Index="2" />
        <InputOTPSlot Index="3" />
        <InputOTPSlot Index="4" />
        <InputOTPSlot Index="5" />
    </InputOTPGroup>
</RzInputOTP>

Grouped 3-3 Layout

Insert InputOTPSeparator to create a grouped pattern like 123-456.

Event Viewer
Source
<RzInputOTP Length="6" Name="VerificationCode">
    <InputOTPGroup>
        <InputOTPSlot Index="0" />
        <InputOTPSlot Index="1" />
        <InputOTPSlot Index="2" />
    </InputOTPGroup>
    <InputOTPSeparator />
    <InputOTPGroup>
        <InputOTPSlot Index="3" />
        <InputOTPSlot Index="4" />
        <InputOTPSlot Index="5" />
    </InputOTPGroup>
</RzInputOTP>

Invalid and Disabled States

Use Invalid to force error styling, and Disabled to lock interaction while still rendering the current value.

Event Viewer
Source
<RzInputOTP Length="6" Name="InvalidVerificationCode" Invalid="true">
    <InputOTPGroup>
        <InputOTPSlot Index="0" />
        <InputOTPSlot Index="1" />
        <InputOTPSlot Index="2" />
        <InputOTPSlot Index="3" />
        <InputOTPSlot Index="4" />
        <InputOTPSlot Index="5" />
    </InputOTPGroup>
</RzInputOTP>

<RzInputOTP Length="6" Name="DisabledVerificationCode" Disabled="true" Value="123456">
    <InputOTPGroup>
        <InputOTPSlot Index="0" />
        <InputOTPSlot Index="1" />
        <InputOTPSlot Index="2" />
        <InputOTPSlot Index="3" />
        <InputOTPSlot Index="4" />
        <InputOTPSlot Index="5" />
    </InputOTPGroup>
</RzInputOTP>

Alphanumeric Mode

Set OtpType to Alphanumeric and use InputMode="text" for recovery codes containing letters and digits.

Event Viewer
Source
<RzInputOTP Length="8"
            Name="RecoveryCode"
            OtpType=InputOtpType.Alphanumeric
            InputMode="text">
    <InputOTPGroup>
        <InputOTPSlot Index="0" />
        <InputOTPSlot Index="1" />
        <InputOTPSlot Index="2" />
        <InputOTPSlot Index="3" />
    </InputOTPGroup>
    <InputOTPSeparator />
    <InputOTPGroup>
        <InputOTPSlot Index="4" />
        <InputOTPSlot Index="5" />
        <InputOTPSlot Index="6" />
        <InputOTPSlot Index="7" />
    </InputOTPGroup>
</RzInputOTP>

RzInputOTP Parameters

PropertyDescriptionTypeDefault
LengthTotal OTP character length.intRequired
NameNative input name submitted with forms.string?null
ValueInitial server-rendered value.string?null
OtpTypeInput filtering mode: Numeric or Alphanumeric.InputOtpTypeNumeric
InputModeOverrides the native inputmode attribute (for example numeric or text).string?null
TextTransformApplies text transformation to OTP input values: None, ToLower, or ToUpper.InputOtpTextTransformNone
AutocompleteNative autocomplete value used by the hidden input.stringone-time-code
DisabledDisables typing and slot interactions.boolfalse
RequiredMarks the native input as required.boolfalse
InvalidForces invalid visual state. If omitted, validation is inferred from For.bool?null
ForForm expression used for validation metadata.Expression<Func<string>>?null
AriaLabelAccessible name for the native input.string?Localized default
AriaDescribedByAssociates descriptive text with the native input.string?null

Nested Component Parameters

ComponentPropertyTypeDescription
InputOTPSlotIndexintZero-based position tied to the native input string.
InputOTPGroupChildContentRenderFragment?Container used to group contiguous slots.
InputOTPSeparatorChildContentRenderFragment?Optional custom separator content between groups.

Alpine API

The rzInputOTP Alpine state exposes value, length, activeIndex, isFocused, and slots[] (with char, isActive, isSelected, and hasFakeCaret for each slot). It handles click-to-focus, keyboard navigation (Arrow keys, Home, End), backspace behavior, and paste normalization. Double-clicking a slot selects all currently filled slots, then Backspace clears all slots and typing a valid character replaces selection with a fresh first-slot value. The API also exposes getValue() and setValue(newValue). It dispatches rz:inputotp:oninput for any value change and rz:inputotp:onchange when a value change results in all slots being filled. Slot focus is constrained so users can only focus already-filled slots or the next slot in sequence.