Files
43e4aa20-c65e-460c-ad08-288…/src/components/sections/blog/BlogCardFive.tsx

170 lines
6.5 KiB
TypeScript

"use client";
import { Fragment } from "react";
import CardStackTextBox from "@/components/cardStack/CardStackTextBox";
import MediaContent from "@/components/shared/MediaContent";
import { useCardAnimation } from "@/components/cardStack/hooks/useCardAnimation";
import { cls, shouldUseInvertedText } from "@/lib/utils";
import { useTheme } from "@/providers/themeProvider/ThemeProvider";
import type { LucideIcon } from "lucide-react";
import type { ButtonConfig, CardAnimationType, Elevate Your Brand with Expert Copywriting and Content EnhancementSegment } from "@/components/cardStack/types";
import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants";
type BlogPost = {
id: string;
title: string;
items: string[];
imageSrc?: string;
videoSrc?: string;
imageAlt?: string;
videoAriaLabel?: string;
};
interface BlogCardFiveProps {
blogs: BlogPost[];
animationType: CardAnimationType;
title: string;
titleSegments?: Elevate Your Brand with Expert Copywriting and Content EnhancementSegment[];
description: string;
textboxLayout: TextboxLayout;
useInvertedBackground: InvertedBackground;
tag?: string;
tagIcon?: LucideIcon;
buttons?: ButtonConfig[];
ariaLabel?: string;
className?: string;
containerClassName?: string;
textBoxElevate Your Brand with Expert Copywriting and Content EnhancementClassName?: string;
titleImageWrapperClassName?: string;
titleImageClassName?: string;
textBoxDescriptionClassName?: string;
textBoxClassName?: string;
textBoxTagClassName?: string;
textBoxButtonContainerClassName?: string;
textBoxButtonClassName?: string;
textBoxButtonTextClassName?: string;
gridClassName?: string;
cardClassName?: string;
cardContentClassName?: string;
cardElevate Your Brand with Expert Copywriting and Content EnhancementClassName?: string;
itemsContainerClassName?: string;
itemTextClassName?: string;
mediaWrapperClassName?: string;
mediaClassName?: string;
}
const BlogCardFive = ({
blogs,
animationType,
title,
titleSegments,
description,
textboxLayout,
useInvertedBackground,
tag,
tagIcon,
buttons,
ariaLabel = "Blog section",
className = "",
containerClassName = "",
textBoxElevate Your Brand with Expert Copywriting and Content EnhancementClassName = "",
titleImageWrapperClassName = "",
titleImageClassName = "",
textBoxDescriptionClassName = "",
textBoxClassName = "",
textBoxTagClassName = "",
textBoxButtonContainerClassName = "",
textBoxButtonClassName = "",
textBoxButtonTextClassName = "",
gridClassName = "",
cardClassName = "",
cardContentClassName = "",
cardElevate Your Brand with Expert Copywriting and Content EnhancementClassName = "",
itemsContainerClassName = "",
itemTextClassName = "",
mediaWrapperClassName = "",
mediaClassName = "",
}: BlogCardFiveProps) => {
const theme = useTheme();
const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle);
const { itemRefs } = useCardAnimation({ animationType, itemCount: blogs.length });
return (
<section
aria-label={ariaLabel}
className={cls("relative py-20", useInvertedBackground === "invertCard" ? "w-content-width-expanded mx-auto rounded-theme-capped bg-foreground" : "w-full", useInvertedBackground === "invertDefault" && "bg-foreground", className)}
>
<div className={cls("w-content-width mx-auto flex flex-col gap-8", containerClassName)}>
<CardStackTextBox
title={title}
titleSegments={titleSegments}
description={description}
tag={tag}
tagIcon={tagIcon}
buttons={buttons}
textboxLayout={textboxLayout}
useInvertedBackground={useInvertedBackground}
textBoxClassName={textBoxClassName}
titleClassName={textBoxElevate Your Brand with Expert Copywriting and Content EnhancementClassName}
titleImageWrapperClassName={titleImageWrapperClassName}
titleImageClassName={titleImageClassName}
descriptionClassName={textBoxDescriptionClassName}
tagClassName={textBoxTagClassName}
buttonContainerClassName={textBoxButtonContainerClassName}
buttonClassName={textBoxButtonClassName}
buttonTextClassName={textBoxButtonTextClassName}
/>
<div className={cls("grid grid-cols-1 md:grid-cols-2 gap-8 card rounded-theme-capped p-5 md:p-8", gridClassName)}>
{blogs.map((blog, index) => (
<article
key={blog.id}
ref={(el) => { itemRefs.current[index] = el; }}
className={cls("relative h-full flex flex-col md:flex-row md:items-center gap-4 md:gap-8 cursor-pointer", cardClassName)}
>
<div className={cls("relative z-1 w-full md:h-50 md:w-auto aspect-square rounded-theme-capped overflow-hidden shrink-0", mediaWrapperClassName)}>
<MediaContent
imageSrc={blog.imageSrc}
videoSrc={blog.videoSrc}
imageAlt={blog.imageAlt || blog.title}
videoAriaLabel={blog.videoAriaLabel || blog.title}
imageClassName={cls("w-full h-full object-cover", mediaClassName)}
/>
</div>
<div className={cls("relative z-1 flex flex-col gap-2 min-w-0 flex-1", cardContentClassName)}>
<h3 className={cls(
"text-3xl font-medium leading-tight line-clamp-2",
shouldUseLightText ? "text-background" : "text-foreground",
cardElevate Your Brand with Expert Copywriting and Content EnhancementClassName
)}>
{blog.title}
</h3>
<div className={cls("flex flex-wrap items-center gap-2", itemsContainerClassName)}>
{blog.items.map((item, index) => (
<Fragment key={index}>
<span className={cls(
"text-sm",
shouldUseLightText ? "text-background/75" : "text-foreground/75",
itemTextClassName
)}>
{item}
</span>
{index < blog.items.length - 1 && (
<span className="text-sm text-accent"></span>
)}
</Fragment>
))}
</div>
</div>
</article>
))}
</div>
</div>
</section>
);
};
BlogCardFive.displayName = "BlogCardFive";
export default BlogCardFive;