From 7d9c48ae02dc168cdff5edd2465d3b8bd0241395 Mon Sep 17 00:00:00 2001 From: bender Date: Fri, 6 Mar 2026 21:43:17 +0000 Subject: [PATCH] Switch to version 1: modified src/components/cardStack/CardStack.tsx --- src/components/cardStack/CardStack.tsx | 258 +++++++++++++++++++++---- 1 file changed, 221 insertions(+), 37 deletions(-) diff --git a/src/components/cardStack/CardStack.tsx b/src/components/cardStack/CardStack.tsx index 045fec6..3003a8a 100644 --- a/src/components/cardStack/CardStack.tsx +++ b/src/components/cardStack/CardStack.tsx @@ -1,45 +1,229 @@ "use client"; -import React, { useState } from "react"; +import { memo, Children } from "react"; +import { CardStackProps } from "./types"; +import GridLayout from "./layouts/grid/GridLayout"; +import AutoCarousel from "./layouts/carousels/AutoCarousel"; +import ButtonCarousel from "./layouts/carousels/ButtonCarousel"; import TimelineBase from "./layouts/timelines/TimelineBase"; +import { gridConfigs } from "./layouts/grid/gridConfigs"; -interface CardStackProps { - children?: React.ReactNode; - title: string; - description?: string; - mediaItems?: Array<{ id: string; imageSrc?: string; imageAlt?: string }>; - tag?: string; - tagIcon?: React.ComponentType<{ className?: string }>; - textboxLayout?: string; - animationType?: string; - useInvertedBackground?: boolean; - ariaLabel?: string; - className?: string; - gridVariant?: string; - uniformGridCustomHeightClasses?: string; - carouselThreshold?: number; - carouselMode?: "auto" | "buttons"; - carouselItemClassName?: string; - mode?: "auto" | "buttons"; -} +const CardStack = ({ + children, + mode = "buttons", + gridVariant = "uniform-all-items-equal", + uniformGridCustomHeightClasses, + gridRowsClassName, + itemHeightClassesOverride, + animationType, + supports3DAnimation = false, + title, + titleSegments, + description, + tag, + tagIcon, + tagAnimation, + buttons, + buttonAnimation, + textboxLayout = "default", + useInvertedBackground, + carouselThreshold = 5, + bottomContent, + className = "", + containerClassName = "", + gridClassName = "", + carouselClassName = "", + carouselItemClassName = "", + controlsClassName = "", + textBoxClassName = "", + titleClassName = "", + titleImageWrapperClassName = "", + titleImageClassName = "", + descriptionClassName = "", + tagClassName = "", + buttonContainerClassName = "", + buttonClassName = "", + buttonTextClassName = "", + ariaLabel = "Card stack", +}: CardStackProps) => { + const childrenArray = Children.toArray(children); + const itemCount = childrenArray.length; -export const CardStack: React.FC = ({ - children, - title, - description, - mediaItems, - tag, - tagIcon: TagIcon, - textboxLayout = "default", animationType = "slide-up", useInvertedBackground = false, - ariaLabel = "Card stack section", className = "", gridVariant = "", uniformGridCustomHeightClasses = "", carouselThreshold = 5, - carouselMode = "buttons"}) => { - const [currentIndex, setCurrentIndex] = useState(0); + // Check if the current grid config has gridRows defined + const gridConfig = gridConfigs[gridVariant]?.[itemCount]; + const hasFixedGridRows = gridConfig && 'gridRows' in gridConfig && gridConfig.gridRows; - return ( - - {children} - - ); + // If grid has fixed row heights and we have uniformGridCustomHeightClasses, + // we need to use min-h-0 on md+ to prevent conflicts + let adjustedHeightClasses = uniformGridCustomHeightClasses; + if (hasFixedGridRows && uniformGridCustomHeightClasses) { + // Extract the mobile min-height and add md:min-h-0 + const mobileMinHeight = uniformGridCustomHeightClasses.split(' ')[0]; + adjustedHeightClasses = `${mobileMinHeight} md:min-h-0`; + } + + // Timeline layout for zigzag pattern (works best with 3-6 items) + if (gridVariant === "timeline" && itemCount >= 3 && itemCount <= 6) { + // Convert depth-3d to scale-rotate for timeline (doesn't support 3D) + const timelineAnimationType = animationType === "depth-3d" ? "scale-rotate" : animationType; + + return ( + + {childrenArray} + + ); + } + + // Use grid for items below threshold, carousel for items at or above threshold + // Timeline with 7+ items will also use carousel + const useCarousel = itemCount >= carouselThreshold || (gridVariant === "timeline" && itemCount > 6); + + // Grid layout for 1-4 items + if (!useCarousel) { + return ( + + {childrenArray} + + ); + } + + // Auto-scroll carousel for 5+ items + if (mode === "auto") { + // Convert depth-3d to scale-rotate for carousel (doesn't support 3D) + const carouselAnimationType = animationType === "depth-3d" ? "scale-rotate" : animationType; + + return ( + + {childrenArray} + + ); + } + + // Button-controlled carousel for 5+ items + // Convert depth-3d to scale-rotate for carousel (doesn't support 3D) + const carouselAnimationType = animationType === "depth-3d" ? "scale-rotate" : animationType; + + return ( + + {childrenArray} + + ); }; -export default CardStack; +CardStack.displayName = "CardStack"; + +export default memo(CardStack);