LivewireUI Modal is a Livewire component that provides you with a modal that supports multiple child modals while maintaining a state.

‚ö° Installation

composer require livewire-ui/modal

ūüéĮ Livewire directive

Add the Livewire directive @livewire('livewire-ui-modal') and also the Javascript @livewireUIScripts directive to your template.

<html>
<body>
    <!-- content -->
    
    @livewire('livewire-ui-modal')
    @livewireUIScripts
</body>
</html>

Next, you will need to publish the required scripts with the following command:

php artisan vendor:publish --tag=livewire-ui:public

ūü•ä Alpine

Livewire UI requires Alpine. You can use the official CDN to quickly include Alpine:

<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>

ūüé® TailwindCSS

The base modal is made with TailwindCSS. If you use a different CSS framework I recommend that you publish the modal template and change the markup to include the required classes for your CSS framework.

php artisan vendor:publish --tag=livewire-ui:views

Creating a modal

You can run php artisan make:livewire EditUser to make the initial Livewire component. Open your component class and make sure it extends the ModalComponent class:

<?php

namespace App\Http\Livewire;

use LivewireUI\Modal\ModalComponent;

class EditUser extends ModalComponent
{
    public function render()
    {
        return view('livewire.edit-user');
    }
}

Opening a modal

To open a modal you will need to emit an event. To open the EditUser modal for example:

<!-- Outside of any Livewire component -->
<button onclick="Livewire.emit('openModal', 'edit-user')">Edit User</button>

<!-- Inside existing Livewire component -->
<button wire:click="$emit('openModal', 'edit-user')">Edit User</button>

Passing parameters

To open the EditUser modal for a specific user we can pass the user id (notice the single quotes):

<!-- Outside of any Livewire component -->
<button onclick='Livewire.emit("openModal", "edit-user", @json(['user' => $user->id]))'>Edit User</button>

<!-- Inside existing Livewire component -->
<button wire:click='$emit("openModal", "edit-user", @json(['user' => $user->id])'>Edit User</button>

The parameters are passed to the mount method on the modal component:

<?php

namespace App\Http\Livewire;

use App\Models\User;
use LivewireUI\Modal\ModalComponent;

class EditUser extends ModalComponent
{
    public User $user;
    
    public function mount(User $user) {
        $this->user = $user;
    }
    
    public function render()
    {
        return view('livewire.edit-user');
    }
}

Opening a child modal

From an existing modal you can use the exact same event and a child modal will be created:

<!-- Edit User Modal -->

<!-- Edit Form -->

<button wire:click='$emit("openModal", "delete-user", @json(['user' => $user->id])'>Delete User</button>

Closing a (child) modal

If for example, a user clicks the ‘Delete’ button which will open a confirm dialog, you can cancel the deletion and return to the edit user modal by emitting the closeModal¬†event. This will open the previous modal. If there is no previous modal the entire modal component is closed and the state will be reset.

<button wire:click="$emit('closeModal')">No, do not delete</button>

You can also close a modal from within your modal component class:

<?php

namespace App\Http\Livewire;

use App\Models\User;
use LivewireUI\Modal\ModalComponent;

class EditUser extends ModalComponent
{
    public User $user;

    public function mount(User $user) {
        $this->user = $user;
    }
    
    public function update()
    {
        $this->user->update($data);
        
        $this->closeModal();
    }

    public function render()
    {
        return view('livewire.edit-user');
    }
}