Installation:
composer require andisiahaan/livewire-modal
Add the Livewire directive to your layout (e.g., resources/views/layouts/app.blade.php):
@livewire('livewire-modal')
Configure Tailwind (if using):
Update tailwind.config.js to include the package’s views:
content: [
'./vendor/andisiahaan/livewire-modal/resources/views/*.blade.php',
// ... existing paths
],
First Modal:
Create a Livewire component extending ModalComponent:
php artisan make:livewire EditUser --extends=ModalComponent
Define a modal trigger in your Blade view:
<x-button wire:click="$dispatch('open-modal', id: 'edit-user', data: { userId: 1 })">
Edit User
</x-button>
@livewireModal('edit-user', EditUser::class, ['userId' => 1])
Triggering Modals:
Use $dispatch to open modals dynamically:
<button wire:click="$dispatch('open-modal', id: 'confirm-delete', data: { itemId: 123 })">
Delete
</button>
Register the modal in Blade:
@livewireModal('confirm-delete', ConfirmDeleteModal::class, ['itemId' => 123])
Nested Modals: Child modals inherit state from parent modals. Use unique IDs for each:
@livewireModal('child-modal', ChildModal::class, ['parentData' => $parentData])
State Management:
Pass data via data prop or use Livewire’s native state:
public $userId;
public $formData = [];
public function mount($userId) {
$this->userId = $userId;
$this->formData = User::find($userId)->toArray();
}
Closing Modals:
Use $emit or $dispatch to close:
public function close() {
$this->emit('close-modal', id: 'edit-user');
}
Or trigger from Blade:
<button wire:click="$dispatch('close-modal', id: 'edit-user')">Cancel</button>
Reusable Modal Components:
Create base modals (e.g., FormModal) and extend for specific use cases:
class FormModal extends ModalComponent {
public $submitText = 'Submit';
public $formFields = [];
}
Alpine.js Integration: Combine with Alpine for dynamic UI (e.g., toggle visibility):
<div x-data="{ open: false }" x-on:open-modal.window="open = true">
@livewireModal('dynamic-modal', DynamicModal::class)
</div>
Validation: Use Livewire’s validation in modals:
use WithValidation;
public $name;
protected $rules = ['name' => 'required|min:3'];
Modal Stacking: Leverage the package’s built-in stacking for overlapping modals. Ensure unique IDs:
@livewireModal('modal-1', ModalOne::class)
@livewireModal('modal-2', ModalTwo::class)
Server-Side Logic: Offload heavy logic to modal components (e.g., CRUD operations):
public function save() {
$validated = $this->validate();
User::update($this->userId, $validated);
$this->emit('close-modal', id: 'edit-user');
}
Duplicate Modal IDs:
edit-user-{{ $user->id }}).State Persistence:
public properties or $persist for critical data:
public $persist = ['userId', 'formData'];
Tailwind Conflicts:
!important sparingly:
.modal-content {
@apply bg-white p-6 !important;
}
Event Listeners:
$dispatch events may not trigger if misconfigured.open-modal vs. openModal).Nested Modal Closing:
public function closeChild() {
$this->emit('close-modal', id: 'parent-modal');
}
Check Livewire Logs: Enable Livewire debug mode to trace modal interactions:
Livewire::configureToUseAlpine();
Livewire::setDebugMode(true);
Inspect Events: Use browser dev tools to verify dispatched events:
window.addEventListener('open-modal', (e) => console.log(e.detail));
Verify Component Registration:
Ensure modals are registered in Blade after the @livewire('livewire-modal') directive.
Custom Animations: Override default animations by extending the modal view:
@push('modal-styles')
<style>
.modal-enter-active {
transition: all 0.5s ease-out;
}
</style>
@endpush
Modal Templates: Replace the default template by publishing views:
php artisan vendor:publish --tag=livewire-modal-views
Then modify resources/views/vendor/livewire-modal/modal.blade.php.
Global Modal Settings:
Configure defaults in ModalComponent:
protected $modalSize = 'lg'; // Default size
protected $showCloseButton = true;
Accessibility: Add ARIA attributes for screen readers:
<div
wire:ignore
x-data="{ open: false }"
x-show="open"
@open-modal.window="open = true"
@close-modal.window="open = false"
role="dialog"
aria-modal="true"
>
<!-- Modal content -->
</div>
Performance: Lazy-load modals by conditionally rendering them:
@if(auth()->check())
@livewireModal('user-settings', UserSettingsModal::class)
@endif
How can I help you explore Laravel packages today?