Files
reui-blocks/blocks/hero226.tsx
T
2026-07-23 06:55:21 +03:30

161 lines
5.0 KiB
TypeScript

"use client";
import Autoplay from "embla-carousel-autoplay";
import { motion } from "framer-motion";
import { ArrowRight } from "lucide-react";
import React, { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import {
Carousel,
type CarouselApi,
CarouselContent,
CarouselItem,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
interface Hero226Props {
className?: string;
}
const Hero226 = ({ className }: Hero226Props) => {
const [api, setApi] = useState<CarouselApi>();
const [current, setCurrent] = useState(0);
const Images = [
{
image:
"/block-media/shadcnblocks/block/lummi/bw12.jpeg",
title: "خانه رؤیایی خود را با ما بسازید",
description: "از طراحی تا اجرا، همراه شما هستیم.",
link: "#",
},
{
image:
"/block-media/shadcnblocks/block/lummi/bw13.jpeg",
title: "خانه‌های هوشمند",
description: "فضاهای زندگی هوشمند برای آینده",
link: "#",
},
{
image:
"/block-media/shadcnblocks/block/lummi/bw14.jpeg",
title: "سازگار با محیط زیست",
description: "خانه‌های پایدار و دوستدار محیط زیست",
link: "#",
},
{
image:
"/block-media/shadcnblocks/block/lummi/bw16.jpeg",
title: "ساخت سفارشی",
description: "راهکارهای متناسب با دیدگاه منحصربه‌فرد شما",
link: "#",
},
{
image:
"/block-media/shadcnblocks/block/lummi/bw17.jpeg",
title: "ساخت سفارشی",
description: "راهکارهای متناسب با دیدگاه منحصربه‌فرد شما",
link: "#",
},
];
useEffect(() => {
if (!api) return;
api.on("select", () => {
setCurrent(api.selectedScrollSnap());
});
}, [api]);
return (
<section className={cn("py-32", className)}>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
className=""
>
<Carousel
setApi={setApi}
className="w-full min-w-0 overflow-hidden"
opts={{
loop: true,
align: "start",
slidesToScroll: 1,
direction: "rtl",
}}
plugins={[
Autoplay({
delay: 2000,
stopOnInteraction: true,
stopOnMouseEnter: true,
}),
]}
>
{/* Override -ml-4 / pl-4 — they break RTL single-slide sizing */}
<CarouselContent className="-ml-0!">
{Images.map((img, index) => (
<CarouselItem key={index} className="basis-full pl-0!">
<div className="relative flex h-166 w-full min-w-0 flex-col items-end justify-between overflow-hidden bg-muted p-8">
<div className="pointer-events-none absolute inset-0">
<img
src={img.image}
alt="تصویر نمونه"
className="size-full object-cover"
/>
</div>
<div className="z-10 mt-42 text-white">
<h1 className="max-w-lg text-end text-2xll font-medium tracking-tight">
{img.title}
</h1>
<p className="my-6 max-w-lg text-end text-lg">
{img.description}
</p>
</div>
<div className="z-10 flex w-full justify-between">
<a href={img.link}>
<Button
variant="outline"
className="text-md group flex w-fit items-center justify-center gap-2 rounded-full px-4 py-1 tracking-tight"
>
شروع رایگان
<ArrowRight className="size-4 -rotate-45 transition-all ease-out group-hover:ms-3 group-hover:rotate-0 rtl:rotate-[135deg] rtl:group-hover:rotate-0" />
</Button>
</a>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<div className="mt-4 flex justify-center gap-2">
{Images.map((_, index) => (
<button
key={index}
type="button"
onClick={() => api?.scrollTo(index)}
className={`h-2.5 w-2.5 rounded-full transition-all ${
current === index
? "w-4 bg-primary"
: "bg-muted-foreground/50"
}`}
aria-label={`رفتن به اسلاید ${index + 1}`}
/>
))}
</div>
</Carousel>
</motion.div>
</section>
);
};
export { Hero226 };
export const GRADIENT_ANGLES = {
top: 0,
right: 90,
bottom: 180,
left: 270,
};