{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "expandable-card",
  "title": "Expandable Cards",
  "description": "Click cards to expand them and show additional information.",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "registry/ui/expandable-card.tsx",
      "content": "\"use client\"\n\nimport React, { useEffect, useId, useRef, useState } from \"react\"\nimport { AnimatePresence, motion } from \"motion/react\"\nimport { useOutsideClick } from \"@/hooks/use-outside-click\"\n\nexport default function ExpandableCardDemo() {\n  const [active, setActive] = useState<(typeof cards)[number] | boolean | null>(\n    null,\n  )\n  const ref = useRef<HTMLDivElement>(null)\n  const id = useId()\n\n  useEffect(() => {\n    function onKeyDown(event: KeyboardEvent) {\n      if (event.key === \"Escape\") {\n        setActive(false)\n      }\n    }\n\n    if (active && typeof active === \"object\") {\n      document.body.style.overflow = \"hidden\"\n    } else {\n      document.body.style.overflow = \"auto\"\n    }\n\n    window.addEventListener(\"keydown\", onKeyDown)\n    return () => window.removeEventListener(\"keydown\", onKeyDown)\n  }, [active])\n\n  useOutsideClick(ref, () => setActive(null))\n\n  return (\n    <>\n      <AnimatePresence>\n        {active && typeof active === \"object\" && (\n          <motion.div\n            initial={{ opacity: 0 }}\n            animate={{ opacity: 1 }}\n            exit={{ opacity: 0 }}\n            className=\"fixed inset-0 z-10 h-full w-full bg-black/20\"\n          />\n        )}\n      </AnimatePresence>\n      <AnimatePresence>\n        {active && typeof active === \"object\" ? (\n          <div className=\"fixed inset-0 z-[100] grid place-items-center\">\n            <motion.button\n              key={`button-${active.title}-${id}`}\n              layout\n              initial={{\n                opacity: 0,\n              }}\n              animate={{\n                opacity: 1,\n              }}\n              exit={{\n                opacity: 0,\n                transition: {\n                  duration: 0.05,\n                },\n              }}\n              className=\"absolute top-2 right-2 flex h-6 w-6 items-center justify-center rounded-full bg-white lg:hidden\"\n              onClick={() => setActive(null)}\n            >\n              <CloseIcon />\n            </motion.button>\n            <motion.div\n              layoutId={`card-${active.title}-${id}`}\n              ref={ref}\n              className=\"flex h-full w-full max-w-[500px] flex-col overflow-hidden bg-white sm:rounded-3xl md:h-fit md:max-h-[90%] dark:bg-neutral-900\"\n            >\n              <motion.div layoutId={`image-${active.title}-${id}`}>\n                <img\n                  width={200}\n                  height={200}\n                  src={active.src}\n                  alt={active.title}\n                  className=\"h-80 w-full object-cover object-top sm:rounded-tl-lg sm:rounded-tr-lg lg:h-80\"\n                />\n              </motion.div>\n\n              <div>\n                <div className=\"flex items-start justify-between p-4\">\n                  <div className=\"\">\n                    <motion.h3\n                      layoutId={`title-${active.title}-${id}`}\n                      className=\"font-bold text-neutral-700 dark:text-neutral-200\"\n                    >\n                      {active.title}\n                    </motion.h3>\n                    <motion.p\n                      layoutId={`description-${active.description}-${id}`}\n                      className=\"text-neutral-600 dark:text-neutral-400\"\n                    >\n                      {active.description}\n                    </motion.p>\n                  </div>\n\n                  <motion.a\n                    layoutId={`button-${active.title}-${id}`}\n                    href={active.ctaLink}\n                    target=\"_blank\"\n                    className=\"rounded-full bg-green-500 px-4 py-3 text-sm font-bold text-white\"\n                  >\n                    {active.ctaText}\n                  </motion.a>\n                </div>\n                <div className=\"relative px-4 pt-4\">\n                  <motion.div\n                    layout\n                    initial={{ opacity: 0 }}\n                    animate={{ opacity: 1 }}\n                    exit={{ opacity: 0 }}\n                    className=\"flex h-40 flex-col items-start gap-4 overflow-auto pb-10 text-xs text-neutral-600 [-ms-overflow-style:none] [-webkit-overflow-scrolling:touch] [mask:linear-gradient(to_bottom,white,white,transparent)] [scrollbar-width:none] md:h-fit md:text-sm lg:text-base dark:text-neutral-400\"\n                  >\n                    {typeof active.content === \"function\"\n                      ? active.content()\n                      : active.content}\n                  </motion.div>\n                </div>\n              </div>\n            </motion.div>\n          </div>\n        ) : null}\n      </AnimatePresence>\n      <ul className=\"mx-auto w-full max-w-2xl gap-4\">\n        {cards.map((card, index) => (\n          <motion.div\n            layoutId={`card-${card.title}-${id}`}\n            key={`card-${card.title}-${id}`}\n            onClick={() => setActive(card)}\n            className=\"flex cursor-pointer flex-col items-center justify-between rounded-xl p-4 hover:bg-neutral-50 md:flex-row dark:hover:bg-neutral-800\"\n          >\n            <div className=\"flex flex-col gap-4 md:flex-row\">\n              <motion.div layoutId={`image-${card.title}-${id}`}>\n                <img\n                  width={100}\n                  height={100}\n                  src={card.src}\n                  alt={card.title}\n                  className=\"h-40 w-40 rounded-lg object-cover object-top md:h-14 md:w-14\"\n                />\n              </motion.div>\n              <div className=\"\">\n                <motion.h3\n                  layoutId={`title-${card.title}-${id}`}\n                  className=\"text-center font-medium text-neutral-800 md:text-left dark:text-neutral-200\"\n                >\n                  {card.title}\n                </motion.h3>\n                <motion.p\n                  layoutId={`description-${card.description}-${id}`}\n                  className=\"text-center text-neutral-600 md:text-left dark:text-neutral-400\"\n                >\n                  {card.description}\n                </motion.p>\n              </div>\n            </div>\n            <motion.button\n              layoutId={`button-${card.title}-${id}`}\n              className=\"mt-4 rounded-full bg-gray-100 px-4 py-2 text-sm font-bold text-black hover:bg-green-500 hover:text-white md:mt-0\"\n            >\n              {card.ctaText}\n            </motion.button>\n          </motion.div>\n        ))}\n      </ul>\n    </>\n  )\n}\n\nexport const CloseIcon = () => {\n  return (\n    <motion.svg\n      initial={{\n        opacity: 0,\n      }}\n      animate={{\n        opacity: 1,\n      }}\n      exit={{\n        opacity: 0,\n        transition: {\n          duration: 0.05,\n        },\n      }}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width=\"24\"\n      height=\"24\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      className=\"h-4 w-4 text-black\"\n    >\n      <path\n        stroke=\"none\"\n        d=\"M0 0h24v24H0z\"\n        fill=\"none\"\n      />\n      <path d=\"M18 6l-12 12\" />\n      <path d=\"M6 6l12 12\" />\n    </motion.svg>\n  )\n}\n\nconst cards = [\n  {\n    description: \"Lana Del Rey\",\n    title: \"Summertime Sadness\",\n    src: \"https://assets.aceternity.com/demos/lana-del-rey.jpeg\",\n    ctaText: \"Play\",\n    ctaLink: \"https://ui.aceternity.com/templates\",\n    content: () => {\n      return (\n        <p>\n          Lana Del Rey, an iconic American singer-songwriter, is celebrated for\n          her melancholic and cinematic music style. Born Elizabeth Woolridge\n          Grant in New York City, she has captivated audiences worldwide with\n          her haunting voice and introspective lyrics. <br /> <br /> Her songs\n          often explore themes of tragic romance, glamour, and melancholia,\n          drawing inspiration from both contemporary and vintage pop culture.\n          With a career that has seen numerous critically acclaimed albums, Lana\n          Del Rey has established herself as a unique and influential figure in\n          the music industry, earning a dedicated fan base and numerous\n          accolades.\n        </p>\n      )\n    },\n  },\n  {\n    description: \"Babbu Maan\",\n    title: \"Mitran Di Chhatri\",\n    src: \"https://assets.aceternity.com/demos/babbu-maan.jpeg\",\n    ctaText: \"Play\",\n    ctaLink: \"https://ui.aceternity.com/templates\",\n    content: () => {\n      return (\n        <p>\n          Babu Maan, a legendary Punjabi singer, is renowned for his soulful\n          voice and profound lyrics that resonate deeply with his audience. Born\n          in the village of Khant Maanpur in Punjab, India, he has become a\n          cultural icon in the Punjabi music industry. <br /> <br /> His songs\n          often reflect the struggles and triumphs of everyday life, capturing\n          the essence of Punjabi culture and traditions. With a career spanning\n          over two decades, Babu Maan has released numerous hit albums and\n          singles that have garnered him a massive fan following both in India\n          and abroad.\n        </p>\n      )\n    },\n  },\n\n  {\n    description: \"Metallica\",\n    title: \"For Whom The Bell Tolls\",\n    src: \"https://assets.aceternity.com/demos/metallica.jpeg\",\n    ctaText: \"Play\",\n    ctaLink: \"https://ui.aceternity.com/templates\",\n    content: () => {\n      return (\n        <p>\n          Metallica, an iconic American heavy metal band, is renowned for their\n          powerful sound and intense performances that resonate deeply with\n          their audience. Formed in Los Angeles, California, they have become a\n          cultural icon in the heavy metal music industry. <br /> <br /> Their\n          songs often reflect themes of aggression, social issues, and personal\n          struggles, capturing the essence of the heavy metal genre. With a\n          career spanning over four decades, Metallica has released numerous hit\n          albums and singles that have garnered them a massive fan following\n          both in the United States and abroad.\n        </p>\n      )\n    },\n  },\n  {\n    description: \"Led Zeppelin\",\n    title: \"Stairway To Heaven\",\n    src: \"https://assets.aceternity.com/demos/led-zeppelin.jpeg\",\n    ctaText: \"Play\",\n    ctaLink: \"https://ui.aceternity.com/templates\",\n    content: () => {\n      return (\n        <p>\n          Led Zeppelin, a legendary British rock band, is renowned for their\n          innovative sound and profound impact on the music industry. Formed in\n          London in 1968, they have become a cultural icon in the rock music\n          world. <br /> <br /> Their songs often reflect a blend of blues, hard\n          rock, and folk music, capturing the essence of the 1970s rock era.\n          With a career spanning over a decade, Led Zeppelin has released\n          numerous hit albums and singles that have garnered them a massive fan\n          following both in the United Kingdom and abroad.\n        </p>\n      )\n    },\n  },\n  {\n    description: \"Mustafa Zahid\",\n    title: \"Toh Phir Aao\",\n    src: \"https://assets.aceternity.com/demos/toh-phir-aao.jpeg\",\n    ctaText: \"Play\",\n    ctaLink: \"https://ui.aceternity.com/templates\",\n    content: () => {\n      return (\n        <p>\n          &quot;Aawarapan&quot;, a Bollywood movie starring Emraan Hashmi, is\n          renowned for its intense storyline and powerful performances. Directed\n          by Mohit Suri, the film has become a significant work in the Indian\n          film industry. <br /> <br /> The movie explores themes of love,\n          redemption, and sacrifice, capturing the essence of human emotions and\n          relationships. With a gripping narrative and memorable music,\n          &quot;Aawarapan&quot; has garnered a massive fan following both in\n          India and abroad, solidifying Emraan Hashmi&apos;s status as a\n          versatile actor.\n        </p>\n      )\n    },\n  },\n]\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/hooks/use-outside-click.ts",
      "content": "import React, { useEffect } from \"react\"\n\nexport const useOutsideClick = (\n  ref: React.RefObject<HTMLDivElement>,\n  callback: Function,\n) => {\n  useEffect(() => {\n    const listener = (event: any) => {\n      // DO NOTHING if the element being clicked is the target element or their children\n      if (!ref.current || ref.current.contains(event.target)) {\n        return\n      }\n      callback(event)\n    }\n\n    document.addEventListener(\"mousedown\", listener)\n    document.addEventListener(\"touchstart\", listener)\n\n    return () => {\n      document.removeEventListener(\"mousedown\", listener)\n      document.removeEventListener(\"touchstart\", listener)\n    }\n  }, [ref, callback])\n}\n",
      "type": "registry:hook"
    }
  ],
  "type": "registry:ui"
}