Toasts

The toaster is a single <ol data-moly-toaster>, at the bottom of this page so the corner can be state driven. In a real application it belongs in the layout. A behavior measures each toast, stacks them, runs the timers and handles the swipe. Everything you see is CSS driven by the custom properties it writes, so the page owns the look. Hover the stack to expand it and pause every timer, drag a toast toward the nearest edge to dismiss it, or press Escape.

From JavaScript

toast() is imperative and works from anywhere. These buttons go through a five line Stimulus controller.

From a Rails flash

These post, set flash and redirect. The layout renders the flash as list items inside the toaster, and the behavior adopts them on connect with timers and swipe intact. No JavaScript is involved, and notice and alert land as success and error.

Where it sits

The corner is the value of the attribute the behavior is registered on, and here it comes from herb:state. Changing it re-places the whole stack, because the behavior is handed the new value and the stylesheet anchors off the same attribute.

What the behavior writes

Nothing here is styled by the package. Each toast carries its place in the stack, the distance it should sit from the anchored edge and its collapsed scale, and the stylesheet turns those into a translate.

Property Holds
--moly-toast-index its place in the stack, 0 at the front
--moly-toast-y how far it sits from the anchored edge, already signed
--moly-toast-scale the collapsed scale, 1 once expanded
--moly-toast-swipe-x the live swipe offset
--moly-toaster-front-height the front toast's measured height
--moly-toaster-gap the gap between toasts

The same package ships the drawer, and both are registered by one install() call against the Herb runtime.