microweber-packages / microweber-livewire-modal
Standalone Livewire modal package for Laravel. Supports stacked/nested modals, unique multi-instance IDs, skins, and configurable close/backdrop/escape options. Drop-in replacement for wire-elements/modal with multi-instance fixes.
Package info
github.com/microweber-packages/microweber-livewire-modal
pkg:composer/microweber-packages/microweber-livewire-modal
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- illuminate/view: ^10.0|^11.0|^12.0|^13.0
- livewire/livewire: ^3.0|^4.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^10.0|^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
- microweber-packages/livewire-modal: *
This package is auto-updated.
Last update: 2026-11-03 17:06:56 UTC
README
Standalone Laravel Livewire modal package with:
- Multiple open instances — each
openModalgets a unique instance id (no clobbering) - Nested / stacked modals — opening a modal inside another keeps the parent open
- Skins — default skin with X close button; swap via config or per-modal options
- Options (all ON by default):
- show close button
- close on click outside (backdrop)
- show backdrop
- close on Escape
Works as a drop-in for wire-elements/modal (livewire-ui-modal / wire-elements-modal aliases) and as a standalone package in any Laravel + Livewire app.
Installation
composer require microweber-packages/microweber-livewire-modal
Laravel auto-discovers the service provider. Publish config/views if needed:
php artisan vendor:publish --tag=livewire-modal-config php artisan vendor:publish --tag=livewire-modal-views
Usage
1. Mount the modal host once (layout / footer)
@livewire('microweber-livewire-modal') {{-- or legacy alias: @livewire('livewire-ui-modal') --}}
2. Create a modal component
use MicroweberPackages\LivewireModal\ModalComponent; class ConfirmDeleteModal extends ModalComponent { public string $title = 'Confirm'; public function confirm(): void { $this->dispatch('item-deleted'); $this->closeModal(); } public function render() { return view('modals.confirm-delete'); } // Optional overrides (defaults are all true / on): // public static function closeModalOnClickAway(): bool { return true; } // public static function closeModalOnEscape(): bool { return true; } // public static function showCloseButton(): bool { return true; } // public static function showBackdrop(): bool { return true; } }
Register it with Livewire:
Livewire::component('confirm-delete-modal', ConfirmDeleteModal::class);
3. Open / close
<button wire:click="$dispatch('openModal', { component: 'confirm-delete-modal', title: 'Delete item?' })"> Delete </button>
From a modal component (opening another / nested modal), use the openModal() helper —
a component-scoped $this->dispatch('openModal', …) is not routed to the modal container
across Livewire component boundaries in Livewire 4, so the helper bridges to a global
browser dispatch for you:
// From inside a ModalComponent (e.g. to open a nested/child modal): $this->openModal('confirm-delete-modal', ['title' => 'Delete item?']); $this->closeModal(); // closes topmost only $this->forceClose()->closeModal(); // closes entire stack
Nested modals
Open a second modal while one is already open — the first stays mounted and visible underneath with a lower z-index. Closing pops only the top instance.
Skins
Default skin: resources/views/skins/default.blade.php.
// config/livewire-modal.php 'skin' => 'default',
Per open:
$dispatch('openModal', { component: 'confirm-delete-modal', modalAttributes: { skin: 'default', showCloseButton: false } })
mw.dialog / bare skins
Use skin: 'mw-dialog' (or bare) when an external wrapper should provide chrome. The package JS wraps the host with mw.dialog when mw.dialog is available (drag, autosize, autoscroll, close button, backdrop). Supported options:
closeButton/showCloseButtonoverlay/showBackdropoverlayClose/closeOnClickAwaycloseOnEscapeautoHeight/autosizeautoScroll/scrollModedraggablewidth/height/title
If mw.dialog is missing, the skin falls back to a simple centered overlay.
Testing
composer test
composer analyse
License
MIT