From 61fd53f7c0b9cd7ba32a92470d518d781ae435aa Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Wed, 18 Nov 2020 18:17:04 +0300 Subject: [PATCH] fix(v2): increase stability of hideable navbar (#3733) * fix * fix(v2): increase stability of hideable navbar * Fix bug after reload * Remove state for hash --- .../src/theme/hooks/useHideableNavbar.ts | 40 +++++++++---------- .../src/theme/hooks/useScrollPosition.ts | 12 +++--- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts index fa5d081dcf..067873f4e4 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts @@ -5,15 +5,15 @@ * LICENSE file in the root directory of this source tree. */ -import {useState, useCallback, useEffect} from 'react'; +import {useState, useCallback, useEffect, useRef} from 'react'; import {useLocation} from '@docusaurus/router'; -import useLocationHash from '@theme/hooks/useLocationHash'; import useScrollPosition from '@theme/hooks/useScrollPosition'; import type {useHideableNavbarReturns} from '@theme/hooks/useHideableNavbar'; const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { - const [isNavbarVisible, setIsNavbarVisible] = useState(true); - const [isFocusedAnchor, setIsFocusedAnchor] = useState(false); + const location = useLocation(); + const [isNavbarVisible, setIsNavbarVisible] = useState(!hideOnScroll); + const isFocusedAnchor = useRef(false); const [lastScrollTop, setLastScrollTop] = useState(0); const [navbarHeight, setNavbarHeight] = useState(0); const navbarRef = useCallback((node: HTMLElement | null) => { @@ -21,8 +21,6 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { setNavbarHeight(node.getBoundingClientRect().height); } }, []); - const location = useLocation(); - const [hash, setHash] = useLocationHash(location.hash); useScrollPosition( ({scrollY: scrollTop}) => { @@ -30,21 +28,21 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { return; } - if (scrollTop === 0) { - setIsNavbarVisible(true); - } - if (scrollTop < navbarHeight) { return; } - if (isFocusedAnchor) { - setIsFocusedAnchor(false); + if (isFocusedAnchor.current) { + isFocusedAnchor.current = false; setIsNavbarVisible(false); setLastScrollTop(scrollTop); return; } + if (lastScrollTop && scrollTop === 0) { + setIsNavbarVisible(true); + } + const documentHeight = document.documentElement.scrollHeight - navbarHeight; const windowHeight = window.innerHeight; @@ -57,7 +55,7 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { setLastScrollTop(scrollTop); }, - [lastScrollTop, navbarHeight], + [lastScrollTop, navbarHeight, isFocusedAnchor], ); useEffect(() => { @@ -65,22 +63,20 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { return; } + if (!lastScrollTop) { + return; + } + setIsNavbarVisible(true); - setHash(location.hash); - }, [location]); + }, [location.pathname]); useEffect(() => { if (!hideOnScroll) { return; } - if (!hash) { - return; - } - - setIsFocusedAnchor(true); - setIsNavbarVisible(false); - }, [hash]); + isFocusedAnchor.current = true; + }, [location.hash]); return { navbarRef, diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts index e56fc85539..f4b6cd0046 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts @@ -31,13 +31,13 @@ const useScrollPosition = ( }; useEffect(() => { - window.addEventListener('scroll', handleScroll); + const opts: AddEventListenerOptions & EventListenerOptions = { + passive: true, + }; - return () => - window.removeEventListener('scroll', handleScroll, { - // @ts-expect-error: See https://github.com/microsoft/TypeScript/issues/32912 - passive: true, - }); + window.addEventListener('scroll', handleScroll, opts); + + return () => window.removeEventListener('scroll', handleScroll, opts); }, deps); return scrollPosition;