|
|
|
@ -5,7 +5,6 @@ import React, { |
|
|
|
|
useState, |
|
|
|
|
useRef, |
|
|
|
|
useEffect, |
|
|
|
|
useCallback, |
|
|
|
|
} from "react"; |
|
|
|
|
|
|
|
|
|
import styles from "./OrganizedContent.module.css"; |
|
|
|
@ -49,8 +48,6 @@ export function OrganizedContent({ |
|
|
|
|
const section = sections[currentIndex]; |
|
|
|
|
const isReadAll = section.id === READ_ALL_ID; |
|
|
|
|
const ref = useRef<HTMLDivElement>(null); |
|
|
|
|
const isVisible = useOnScreen(ref.current); |
|
|
|
|
const burgerVisible = useBurger(isVisible); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
mobileNavOpen |
|
|
|
@ -99,9 +96,7 @@ export function OrganizedContent({ |
|
|
|
|
)} |
|
|
|
|
</div> |
|
|
|
|
<button |
|
|
|
|
className={`${styles.burger} ${ |
|
|
|
|
burgerVisible ? styles.burgerVisible : "" |
|
|
|
|
}`}
|
|
|
|
|
className={styles.burger} |
|
|
|
|
onClick={() => setMobileNavOpen(!mobileNavOpen)} |
|
|
|
|
> |
|
|
|
|
<Burger /> |
|
|
|
@ -213,20 +208,6 @@ function Footer({ sections, currentIndex, link: Link }: FooterProps) { |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function useDebounce(func: () => void, delay = 300) { |
|
|
|
|
const timerRef = useRef<number | undefined>(undefined); |
|
|
|
|
return useCallback(() => { |
|
|
|
|
if (timerRef.current != null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
timerRef.current = window.setTimeout(() => { |
|
|
|
|
func(); |
|
|
|
|
timerRef.current = undefined; |
|
|
|
|
}, delay); |
|
|
|
|
}, [func, delay]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export interface SectionWithContent { |
|
|
|
|
section: Section; |
|
|
|
|
Content: ComponentType; |
|
|
|
@ -312,53 +293,6 @@ function Arrow({ direction }: { direction: "left" | "right" }) { |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function useOnScreen(element: HTMLDivElement | null) { |
|
|
|
|
const [isIntersecting, setIntersecting] = useState(false); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
const observer = new IntersectionObserver(([entry]) => |
|
|
|
|
setIntersecting(entry.isIntersecting) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (element) { |
|
|
|
|
observer.observe(element); |
|
|
|
|
} |
|
|
|
|
// Remove the observer as soon as the component is unmounted
|
|
|
|
|
return () => { |
|
|
|
|
observer.disconnect(); |
|
|
|
|
}; |
|
|
|
|
}, [element]); |
|
|
|
|
|
|
|
|
|
return isIntersecting; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function useBurger(componentIsVisible: boolean): boolean { |
|
|
|
|
const [prevScrollPos, setPrevScrollPos] = useState(0); |
|
|
|
|
const [burgerVisible, setBurgerVisible] = useState(true); |
|
|
|
|
|
|
|
|
|
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(() => { |
|
|
|
|
window.addEventListener("scroll", handleScroll); |
|
|
|
|
|
|
|
|
|
return () => window.removeEventListener("scroll", handleScroll); |
|
|
|
|
}, [handleScroll]); |
|
|
|
|
|
|
|
|
|
return burgerVisible; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Inlining this svg because we want to fill in colors using css variables
|
|
|
|
|
function Burger() { |
|
|
|
|
return ( |
|
|
|
|