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");
|
: (document.body.style.overflow = "visible");
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const isVisible = useOnScreen(ref);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.wrapper} ref={ref}>
|
||||||
<Nav sections={sections} currentIndex={currentIndex} link={props.link} />
|
<Nav sections={sections} currentIndex={currentIndex} link={props.link} />
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
{isReadAll ? (
|
{isReadAll ? (
|
||||||
|
@ -76,6 +79,7 @@ export function OrganizedContent(props: Props) {
|
||||||
currentIndex={currentIndex}
|
currentIndex={currentIndex}
|
||||||
link={props.link}
|
link={props.link}
|
||||||
pageTitle={props.pageTitle}
|
pageTitle={props.pageTitle}
|
||||||
|
componentIsVisible={isVisible}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -166,6 +170,7 @@ interface MobileProps {
|
||||||
currentIndex: number;
|
currentIndex: number;
|
||||||
link: Link;
|
link: Link;
|
||||||
pageTitle: string;
|
pageTitle: string;
|
||||||
|
componentIsVisible: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function MobileWrapper(mobileProps: MobileProps) {
|
function MobileWrapper(mobileProps: MobileProps) {
|
||||||
|
@ -174,7 +179,7 @@ function MobileWrapper(mobileProps: MobileProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={wrapperRef}>
|
<div ref={wrapperRef}>
|
||||||
<Burger open={mobileProps.open} setOpen={mobileProps.setOpen} />
|
<Burger {...mobileProps} />
|
||||||
<Menu {...mobileProps} />
|
<Menu {...mobileProps} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -183,23 +188,24 @@ function MobileWrapper(mobileProps: MobileProps) {
|
||||||
interface BurgerProps {
|
interface BurgerProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
setOpen: React.Dispatch<React.SetStateAction<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 [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||||
const [visible, setVisible] = useState(true);
|
const [burgerVisible, setBurgerVisible] = useState(true);
|
||||||
const debouncedPrevScrollPos = useDebounce<number>(prevScrollPos, 100);
|
const debouncedPrevScrollPos = useDebounce<number>(prevScrollPos, 100);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
// find current scroll position
|
// find current scroll position
|
||||||
const currentScrollPos = window.pageYOffset;
|
const currentScrollPos = window.pageYOffset;
|
||||||
|
|
||||||
// set state based on location info (explained in more detail below)
|
// set state based on location info (explained in more detail below)
|
||||||
setVisible(
|
setBurgerVisible(
|
||||||
(debouncedPrevScrollPos > currentScrollPos &&
|
componentIsVisible &&
|
||||||
debouncedPrevScrollPos - currentScrollPos > 70) ||
|
((debouncedPrevScrollPos > currentScrollPos &&
|
||||||
currentScrollPos < 10
|
debouncedPrevScrollPos - currentScrollPos > 70) ||
|
||||||
|
currentScrollPos < 10)
|
||||||
);
|
);
|
||||||
|
|
||||||
// set state to new scroll position
|
// set state to new scroll position
|
||||||
|
@ -208,11 +214,13 @@ const Burger = ({ open, setOpen }: BurgerProps) => {
|
||||||
window.addEventListener("scroll", handleScroll);
|
window.addEventListener("scroll", handleScroll);
|
||||||
|
|
||||||
return () => window.removeEventListener("scroll", handleScroll);
|
return () => window.removeEventListener("scroll", handleScroll);
|
||||||
}, [debouncedPrevScrollPos, visible]);
|
}, [componentIsVisible, debouncedPrevScrollPos, burgerVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.burger + " " + (visible ? "" : styles.hiddenBurger)}
|
className={
|
||||||
|
styles.burger + " " + (burgerVisible ? "" : styles.hiddenBurger)
|
||||||
|
}
|
||||||
onClick={() => setOpen(!open)}
|
onClick={() => setOpen(!open)}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
@ -317,3 +325,23 @@ function Arrow({ direction }: { direction: "left" | "right" }) {
|
||||||
</svg>
|
</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