{ "name": "infinite-slider", "type": "registry:ui", "registryDependencies": [], "dependencies": [ "motion", "react-use-measure" ], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "infinite-slider.tsx", "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport { useMotionValue, animate, motion } from 'motion/react';\nimport { useState, useEffect } from 'react';\nimport useMeasure from 'react-use-measure';\n\nexport type InfiniteSliderProps = {\n children: React.ReactNode;\n gap?: number;\n speed?: number;\n speedOnHover?: number;\n direction?: 'horizontal' | 'vertical';\n reverse?: boolean;\n className?: string;\n};\n\nexport function InfiniteSlider({\n children,\n gap = 16,\n speed = 100,\n speedOnHover,\n direction = 'horizontal',\n reverse = false,\n className,\n}: InfiniteSliderProps) {\n const [currentSpeed, setCurrentSpeed] = useState(speed);\n const [ref, { width, height }] = useMeasure();\n const translation = useMotionValue(0);\n const [isTransitioning, setIsTransitioning] = useState(false);\n const [key, setKey] = useState(0);\n\n useEffect(() => {\n let controls;\n const size = direction === 'horizontal' ? width : height;\n const contentSize = size + gap;\n const from = reverse ? -contentSize / 2 : 0;\n const to = reverse ? 0 : -contentSize / 2;\n\n const distanceToTravel = Math.abs(to - from);\n const duration = distanceToTravel / currentSpeed;\n\n if (isTransitioning) {\n const remainingDistance = Math.abs(translation.get() - to);\n const transitionDuration = remainingDistance / currentSpeed;\n\n controls = animate(translation, [translation.get(), to], {\n ease: 'linear',\n duration: transitionDuration,\n onComplete: () => {\n setIsTransitioning(false);\n setKey((prevKey) => prevKey + 1);\n },\n });\n } else {\n controls = animate(translation, [from, to], {\n ease: 'linear',\n duration: duration,\n repeat: Infinity,\n repeatType: 'loop',\n repeatDelay: 0,\n onRepeat: () => {\n translation.set(from);\n },\n });\n }\n\n return controls?.stop;\n }, [\n key,\n translation,\n currentSpeed,\n width,\n height,\n gap,\n isTransitioning,\n direction,\n reverse,\n ]);\n\n const hoverProps = speedOnHover\n ? {\n onHoverStart: () => {\n setIsTransitioning(true);\n setCurrentSpeed(speedOnHover);\n },\n onHoverEnd: () => {\n setIsTransitioning(true);\n setCurrentSpeed(speed);\n },\n }\n : {};\n\n return (\n
\n \n {children}\n {children}\n \n
\n );\n}\n", "type": "registry:ui" } ] }