{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"motion-primitives-infinite-slider","type":"registry:component","title":"Infinite Slider","description":"Tailark motion primitives infinite-slider component","dependencies":["motion","react-use-measure"],"registryDependencies":["@tailark/core-utils"],"files":[{"path":"core/motion-primitives/infinite-slider.tsx","type":"registry:component","target":"@ui/motion-primitives/infinite-slider.tsx","content":"'use client'\nimport { cn } from '@/lib/utils'\nimport { LazyMotion, domAnimation, m, useMotionValue, animate } from 'motion/react'\nimport { useState, useEffect, type ReactNode } from 'react'\nimport useMeasure from 'react-use-measure'\n\nexport type InfiniteSliderProps = {\n    children: 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({ children, gap = 16, speed = 100, speedOnHover, direction = 'horizontal', reverse = false, className }: 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    }, [key, translation, currentSpeed, width, height, gap, isTransitioning, direction, reverse])\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        <LazyMotion features={domAnimation}>\n        <div className={cn('overflow-hidden', className)}>\n            <m.div\n                className=\"flex w-max\"\n                style={{\n                    ...(direction === 'horizontal' ? { x: translation } : { y: translation }),\n                    gap: `${gap}px`,\n                    flexDirection: direction === 'horizontal' ? 'row' : 'column',\n                }}\n                ref={ref}\n                {...hoverProps}>\n                {children}\n                {children}\n            </m.div>\n        </div>\n    \n        </LazyMotion>)\n}\n"}]}