Animated Toast Stack
beui/animated-toast-stackFreeComponent
Stacked toasts with status morphs, swipe dismissal, actions and layout-aware motion.
Install it
npx shadcn@latest add https://beui.dev/r/animated-toast-stack.jsonSource
1"use client";2// beui.dev/components/motion/animated-toast-stack34import {5 AlertCircle,6 Bell,7 Check,8 Info,9 LoaderCircle,10 X,11 type LucideIcon,12} from "lucide-react";13import {14 AnimatePresence,15 motion,16 useReducedMotion,17 type Transition,18} from "motion/react";19import {20 memo,21 useCallback,22 useEffect,23 useMemo,24 useRef,25 useState,26 type ReactNode,27} from "react";28import { createPortal } from "react-dom";29import { EASE_OUT } from "@/lib/ease";30import { cn } from "@/lib/utils";3132export type ToastStatus = "neutral" | "info" | "loading" | "success" | "error";33export type ToastPosition =34 | "top-left"35 | "top-center"36 | "top-right"37 | "bottom-left"38 | "bottom-center"39 | "bottom-right";4041export type AnimatedToastAction = {42 label: ReactNode;43 onClick: (toast: AnimatedToast) => void;44};4546export type AnimatedToast = {47 id: string;48 title: ReactNode;49 description?: ReactNode;50 status?: ToastStatus;51 icon?: ReactNode;52 action?: AnimatedToastAction;53 duration?: number;54 dismissible?: boolean;55 createdAt?: number;56};5758export type ToastInput = Omit<AnimatedToast, "id" | "createdAt"> & {59 id?: string;60};6162export type ToastClassNames = {63 root?: string;64 item?: string;65 surface?: string;66 iconWrap?: string;67 content?: string;68 title?: string;69 description?: string;70 action?: string;71 close?: string;72 progress?: string;73};7475export interface AnimatedToastStackProps {76 toasts: AnimatedToast[];77 onDismiss?: (id: string) => void;78 position?: ToastPosition;79 placement?: "static" | "fixed" | "absolute";80 fixed?: boolean;81 portal?: boolean;82 portalRoot?: Element | null;83 maxVisible?: number;84 className?: string;85 classNames?: ToastClassNames;86 icons?: Partial<Record<ToastStatus, ReactNode>>;87 renderToast?: (toast: AnimatedToast) => ReactNode;88}8990export interface UseAnimatedToastStackOptions {91 initialToasts?: ToastInput[];92 defaultDuration?: number;93 limit?: number;94}9596const STACK_SPRING: Transition = {97 type: "spring",98 stiffness: 420,99 damping: 34,100 mass: 0.75,101};102103const CONTENT_TRANSITION = {104 duration: 0.28,105 ease: EASE_OUT,106} as const;107108const STATUS_ICON: Record<ToastStatus, LucideIcon> = {109 neutral: Bell,110 info: Info,111 loading: LoaderCircle,112 success: Check,113 error: AlertCircle,114};115116const STATUS_CLASS: Record<ToastStatus, string> = {117 neutral: "text-muted-foreground bg-primary/[0.05]",118 info: "text-primary bg-primary/10",119 loading: "text-primary bg-primary/10",120// … truncated
What it pulls in
npm packages
Files it writes
More from beui
All 104 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Swap Bluraction-swap-blur | beui | Components | Free | 3 deps · 4 files | |
| Action Swap Cascadeaction-swap-cascade | beui | Components | Free | 3 deps · 4 files | |
| Action Swap Rollaction-swap-roll | beui | Components | Free | 3 deps · 4 files | |
| Agent Activityagent-activity | beui | Components | Free | 4 deps · 9 files | |
| Agent Loading States Agent Progressagent-progress | beui | Components | Free | 3 deps · 3 files | |
| AI Sidebarai-sidebar | beui | Components | Free | 4 deps · 5 files | |
| Animated Badgeanimated-badge | beui | Components | Free | 4 deps · 3 files | |
| Number Animation Animated Numberanimated-number | beui | Components | Free | 3 deps · 3 files |
