'use client'; import * as React from 'react'; import { cn } from '@/utils/cn'; type TimelineContentProps = { children: React.ReactNode; animationNum: number; className?: string; timelineRef: React.RefObject; as?: T; visibleClassName?: string; hiddenClassName?: string; once?: boolean; } & React.HTMLAttributes; export default function TimelineContent< T extends keyof HTMLElementTagNameMap = 'div', >({ children, animationNum, timelineRef, className, as, visibleClassName = 'translate-y-0 opacity-100 blur-0', hiddenClassName = 'translate-y-2.5 opacity-0 blur-md', once = true, ...rest }: TimelineContentProps) { const [isInView, setIsInView] = React.useState(false); const Component = as || 'div'; React.useEffect(() => { const element = timelineRef.current; if (!element) return; const observer = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setIsInView(true); if (once) observer.unobserve(element); } else if (!once) { setIsInView(false); } }); observer.observe(element); return () => observer.disconnect(); }, [once, timelineRef]); return React.createElement( Component, { className: cn( 'transition-[opacity,filter,transform] duration-500 ease-out will-change-[transform,filter,opacity]', isInView ? visibleClassName : hiddenClassName, className, ), style: { transitionDelay: `${animationNum * 0.16}s`, ...rest.style, }, ...rest, }, children, ); }