{
  "name": "transition-panel-card",
  "type": "registry:ui",
  "componentName": "transition-panel",
  "description": "Card component with transition panel animations.",
  "files": [
    {
      "path": "transition-panel-card.tsx",
      "content": "'use client';\nimport React, { useEffect, useState } from 'react';\nimport { TransitionPanel } from '@/components/core/transition-panel';\nimport useMeasure from 'react-use-measure';\n\nconst FEATURES = [\n  {\n    title: 'Brand',\n    description:\n      'Develop a distinctive brand identity with tailored logos and guidelines to ensure consistent messaging across all platforms.',\n  },\n  {\n    title: 'Product',\n    description:\n      'Design and refine products that excel in user experience, meeting needs effectively and creating memorable interactions. We specialize in web applications.',\n  },\n  {\n    title: 'Website',\n    description:\n      'Create impactful websites that combine beautiful aesthetics with functional design, ensuring a superior online presence.',\n  },\n  {\n    title: 'Design System',\n    description:\n      'Develop a design system that unifies your brand identity, ensuring consistency across all platforms and products.',\n  },\n];\n\nfunction Button({\n  onClick,\n  children,\n}: {\n  onClick: () => void;\n  children: React.ReactNode;\n}) {\n  return (\n    <button\n      onClick={onClick}\n      type='button'\n      className='relative flex h-8 shrink-0 scale-100 appearance-none items-center justify-center rounded-lg border border-zinc-950/10 bg-transparent px-2 text-sm text-zinc-500 transition-colors select-none hover:bg-zinc-100 hover:text-zinc-800 focus-visible:ring-2 active:scale-[0.98] dark:border-zinc-50/10 dark:text-zinc-50 dark:hover:bg-zinc-800'\n    >\n      {children}\n    </button>\n  );\n}\nexport function TransitionPanelCard() {\n  const [activeIndex, setActiveIndex] = useState(0);\n  const [direction, setDirection] = useState(1);\n  const [ref, bounds] = useMeasure();\n\n  const handleSetActiveIndex = (newIndex: number) => {\n    setDirection(newIndex > activeIndex ? 1 : -1);\n    setActiveIndex(newIndex);\n  };\n\n  useEffect(() => {\n    if (activeIndex < 0) setActiveIndex(0);\n    if (activeIndex >= FEATURES.length) setActiveIndex(FEATURES.length - 1);\n  }, [activeIndex]);\n\n  return (\n    <div className='w-[364px] overflow-hidden rounded-xl border border-zinc-950/10 bg-white dark:bg-zinc-700'>\n      <TransitionPanel\n        activeIndex={activeIndex}\n        variants={{\n          enter: (direction) => ({\n            x: direction > 0 ? 364 : -364,\n            opacity: 0,\n            height: bounds.height > 0 ? bounds.height : 'auto',\n            position: 'initial',\n          }),\n          center: {\n            zIndex: 1,\n            x: 0,\n            opacity: 1,\n            height: bounds.height > 0 ? bounds.height : 'auto',\n          },\n          exit: (direction) => ({\n            zIndex: 0,\n            x: direction < 0 ? 364 : -364,\n            opacity: 0,\n            position: 'absolute',\n            top: 0,\n            width: '100%',\n          }),\n        }}\n        transition={{\n          x: { type: 'spring', stiffness: 300, damping: 30 },\n          opacity: { duration: 0.2 },\n        }}\n        custom={direction}\n      >\n        {FEATURES.map((feature, index) => (\n          <div key={index} className='px-4 pt-4' ref={ref}>\n            <h3 className='mb-0.5 font-medium text-zinc-800 dark:text-zinc-100'>\n              {feature.title}\n            </h3>\n            <p className='text-zinc-600 dark:text-zinc-400'>\n              {feature.description}\n            </p>\n          </div>\n        ))}\n      </TransitionPanel>\n      <div className='flex justify-between p-4'>\n        {activeIndex > 0 ? (\n          <Button onClick={() => handleSetActiveIndex(activeIndex - 1)}>\n            Previous\n          </Button>\n        ) : (\n          <div />\n        )}\n        <Button\n          onClick={() =>\n            activeIndex === FEATURES.length - 1\n              ? null\n              : handleSetActiveIndex(activeIndex + 1)\n          }\n        >\n          {activeIndex === FEATURES.length - 1 ? 'Close' : 'Next'}\n        </Button>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/transition-panel.tsx",
      "content": "'use client';\nimport {\n  AnimatePresence,\n  Transition,\n  Variant,\n  motion,\n  MotionProps,\n} from 'motion/react';\nimport { cn } from '@/lib/utils';\n\nexport type TransitionPanelProps = {\n  children: React.ReactNode[];\n  className?: string;\n  transition?: Transition;\n  activeIndex: number;\n  variants?: { enter: Variant; center: Variant; exit: Variant };\n} & MotionProps;\n\nexport function TransitionPanel({\n  children,\n  className,\n  transition,\n  variants,\n  activeIndex,\n  ...motionProps\n}: TransitionPanelProps) {\n  return (\n    <div className={cn('relative', className)}>\n      <AnimatePresence\n        initial={false}\n        mode='popLayout'\n        custom={motionProps.custom}\n      >\n        <motion.div\n          key={activeIndex}\n          variants={variants}\n          transition={transition}\n          initial='enter'\n          animate='center'\n          exit='exit'\n          {...motionProps}\n        >\n          {children[activeIndex]}\n        </motion.div>\n      </AnimatePresence>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}