{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitives-texts-rotating",
  "title": "Rotating Text",
  "description": "A rotating text animation.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "@unlumen-ui/hooks-use-is-in-view",
    "@unlumen-ui/lib-get-strict-context"
  ],
  "files": [
    {
      "path": "registry/primitives/texts/rotating/index.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { motion, AnimatePresence, type HTMLMotionProps } from \"motion/react\";\n\nimport {\n  useIsInView,\n  type UseIsInViewOptions,\n} from \"@/hooks/use-is-in-view\";\nimport { getStrictContext } from \"@/lib/get-strict-context\";\n\ntype RotatingTextContextType = {\n  currentText: string;\n  y: number;\n  isInView: boolean;\n};\n\nconst [RotatingTextProvider, useRotatingText] =\n  getStrictContext<RotatingTextContextType>(\"RotatingTextContext\");\n\ntype RotatingTextContainerProps = React.ComponentProps<\"div\"> & {\n  text: string | string[];\n  duration?: number;\n  y?: number;\n  delay?: number;\n} & UseIsInViewOptions;\n\nfunction RotatingTextContainer({\n  ref,\n  text,\n  y = -50,\n  duration = 2000,\n  delay = 0,\n  style,\n  inView = false,\n  inViewMargin = \"0px\",\n  inViewOnce = true,\n  ...props\n}: RotatingTextContainerProps) {\n  const [index, setIndex] = React.useState(0);\n\n  const { ref: localRef, isInView } = useIsInView(\n    ref as React.Ref<HTMLDivElement>,\n    {\n      inView,\n      inViewOnce,\n      inViewMargin,\n    },\n  );\n\n  React.useEffect(() => {\n    if (!Array.isArray(text)) return;\n    if (inView && !isInView) return;\n\n    let intervalId: ReturnType<typeof setInterval> | undefined;\n\n    const timeoutId = setTimeout(() => {\n      setIndex((prev) => (prev + 1) % text.length);\n      intervalId = setInterval(\n        () => setIndex((prev) => (prev + 1) % text.length),\n        duration,\n      );\n    }, delay);\n\n    return () => {\n      clearTimeout(timeoutId);\n      if (intervalId) clearInterval(intervalId);\n    };\n  }, [text, duration, delay, inView, isInView]);\n\n  const currentText = Array.isArray(text) ? text[index] : text;\n\n  return (\n    <RotatingTextProvider value={{ currentText, y, isInView }}>\n      <div\n        ref={localRef}\n        style={{\n          overflow: \"hidden\",\n          paddingBlock: \"0.25rem\",\n          ...style,\n        }}\n        {...props}\n      />\n    </RotatingTextProvider>\n  );\n}\n\ntype RotatingTextProps = Omit<HTMLMotionProps<\"div\">, \"children\">;\n\nfunction RotatingText({\n  transition = { duration: 0.3, ease: \"easeOut\" },\n  ...props\n}: RotatingTextProps) {\n  const { currentText, y, isInView } = useRotatingText();\n\n  return (\n    <AnimatePresence mode=\"wait\">\n      {isInView && (\n        <motion.div\n          key={currentText}\n          transition={transition}\n          initial={{ opacity: 0, y: -y }}\n          animate={{ opacity: 1, y: 0 }}\n          exit={{ opacity: 0, y }}\n          {...props}\n        >\n          {currentText}\n        </motion.div>\n      )}\n    </AnimatePresence>\n  );\n}\n\nexport {\n  RotatingTextContainer,\n  RotatingText,\n  useRotatingText,\n  type RotatingTextContainerProps,\n  type RotatingTextProps,\n  type RotatingTextContextType,\n};\n",
      "type": "registry:ui",
      "target": "components/unlumen-ui/primitives/texts/rotating.tsx"
    }
  ],
  "type": "registry:ui"
}