-
-
Save burnz/70ab9ebd493b8cb4ce5163f276f5f0a6 to your computer and use it in GitHub Desktop.
Fluent toaster(alerts) for laravel/livewire using alpinejs and tailwindcss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public function showToasters(){ | |
// default info toaster with timeout | |
$this->toaster('your message'); | |
// makes it persistent | |
$this->toaster('your message')->persistent(); | |
// warning toaster with timeout | |
$this->toaster('your message')->warning(); | |
//And so on | |
//By using __destruct() we have made Toaster a Pending Object. So you can use methods in any order | |
$this->toaster('your message')->error()->persistent(); | |
$this->toaster()->success('give message to type method if you want')->persistent(); | |
$this->toaster()->timeout(15000)->info('give message to type method if you want'); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Don't forget to add toaster.blade.php to you layout file | |
@include('toasters.blade.php') | |
//Or if it is a blade component | |
<x-toasters></x-toasters> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public function boot(){ | |
Livewire\Component::macro('toaster', function (?string $message = null, ?string $type = "info"): Toaster | |
{ | |
return new Toaster($message, $type, $this); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//you can use toaster elsewhere in laravel as well add the helper for luxury (❁´◡`❁) | |
//helpers.php | |
function toaster(?string $message = null, ?string $type = 'info'){ | |
return new App\Support\Toaster($message,$type); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Support; | |
use Livewire\Component; | |
class Toaster | |
{ | |
public ?Component $component = null; | |
public string $message; | |
public string $type; | |
public bool $persistent = false; | |
public int $timeout = 5000; | |
public function __construct(?string $message = null, ?string $type = "info", ?Component &$component = null) | |
{ | |
$this->component = $component; | |
$this->message = $message; | |
$this->type = $type; | |
} | |
public function message(string $message = null, string $type = "info") | |
{ | |
$this->type = $type; | |
if ($message) { | |
$this->message = $message; | |
} | |
return $this; | |
} | |
public function success(?string $message = null) | |
{ | |
return $this->message($message, 'success'); | |
} | |
public function info(?string $message = null) | |
{ | |
return $this->message($message, 'info'; | |
} | |
public function warning(?string $message = null) | |
{ | |
return $this->message($message, 'warning'); | |
} | |
public function error(?string $message = null) | |
{ | |
return $this->message($message, 'error'); | |
} | |
public function persistent() | |
{ | |
$this->persistent = true; | |
return $this; | |
} | |
public function timeout(int $milliseconds){ | |
$this->timeout = $milliseconds; | |
return $this; | |
} | |
public function generate() | |
{ | |
if (!$this->message) { | |
return; | |
} | |
$payload = [ | |
"type" => ($this->type ?: "info"), | |
"message" => $this->message, | |
"persistent" => $this->persistent, | |
"timeout" => $this->timeout | |
]; | |
if ($this->component && empty($this->component->redirectTo)) { | |
$this->component->dispatchBrowserEvent('livewire-toaster', $payload); | |
} else { | |
session()->flash('livewire.toaster', $payload); | |
} | |
} | |
public function __destruct() | |
{ | |
$this->generate(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div x-cloak | |
x-data="toaster()" | |
x-init="init()" | |
x-on:livewire-toaster.window="trigger" | |
class="fixed bottom-0 right-0 flex flex-col max-w-sm p-4 space-y-3 w-80"> | |
<template x-for="(toast,index) in toasters" :key="index"> | |
<div x-show="toasters.indexOf(toast) >= 0" | |
x-transition:enter="transition ease-out duration-300" | |
x-transition:enter-start="opacity-0 transform scale-50" | |
x-transition:enter-end="opacity-100 transform scale-100" | |
x-transition:leave="transition ease-in duration-300" | |
x-transition:leave-start="opacity-100 transform scale-100" | |
x-transition:leave-end="opacity-0 transform scale-50"> | |
<div class="flex items-center justify-between w-full px-2 py-3 space-x-6 shadow-lg toaster" | |
:class="toast.type"> | |
<span x-html="toast.message" class="mr-2 capitalize"></span> | |
<button class="p-0.5 btn rounded-full error low focus:outline-none focusable" | |
x-on:click="close(toast)" x-show="toast.persistent"> | |
<x-icon name="close" /> | |
</button> | |
</div> | |
</div> | |
</template> | |
</div> | |
<script> | |
function toaster() { | |
return { | |
toasters: [], | |
flash: JSON.parse(JSON.stringify(@json(session('livewire.toaster')))), | |
trigger(event = null) { | |
if (event == null) return; | |
this.flash = event.detail ? event.detail : event; | |
let toast = { | |
type: this.flash.type, | |
message: this.flash.message, | |
persistent: this.flash.persistent, | |
timeout:this.flash.timeout | |
} | |
this.toasters.push(toast) | |
if (!toast.persistent) { | |
this.autoClose(toast) | |
} | |
}, | |
autoClose(toast) { | |
setTimeout(() => { | |
this.close(toast) | |
}, toast.timeout); | |
}, | |
close(toast) { | |
this.toasters.splice(this.toasters.indexOf(toast), 1) | |
}, | |
init() { | |
if (this.flash) { | |
this.trigger(this.flash) | |
} | |
}, | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment