mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-29 17:07:08 +02:00
94 lines
2.2 KiB
JavaScript
94 lines
2.2 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import {useState, useCallback, useEffect} from 'react';
|
|
import {useLocation} from '@docusaurus/router';
|
|
import useLocationHash from '@theme/hooks/useLocationHash';
|
|
|
|
const useHideableNavbar = hideOnScroll => {
|
|
const [isNavbarVisible, setIsNavbarVisible] = useState(true);
|
|
const [isFocusedAnchor, setIsFocusedAnchor] = useState(false);
|
|
const [lastScrollTop, setLastScrollTop] = useState(0);
|
|
const [navbarHeight, setNavbarHeight] = useState(0);
|
|
const navbarRef = useCallback(node => {
|
|
if (node !== null) {
|
|
setNavbarHeight(node.getBoundingClientRect().height);
|
|
}
|
|
}, []);
|
|
const location = useLocation();
|
|
const [hash, setHash] = useLocationHash(location.hash);
|
|
|
|
const handleScroll = () => {
|
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
|
|
if (scrollTop === 0) {
|
|
setIsNavbarVisible(true);
|
|
}
|
|
|
|
if (scrollTop < navbarHeight) {
|
|
return;
|
|
}
|
|
|
|
if (isFocusedAnchor) {
|
|
setIsFocusedAnchor(false);
|
|
setIsNavbarVisible(false);
|
|
setLastScrollTop(scrollTop);
|
|
return;
|
|
}
|
|
|
|
const documentHeight = document.documentElement.scrollHeight - navbarHeight;
|
|
const windowHeight = window.innerHeight;
|
|
|
|
if (lastScrollTop && scrollTop >= lastScrollTop) {
|
|
setIsNavbarVisible(false);
|
|
} else if (scrollTop + windowHeight < documentHeight) {
|
|
setIsNavbarVisible(true);
|
|
}
|
|
|
|
setLastScrollTop(scrollTop);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!hideOnScroll) {
|
|
return undefined;
|
|
}
|
|
|
|
window.addEventListener('scroll', handleScroll);
|
|
|
|
return () => {
|
|
window.removeEventListener('scroll', handleScroll);
|
|
};
|
|
}, [lastScrollTop, navbarHeight]);
|
|
|
|
useEffect(() => {
|
|
if (!hideOnScroll) {
|
|
return;
|
|
}
|
|
|
|
setIsNavbarVisible(true);
|
|
setHash(location.hash);
|
|
}, [location]);
|
|
|
|
useEffect(() => {
|
|
if (!hideOnScroll) {
|
|
return;
|
|
}
|
|
|
|
if (!hash) {
|
|
return;
|
|
}
|
|
|
|
setIsFocusedAnchor(true);
|
|
}, [hash]);
|
|
|
|
return {
|
|
navbarRef,
|
|
isNavbarVisible,
|
|
};
|
|
};
|
|
|
|
export default useHideableNavbar;
|