{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "transitions-expanding-card",
  "type": "registry:component",
  "title": "Expanding Card",
  "description": "Smoothly expand a card into a detail view with multiple animation styles.",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/new-york/animations/transitions/expanding-card.tsx",
      "content": "\"use client\";\n\nimport React, { useState, useId } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface CardItem {\n    id: number | string;\n    title: string;\n    description: string;\n    longDescription: string;\n    image: string;\n}\n\ninterface ExpandingCardProps {\n    items: CardItem[];\n    className?: string;\n    columns?: 2 | 3 | 4;\n    variant?: \"scale-center\" | \"slide-up\" | \"rotate-scale\" | \"elastic\" | \"fade-scale\";\n}\n\nexport function ExpandingCard({ items, className, columns = 3, variant = \"scale-center\" }: ExpandingCardProps) {\n    const [selectedId, setSelectedId] = useState<number | string | null>(null);\n    const id = useId();\n\n    const gridCols = {\n        2: \"md:grid-cols-2\",\n        3: \"md:grid-cols-3\",\n        4: \"md:grid-cols-4\"\n    }[columns];\n\n    const getExpandTransition = () => {\n        switch (variant) {\n            case \"scale-center\":\n                return { type: \"spring\" as const, bounce: 0.2, duration: 0.6 };\n            case \"slide-up\":\n                return { type: \"spring\" as const, bounce: 0.15, duration: 0.5 };\n            case \"rotate-scale\":\n                return { type: \"spring\" as const, bounce: 0.25, duration: 0.7 };\n            case \"elastic\":\n                return { type: \"spring\" as const, bounce: 0.4, duration: 0.8 };\n            case \"fade-scale\":\n                return { type: \"tween\" as const, duration: 0.3, ease: \"easeOut\" as const };\n            default:\n                return { type: \"spring\" as const, bounce: 0.2, duration: 0.6 };\n        }\n    };\n\n    const getExpandInitial = () => {\n        switch (variant) {\n            case \"slide-up\":\n                return { opacity: 0, y: 50 };\n            case \"rotate-scale\":\n                return { opacity: 0, scale: 0.8, rotate: -5 };\n            case \"fade-scale\":\n                return { opacity: 0, scale: 0.95 };\n            default:\n                return {};\n        }\n    };\n\n    const getExpandAnimate = () => {\n        switch (variant) {\n            case \"slide-up\":\n                return { opacity: 1, y: 0 };\n            case \"rotate-scale\":\n                return { opacity: 1, scale: 1, rotate: 0 };\n            case \"fade-scale\":\n                return { opacity: 1, scale: 1 };\n            default:\n                return {};\n        }\n    };\n\n    return (\n        <div className={cn(\"flex flex-col items-center justify-center min-h-[600px] w-full p-8 bg-zinc-50 dark:bg-zinc-900 rounded-xl overflow-hidden relative\", className)}>\n            <div className={cn(\"grid grid-cols-1 gap-4 w-full max-w-6xl relative z-10\", gridCols)}>\n                {items.map((card) => (\n                    <motion.div\n                        key={card.id}\n                        layoutId={`${id}-card-${card.id}`}\n                        onClick={() => setSelectedId(card.id)}\n                        className={cn(\n                            \"relative overflow-hidden rounded-xl cursor-pointer shadow-lg hover:shadow-xl transition-shadow bg-white dark:bg-zinc-800\",\n                            \"flex flex-col h-64 group\"\n                        )}\n                        whileHover={{ scale: 1.02 }}\n                        whileTap={{ scale: 0.98 }}\n                    >\n                        <motion.div\n                            layoutId={`${id}-image-${card.id}`}\n                            className=\"h-40 w-full overflow-hidden\"\n                        >\n                            <img\n                                src={card.image}\n                                alt={card.title}\n                                className=\"w-full h-full object-cover transition-transform duration-500 group-hover:scale-110\"\n                            />\n                        </motion.div>\n                        <div className=\"p-4\">\n                            <motion.h3\n                                layoutId={`${id}-title-${card.id}`}\n                                className=\"text-lg font-bold text-zinc-900 dark:text-zinc-100\"\n                            >\n                                {card.title}\n                            </motion.h3>\n                            <motion.p\n                                layoutId={`${id}-desc-${card.id}`}\n                                className=\"text-sm text-zinc-500 dark:text-zinc-400 mt-1\"\n                            >\n                                {card.description}\n                            </motion.p>\n                        </div>\n                    </motion.div>\n                ))}\n            </div>\n\n            <AnimatePresence>\n                {selectedId && (\n                    <>\n                        <motion.div\n                            initial={{ opacity: 0 }}\n                            animate={{ opacity: 1 }}\n                            exit={{ opacity: 0 }}\n                            onClick={() => setSelectedId(null)}\n                            className=\"absolute inset-0 bg-black/50 backdrop-blur-sm z-20\"\n                        />\n                        <div className=\"absolute inset-0 flex items-center justify-center z-30 pointer-events-none p-4\">\n                            {items\n                                .filter((c) => c.id === selectedId)\n                                .map((card) => (\n                                    <motion.div\n                                        key={card.id}\n                                        layoutId={`${id}-card-${card.id}`}\n                                        className=\"w-full max-w-lg bg-white dark:bg-zinc-900 rounded-2xl overflow-hidden shadow-2xl pointer-events-auto relative max-h-[85vh] flex flex-col\"\n                                        transition={getExpandTransition()}\n                                        initial={getExpandInitial()}\n                                        animate={getExpandAnimate()}\n                                    >\n                                        <motion.button\n                                            className=\"absolute top-4 right-4 p-2 bg-black/10 dark:bg-white/10 rounded-full text-zinc-900 dark:text-zinc-100 z-50 hover:bg-black/20 dark:hover:bg-white/20 transition-colors\"\n                                            onClick={(e) => {\n                                                e.stopPropagation();\n                                                setSelectedId(null);\n                                            }}\n                                            initial={{ opacity: 0 }}\n                                            animate={{ opacity: 1, transition: { delay: 0.2 } }}\n                                            exit={{ opacity: 0 }}\n                                        >\n                                            <X size={20} />\n                                        </motion.button>\n\n                                        <motion.div\n                                            layoutId={`${id}-image-${card.id}`}\n                                            className=\"h-64 w-full overflow-hidden flex-shrink-0\"\n                                        >\n                                            <img\n                                                src={card.image}\n                                                alt={card.title}\n                                                className=\"w-full h-full object-cover\"\n                                            />\n                                        </motion.div>\n\n                                        <div className=\"p-6 overflow-y-auto\">\n                                            <motion.h3\n                                                layoutId={`${id}-title-${card.id}`}\n                                                className=\"text-2xl font-bold text-zinc-900 dark:text-zinc-100 mb-2\"\n                                            >\n                                                {card.title}\n                                            </motion.h3>\n                                            <motion.p\n                                                layoutId={`${id}-desc-${card.id}`}\n                                                className=\"text-base text-zinc-600 dark:text-zinc-400 mb-4\"\n                                            >\n                                                {card.description}\n                                            </motion.p>\n\n                                            <motion.div\n                                                initial={{ opacity: 0, y: 20 }}\n                                                animate={{ opacity: 1, y: 0 }}\n                                                exit={{ opacity: 0, y: 10 }}\n                                                transition={{ delay: 0.1 }}\n                                                className=\"text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed space-y-4\"\n                                            >\n                                                <p>{card.longDescription}</p>\n                                            </motion.div>\n                                        </div>\n                                    </motion.div>\n                                ))}\n                        </div>\n                    </>\n                )}\n            </AnimatePresence>\n        </div>\n    );\n}\n",
      "type": "registry:component"
    }
  ]
}