"use client"; import * as React from "react"; import * as ToastPrimitives from "@radix-ui/react-toast"; import { cva, type VariantProps } from "class-variance-authority"; import { X } from "lucide-react"; import { cn } from "@/lib/utils"; const ToastProvider = ToastPrimitives.Provider; const ToastViewport = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); ToastViewport.displayName = ToastPrimitives.Viewport.displayName; const toastVariants = cva( "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", { variants: { variant: { default: "border bg-background text-foreground", destructive: "destructive group border-destructive bg-destructive text-destructive-foreground", }, }, defaultVariants: { variant: "default", }, } ); const Toast = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & VariantProps >(({ className, variant, ...props }, ref) => { return ( ); }); Toast.displayName = ToastPrimitives.Root.displayName; const ToastAction = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); ToastAction.displayName = ToastPrimitives.Action.displayName; const ToastClose = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); ToastClose.displayName = ToastPrimitives.Close.displayName; const ToastTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); ToastTitle.displayName = ToastPrimitives.Title.displayName; const ToastDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); ToastDescription.displayName = ToastPrimitives.Description.displayName; type ToastProps = React.ComponentPropsWithoutRef; type ToastActionElement = React.ReactElement; interface ToastState { toasts: Array<{ id: string; title?: string; description?: string; action?: ToastActionElement; variant?: "default" | "destructive"; }>; } const toastState: ToastState = { toasts: [] }; const listeners: Array<() => void> = []; function dispatch() { listeners.forEach((listener) => listener()); } export function toast({ title, description, variant = "default", }: { title?: string; description?: string; variant?: "default" | "destructive"; }) { const id = Math.random().toString(36).substring(2, 9); toastState.toasts.push({ id, title, description, variant }); dispatch(); setTimeout(() => { toastState.toasts = toastState.toasts.filter((t) => t.id !== id); dispatch(); }, 5000); } function useToastState() { const [state, setState] = React.useState(toastState); React.useEffect(() => { const listener = () => setState({ ...toastState }); listeners.push(listener); return () => { const index = listeners.indexOf(listener); if (index > -1) listeners.splice(index, 1); }; }, []); return state; } function Toaster() { const state = useToastState(); return ( {state.toasts.map((t) => (
{t.title && {t.title}} {t.description && {t.description}}
))}
); } export { type ToastProps, type ToastActionElement, ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction, Toaster, };