{
  "name": "matrix-text",
  "type": "registry:component",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "type": "registry:component",
      "content": "\"use client\";\n\n/**\n * @author: @dorianbaffier\n * @description: Matrix Text\n * @version: 1.0.0\n * @date: 2025-06-26\n * @license: MIT\n * @website: https://kokonutui.com\n * @github: https://github.com/kokonut-labs/kokonutui\n */\n\nimport { motion } from \"motion/react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface LetterState {\n  char: string;\n  isMatrix: boolean;\n  isSpace: boolean;\n}\n\ninterface MatrixTextProps {\n  text?: string;\n  className?: string;\n  initialDelay?: number;\n  letterAnimationDuration?: number;\n  letterInterval?: number;\n}\n\nconst MatrixText = ({\n  text = \"HelloWorld!\",\n  className,\n  initialDelay = 200,\n  letterAnimationDuration = 500,\n  letterInterval = 100,\n}: MatrixTextProps) => {\n  const [letters, setLetters] = useState<LetterState[]>(() =>\n    text.split(\"\").map((char) => ({\n      char,\n      isMatrix: false,\n      isSpace: char === \" \",\n    }))\n  );\n  const [isAnimating, setIsAnimating] = useState(false);\n\n  const getRandomChar = useCallback(\n    () => (Math.random() > 0.5 ? \"1\" : \"0\"),\n    []\n  );\n\n  const animateLetter = useCallback(\n    (index: number) => {\n      if (index >= text.length) return;\n\n      requestAnimationFrame(() => {\n        setLetters((prev) => {\n          const newLetters = [...prev];\n          if (!newLetters[index].isSpace) {\n            newLetters[index] = {\n              ...newLetters[index],\n              char: getRandomChar(),\n              isMatrix: true,\n            };\n          }\n          return newLetters;\n        });\n\n        setTimeout(() => {\n          setLetters((prev) => {\n            const newLetters = [...prev];\n            newLetters[index] = {\n              ...newLetters[index],\n              char: text[index],\n              isMatrix: false,\n            };\n            return newLetters;\n          });\n        }, letterAnimationDuration);\n      });\n    },\n    [getRandomChar, text, letterAnimationDuration]\n  );\n\n  const startAnimation = useCallback(() => {\n    if (isAnimating) return;\n\n    setIsAnimating(true);\n    let currentIndex = 0;\n\n    const animate = () => {\n      if (currentIndex >= text.length) {\n        setIsAnimating(false);\n        return;\n      }\n\n      animateLetter(currentIndex);\n      currentIndex++;\n      setTimeout(animate, letterInterval);\n    };\n\n    animate();\n  }, [animateLetter, text, isAnimating, letterInterval]);\n\n  useEffect(() => {\n    const timer = setTimeout(startAnimation, initialDelay);\n    return () => clearTimeout(timer);\n  }, []);\n\n  const motionVariants = useMemo(\n    () => ({\n      // initial: {\n      //     color: \"rgb(var(--foreground-rgb))\",\n      // },\n      matrix: {\n        color: \"#00ff00\",\n        textShadow: \"0 2px 4px rgba(0, 255, 0, 0.5)\",\n      },\n      // normal: {\n      //     color: \"rgb(var(--foreground-rgb))\",\n      //     textShadow: \"none\",\n      // },\n    }),\n    []\n  );\n\n  return (\n    <div\n      aria-label=\"Matrix text animation\"\n      className={cn(\n        \"flex min-h-screen items-center justify-center text-black dark:text-white\",\n        className\n      )}\n    >\n      <div className=\"flex h-24 items-center justify-center\">\n        <div className=\"flex flex-wrap items-center justify-center\">\n          {letters.map((letter, index) => (\n            <motion.div\n              animate={letter.isMatrix ? \"matrix\" : \"normal\"}\n              className=\"w-[1ch] overflow-hidden text-center font-mono text-4xl md:text-6xl\"\n              initial=\"initial\"\n              key={`${index}-${letter.char}`}\n              style={{\n                display: \"inline-block\",\n                fontVariantNumeric: \"tabular-nums\",\n              }}\n              transition={{\n                duration: 0.1,\n                ease: \"easeInOut\",\n              }}\n              variants={motionVariants}\n            >\n              {letter.isSpace ? \"\\u00A0\" : letter.char}\n            </motion.div>\n          ))}\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport default MatrixText;\n",
      "path": "/components/kokonutui/matrix-text.tsx",
      "target": "components/kokonutui/matrix-text.tsx"
    }
  ]
}