{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "logo-stepper",
  "type": "registry:ui",
  "title": "Logo Stepper",
  "description": "logo showcase with names, smooth animations, hover effects, and modern UI.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": ["motion", "clsx", "tailwind-merge"],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/logo-stepper.tsx",
      "content": "'use client';\nimport React, { useState, useEffect } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\n\ntype AnimationDirection = 'loop' | 'vloop';\n\ninterface LogoItem {\n  icon: React.ReactNode;\n  label: string;\n}\n\ninterface LogoStepperProps {\n  logos: LogoItem[];\n  animationDuration?: number;\n  animationDelay?: number;\n  direction?: AnimationDirection;\n  visibleCount?: number;\n}\n\nexport const LogoStepper: React.FC<LogoStepperProps> = ({\n  logos,\n  animationDuration = 0.6,\n  animationDelay = 1.2,\n  direction = 'loop',\n  visibleCount = 5,\n}) => {\n  const [currentIndex, setCurrentIndex] = useState(0);\n\n  useEffect(() => {\n    const interval = setInterval(() => {\n      setCurrentIndex((prev) => (prev + 1) % logos.length);\n    }, animationDelay * 1000);\n\n    return () => clearInterval(interval);\n  }, [logos.length, animationDelay]);\n\n  const getVisibleLogos = () => {\n    const visible = [];\n    const offset = Math.floor(visibleCount / 2);\n\n    for (let i = -offset; i <= offset; i++) {\n      const index = (currentIndex + i + logos.length) % logos.length;\n      visible.push({\n        logo: logos[index],\n        originalIndex: index,\n        position: i,\n      });\n    }\n\n    return visible;\n  };\n\n  const visibleLogos = getVisibleLogos();\n\n  return (\n    <div className='relative w-full flex items-start justify-center overflow-hidden py-4'>\n      <div\n        className='flex items-start justify-center gap-6'\n        style={{ width: 'fit-content' }}\n      >\n        <AnimatePresence initial={false} mode='popLayout'>\n          {visibleLogos.map(({ logo, originalIndex, position }) => {\n            let lineOpacity = 0;\n            if (position === 0) lineOpacity = 1;\n            else if (position === -1) lineOpacity = 0.3;\n            else if (position === 1) lineOpacity = 0.3;\n\n            return (\n              <motion.div\n                key={originalIndex}\n                layout='position'\n                initial={{\n                  x: direction === 'loop' ? 120 : -120,\n                  opacity: 0,\n                  scale: 0.7,\n                }}\n                animate={{\n                  x: 0,\n                  opacity: position === 0 ? 1 : 0.3,\n                  scale: position === 0 ? 1 : 0.75,\n                }}\n                exit={{\n                  x: direction === 'loop' ? -120 : 120,\n                  opacity: 0,\n                  scale: 0.7,\n                }}\n                transition={{\n                  duration: animationDuration,\n                  ease: [0.4, 0, 0.2, 1],\n                }}\n                className='flex flex-col items-center shrink-0 min-h-50 w-20'\n              >\n                <motion.div className='rounded-xl border border-border bg-card p-4 hover:border-primary transition-colors'>\n                  <div className='w-12 h-12 flex items-center justify-center'>\n                    {logo.icon}\n                  </div>\n                </motion.div>\n\n                <motion.div\n                  initial={{ opacity: 0 }}\n                  animate={{ opacity: lineOpacity }}\n                  exit={{ opacity: 0 }}\n                  transition={{\n                    duration: animationDuration,\n                    ease: [0.4, 0, 0.2, 1],\n                  }}\n                  className='flex flex-col items-center mt-4 h-28'\n                >\n                  <div className='w-0.5 h-16 mb-4 bg-border' />\n                  <span className='text-muted-foreground uppercase text-xs font-medium tracking-wider whitespace-nowrap'>\n                    {logo.label}\n                  </span>\n                </motion.div>\n              </motion.div>\n            );\n          })}\n        </AnimatePresence>\n      </div>\n    </div>\n  );\n};\n"
    },
    {
      "type": "registry:lib",
      "path": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}"
    }
  ]
}
