diff --git a/packages/docusaurus-theme-common/src/contexts/navbarMobileSidebar.tsx b/packages/docusaurus-theme-common/src/contexts/navbarMobileSidebar.tsx index 6ed86329b6..36c55b41e7 100644 --- a/packages/docusaurus-theme-common/src/contexts/navbarMobileSidebar.tsx +++ b/packages/docusaurus-theme-common/src/contexts/navbarMobileSidebar.tsx @@ -53,18 +53,6 @@ function useContextValue(): ContextValue { const [shown, setShown] = useState(false); - // Close mobile sidebar on navigation pop - // Most likely firing when using the Android back button (but not only) - useHistoryPopHandler(() => { - if (shown) { - setShown(false); - // Prevent pop navigation; seems desirable enough - // See https://github.com/facebook/docusaurus/pull/5462#issuecomment-911699846 - return false; - } - return undefined; - }); - const toggle = useCallback(() => { setShown((s) => !s); }, []); @@ -81,13 +69,45 @@ function useContextValue(): ContextValue { ); } +// A component hook wrapper enables conditional rendering +// See reason here: https://github.com/facebook/docusaurus/issues/10988 +function OnHistoryPop({ + handler, +}: { + handler: Parameters[0]; +}) { + useHistoryPopHandler(handler); + return null; +} + export function NavbarMobileSidebarProvider({ children, }: { children: ReactNode; }): ReactNode { const value = useContextValue(); - return {children}; + return ( + <> + { + // Close mobile sidebar on navigation pop + // Most likely firing when using the Android back button (but not only) + // Important: we can only have a single history blocker at a time + // That's why this needs to be rendered conditionally + // See bug report https://github.com/facebook/docusaurus/issues/10988 + value.shown && ( + { + value.toggle(); + // Prevent pop navigation; seems desirable enough + // See https://github.com/facebook/docusaurus/pull/5462#issuecomment-911699846 + return false; + }} + /> + ) + } + {children} + + ); } export function useNavbarMobileSidebar(): ContextValue { diff --git a/website/_dogfooding/_pages tests/history-tests.tsx b/website/_dogfooding/_pages tests/history-tests.tsx new file mode 100644 index 0000000000..77e8a56a80 --- /dev/null +++ b/website/_dogfooding/_pages tests/history-tests.tsx @@ -0,0 +1,33 @@ +/** + * 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 {useEffect, type ReactNode} from 'react'; +import {useHistory} from '@docusaurus/router'; +import Layout from '@theme/Layout'; +import Heading from '@theme/Heading'; + +// Test for https://github.com/facebook/docusaurus/issues/10988 +function BlockNavigation() { + const history = useHistory(); + useEffect(() => { + return history.block(() => { + // eslint-disable-next-line no-alert + alert('navigation blocked successfully'); + return false; + }); + }, [history]); + return false; +} + +export default function HistoryTestsPage(): ReactNode { + return ( + + History tests +

This page should block navigation

+ +
+ ); +} diff --git a/website/_dogfooding/_pages tests/index.mdx b/website/_dogfooding/_pages tests/index.mdx index d862394e29..6ed5de6daf 100644 --- a/website/_dogfooding/_pages tests/index.mdx +++ b/website/_dogfooding/_pages tests/index.mdx @@ -39,4 +39,5 @@ import Readme from "../README.mdx" - [Head metadata tests](/tests/pages/head-metadata) - [Unlisted page](/tests/pages/unlisted) - [Analytics](/tests/pages/analytics) +- [History tests](/tests/pages/history-tests) - [Embeds](/tests/pages/embeds)