{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "word-rotate",
  "type": "registry:component",
  "title": "Word rotate",
  "description": "Rotates words inside a sentence: the old word lifts and blurs away as the next rises in. The slot keeps the widest word's width so the line never jumps.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/premium/word-rotate.tsx",
      "type": "registry:ui",
      "target": "components/ui/word-rotate.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Cycles through a list of words in place: the old word lifts and blurs out,\n * the next rises in. The slot keeps the width of the longest word so the\n * sentence around it never jumps. Screen readers hear the full list once.\n */\ntype WordRotateProps = {\n  words?: string[]\n  /** Milliseconds each word stays. */\n  interval?: number\n  className?: string\n  /** Text before the rotating word. */\n  prefix?: React.ReactNode\n}\n\nfunction WordRotate({ words = [\"startups\", \"agencies\", \"fintech\", \"health\", \"AI products\"], interval = 2200, className, prefix = \"Interfaces for\" }: WordRotateProps) {\n  const reduce = useReducedMotion()\n  const [i, setI] = React.useState(0)\n  React.useEffect(() => {\n    if (reduce || words.length < 2) return\n    const id = window.setInterval(() => setI((n) => (n + 1) % words.length), interval)\n    return () => window.clearInterval(id)\n  }, [words.length, interval, reduce])\n  const longest = words.reduce((a, b) => (b.length > a.length ? b : a), \"\")\n  return (\n    <span data-slot=\"word-rotate\" className={cn(\"inline-flex flex-wrap items-baseline gap-x-[0.28em] text-4xl font-medium tracking-[-0.045em] text-fg sm:text-5xl\", className)}>\n      {prefix ? <span>{prefix}</span> : null}\n      <span className=\"sr-only\">{words.join(\", \")}</span>\n      <span aria-hidden className=\"relative inline-grid\">\n        <span className=\"invisible col-start-1 row-start-1\">{longest}</span>\n        <AnimatePresence mode=\"popLayout\" initial={false}>\n          <motion.span\n            key={words[i]}\n            className=\"col-start-1 row-start-1 text-accent-fg\"\n            initial={{ y: \"0.6em\", opacity: 0, filter: \"blur(6px)\" }}\n            animate={{ y: 0, opacity: 1, filter: \"blur(0px)\" }}\n            exit={{ y: \"-0.6em\", opacity: 0, filter: \"blur(6px)\" }}\n            transition={{ type: \"spring\", bounce: 0.15, duration: 0.55 }}\n          >\n            {words[i]}\n          </motion.span>\n        </AnimatePresence>\n      </span>\n    </span>\n  )\n}\n\nexport { WordRotate }\nexport type { WordRotateProps }\n"
    }
  ]
}
