a89s/gooey-toast

A gooey expandable toast notification component for Laravel, Livewire

Maintainers

Package info

github.com/a89s/gooey-toast

Language:Blade

pkg:composer/a89s/gooey-toast

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

1.0.0 2026-02-20 06:35 UTC

This package is auto-updated.

Last update: 2026-04-04 13:21:49 UTC


README

⚠️ Work in progress — This package is under active development and not production-ready yet. APIs may change. Use at your own risk.

Inspiration for this package was taken from - anl331

A gooey expandable toast notification component for Laravel 10 / 11 / 12.

Features a unique SVG gooey blob animation, expandable detail rows, action buttons with icons and colors, promise toasts, progress toasts, undo countdown, persistent toasts, custom colors, message text blocks, vibration, action confirmation, animated timer bars, dark/light theming, and per-type entrance animations. Zero external CSS dependencies — works with any stack.

Screenshots

Screenshot 1 - Click here
Screenshot 2 - Click here
Screenshot 3 - Click here
Screenshot 4 - Click here
Screenshot 5 - Click here
Screenshot 6 - Click here

Installation

composer require a89s/gooey-toast

The package auto-discovers its service provider. No manual registration needed.

Publish the config (optional):

php artisan vendor:publish --tag=gooey-toast-config

Publishing Views

To customize the component markup:

php artisan vendor:publish --tag=gooey-toast-views

Views will be published to resources/views/vendor/gooey-toast/.

Setup

Add the component to your layout, just before </body>:

<x-gooey-toast />

The component requires Alpine.js (already included if you use Livewire). For non-Livewire projects, include Alpine yourself:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"></script>

Advanced Placement

If you need styles in <head> and scripts before </body> separately, use the Blade directives instead of the component:

<head>
    @gooeyToastStyles
</head>
<body>
    ...
    @gooeyToastScripts
</body>

Usage

JavaScript

// Simple
toast({ type: 'success', title: 'Saved!' });

// With details and footer
toast({
    type: 'error',
    title: 'Upload failed',
    details: [
        { label: 'File', value: 'report.pdf' },
        { label: 'Error', value: 'File too large' },
    ],
    footer: 'Max file size: 10 MB',
});

Livewire

$this->dispatch('toast', [
    'type'    => 'success',
    'title'   => 'Deployment complete',
    'details' => [
        ['label' => 'Environment', 'value' => 'Production'],
        ['label' => 'Branch',      'value' => 'main'],
    ],
    'footer' => 'https://deploy.example.com/logs/3f8a2c1',
]);

PHP API (No Livewire Required)

Use the GooeyToast facade to trigger toasts directly from PHP code. Works with any Laravel project, no Livewire needed:

use A89s\GooeyToast\Facades\GooeyToast;

// Quick toasts
GooeyToast::success('Saved!');
GooeyToast::error('Something went wrong');
GooeyToast::warning('Warning message');
GooeyToast::info('Information');

// Fluent builder
GooeyToast::make('Title', 'success')
    ->message('Additional message')
    ->send();

// With avatar
GooeyToast::make('New message', 'info')
    ->avatar('/avatars/user.jpg')
    ->avatarSize('32px')
    ->send();

// Full configuration
GooeyToast::make('Deployment complete', 'success')
    ->details([
        ['label' => 'Environment', 'value' => 'Production'],
        ['label' => 'Branch', 'value' => 'main'],
    ])
    ->footer('https://deploy.example.com/logs/123')
    ->duration(5000)
    ->send();

Available Methods

Method Description
make($title, $type) Create a new toast
success($title, $message) Quick success toast
error($title, $message) Quick error toast
warning($title, $message) Quick warning toast
info($title, $message) Quick info toast

Builder Methods

Method Description
title($title) Set toast title
type($type) Set toast type
message($message) Set message text block
details($array) Set detail rows
detail($label, $value) Add a detail row
footer($text) Set footer text
actions($array) Set action buttons
action($label, $event, $icon, $color, $confirm) Add an action button
vibrate($pattern) Enable vibration (mobile)
duration($ms) Set duration
persistent() Make persistent
color($color) Set custom color
avatar($url) Set avatar image
avatarSize($size) Set avatar size
id($id) Set toast ID
send() Send the toast

Toast Types

Type Color Entrance
success Green Smooth slide-up
error Red Slide-up + shake
warning Amber Slide-up + bounce
info Blue Smooth slide-up
loading Gray Smooth slide-up (spinner icon)

Progress Toasts

Show a progress bar that updates as work completes:

// Create a progress toast — returns an ID
const id = toast.progress('Uploading photos...');

// Update progress (0 to 1)
toast.progress(id, 0.25);
toast.progress(id, 0.5);
toast.progress(id, 0.75);

// Complete — auto-switches to success type
toast.progress(id, 1, 'Upload complete!');

With options:

const id = toast.progress('Processing...', { type: 'warning', color: '#8b5cf6' });

Livewire

// Start
$this->dispatch('toast', [
    'id'       => 'upload-1',
    'type'     => 'info',
    'title'    => 'Uploading...',
    'progress' => 0,
]);

// Update
$this->dispatch('toast-update', [
    'id'       => 'upload-1',
    'progress' => 0.5,
]);

// Complete
$this->dispatch('toast-update', [
    'id'       => 'upload-1',
    'progress' => 1,
    'type'     => 'success',
    'title'    => 'Uploaded!',
]);

Undo Toasts

Show a toast with an inline undo button and countdown. If the user doesn't click undo, a confirm event fires when the countdown expires.

toast.undo('Message deleted', 'confirm-delete', { id: 123 });

// Listen — only fires if NOT undone
window.addEventListener('confirm-delete', (e) => {
    fetch(`/api/messages/${e.detail.id}`, { method: 'DELETE' });
});

With more options:

toast.undo({
    title: 'Item archived',
    event: 'confirm-archive',      // fires on countdown expiry
    undoEvent: 'undo-archive',     // fires if user clicks undo (optional)
    data: { id: 456 },
    duration: 8000,                // countdown length in ms
    type: 'info',                  // toast type (default: warning)
});

Livewire

$this->dispatch('toast-undo', [
    'title'    => 'Item deleted',
    'event'    => 'confirm-delete',
    'data'     => ['id' => $id],
    'duration' => 5000,
]);

Persistent Toasts

Toasts that never auto-dismiss. Only removed by the close button, an action button, or swipe.

toast({ type: 'error', title: 'Connection lost', persistent: true });

Livewire

$this->dispatch('toast', [
    'type'       => 'error',
    'title'      => 'Payment failed',
    'persistent' => true,
    'details'    => [
        ['label' => 'Reason', 'value' => 'Card declined'],
    ],
]);

Custom Colors

Override the type color for any toast. Applies to the icon, title, timer bars, and progress bar.

toast({ type: 'success', title: 'VIP Access Granted', color: '#8b5cf6' });

Works with all toast types:

toast.undo('Archived', 'confirm-archive', { id: 1 });
toast.progress('Syncing...', { color: '#ec4899' });
toast({ type: 'info', title: 'Custom', color: '#06b6d4', persistent: true });

Livewire

$this->dispatch('toast', [
    'type'  => 'success',
    'title' => 'Branded notification',
    'color' => '#8b5cf6',
]);

Message Text

Display a plain text message block in the expanded body. Unlike details (key-value rows), message renders as a natural paragraph — ideal for chat notifications, alerts, or any freeform content.

toast({
    type: 'info',
    title: 'Melissa',
    avatar: '/avatars/melissa.jpg',
    message: 'Please visit HR when you get a chance 👋',
    footer: '1h ago',
});

Livewire

$this->dispatch('toast', [
    'type'    => 'info',
    'title'   => 'Melissa',
    'avatar'  => '/avatars/melissa.jpg',
    'message' => 'Please visit HR when you get a chance 👋',
    'footer'  => '1h ago',
]);

PHP API

GooeyToast::make('Melissa', 'info')
    ->avatar('/avatars/melissa.jpg')
    ->message('Please visit HR when you get a chance 👋')
    ->footer('1h ago')
    ->send();

Action Buttons

Add clickable buttons to the expanded toast body. Each button dispatches a custom window event and dismisses the toast. When there are 2+ buttons they display side by side; a single button stays full width.

toast({
    type: 'success',
    title: 'Message sent',
    actions: [
        { label: 'Undo', icon: 'undo', event: 'undo-send' },
        { label: 'View', icon: 'external-link', event: 'view-message', data: { id: 123 } },
    ],
});

// Listen for the event
window.addEventListener('view-message', (e) => {
    console.log(e.detail); // { id: 123 }
});

Action Button Colors

Give individual action buttons a custom color. The button gets a tinted background and colored text.

toast({
    type: 'info',
    title: 'Incoming call',
    persistent: true,
    actions: [
        { label: 'Accept', icon: 'check', event: 'accept', color: '#22c55e' },
        { label: 'Decline', icon: 'x', event: 'decline', color: '#ef4444' },
    ],
});

Action Confirmation

Add confirm: true to an action to require a two-step click. The first click changes the label to "Sure?" for 3 seconds. If clicked again, the event fires. If not, the label reverts.

toast({
    type: 'warning',
    title: 'Delete account',
    actions: [
        { label: 'Delete', icon: 'trash', event: 'delete-account', color: '#ef4444', confirm: true },
    ],
});

Available Icons

external-link, eye, undo, retry, reply, map-pin, download, copy, trash, check, x, image

You can also register custom icons:

toast.registerIcon('star', '<svg viewBox="0 0 24 24">...</svg>');

// Use in toasts
toast({ type: 'success', title: 'Favorited!', icon: 'star' });

Promise Toasts

Show a loading spinner that resolves to success or error automatically:

toast.promise(fetch('/api/save'), {
    loading: 'Saving...',
    success: 'Saved!',
    error: 'Failed to save',
});

Returns the original promise so you can chain .then().

Updating Toasts

Update any toast by ID:

toast.update('my-toast', { title: 'New title', type: 'success' });

Livewire

$this->dispatch('toast-update', [
    'id'    => 'my-toast',
    'title' => 'Updated!',
    'type'  => 'success',
]);

Theme Switching

The component supports dark and light themes. Set the default in config, or switch at runtime:

toast.theme('light');
toast.theme('dark');

Configuration

// config/gooey-toast.php
return [
    'position'   => 'bottom-center', // bottom-center, bottom-right, top-center, top-right
    'duration'   => 5000,            // auto-dismiss ms (0 = never)
    'max_toasts' => 5,
    'theme'      => 'dark',          // dark, light
];

User Avatars

Display a user avatar image instead of the default type icon:

toast({
    title: 'New message from John',
    avatar: '/avatars/john.jpg',
    type: 'info'
});

Custom Avatar Size

Override the default size (18px) with any CSS unit:

toast({
    title: 'Welcome back!',
    avatar: '/avatars/user.png',
    avatarSize: '32px',
    type: 'success'
});

Vibration

Trigger a device vibration (mobile only) when a toast appears. Uses the Vibration API — silently ignored on desktop browsers.

// Simple vibration (200ms)
toast({ type: 'info', title: 'Alert!', vibrate: true });

// Custom pattern (vibrate, pause, vibrate)
toast({ type: 'info', title: 'Incoming call', vibrate: [200, 100, 200] });

PHP API

GooeyToast::make('Incoming call', 'info')
    ->vibrate([200, 100, 200])
    ->send();

Full Options Reference

toast({
    type: 'success',             // success, error, warning, info, loading
    title: 'Notification',       // required
    id: 'my-id',                 // optional — use for updates
    message: 'Text block',      // optional — plain text message
    avatar: '/path/to/image.jpg', // optional — avatar image URL
    avatarSize: '32px',         // optional — avatar size (default: 18px)
    details: [                   // optional — expandable rows
        { label: 'Key', value: 'Value' },
    ],
    footer: 'Footer text',      // optional
    actions: [                   // optional — buttons in expanded body
        { label: 'Click me', icon: 'check', event: 'my-event', data: {}, color: '#22c55e', confirm: false },
    ],
    duration: 5000,              // optional — override config duration
    persistent: false,           // optional — never auto-dismiss
    color: '#8b5cf6',            // optional — override type color
    progress: 0.5,              // optional — show progress bar (0 to 1)
    icon: 'star',                // optional — override type icon (registered name)
    vibrate: true,               // optional — vibrate on mobile (true or [ms] pattern)
});

License

MIT — see LICENSE.