{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "image-player",
  "title": "Image Player",
  "description": "Create your own image player GIF/video, with image player component.",
  "files": [
    {
      "path": "registry/blocks/image-player/index.tsx",
      "content": "/* eslint-disable @next/next/no-img-element */\n'use client';\nimport * as React from 'react';\n\ninterface ImagePlayerProps\n  extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, 'src'> {\n  images: string[];\n  interval?: number;\n  loop?: boolean;\n  onComplete?: () => void;\n  renderImage?: (src: string, index: number) => React.ReactNode;\n\n  renderLoading?: () => React.ReactNode;\n}\n\nexport const ImagePlayer: React.FC<ImagePlayerProps> = ({\n  images,\n  interval = 500,\n  loop = true,\n  onComplete,\n  renderImage,\n  renderLoading,\n  ...props\n}) => {\n  const [currentIndex, setCurrentIndex] = React.useState<number>(0);\n  const [imagesLoaded, setImagesLoaded] = React.useState(false);\n  const intervalRef = React.useRef<NodeJS.Timeout | null>(null);\n\n  const currentImage = React.useMemo(\n    () => images[currentIndex],\n    [images, currentIndex],\n  );\n\n  React.useEffect(() => {\n    const loadImage = (src: string): Promise<void> => {\n      return new Promise((resolve) => {\n        const img = document.createElement('img');\n        img.src = src;\n        img.onload = () => resolve();\n      });\n    };\n\n    Promise.all(images.map(loadImage))\n      .then(() => {\n        setImagesLoaded(true);\n      })\n      .catch(() => {\n        setImagesLoaded(true);\n      });\n  }, [images]);\n\n  React.useEffect(() => {\n    if (images.length <= 1 || !imagesLoaded) return;\n\n    intervalRef.current = setInterval(() => {\n      setCurrentIndex((prevIndex) => {\n        const nextIndex = prevIndex + 1;\n\n        if (nextIndex >= images.length) {\n          if (loop) {\n            return 0;\n          } else {\n            onComplete?.();\n            return prevIndex;\n          }\n        }\n\n        return nextIndex;\n      });\n    }, interval);\n\n    return () => {\n      if (intervalRef.current) {\n        clearInterval(intervalRef.current);\n      }\n    };\n  }, [images.length, interval, loop, onComplete, imagesLoaded]);\n\n  React.useEffect(() => {\n    setCurrentIndex(0);\n  }, [images]);\n\n  if (!images || images.length === 0) {\n    return <div className=\"text-destructive\">No images !!</div>;\n  }\n\n  if (!imagesLoaded) {\n    return renderLoading ? (\n      renderLoading()\n    ) : (\n      <div className=\"w-full h-full rounded-xl bg-gradient-to-r from-gray-200 to-gray-300 animate-pulse\" />\n    );\n  }\n\n  return (\n    <>\n      {renderImage ? (\n        renderImage(currentImage, currentIndex)\n      ) : (\n        <img\n          src={currentImage}\n          alt={props.alt || 'Slideshow image'}\n          {...props}\n        />\n      )}\n    </>\n  );\n};\n",
      "type": "registry:block",
      "target": "components/systaliko-ui/image-player.tsx"
    }
  ],
  "type": "registry:block"
}