"use client" import { useEffect, useRef, useState } from "react" import { motion, useScroll, useTransform, Variants } from "framer-motion" import { cn } from "@/lib/utils" import Container from "@/components/Container" const cardVariants: Variants = { offscreen: { y: 75, opacity: 0, }, onscreen: { y: 0, opacity: 1, transition: { duration: 0.4, }, }, } const pointVariants: Variants = { offscreen: { scale: 0, opacity: 0, }, onscreen: { scale: 1.1, opacity: 1, transition: { duration: 0.3, }, }, } const Timeline = ({ data }: { data: TimeLineProps[] }) => { const ref = useRef(null) const containerRef = useRef(null) const [height, setHeight] = useState(0) useEffect(() => { const updateHeight = () => { if (ref.current) { const rect = ref.current.getBoundingClientRect() setHeight(rect.height) } } updateHeight() window.addEventListener("resize", updateHeight) return () => window.removeEventListener("resize", updateHeight) }, []) const { scrollYProgress } = useScroll({ target: containerRef, offset: ["start 0%", "end 50%"], }) const heightTransform = useTransform(scrollYProgress, [0, 1], [0, height]) const opacityTransform = useTransform(scrollYProgress, [0, 0.1], [0, 1]) return (

How it works?

We work in a structured way. Here is how you will be onboard:

{data.map((item, index) => { const isEven = index % 2 !== 0 return (

{item.title}

{item.content}
) })}
) } export default Timeline