"use client"; import * as React from "react"; import { CheckCircle2, AlertTriangle, Info, X, XCircle } from "lucide-react"; import { cn } from "@/lib/utils"; type ToastKind = "success" | "error" | "info" | "warning"; interface ToastItem { id: number; kind: ToastKind; title: string; description?: string; duration: number; } type Listener = (items: ToastItem[]) => void; let items: ToastItem[] = []; let seq = 1; const listeners = new Set(); function publish() { for (const l of listeners) l([...items]); } function push(kind: ToastKind, title: string, description?: string, duration = 4200) { const id = seq++; items = [...items, { id, kind, title, description, duration }]; publish(); if (duration > 0) setTimeout(() => dismiss(id), duration); return id; } export function dismiss(id: number) { items = items.filter((t) => t.id !== id); publish(); } export const toast = { success: (title: string, description?: string) => push("success", title, description), error: (title: string, description?: string) => push("error", title, description, 6000), info: (title: string, description?: string) => push("info", title, description), warning: (title: string, description?: string) => push("warning", title, description, 5000), }; const ICONS: Record = { success: , error: , info: , warning: , }; export function Toaster() { const [list, setList] = React.useState([]); React.useEffect(() => { listeners.add(setList); return () => { listeners.delete(setList); }; }, []); if (list.length === 0) return null; return (
{list.map((t) => (
{ICONS[t.kind]}

{t.title}

{t.description ?

{t.description}

: null}
))}
); }