{
  "name": "text-scramble-custom-char-duration",
  "type": "registry:ui",
  "componentName": "text-scramble",
  "description": "Text scramble with custom character animation durations.",
  "files": [
    {
      "path": "text-scramble-custom-char-duration.tsx",
      "content": "import { TextScramble } from '@/components/core/text-scramble';\n\nexport function TextScrambleCustomCharacterDuration() {\n  return (\n    <TextScramble\n      className='font-mono text-sm'\n      duration={1.2}\n      characterSet='. '\n    >\n      Generating the interface...\n    </TextScramble>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "components/core/text-scramble.tsx",
      "content": "'use client';\nimport { type JSX, useEffect, useState } from 'react';\nimport { motion, MotionProps } from 'motion/react';\n\nexport type TextScrambleProps = {\n  children: string;\n  duration?: number;\n  speed?: number;\n  characterSet?: string;\n  as?: React.ElementType;\n  className?: string;\n  trigger?: boolean;\n  onScrambleComplete?: () => void;\n} & MotionProps;\n\nconst defaultChars =\n  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\nexport function TextScramble({\n  children,\n  duration = 0.8,\n  speed = 0.04,\n  characterSet = defaultChars,\n  className,\n  as: Component = 'p',\n  trigger = true,\n  onScrambleComplete,\n  ...props\n}: TextScrambleProps) {\n  const MotionComponent = motion.create(\n    Component as keyof JSX.IntrinsicElements\n  );\n  const [scrambledText, setScrambledText] = useState<string | null>(null);\n  const displayText = scrambledText ?? children;\n\n  useEffect(() => {\n    if (!trigger) {\n      setScrambledText(null);\n      return;\n    }\n\n    const steps = Math.max(1, duration / speed);\n    let step = 0;\n\n    const interval = window.setInterval(() => {\n      let scrambled = '';\n      const progress = step / steps;\n\n      for (let i = 0; i < children.length; i++) {\n        if (children[i] === ' ') {\n          scrambled += ' ';\n          continue;\n        }\n\n        if (progress * children.length > i) {\n          scrambled += children[i];\n        } else {\n          scrambled +=\n            characterSet[Math.floor(Math.random() * characterSet.length)];\n        }\n      }\n\n      setScrambledText(scrambled);\n      step++;\n\n      if (step > steps) {\n        window.clearInterval(interval);\n        setScrambledText(null);\n        onScrambleComplete?.();\n      }\n    }, speed * 1000);\n\n    return () => window.clearInterval(interval);\n  }, [characterSet, children, duration, onScrambleComplete, speed, trigger]);\n\n  return (\n    <MotionComponent className={className} {...props}>\n      {displayText}\n    </MotionComponent>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}