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.
This commit is contained in:
Gigi
2025-10-11 01:48:45 +01:00
parent ffe848883e
commit 3a8203d26e
2 changed files with 27 additions and 10 deletions

View File

@@ -87,11 +87,14 @@ const ThreePaneLayout: React.FC<ThreePaneLayoutProps> = (props) => {
const isMobile = useIsMobile()
const sidebarRef = useRef<HTMLDivElement>(null)
const highlightsRef = useRef<HTMLDivElement>(null)
const mainPaneRef = useRef<HTMLDivElement>(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<ThreePaneLayoutProps> = (props) => {
isMobile={isMobile}
/>
</div>
<div className={`pane main ${isMobile && (props.isSidebarOpen || !props.isHighlightsCollapsed) ? 'mobile-hidden' : ''}`}>
<div
ref={mainPaneRef}
className={`pane main ${isMobile && (props.isSidebarOpen || !props.isHighlightsCollapsed) ? 'mobile-hidden' : ''}`}
>
{props.showSettings ? (
<Settings
settings={props.settings}

View File

@@ -1,33 +1,44 @@
import { useState, useEffect } from 'react'
import { useState, useEffect, RefObject } from 'react'
export type ScrollDirection = 'up' | 'down' | 'none'
interface UseScrollDirectionOptions {
threshold?: number
enabled?: boolean
elementRef?: RefObject<HTMLElement>
}
/**
* 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<ScrollDirection>('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
}