{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "random-letter-swap-hover",
  "type": "registry:block",
  "title": "Random letter swap hover",
  "description": "Random letter swap hover",
  "files": [
    {
      "path": "components/usages/randomletterswaphoverusage.tsx",
      "content": "\"use client\";\r\n\r\nimport React from \"react\";\r\n\r\nimport {\r\n\tRandomLetterSwapForward,\r\n\tRandomLetterSwapPingPong,\r\n} from \"@/registry/open-source/random-letter-swap-hover\";\r\n\r\nexport default function Usage() {\r\n\treturn (\r\n\t\t<div className=\"h-screen w-full flex items-center justify-center relative overflow-hidden bg-background\">\r\n\t\t\t<div className=\"w-dvw h-dvh rounded-lg bg-background text-3xl md:text-5xl flex flex-col items-center justify-center font-overused-grotesk\">\r\n\t\t\t\t<div className=\"h-full text-red-500 rounded-xl py-12  align-text-center gap-y-1 md:gap-y-2 flex flex-col justify-center items-center\">\r\n\t\t\t\t\t<RandomLetterSwapForward\r\n\t\t\t\t\t\tlabel=\"Right here!\"\r\n\t\t\t\t\t\treverse={true}\r\n\t\t\t\t\t\tclassName=\"\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t<RandomLetterSwapForward\r\n\t\t\t\t\t\tlabel=\"Right now!\"\r\n\t\t\t\t\t\treverse={false}\r\n\t\t\t\t\t\tclassName=\"font-bold italic px-4\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t<RandomLetterSwapPingPong label=\"Right here!\" className=\"\" />\r\n\t\t\t\t\t<RandomLetterSwapPingPong\r\n\t\t\t\t\t\tlabel=\"Right now!\"\r\n\t\t\t\t\t\treverse={false}\r\n\t\t\t\t\t\tclassName=\" font-bold\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n}\r\n",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/randomletterswaphoverusage.tsx",
      "content": "\"use client\";\r\n\r\nimport React from \"react\";\r\n\r\nimport {\r\n\tRandomLetterSwapForward,\r\n\tRandomLetterSwapPingPong,\r\n} from \"@/registry/open-source/random-letter-swap-hover\";\r\n\r\nexport default function Usage() {\r\n\treturn (\r\n\t\t<div className=\"h-screen w-full flex items-center justify-center relative overflow-hidden bg-background\">\r\n\t\t\t<div className=\"w-dvw h-dvh rounded-lg bg-background text-3xl md:text-5xl flex flex-col items-center justify-center font-overused-grotesk\">\r\n\t\t\t\t<div className=\"h-full text-red-500 rounded-xl py-12  align-text-center gap-y-1 md:gap-y-2 flex flex-col justify-center items-center\">\r\n\t\t\t\t\t<RandomLetterSwapForward\r\n\t\t\t\t\t\tlabel=\"Right here!\"\r\n\t\t\t\t\t\treverse={true}\r\n\t\t\t\t\t\tclassName=\"\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t<RandomLetterSwapForward\r\n\t\t\t\t\t\tlabel=\"Right now!\"\r\n\t\t\t\t\t\treverse={false}\r\n\t\t\t\t\t\tclassName=\"font-bold italic px-4\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t<RandomLetterSwapPingPong label=\"Right here!\" className=\"\" />\r\n\t\t\t\t\t<RandomLetterSwapPingPong\r\n\t\t\t\t\t\tlabel=\"Right now!\"\r\n\t\t\t\t\t\treverse={false}\r\n\t\t\t\t\t\tclassName=\" font-bold\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n}\r\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/random-letter-swap-hover.tsx",
      "content": "\"use client\";\n\nimport { useState } from \"react\";\n\nimport { debounce } from \"lodash\";\nimport { DynamicAnimationOptions, motion, useAnimate } from \"motion/react\";\n\n// Credit:\n// https://www.fancycomponents.dev/docs/components/text/random-letter-swap\n\ninterface TextProps {\n\tlabel: string;\n\treverse?: boolean;\n\ttransition?: DynamicAnimationOptions;\n\tstaggerDuration?: number;\n\tclassName?: string;\n\tonClick?: () => void;\n}\n\nconst RandomLetterSwapForward = ({\n\tlabel,\n\treverse = true,\n\ttransition = {\n\t\ttype: \"spring\",\n\t\tduration: 0.8,\n\t},\n\tstaggerDuration = 0.02,\n\tclassName,\n\tonClick,\n\t...props\n}: TextProps) => {\n\tconst [scope, animate] = useAnimate();\n\tconst [blocked, setBlocked] = useState(false);\n\n\tconst mergeTransition = (\n\t\ttransition: DynamicAnimationOptions,\n\t\ti: number\n\t) => ({\n\t\t...transition,\n\t\tdelay: i * staggerDuration,\n\t});\n\n\tconst shuffledIndices = Array.from(\n\t\t{ length: label.length },\n\t\t(_, i) => i\n\t).sort(() => Math.random() - 0.5);\n\n\tconst hoverStart = debounce(\n\t\t() => {\n\t\t\tif (blocked) return;\n\t\t\tsetBlocked(true);\n\n\t\t\tfor (let i = 0; i < label.length; i++) {\n\t\t\t\tconst randomIndex = shuffledIndices[i];\n\t\t\t\tanimate(\n\t\t\t\t\t\".letter-\" + randomIndex,\n\t\t\t\t\t{\n\t\t\t\t\t\ty: reverse ? \"100%\" : \"-100%\",\n\t\t\t\t\t},\n\t\t\t\t\tmergeTransition(transition, i)\n\t\t\t\t).then(() => {\n\t\t\t\t\tanimate(\n\t\t\t\t\t\t\".letter-\" + randomIndex,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ty: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tduration: 0,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tanimate(\n\t\t\t\t\t\".letter-secondary-\" + randomIndex,\n\t\t\t\t\t{\n\t\t\t\t\t\ttop: \"0%\",\n\t\t\t\t\t},\n\t\t\t\t\tmergeTransition(transition, i)\n\t\t\t\t)\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tanimate(\n\t\t\t\t\t\t\t\".letter-secondary-\" + randomIndex,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttop: reverse ? \"-100%\" : \"100%\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tduration: 0,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t})\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (i === label.length - 1) {\n\t\t\t\t\t\t\tsetBlocked(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t100,\n\t\t{ leading: true, trailing: true }\n\t);\n\n\treturn (\n\t\t<motion.span\n\t\t\tclassName={`flex justify-center items-center relative overflow-hidden ${className}`}\n\t\t\tonHoverStart={hoverStart}\n\t\t\tonClick={onClick}\n\t\t\tref={scope}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"sr-only\">{label}</span>\n\n\t\t\t{label.split(\"\").map((letter: string, i: number) => {\n\t\t\t\treturn (\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName=\"whitespace-pre relative flex\"\n\t\t\t\t\t\tkey={i + \"random-letter-swap\"}\n\t\t\t\t\t>\n\t\t\t\t\t\t<motion.span\n\t\t\t\t\t\t\tclassName={`relative pb-2 letter-${i}`}\n\t\t\t\t\t\t\tstyle={{ top: 0 }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{letter}\n\t\t\t\t\t\t</motion.span>\n\t\t\t\t\t\t<motion.span\n\t\t\t\t\t\t\tclassName={`absolute letter-secondary-${i}`}\n\t\t\t\t\t\t\taria-hidden={true}\n\t\t\t\t\t\t\tstyle={{ top: reverse ? \"-100%\" : \"100%\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{letter}\n\t\t\t\t\t\t</motion.span>\n\t\t\t\t\t</span>\n\t\t\t\t);\n\t\t\t})}\n\t\t</motion.span>\n\t);\n};\n\nconst RandomLetterSwapPingPong = ({\n\tlabel,\n\treverse = true,\n\ttransition = {\n\t\ttype: \"spring\",\n\t\tduration: 0.8,\n\t},\n\tstaggerDuration = 0.02,\n\tclassName,\n\tonClick,\n\t...props\n}: TextProps) => {\n\tconst [scope, animate] = useAnimate();\n\tconst [blocked, setBlocked] = useState(false);\n\n\tconst mergeTransition = (\n\t\ttransition: DynamicAnimationOptions,\n\t\ti: number\n\t) => ({\n\t\t...transition,\n\t\tdelay: i * staggerDuration,\n\t});\n\n\tconst shuffledIndices = Array.from(\n\t\t{ length: label.length },\n\t\t(_, i) => i\n\t).sort(() => Math.random() - 0.5);\n\n\tconst hoverStart = debounce(\n\t\t() => {\n\t\t\tif (blocked) return;\n\t\t\tsetBlocked(true);\n\n\t\t\tfor (let i = 0; i < label.length; i++) {\n\t\t\t\tconst randomIndex = shuffledIndices[i];\n\t\t\t\tanimate(\n\t\t\t\t\t\".letter-\" + randomIndex,\n\t\t\t\t\t{\n\t\t\t\t\t\ty: reverse ? \"100%\" : \"-100%\",\n\t\t\t\t\t},\n\t\t\t\t\tmergeTransition(transition, i)\n\t\t\t\t);\n\n\t\t\t\tanimate(\n\t\t\t\t\t\".letter-secondary-\" + randomIndex,\n\t\t\t\t\t{\n\t\t\t\t\t\ttop: \"0%\",\n\t\t\t\t\t},\n\t\t\t\t\tmergeTransition(transition, i)\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t100,\n\t\t{ leading: true, trailing: true }\n\t);\n\n\tconst hoverEnd = debounce(\n\t\t() => {\n\t\t\tsetBlocked(false);\n\n\t\t\tfor (let i = 0; i < label.length; i++) {\n\t\t\t\tconst randomIndex = shuffledIndices[i];\n\t\t\t\tanimate(\n\t\t\t\t\t\".letter-\" + randomIndex,\n\t\t\t\t\t{\n\t\t\t\t\t\ty: 0,\n\t\t\t\t\t},\n\t\t\t\t\tmergeTransition(transition, i)\n\t\t\t\t);\n\n\t\t\t\tanimate(\n\t\t\t\t\t\".letter-secondary-\" + randomIndex,\n\t\t\t\t\t{\n\t\t\t\t\t\ttop: reverse ? \"-100%\" : \"100%\",\n\t\t\t\t\t},\n\t\t\t\t\tmergeTransition(transition, i)\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t100,\n\t\t{ leading: true, trailing: true }\n\t);\n\n\treturn (\n\t\t<motion.span\n\t\t\tclassName={`flex justify-center items-center relative overflow-hidden  ${className} `}\n\t\t\tonHoverStart={hoverStart}\n\t\t\tonHoverEnd={hoverEnd}\n\t\t\tonClick={onClick}\n\t\t\tref={scope}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"sr-only\">{label}</span>\n\n\t\t\t{label.split(\"\").map((letter: string, i: number) => {\n\t\t\t\treturn (\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName=\"whitespace-pre relative flex\"\n\t\t\t\t\t\tkey={i + \"random-letter-swap-hover\"}\n\t\t\t\t\t>\n\t\t\t\t\t\t<motion.span\n\t\t\t\t\t\t\tclassName={`relative pb-2 letter-${i}`}\n\t\t\t\t\t\t\tstyle={{ top: 0 }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{letter}\n\t\t\t\t\t\t</motion.span>\n\t\t\t\t\t\t<motion.span\n\t\t\t\t\t\t\tclassName={`absolute letter-secondary-${i}`}\n\t\t\t\t\t\t\taria-hidden={true}\n\t\t\t\t\t\t\tstyle={{ top: reverse ? \"-100%\" : \"100%\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{letter}\n\t\t\t\t\t\t</motion.span>\n\t\t\t\t\t</span>\n\t\t\t\t);\n\t\t\t})}\n\t\t</motion.span>\n\t);\n};\n\nexport { RandomLetterSwapForward, RandomLetterSwapPingPong };\n",
      "type": "registry:ui"
    }
  ]
}