From 0360364570a313eb62290969c8f1a30dcc302579 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Tue, 18 May 2021 16:55:11 +0300 Subject: [PATCH] fix(v2): do not focus on skip link if page refreshed (#4797) * fix(v2): do not focus on skip link if page refreshed * rename ref Co-authored-by: slorber --- .../src/theme/SkipToContent/index.tsx | 13 ++++++------ .../src/theme/hooks/useHideableNavbar.ts | 5 +++-- packages/docusaurus-theme-common/src/index.ts | 2 ++ .../src/utils/useChangeRoute.ts | 21 +++++++++++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 packages/docusaurus-theme-common/src/utils/useChangeRoute.ts diff --git a/packages/docusaurus-theme-classic/src/theme/SkipToContent/index.tsx b/packages/docusaurus-theme-classic/src/theme/SkipToContent/index.tsx index ae0b4833b5..2fc122a332 100644 --- a/packages/docusaurus-theme-classic/src/theme/SkipToContent/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/SkipToContent/index.tsx @@ -5,9 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useRef, useEffect} from 'react'; +import React, {useRef} from 'react'; import Translate from '@docusaurus/Translate'; -import {useLocation} from '@docusaurus/router'; +import {useChangeRoute} from '@docusaurus/theme-common'; + import styles from './styles.module.css'; function programmaticFocus(el: HTMLElement) { @@ -18,8 +19,6 @@ function programmaticFocus(el: HTMLElement) { function SkipToContent(): JSX.Element { const containerRef = useRef(null); - const location = useLocation(); - const handleSkip = (e: React.MouseEvent) => { e.preventDefault(); @@ -32,11 +31,11 @@ function SkipToContent(): JSX.Element { } }; - useEffect(() => { - if (!location.hash && containerRef.current) { + useChangeRoute(() => { + if (containerRef.current) { programmaticFocus(containerRef.current); } - }, [location.pathname]); + }); return (
diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts index 466bc4551e..ec840f7951 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts @@ -8,6 +8,7 @@ import {useState, useCallback, useEffect, useRef} from 'react'; import {useLocation} from '@docusaurus/router'; import useScrollPosition from '@theme/hooks/useScrollPosition'; +import {useChangeRoute} from '@docusaurus/theme-common'; import type {useHideableNavbarReturns} from '@theme/hooks/useHideableNavbar'; const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { @@ -55,13 +56,13 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { [navbarHeight, isFocusedAnchor], ); - useEffect(() => { + useChangeRoute(() => { if (!hideOnScroll) { return; } setIsNavbarVisible(true); - }, [location.pathname]); + }); useEffect(() => { if (!hideOnScroll) { diff --git a/packages/docusaurus-theme-common/src/index.ts b/packages/docusaurus-theme-common/src/index.ts index 99278499ca..4411fd5d0b 100644 --- a/packages/docusaurus-theme-common/src/index.ts +++ b/packages/docusaurus-theme-common/src/index.ts @@ -33,6 +33,8 @@ export {useTitleFormatter} from './utils/generalUtils'; export {usePluralForm} from './utils/usePluralForm'; +export {useChangeRoute} from './utils/useChangeRoute'; + export { useDocsPreferredVersion, useDocsPreferredVersionByPluginId, diff --git a/packages/docusaurus-theme-common/src/utils/useChangeRoute.ts b/packages/docusaurus-theme-common/src/utils/useChangeRoute.ts new file mode 100644 index 0000000000..97ac26c87d --- /dev/null +++ b/packages/docusaurus-theme-common/src/utils/useChangeRoute.ts @@ -0,0 +1,21 @@ +/** + * 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 {useRef, useEffect} from 'react'; +import {useLocation} from '@docusaurus/router'; + +export function useChangeRoute(onRouteChange: () => void): void { + const {pathname} = useLocation(); + const latestPathnameRef = useRef(pathname); + + useEffect(() => { + if (pathname !== latestPathnameRef.current) { + latestPathnameRef.current = pathname; + onRouteChange(); + } + }, [pathname, latestPathnameRef, onRouteChange]); +}