Files
06456e15-299e-41ce-bd9a-c06…/src/components/sections/hero/HeroBillboard.tsx

161 lines
5.1 KiB
TypeScript

"use client";
import TextBox from "@/components/Textbox";
import MediaContent from "@/components/shared/MediaContent";
import HeroBackgrounds, { type HeroBackgroundVariantProps } from "@/components/background/HeroBackgrounds";
import LogoMarquee, { type MarqueeItem } from "@/components/shared/LogoMarquee";
import { cls } from "@/lib/utils";
import type { LucideIcon } from "lucide-react";
import type { ButtonConfig } from "@/types/button";
import type { Avatar } from "@/components/shared/AvatarGroup";
type HeroBillboardBackgroundProps = Extract<
HeroBackgroundVariantProps,
| { variant: "plain" }
| { variant: "animated-grid" }
| { variant: "canvas-reveal" }
| { variant: "cell-wave" }
| { variant: "downward-rays-animated" }
| { variant: "downward-rays-animated-grid" }
| { variant: "downward-rays-static" }
| { variant: "downward-rays-static-grid" }
| { variant: "gradient-bars" }
| { variant: "radial-gradient" }
| { variant: "rotated-rays-animated" }
| { variant: "rotated-rays-animated-grid" }
| { variant: "rotated-rays-static" }
| { variant: "rotated-rays-static-grid" }
| { variant: "sparkles-gradient" }
>;
interface HeroBillboardProps {
title: string;
description: string;
background: HeroBillboardBackgroundProps;
tag?: string;
tagIcon?: LucideIcon;
buttons?: ButtonConfig[];
avatars?: Avatar[];
avatarText?: string;
imageSrc?: string;
videoSrc?: string;
imageAlt?: string;
videoAriaLabel?: string;
marqueeItems?: MarqueeItem[];
marqueeSpeed?: number;
showMarqueeCard?: boolean;
ariaLabel?: string;
className?: string;
containerClassName?: string;
textBoxClassName?: string;
titleClassName?: string;
descriptionClassName?: string;
tagClassName?: string;
avatarGroupClassName?: string;
buttonContainerClassName?: string;
buttonClassName?: string;
buttonTextClassName?: string;
mediaWrapperClassName?: string;
imageClassName?: string;
marqueeClassName?: string;
marqueeItemClassName?: string;
marqueeCardClassName?: string;
marqueeImageClassName?: string;
marqueeTextClassName?: string;
marqueeIconClassName?: string;
}
const HeroBillboard = ({
title,
description,
background,
tag,
tagIcon,
buttons,
avatars,
avatarText,
imageSrc,
videoSrc,
imageAlt = "",
videoAriaLabel = "Hero video",
marqueeItems,
marqueeSpeed = 30,
showMarqueeCard = true,
ariaLabel = "Hero section",
className = "",
containerClassName = "",
textBoxClassName = "",
titleClassName = "",
descriptionClassName = "",
tagClassName = "",
avatarGroupClassName = "",
buttonContainerClassName = "",
buttonClassName = "",
buttonTextClassName = "",
mediaWrapperClassName = "",
imageClassName = "",
marqueeClassName = "",
marqueeItemClassName = "",
marqueeCardClassName = "",
marqueeImageClassName = "",
marqueeTextClassName = "",
marqueeIconClassName = "",
}: HeroBillboardProps) => {
return (
<section
aria-label={ariaLabel}
className={cls("relative w-full py-hero-page-padding", className)}
>
<HeroBackgrounds {...background} />
<div className={cls("w-content-width mx-auto flex flex-col gap-14 md:gap-15 relative z-10", containerClassName)}>
<TextBox
title={title}
description={description}
tag={tag}
tagIcon={tagIcon}
buttons={buttons}
avatars={avatars}
avatarText={avatarText}
avatarsAbove={true}
className={cls("flex flex-col gap-3 md:gap-1", textBoxClassName)}
titleClassName={cls("text-6xl font-medium text-balance", titleClassName)}
descriptionClassName={cls("text-base md:text-lg leading-[1.2]", descriptionClassName)}
tagClassName={cls("px-3 py-1 text-sm rounded-theme card text-foreground inline-flex items-center gap-2 mb-3", tagClassName)}
avatarGroupClassName={avatarGroupClassName}
buttonContainerClassName={cls("flex flex-wrap gap-4 mt-3", buttonContainerClassName)}
buttonClassName={buttonClassName}
buttonTextClassName={buttonTextClassName}
center={true}
/>
<div className="flex flex-col gap-3" >
<div className={cls("w-full overflow-hidden rounded-theme-capped card p-4", mediaWrapperClassName)}>
<MediaContent
imageSrc={imageSrc}
videoSrc={videoSrc}
imageAlt={imageAlt}
videoAriaLabel={videoAriaLabel}
imageClassName={cls("z-1", imageClassName)}
/>
</div>
{marqueeItems && marqueeItems.length > 0 && (
<LogoMarquee
items={marqueeItems}
speed={marqueeSpeed}
showCard={showMarqueeCard}
className={cls("w-content-width mx-auto z-10", marqueeClassName)}
itemClassName={marqueeItemClassName}
cardClassName={marqueeCardClassName}
imageClassName={marqueeImageClassName}
textClassName={marqueeTextClassName}
iconClassName={marqueeIconClassName}
/>
)}
</div>
</div>
</section>
);
};
HeroBillboard.displayName = "HeroBillboard";
export default HeroBillboard;