- 
      
 - 
        
Save shoemoney/fe6448485e2f97a91caf20314f387cbc to your computer and use it in GitHub Desktop.  
    Fluent toaster(alerts) for laravel/livewire using alpinejs and tailwindcss
  
        
  
    
      This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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