Files
reui-blocks/blocks/gallery17.tsx
T

188 lines
5.5 KiB
TypeScript

"use client";
import { ArrowLeft, ArrowRight } from "lucide-react";
import { startTransition, useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import {
Carousel,
CarouselContent,
CarouselItem,
type CarouselApi,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
const IMAGES = [
{
src: "/block-media/shadcnblocks/block/placeholder-dark-1.svg",
alt: "تصویر گالری ۱",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-2.svg",
alt: "تصویر گالری ۲",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-3.svg",
alt: "تصویر گالری ۳",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-4.svg",
alt: "تصویر گالری ۴",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-5.svg",
alt: "تصویر گالری ۵",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-1.svg",
alt: "تصویر گالری ۶",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-2.svg",
alt: "تصویر گالری ۷",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-3.svg",
alt: "تصویر گالری ۸",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-4.svg",
alt: "تصویر گالری ۹",
},
{
src: "/block-media/shadcnblocks/block/placeholder-dark-5.svg",
alt: "تصویر گالری ۱۰",
},
];
interface Gallery17Props {
className?: string;
}
const Gallery17 = ({ className }: Gallery17Props) => {
const [api, setApi] = useState<CarouselApi>();
const [current, setCurrent] = useState(0);
const [count, setCount] = useState(0);
const [canScrollPrev, setCanScrollPrev] = useState(false);
const [canScrollNext, setCanScrollNext] = useState(false);
useEffect(() => {
if (!api) {
return;
}
const updateSelection = () => {
startTransition(() => {
setCount(api.scrollSnapList().length);
setCurrent(api.selectedScrollSnap() + 1);
setCanScrollPrev(api.canScrollPrev());
setCanScrollNext(api.canScrollNext());
});
};
updateSelection();
api.on("select", updateSelection);
return () => {
api.off("select", updateSelection);
};
}, [api]);
useEffect(() => {
if (!api) {
return;
}
api.reInit();
}, [api]);
return (
<section
dir="rtl"
lang="fa"
className={cn("overflow-hidden py-32", className)}
>
<div className="container md:px-45">
<Carousel
dir="rtl"
className="mx-auto w-full max-w-[50rem] [&>div:nth-child(1)]:md:overflow-visible"
setApi={setApi}
opts={{
startIndex: 1,
direction: "rtl",
}}
>
<CarouselContent className="-ms-4 me-0">
{IMAGES.map((img, index) => (
<CarouselItem
key={`carousel-img-${index}`}
className="basis-full ps-4 pe-0"
>
<div
className={cn(
"aspect-[1.333333333] max-w-[50rem] overflow-hidden rounded-[0.75rem] transition-all duration-300",
current === index + 1
? "scale-100 opacity-100"
: "scale-70 opacity-40",
)}
>
<img
className="block size-full object-cover object-center"
src={img.src}
alt={img.alt}
/>
</div>
</CarouselItem>
))}
</CarouselContent>
<div className="mt-4 hidden md:block">
<Button
type="button"
size="icon"
variant="default"
className="absolute top-1/2 size-10 -translate-y-1/2 max-[767px]:static max-[767px]:translate-y-0 md:start-[-6.25rem] md:size-14 lg:start-[-9.9375rem] lg:size-14 [&>svg]:size-6!"
disabled={!canScrollPrev}
onClick={() => api?.scrollPrev()}
>
<ArrowRight className="size-6" />
<span className="sr-only">اسلاید قبلی</span>
</Button>
<Button
type="button"
size="icon"
variant="default"
className="absolute top-1/2 size-10 -translate-y-1/2 max-[767px]:static max-[767px]:translate-y-0 md:end-[-6.25rem] md:size-14 lg:end-[-9.9375rem] lg:size-14 [&>svg]:size-6!"
disabled={!canScrollNext}
onClick={() => api?.scrollNext()}
>
<ArrowLeft className="size-6" />
<span className="sr-only">اسلاید بعدی</span>
</Button>
</div>
</Carousel>
<div className="mx-auto mt-10 flex w-full max-w-[33.9375rem] items-center justify-center">
{Array.from({ length: count }).map((_, index) => (
<button
type="button"
aria-label={`رفتن به اسلاید ${(index + 1).toLocaleString("fa-IR")}`}
key={`carousel-dot-btn-${index}`}
className="p-2"
onClick={() => {
api?.scrollTo(index);
}}
>
<div
className={cn(
"size-3 rounded-full",
current === index + 1 ? "bg-black" : "bg-black/10",
)}
/>
</button>
))}
</div>
</div>
</section>
);
};
export { Gallery17 };