{
  "title": "Scramble Text",
  "description": "A hover-triggered text effect that scrambles and restores characters with smooth motion",
  "name": "motion-scramble-text",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [],
  "type": "registry:ui",
  "files": [
    {
      "path": "components/paceui/motion/scramble-text.tsx",
      "type": "registry:ui",
      "content": "import { type ComponentProps, useCallback, useEffect, useRef } from \"react\";\n\nimport { animate } from \"motion/react\";\n\ntype ScrambleTextProps = {\n    random?: boolean;\n    scrambleOnLoad?: boolean;\n} & ComponentProps<\"div\">;\n\nconst defaultChars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\nexport const ScrambleText = ({ scrambleOnLoad = true, random = true, ...props }: ScrambleTextProps) => {\n    const wrapperRef = useRef<HTMLDivElement | null>(null);\n    const originalText = useRef<string | null>(null);\n    const isAnimating = useRef<boolean>(false);\n\n    const scramble = useCallback(() => {\n        const target = wrapperRef.current;\n        if (!target || isAnimating.current) return;\n\n        if (originalText.current === null) {\n            originalText.current = target.innerText;\n        }\n\n        const text = originalText.current;\n        const chars = random ? defaultChars : text.replace(/\\s/g, \"\");\n        const length = text.length;\n\n        isAnimating.current = true;\n\n        animate(0, length, {\n            duration: 1,\n            ease: \"easeIn\",\n            onUpdate: (latest) => {\n                const progress = Math.floor(latest);\n                let scrambled = \"\";\n                for (let i = 0; i < length; i++) {\n                    if (text[i] === \" \") {\n                        scrambled += \" \";\n                    } else if (i < progress) {\n                        scrambled += text[i];\n                    } else {\n                        scrambled += chars[Math.floor(Math.random() * chars.length)];\n                    }\n                }\n                target.innerText = scrambled;\n            },\n            onComplete: () => {\n                target.innerText = text;\n                isAnimating.current = false;\n            },\n        });\n    }, [random]);\n\n    useEffect(() => {\n        if (scrambleOnLoad) scramble();\n        const target = wrapperRef.current;\n        if (target) {\n            target.addEventListener(\"pointerenter\", scramble);\n            return () => target.removeEventListener(\"pointerenter\", scramble);\n        }\n    }, [scramble, scrambleOnLoad]);\n\n    return <div {...props} ref={wrapperRef} />;\n};\n"
    }
  ],
  "mcp": {
    "description": "Provides refined UI interactions and accessible controls. A hover-triggered text effect that scrambles and restores characters with smooth motion Configurable props include: {; random?: boolean;; scrambleOnLoad?: boolean;. Relies on motion. Optimal for building reusable interface elements and user input flows.",
    "tags": [
      "component",
      "motion",
      "animation"
    ]
  }
}