{
  "name": "text-loop-on-index",
  "type": "registry:ui",
  "componentName": "text-loop",
  "description": "Text loop with index-based animations and transitions.",
  "files": [
    {
      "path": "text-loop-on-index.tsx",
      "content": "'use client';\nimport { TextLoop } from '@/components/core/text-loop';\nimport { Music } from 'lucide-react';\nimport { useState } from 'react';\n\nexport function TextLoopOnIndexChange() {\n  const [direction, setDirection] = useState(-1);\n\n  return (\n    <TextLoop\n      className='text-sm'\n      transition={{\n        type: 'spring',\n        stiffness: 150,\n        damping: 19,\n        mass: 1.2,\n      }}\n      interval={2.5}\n      onIndexChange={(index) => {\n        setDirection(index === 0 ? -1 : 1);\n      }}\n      variants={{\n        initial: {\n          y: -direction * 20,\n          rotateX: -direction * 90,\n          opacity: 0,\n          filter: 'blur(4px)',\n        },\n        animate: {\n          y: 0,\n          rotateX: 0,\n          opacity: 1,\n          filter: 'blur(0px)',\n        },\n        exit: {\n          y: -direction * 20,\n          rotateX: -direction * 90,\n          opacity: 0,\n          filter: 'blur(4px)',\n        },\n      }}\n    >\n      <span>\n        <Music size={12} className='mr-1 inline-block' />A Little Lost・Arthur\n        Russell\n      </span>\n      <span>La Trinité, Martinique</span>\n    </TextLoop>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/text-loop.tsx",
      "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport {\n  motion,\n  AnimatePresence,\n  Transition,\n  Variants,\n  AnimatePresenceProps,\n} from 'motion/react';\nimport { useState, useEffect, Children } from 'react';\n\nexport type TextLoopProps = {\n  children: React.ReactNode[];\n  className?: string;\n  interval?: number;\n  transition?: Transition;\n  variants?: Variants;\n  onIndexChange?: (index: number) => void;\n  trigger?: boolean;\n  mode?: AnimatePresenceProps['mode'];\n};\n\nexport function TextLoop({\n  children,\n  className,\n  interval = 2,\n  transition = { duration: 0.3 },\n  variants,\n  onIndexChange,\n  trigger = true,\n  mode = 'popLayout',\n}: TextLoopProps) {\n  const [currentIndex, setCurrentIndex] = useState(0);\n  const items = Children.toArray(children);\n\n  useEffect(() => {\n    if (!trigger) return;\n\n    const intervalMs = interval * 1000;\n    const timer = setInterval(() => {\n      setCurrentIndex((current) => {\n        const next = (current + 1) % items.length;\n        onIndexChange?.(next);\n        return next;\n      });\n    }, intervalMs);\n    return () => clearInterval(timer);\n  }, [items.length, interval, onIndexChange, trigger]);\n\n  const motionVariants: Variants = {\n    initial: { y: 20, opacity: 0 },\n    animate: { y: 0, opacity: 1 },\n    exit: { y: -20, opacity: 0 },\n  };\n\n  return (\n    <div className={cn('relative inline-block whitespace-nowrap', className)}>\n      <AnimatePresence mode={mode} initial={false}>\n        <motion.div\n          key={currentIndex}\n          initial='initial'\n          animate='animate'\n          exit='exit'\n          transition={transition}\n          variants={variants || motionVariants}\n        >\n          {items[currentIndex]}\n        </motion.div>\n      </AnimatePresence>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}