{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "show-more",
  "title": "Show More",
  "description": "A component that shows/hides additional content with smooth animations.",
  "dependencies": [
    "lucide-react",
    "motion",
    "clsx",
    "tailwind-merge"
  ],
  "registryDependencies": [
    "https://optics.agusmayol.com.ar/r/separator.json",
    "https://optics.agusmayol.com.ar/r/button.json",
    "https://optics.agusmayol.com.ar/r/accordion.json",
    "https://optics.agusmayol.com.ar/r/utils.json"
  ],
  "files": [
    {
      "path": "registry/optics/show-more.jsx",
      "content": "\"use client\";\nimport { cn } from \"@/registry/optics/lib/utils\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Separator } from \"@/registry/optics/separator\";\nimport {\n\tAccordion,\n\tAccordionItem,\n\tAccordionTrigger,\n\tAccordionContent,\n\tuseAccordionItem,\n} from \"@/registry/optics/accordion\";\nimport { buttonVariants } from \"@/registry/optics/button\";\nimport { useMemo } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\n\n// Helper function to extract color variable\nconst getColorVar = (color) => {\n\tif (!color) return \"oklch(var(--background))\";\n\t// If it's a CSS value (contains functions or hex), return it as is\n\tif (color.match(/\\(|var\\(|hsl\\(|oklch\\(|rgb\\(|rgba\\(|#[0-9a-fA-F]/)) {\n\t\treturn color;\n\t}\n\n\t// Extract color name from Tailwind classes like \"from-background\" or \"bg-background\"\n\tconst colorName = color.startsWith(\"from-\")\n\t\t? color.slice(5)\n\t\t: color.startsWith(\"bg-\")\n\t\t\t? color.slice(3)\n\t\t\t: color;\n\n\t// Return CSS variable format\n\treturn `var(--${colorName})`;\n};\n\nfunction ShowMoreButton({ isOpen }) {\n\treturn (\n\t\t<div className=\"w-full -mt-4.5 flex items-center justify-center pb-2\">\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\tbuttonVariants({\n\t\t\t\t\t\tvariant: \"raised\",\n\t\t\t\t\t\tsize: \"default\",\n\t\t\t\t\t}),\n\t\t\t\t\t\"rounded-full squircle-none z-10 relative overflow-hidden\",\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"absolute inset-0 flex mr-6 items-center justify-center transition-all duration-300 ease-in-out will-change-[transform,opacity]\",\n\t\t\t\t\t\tisOpen ? \"translate-y-0 opacity-100\" : \"translate-y-full opacity-0\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\tShow Less\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"transition-all duration-300 ease-in-out will-change-[transform,opacity]\",\n\t\t\t\t\t\tisOpen\n\t\t\t\t\t\t\t? \"-translate-y-full opacity-0\"\n\t\t\t\t\t\t\t: \"translate-y-0 opacity-100\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\tShow More\n\t\t\t\t</div>\n\t\t\t\t<ChevronDown\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-300 ease-in-out -mt-0.5\",\n\t\t\t\t\t\tisOpen ? \"rotate-180\" : \"rotate-0\",\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction ShowMoreContent({\n\tchildren,\n\tmoreContent,\n\tshowSeparator,\n\tmaskColor,\n\tdefaultColor,\n\tdarkColor,\n}) {\n\tconst { isOpen } = useAccordionItem();\n\n\treturn (\n\t\t<div className=\"relative\">\n\t\t\t{/* Main content - always visible */}\n\t\t\t<div className=\"relative\">{children}</div>\n\n\t\t\t{/* Top button & mask - visible when closed */}\n\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t{!isOpen && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\ttransition={{ duration: 0.25, ease: \"easeInOut\" }}\n\t\t\t\t\t\tclassName=\"w-full pt-6 relative z-10\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{showSeparator && (\n\t\t\t\t\t\t\t<div className=\"relative z-[1]\">\n\t\t\t\t\t\t\t\t<Separator decoration />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{/* Fade mask */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\tclassName=\"pointer-events-none absolute inset-x-0 bottom-6.75 z-[5]\"\n\t\t\t\t\t\t\tstyle={{ height: \"80px\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"dark:hidden absolute inset-x-0 bottom-0 h-full\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundImage: `linear-gradient(to top, ${getColorVar(defaultColor)}, transparent)`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"hidden dark:block absolute inset-x-0 bottom-0 h-full\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundImage: `linear-gradient(to top, ${getColorVar(darkColor)}, transparent)`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<AccordionTrigger\n\t\t\t\t\t\t\tshowArrow={false}\n\t\t\t\t\t\t\tclassName=\"w-full px-0 pt-0 pb-0 group flex-row-reverse items-center justify-end hover:no-underline hover:cursor-pointer rounded-none [&>svg]:hidden relative z-10\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ShowMoreButton isOpen={isOpen} />\n\t\t\t\t\t\t</AccordionTrigger>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\n\t\t\t<AccordionContent\n\t\t\t\tclassName=\"border-none p-0 relative overflow-hidden\"\n\t\t\t\tkeepRendered\n\t\t\t>\n\t\t\t\t{moreContent}\n\t\t\t</AccordionContent>\n\n\t\t\t{/* Bottom button & mask - visible when open */}\n\t\t\t<AnimatePresence mode=\"wait\">\n\t\t\t\t{isOpen && (\n\t\t\t\t\t<motion.div\n\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\texit={{ opacity: 0 }}\n\t\t\t\t\t\ttransition={{ duration: 0.25, ease: \"easeInOut\" }}\n\t\t\t\t\t\tclassName=\"w-full mt-8 relative z-10\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{showSeparator && (\n\t\t\t\t\t\t\t<div className=\"relative z-[10]\">\n\t\t\t\t\t\t\t\t<Separator decoration />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<AccordionTrigger\n\t\t\t\t\t\t\tshowArrow={false}\n\t\t\t\t\t\t\tclassName=\"w-full px-0 pt-0 pb-0 group flex-row-reverse items-center justify-end hover:no-underline hover:cursor-pointer rounded-none [&>svg]:hidden relative z-[11]\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ShowMoreButton isOpen={isOpen} />\n\t\t\t\t\t\t</AccordionTrigger>\n\t\t\t\t\t\t{/* Fade mask */}\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\tclassName=\"pointer-events-none absolute inset-x-0 bottom-6.75 z-[9]\"\n\t\t\t\t\t\t\tstyle={{ height: \"40px\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"dark:hidden absolute inset-x-0 bottom-0 h-full\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundImage: `linear-gradient(to top, ${getColorVar(defaultColor)}, transparent)`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"hidden dark:block absolute inset-x-0 bottom-0 h-full\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundImage: `linear-gradient(to top, ${getColorVar(darkColor)}, transparent)`,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</motion.div>\n\t\t\t\t)}\n\t\t\t</AnimatePresence>\n\t\t</div>\n\t);\n}\n\nexport function ShowMore({\n\tchildren = null,\n\tmoreContent = null,\n\tmaskColor = \"oklch(var(--background))\",\n\tshowSeparator = true,\n}) {\n\t// If no moreContent is provided, don't render the show more functionality\n\tconst hasMoreContent = moreContent != null;\n\n\t// Get default and dark colors\n\tconst defaultColor = useMemo(\n\t\t() =>\n\t\t\ttypeof maskColor === \"object\" && maskColor !== null\n\t\t\t\t? maskColor.default || maskColor.dark || \"oklch(var(--background))\"\n\t\t\t\t: maskColor,\n\t\t[maskColor],\n\t);\n\tconst darkColor = useMemo(\n\t\t() =>\n\t\t\ttypeof maskColor === \"object\" && maskColor !== null\n\t\t\t\t? maskColor.dark || maskColor.default || \"oklch(var(--background))\"\n\t\t\t\t: maskColor,\n\t\t[maskColor],\n\t);\n\n\tif (!hasMoreContent) {\n\t\treturn <div>{children}</div>;\n\t}\n\n\treturn (\n\t\t<Accordion type=\"single\" collapsible className=\"w-full\">\n\t\t\t<AccordionItem value=\"show-more\" className=\"w-full border-none\">\n\t\t\t\t<ShowMoreContent\n\t\t\t\t\tmoreContent={moreContent}\n\t\t\t\t\tshowSeparator={showSeparator}\n\t\t\t\t\tmaskColor={maskColor}\n\t\t\t\t\tdefaultColor={defaultColor}\n\t\t\t\t\tdarkColor={darkColor}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</ShowMoreContent>\n\t\t\t</AccordionItem>\n\t\t</Accordion>\n\t);\n}\n\nShowMoreButton.displayName = \"ShowMoreButton\";\nShowMoreContent.displayName = \"ShowMoreContent\";\nShowMore.displayName = \"ShowMore\";\n",
      "type": "registry:component",
      "target": "components/optics/show-more.jsx"
    }
  ],
  "type": "registry:component"
}