Toaster
The region that stacks and manages toast notifications.
Installation
Included in poetry-ui — available as
poetry_toaster
the moment you've installed Poetry,
with no per-component step. To own the source and edit it, copy it into your app:
bin/rails g poetry:add toaster
Default
-
Changes saved
-
Event scheduled
<div class="h-56 w-full overflow-hidden rounded-lg border contain-content">
<%= poetry_toaster do %>
<%= poetry_toast(variant: :success, duration: 0) do |toast| %>
<% toast.with_title { "Changes saved" } %>
<% end %>
<%= poetry_toast(duration: 0) do |toast| %>
<% toast.with_title { "Event scheduled" } %>
<% end %>
<% end %>
</div>
Positions
<%# Six live toaster regions pinned to the REAL viewport - each
poetry_toast_trigger stamps its <template>'s toast into the region
addressed by toaster: (the first-party no-round-trip delivery path);
duration: 4000 auto-dismisses. Real layouts run ONE toaster per page. %>
<div>
<div class="grid w-fit grid-cols-3 gap-2">
<% %i[top-left top-center top-right bottom-left bottom-center bottom-right].each do |position| %>
<%= poetry_toast_trigger(template: "toast-demo-#{position}",
toaster: "toaster-demo-#{position}") do %>
<%= position.to_s.tr("-", " ").capitalize %>
<% end %>
<% end %>
</div>
<% %i[top-left top-center top-right bottom-left bottom-center bottom-right].each do |position| %>
<%= poetry_toaster(position: position, id: "toaster-demo-#{position}") %>
<template id="toast-demo-<%= position %>">
<%= poetry_toast(duration: 4000) do |toast| %>
<% toast.with_title { "#{position.to_s.tr("-", " ").capitalize} toast" } %>
<% end %>
</template>
<% end %>
</div>
API
Poetry::Ui::Toaster::Component — options are
constructor keywords (the poetry_* helper forwards them);
slots are composed inside the block. Generated from the gem's source documentation.
| Option | Type | Details | Description |
|---|---|---|---|
| position: | Symbol | one of: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right; defaults to :"bottom-right" |
The stack's corner - set here, not per toast; each toast's slide direction follows it. |
| hotkey: | String | defaults to "F8" |
The keyboard shortcut that focuses the most recent toast. |
| limit: | Integer | defaults to 3 |
The maximum visible toasts; overflow queues hidden with timers held. |
Styling
Every part carries a stable data-slot attribute — target
[data-slot=…] from your own CSS to restyle it. State rides
data attributes on the parts below. This contract is verified against rendered DOM in CI.
| Part | Description |
|---|---|
| [data-slot=toaster] | The toast viewport itself (<ol>, role=region, data-turbo-permanent) - the corner geometry and the Turbo Stream append target ride here |
State attributes
| Part | Attribute | Condition | Values |
|---|---|---|---|
| toaster | data-position | always - the corner; each toast's slide direction keys off it via group/toaster | top-left · top-center · top-right · bottom-left · bottom-center · bottom-right |
| toaster | data-poetry-top-layer | always - the dismissal layer exempts presses here, so clicking a toast never dismisses the overlay under it | — |
Wiring
The Stimulus surface each element carries — declared in the component, verified against rendered DOM in CI. Bare actions fire on the element's default event.
| Element | Controller | Wiring |
|---|---|---|
| root | poetry--core--toaster | registers · value hotkey · value limit · value position |