From cda29a43e7f431580f9cd1ac315d79220cf6680a Mon Sep 17 00:00:00 2001 From: bender Date: Wed, 11 Mar 2026 20:30:39 +0000 Subject: [PATCH] Update src/components/sections/feature/FeatureBento.tsx --- .../sections/feature/FeatureBento.tsx | 370 +++++------------- 1 file changed, 106 insertions(+), 264 deletions(-) diff --git a/src/components/sections/feature/FeatureBento.tsx b/src/components/sections/feature/FeatureBento.tsx index 462ddb5..f3fe303 100644 --- a/src/components/sections/feature/FeatureBento.tsx +++ b/src/components/sections/feature/FeatureBento.tsx @@ -1,146 +1,44 @@ "use client"; -import CardStack from "@/components/cardStack/CardStack"; -import Button from "@/components/button/Button"; -import { cls, shouldUseInvertedText } from "@/lib/utils"; -import { getButtonProps } from "@/lib/buttonUtils"; -import { useTheme } from "@/providers/themeProvider/ThemeProvider"; -import { BentoGlobe } from "@/components/bento/BentoGlobe"; -import BentoIconInfoCards from "@/components/bento/BentoIconInfoCards"; -import BentoAnimatedBarChart from "@/components/bento/BentoAnimatedBarChart"; -import Bento3DStackCards from "@/components/bento/Bento3DStackCards"; -import Bento3DTaskList, { type TaskItem } from "@/components/bento/Bento3DTaskList"; -import BentoOrbitingIcons, { type OrbitingItem } from "@/components/bento/BentoOrbitingIcons"; -import BentoMap from "@/components/bento/BentoMap"; -import BentoMarquee from "@/components/bento/BentoMarquee"; -import BentoLineChart from "@/components/bento/BentoLineChart/BentoLineChart"; -import BentoPhoneAnimation, { type PhoneApp, type PhoneApps8 } from "@/components/bento/BentoPhoneAnimation"; -import BentoChatAnimation, { type ChatExchange } from "@/components/bento/BentoChatAnimation"; -import Bento3DCardGrid from "@/components/bento/Bento3DCardGrid"; -import BentoRevealIcon from "@/components/bento/BentoRevealIcon"; -import BentoTimeline, { type TimelineItem } from "@/components/bento/BentoTimeline"; -import BentoMediaStack, { type MediaStackItem } from "@/components/bento/BentoMediaStack"; -import type { LucideIcon } from "lucide-react"; +import React, { useMemo } from "react"; +import CardStack from "@/components/card/CardStack"; +import TextBox from "@/components/Textbox"; +import type { BentoAnimationType } from "@/types/animations"; -export type { PhoneApp, PhoneApps8, ChatExchange, TimelineItem, MediaStackItem }; -import type { ButtonConfig, CardAnimationTypeWith3D, TitleSegment, ButtonAnimationType } from "@/components/cardStack/types"; - -import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; - -type BentoAnimationType = Exclude; - -export type BentoInfoItem = { - icon: LucideIcon; - label: string; - value: string; -}; - -export type Bento3DItem = { - icon: LucideIcon; - title: string; - subtitle: string; - detail: string; -}; - -type BaseFeatureCard = { - title: string; - description: string; - button?: ButtonConfig; -}; - -export type FeatureCard = BaseFeatureCard & ( - | { - bentoComponent: "icon-info-cards"; - items: BentoInfoItem[]; - } - | { - bentoComponent: "3d-stack-cards"; - items: [Bento3DItem, Bento3DItem, Bento3DItem]; - } - | { - bentoComponent: "3d-task-list"; - title: string; - items: TaskItem[]; - } - | { - bentoComponent: "orbiting-icons"; - centerIcon: LucideIcon; - items: OrbitingItem[]; - } - | ({ - bentoComponent: "marquee"; - centerIcon: LucideIcon; - } & ( - | { variant: "text"; texts: string[] } - | { variant: "icon"; icons: LucideIcon[] } - )) - | { - bentoComponent: "globe" | "animated-bar-chart" | "map" | "line-chart"; - items?: never; - } - | { - bentoComponent: "3d-card-grid"; - items: [{ name: string; icon: LucideIcon }, { name: string; icon: LucideIcon }, { name: string; icon: LucideIcon }, { name: string; icon: LucideIcon }]; - centerIcon: LucideIcon; - } - | { - bentoComponent: "phone"; - statusIcon: LucideIcon; - alertIcon: LucideIcon; - alertTitle: string; - alertMessage: string; - apps: PhoneApps8; - } - | { - bentoComponent: "chat"; - aiIcon: LucideIcon; - userIcon: LucideIcon; - exchanges: ChatExchange[]; - placeholder: string; - } - | { - bentoComponent: "reveal-icon"; - icon: LucideIcon; - } - | { - bentoComponent: "timeline"; - heading: string; - subheading: string; - items: [TimelineItem, TimelineItem, TimelineItem]; - completedLabel: string; - } - | { - bentoComponent: "media-stack"; - items: [MediaStackItem, MediaStackItem, MediaStackItem]; - } -); - -interface FeatureBentoProps { - features: FeatureCard[]; +export interface FeatureBentoProps { + features?: Array<{ + id: string; + title: string; + description: string; + icon?: React.ReactNode; + mediaItems?: Array<{ type: string; src: string; alt?: string }>; + }>; carouselMode?: "auto" | "buttons"; - animationType: BentoAnimationType; - title: string; - titleSegments?: TitleSegment[]; - description: string; + gridVariant?: string; + uniformGridCustomHeightClasses?: string; + animationType?: BentoAnimationType; + title?: string; + titleSegments?: Array<{ type: "text"; content: string } | { type: "image"; src: string; alt?: string }>; + description?: string; tag?: string; - tagIcon?: LucideIcon; - tagAnimation?: ButtonAnimationType; - buttons?: ButtonConfig[]; - buttonAnimation?: ButtonAnimationType; - textboxLayout: TextboxLayout; - useInvertedBackground: InvertedBackground; + tagAnimation?: "none" | "opacity" | "slide-up" | "blur-reveal"; + buttons?: Array<{ text: string; onClick?: () => void; href?: string }>; + buttonAnimation?: "none" | "opacity" | "slide-up" | "blur-reveal"; + textboxLayout?: "default" | "split" | "split-actions" | "split-description" | "inline-image"; + useInvertedBackground?: boolean; ariaLabel?: string; className?: string; containerClassName?: string; cardClassName?: string; + mediaClassName?: string; textBoxTitleClassName?: string; textBoxTitleImageWrapperClassName?: string; textBoxTitleImageClassName?: string; textBoxDescriptionClassName?: string; cardTitleClassName?: string; cardDescriptionClassName?: string; - cardButtonClassName?: string; - cardButtonTextClassName?: string; + cardIconClassName?: string; + cardIconWrapperClassName?: string; gridClassName?: string; carouselClassName?: string; controlsClassName?: string; @@ -151,150 +49,94 @@ interface FeatureBentoProps { textBoxButtonTextClassName?: string; } -const FeatureBento = ({ - features, - carouselMode = "buttons", - animationType, - title, +const FeatureBento: React.FC = ({ + features = [], + gridVariant = "uniform-all-items-equal", uniformGridCustomHeightClasses = "min-h-95 2xl:min-h-105", animationType = "slide-up", title, titleSegments, - description, - tag, - tagIcon, + description = "", tag, tagAnimation, buttons, buttonAnimation, - textboxLayout, - useInvertedBackground, - ariaLabel = "Feature section", - className = "", - containerClassName = "", - cardClassName = "", - textBoxTitleClassName = "", - textBoxTitleImageWrapperClassName = "", - textBoxTitleImageClassName = "", - textBoxDescriptionClassName = "", - cardTitleClassName = "", - cardDescriptionClassName = "", - cardButtonClassName = "", - cardButtonTextClassName = "", - gridClassName = "", - carouselClassName = "", - controlsClassName = "", - textBoxClassName = "", - textBoxTagClassName = "", - textBoxButtonContainerClassName = "", - textBoxButtonClassName = "", - textBoxButtonTextClassName = "", -}: FeatureBentoProps) => { - const theme = useTheme(); - const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle); - - const getBentoComponent = (feature: FeatureCard) => { - switch (feature.bentoComponent) { - case "globe": - return ( -
- -
- ); - case "icon-info-cards": - return ; - case "animated-bar-chart": - return ; - case "3d-stack-cards": - return ({ Icon: item.icon, title: item.title, subtitle: item.subtitle, detail: item.detail }))} useInvertedBackground={useInvertedBackground} />; - case "3d-task-list": - return ; - case "orbiting-icons": - return ; - case "marquee": - return feature.variant === "text" - ? - : ; - case "map": - return ; - case "line-chart": - return ; - case "3d-card-grid": - return ; - case "phone": - return ; - case "chat": - return ; - case "reveal-icon": - return ; - case "timeline": - return ; - case "media-stack": - return ; - } - }; - - return ( - - {features.map((feature, index) => ( + textboxLayout = "default", useInvertedBackground = false, + ariaLabel = "Feature section", className = "", containerClassName = "", cardClassName = "", mediaClassName = "", textBoxTitleClassName = "", textBoxTitleImageWrapperClassName = "", textBoxTitleImageClassName = "", textBoxDescriptionClassName = "", cardTitleClassName = "", cardDescriptionClassName = "", cardIconClassName = "", cardIconWrapperClassName = "", gridClassName = "", carouselClassName = "", controlsClassName = "", textBoxClassName = "", textBoxTagClassName = "", textBoxButtonContainerClassName = "", textBoxButtonClassName = "", textBoxButtonTextClassName = ""}) => { + const cardItems = useMemo( + () => + features.map((feature) => (
-
- {getBentoComponent(feature)} -
-
-

- {feature.title} -

-

- {feature.description} -

-
- {feature.button && ( -
- ))} -
+ )), + [features, cardClassName, cardIconWrapperClassName, cardIconClassName, cardTitleClassName, cardDescriptionClassName, mediaClassName] + ); + + return ( +
+ {title && ( +
+ +
+ )} + +
+ + {cardItems.map((item) => item)} + +
+
); }; -FeatureBento.displayName = "FeatureBento"; - -export default FeatureBento; +export default FeatureBento; \ No newline at end of file