Toast stack

Toasts that pile up like cards. A new one slides in at the front and pushes the rest back, each a little smaller and tucked under. Hover the pile and it fans out so you can read them all. Flick one sideways and it goes with your finger, turning as it leaves.

    Installation

    Terminalbash
    npx @neelshha/ui@latest add toast-stack

    Usage

    page.tsxtsx
    import { ToastStack, toast } from "@/components/ui/toast-stack";
    
    // Once, near the root of the app.
    <ToastStack />
    
    // Then from anywhere.
    toast("Changes saved", { tone: "success" });

    The stack and toast share a store, so a toast can come from an event handler, a fetch callback, or anywhere else, without a hook or a provider.

    Loading, then done

    toast returns an id. Send the same id again to change that toast in place, the way the Upload button above does.

    page.tsxtsx
    const id = toast("Uploading 3 files", { tone: "loading" });
    await upload(files);
    toast("3 files uploaded", { id, tone: "success" });

    Positions

    Toasts come in from the edge they sit on, and a flick sends them off toward it.

      page.tsxtsx
      <ToastStack position="top-center" />

      Keyboard

      Alt+T moves focus to the main stack, and it fans out while focus is in it. Tab goes through each toast's buttons, and Escape dismisses the one with focus. When the last one goes, focus goes back to where it was. Screen readers hear new toasts without being cut off.

      API

      A toast's clock waits while the stack is fanned out and while the tab is hidden, so nothing goes before it's been seen. dismissToast(id) sends one away, and dismissToast() sends them all.

      toast(title, options)

      PropTypeDefaultDescription
      descriptionReactNodeA second line, under the title.
      tone"neutral" | "success" | "error" | "loading""neutral"The icon and its colour. A loading toast stays until it changes.
      action{ label: string; onClick: () => void }One button, like Undo. Pressing it dismisses the toast too.
      idstringSend a toast with the same id to change it in place. Its clock starts over.
      durationnumber4000Milliseconds on screen once it's in view. Infinity keeps it until it's dismissed.
      stackstring"default"The stack that shows it, for a page with more than one.

      ToastStack

      Other props go to the section. --ns-toasts-width and --ns-toasts-offset set its width and its distance from the edges.

      PropTypeDefaultDescription
      position"bottom-right" | "bottom-center" | "bottom-left" | "top-right" | "top-center" | "top-left""bottom-right"Where on the screen it sits. Toasts flick away toward its side, or either way in the middle.
      visiblenumber3How many show at once. Older ones wait out of sight until those in front go.
      expandbooleanfalseKeeps the stack fanned out, not just on hover or focus.
      stackstring"default"Shows only the toasts sent to this stack.