{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"ui-toast","type":"registry:component","title":"Toast","description":"Application toast provider and hook for transient notifications.","version":"1.0.0","status":"ga","files":[{"path":"src/components/ui/toast.tsx","type":"registry:component","content":"'use client'\n\nimport * as React from 'react'\nimport * as ToastPrimitives from '@radix-ui/react-toast'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\nimport { X } from 'lucide-react'\n\nexport interface Toast {\n  id: string\n  title?: string\n  description?: string\n  variant?: 'default' | 'destructive'\n}\n\ninterface ToastContextValue {\n  toasts: Toast[]\n  addToast: (toast: Omit<Toast, 'id'>) => void\n  removeToast: (id: string) => void\n}\n\nconst ToastContext = React.createContext<ToastContextValue | undefined>(undefined)\n\nexport function ToastProvider({ children }: { children: React.ReactNode }) {\n  const [toasts, setToasts] = React.useState<Toast[]>([])\n\n  const addToast = React.useCallback((toast: Omit<Toast, 'id'>) => {\n    const id = crypto.randomUUID()\n    setToasts((prev) => [...prev, { ...toast, id }])\n    // Auto-dismiss after 5 seconds\n    setTimeout(() => {\n      setToasts((prev) => prev.filter((t) => t.id !== id))\n    }, 5000)\n  }, [])\n\n  const removeToast = React.useCallback((id: string) => {\n    setToasts((prev) => prev.filter((t) => t.id !== id))\n  }, [])\n\n  return (\n    <ToastContext.Provider value={{ toasts, addToast, removeToast }}>\n      <ToastPrimitives.Provider swipeDirection=\"right\">\n        {children}\n        {toasts.map((toast) => (\n          <ToastRoot\n            key={toast.id}\n            open\n            variant={toast.variant}\n            duration={5000}\n            onOpenChange={(open) => {\n              if (!open) removeToast(toast.id)\n            }}\n          >\n            <div className=\"grid gap-1\">\n              {toast.title && <ToastTitle>{toast.title}</ToastTitle>}\n              {toast.description && (\n                <ToastDescription>{toast.description}</ToastDescription>\n              )}\n            </div>\n            <ToastClose>\n              <X className=\"h-4 w-4\" />\n            </ToastClose>\n          </ToastRoot>\n        ))}\n        <ToastViewport />\n      </ToastPrimitives.Provider>\n    </ToastContext.Provider>\n  )\n}\n\nexport function useToast() {\n  const context = React.useContext(ToastContext)\n  if (!context) {\n    throw new Error('useToast must be used within a ToastProvider')\n  }\n  return {\n    toast: context.addToast,\n    dismiss: context.removeToast,\n    toasts: context.toasts,\n  }\n}\n\nconst toastVariants = cva(\n  'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all',\n  {\n    variants: {\n      variant: {\n        default: 'border bg-background text-foreground',\n        destructive:\n          'destructive border-destructive bg-destructive text-destructive-foreground',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n    },\n  },\n)\n\nconst ToastViewport = React.forwardRef<\n  React.ComponentRef<typeof ToastPrimitives.Viewport>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Viewport\n    ref={ref}\n    className={cn(\n      'fixed bottom-0 right-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',\n      className,\n    )}\n    {...props}\n  />\n))\nToastViewport.displayName = ToastPrimitives.Viewport.displayName\n\nconst ToastRoot = React.forwardRef<\n  React.ComponentRef<typeof ToastPrimitives.Root>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &\n    VariantProps<typeof toastVariants>\n>(({ className, variant, ...props }, ref) => (\n  <ToastPrimitives.Root\n    ref={ref}\n    className={cn(\n      toastVariants({ variant }),\n      'data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-bottom-full data-[state=open]:sm:slide-in-from-bottom-2',\n      className,\n    )}\n    {...props}\n  />\n))\nToastRoot.displayName = ToastPrimitives.Root.displayName\n\nconst ToastClose = React.forwardRef<\n  React.ComponentRef<typeof ToastPrimitives.Close>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Close\n    ref={ref}\n    className={cn(\n      'absolute right-1 top-1 rounded-md p-1 text-foreground/60 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none group-hover:opacity-100',\n      className,\n    )}\n    toast-close=\"\"\n    {...props}\n  />\n))\nToastClose.displayName = ToastPrimitives.Close.displayName\n\nconst ToastTitle = React.forwardRef<\n  React.ComponentRef<typeof ToastPrimitives.Title>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Title\n    ref={ref}\n    className={cn('text-sm font-semibold', className)}\n    {...props}\n  />\n))\nToastTitle.displayName = ToastPrimitives.Title.displayName\n\nconst ToastDescription = React.forwardRef<\n  React.ComponentRef<typeof ToastPrimitives.Description>,\n  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>\n>(({ className, ...props }, ref) => (\n  <ToastPrimitives.Description\n    ref={ref}\n    className={cn('text-sm opacity-90', className)}\n    {...props}\n  />\n))\nToastDescription.displayName = ToastPrimitives.Description.displayName\n"}]}