feat(SW-1960): Improved scrolling and tabnavigation on hotel pages
Approved-by: Matilda Landström
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
||||
|
||||
import { debounce } from "../utils/debounce"
|
||||
|
||||
export default function useScrollSpy(
|
||||
sectionIds: string[],
|
||||
options: IntersectionObserverInit = {}
|
||||
@@ -9,6 +11,7 @@ export default function useScrollSpy(
|
||||
} {
|
||||
const [activeSectionId, setActiveSectionId] = useState("")
|
||||
const observerIsInactive = useRef(false)
|
||||
const safetyTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
const mergedOptions = useMemo(
|
||||
() => ({
|
||||
@@ -42,6 +45,22 @@ export default function useScrollSpy(
|
||||
[]
|
||||
)
|
||||
|
||||
// Scroll event listener to reset the observerIsInactive state
|
||||
// This is to support the pauseScrollSpy function to prevent the observer from firing when scrolling.
|
||||
useEffect(() => {
|
||||
const handleScroll = debounce(() => {
|
||||
if (observerIsInactive.current) {
|
||||
observerIsInactive.current = false
|
||||
}
|
||||
}, 200)
|
||||
|
||||
window.addEventListener("scroll", handleScroll, { passive: true })
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("scroll", handleScroll)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(handleIntersection, mergedOptions)
|
||||
const elements = sectionIds
|
||||
@@ -55,12 +74,18 @@ export default function useScrollSpy(
|
||||
return () => elements.forEach((el) => el && observer.unobserve(el))
|
||||
}, [sectionIds, mergedOptions, handleIntersection])
|
||||
|
||||
const pauseScrollSpy = () => {
|
||||
function pauseScrollSpy() {
|
||||
observerIsInactive.current = true
|
||||
|
||||
setTimeout(() => {
|
||||
if (safetyTimeoutRef.current) {
|
||||
clearTimeout(safetyTimeoutRef.current)
|
||||
}
|
||||
|
||||
// Safety timeout - maximum time to wait before re-enabling
|
||||
safetyTimeoutRef.current = setTimeout(() => {
|
||||
observerIsInactive.current = false
|
||||
}, 500)
|
||||
safetyTimeoutRef.current = null
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
return { activeSectionId, pauseScrollSpy }
|
||||
|
||||
Reference in New Issue
Block a user