|
|
|
@ -4,6 +4,7 @@ import React, { |
|
|
|
|
useState, |
|
|
|
|
useRef, |
|
|
|
|
useEffect, |
|
|
|
|
useCallback, |
|
|
|
|
} from "react"; |
|
|
|
|
import styles from "./OrganizedContent.module.css"; |
|
|
|
|
|
|
|
|
@ -194,27 +195,26 @@ interface BurgerProps { |
|
|
|
|
const Burger = ({ open, setOpen, componentIsVisible }: BurgerProps) => { |
|
|
|
|
const [prevScrollPos, setPrevScrollPos] = useState(0); |
|
|
|
|
const [burgerVisible, setBurgerVisible] = useState(true); |
|
|
|
|
const debouncedPrevScrollPos = useDebounce<number>(prevScrollPos, 100); |
|
|
|
|
|
|
|
|
|
const handleScroll = useDebounce(() => { |
|
|
|
|
// find current scroll position
|
|
|
|
|
const currentScrollPos = window.pageYOffset; |
|
|
|
|
setBurgerVisible( |
|
|
|
|
componentIsVisible && |
|
|
|
|
((prevScrollPos > currentScrollPos && |
|
|
|
|
prevScrollPos - currentScrollPos > 70) || |
|
|
|
|
currentScrollPos < 10) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// set state to new scroll position
|
|
|
|
|
setPrevScrollPos(currentScrollPos); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
const handleScroll = () => { |
|
|
|
|
// find current scroll position
|
|
|
|
|
const currentScrollPos = window.pageYOffset; |
|
|
|
|
// set state based on location info (explained in more detail below)
|
|
|
|
|
setBurgerVisible( |
|
|
|
|
componentIsVisible && |
|
|
|
|
((debouncedPrevScrollPos > currentScrollPos && |
|
|
|
|
debouncedPrevScrollPos - currentScrollPos > 70) || |
|
|
|
|
currentScrollPos < 10) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// set state to new scroll position
|
|
|
|
|
setPrevScrollPos(currentScrollPos); |
|
|
|
|
}; |
|
|
|
|
window.addEventListener("scroll", handleScroll); |
|
|
|
|
|
|
|
|
|
return () => window.removeEventListener("scroll", handleScroll); |
|
|
|
|
}, [componentIsVisible, debouncedPrevScrollPos, burgerVisible]); |
|
|
|
|
}, [handleScroll]); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div |
|
|
|
@ -274,18 +274,18 @@ function useOutsideAlerter( |
|
|
|
|
}, [ref, setOpen]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function useDebounce<T>(value: T, delay?: number): T { |
|
|
|
|
const [debouncedValue, setDebouncedValue] = useState<T>(value); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
const timer = setTimeout(() => setDebouncedValue(value), delay || 500); |
|
|
|
|
|
|
|
|
|
return () => { |
|
|
|
|
clearTimeout(timer); |
|
|
|
|
}; |
|
|
|
|
}, [value, delay]); |
|
|
|
|
function useDebounce(func: () => void, delay = 300) { |
|
|
|
|
const timerRef = useRef<number | undefined>(undefined); |
|
|
|
|
return useCallback(() => { |
|
|
|
|
if (timerRef.current != null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return debouncedValue; |
|
|
|
|
timerRef.current = window.setTimeout(() => { |
|
|
|
|
func(); |
|
|
|
|
timerRef.current = undefined; |
|
|
|
|
}, delay); |
|
|
|
|
}, [func, delay]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function createSections(sections: Section[]) { |
|
|
|
|