85 lines
3.3 KiB
TypeScript
85 lines
3.3 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { Placeholder } from "@/components/ui/Placeholder";
|
||
import { sliderSlides } from "@/data/sample";
|
||
|
||
export function HeroSlider() {
|
||
const [active, setActive] = useState(1);
|
||
|
||
const positions = [
|
||
{ offset: -1, scale: "scale-[0.92]", opacity: "opacity-55", z: "z-10" },
|
||
{ offset: 0, scale: "scale-100", opacity: "opacity-100", z: "z-20" },
|
||
{ offset: 1, scale: "scale-[0.92]", opacity: "opacity-55", z: "z-10" },
|
||
];
|
||
|
||
return (
|
||
<section className="overflow-x-clip bg-gradient-to-b from-red-light/30 to-background py-4 md:py-6">
|
||
<div className="relative mx-auto w-full max-w-7xl px-4">
|
||
<div className="relative h-[220px] sm:h-[280px] md:h-[340px] lg:h-[380px]">
|
||
{positions.map(({ offset, scale, opacity, z }) => {
|
||
const isCenter = offset === 0;
|
||
|
||
return (
|
||
<div
|
||
key={offset}
|
||
className={`absolute top-1/2 -translate-y-1/2 transition-all duration-500 ease-out ${scale} ${opacity} ${z} ${
|
||
isCenter
|
||
? "inset-x-0 w-full origin-center"
|
||
: offset === -1
|
||
? "right-full mr-1.5 w-[78%] origin-right sm:w-[70%] md:w-[65%]"
|
||
: "left-full ml-1.5 w-[78%] origin-left sm:w-[70%] md:w-[65%]"
|
||
} ${isCenter ? "" : "pointer-events-none"}`}
|
||
>
|
||
<div className="overflow-hidden rounded-2xl border border-border bg-surface shadow-lg">
|
||
<Placeholder
|
||
width="100%"
|
||
label={isCenter ? "1280×380" : "880×350"}
|
||
className={`w-full rounded-none border-0 h-[200px] sm:h-[260px] md:h-[310px] ${
|
||
isCenter ? "lg:h-[380px]" : "lg:h-[350px]"
|
||
}`}
|
||
/>
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
<div className="mt-5 flex items-center justify-center gap-3">
|
||
<button
|
||
type="button"
|
||
onClick={() =>
|
||
setActive((prev) => (prev - 1 + sliderSlides.length) % sliderSlides.length)
|
||
}
|
||
className="flex h-9 w-9 items-center justify-center rounded-full border border-border text-red transition-colors hover:border-red hover:bg-red-light"
|
||
aria-label="اسلاید قبلی"
|
||
>
|
||
→
|
||
</button>
|
||
<div className="flex gap-2">
|
||
{sliderSlides.map((slide, i) => (
|
||
<button
|
||
key={slide.id}
|
||
type="button"
|
||
onClick={() => setActive(i)}
|
||
aria-label={`اسلاید ${i + 1}`}
|
||
className={`h-2 rounded-full transition-all ${
|
||
i === active ? "w-8 bg-red" : "w-2 bg-red-muted/50"
|
||
}`}
|
||
/>
|
||
))}
|
||
</div>
|
||
<button
|
||
type="button"
|
||
onClick={() => setActive((prev) => (prev + 1) % sliderSlides.length)}
|
||
className="flex h-9 w-9 items-center justify-center rounded-full border border-border text-red transition-colors hover:border-red hover:bg-red-light"
|
||
aria-label="اسلاید بعدی"
|
||
>
|
||
←
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
}
|