haxneeraj/laravel-livewire4-toaster
composer require haxneeraj/laravel-livewire4-toaster
php artisan vendor:publish --provider="Haxneeraj\Livewire4Toaster\Livewire4ToasterServiceProvider"
resources/views/layouts/app.blade.php):
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('toaster', () => ({
toasts: [],
// ... (see README for full Alpine script)
}));
});
</script>
use Haxneeraj\Livewire4Toaster\Traits\HasToaster;
class MyComponent extends Component {
use HasToaster;
public function save() {
$this->success('Data saved successfully!');
}
}
Trigger a toast from a Livewire component method:
public function deleteItem() {
try {
$this->delete($item);
$this->success('Item deleted!', ['position' => 'top-right']);
} catch (\Exception $e) {
$this->error('Failed to delete: ' . $e->getMessage());
}
}
Component Integration:
HasToaster trait in any Livewire component for method-based toasts (success(), error(), etc.).class UserProfile extends Component {
use HasToaster;
public function updateProfile() {
if ($this->validate()) {
$this->success('Profile updated!', [
'duration' => 5000,
'queue' => true,
]);
}
}
}
Controller/Service Layer:
Toast::info('Message')) or helper (toast('warning', 'Message')) for non-Livewire contexts.use Haxneeraj\Livewire4Toaster\Facades\Toast;
public function store(Request $request) {
$validated = $request->validate([...]);
Toast::success('Resource created!', ['position' => 'bottom-left']);
return redirect()->back();
}
Event-Driven Dispatch:
dispatch():
$this->dispatch('toast', type: 'success', message: 'Event-triggered toast!');
x-on:toast.window="toaster.addToast($event.detail.type, $event.detail.message)"
Queue Management:
$this->info('Processing...', ['queue' => true]);
$this->warning('Next step', ['queue' => true]);
config/livewire4-toaster.php:
'queue' => [
'enabled' => true,
'max_at_once' => 1,
],
Dynamic Toasts:
$this->success('User <strong>' . $user->name . '</strong> created.', [
'html' => true,
]);
@livewireScripts
@stack('scripts')
<script src="{{ asset('js/livewire4-toaster.js') }}"></script>
toaster data:
Alpine.data('toaster', () => ({
// Override default classes
toastClasses: {
success: 'bg-green-500 text-white',
error: 'bg-red-500 text-white',
// ...
}
}));
Livewire\Component (not Livewire\Livewire).
For older Livewire 3 components, use the livewire:ignore directive on the Alpine script.Alpine Initialization:
toaster script runs after Livewire’s Alpine initialization. Wrap it in alpine:init or place it in a @stack('scripts') section loaded last.Alpine is not defined errors.Duplicate Toasts:
duplicate: 'suppress' is set.duplicate: 'replace' to overwrite duplicates or adjust the duplicateCheck duration in config:
'duplicate' => [
'check' => 1000, // Check for duplicates every 1 second
'method' => 'suppress',
],
Queue Conflicts:
max_at_once in config matches your use case (e.g., max_at_once: 3 for 3 concurrent toasts).Livewire 4 dispatch():
dispatch().toast in this package). Example:
$this->dispatch('toast', type: 'info', message: 'Hello!');
CSS Conflicts:
!important in Alpine’s toastClasses or scope styles with a unique class:
toastClasses: {
container: 'livewire-toaster-container',
toast: 'livewire-toaster',
}
Then add CSS:
.livewire-toaster-container { position: fixed; z-index: 9999; }
window.addEventListener('toast', (e) => {
console.log('Toast event:', e.detail);
});
config/livewire4-toaster.php for typos or incorrect paths (e.g., position values must match Alpine’s logic).Custom Toast Types:
Add new toast types by extending Alpine’s toaster data:
Alpine.data('toaster', () => ({
toastTypes: {
...defaultTypes,
custom: {
icon: '✨',
classes: 'bg-purple-500',
},
},
}));
Then use in PHP:
$this->toast('custom', 'This is a custom toast!');
Progress Bar Customization: Override the progress bar template in Alpine:
progressBarTemplate: `
<div class="w-full h-1 bg-blue-500 transition-all"></div>
`,
Server-Side Logic: Extend the trait to add component-specific logic:
use Haxneeraj\Livewire4Toaster\Traits\HasToaster;
class MyComponent extends Component {
use HasToaster {
HasToaster::toast as private __toast;
}
public function toast($type, $message, $options = []) {
$options['position'] = 'bottom-right'; // Force position
return $this->__toast($type, $message, $options);
}
}
Testing: Mock toasts in PHPUnit:
$component->expectsToDispatch('toast')
->with(['type' => 'success', 'message' => 'Test']);
$component->success('Test');
top-right, top-left, bottom-right, bottom-left). Custom positions require Alpine updates.5000 = 5 seconds).queue: true globally in config affects all toasts unless overridden per-call.How can I help you explore Laravel packages today?