{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "PixelTransition-JS-CSS",
	"title": "PixelTransition",
	"description": "Pixel dissolve transition for content reveal on hover.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:file",
			"path": "PixelTransition.css",
			"target": "@components/PixelTransition.css",
			"content": ".pixelated-image-card {\n  background-color: #222;\n  color: var(--color-primary, #fff);\n  border-radius: 15px;\n  border: 2px solid #fff;\n  width: 300px;\n  max-width: 100%;\n  position: relative;\n  overflow: hidden;\n}\n\n.pixelated-image-card__default,\n.pixelated-image-card__active,\n.pixelated-image-card__pixels {\n  width: 100%;\n  height: 100%;\n  position: absolute;\n  top: 0;\n  left: 0;\n}\n\n.pixelated-image-card__active {\n  z-index: 2;\n}\n\n.pixelated-image-card__active {\n  display: none;\n}\n\n.pixelated-image-card__pixels {\n  pointer-events: none;\n  position: absolute;\n  z-index: 3;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.pixelated-image-card__pixel {\n  display: none;\n  position: absolute;\n}\n"
		},
		{
			"type": "registry:component",
			"path": "PixelTransition.jsx",
			"content": "import { useRef, useEffect, useState } from 'react';\nimport { gsap } from 'gsap';\nimport './PixelTransition.css';\n\nfunction PixelTransition({\n  firstContent,\n  secondContent,\n  gridSize = 7,\n  pixelColor = 'currentColor',\n  animationStepDuration = 0.3,\n  once = false,\n  aspectRatio = '100%',\n  className = '',\n  style = {}\n}) {\n  const containerRef = useRef(null);\n  const pixelGridRef = useRef(null);\n  const activeRef = useRef(null);\n  const delayedCallRef = useRef(null);\n\n  const [isActive, setIsActive] = useState(false);\n\n  const isTouchDevice =\n    'ontouchstart' in window || navigator.maxTouchPoints > 0 || window.matchMedia('(pointer: coarse)').matches;\n\n  useEffect(() => {\n    const pixelGridEl = pixelGridRef.current;\n    if (!pixelGridEl) return;\n\n    pixelGridEl.innerHTML = '';\n\n    for (let row = 0; row < gridSize; row++) {\n      for (let col = 0; col < gridSize; col++) {\n        const pixel = document.createElement('div');\n        pixel.classList.add('pixelated-image-card__pixel');\n        pixel.style.backgroundColor = pixelColor;\n\n        const size = 100 / gridSize;\n        pixel.style.width = `${size}%`;\n        pixel.style.height = `${size}%`;\n        pixel.style.left = `${col * size}%`;\n        pixel.style.top = `${row * size}%`;\n        pixelGridEl.appendChild(pixel);\n      }\n    }\n  }, [gridSize, pixelColor]);\n\n  const animatePixels = activate => {\n    setIsActive(activate);\n\n    const pixelGridEl = pixelGridRef.current;\n    const activeEl = activeRef.current;\n    if (!pixelGridEl || !activeEl) return;\n\n    const pixels = pixelGridEl.querySelectorAll('.pixelated-image-card__pixel');\n    if (!pixels.length) return;\n\n    gsap.killTweensOf(pixels);\n    if (delayedCallRef.current) {\n      delayedCallRef.current.kill();\n    }\n\n    gsap.set(pixels, { display: 'none' });\n\n    const totalPixels = pixels.length;\n    const staggerDuration = animationStepDuration / totalPixels;\n\n    gsap.to(pixels, {\n      display: 'block',\n      duration: 0,\n      stagger: {\n        each: staggerDuration,\n        from: 'random'\n      }\n    });\n\n    delayedCallRef.current = gsap.delayedCall(animationStepDuration, () => {\n      activeEl.style.display = activate ? 'block' : 'none';\n      activeEl.style.pointerEvents = activate ? 'none' : '';\n    });\n\n    gsap.to(pixels, {\n      display: 'none',\n      duration: 0,\n      delay: animationStepDuration,\n      stagger: {\n        each: staggerDuration,\n        from: 'random'\n      }\n    });\n  };\n\n  const handleEnter = () => {\n    if (!isActive) animatePixels(true);\n  };\n  const handleLeave = () => {\n    if (isActive && !once) animatePixels(false);\n  };\n  const handleClick = () => {\n    if (!isActive) animatePixels(true);\n    else if (isActive && !once) animatePixels(false);\n  };\n\n  return (\n    <div\n      ref={containerRef}\n      className={`pixelated-image-card ${className}`}\n      style={style}\n      onMouseEnter={!isTouchDevice ? handleEnter : undefined}\n      onMouseLeave={!isTouchDevice ? handleLeave : undefined}\n      onClick={isTouchDevice ? handleClick : undefined}\n      onFocus={!isTouchDevice ? handleEnter : undefined}\n      onBlur={!isTouchDevice ? handleLeave : undefined}\n      tabIndex={0}\n    >\n      <div style={{ paddingTop: aspectRatio }} />\n      <div className=\"pixelated-image-card__default\" aria-hidden={isActive}>\n        {firstContent}\n      </div>\n      <div className=\"pixelated-image-card__active\" ref={activeRef} aria-hidden={!isActive}>\n        {secondContent}\n      </div>\n      <div className=\"pixelated-image-card__pixels\" ref={pixelGridRef} />\n    </div>\n  );\n}\n\nexport default PixelTransition;\n"
		}
	],
	"registryDependencies": [],
	"dependencies": [
		"gsap@^3.13.0"
	]
}