"use client" import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" import { X } from "lucide-react" import { cn } from "@/lib/utils" 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 duration-300 ease-in-out transform", { variants: { variant: { default: "border bg-background text-foreground", destructive: "destructive group border-destructive bg-destructive text-destructive-foreground", success: "border-green-200 bg-green-50 text-green-900", warning: "border-yellow-200 bg-yellow-50 text-yellow-900", }, }, defaultVariants: { variant: "default", }, } ) const Toast = React.forwardRef< HTMLDivElement, React.HTMLAttributes & VariantProps & { onOpenChange?: (open: boolean) => void open?: boolean } >(({ className, variant, onOpenChange, open, ...props }, ref) => { const [isVisible, setIsVisible] = React.useState(true) const [isClosing, setIsClosing] = React.useState(false) // 處理關閉動畫 const handleClose = React.useCallback(() => { if (isClosing) return // 防止重複觸發 setIsClosing(true) setIsVisible(false) // 等待動畫完成後調用 onOpenChange setTimeout(() => { onOpenChange?.(false) }, 300) // 與 CSS 動畫時間一致 }, [onOpenChange, isClosing]) // 處理外部觸發的關閉 React.useEffect(() => { if (open === false && !isClosing) { handleClose() } }, [open, isClosing, handleClose]) return (
) }) Toast.displayName = "Toast" const ToastAction = React.forwardRef< HTMLButtonElement, React.ButtonHTMLAttributes >(({ className, ...props }, ref) => ( )) ToastClose.displayName = "ToastClose" const ToastTitle = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
)) ToastTitle.displayName = "ToastTitle" const ToastDescription = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
)) ToastDescription.displayName = "ToastDescription" type ToastProps = React.ComponentProps type ToastActionElement = React.ReactElement const ToastProvider = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
)) ToastProvider.displayName = "ToastProvider" const ToastViewport = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
)) ToastViewport.displayName = "ToastViewport" export { type ToastProps, type ToastActionElement, Toast, ToastAction, ToastClose, ToastTitle, ToastDescription, ToastProvider, ToastViewport, }