'use client' import { useCallback, useEffect, useRef, RefObject } from 'react' export function useSyncScroll( leftPanelRef: RefObject, rightPanelRef: RefObject, deps: unknown[], ) { const isScrolling = useRef(false) const setupSyncScroll = useCallback(() => { const leftPanel = leftPanelRef.current const rightPanel = rightPanelRef.current if (!leftPanel || !rightPanel) return const handleLeftScroll = () => { if (isScrolling.current) return isScrolling.current = true const leftScrollPercent = leftPanel.scrollTop / (leftPanel.scrollHeight - leftPanel.clientHeight || 1) const rightMaxScroll = rightPanel.scrollHeight - rightPanel.clientHeight rightPanel.scrollTop = leftScrollPercent * rightMaxScroll setTimeout(() => { isScrolling.current = false }, 10) } const handleRightScroll = () => { if (isScrolling.current) return isScrolling.current = true const rightScrollPercent = rightPanel.scrollTop / (rightPanel.scrollHeight - rightPanel.clientHeight || 1) const leftMaxScroll = leftPanel.scrollHeight - leftPanel.clientHeight leftPanel.scrollTop = rightScrollPercent * leftMaxScroll setTimeout(() => { isScrolling.current = false }, 10) } leftPanel.addEventListener('scroll', handleLeftScroll) rightPanel.addEventListener('scroll', handleRightScroll) return () => { leftPanel.removeEventListener('scroll', handleLeftScroll) rightPanel.removeEventListener('scroll', handleRightScroll) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { const cleanup = setupSyncScroll() return cleanup // eslint-disable-next-line react-hooks/exhaustive-deps }, [setupSyncScroll, ...deps]) }