{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hacker-text",
  "title": "Hacker Text",
  "description": "A text animation that scrambles letters before revealing the final text.",
  "dependencies": [],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/react/atlasui/hacker-text.tsx",
      "content": "\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { Bebas_Neue } from \"next/font/google\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst bebas = Bebas_Neue({ subsets: [\"latin\"], weight: [\"400\"] });\n\nexport const HackerText = ({\n  text,\n  className,\n}: {\n  text: string;\n  className?: string;\n}) => {\n  const letters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n  useEffect(() => {\n    const textElement = document.getElementById(\"text\");\n    let interval: NodeJS.Timeout | null = null;\n    let timeout: NodeJS.Timeout | null = null;\n\n    const scrambleText = (target: HTMLElement) => {\n      let iteration = 0;\n\n      clearInterval(interval as NodeJS.Timeout);\n\n      interval = setInterval(() => {\n        if (!target.dataset.value) return;\n\n        target.innerText = target.innerText\n          .split(\"\")\n          .map((letter, index) => {\n            if (index < iteration) {\n              return target.dataset.value![index];\n            }\n            return letters[Math.floor(Math.random() * 26)];\n          })\n          .join(\"\");\n\n        if (iteration >= target.dataset.value.length) {\n          clearInterval(interval as NodeJS.Timeout);\n        }\n\n        iteration += 1 / 3;\n      }, 30);\n    };\n\n    const applyEffect = () => {\n      if (window.matchMedia(\"(min-width: 768px)\").matches) {\n        // For non-mobile devices\n        if (textElement) {\n          textElement.addEventListener(\"mouseover\", (event) => {\n            const target = event.target as HTMLElement;\n            scrambleText(target);\n          });\n        }\n      }\n      // Run the effect after 600ms on page load for all devices\n      if (textElement) {\n        timeout = setTimeout(() => {\n          scrambleText(textElement);\n        }, 600);\n      }\n    };\n\n    applyEffect();\n\n    return () => {\n      if (textElement && window.matchMedia(\"(min-width: 768px)\").matches) {\n        textElement.removeEventListener(\"mouseover\", (event) => {\n          const target = event.target as HTMLElement;\n          scrambleText(target);\n        });\n      }\n      if (interval) {\n        clearInterval(interval);\n      }\n      if (timeout) {\n        clearTimeout(timeout);\n      }\n    };\n  }, [letters]);\n  return (\n    <span\n      id=\"text\"\n      data-value={text}\n      className={cn(\"text-4xl uppercase\", bebas.className, className)}\n    >\n      {text}\n    </span>\n  );\n};\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}