{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "ScrollReveal-TS-TW",
	"title": "ScrollReveal",
	"description": "Text gently unblurs and reveals on scroll.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:component",
			"path": "ScrollReveal/ScrollReveal.tsx",
			"content": "import React, { useEffect, useRef, useMemo, type ReactNode, type RefObject } from 'react';\nimport { gsap } from 'gsap';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\n\ngsap.registerPlugin(ScrollTrigger);\n\ninterface ScrollRevealProps {\n  children: ReactNode;\n  scrollContainerRef?: RefObject<HTMLElement>;\n  enableBlur?: boolean;\n  baseOpacity?: number;\n  baseRotation?: number;\n  blurStrength?: number;\n  containerClassName?: string;\n  textClassName?: string;\n  rotationEnd?: string;\n  wordAnimationEnd?: string;\n}\n\nconst ScrollReveal: React.FC<ScrollRevealProps> = ({\n  children,\n  scrollContainerRef,\n  enableBlur = true,\n  baseOpacity = 0.1,\n  baseRotation = 3,\n  blurStrength = 4,\n  containerClassName = '',\n  textClassName = '',\n  rotationEnd = 'bottom bottom',\n  wordAnimationEnd = 'bottom bottom'\n}) => {\n  const containerRef = useRef<HTMLHeadingElement>(null);\n\n  const splitText = useMemo(() => {\n    const text = typeof children === 'string' ? children : '';\n    return text.split(/(\\s+)/).map((word, index) => {\n      if (word.match(/^\\s+$/)) return word;\n      return (\n        <span className=\"inline-block word\" key={index}>\n          {word}\n        </span>\n      );\n    });\n  }, [children]);\n\n  useEffect(() => {\n    const el = containerRef.current;\n    if (!el) return;\n\n    const scroller = scrollContainerRef && scrollContainerRef.current ? scrollContainerRef.current : window;\n\n    gsap.fromTo(\n      el,\n      { transformOrigin: '0% 50%', rotate: baseRotation },\n      {\n        ease: 'none',\n        rotate: 0,\n        scrollTrigger: {\n          trigger: el,\n          scroller,\n          start: 'top bottom',\n          end: rotationEnd,\n          scrub: true\n        }\n      }\n    );\n\n    const wordElements = el.querySelectorAll<HTMLElement>('.word');\n\n    gsap.fromTo(\n      wordElements,\n      { opacity: baseOpacity, willChange: 'opacity' },\n      {\n        ease: 'none',\n        opacity: 1,\n        stagger: 0.05,\n        scrollTrigger: {\n          trigger: el,\n          scroller,\n          start: 'top bottom-=20%',\n          end: wordAnimationEnd,\n          scrub: true\n        }\n      }\n    );\n\n    if (enableBlur) {\n      gsap.fromTo(\n        wordElements,\n        { filter: `blur(${blurStrength}px)` },\n        {\n          ease: 'none',\n          filter: 'blur(0px)',\n          stagger: 0.05,\n          scrollTrigger: {\n            trigger: el,\n            scroller,\n            start: 'top bottom-=20%',\n            end: wordAnimationEnd,\n            scrub: true\n          }\n        }\n      );\n    }\n\n    return () => {\n      ScrollTrigger.getAll().forEach(trigger => trigger.kill());\n    };\n  }, [scrollContainerRef, enableBlur, baseRotation, baseOpacity, rotationEnd, wordAnimationEnd, blurStrength]);\n\n  return (\n    <h2 ref={containerRef} className={`my-5 ${containerClassName}`}>\n      <p className={`text-[clamp(1.6rem,4vw,3rem)] leading-[1.5] font-semibold ${textClassName}`}>{splitText}</p>\n    </h2>\n  );\n};\n\nexport default ScrollReveal;\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"gsap@^3.13.0"
	]
}