43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/app/lib/cn";
|
|
import Image, { type StaticImageData } from "next/image";
|
|
import { useState, type FC } from "react";
|
|
|
|
type ProductGalleryProps = {
|
|
images: readonly StaticImageData[];
|
|
alt: string;
|
|
};
|
|
|
|
const ProductGallery: FC<ProductGalleryProps> = ({ images, alt }) => {
|
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
|
|
return (
|
|
<div className="flex w-full shrink-0 flex-col gap-3 lg:w-[45%] lg:max-w-120">
|
|
<div className="relative aspect-square w-full overflow-hidden rounded-2xl bg-[#F7FAFC]">
|
|
<Image src={images[activeIndex]} alt={alt} fill priority className="object-contain p-4" sizes="(max-width: 1024px) 100vw, 480px" />
|
|
</div>
|
|
|
|
<div className="grid grid-cols-4 gap-2.5">
|
|
{images.slice(0, 4).map((image, index) => (
|
|
<button
|
|
key={index}
|
|
type="button"
|
|
aria-label={`تصویر ${index + 1}`}
|
|
aria-pressed={activeIndex === index}
|
|
onClick={() => setActiveIndex(index)}
|
|
className={cn(
|
|
"relative aspect-square overflow-hidden rounded-xl border-2 bg-[#F7FAFC] transition-colors",
|
|
activeIndex === index ? "border-primary" : "border-transparent",
|
|
)}
|
|
>
|
|
<Image src={image} alt="" fill className="object-contain p-1" sizes="(max-width: 1024px) 22vw, 96px" />
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ProductGallery;
|