{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitive-marquee",
  "type": "registry:ui",
  "title": "Marquee",
  "description": "Continuously scroll overflowing content and pause it on hover or focus.",
  "dependencies": [
    "motion"
  ],
  "categories": [
    "primitive",
    "loops"
  ],
  "docs": "https://motion-lexicon.pages.dev/en/primitives/marquee/",
  "files": [
    {
      "path": "src/registry/primitives/marquee.tsx",
      "type": "registry:ui",
      "target": "components/motion-lexicon/primitives/marquee.tsx",
      "content": "\"use client\";\n\nimport { motion, useAnimationControls, useReducedMotion } from \"motion/react\";\nimport { useEffect, type ReactNode } from \"react\";\n\nexport type MarqueePrimitiveProps = {\n  children: ReactNode;\n  duration?: number;\n  gap?: number;\n  direction?: \"left\" | \"right\";\n  pauseOnHover?: boolean;\n  className?: string;\n  trackClassName?: string;\n};\n\nexport function MarqueePrimitive({\n  children,\n  duration = 8,\n  gap = 32,\n  direction = \"left\",\n  pauseOnHover = true,\n  className,\n  trackClassName,\n}: MarqueePrimitiveProps) {\n  const reduceMotion = useReducedMotion();\n  const controls = useAnimationControls();\n  const target = direction === \"left\" ? \"translate3d(-50%, 0, 0)\" : \"translate3d(0%, 0, 0)\";\n  const initial = direction === \"left\" ? \"translate3d(0%, 0, 0)\" : \"translate3d(-50%, 0, 0)\";\n\n  useEffect(() => {\n    if (reduceMotion) return;\n    void controls.start({ transform: target }, { duration, ease: \"linear\", repeat: Infinity });\n    return () => controls.stop();\n  }, [controls, duration, reduceMotion, target]);\n\n  const resume = () => {\n    if (!pauseOnHover || reduceMotion) return;\n    void controls.start({ transform: target }, { duration, ease: \"linear\", repeat: Infinity });\n  };\n\n  return (\n    <div\n      className={`overflow-hidden ${className ?? \"\"}`}\n      onPointerEnter={() => pauseOnHover && controls.stop()}\n      onPointerLeave={resume}\n      onFocus={() => pauseOnHover && controls.stop()}\n      onBlur={resume}\n    >\n      <motion.div\n        className={`flex w-max ${trackClassName ?? \"\"}`}\n        style={{ gap }}\n        initial={{ transform: initial }}\n        animate={controls}\n      >\n        <span className=\"flex shrink-0 items-center\" style={{ gap }}>{children}</span>\n        <span aria-hidden=\"true\" className=\"flex shrink-0 items-center\" style={{ gap }}>{children}</span>\n      </motion.div>\n    </div>\n  );\n}\n"
    }
  ]
}
