Toast
A succinct message that is displayed temporarily.
JS (Optional)
This component requires the toast
stimulus controller.
If you want to add toast with JS, you will need the
toast_container_controller
stimulus controller.
See Toast Container With JS for more information.
Anatomy
Toast do |t|t.content dot.titlet.descriptionendend
API Reference
Toast
Name | Type | Default |
---|---|---|
variant: | symbol | :default |
Visual style of the toast. Options: :default | :destructive | ||
side: | symbol | :top |
Controls slide in/out animation direction. Set this to bottom if ToastContainer is set to one of :bottom_center | :bottom_left | :bottom_right . Options: :top | :bottom | ||
duration: | number | 5000 |
The time in milliseconds that should elapse before automatically closing each toast. Setting it to 0 will disable the auto-close feature. | ||
attributes | keyword arguments |
Toast#content
Name | Type | |
---|---|---|
attributes | keyword arguments |
Toast#title
Name | Type | |
---|---|---|
attributes | keyword arguments |
Toast#description
Name | Type | |
---|---|---|
attributes | keyword arguments |
Toast#action
Name | Type | Default |
---|---|---|
as_child: | boolean | false |
When true, merges toast action styling with a custom element passed as block content instead of rendering a default button. | ||
attributes | keyword arguments |
Toast#action_to
Rails button_to helper styled as a toast action button.
Name | Type | Default |
---|---|---|
name | string | nil |
The button text or content to display. | ||
options | string | hash | nil |
URL or options hash for the form submission target. | ||
html_options | hash | nil |
Additional HTML attributes for the form and button elements. |
ToastContainer
Name | Type | Default |
---|---|---|
side: | symbol | :top_center |
Positioning of the toast container on screen. Options: :top_center | :top_left | :top_right | :bottom_center | :bottom_left | :bottom_right | ||
attributes | keyword arguments |
Keyboard Interactions
Key | Description |
---|---|
Tab | Moves focus to the next focusable element. |
Shift+Tab | Moves focus to the previous focusable element. |
Enter | When focus is on the close button, closes the toast. |
Space | When focus is on the close button, closes the toast. |
Esc | When focus is on a Toast , closes the toast. |
Examples
Toast Container With Flash
# some_controller.rbdef createredirect_to path,notice: {title: "Uh oh! Something went wrong.",description: "There was a problem with your request."})end# layouts/application.html.erb<%= render ToastContainer.new(id: "toast-container") do %><% flash.each do |flash_type, flash_content| %><%= render Toast.new(variant: flash_type == "notice" ? :default : :destructive) do |t| %><%= t.content do %><% if flash_content.is_a?(Hash) %><% flash_content = flash_content.transform_keys(&:to_sym) %><%= t.title { flash_content["title"] } %><%= t.description { flash_content["description"] } %><% else %><%= t.title { flash_content } %><% end %><% end %><% end %><% end %><% end %>
<form action="/examples/toast" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="JX_EyEw3Rn4YhvlUHlkKiCQkIFTWCO1KykfmcDOdtVSGsG0-Y6TR8VVruf1jvuWDPg6TxWlpJMw4imP3oHa0wA" autocomplete="off" /> <button type="submit" data-shadcn-phlexcomponents="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 h-9 px-4 py-2 has-[>svg]:px-3">Show toast</button></form>
Toast Container With JS
<%= render Button.new(id: "show-toast", variant: :outline) { "Show toast" } %>
<button type="button" id="show-toast" data-shadcn-phlexcomponents="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 h-9 px-4 py-2 has-[>svg]:px-3">Show toast</button>
// application.jsconst button = document.querySelector('#show-toast')const toastContainer =window.Stimulus.getControllerForElementAndIdentifier(document.querySelector('#toast-container'),'toast-container',)button.addEventListener('click', () => {toastContainer.add({title: 'Uh oh! Something went wrong.',description: 'There was a problem with your request.',})})
Toast Container With JS (Custom HTML)
<%= render Button.new(id: "show-toast-custom", variant: :outline) { "Show toast" } %>
<button type="button" id="show-toast-custom" data-shadcn-phlexcomponents="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 h-9 px-4 py-2 has-[>svg]:px-3">Show toast</button>
// application.jsconst button = document.querySelector('#show-toast-custom')const toastContainer =window.Stimulus.getControllerForElementAndIdentifier(document.querySelector('#toast-container'),'toast-container',)button.addEventListener('click', () => {toastContainer.addToast({variant: 'destructive',title: '<div class="text-lg">This is a custom title</div>',description:'<ul class="list-disc ml-4"><li>item 1</li><li>item 2</li><ul>',action:'<button data-controller="try-again" data-action="try-again#tryAgain">Try again</button>',duration: 10000,})})
Toast Container With Turbo Stream
# some_controller.rbdef createrespond_to do |format|format.turbo_stream {flash.now[:notice] = {title: "Uh oh! Something went wrong.",description: "There was a problem with your request."}}endend# some_controller/create.turbo_stream.erb<%= turbo_stream.prepend "toast-container", partial: "layouts/flash" %># layouts/application.html.erb<%= render ToastContainer.new(id:"toast-container") do %><%= render "layouts/flash" %><% end %># layouts/flash.html.erb<% flash.each do |flash_type, flash_content| %><%= render Toast.new(variant: flash_type == "notice" ? :default : :destructive) do |t| %><%= t.content do %><% if flash_content.is_a?(Hash) %><% flash_content = flash_content.transform_keys(&:to_sym) %><%= t.title { flash_content[:title] } %><%= t.description { flash_content[:description] } %><% else %><%= t.title { flash_content } %><% end %><% end %><% end %><% end %>
<form action="/examples/toast_turbo_stream" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="g7QkNxczFUt8xMEoE6jUyHkuNY6XA5et6uB5Z4BUnFpvi2V_HJzuYbdwE6HbJFQexkjuUodOPkYtlvBdn7ZoXA" autocomplete="off" /> <button type="submit" data-shadcn-phlexcomponents="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 h-9 px-4 py-2 has-[>svg]:px-3">Show toast</button></form>
On This Page