{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "gallery-grid-block-shadcnui", "type": "registry:block", "title": "Gallery Grid with Lightbox", "description": "Filterable image gallery with animated lightbox and navigation", "registryDependencies": [ "button" ], "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-shadcn/src/components/sections/gallery-grid-block.tsx", "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card } from \"@/components/ui/card\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { ChevronLeft, ChevronRight, Grid, X, ZoomIn } from \"lucide-react\";\nimport { KeyboardEvent, useState } from \"react\";\n\nconst galleryImages = [\n {\n id: 1,\n url: \"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=500\",\n title: \"Abstract Architecture\",\n category: \"Architecture\",\n },\n {\n id: 2,\n url: \"https://images.unsplash.com/photo-1618556450994-a6a128ef0d9d?w=500\",\n title: \"Modern Design\",\n category: \"Design\",\n },\n {\n id: 3,\n url: \"https://images.unsplash.com/photo-1618005198919-d3d4b5a92ead?w=500\",\n title: \"Urban Landscape\",\n category: \"Nature\",\n },\n {\n id: 4,\n url: \"https://images.unsplash.com/photo-1634017839464-5c339ebe3cb4?w=500\",\n title: \"Digital Art\",\n category: \"Art\",\n },\n {\n id: 5,\n url: \"https://images.unsplash.com/photo-1618556450991-2f1af64e8191?w=500\",\n title: \"Creative Space\",\n category: \"Architecture\",\n },\n {\n id: 6,\n url: \"https://images.unsplash.com/photo-1618005198919-d3d4b5a92ead?w=500\",\n title: \"Minimalist View\",\n category: \"Design\",\n },\n];\n\nexport function GalleryGridBlock() {\n const [selectedImage, setSelectedImage] = useState(null);\n const [filter, setFilter] = useState(\"All\");\n\n const categories = [\n \"All\",\n ...new Set(galleryImages.map((img) => img.category)),\n ];\n\n const filteredImages =\n filter === \"All\"\n ? galleryImages\n : galleryImages.filter((img) => img.category === filter);\n\n const handleNext = () => {\n if (selectedImage !== null) {\n const currentIndex = galleryImages.findIndex(\n (img) => img.id === selectedImage\n );\n const nextIndex = (currentIndex + 1) % galleryImages.length;\n setSelectedImage(galleryImages[nextIndex].id);\n }\n };\n\n const handlePrev = () => {\n if (selectedImage !== null) {\n const currentIndex = galleryImages.findIndex(\n (img) => img.id === selectedImage\n );\n const prevIndex =\n (currentIndex - 1 + galleryImages.length) % galleryImages.length;\n setSelectedImage(galleryImages[prevIndex].id);\n }\n };\n\n const selectedImageData = galleryImages.find(\n (img) => img.id === selectedImage\n );\n\n const handleCardKeyDown = (\n event: KeyboardEvent,\n imageId: number\n ) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setSelectedImage(imageId);\n }\n };\n\n return (\n \n
\n \n \n \n Gallery\n \n \n Our Portfolio\n \n

\n Explore our collection of stunning visuals and creative work\n

\n \n\n {/* Filter Buttons */}\n \n {categories.map((category) => (\n setFilter(category)}\n aria-pressed={filter === category}\n >\n {category}\n \n ))}\n \n\n {/* Gallery Grid */}\n \n \n {filteredImages.map((image, index) => (\n \n setSelectedImage(image.id)}\n onKeyDown={(event) => handleCardKeyDown(event, image.id)}\n role=\"button\"\n tabIndex={0}\n aria-label={`View details for ${image.title}`}\n >\n
\n \n\n {/* Overlay */}\n \n \n

\n {image.title}\n

\n {image.category}\n \n
\n \n \n ))}\n
\n \n\n {/* Lightbox */}\n \n {selectedImage !== null && selectedImageData && (\n setSelectedImage(null)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"gallery-dialog-title\"\n aria-describedby=\"gallery-dialog-description\"\n >\n e.stopPropagation()}\n className=\"relative max-h-[90vh] max-w-5xl\"\n >\n {/* Close Button */}\n setSelectedImage(null)}\n aria-label=\"Close gallery dialog\"\n >\n \n \n\n {/* Navigation Buttons */}\n {\n e.stopPropagation();\n handlePrev();\n }}\n aria-label=\"View previous image\"\n >\n \n \n {\n e.stopPropagation();\n handleNext();\n }}\n aria-label=\"View next image\"\n >\n \n \n\n {/* Image */}\n \n\n {/* Image Info */}\n \n \n {selectedImageData.title}\n \n \n {selectedImageData.category}\n \n \n \n \n )}\n \n
\n \n );\n}\n", "type": "registry:block", "target": "components/uitripled/gallery-grid-block-shadcnui.tsx" } ] }