mirror of
https://github.com/dergigi/boris.git
synced 2025-12-30 13:04:57 +01:00
- 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.
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
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 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,
|
|
elementRef
|
|
}: UseScrollDirectionOptions = {}): ScrollDirection {
|
|
const [scrollDirection, setScrollDirection] = useState<ScrollDirection>('none')
|
|
|
|
useEffect(() => {
|
|
if (!enabled) return
|
|
|
|
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 = getScrollY()
|
|
|
|
// Only update if scroll distance exceeds threshold
|
|
if (Math.abs(scrollY - lastScrollY) < threshold) {
|
|
ticking = false
|
|
return
|
|
}
|
|
|
|
setScrollDirection(scrollY > lastScrollY ? 'down' : 'up')
|
|
lastScrollY = scrollY > 0 ? scrollY : 0
|
|
ticking = false
|
|
}
|
|
|
|
const onScroll = () => {
|
|
if (!ticking) {
|
|
window.requestAnimationFrame(updateScrollDirection)
|
|
ticking = true
|
|
}
|
|
}
|
|
|
|
scrollElement.addEventListener('scroll', onScroll)
|
|
|
|
return () => {
|
|
scrollElement.removeEventListener('scroll', onScroll)
|
|
}
|
|
}, [threshold, enabled, elementRef])
|
|
|
|
return scrollDirection
|
|
}
|
|
|