asafefe.dev

Toast Stack

New

A provider and useToast hook. Toasts stack into a deck, fan out on hover, and swipe away to dismiss.

motionlucide-reactutils@soultel/use-reduced-motion-safe

hover the stack, swipe to dismiss

    Installation

    $ pnpm dlx shadcn@latest add @soultel/toast-stack

    No namespace set up? npx shadcn@latest add https://asafefe.dev/r/toast-stack.json works too.

    Manual installation
    1. 1. Install the dependencies.
      terminal1 lines
      npm install motion lucide-react
    2. 2. Copy the source from the Code tab into components/toast-stack.tsx.

    Usage

    example.tsx14 lines
    // layout.tsx
    import { ToastProvider } from "@/components/toast-stack"
    
    export default function Layout({ children }: { children: React.ReactNode }) {
      return <ToastProvider position="bottom-right">{children}</ToastProvider>
    }
    
    // anywhere inside
    import { useToast } from "@/components/toast-stack"
    
    export function SaveButton() {
      const { toast } = useToast()
      return <button onClick={() => toast.success("Changes saved", { description: "Your profile is up to date." })}>Save</button>
    }

    Props

    PropTypeDefaultDescription
    position"bottom-right" | "bottom-center" | "top-right" | ..."bottom-right"Corner of the viewport the stack sits in.
    durationnumber4000Default time on screen in ms. Timers pause on hover, focus, and hidden tabs.
    visibleToastsnumber3Toasts shown in the deck. The rest wait behind.
    gapnumber10Space between expanded toasts in px.
    classNamestring-Viewport classes. "absolute" keeps the stack inside a relative parent.
    toast(title, options)=> id-options: description, variant, duration, action, id. Also toast.success, toast.error, toast.info.
    dismiss(id?)void-Dismiss one toast, or all of them without an id.