Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Otp Input Laravel Package

hasan-ahani/filament-otp-input

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require hasan-ahani/filament-otp-input
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="HasanAhan\FilamentOtpInput\FilamentOtpInputServiceProvider"
    
  2. Register the Component Add the component to your Filament form:

    use HasanAhan\FilamentOtpInput\Components\OtpInput;
    
    OtpInput::make('otp_code')
        ->label('One-Time Passcode')
        ->required()
        ->live() // Optional: Validate in real-time
        ->rules(['required', 'digits:6']) // Custom validation rules
    
  3. First Use Case Use it in a Filament Form (e.g., login, password reset, or 2FA verification):

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                OtpInput::make('verification_code')
                    ->label('Enter OTP')
                    ->maxLength(6)
                    ->onChange(function (Form $form, string $value) {
                        // Trigger action (e.g., verify OTP)
                        $this->verifyOtp($value);
                    }),
            ]);
    }
    

Implementation Patterns

Core Workflows

  1. Basic OTP Input

    OtpInput::make('otp')
        ->numberOfInputs(6) // Default: 6
        ->autofocus()       // Auto-focus first input
        ->placeholder('0')  // Placeholder for each digit
    
  2. Dynamic Actions

    • On Change: Trigger logic when OTP changes (e.g., auto-submit or validation).
      ->onChange(function (Form $form, string $value) {
          if ($value->length === 6) {
              $form->submit();
          }
      })
      
    • On Submit: Handle form submission with OTP.
      public function submitOtp(Form $form)
      {
          $otp = $form->get('otp');
          // Verify OTP with your service (e.g., Laravel Notifications)
      }
      
  3. Integration with Filament Features

    • Live Validation: Use Filament’s built-in validation.
      ->rules(['required', 'digits:6', 'otp_verifiable']) // Custom rule
      
    • Conditional Logic: Show/hide based on user state.
      OtpInput::make('otp')
          ->visible(fn (Form $form) => $form->get('enable_otp'))
      
  4. Custom Styling Override Blade templates or use Filament’s CSS utilities:

    ->extraAttributes(['class' => 'bg-gray-50 border-gray-300'])
    

Advanced Patterns

  1. Resend OTP Logic Combine with a button to resend OTP:

    use Filament\Forms\Components\Actions\Action;
    
    Action::make('resend_otp')
        ->label('Resend OTP')
        ->action(function (Form $form) {
            $this->sendOtp($form->get('email'));
            $form->fill('otp', ''); // Clear input
        }),
    
  2. Multi-Step Forms Use in a Filament Multi-Step Form for progressive OTP verification:

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                // Step 1: Email input
                TextInput::make('email')->required(),
                // Step 2: OTP input (conditional)
                OtpInput::make('otp')
                    ->visibleOn('email')
                    ->afterStateUpdated(function (Form $form) {
                        $form->moveToStep(3); // Proceed to next step
                    }),
            ]);
    }
    
  3. Localization Translate labels/placeholders:

    ->label(__('auth.otp_code'))
    ->placeholder(__('auth.digit_placeholder'))
    

Gotchas and Tips

Pitfalls

  1. Auto-Submit Conflicts

    • If onChange triggers submission, ensure the form’s submit action is idempotent.
    • Fix: Use ->defer() or debounce the action:
      ->onChange(fn ($value) => $this->verifyOtpLater($value))
      
  2. Validation Timing

    • Live validation (->live()) may fire before the OTP is fully entered.
    • Fix: Use ->afterStateUpdated() for post-submission validation:
      ->afterStateUpdated(fn ($state) => $this->validateOtp($state))
      
  3. Mobile Input Issues

    • Some mobile keyboards may not handle backspace-to-previous-input well.
    • Fix: Test on target devices or add a helper button:
      ->extraAttributes(['data-mobile-friendly' => 'true'])
      
  4. CSRF Token Refresh

    • OTP forms may time out if the session expires during input.
    • Fix: Refresh CSRF token dynamically or use Filament’s ->preserveCsrfToken().

Debugging Tips

  1. Log OTP State Use ->afterStateUpdated() to debug:

    ->afterStateUpdated(fn ($state) => \Log::info('OTP entered:', ['otp' => $state]))
    
  2. Check JavaScript Events Inspect browser console for errors (e.g., Uncaught TypeError if onChange misfires).

  3. Clear Cache If styles/behavior break after updates:

    php artisan view:clear
    php artisan filament:cache-reset
    

Extension Points

  1. Custom Validation Rules Create a reusable rule for OTP verification:

    use Illuminate\Validation\Rule;
    
    Rule::macro('otpVerifiable', function ($otp) {
        return function ($attribute, $value, $fail) {
            if (!$this->otpService->verify($value, $otp)) {
                $fail('Invalid OTP.');
            }
        };
    });
    

    Then use:

    ->rules(['required', 'digits:6', Rule::otpVerifiable($user->otp)])
    
  2. Override Templates Publish and modify the Blade view:

    php artisan vendor:publish --tag=filament-otp-input-views
    

    Edit resources/views/vendor/filament-otp-input/otp-input.blade.php.

  3. Add Haptic Feedback Enhance UX with JavaScript:

    document.querySelectorAll('.filament-otp-input input').forEach(input => {
        input.addEventListener('input', () => {
            input.setAttribute('data-haptic', 'success');
        });
    });
    
  4. Accessibility Add ARIA labels for screen readers:

    ->extraAttributes([
        'aria-label' => 'One-Time Passcode',
        'role' => 'textbox',
    ])
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui