{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "image-gallery-1", "type": "registry:block", "description": "Masonry-style responsive gallery using random images with dynamic aspect ratios.", "dependencies": [ "motion" ], "registryDependencies": [ "aspect-ratio" ], "files": [ { "path": "registry/blocks/image-gallery/1/image-gallery.tsx", "content": "import { LazyImage } from \"./lazy-image\";\n\nexport function ImageGallery() {\n return (\n
\n
\n {Array.from({ length: 4 }).map((_, col) => (\n
\n {/* biome-ignore lint/nursery/noShadow: false positive */}\n {Array.from({ length: 8 }).map((_, index) => {\n const isPortrait = Math.random() > 0.5;\n const width = isPortrait ? 1080 : 1920;\n const height = isPortrait ? 1920 : 1080;\n const ratio = isPortrait ? 9 / 16 : 16 / 9;\n\n return (\n \n );\n })}\n
\n ))}\n
\n
\n );\n}\n", "type": "registry:component" }, { "path": "registry/blocks/image-gallery/1/lazy-image.tsx", "content": "\"use client\";\n\nimport { useInView } from \"motion/react\";\nimport React from \"react\";\nimport { AspectRatio } from \"@/components/ui/aspect-ratio\";\nimport { cn } from \"@/lib/utils\";\n\ntype LazyImageProps = {\n alt: string;\n src: string;\n className?: string;\n AspectRatioClassName?: string;\n /** URL of the fallback image. default: undefined */\n fallback?: string;\n /** The ratio of the image. */\n ratio: number;\n /** Whether the image should only load when it is in view. default: false */\n inView?: boolean;\n};\n\nexport function LazyImage({\n alt,\n src,\n ratio,\n fallback,\n inView = false,\n className,\n AspectRatioClassName,\n}: LazyImageProps) {\n const ref = React.useRef(null);\n const imgRef = React.useRef(null);\n const isInView = useInView(ref, { once: true });\n\n const [imgSrc, setImgSrc] = React.useState(\n inView ? undefined : src\n );\n const [isLoading, setIsLoading] = React.useState(true);\n\n const handleError = () => {\n if (fallback) {\n setImgSrc(fallback);\n }\n setIsLoading(false);\n };\n\n const handleLoad = React.useCallback(() => {\n setIsLoading(false);\n }, []);\n\n // Load image only when inView\n React.useEffect(() => {\n if (inView && isInView && !imgSrc) {\n setImgSrc(src);\n }\n }, [inView, isInView, src, imgSrc]);\n\n // Handle cached images instantly\n React.useEffect(() => {\n if (imgRef.current?.complete) {\n handleLoad();\n }\n }, [handleLoad]);\n\n return (\n \n {imgSrc && (\n // biome-ignore lint/nursery/useImageSize: dynamic image size\n \n )}\n \n );\n}\n", "type": "registry:component" } ], "categories": [ "image-gallery" ] }