andisiahaan / livewire-dialog
A powerful Livewire dialog system with stack management, multiple dialog types, and rich customization
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/andisiahaan/livewire-dialog
Requires
- php: ^8.2
- livewire/livewire: ^4.0
Requires (Dev)
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^12.3
README
A powerful dialog system for Laravel Livewire with stack management, multiple dialog types (Modal, Sheet, Drawer), and rich customization options.
Features
- Stack-Based Management - Open multiple dialogs with automatic history management
- Multiple Dialog Types - Modal, Sheet (bottom slide), Drawer (side slide), Alert, Confirm
- Configurable Animations - Fade, Scale, Slide-up, Slide-down, Slide-left, Slide-right
- Position Options - Center, Top, Bottom, Left, Right
- Preset System - Reusable configuration presets
- Lifecycle Hooks -
onOpening(),onClosing(),onClosed() - Fluent Configuration -
DialogOptions::make()->size('lg')->dismissible() - Full Livewire 4 Support
Installation
composer require andisiahaan/livewire-dialog
Quick Start
1. Add Dialog Container
Add the Livewire directive to your layout (before </body>):
<html> <body> <!-- Your content --> @livewire('dialog-container') </body> </html>
2. Create a Dialog Component
<?php namespace App\Livewire; use AndiSiahaan\Dialog\Components\BaseDialog; use AndiSiahaan\Dialog\Support\DialogOptions; class EditUser extends BaseDialog { public $user; public function mount($userId) { $this->user = User::findOrFail($userId); } public function dialogOptions(): DialogOptions { return DialogOptions::make() ->size('lg') ->dismissOnClickOutside(false); } public function save() { $this->user->save(); $this->dismiss(); } public function render() { return view('livewire.edit-user'); } }
3. Open the Dialog
<!-- From HTML/JavaScript --> <button onclick="DialogSystem.open('edit-user', { userId: 1 })">Edit User</button> <!-- From Livewire component --> <button wire:click="$dispatch('dialog:open', { component: 'edit-user', arguments: { userId: {{ $user->id }} }})"> Edit User </button>
Opening Dialogs
Via JavaScript
// Basic modal DialogSystem.open('edit-user', { userId: 1 }); // With options DialogSystem.open('edit-user', { userId: 1 }, { size: 'lg', animation: 'fade' });
Via Dialog Facade (PHP)
use AndiSiahaan\Dialog\Dialog; // Modal Dialog::modal('edit-user', ['userId' => $id]); // Sheet (slides from bottom) Dialog::sheet('select-option'); // Drawer (slides from side) Dialog::drawer('navigation-menu', [], 'left'); // Alert Dialog::alert('Success!', 'User has been saved.'); // Confirm Dialog::confirm('Delete?', 'Are you sure you want to delete this user?');
Via Trait
use AndiSiahaan\Dialog\Concerns\InteractsWithDialog; class UserList extends Component { use InteractsWithDialog; public function editUser($id) { $this->openDialog('edit-user', ['userId' => $id]); } public function showSheet() { $this->openSheet('select-option'); } public function deleteUser($id) { $this->confirmAction('Delete this user?', 'confirmDelete', ['userId' => $id]); } }
Via Helper Functions
dialog('edit-user', ['userId' => $id]); dialog_modal('edit-user', ['userId' => $id]); dialog_sheet('select-option'); dialog_drawer('sidebar', [], 'left'); dialog_alert('Success!', 'Data saved.'); dialog_confirm('Delete?', 'Are you sure?');
Dismissing Dialogs
From View
<button wire:click="dismiss">Close</button>
From Component
public function save() { $this->user->save(); $this->dismiss(); } // Force close all dialogs public function cancel() { $this->forceAll()->dismiss(); } // Skip previous dialog public function deleteAndGoBack() { $this->skipPrevious()->dismiss(); } // Dismiss with events public function save() { $this->dismissWithEvents([ UserList::class => 'refreshList', ]); }
Dialog Options
Override dialogOptions() in your dialog:
public function dialogOptions(): DialogOptions { return DialogOptions::make() ->size('lg') // sm, md, lg, xl, 2xl-7xl, full ->position('center') // center, top, bottom, left, right ->animation('scale') // none, fade, scale, slide-up/down/left/right ->dismissible() // Enable dismiss ->dismissOnEscape(true) // Close on Escape key ->dismissOnClickOutside(false) // Close on backdrop click ->escapeClosesAll(true) // Escape closes all dialogs ->destroyOnDismiss(true) // Destroy component on close ->persistent(); // Cannot be dismissed at all }
Using Presets
Define presets in config/dialog.php:
'presets' => [ 'confirmation' => [ 'size' => 'sm', 'animation' => 'scale', 'dismiss_on_click_outside' => false, ], 'fullscreen' => [ 'size' => 'full', 'animation' => 'fade', ], ],
Use them in your dialog:
public function dialogOptions(): DialogOptions { return DialogOptions::make()->preset('confirmation'); }
Lifecycle Hooks
Override these methods in your dialog component:
// Called when dialog is opening (return false to prevent) protected function onOpening(): bool { return true; } // Called when dialog is closing (return false to prevent) protected function onClosing(): bool { if ($this->formIsDirty) { return false; // Prevent closing } return true; } // Called after dialog has closed protected function onClosed(): void { // Cleanup logic }
TailwindCSS Setup
Add the package views to your tailwind.config.js:
export default { content: [ './vendor/andisiahaan/livewire-dialog/resources/views/**/*.blade.php', // ... your other paths ], safelist: [ { pattern: /max-w-(sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl)/, variants: ['sm', 'md', 'lg', 'xl', '2xl'] } ], }
Configuration
Publish the config file:
php artisan vendor:publish --tag=dialog-config
Publish the views:
php artisan vendor:publish --tag=dialog-views
API Reference
Dialog Facade Methods
| Method | Description |
|---|---|
Dialog::open($component, $args, $options) |
Open a dialog |
Dialog::modal($component, $args) |
Open a modal dialog |
Dialog::sheet($component, $args) |
Open a sheet (bottom slide) |
Dialog::drawer($component, $args, $position) |
Open a drawer (side slide) |
Dialog::alert($title, $message) |
Show an alert dialog |
Dialog::confirm($title, $message, $confirmText, $cancelText) |
Show a confirm dialog |
Dialog::dismiss() |
Dismiss current dialog |
Dialog::dismissAll() |
Dismiss all dialogs |
JavaScript API
| Method | Description |
|---|---|
DialogSystem.open(component, args, options) |
Open a dialog |
DialogSystem.dismiss(force) |
Dismiss current dialog |
DialogSystem.dismissAll() |
Dismiss all dialogs |
Dialog Component Methods
| Method | Description |
|---|---|
dismiss() |
Dismiss the dialog |
dismissWith($data) |
Dismiss with data |
dismissWithEvents($events) |
Dismiss and dispatch events |
replace($component, $args) |
Replace with another dialog |
forceAll() |
Chain: force close all |
skipPrevious($count) |
Chain: skip previous dialogs |
License
MIT License. See LICENSE for more information.