import { useCallback, useEffect, useState } from 'react'; export interface UseIntersectionVisibleOptions { root?: Element | Document | null; rootMargin?: string; threshold?: number | number[]; /** true — 포커스·전체화면 등 항상 활성 */ initialVisible?: boolean; } /** * 요소가 뷰포트(또는 root)에 들어왔는지 — 차트·폴링 gating 용 */ export function useIntersectionVisible( options: UseIntersectionVisibleOptions = {}, ): { ref: (node: HTMLElement | null) => void; visible: boolean } { const { root = null, rootMargin = '100px 0px', threshold = 0.05, initialVisible = false, } = options; const [element, setElement] = useState(null); const [visible, setVisible] = useState(initialVisible); const ref = useCallback((node: HTMLElement | null) => { setElement(node); }, []); useEffect(() => { if (!element) return; const io = new IntersectionObserver( entries => { setVisible(entries[0]?.isIntersecting ?? false); }, { root, rootMargin, threshold }, ); io.observe(element); return () => io.disconnect(); }, [element, root, rootMargin, threshold]); return { ref, visible }; }