"use client"; import "photoswipe/style.css"; import PhotoSwipeLightbox from "photoswipe/lightbox"; import { useCallback, useEffect, useRef, useState } from "react"; import { AspectRatio } from "@/components/ui/aspect-ratio"; import { Badge, badgeVariants } from "@/components/ui/badge"; import { buttonVariants } from "@/components/ui/button"; import { Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, } from "@/components/ui/carousel"; import { useMediaQuery } from "@/hooks/useMediaQuery"; import { cn } from "@/lib/utils"; type ProductImages = { srcset: string; src: string; alt: string; width: number; height: number; sizes: string; thumbnail: string; }[]; interface ProductGallery7Props { images: ProductImages; galleryID: string; className?: string; } const PRODUCT_IMAGES: ProductImages = [ { srcset: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/point-normal-Xp0bTCLD07k-unsplash-3.jpg 2160w, /block-media/shadcnblocks/block/ecommerce/skin-care-product/point-normal-Xp0bTCLD07k-unsplash-2.jpg 1920w, /block-media/shadcnblocks/block/ecommerce/skin-care-product/point-normal-Xp0bTCLD07k-unsplash-1.jpg 640w", src: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/point-normal-Xp0bTCLD07k-unsplash-3.jpg", thumbnail: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/point-normal-Xp0bTCLD07k-unsplash-1.jpg", sizes: "(min-width: 2160px) 2160px, (min-width: 1920px) 1920px, 100vw", alt: "", width: 2160, height: 2700, }, { srcset: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/brittney-weng-CSquI0aw_Rg-unsplash-3.jpg 2400w, /block-media/shadcnblocks/block/ecommerce/skin-care-product/brittney-weng-CSquI0aw_Rg-unsplash-2.jpg 1920w, /block-media/shadcnblocks/block/ecommerce/skin-care-product/brittney-weng-CSquI0aw_Rg-unsplash-1.jpg 640w", src: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/brittney-weng-CSquI0aw_Rg-unsplash-3.jpg", thumbnail: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/brittney-weng-CSquI0aw_Rg-unsplash-1.jpg", sizes: "(min-width: 2400px) 2400px, (min-width: 1920px) 1920px, 100vw", alt: "", width: 2400, height: 3000, }, { srcset: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/kadarius-seegars-Mxy5gokl8mE-unsplash-3.jpg 2400w, /block-media/shadcnblocks/block/ecommerce/skin-care-product/kadarius-seegars-Mxy5gokl8mE-unsplash-2.jpg 1920w, /block-media/shadcnblocks/block/ecommerce/skin-care-product/kadarius-seegars-Mxy5gokl8mE-unsplash-1.jpg 640w", src: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/kadarius-seegars-Mxy5gokl8mE-unsplash-3.jpg", thumbnail: "/block-media/shadcnblocks/block/ecommerce/skin-care-product/kadarius-seegars-Mxy5gokl8mE-unsplash-1.jpg", sizes: "(min-width: 2400px) 2400px, (min-width: 1920px) 1920px, 100vw", alt: "", width: 2400, height: 3600, }, ]; const ProductGallery7 = ({ images = PRODUCT_IMAGES, galleryID = "ProductGallery7", className, }: ProductGallery7Props) => { const [api, setApi] = useState(); const [current, setCurrent] = useState(0); const lightboxRef = useRef(null); const previewRef = useRef(null); const thumbnailRef = useRef(null); const isDesktop = useMediaQuery("(width >= 900px)"); useEffect(() => { const lightbox = new PhotoSwipeLightbox({ gallery: "#" + galleryID, children: "a", bgOpacity: 1, wheelToZoom: true, arrowPrev: false, arrowNext: false, close: false, zoom: false, counter: false, mainClass: "[&>div:first-child]:!bg-background", pswpModule: () => import("photoswipe"), }); const buttonClassName = cn( buttonVariants({ variant: "outline", size: "icon", className: "rounded-full", }), ); const indicatorClassName = cn(badgeVariants({ variant: "secondary" })); lightbox.on("uiRegister", () => { if (lightbox?.pswp?.ui) { lightbox.pswp.ui.registerElement({ name: "custom-close-btn", order: 10, isButton: false, appendTo: "root", className: "absolute top-5 end-5", html: ` `, onInit: (el, pswp) => { el.querySelector("#pswp-close")?.addEventListener("click", () => pswp.close(), ); }, }); } if (lightbox?.pswp?.ui) { lightbox.pswp.ui.registerElement({ name: "custom-indicator-btn", order: 10, isButton: false, appendTo: "root", className: "absolute top-5 start-5", html: `
`, onInit: (el, pswp) => { const indicatorElem = el.querySelector("#pswp-indicator"); pswp.on("change", () => { if (indicatorElem) { indicatorElem.innerHTML = `${pswp.currIndex + 1} / ${pswp.getNumItems()}`; } }); }, }); } if (lightbox?.pswp?.ui) { lightbox.pswp.ui.registerElement({ name: "custom-next-prev-btns", order: 10, isButton: false, appendTo: "root", className: "absolute top-1/2 inset-x-0 -translate-y-1/2", html: `
`, onInit: (el, pswp) => { el.querySelector("#pswp-prev")?.addEventListener("click", () => pswp.next(), ); el.querySelector("#pswp-next")?.addEventListener("click", () => pswp.prev(), ); }, }); } }); lightbox.init(); lightboxRef.current = lightbox; return () => { lightbox.destroy(); lightboxRef.current = null; }; }, [galleryID]); const onSelect = useCallback((carouselApi: CarouselApi) => { if (!carouselApi) return; setCurrent(carouselApi.selectedScrollSnap() + 1); }, []); useEffect(() => { if (!api) return; onSelect(api); api.on("reInit", onSelect); api.on("select", onSelect); return () => { api.off("select", onSelect); }; }, [api, onSelect]); useEffect(() => { const lightbox = lightboxRef.current; if (!lightbox || !api) return; const syncCarousel = () => { api.scrollTo(lightbox.pswp?.currIndex || 0); }; lightbox.on("change", syncCarousel); return () => { lightbox.off("change", syncCarousel); }; }, [api]); useEffect(() => { if (!previewRef.current || !thumbnailRef.current) return; const observer = new ResizeObserver(([entry]) => { if (!isDesktop && thumbnailRef.current) { thumbnailRef.current.style.height = `${entry.contentRect.height}px`; } }); if (!isDesktop) { observer.observe(previewRef.current); } return () => observer.disconnect(); }, [isDesktop]); if (!images) return; return (
    {images.map((img, index) => (
  • ))}
New
{images.map((img, index) => ( {img.alt} ))}
{current > 1 && ( )} {current < images.length && ( )}
{current || 1} / {images.length}
); }; export { ProductGallery7 };