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

Livewire Modal Laravel Package

devsrv/livewire-modal

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require devsrv/livewire-modal
    
  2. Include the base modal component in your layout (once globally):

    <x-livewiremodal-base />
    

    Ensure this is placed after @livewireStyles and before @livewireScripts in your <body>.

  3. Trigger a modal from a Livewire component:

    <button wire:click="$emit('livewire-modal:open', 'modal-component-name')">
        Open Modal
    </button>
    
  4. Define your modal component (e.g., ModalComponent.php):

    public function render()
    {
        return view('livewire.modal-component');
    }
    
    <!-- resources/views/livewire/modal-component.blade.php -->
    <div class="modal-content">
        <!-- Your modal content here -->
    </div>
    

First Use Case: Quick Alert Modal

Use the built-in alert system for instant feedback:

<button wire:click="$emit('livewire-modal:alert', 'Success!', 'success')">
    Show Success Alert
</button>

Supports types: info, warning, success, danger.


Implementation Patterns

1. Triggering Modals

From Livewire:

<button wire:click="$emit('livewire-modal:open', 'user-edit-modal', { userId: 123 })">
    Edit User
</button>

Pass data via the 3rd argument (as JSON).

From Alpine.js:

<button x-on:click="$wire.emit('livewire-modal:open', 'user-edit-modal', { userId: 123 })">
    Edit User
</button>

From Vanilla JS:

document.querySelector('#open-modal').addEventListener('click', () => {
    window.Livewire.emit('livewire-modal:open', 'user-edit-modal');
});

2. Modal Component Structure

  • Required: Extend devsrv\LivewireModal\Modal or use $this->modal = true; in your Livewire class.

  • Example:

    public $modal = true;
    public $userId;
    
    public function mount($userId)
    {
        $this->userId = $userId;
    }
    
  • Dynamic Content:

    <div class="modal-header">Edit User #{{ $userId }}</div>
    <div class="modal-body">
        <!-- Dynamic form here -->
    </div>
    

3. Handling Modal Events

Listen for modal lifecycle events in your Livewire component:

protected $listeners = [
    'modalOpened' => 'onModalOpened',
    'modalClosed' => 'onModalClosed',
];

public function onModalOpened()
{
    $this->emit('alert', 'Modal opened!', 'info');
}

public function onModalClosed()
{
    $this->reset(['formData']);
}

4. Custom Styling

Override default styles by publishing the package assets:

php artisan vendor:publish --provider="devsrv\LivewireModal\LivewireModalServiceProvider" --tag=public

Then extend the CSS in public/css/livewire-modal.css.


5. Nested Modals

Use unique modal names to stack modals:

<button wire:click="$emit('livewire-modal:open', 'modal-level-1')">
    Open Level 1
</button>
<!-- Inside modal-level-1 -->
<button wire:click="$emit('livewire-modal:open', 'modal-level-2')">
    Open Level 2
</button>

Gotchas and Tips

Pitfalls

  1. Missing Base Component:

    • Error: Modal fails to open silently.
    • Fix: Ensure <x-livewiremodal-base /> is included once in your layout.
  2. Bootstrap 5 vs. 4:

    • Issue: Modal styles break if using Bootstrap 4 without jQuery.
    • Fix: Stick to Bootstrap 5 or include jQuery if using Bootstrap 4:
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
      
  3. Alpine.js Conflicts:

    • Issue: Alpine.js directives not working inside modals.
    • Fix: Ensure Alpine is loaded before Livewire scripts and use x-ignore for dynamic content:
      <div x-data="{ open: false }" x-ignore>
          <!-- Dynamic content -->
      </div>
      
  4. Modal Not Closing:

    • Cause: Missing $this->modal = true; in Livewire class or unhandled exceptions.
    • Debug: Check browser console for Livewire errors and ensure modalClosed listeners are properly defined.

Debugging Tips

  1. Check Emitted Events: Use browser dev tools to verify events are firing:

    window.addEventListener('livewire:initialized', () => {
        window.Livewire.on('livewire-modal:open', (name, data) => {
            console.log('Modal opened:', name, data);
        });
    });
    
  2. Inspect Modal Stack: The package uses a stack system. Log the stack to debug nesting:

    protected $listeners = [
        'modalStackUpdated' => 'logModalStack',
    ];
    
    public function logModalStack($stack)
    {
        \Log::info('Current modal stack:', $stack);
    }
    
  3. Force Modal Close: Manually trigger close via JavaScript for testing:

    window.Livewire.emit('livewire-modal:close');
    

Extension Points

  1. Custom Modal Templates: Override the base modal template by publishing the view:

    php artisan vendor:publish --provider="devsrv\LivewireModal\LivewireModalServiceProvider" --tag=views
    

    Then modify resources/views/vendor/livewire-modal/base.blade.php.

  2. Add Animation: Extend the modal class to include animations:

    // In your Livewire component
    public function mount()
    {
        $this->modalOptions = [
            'animation' => true,
        ];
    }
    
  3. Global Modal Config: Set default options in config/livewire-modal.php (published via):

    php artisan vendor:publish --provider="devsrv\LivewireModal\LivewireModalServiceProvider" --tag=config
    

    Example config:

    'default' => [
        'backdrop' => 'static',
        'keyboard' => true,
        'focus' => true,
    ],
    
  4. Server-Side Validation: Combine with Livewire validation for seamless UX:

    public function save()
    {
        $this->validate([
            'name' => 'required',
        ]);
        // Save logic
        $this->emit('livewire-modal:close');
    }
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours