Ask AI about this page

OTP Input Component

Introduction

The otp component provides a secure and user-friendly way to handle One-Time Password (OTP) input. It features automatic focus progression, paste handling, validation with custom patterns, accessibility support, and seamless integration with both Livewire and Alpine.js. Perfect for authentication flows, verification codes, and any multi-digit input scenarios.

Installation

Use the fluxtor artisan command to install the otp component easily:

php artisan fluxtor:install otp

Basic Usage

<x-ui.otp 
    wire:model="verificationCode"
/>

Bind To Livewire

To use with Livewire you need to only use wire:model="code" to bind your OTP state:

<!--
    this asume you have $verificationCode in your class component
-->

<div class="max-w-md mx-auto">
    <x-ui.otp 
        wire:model="verificationCode"
    />
</div>

Using it within Blade & Alpine

You can use it outside Livewire with just Alpine (with Blade):

<div class="max-w-md mx-auto" x-data="{ code: null }">
    <x-ui.otp 
        x-model="code" 
    />
</div>

Because we're making this possible using (like) the x-modelable API, so you can't use state as a variable name because the component uses it internally.

Customization

Custom Length

Control the number of input fields with the length parameter.

<x-ui.otp 
    wire:model="code4"
    :length="4"
/>
<x-ui.otp 
    wire:model="code6"
    :length="6"
/>
<x-ui.otp 
    wire:model="code8"
    :length="8"
/>

Sloted Inputs

you can pass the individual inputs as a slot and you tweack it as you need

note we're using <x-ui.otp.input> not the native input

<x-ui.otp
    wire:model="code"
>
    <x-ui.otp.input class="rounded-full m-2" />
    <x-ui.otp.input class="rounded-full m-2"/>
    <x-ui.otp.input class="rounded-full m-2"/>
    <x-ui.otp.input class="rounded-full m-2"/>
    <x-ui.otp.input class="rounded-full m-2"/>
</x-ui.otp>    

Separator

<x-ui.otp
    wire:model="code"
>
    <x-ui.otp.input />
    <x-ui.otp.input/>
    
    <x-ui.otp.separator/>
    
    <x-ui.otp.input />
    <x-ui.otp.input />
    
    <x-ui.otp.separator/>
    
    <x-ui.otp.input />
    <x-ui.otp.input />
</x-ui.otp>    

Input Types and Validation

Control what characters are allowed with different input types and patterns.

<x-ui.otp 
    wire:model="numericCode"
    allowedPattern="[0-9]"
/>
<x-ui.otp 
    wire:model="alphanumericCode"
    allowedPattern="[A-Za-z0-9]"
/>
<x-ui.otp 
    wire:model="letterCode"
    allowedPattern="[A-Za-z]"
/>

AutoFocus

to focus the first relevent input in the initialization phase you may use the autofocus

<x-ui.otp 
    ...
    autofocus
/>

Advanced Features

Pre-filled Values

The component automatically handles external state synchronization and can display pre-filled values.

Current value:

<div x-data="{ code: '1234' }">
    <x-ui.otp x-model="code" />
</div>

Paste Handling

The component intelligently handles pasted content, filtering valid characters and auto-filling inputs.

The component will extract valid digits and fill the inputs automatically.

Real-time Validation

Monitor input changes in real-time with Alpine.js effects.

<div 
    x-data="{
        code: null,
        isValid: false,
    }"
    x-init="
         queueMicrotask(() => {
            Alpine.effect(() => {
                console.log('here')
                isValid = code && code.length === 4;
            });
        });
    "
>
    <label class="block text-sm font-medium mb-2">Enter 4-digit code</label>
    <x-ui.otp x-model="code" />
    <div class="mt-2">
        <span x-show="isValid" style="display: none;" class="text-green-600 text-sm">✓ Valid code entered</span>
        <span x-show="!isValid" style="display: none;" class="text-red-600 text-sm">Please enter a complete 4-digit code</span>
    </div>
</div>

Component Props

Prop Name Type Default Required Description
length integer 4 No Number of input fields to render
type string 'text' No HTML input type attribute
allowedPattern string '[0-9]' No Regex pattern for allowed characters
wire:model string - Yes* Livewire property to bind to
x-model string - Yes* Alpine.js property to bind to
class string 'contents' No Additional CSS classes for container

*Either wire:model or x-model is required

Technical Notes

  • Uses queueMicrotask() to prevent race conditions during DOM updates
  • Synchronizes external state changes automatically
  • Handles edge cases like partial pastes and invalid character filtering

© FLuxtor Copyright 2024-2025. All rights reserved.