From 2936b85b31791a5863f4e6b89b8834bfe4c982c8 Mon Sep 17 00:00:00 2001 From: bender Date: Mon, 9 Mar 2026 08:26:29 +0000 Subject: [PATCH] Switch to version 1: modified src/components/cardStack/layouts/timelines/TimelineProcessFlow.tsx --- .../layouts/timelines/TimelineProcessFlow.tsx | 209 ++++++++++++++++-- 1 file changed, 189 insertions(+), 20 deletions(-) diff --git a/src/components/cardStack/layouts/timelines/TimelineProcessFlow.tsx b/src/components/cardStack/layouts/timelines/TimelineProcessFlow.tsx index f78d3f2..5e40887 100644 --- a/src/components/cardStack/layouts/timelines/TimelineProcessFlow.tsx +++ b/src/components/cardStack/layouts/timelines/TimelineProcessFlow.tsx @@ -1,33 +1,202 @@ -import React from "react"; -import { useCardAnimation } from "@/components/cardStack/hooks/useCardAnimation"; +"use client"; + +import React, { useEffect, useRef, memo, useState } from "react"; +import { gsap } from "gsap"; +import { ScrollTrigger } from "gsap/ScrollTrigger"; +import CardStackTextBox from "../../CardStackTextBox"; +import { useCardAnimation } from "../../hooks/useCardAnimation"; +import { cls } from "@/lib/utils"; +import type { LucideIcon } from "lucide-react"; +import type { ButtonConfig, ButtonAnimationType, CardAnimationType, TitleSegment } from "../../types"; +import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; + +gsap.registerPlugin(ScrollTrigger); interface TimelineProcessFlowItem { id: string; + content: React.ReactNode; + media: React.ReactNode; reverse: boolean; - media: React.ReactElement; - content: React.ReactElement; } interface TimelineProcessFlowProps { - items?: TimelineProcessFlowItem[]; + items: TimelineProcessFlowItem[]; + title: string; + titleSegments?: TitleSegment[]; + description: string; + tag?: string; + tagIcon?: LucideIcon; + tagAnimation?: ButtonAnimationType; + buttons?: ButtonConfig[]; + buttonAnimation?: ButtonAnimationType; + textboxLayout: TextboxLayout; + animationType: CardAnimationType; + useInvertedBackground?: InvertedBackground; + ariaLabel?: string; + className?: string; + containerClassName?: string; + textBoxClassName?: string; + textBoxTitleClassName?: string; + textBoxDescriptionClassName?: string; + textBoxTagClassName?: string; + textBoxButtonContainerClassName?: string; + textBoxButtonClassName?: string; + textBoxButtonTextClassName?: string; + itemClassName?: string; + mediaWrapperClassName?: string; + numberClassName?: string; + contentWrapperClassName?: string; + gapClassName?: string; + titleImageWrapperClassName?: string; + titleImageClassName?: string; } -export default function TimelineProcessFlow({ items = [] }: TimelineProcessFlowProps) { - const state = useCardAnimation({ - rotationX: 0, - rotationY: 0, - rotationZ: 0, - perspective: 1000, - duration: 0.3, - }); +const TimelineProcessFlow = ({ + items, + title, + titleSegments, + description, + tag, + tagIcon, + tagAnimation, + buttons, + buttonAnimation, + textboxLayout, + animationType, + useInvertedBackground, + ariaLabel = "Timeline process flow section", + className = "", + containerClassName = "", + textBoxClassName = "", + textBoxTitleClassName = "", + textBoxDescriptionClassName = "", + textBoxTagClassName = "", + textBoxButtonContainerClassName = "", + textBoxButtonClassName = "", + textBoxButtonTextClassName = "", + itemClassName = "", + mediaWrapperClassName = "", + numberClassName = "", + contentWrapperClassName = "", + gapClassName = "", + titleImageWrapperClassName = "", + titleImageClassName = "", +}: TimelineProcessFlowProps) => { + const processLineRef = useRef(null); + const { itemRefs } = useCardAnimation({ animationType, itemCount: items.length, useIndividualTriggers: true }); + const [isMdScreen, setIsMdScreen] = useState(false); + + useEffect(() => { + const checkScreenSize = () => { + setIsMdScreen(window.innerWidth >= 768); + }; + + checkScreenSize(); + window.addEventListener('resize', checkScreenSize); + + return () => window.removeEventListener('resize', checkScreenSize); + }, []); + + useEffect(() => { + if (!processLineRef.current) return; + + gsap.fromTo( + processLineRef.current, + { yPercent: -100 }, + { + yPercent: 0, + ease: "none", + scrollTrigger: { + trigger: ".timeline-line", + start: "top center", + end: "bottom center", + scrub: true, + }, + } + ); + + return () => { + ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); + }; + }, []); return ( -
- {items.map((item) => ( -
- {item.content} +
+
+
+
- ))} -
+
+
+
+
+
+
+
    + {items.map((item, index) => ( +
  1. { + itemRefs.current[index] = el; + }} + className={cls( + "relative z-10 w-full flex flex-col gap-6 md:gap-0 md:flex-row justify-between", + item.reverse && "flex-col md:flex-row-reverse", + itemClassName + )} + > +
    + {item.media} +
    +
    +

    {item.id}

    +
    +
    + {item.content} +
    +
  2. + ))} +
+
+
+
); -} +}; + +TimelineProcessFlow.displayName = "TimelineProcessFlow"; + +export default memo(TimelineProcessFlow);