Files
documentation/node_modules/@docusaurus/theme-common/lib/hooks/useHideableNavbar.js
2024-03-22 03:47:51 +05:30

65 lines
2.4 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, useRef } from 'react';
import { useLocationChange } from '../utils/useLocationChange';
import { useScrollPosition } from '../utils/scrollUtils';
/**
* Wires the imperative logic of a hideable navbar.
* @param hideOnScroll If `false`, this hook is basically a no-op.
*/
export function useHideableNavbar(hideOnScroll) {
const [isNavbarVisible, setIsNavbarVisible] = useState(hideOnScroll);
const isFocusedAnchor = useRef(false);
const navbarHeight = useRef(0);
const navbarRef = useCallback((node) => {
if (node !== null) {
navbarHeight.current = node.getBoundingClientRect().height;
}
}, []);
useScrollPosition(({ scrollY: scrollTop }, lastPosition) => {
if (!hideOnScroll) {
return;
}
// Needed mostly for handling rubber band scrolling.
// See https://github.com/facebook/docusaurus/pull/5721
if (scrollTop < navbarHeight.current) {
setIsNavbarVisible(true);
return;
}
if (isFocusedAnchor.current) {
isFocusedAnchor.current = false;
return;
}
const lastScrollTop = lastPosition?.scrollY;
const documentHeight = document.documentElement.scrollHeight - navbarHeight.current;
const windowHeight = window.innerHeight;
if (lastScrollTop && scrollTop >= lastScrollTop) {
setIsNavbarVisible(false);
}
else if (scrollTop + windowHeight < documentHeight) {
setIsNavbarVisible(true);
}
});
useLocationChange((locationChangeEvent) => {
if (!hideOnScroll) {
return;
}
// See https://github.com/facebook/docusaurus/pull/8059#issuecomment-1239639480
const currentHash = locationChangeEvent.location.hash;
const currentHashAnchor = currentHash
? document.getElementById(currentHash.substring(1))
: undefined;
if (currentHashAnchor) {
isFocusedAnchor.current = true;
setIsNavbarVisible(false);
return;
}
setIsNavbarVisible(true);
});
return { navbarRef, isNavbarVisible };
}
//# sourceMappingURL=useHideableNavbar.js.map