<turbo-frame data-turbo-action="advance" id="lui-main-layout" data-turbo-frame="lui-main-layout" class="min-h-0 " style=""> <div class="lui-layout-loading" style="display: none;"> <div class="lui-action_bar"> <div class="lui-action_bar__left w-1/4"> <div class="lui-skeleton__bar"></div> </div> <div class="lui-action_bar__right w-1/4"> <div class="lui-skeleton__bar"></div> </div> </div> <div class="lui-show-layout"> <div class="lui-skeleton "> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__footer"> <div class="lui-skeleton__bar--footer"></div> <div class="lui-skeleton__bar--footer lui-skeleton__bar--footer--invisible"></div> </div> </div> <div class="lui-skeleton lui-skeleton--full"> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__footer"> <div class="lui-skeleton__bar--footer"></div> <div class="lui-skeleton__bar--footer lui-skeleton__bar--footer--invisible"></div> </div> </div> <div class="lui-skeleton lui-skeleton--full"> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__item"> <div class="lui-skeleton__bar" style="width: 100%"></div> </div> <div class="lui-skeleton__footer"> <div class="lui-skeleton__bar--footer"></div> <div class="lui-skeleton__bar--footer lui-skeleton__bar--footer--invisible"></div> </div> </div> </div> </div> <div class="lui-main_layout__content" data-skeleton-loading="true"> <div class="flex flex-col gap-4"> <a data-turbo-method="get" disabled="disabled" href="/toaster/random_toaster?type=informative"> <div class="lui-toaster" data-controller="toaster" data-toaster-persistent-value="true" data-toaster-timeout-value="2000"> <div class="lui-toaster__content"> <div class="lui-toaster__content-title"> <i class="fa-regular fa-circle-info fa-xs text-general-informative-800"></i> <div class="lui-toaster__content-title__text"> Hover or click me </div> </div> <div class="lui-toaster__content-description">To create a new toast</div> </div> <div class="lui-toaster__close" data-action="click->toaster#dismiss"> <i class="fa-regular fa-xmark fa-xs"></i> </div> </div> </a> <a data-turbo-method="get" disabled="disabled" href="/toaster/random_toaster?type=success"> <div class="lui-toaster" data-controller="toaster" data-toaster-persistent-value="true" data-toaster-timeout-value="2000"> <div class="lui-toaster__content"> <div class="lui-toaster__content-title"> <i class="fa-regular fa-circle-check fa-xs text-general-success-800"></i> <div class="lui-toaster__content-title__text"> Hover or click me </div> </div> <div class="lui-toaster__content-description">To create a new toast</div> </div> <div class="lui-toaster__close" data-action="click->toaster#dismiss"> <i class="fa-regular fa-xmark fa-xs"></i> </div> </div> </a> <a data-turbo-method="get" disabled="disabled" href="/toaster/random_toaster?type=warning"> <div class="lui-toaster" data-controller="toaster" data-toaster-persistent-value="true" data-toaster-timeout-value="2000"> <div class="lui-toaster__content"> <div class="lui-toaster__content-title"> <i class="fa-regular fa-circle-exclamation fa-xs text-general-notice-800"></i> <div class="lui-toaster__content-title__text"> Hover or click me </div> </div> <div class="lui-toaster__content-description">To create a new toast</div> </div> <div class="lui-toaster__close" data-action="click->toaster#dismiss"> <i class="fa-regular fa-xmark fa-xs"></i> </div> </div> </a> <a data-turbo-method="get" disabled="disabled" href="/toaster/random_toaster?type=danger"> <div class="lui-toaster" data-controller="toaster" data-toaster-persistent-value="true" data-toaster-timeout-value="2000"> <div class="lui-toaster__content"> <div class="lui-toaster__content-title"> <i class="fa-regular fa-circle-xmark fa-xs text-general-danger-800"></i> <div class="lui-toaster__content-title__text"> Hover or click me </div> </div> <div class="lui-toaster__content-description">To create a new toast</div> </div> <div class="lui-toaster__close" data-action="click->toaster#dismiss"> <i class="fa-regular fa-xmark fa-xs"></i> </div> </div> </a> <a class="lui-button lui-button--size-default lui-button--core--primary w-fit w-fit" data-controller="lui--button" href="/toaster/random_toaster" data-turbo-method="get"> <span class="lui-button__text" data-lui--button-target="text"> Hover or click me for random toast </span> </a> <a class="lui-button lui-button--size-default lui-button--core--primary w-fit w-fit" data-controller="lui--button" href="/toaster/clear_toasters" data-turbo-method="get"> <span class="lui-button__text" data-lui--button-target="text"> Clear toasters </span> </a> </div> </div></turbo-frame><turbo-frame id="lui-main-layout-actions"></turbo-frame><turbo-cable-stream-source channel="Turbo::StreamsChannel" signed-stream-name="InRvYXN0ZXJzIg==--7c1405336eb46a24b1b64d0d30019fb9fce53bc08bd9a1c5f30369d28862a109"></turbo-cable-stream-source><div id="lui-toasters" popover="manual" data-controller="toasters" data-toasters-new-toaster-url-value=""></div>Toaster
Description
Related components
| Used Components | Components where is Used |
|---|---|
| Label |
Usage rules
- ✅ Do
- ❌ Don't
<%= render LooposUi::MainLayout.new do %> <div class="flex flex-col gap-4"> <% args = { title: "Hover or click me", description: "To create a new toast", persistent: true } link_args = { data: { turbo_method: :get }, disabled: true } %> <%= link_to random_toaster_toaster_index_path(type: :informative), **link_args do %> <%= render LooposUi::Toaster.informative(**args) %> <% end %> <%= link_to random_toaster_toaster_index_path(type: :success), **link_args do %> <%= render LooposUi::Toaster.success(**args) %> <% end %> <%= link_to random_toaster_toaster_index_path(type: :warning), **link_args do %> <%= render LooposUi::Toaster.warning(**args) %> <% end %> <%= link_to random_toaster_toaster_index_path(type: :danger), **link_args do %> <%= render LooposUi::Toaster.danger(**args) %> <% end %> <%= render LooposUi::Button.new( href: random_toaster_toaster_index_path, text: "Hover or click me for random toast", tag_options: { "data-turbo-method": :get } ) %> <%= render LooposUi::Button.new( href: clear_toasters_toaster_index_path, text: "Clear toasters", tag_options: { "data-turbo-method": :get } ) %> </div><% end %>No notes provided.
No params configured.
Description
The Toaster component is a notification element that appears at the top of the screen to display important messages to users. It supports different variants for different types of notifications (informative, success, warning, danger) and can include a title, description, and dismissal option.
It uses the HTML Popover API for positioning and animations, and appears at the top of the screen with a slide-down animation (when animated: true).
Arguments
| Property | Default | Description |
|---|---|---|
title |
nil |
Title text of the toaster notification (required) |
description |
nil |
Optional description text below the title |
variant |
:informative |
Visual style of the toaster (:informative, :success, :warning, :danger) |
dismissible |
true |
Whether the toaster can be dismissed via close button |
animated |
true |
Whether to animate the toaster entrance/exit |
timeout |
2000 |
Time in milliseconds before auto-dismissal |
persistent |
false |
If true, disables auto-dismissal timeout |
Variants
Each variant comes with its own icon and styling:
:informative- Blue info icon:success- Green checkmark icon:warning- Yellow exclamation icon:danger- Red X icon
Show a toaster from the Backend
You can render a toaster inline in your view, but more often than not you will want to show them like a notification from the backend, in a controller or service for example.
This can be achieved by streaming the toaster using the stream_toaster_* methods, available through the LooposUi::StreamToaster module.
This module is automatically included in the ApplicationController.
The stream_toaster_* methods are:
stream_toaster(toaster, **options)stream_toaster_success(**options)stream_toaster_warning(**options)stream_toaster_danger(**options)stream_toaster_informative(**options)
The stream_toaster method is the most generic one, and accepts a toaster argument, which is an instance of LooposUi::Toaster.
The other methods are convenience methods that create a LooposUi::Toaster instance with the appropriate variant and then stream it.
You also have helper methods for each variant:
LooposUi::Toaster.success(title: "Operation completed")LooposUi::Toaster.warning(title: "Something went wrong")LooposUi::Toaster.danger(title: "An error occurred")LooposUi::Toaster.informative(title: "Information")# equivalent toLooposUi::Toaster.new(title: "Operation completed", variant: :success)# ...You can also clear all toasters by calling stream_clear_toasters in your controller.
Show a toaster from the Frontend
To show a toaster from the frontend, for example from a Stimulus controller or a React component, you can use the showToaster function.
import showToaster from "@loopos_ui/toaster"// ...showToaster({ title: "Operation completed", description: "The operation was completed successfully", variant: "success", timeout: 2000, persistent: false, dismissible: true, animated: true,})The showToaster function expects a toaster object, which follows the same interface as the LooposUi::Toaster class.