Toast

An opinionated toast component.

Examples

Types

Click any to spawn a toast.

About

Trigger toasts from the server with Turbo Streams or from JavaScript via window.RubyUI.toast.*. Heavily inspired by the original sonner.

Mount

# In application_layout.rb (Phlex), once globally:
render RubyUI::ToastRegion.new

# Pass flash to render Rails flash on initial load:
render RubyUI::ToastRegion.new(flash: helpers.flash.to_h)

Position

Use the position prop to change where toasts mount.

Server-pushed (Turbo Stream)

Append a toast to the global region from any controller.

# Option A — custom Turbo Stream action (compact):
render turbo_stream: turbo_stream.action(
	:toast,
	target: "ruby-ui-toaster",
	variant: :success,
	title: "Saved",
	description: "Project updated."
)

# Option B — append a fully-rendered ToastItem (for Action / Cancel slots):
render turbo_stream: turbo_stream.append("ruby-ui-toaster") {
	render RubyUI::ToastItem.new(variant: :success) do
		render RubyUI::ToastIcon.new(variant: :success)
		render RubyUI::ToastTitle.new { "Saved" }
		render RubyUI::ToastDescription.new { "Project updated." }
	end
}

JavaScript API

Hotwire-friendly: window.RubyUI.toast.* is sugar over a CustomEvent dispatch. Either path works.

// Sugar:
RubyUI.toast.success("Saved", { description: "Project updated." })
RubyUI.toast.error("Boom")
RubyUI.toast.info("Heads up")
RubyUI.toast.warning("Storage almost full")
RubyUI.toast.loading("Working...")
RubyUI.toast.dismiss(id)              // no-arg: dismiss all
RubyUI.toast.promise(p, { loading, success, error })

// Equivalent CustomEvent (any source can dispatch this):
window.dispatchEvent(new CustomEvent("ruby-ui:toast", {
  detail: { variant: "success", title: "Saved", description: "..." }
}))

Installation

Components

ComponentBuilt usingSource
ToastPhlex
ToastActionPhlex
ToastCancelPhlex
ToastClosePhlex
ToastDescriptionPhlex
ToastDocsPhlex
ToastIconPhlex
ToastItemPhlex
ToastRegionPhlex
ToastTitlePhlex
ToastControllerStimulus JS
ToasterControllerStimulus JS

API Reference

Toaster (Region)

PropDefaultValuesDescription
position:bottom_right:top_left | :top_center | :top_right | :bottom_left | :bottom_center | :bottom_rightWhere the toaster mounts on the viewport.
expandfalseBooleanAlways show items expanded (no stack peek).
max3IntegerMax visible toasts before oldest auto-evicts.
duration4000Integer (ms)Default lifetime per toast. Pass 0 or Infinity to disable auto-dismiss.
gap14Integer (px)Spacing between toasts when expanded.
offset24Integer (px)Distance from the viewport edge.
theme:system:system | :light | :darkColor scheme override.
rich_colorsfalseBooleanEnable variant-tinted backgrounds.
close_buttonfalseBooleanRender an X button in every toast (top-right).
hotkey%w[alt t]Array<String>Keyboard shortcut to focus the first toast.
dir:ltr:ltr | :rtlText direction.
flashnilHash | nilPass `helpers.flash.to_h` to render Rails flash on initial load.

ToastItem

PropDefaultValuesDescription
variant:default:default | :success | :error | :warning | :info | :loadingVisual + a11y role + icon.
idnilStringDOM id; auto-generated when not provided.
durationnilInteger | nilOverride the Region default. nil inherits.
dismissibletrueBooleanAllow Escape, swipe, X, and force-dismiss to close.
invertfalseBooleanInvert background/foreground (light-on-dark in light theme).
on_dismissnilStringStimulus action descriptor fired when the user dismisses.
on_auto_closenilStringStimulus action descriptor fired when the timer expires.

JS API options

Second argument to RubyUI.toast.<variant>(message, options) or ruby-ui:toast CustomEvent detail.

PropDefaultValuesDescription
titleStringHeadline text. Falls back to the first positional argument.
descriptionStringSecondary line under the title.
duration(Region default)Number | Infinityms before auto-dismiss. Infinity = sticky.
action{ label, onClick }Primary action button rendered inside the toast.
cancel{ label, onClick }Secondary dismiss button.
closeButtonfalseBooleanForce an X close button on this toast.
position(Region default)StringPer-toast position override (changes Region's data-position before append).
id(auto)StringSet a stable id (used by .dismiss(id) and .promise).
dismissibletrueBooleanDisable Escape / swipe / dismiss-all for this toast.
classNameStringExtra classes appended to the rendered <li>.