93 lines
3.5 KiB
TypeScript
93 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import React, { useMemo } from "react";
|
|
import CardList from "@/components/card/CardList";
|
|
import type { ButtonAnimationType } from "@/types/animations";
|
|
import type { LucideIcon } from "lucide-react";
|
|
|
|
export interface FeatureCardTwelveProps {
|
|
features?: Array<{
|
|
id: string;
|
|
title: string;
|
|
description: string;
|
|
icon?: React.ReactNode;
|
|
}>;
|
|
animationType?: ButtonAnimationType;
|
|
textboxLayout?: "default" | "split" | "split-actions" | "split-description" | "inline-image";
|
|
description?: string;
|
|
tag?: string;
|
|
tagIcon?: LucideIcon;
|
|
tagAnimation?: "none" | "opacity" | "slide-up" | "blur-reveal";
|
|
buttons?: Array<{ text: string; onClick?: () => void; href?: string }>;
|
|
buttonAnimation?: "none" | "opacity" | "slide-up" | "blur-reveal";
|
|
useInvertedBackground?: boolean;
|
|
ariaLabel?: string;
|
|
className?: string;
|
|
containerClassName?: string;
|
|
cardClassName?: string;
|
|
textBoxTitleClassName?: string;
|
|
textBoxDescriptionClassName?: string;
|
|
cardTitleClassName?: string;
|
|
cardDescriptionClassName?: string;
|
|
cardIconClassName?: string;
|
|
cardIconWrapperClassName?: string;
|
|
listClassName?: string;
|
|
itemClassName?: string;
|
|
textBoxClassName?: string;
|
|
textBoxTagClassName?: string;
|
|
textBoxButtonContainerClassName?: string;
|
|
textBoxButtonClassName?: string;
|
|
textBoxButtonTextClassName?: string;
|
|
}
|
|
|
|
const FeatureCardTwelve: React.FC<FeatureCardTwelveProps> = ({
|
|
features = [],
|
|
animationType = "slide-up", textboxLayout = "default", description = "", tag,
|
|
tagIcon,
|
|
tagAnimation,
|
|
buttons,
|
|
buttonAnimation,
|
|
useInvertedBackground = false,
|
|
ariaLabel = "Feature section", className = "", containerClassName = "", cardClassName = "", textBoxTitleClassName = "", textBoxDescriptionClassName = "", cardTitleClassName = "", cardDescriptionClassName = "", cardIconClassName = "", cardIconWrapperClassName = "", listClassName = "", itemClassName = "", textBoxClassName = "", textBoxTagClassName = "", textBoxButtonContainerClassName = "", textBoxButtonClassName = "", textBoxButtonTextClassName = ""}) => {
|
|
const listItems = useMemo(
|
|
() =>
|
|
features.map((feature) => (
|
|
<div key={feature.id} className={`flex gap-4 p-4 rounded-lg bg-card/50 ${itemClassName}`}>
|
|
{feature.icon && (
|
|
<div className={`flex-shrink-0 flex items-center justify-center w-10 h-10 rounded-lg bg-primary-cta/10 ${cardIconWrapperClassName}`}>
|
|
<span className={`text-lg ${cardIconClassName}`}>{feature.icon}</span>
|
|
</div>
|
|
)}
|
|
<div className="flex-1 min-w-0">
|
|
<h3 className={`text-sm font-semibold text-foreground ${cardTitleClassName}`}>
|
|
{feature.title}
|
|
</h3>
|
|
<p className={`text-xs text-foreground/70 ${cardDescriptionClassName}`}>
|
|
{feature.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)),
|
|
[features, itemClassName, cardIconWrapperClassName, cardIconClassName, cardTitleClassName, cardDescriptionClassName]
|
|
);
|
|
|
|
return (
|
|
<div
|
|
className={`w-full py-20 ${useInvertedBackground ? "bg-background/50" : ""} ${containerClassName}`}
|
|
aria-label={ariaLabel}
|
|
>
|
|
<div className="max-w-content-width mx-auto px-4">
|
|
<CardList
|
|
animationType={animationType}
|
|
ariaLabel={ariaLabel}
|
|
className={className}
|
|
listClassName={listClassName}
|
|
>
|
|
{listItems.map((item) => item)}
|
|
</CardList>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FeatureCardTwelve; |