{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "custom-toast", "type": "registry:ui", "title": "Custom Toast", "description": "Beautiful toast with progress bar and colored variants.", "dependencies": [ "sonner", "lucide-react" ], "registryDependencies": [ "button" ], "files": [ { "path": "registry/new-york/ui/custom-toast.tsx", "content": "\"use client\"\n\nimport {\n CircleCheckIcon,\n InfoIcon,\n OctagonXIcon,\n TriangleAlertIcon,\n XIcon,\n} from \"lucide-react\"\nimport { useEffect, useState } from \"react\"\nimport { toast } from \"sonner\"\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\n\ntype ToastType = \"success\" | \"error\" | \"warning\" | \"info\"\n\ninterface CustomToastProps {\n id: string | number\n type: ToastType\n message: string\n description?: string\n duration?: number\n}\n\nconst config: Record<\n ToastType,\n { icon: React.ElementType; progressColor: string; iconColor: string }\n> = {\n success: {\n icon: CircleCheckIcon,\n progressColor: \"bg-green-500\",\n iconColor: \"text-green-500\",\n },\n error: {\n icon: OctagonXIcon,\n progressColor: \"bg-red-500\",\n iconColor: \"text-red-500\",\n },\n warning: {\n icon: TriangleAlertIcon,\n progressColor: \"bg-amber-500\",\n iconColor: \"text-amber-500\",\n },\n info: {\n icon: InfoIcon,\n progressColor: \"bg-blue-500\",\n iconColor: \"text-blue-500\",\n },\n}\n\nexport function CustomToast({\n id,\n type,\n message,\n description,\n duration = 4000,\n}: CustomToastProps) {\n const [progress, setProgress] = useState(100)\n const { icon: Icon, progressColor, iconColor } = config[type]\n\n useEffect(() => {\n const startTime = Date.now()\n\n const interval = setInterval(() => {\n const elapsed = Date.now() - startTime\n const remaining = Math.max(0, 100 - (elapsed / duration) * 100)\n setProgress(remaining)\n\n if (remaining === 0) {\n clearInterval(interval)\n toast.dismiss(id)\n }\n }, 16)\n\n return () => clearInterval(interval)\n }, [duration, id])\n\n return (\n \n \n\n
\n

{message}

\n {description && (\n

\n {description}\n

\n )}\n
\n\n toast.dismiss(id)}\n className=\"size-6 shrink-0 opacity-70 hover:opacity-100\"\n >\n \n \n\n {/* Progress bar */}\n
\n \n
\n \n )\n}\n", "type": "registry:ui" } ] }