Make burger disappear when off screen
This commit is contained in:
parent
5a3fdb9005
commit
db88a7699c
|
@ -49,8 +49,11 @@ export function OrganizedContent(props: Props) {
|
|||
: (document.body.style.overflow = "visible");
|
||||
}, [open]);
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const isVisible = useOnScreen(ref);
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.wrapper} ref={ref}>
|
||||
<Nav sections={sections} currentIndex={currentIndex} link={props.link} />
|
||||
<div className={styles.content}>
|
||||
{isReadAll ? (
|
||||
|
@ -76,6 +79,7 @@ export function OrganizedContent(props: Props) {
|
|||
currentIndex={currentIndex}
|
||||
link={props.link}
|
||||
pageTitle={props.pageTitle}
|
||||
componentIsVisible={isVisible}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -166,6 +170,7 @@ interface MobileProps {
|
|||
currentIndex: number;
|
||||
link: Link;
|
||||
pageTitle: string;
|
||||
componentIsVisible: boolean;
|
||||
}
|
||||
|
||||
function MobileWrapper(mobileProps: MobileProps) {
|
||||
|
@ -174,7 +179,7 @@ function MobileWrapper(mobileProps: MobileProps) {
|
|||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<Burger open={mobileProps.open} setOpen={mobileProps.setOpen} />
|
||||
<Burger {...mobileProps} />
|
||||
<Menu {...mobileProps} />
|
||||
</div>
|
||||
);
|
||||
|
@ -183,23 +188,24 @@ function MobileWrapper(mobileProps: MobileProps) {
|
|||
interface BurgerProps {
|
||||
open: boolean;
|
||||
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
componentIsVisible: boolean;
|
||||
}
|
||||
|
||||
const Burger = ({ open, setOpen }: BurgerProps) => {
|
||||
const Burger = ({ open, setOpen, componentIsVisible }: BurgerProps) => {
|
||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||
const [visible, setVisible] = useState(true);
|
||||
const [burgerVisible, setBurgerVisible] = useState(true);
|
||||
const debouncedPrevScrollPos = useDebounce<number>(prevScrollPos, 100);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
// find current scroll position
|
||||
const currentScrollPos = window.pageYOffset;
|
||||
|
||||
// set state based on location info (explained in more detail below)
|
||||
setVisible(
|
||||
(debouncedPrevScrollPos > currentScrollPos &&
|
||||
debouncedPrevScrollPos - currentScrollPos > 70) ||
|
||||
currentScrollPos < 10
|
||||
setBurgerVisible(
|
||||
componentIsVisible &&
|
||||
((debouncedPrevScrollPos > currentScrollPos &&
|
||||
debouncedPrevScrollPos - currentScrollPos > 70) ||
|
||||
currentScrollPos < 10)
|
||||
);
|
||||
|
||||
// set state to new scroll position
|
||||
|
@ -208,11 +214,13 @@ const Burger = ({ open, setOpen }: BurgerProps) => {
|
|||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, [debouncedPrevScrollPos, visible]);
|
||||
}, [componentIsVisible, debouncedPrevScrollPos, burgerVisible]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.burger + " " + (visible ? "" : styles.hiddenBurger)}
|
||||
className={
|
||||
styles.burger + " " + (burgerVisible ? "" : styles.hiddenBurger)
|
||||
}
|
||||
onClick={() => setOpen(!open)}
|
||||
>
|
||||
<div>
|
||||
|
@ -317,3 +325,23 @@ function Arrow({ direction }: { direction: "left" | "right" }) {
|
|||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function useOnScreen(ref: React.RefObject<HTMLDivElement>) {
|
||||
const [isIntersecting, setIntersecting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(([entry]) =>
|
||||
setIntersecting(entry.isIntersecting)
|
||||
);
|
||||
|
||||
if (ref.current) {
|
||||
observer.observe(ref.current);
|
||||
}
|
||||
// Remove the observer as soon as the component is unmounted
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [ref]);
|
||||
|
||||
return isIntersecting;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue