{ "name": "text-loop", "type": "registry:ui", "registryDependencies": [], "dependencies": [ "motion" ], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "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