'use client'; import { ReactNode, useRef, useState } from 'react'; import { motion, useInView, Variant, Transition, UseInViewOptions, } from 'motion/react'; export type InViewProps = { children: ReactNode; variants?: { hidden: Variant; visible: Variant; }; transition?: Transition; viewOptions?: UseInViewOptions; as?: React.ElementType; once?: boolean }; const defaultVariants = { hidden: { opacity: 0 }, visible: { opacity: 1 }, }; export function InView({ children, variants = defaultVariants, transition, viewOptions, as = 'div', once }: InViewProps) { const ref = useRef(null); const isInView = useInView(ref, viewOptions); const [isViewed, setIsViewed] = useState(false) const MotionComponent = motion[as as keyof typeof motion] as typeof as; return ( <MotionComponent ref={ref} initial='hidden' onAnimationComplete={() => { if (once) setIsViewed(true) }} animate={(isInView || isViewed) ? "visible" : "hidden"} variants={variants} transition={transition} > {children} </MotionComponent> ); }