{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gooey-tabs",
  "type": "registry:block",
  "title": "Gooey tabs",
  "description": "Gooey tabs",
  "files": [
    {
      "path": "components/usages/gooeytabsusage.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport { GooeyDemo } from \"@/registry/open-source/gooey-tabs\";\n\nexport default function Usage() {\n\treturn (\n\t\t<div className=\"h-screen w-full flex items-center justify-center relative overflow-hidden bg-background\">\n\t\t\t<GooeyDemo />\n\t\t</div>\n\t);\n}\n",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/gooeytabsusage.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport { GooeyDemo } from \"@/registry/open-source/gooey-tabs\";\n\nexport default function Usage() {\n\treturn (\n\t\t<div className=\"h-screen w-full flex items-center justify-center relative overflow-hidden bg-background\">\n\t\t\t<GooeyDemo />\n\t\t</div>\n\t);\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/gooey-tabs.tsx",
      "content": "import { useState } from \"react\";\r\n\r\nimport dynamic from \"next/dynamic\";\r\n\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { AnimatePresence, motion } from \"motion/react\";\r\n\r\n// Credit:\r\n// https://www.fancycomponents.dev/docs/components/filter/gooey-svg-filter\r\n\r\nconst TAB_CONTENT = [\r\n\t{\r\n\t\ttitle: \"2024\",\r\n\t\tfiles: [\r\n\t\t\t\"learning-to-meditate.md\",\r\n\t\t\t\"spring-garden-plans.md\",\r\n\t\t\t\"travel-wishlist.md\",\r\n\t\t\t\"new-coding-projects.md\",\r\n\t\t],\r\n\t},\r\n\t{\r\n\t\ttitle: \"2023\",\r\n\t\tfiles: [\r\n\t\t\t\"year-in-review.md\",\r\n\t\t\t\"marathon-training-log.md\",\r\n\t\t\t\"recipe-collection.md\",\r\n\t\t\t\"book-reflections.md\",\r\n\t\t],\r\n\t},\r\n\t{\r\n\t\ttitle: \"2022\",\r\n\t\tfiles: [\r\n\t\t\t\"moving-to-a-new-city.md\",\r\n\t\t\t\"starting-a-blog.md\",\r\n\t\t\t\"photography-basics.md\",\r\n\t\t\t\"first-coding-project.md\",\r\n\t\t],\r\n\t},\r\n\t{\r\n\t\ttitle: \"2021\",\r\n\t\tfiles: [\r\n\t\t\t\"goals-and-aspirations.md\",\r\n\t\t\t\"daily-gratitude.md\",\r\n\t\t\t\"learning-to-cook.md\",\r\n\t\t\t\"remote-work-journal.md\",\r\n\t\t],\r\n\t},\r\n];\r\n\r\nexport function GooeyDemo() {\r\n\tconst [activeTab, setActiveTab] = useState(0);\r\n\tconst [isGooeyEnabled, setIsGooeyEnabled] = useState(true);\r\n\r\n\treturn (\r\n\t\t<div className=\"relative w-full h-full flex justify-center p-8 font-calendas md:text-base text-xs sm:text-sm bg-background dark:bg-background\">\r\n\t\t\t<GooeyFilter id=\"gooey-filter\" strength={15} />\r\n\r\n\t\t\t<Button\r\n\t\t\t\tvariant=\"outline\"\r\n\t\t\t\tonClick={() => setIsGooeyEnabled(!isGooeyEnabled)}\r\n\t\t\t\tclassName=\"absolute top-4 left-4 font-overusedGrotesk\"\r\n\t\t\t>\r\n\t\t\t\t{isGooeyEnabled ? \"Disable filter\" : \"Enable filter\"}\r\n\t\t\t</Button>\r\n\r\n\t\t\t<div className=\"w-11/12 md:w-4/5 relative mt-24\">\r\n\t\t\t\t<div\r\n\t\t\t\t\tclassName=\"absolute inset-0\"\r\n\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\tfilter: isGooeyEnabled ? \"url(#gooey-filter)\" : \"none\",\r\n\t\t\t\t\t}}\r\n\t\t\t\t>\r\n\t\t\t\t\t<div className=\"flex w-full \">\r\n\t\t\t\t\t\t{TAB_CONTENT.map((_, index) => (\r\n\t\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\t\tkey={index + \"gooey-tabs\"}\r\n\t\t\t\t\t\t\t\tclassName=\"relative flex-1 h-8 md:h-12\"\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t{activeTab === index && (\r\n\t\t\t\t\t\t\t\t\t<motion.div\r\n\t\t\t\t\t\t\t\t\t\tlayoutId=\"active-tab\"\r\n\t\t\t\t\t\t\t\t\t\tclassName=\"absolute inset-0 bg-background\"\r\n\t\t\t\t\t\t\t\t\t\ttransition={{\r\n\t\t\t\t\t\t\t\t\t\t\ttype: \"spring\",\r\n\t\t\t\t\t\t\t\t\t\t\tbounce: 0.0,\r\n\t\t\t\t\t\t\t\t\t\t\tduration: 0.4,\r\n\t\t\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t))}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t{/* Content panel */}\r\n\t\t\t\t\t<div className=\"w-full h-[200px] sm:h-[250px] md:h-[300px] bg-background overflow-hidden text-muted-foreground\">\r\n\t\t\t\t\t\t<AnimatePresence mode=\"popLayout\">\r\n\t\t\t\t\t\t\t<motion.div\r\n\t\t\t\t\t\t\t\tkey={activeTab}\r\n\t\t\t\t\t\t\t\tinitial={{\r\n\t\t\t\t\t\t\t\t\topacity: 0,\r\n\t\t\t\t\t\t\t\t\ty: 50,\r\n\t\t\t\t\t\t\t\t\tfilter: \"blur(10px)\",\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tanimate={{\r\n\t\t\t\t\t\t\t\t\topacity: 1,\r\n\t\t\t\t\t\t\t\t\ty: 0,\r\n\t\t\t\t\t\t\t\t\tfilter: \"blur(0px)\",\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\texit={{\r\n\t\t\t\t\t\t\t\t\topacity: 0,\r\n\t\t\t\t\t\t\t\t\ty: -50,\r\n\t\t\t\t\t\t\t\t\tfilter: \"blur(10px)\",\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\ttransition={{\r\n\t\t\t\t\t\t\t\t\tduration: 0.2,\r\n\t\t\t\t\t\t\t\t\tease: \"easeOut\",\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tclassName=\"p-8 md:p-12\"\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t<div className=\"space-y-2 mt-4 sm:mt-8 md:mt-8\">\r\n\t\t\t\t\t\t\t\t\t<ul className=\"\">\r\n\t\t\t\t\t\t\t\t\t\t{TAB_CONTENT[activeTab].files.map(\r\n\t\t\t\t\t\t\t\t\t\t\t(file, index) => (\r\n\t\t\t\t\t\t\t\t\t\t\t\t<li\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={file}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"border-b border-muted-foreground/50 pt-2 pb-1 text-foreground\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t{file}\r\n\t\t\t\t\t\t\t\t\t\t\t\t</li>\r\n\t\t\t\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t\t</ul>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t</motion.div>\r\n\t\t\t\t\t\t</AnimatePresence>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{/* Interactive text overlay, no filter */}\r\n\t\t\t\t<div className=\"relative flex w-full \">\r\n\t\t\t\t\t{TAB_CONTENT.map((tab, index) => (\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\tkey={index + \"gooey-content\"}\r\n\t\t\t\t\t\t\tonClick={() => setActiveTab(index)}\r\n\t\t\t\t\t\t\tclassName=\"flex-1 h-8 md:h-12\"\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<span\r\n\t\t\t\t\t\t\t\tclassName={`\r\n                w-full h-full flex items-center justify-center\r\n                ${activeTab === index ? \"text-foreground\" : \"text-muted-foreground\"}\r\n              `}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t{tab.title}\r\n\t\t\t\t\t\t\t</span>\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n}\r\n\r\nconst GooeyFilter = ({\r\n\tid = \"goo-filter\",\r\n\tstrength = 10,\r\n}: {\r\n\tid?: string;\r\n\tstrength?: number;\r\n}) => {\r\n\treturn (\r\n\t\t<svg className=\"hidden absolute\">\r\n\t\t\t<defs>\r\n\t\t\t\t<filter id={id}>\r\n\t\t\t\t\t<feGaussianBlur\r\n\t\t\t\t\t\tin=\"SourceGraphic\"\r\n\t\t\t\t\t\tstdDeviation={strength}\r\n\t\t\t\t\t\tresult=\"blur\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t<feColorMatrix\r\n\t\t\t\t\t\tin=\"blur\"\r\n\t\t\t\t\t\ttype=\"matrix\"\r\n\t\t\t\t\t\tvalues=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9\"\r\n\t\t\t\t\t\tresult=\"goo\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"goo\" operator=\"atop\" />\r\n\t\t\t\t</filter>\r\n\t\t\t</defs>\r\n\t\t</svg>\r\n\t);\r\n};\r\n\r\nexport default GooeyFilter;\r\n",
      "type": "registry:ui"
    },
    {
      "path": "components/ui/button.tsx",
      "content": "import * as React from \"react\";\r\n\r\nimport { cn } from \"@/registry/utilities/cn\";\r\nimport { Slot } from \"@radix-ui/react-slot\";\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\n\r\nconst buttonVariants = cva(\r\n\t\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm text-white hover:text-gray-400 font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\r\n\t{\r\n\t\tvariants: {\r\n\t\t\tvariant: {\r\n\t\t\t\tsimple:\r\n\t\t\t\t\t\"bg-secondary relative z-10 bg-transparent hover:border-secondary hover:bg-secondary/50  border border-transparent dark:text-white text-sm md:text-sm transition font-medium duration-200  rounded-md px-4 py-2  flex items-center justify-center\",\r\n\t\t\t\tdefault: \"bg-primary text-primary-foreground hover:bg-primary/90\",\r\n\t\t\t\tdestructive:\r\n\t\t\t\t\t\"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\r\n\t\t\t\toutline:\r\n\t\t\t\t\t\"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\r\n\t\t\t\tsecondary:\r\n\t\t\t\t\t\"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\r\n\t\t\t\tghost: \"hover:bg-accent hover:text-black hover:stroke-black dark:text-white text-black\",\r\n\t\t\t\tlink: \"text-primary underline-offset-4 hover:underline\",\r\n\t\t\t},\r\n\t\t\tsize: {\r\n\t\t\t\tdefault: \"h-10 px-4 py-2\",\r\n\t\t\t\tsm: \"h-9 rounded-md px-3\",\r\n\t\t\t\tlg: \"h-11 rounded-md px-8\",\r\n\t\t\t\ticon: \"h-10 w-10\",\r\n\t\t\t},\r\n\t\t},\r\n\t\tdefaultVariants: {\r\n\t\t\tvariant: \"default\",\r\n\t\t\tsize: \"default\",\r\n\t\t},\r\n\t}\r\n);\r\n\r\nexport interface ButtonProps\r\n\textends React.ButtonHTMLAttributes<HTMLButtonElement>,\r\n\t\tVariantProps<typeof buttonVariants> {\r\n\tasChild?: boolean;\r\n}\r\n\r\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\r\n\t({ className, variant, size, asChild = false, ...props }, ref) => {\r\n\t\tconst Comp = asChild ? Slot : \"button\";\r\n\t\treturn (\r\n\t\t\t<Comp\r\n\t\t\t\tclassName={cn(buttonVariants({ variant, size, className }))}\r\n\t\t\t\tref={ref}\r\n\t\t\t\t{...props}\r\n\t\t\t/>\r\n\t\t);\r\n\t}\r\n);\r\nButton.displayName = \"Button\";\r\n\r\nexport { Button, buttonVariants };\r\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"
    }
  ]
}