{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "rich-popover",
  "type": "registry:block",
  "title": "Rich popover",
  "description": "Rich popover",
  "files": [
    {
      "path": "components/usages/richpopoverusage.tsx",
      "content": "\"use client\";\n\nimport { YoutubeIcon } from \"@/registry/open-source/icons/youtube\";\nimport RichPopover from \"@/registry/open-source/rich-popover\";\n\nexport default function RichPopoverDemo() {\n\treturn (\n\t\t<div className=\"flex items-center justify-center p-6\">\n\t\t\t<div className=\"max-w-2xl space-y-4 text-base leading-relaxed\">\n\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\tOpenAI has just announced their latest breakthrough in artificial\n\t\t\t\t\tintelligence\n\t\t\t\t\t<RichPopover\n\t\t\t\t\t\ttrigger={\n\t\t\t\t\t\t\t<span className=\"bg-background mx-2 inline-flex size-8 cursor-pointer items-center justify-center rounded-md border align-middle\">\n\t\t\t\t\t\t\t\t<YoutubeIcon className=\"h-4 w-4 fill-red-600\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitle=\"Introducing GPT-5\"\n\t\t\t\t\t\tdescription={\n\t\t\t\t\t\t\t'\"GPT-5 features state-of-the-art performance across coding, math, writing assistance, health, visual perception, and more. Use GPT-5 to build websites, create apps, and tap into its improved writing capabilities to help with everyday tasks like reports, emails, and editing.\"'\n\t\t\t\t\t\t}\n\t\t\t\t\t\thref=\"https://www.youtube.com/watch?v=boJG84Jcf-4\"\n\t\t\t\t\t\tactionLabel=\"Watch announcement\"\n\t\t\t\t\t\tactionHref=\"https://www.youtube.com/watch?v=boJG84Jcf-4\"\n\t\t\t\t\t\tmeta=\"0:00–2:15\"\n\t\t\t\t\t/>\n\t\t\t\t\tmarking a significant leap forward in AI capabilities. This new\n\t\t\t\t\tmodel represents the most advanced language model ever created,\n\t\t\t\t\twith unprecedented performance across multiple domains including\n\t\t\t\t\tcoding, mathematics, and creative writing.\n\t\t\t\t</p>\n\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\tGPT-5&apos;s enhanced capabilities extend beyond traditional text\n\t\t\t\t\tprocessing to include improved visual perception and\n\t\t\t\t\thealth-related assistance, making it a versatile tool for both\n\t\t\t\t\tprofessional and personal use. The model is now rolling out to\n\t\t\t\t\tall users, democratizing access to cutting-edge AI technology.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/richpopoverusage.tsx",
      "content": "\"use client\";\n\nimport { YoutubeIcon } from \"@/registry/open-source/icons/youtube\";\nimport RichPopover from \"@/registry/open-source/rich-popover\";\n\nexport default function RichPopoverDemo() {\n\treturn (\n\t\t<div className=\"flex items-center justify-center p-6\">\n\t\t\t<div className=\"max-w-2xl space-y-4 text-base leading-relaxed\">\n\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\tOpenAI has just announced their latest breakthrough in artificial\n\t\t\t\t\tintelligence\n\t\t\t\t\t<RichPopover\n\t\t\t\t\t\ttrigger={\n\t\t\t\t\t\t\t<span className=\"bg-background mx-2 inline-flex size-8 cursor-pointer items-center justify-center rounded-md border align-middle\">\n\t\t\t\t\t\t\t\t<YoutubeIcon className=\"h-4 w-4 fill-red-600\" />\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitle=\"Introducing GPT-5\"\n\t\t\t\t\t\tdescription={\n\t\t\t\t\t\t\t'\"GPT-5 features state-of-the-art performance across coding, math, writing assistance, health, visual perception, and more. Use GPT-5 to build websites, create apps, and tap into its improved writing capabilities to help with everyday tasks like reports, emails, and editing.\"'\n\t\t\t\t\t\t}\n\t\t\t\t\t\thref=\"https://www.youtube.com/watch?v=boJG84Jcf-4\"\n\t\t\t\t\t\tactionLabel=\"Watch announcement\"\n\t\t\t\t\t\tactionHref=\"https://www.youtube.com/watch?v=boJG84Jcf-4\"\n\t\t\t\t\t\tmeta=\"0:00–2:15\"\n\t\t\t\t\t/>\n\t\t\t\t\tmarking a significant leap forward in AI capabilities. This new\n\t\t\t\t\tmodel represents the most advanced language model ever created,\n\t\t\t\t\twith unprecedented performance across multiple domains including\n\t\t\t\t\tcoding, mathematics, and creative writing.\n\t\t\t\t</p>\n\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\tGPT-5&apos;s enhanced capabilities extend beyond traditional text\n\t\t\t\t\tprocessing to include improved visual perception and\n\t\t\t\t\thealth-related assistance, making it a versatile tool for both\n\t\t\t\t\tprofessional and personal use. The model is now rolling out to\n\t\t\t\t\tall users, democratizing access to cutting-edge AI technology.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/icons/youtube.tsx",
      "content": "\"use client\";\n\nimport type { HTMLAttributes } from \"react\";\nimport { forwardRef, useCallback, useImperativeHandle, useRef } from \"react\";\n\nimport { cn } from \"@/registry/utilities/cn\";\nimport { motion, useAnimation } from \"motion/react\";\nimport type { Variants } from \"motion/react\";\n\nexport interface YoutubeIconHandle {\n\tstartAnimation: () => void;\n\tstopAnimation: () => void;\n}\n\ninterface YoutubeIconProps extends HTMLAttributes<HTMLDivElement> {\n\tsize?: number;\n}\n\nconst pathVariants: Variants = {\n\tnormal: {\n\t\topacity: 1,\n\t\tpathLength: 1,\n\t\tpathOffset: 0,\n\t\ttransition: {\n\t\t\tduration: 0.4,\n\t\t\topacity: { duration: 0.1 },\n\t\t},\n\t},\n\tanimate: {\n\t\topacity: [0, 1],\n\t\tpathLength: [0, 1],\n\t\tpathOffset: [1, 0],\n\t\ttransition: {\n\t\t\tduration: 0.6,\n\t\t\tease: \"linear\",\n\t\t\topacity: { duration: 0.1 },\n\t\t},\n\t},\n};\n\nconst triangleVariants: Variants = {\n\tnormal: {\n\t\topacity: 1,\n\t\tpathLength: 1,\n\t\tpathOffset: 0,\n\t\ttransition: {\n\t\t\tduration: 0.4,\n\t\t\topacity: { duration: 0.1 },\n\t\t},\n\t},\n\tanimate: {\n\t\topacity: [0, 1],\n\t\tpathLength: [0, 1],\n\t\tpathOffset: [1, 0],\n\t\ttransition: {\n\t\t\tduration: 0.6,\n\t\t\tease: \"linear\",\n\t\t\topacity: { duration: 0.1 },\n\t\t},\n\t},\n};\n\nconst YoutubeIcon = forwardRef<YoutubeIconHandle, YoutubeIconProps>(\n\t({ onMouseEnter, onMouseLeave, className, size = 28, ...props }, ref) => {\n\t\tconst pathControls = useAnimation();\n\t\tconst triangleControls = useAnimation();\n\t\tconst isControlledRef = useRef(false);\n\n\t\tuseImperativeHandle(ref, () => {\n\t\t\tisControlledRef.current = true;\n\n\t\t\treturn {\n\t\t\t\tstartAnimation: () => {\n\t\t\t\t\tpathControls.start(\"animate\");\n\t\t\t\t\ttriangleControls.start(\"animate\");\n\t\t\t\t},\n\t\t\t\tstopAnimation: () => {\n\t\t\t\t\tpathControls.start(\"normal\");\n\t\t\t\t\ttriangleControls.start(\"normal\");\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\n\t\tconst handleMouseEnter = useCallback(\n\t\t\t(e: React.MouseEvent<HTMLDivElement>) => {\n\t\t\t\tif (!isControlledRef.current) {\n\t\t\t\t\tpathControls.start(\"animate\");\n\t\t\t\t\ttriangleControls.start(\"animate\");\n\t\t\t\t} else {\n\t\t\t\t\tonMouseEnter?.(e);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[onMouseEnter, pathControls, triangleControls]\n\t\t);\n\n\t\tconst handleMouseLeave = useCallback(\n\t\t\t(e: React.MouseEvent<HTMLDivElement>) => {\n\t\t\t\tif (!isControlledRef.current) {\n\t\t\t\t\tpathControls.start(\"normal\");\n\t\t\t\t\ttriangleControls.start(\"normal\");\n\t\t\t\t} else {\n\t\t\t\t\tonMouseLeave?.(e);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[pathControls, triangleControls, onMouseLeave]\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t`cursor-pointer select-none p-2 hover:bg-accent rounded-md transition-colors duration-200 flex items-center justify-center`,\n\t\t\t\t\tclassName\n\t\t\t\t)}\n\t\t\t\tonMouseEnter={handleMouseEnter}\n\t\t\t\tonMouseLeave={handleMouseLeave}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\twidth={size}\n\t\t\t\t\theight={size}\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<motion.path\n\t\t\t\t\t\tvariants={pathVariants}\n\t\t\t\t\t\tinitial=\"normal\"\n\t\t\t\t\t\tanimate={pathControls}\n\t\t\t\t\t\td=\"M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17\"\n\t\t\t\t\t/>\n\t\t\t\t\t<motion.path\n\t\t\t\t\t\tvariants={triangleVariants}\n\t\t\t\t\t\tinitial=\"normal\"\n\t\t\t\t\t\tanimate={triangleControls}\n\t\t\t\t\t\td=\"M10 15l5-3-5-3z\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nYoutubeIcon.displayName = \"YoutubeIcon\";\n\nexport { YoutubeIcon };\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/utilities/cn.ts",
      "content": "import { ClassValue, clsx } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n\treturn twMerge(clsx(inputs));\r\n}\r\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/rich-popover.tsx",
      "content": "\"use client\";\n\nimport type * as React from \"react\";\n\nimport Link from \"next/link\";\n\nimport * as Popover from \"@radix-ui/react-popover\";\nimport { Clock, ExternalLink, Play } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\n\n// Credit:\n// https://smoothui.dev/doc/components/rich-popover\nexport interface RichTooltipProps {\n\ttrigger: React.ReactNode;\n\ttitle: string;\n\tdescription?: string;\n\ticon?: React.ReactNode;\n\thref?: string;\n\tactionLabel?: string;\n\tactionHref?: string;\n\tonActionClick?: () => void;\n\tmeta?: string;\n\tclassName?: string;\n\tside?: \"top\" | \"bottom\" | \"left\" | \"right\";\n\talign?: \"start\" | \"center\" | \"end\";\n}\n\nexport function YouTubeIcon({\n\tclassName = \"h-4 w-4 fill-red-600\",\n}: {\n\tclassName?: string;\n}) {\n\treturn (\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 16 16\"\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tclassName={className}\n\t\t\trole=\"img\"\n\t\t\taria-label=\"YouTube\"\n\t\t\tfocusable=\"false\"\n\t\t>\n\t\t\t<path d=\"M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 0 1 1.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.01 2.01 0 0 1-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.01 2.01 0 0 1-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31 31 0 0 1 0 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.01 2.01 0 0 1 1.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A100 100 0 0 1 7.858 2zM6.4 5.209v4.818l4.157-2.408z\" />\n\t\t</svg>\n\t);\n}\n\nexport default function RichPopover({\n\ttrigger,\n\ttitle,\n\tdescription,\n\ticon,\n\thref,\n\tactionLabel,\n\tactionHref,\n\tonActionClick,\n\tmeta,\n\tclassName = \"\",\n\tside = \"top\",\n\talign = \"center\",\n}: RichTooltipProps) {\n\tconst Title = (\n\t\t<div className=\"flex items-center gap-2 text-sm font-medium\">\n\t\t\t{icon ?? <YouTubeIcon />}\n\t\t\t{href ? (\n\t\t\t\t<Link\n\t\t\t\t\thref={href}\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\tclassName=\"inline-flex items-center gap-1 hover:underline\"\n\t\t\t\t>\n\t\t\t\t\t<span>{title}</span>\n\t\t\t\t\t<ExternalLink className=\"h-3.5 w-3.5 opacity-70\" />\n\t\t\t\t</Link>\n\t\t\t) : (\n\t\t\t\t<span>{title}</span>\n\t\t\t)}\n\t\t</div>\n\t);\n\n\tconst Action = actionLabel ? (\n\t\tactionHref ? (\n\t\t\t<Link\n\t\t\t\thref={actionHref}\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclassName=\"inline-flex items-center gap-2 rounded-full bg-background px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-background/90\"\n\t\t\t>\n\t\t\t\t<Play className=\"h-3.5 w-3.5\" /> {actionLabel}\n\t\t\t</Link>\n\t\t) : (\n\t\t\t<button\n\t\t\t\tonClick={onActionClick}\n\t\t\t\tclassName=\"inline-flex items-center gap-2 rounded-full bg-background px-3 py-2 text-xs font-medium text-foreground transition-colors hover:bg-background/90\"\n\t\t\t\ttype=\"button\"\n\t\t\t>\n\t\t\t\t<Play className=\"h-3.5 w-3.5\" /> {actionLabel}\n\t\t\t</button>\n\t\t)\n\t) : null;\n\n\treturn (\n\t\t<Popover.Root>\n\t\t\t<Popover.Trigger asChild>{trigger}</Popover.Trigger>\n\t\t\t<Popover.Portal>\n\t\t\t\t<Popover.Content\n\t\t\t\t\tside={side}\n\t\t\t\t\talign={align}\n\t\t\t\t\tsideOffset={8}\n\t\t\t\t\tclassName={`z-50 ${className}`}\n\t\t\t\t\tasChild\n\t\t\t\t>\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tinitial={{\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\tscale: 0.95,\n\t\t\t\t\t\t\ty: 5,\n\t\t\t\t\t\t\tfilter: \"blur(8px)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1, y: 0, filter: \"blur(0px)\" }}\n\t\t\t\t\t\texit={{ opacity: 0, scale: 0.95, y: 5, filter: \"blur(8px)\" }}\n\t\t\t\t\t\ttransition={{\n\t\t\t\t\t\t\ttype: \"spring\",\n\t\t\t\t\t\t\tstiffness: 500,\n\t\t\t\t\t\t\tdamping: 30,\n\t\t\t\t\t\t\tduration: 0.2,\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName=\"relative rounded-2xl border border-white/10 bg-background px-4 py-3 text-foreground shadow-xl\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{Title}\n\t\t\t\t\t\t{description && (\n\t\t\t\t\t\t\t<p className=\"mt-3 max-w-xs text-base leading-relaxed text-balance text-foreground/90\">\n\t\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{(meta || Action) && (\n\t\t\t\t\t\t\t<div className=\"mt-4 flex items-center justify-between gap-3\">\n\t\t\t\t\t\t\t\t{meta ? (\n\t\t\t\t\t\t\t\t\t<span className=\"inline-flex items-center gap-1 rounded-full bg-background/10 px-3 py-1 text-xs text-foreground\">\n\t\t\t\t\t\t\t\t\t\t<Clock className=\"h-3.5 w-3.5\" /> {meta}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{Action}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{/* Tail */}\n\t\t\t\t\t\t<Popover.Arrow className=\"fill-black\" />\n\t\t\t\t\t</motion.div>\n\t\t\t\t</Popover.Content>\n\t\t\t</Popover.Portal>\n\t\t</Popover.Root>\n\t);\n}\n",
      "type": "registry:ui"
    }
  ]
}