Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Toast Stack Notification Block for Solid

A post scheduler's publishing queue with an Add a toast button: the toasts overlap in a stack of three, open into a list on hover or focus, and the rest wait their turn.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Keep a burst of toasts readable, with this toast stack for Solid with Ark UI. It's the publishing queue of Skeinpost, a social post scheduler, drawn in greys inside a hairline frame with a plus mark on each corner: a top bar and a week of posts. The real Add a toast Shine Button sits on the top bar and cycles four kinds (success, error, warning and info). At the stage's foot end the stack is drawn in place: three toasts that overlap, each a step behind and smaller than the one in front, wearing the look of the catalog's Toast; hover or focus anywhere on the stack and it opens into a list. A foot band says how many are showing and how many wait ("3 showing, 2 waiting") and holds Dismiss all. Press Add a toast and the block hands the same stack to a real toaster through its own queue: at most three are up, the others wait and move up one at a time as you dismiss. It's built from Toast, Button, Shine Button and Guides, with CSS motion only. For publishing tools, dashboards and any app where saves and errors arrive faster than people read.

FAQ

Why is a stack already on the page, and what do I keep?

So you can see the stack without pressing anything: on load it is drawn in place at the stage's foot end, three toasts with two waiting, using the catalog toast's own classes. Add a toast raises the same toasts through a real toaster and the drawn stack stays gone until a reload. In your app keep the toaster, raise, withdraw and the queue helpers (grow, shut), and drop the drawn copy: DrawnToast, the "in-place" state and the ol.

Why does the block keep its own queue of waiting toasts?

The three toasters disagree about what happens to a fourth toast: one queues it, the others tuck the oldest out of sight. The block keeps the queue itself and never has more than three real toasts, so the cap of three, the waiting count and the order a waiting toast moves up are the same on every library. Dismissing a toast, with its close button or with Dismiss all, moves the next one up.

How is the real toast raised on each library?

The block makes its own toaster with createToaster({ max: 3, overlap: true, placement: "bottom-end" }), renders <Toaster toaster={toaster} /> once, and raises a toast with toaster.create({ id, type, title, description, duration }). Its onStatusChange reports "dismissing" when a toast is closed, which is how the queue hears about it.The block wraps the call in raise(note), so the rest of the file doesn't care which library is under it.

Do the toasts time out, and what about hover and focus?

Not in this demo: each toast stays until it is dismissed, so the queue only moves when you move it and nothing disappears before it can be read. The real toaster takes a duration (duration or timeout) and pauses it while the pointer or keyboard focus is on the stack, so setting one is a one-line change. Hovering or focusing the stack opens it into a list on every library; the drawn copy does the same with CSS alone.

Is it accessible?

The real toasts live in the library's live region, which speaks each toast once and never takes focus, so the block's own status line stays quiet and only says what the toasts cannot: that a toast was queued instead of shown. Every toast has a close button. The drawn copy is a list named "Notifications" with a Dismiss button per toast that names it; only the front toast's words are visible until the stack opens, and the others are hidden from keyboard and screen readers until then (focusing the front toast opens the stack, so Tab reaches them). The error icon is the only status colour, and with reduced motion nothing slides.

What stays local?

Everything. Nothing is posted: the week is a drawing, the toasts are typed words at the top of the file (SAMPLES), and the block says so in its header. In your app, raise a toast from the response of your own request, call withdraw(id) when its cause goes away, and keep the queue if you want the same cap on every library.