Installation:
composer require corepine/modal
php artisan vendor:publish --tag=corepine-modal-config
Add Tailwind CSS import to your main file:
@import "../../vendor/corepine/modal/resources/css/app.css";
Livewire Stack Mode Setup:
Include the modal host in your layout (e.g., app.blade.php):
<x-corepine.modal.assets />
First Modal: Create a Livewire modal class:
php artisan make:livewire MyModal
Extend Corepine\Modal\Modal:
use Corepine\Modal\Modal;
class MyModal extends Modal
{
public $name = 'John Doe';
}
Trigger it from a button:
<x-corepine.modal.trigger wire:click="$openModal('MyModal')" />
Standalone Alpine Mode: Use the component directly in Blade:
<x-corepine.modal
wire:ignore
x-data="{ open: false }"
@open.window="open = true"
@close.window="open = false"
>
<div x-show="open">
<!-- Modal content -->
</div>
</x-corepine.modal>
$openModal() to trigger nested modals.
// Parent modal
public function openChildModal()
{
$this->openModal('ChildModal', ['param' => 'value']);
}
public function save()
{
// Logic
$this->close();
}
x-data and @open.window/@close.window for browser-triggered modals.
<x-corepine.modal
x-data="{ open: false }"
@open.window="open = true"
>
<div x-show="open" x-transition>
<!-- Content -->
</div>
</x-corepine.modal>
modal): Default centered modal.drawer): Left/right panel (use direction="left|right").sheet): Bottom-up modal (use type="sheet").
<x-corepine.modal type="sheet" direction="left">
<!-- Content -->
</x-corepine.modal>
Corepine\Modal\Events to dispatch/modal-specific events (e.g., ModalOpened).config/corepine-modal.php (e.g., backdrop opacity, animations).wire:model to sync Livewire properties with Alpine state:
<input wire:model="name" x-model="localName" @change="name = localName">
Livewire Host Missing:
<x-corepine.modal.assets /> is included in your layout once.Modal Stack Leaks:
$close() calls.$this->close() in shell actions or use $this->closeModal() to target specific modals.Tailwind Conflicts:
.my-modal .bg-blue-500) or use !important sparingly.Alpine + Livewire State Clashes:
wire:ignore on Alpine-managed elements or sync state explicitly.z-index layers. Corepine modals use a base z-50 with increments for stacking.php artisan tinker
>>> event(new \Corepine\Modal\Events\ModalOpened('MyModal'));
.env:
LIVEWIRE_LOG_LEVEL=debug
Custom Modal Classes:
Corepine\Modal\Modal to add shared logic (e.g., auth checks):
class AuthModal extends Modal
{
public function mount()
{
if (!auth()->check()) {
$this->close();
}
}
}
Dynamic Content:
<x-corepine.modal>
<x-slot name="title">
{{ $this->title ?? 'Default Title' }}
</x-slot>
</x-corepine.modal>
Animation Overrides:
@layer components.modal {
.corepine-modal-enter-active {
@apply transition-all duration-300;
}
}
Package-Safe Event Names:
$this->dispatch('my-package::modal-opened', modal: $this);
'events' => [
'opened' => 'my-package::modal-opened',
],
How can I help you explore Laravel packages today?