// frontend\src\components\ui\LazyMountWhenVisible.tsx 'use client' import { useEffect, useRef, useState, type ReactNode } from 'react' type Props = { children: ReactNode placeholder?: ReactNode rootMargin?: string threshold?: number className?: string once?: boolean } export default function LazyMountWhenVisible({ children, placeholder = null, rootMargin = '300px', threshold = 0.01, className, once = true, }: Props) { const hostRef = useRef(null) const [visible, setVisible] = useState(false) useEffect(() => { const el = hostRef.current if (!el) return if (visible && once) return const io = new IntersectionObserver( (entries) => { const entry = entries[0] if (!entry) return if (entry.isIntersecting) { setVisible(true) if (once) io.disconnect() } else if (!once) { setVisible(false) } }, { rootMargin, threshold } ) io.observe(el) return () => io.disconnect() }, [visible, once, rootMargin, threshold]) return (
{visible ? children : placeholder}
) }