{
  "title": "Squash Text",
  "description": "Characters bounce and squash into place with playful, dynamic energy.",
  "name": "gsap-squash-text",
  "dependencies": [
    "gsap",
    "@gsap/react"
  ],
  "registryDependencies": [],
  "type": "registry:ui",
  "files": [
    {
      "path": "components/paceui/gsap/squash-text.tsx",
      "type": "registry:ui",
      "content": "import { type ComponentProps, useRef } from \"react\";\n\nimport { useGSAP } from \"@gsap/react\";\nimport gsap from \"gsap\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype SquashTextProps = {\n    repeat?: boolean | number;\n} & ComponentProps<\"div\">;\n\nexport const SquashText = ({ repeat = true, children, className, ...props }: SquashTextProps) => {\n    const text = String(children);\n    const chars = text.split(\"\");\n    const containerRef = useRef<HTMLDivElement | null>(null);\n\n    useGSAP(\n        () => {\n            if (!containerRef.current) return;\n            const elements = containerRef.current.querySelectorAll<HTMLSpanElement>(\".squash-char\");\n            if (!elements.length) return;\n\n            const charsLen = elements.length;\n            const repeatCount = repeat === true ? -1 : repeat === false ? 0 : repeat;\n\n            elements.forEach((el, i) => {\n                const progress = i / (charsLen - 1 || 1);\n                const staggerDelay = (1 - Math.cos((progress * Math.PI) / 2)) * 0.1;\n                const customRot = 15 - ((i * 13) % 30);\n\n                gsap.fromTo(\n                    el,\n                    {\n                        opacity: 0,\n                        y: -100,\n                        scaleX: 1,\n                        scaleY: 1,\n                        rotate: 0,\n                    },\n                    {\n                        keyframes: [\n                            { duration: 0.3, y: 0, opacity: 0.5, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.in\" },\n                            { duration: 0.075, y: 0, opacity: 0.625, scaleX: 1.5, scaleY: 0.8, rotate: customRot, ease: \"power1.out\" },\n                            { duration: 0.075, y: 0, opacity: 0.75, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.in\" },\n                            { duration: 0.3, y: -40, opacity: 1, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.out\" },\n                            { duration: 0.3, y: 0, opacity: 1, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.in\" },\n                            { duration: 0.0375, y: 0, opacity: 1, scaleX: 1.25, scaleY: 0.9, rotate: customRot * 0.5, ease: \"power1.out\" },\n                            { duration: 0.0375, y: 0, opacity: 1, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.in\" },\n                            { duration: 0.15, y: -15, opacity: 1, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.out\" },\n                            { duration: 0.15, y: 0, opacity: 1, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.in\" },\n                            { duration: 0.0375, y: 0, opacity: 1, scaleX: 1.1, scaleY: 0.95, rotate: customRot * 0.25, ease: \"power1.out\" },\n                            { duration: 0.0375, y: 0, opacity: 1, scaleX: 1, scaleY: 1, rotate: 0, ease: \"power1.in\" },\n                        ],\n                        delay: staggerDelay,\n                        repeat: repeatCount,\n                        repeatDelay: 0,\n                    },\n                );\n            });\n        },\n        { scope: containerRef, dependencies: [repeat, text] },\n    );\n\n    return (\n        <div ref={containerRef} className={cn(\"overflow-hidden\", className)} {...props}>\n            {chars.map((char, i) => (\n                <span\n                    key={i}\n                    className=\"squash-char\"\n                    style={{\n                        display: \"inline-block\",\n                        whiteSpace: char === \" \" ? \"pre\" : \"normal\",\n                        transformOrigin: \"50% 100%\",\n                    }}>\n                    {char}\n                </span>\n            ))}\n        </div>\n    );\n};\n"
    }
  ],
  "mcp": {
    "description": "Provides refined UI interactions and accessible controls. Characters bounce and squash into place with playful, dynamic energy. Configurable props include: {; repeat?: boolean | number;. Relies on gsap, @gsap/react. Optimal for building reusable interface elements and user input flows.",
    "tags": [
      "component",
      "gsap",
      "animation"
    ]
  }
}