{
    "name": "squash-text",
    "title": "Squash Text",
    "description": "Characters bounce and squash into place with playful, dynamic energy.",
    "type": "registry:ui",
    "dependencies": ["gsap", "@gsap/react"],
    "files": [
        {
            "path": "components/gsap/squash-text.tsx",
            "type": "registry:ui",
            "target": "~/components/gsap/squash-text.tsx",
            "content": "\"use client\";\n\nimport { ComponentProps, useId, useRef } from \"react\";\n\nimport { useGSAP } from \"@gsap/react\";\nimport gsap from \"gsap\";\nimport { CustomBounce } from \"gsap/CustomBounce\";\nimport { CustomEase } from \"gsap/CustomEase\";\nimport { SplitText } from \"gsap/SplitText\";\n\n// Ensure plugins are registered globally\nif (typeof window !== \"undefined\") {\n    gsap.registerPlugin(CustomEase, CustomBounce, SplitText);\n}\n\ntype SquashTextProps = {\n    repeat?: boolean | number;\n} & ComponentProps<\"div\">;\n\nexport const SquashText = ({ repeat = true, children, ...props }: SquashTextProps) => {\n    const wrapperRef = useRef<HTMLDivElement | null>(null);\n    const bounceId = useId();\n\n    // We sanitize the IDs for GSAP ease names\n    const bounceEase = `bounce${bounceId.replace(/:/g, \"\")}`;\n    const squashEase = `squash${bounceId.replace(/:/g, \"\")}`;\n\n    useGSAP(\n        () => {\n            if (!wrapperRef.current) return;\n\n            // 1. Create the Custom Bounce\n            CustomBounce.create(bounceEase, {\n                strength: 0.6,\n                squash: 1,\n                squashID: squashEase,\n            });\n\n            // 2. Initialize SplitText\n            const split = new SplitText(wrapperRef.current, { type: \"chars\" });\n            const chars = split.chars;\n\n            // 3. Create Timeline\n            const tl = gsap.timeline({\n                defaults: { duration: 1.5, stagger: { amount: 0.1, ease: \"sine.in\" } },\n                repeat: repeat === true ? -1 : repeat === false ? 0 : repeat,\n            });\n\n            tl.from(\n                chars,\n                {\n                    duration: 0.6,\n                    opacity: 0,\n                    ease: \"power1.inOut\",\n                },\n                0,\n            )\n                .from(\n                    chars,\n                    {\n                        y: -100,\n                        ease: bounceEase,\n                    },\n                    0,\n                )\n                .to(\n                    chars,\n                    {\n                        scaleX: 1.5,\n                        scaleY: 0.8,\n                        rotate: () => 15 - 30 * Math.random(),\n                        ease: squashEase,\n                        transformOrigin: \"50% 100%\",\n                    },\n                    0,\n                );\n\n            // Cleanup: Revert the split text when component unmounts\n            return () => {\n                split.revert();\n            };\n        },\n        { scope: wrapperRef, dependencies: [repeat] },\n    );\n\n    return (\n        <div {...props} ref={wrapperRef}>\n            {children}\n        </div>\n    );\n};\n"
        }
    ]
}
