From 3a8203d26e058cd09087f9eaf34cb14873ffbf2d Mon Sep 17 00:00:00 2001 From: Gigi Date: Sat, 11 Oct 2025 01:48:45 +0100 Subject: [PATCH] fix: mobile button scroll detection on main pane element - Update useScrollDirection to accept elementRef parameter - Detect scroll on main pane div instead of window - Create mainPaneRef and attach to scrollable content area - Fix issue where scroll events weren't detected on mobile On mobile, content scrolls within .pane.main (overflow-y: auto) not on window. Now buttons properly hide on scroll down and show on scroll up. --- src/components/ThreePaneLayout.tsx | 10 ++++++++-- src/hooks/useScrollDirection.ts | 27 +++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/components/ThreePaneLayout.tsx b/src/components/ThreePaneLayout.tsx index 19f517c3..ea588fc2 100644 --- a/src/components/ThreePaneLayout.tsx +++ b/src/components/ThreePaneLayout.tsx @@ -87,11 +87,14 @@ const ThreePaneLayout: React.FC = (props) => { const isMobile = useIsMobile() const sidebarRef = useRef(null) const highlightsRef = useRef(null) + const mainPaneRef = useRef(null) // Detect scroll direction to hide/show mobile buttons + // On mobile, scroll happens in the main pane, not on window const scrollDirection = useScrollDirection({ threshold: 10, - enabled: isMobile && !props.isSidebarOpen && props.isHighlightsCollapsed + enabled: isMobile && !props.isSidebarOpen && props.isHighlightsCollapsed, + elementRef: mainPaneRef }) const showMobileButtons = scrollDirection !== 'down' @@ -267,7 +270,10 @@ const ThreePaneLayout: React.FC = (props) => { isMobile={isMobile} /> -
+
{props.showSettings ? ( } /** - * Hook to detect scroll direction + * Hook to detect scroll direction on window or a specific element * @param options Configuration options * @param options.threshold Minimum scroll distance to trigger direction change (default: 10) * @param options.enabled Whether scroll detection is enabled (default: true) + * @param options.elementRef Optional ref to a scrollable element (uses window if not provided) * @returns Current scroll direction ('up', 'down', or 'none') */ export function useScrollDirection({ threshold = 10, - enabled = true + enabled = true, + elementRef }: UseScrollDirectionOptions = {}): ScrollDirection { const [scrollDirection, setScrollDirection] = useState('none') useEffect(() => { if (!enabled) return - let lastScrollY = window.scrollY + const scrollElement = elementRef?.current || window + const getScrollY = () => { + if (elementRef?.current) { + return elementRef.current.scrollTop + } + return window.scrollY + } + + let lastScrollY = getScrollY() let ticking = false const updateScrollDirection = () => { - const scrollY = window.scrollY + const scrollY = getScrollY() // Only update if scroll distance exceeds threshold if (Math.abs(scrollY - lastScrollY) < threshold) { @@ -47,12 +58,12 @@ export function useScrollDirection({ } } - window.addEventListener('scroll', onScroll) + scrollElement.addEventListener('scroll', onScroll) return () => { - window.removeEventListener('scroll', onScroll) + scrollElement.removeEventListener('scroll', onScroll) } - }, [threshold, enabled]) + }, [threshold, enabled, elementRef]) return scrollDirection }