137 lines
5.0 KiB
TypeScript
137 lines
5.0 KiB
TypeScript
"use client";
|
|
|
|
import { ArrowRight, ChevronDown } from "lucide-react";
|
|
import { useEffect, useState } from "react";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
import type { CarouselApi } from "@/components/ui/carousel";
|
|
import {
|
|
Carousel,
|
|
CarouselContent,
|
|
CarouselItem,
|
|
} from "@/components/ui/carousel";
|
|
|
|
const features = [
|
|
{
|
|
id: "feature-1",
|
|
title: "Feature 1",
|
|
description:
|
|
"Nam vitae molestie arcu. Quisque eu libero orci. Aliquam imperdiet magna nec massa consectetur, id interdum ante congue.",
|
|
href: "#",
|
|
image: "https://deifkwefumgah.cloudfront.net/shadcnblocks/block/placeholder-1.svg",
|
|
},
|
|
{
|
|
id: "feature-2",
|
|
title: "Feature 2",
|
|
description:
|
|
"Nam vitae molestie arcu. Quisque eu libero orci. Aliquam imperdiet magna nec massa consectetur, id interdum ante congue.",
|
|
href: "#",
|
|
image: "https://deifkwefumgah.cloudfront.net/shadcnblocks/block/placeholder-2.svg",
|
|
},
|
|
{
|
|
id: "feature-3",
|
|
title: "Feature 3",
|
|
description:
|
|
"Nam vitae molestie arcu. Quisque eu libero orci. Aliquam imperdiet magna nec massa consectetur, id interdum ante congue.",
|
|
href: "#",
|
|
image: "https://deifkwefumgah.cloudfront.net/shadcnblocks/block/placeholder-3.svg",
|
|
},
|
|
];
|
|
|
|
interface FeatureCarouselGridProps {
|
|
className?: string;
|
|
}
|
|
|
|
const FeatureCarouselGrid = ({ className }: FeatureCarouselGridProps) => {
|
|
const [selection, setSelection] = useState(0);
|
|
const [carouselApi, setCarouselApi] = useState<CarouselApi>();
|
|
useEffect(() => {
|
|
if (!carouselApi) {
|
|
return;
|
|
}
|
|
carouselApi.scrollTo(selection);
|
|
}, [carouselApi, selection]);
|
|
useEffect(() => {
|
|
if (!carouselApi) {
|
|
return;
|
|
}
|
|
const updateSelection = () => {
|
|
setSelection(carouselApi.selectedScrollSnap());
|
|
};
|
|
carouselApi.on("select", updateSelection);
|
|
return () => {
|
|
carouselApi.off("select", updateSelection);
|
|
};
|
|
}, [carouselApi]);
|
|
return (
|
|
<section className={cn("py-32", className)}>
|
|
<div className="container mx-auto">
|
|
<div className="flex flex-col gap-8 md:flex-row-reverse">
|
|
<div className="aspect-5/6 overflow-clip rounded-3xl bg-accent">
|
|
<Carousel
|
|
setApi={setCarouselApi}
|
|
className="h-full w-full [&>div]:h-full"
|
|
>
|
|
<CarouselContent className="mx-0 h-full w-full">
|
|
{features.map((feature) => (
|
|
<CarouselItem key={feature.id} className="px-0">
|
|
<img
|
|
src={feature.image}
|
|
alt={feature.title}
|
|
className="h-full w-full object-cover object-center"
|
|
/>
|
|
</CarouselItem>
|
|
))}
|
|
</CarouselContent>
|
|
</Carousel>
|
|
</div>
|
|
<div className="flex shrink-0 flex-col md:w-1/2 md:pr-8 lg:pr-24 lg:text-left 2xl:pr-32">
|
|
<h2 className="text-heading-2 mb-6 font-semibold text-pretty">
|
|
Features
|
|
</h2>
|
|
<p className="text-body mb-16 leading-relaxed text-muted-foreground">
|
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Elig
|
|
doloremque mollitia fugiat omnis! Porro facilis quo animi
|
|
consequatur. Explicabo.
|
|
</p>
|
|
<ul className="space-y-2">
|
|
{features.map((feature, i) => (
|
|
<li
|
|
key={feature.id}
|
|
className="group relative w-full cursor-pointer px-6 py-3 transition data-open:bg-accent"
|
|
data-open={selection === i ? "true" : undefined}
|
|
onClick={() => setSelection(i)}
|
|
>
|
|
<div className="flex items-center justify-between gap-x-2">
|
|
<div className="text-body-sm font-semibold text-accent-foreground">
|
|
{feature.title}
|
|
</div>
|
|
<div className="flex size-8 items-center justify-center rounded-full bg-accent text-accent-foreground group-hover:bg-primary group-hover:text-primary-foreground group-data-open:bg-primary group-data-open:text-primary-foreground">
|
|
<ChevronDown className="size-4 shrink-0 transition-transform duration-200 group-data-open:rotate-180" />
|
|
</div>
|
|
</div>
|
|
<div className="text-body-sm hidden font-medium group-data-open:block">
|
|
<p className="my-4 text-muted-foreground lg:my-6">
|
|
{feature.description}
|
|
</p>
|
|
<a
|
|
href="#"
|
|
className="group/link text-body-sm flex items-center pb-3 text-accent-foreground"
|
|
>
|
|
Learn more{" "}
|
|
<ArrowRight className="ml-2 size-4 transition-transform group-hover/link:translate-x-1" />
|
|
</a>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { FeatureCarouselGrid };
|