{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card-split-accordian",
  "type": "registry:component",
  "title": "Card Split Accordian",
  "description": "An animated card split accordion that smoothly expands to reveal detailed information.",
  "dependencies": [
    "lucide-react",
    "motion",
    "react-icons",
    "react-use-measure"
  ],
  "files": [
    {
      "path": "components/watermelon/card-split-accordian.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport React, { useState, type FC } from 'react';\nimport { motion, MotionConfig, type Transition } from 'motion/react';\nimport { ChevronDown, Send } from 'lucide-react';\nimport { HiCursorArrowRipple } from 'react-icons/hi2';\nimport { Layers } from 'lucide-react';\nimport { IoIosTimer } from 'react-icons/io';\nimport { PiHandTap } from 'react-icons/pi';\nimport useMeasure from 'react-use-measure';\n\nexport interface AccordionItemData {\n  id: number;\n  title: string;\n  icon: React.ReactNode;\n  content: string;\n}\n\ninterface AccordionItemProps {\n  item: AccordionItemData;\n\n  setOpenId: (id: number | null) => void;\n  index: number;\n  total: number;\n  openIndex: number;\n}\ninterface AccordionProps {\n  items?: AccordionItemData[];\n}\n\nconst springTransition: Transition = {\n  type: 'spring',\n  stiffness: 600,\n  damping: 50,\n  mass: 1,\n};\n\nconst DEFAULT_ITEMS: AccordionItemData[] = [\n  {\n    id: 1,\n    title: 'What is Interaction Design?',\n    icon: <HiCursorArrowRipple className=\"size-3 -rotate-10 md:size-4\" />,\n    content:\n      'Interaction design focuses on creating engaging interfaces with well-thought-out behaviors and actions.',\n  },\n  {\n    id: 2,\n    title: 'Principles & Patterns',\n    icon: <Layers size={24} />,\n    content:\n      'Fundamental guidelines and repeated solutions that ensure consistency and usability in design.',\n  },\n  {\n    id: 3,\n    title: 'Usability & Accessibility',\n    icon: <PiHandTap size={26} className=\"-rotate-20\" />,\n    content:\n      'Designing experiences that are easy to use and accessible to people of all abilities.',\n  },\n  {\n    id: 4,\n    title: 'Prototyping & Testing',\n    icon: <Send size={24} />,\n    content:\n      'Rapid experimentation and validation of ideas through prototypes and real user testing.',\n  },\n  {\n    id: 5,\n    title: 'UX Optimisation',\n    icon: <IoIosTimer size={26} />,\n    content:\n      'Improving user experience by analyzing behavior and refining interactions over time.',\n  },\n];\n\nconst AccordionItem: FC<AccordionItemProps> = ({\n  item,\n  setOpenId,\n  index,\n  total,\n  openIndex,\n}) => {\n  const [ref, bounds] = useMeasure();\n  const isOpen = index === openIndex;\n\n  const isFirst = index === 0;\n  const isLast = index === total - 1;\n\n  const isBeforeOpen = index === openIndex - 1;\n  const isAfterOpen = index === openIndex + 1;\n\n  const isAlone = (isAfterOpen && isLast) || (isBeforeOpen && isFirst);\n\n  const BORDER_WIDTH = '1px';\n  const BORDER_STYLE = 'solid';\n  const borderTopWidth =\n    isFirst || isAfterOpen || isOpen ? BORDER_WIDTH : '0px';\n  const borderBottomWidth =\n    isLast || isBeforeOpen || isOpen ? BORDER_WIDTH : '0px';\n  const borderLeftWidth = BORDER_WIDTH;\n  const borderRightWidth = BORDER_WIDTH;\n\n  let borderTopLeftRadius = 0;\n  let borderTopRightRadius = 0;\n  let borderBottomLeftRadius = 0;\n  let borderBottomRightRadius = 0;\n\n  if (isOpen || isAlone) {\n    borderTopLeftRadius = 20;\n    borderTopRightRadius = 20;\n    borderBottomLeftRadius = 20;\n    borderBottomRightRadius = 20;\n  } else if (isBeforeOpen) {\n    borderBottomLeftRadius = 20;\n    borderBottomRightRadius = 20;\n  } else if (isAfterOpen) {\n    borderTopLeftRadius = 20;\n    borderTopRightRadius = 20;\n  } else if (isFirst) {\n    borderTopLeftRadius = 20;\n    borderTopRightRadius = 20;\n  } else if (isLast) {\n    borderBottomLeftRadius = 20;\n    borderBottomRightRadius = 20;\n  }\n\n  return (\n    <MotionConfig transition={springTransition}>\n      <motion.li layout>\n        <motion.div\n          animate={{\n            borderTopLeftRadius,\n            borderTopRightRadius,\n            borderBottomLeftRadius,\n            borderBottomRightRadius,\n          }}\n          className=\"overflow-hidden border-solid border-zinc-200 bg-zinc-50 will-change-transform dark:border-zinc-800 dark:bg-zinc-900\"\n          style={{\n            borderTopWidth,\n            borderBottomWidth,\n            borderLeftWidth,\n            borderRightWidth,\n            borderStyle: BORDER_STYLE,\n            marginBlock: isOpen ? '10px' : '0px',\n          }}\n        >\n          <button\n            onClick={() => setOpenId(isOpen ? null : item.id)}\n            className=\"flex w-full cursor-pointer items-center justify-between px-[12px] py-[10px]\"\n          >\n            <div className=\"flex items-center gap-[12px]\">\n              {item.icon}\n\n              <span className=\"text-sm font-bold text-[#272729] md:text-lg dark:text-zinc-100\">\n                {item.title}\n              </span>\n            </div>\n\n            <motion.div animate={{ rotate: isOpen ? 180 : 0 }}>\n              <ChevronDown className=\"size-5 text-neutral-400 md:size-[1.625rem] dark:text-zinc-600\" />\n            </motion.div>\n          </button>\n\n          <motion.div\n            initial={false}\n            animate={{\n              height: isOpen ? bounds.height : 0,\n              opacity: isOpen ? 1 : 0,\n            }}\n            className=\"overflow-hidden will-change-transform\"\n          >\n            <div ref={ref}>\n              <div className=\"px-5 pb-5 text-xs font-medium text-[#545359] md:text-[18px] dark:text-zinc-400\">\n                {item.content}\n              </div>\n            </div>\n          </motion.div>\n        </motion.div>\n      </motion.li>\n    </MotionConfig>\n  );\n};\n\nexport const AccordionApp: FC<AccordionProps> = ({ items }) => {\n  const defaultItems = items ?? DEFAULT_ITEMS;\n\n  const [openId, setOpenId] = useState<number | null>(null);\n\n  const openIndex = defaultItems.findIndex((item) => item.id === openId);\n\n  return (\n    <div className=\"flex w-full flex-col items-center justify-center p-6 transition-colors duration-500\">\n      <ul className=\"w-xs md:w-sm\">\n        {defaultItems.map((item, index) => (\n          <AccordionItem\n            key={item.id}\n            item={item}\n            setOpenId={setOpenId}\n            index={index}\n            total={defaultItems.length}\n            openIndex={openIndex}\n          />\n        ))}\n      </ul>\n    </div>\n  );\n};\n"
    }
  ]
}
