Skip to content

Commit cb69b40

Browse files
authored
fix(theme): mobile drawer history blocker should be rendered conditionally (workaround) (#10989)
Add history blocker workaround
1 parent 7cf94c0 commit cb69b40

File tree

3 files changed

+67
-13
lines changed

3 files changed

+67
-13
lines changed

packages/docusaurus-theme-common/src/contexts/navbarMobileSidebar.tsx

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,6 @@ function useContextValue(): ContextValue {
5353

5454
const [shown, setShown] = useState(false);
5555

56-
// Close mobile sidebar on navigation pop
57-
// Most likely firing when using the Android back button (but not only)
58-
useHistoryPopHandler(() => {
59-
if (shown) {
60-
setShown(false);
61-
// Prevent pop navigation; seems desirable enough
62-
// See https://github.com/facebook/docusaurus/pull/5462#issuecomment-911699846
63-
return false;
64-
}
65-
return undefined;
66-
});
67-
6856
const toggle = useCallback(() => {
6957
setShown((s) => !s);
7058
}, []);
@@ -81,13 +69,45 @@ function useContextValue(): ContextValue {
8169
);
8270
}
8371

72+
// A component hook wrapper enables conditional rendering
73+
// See reason here: https://github.com/facebook/docusaurus/issues/10988
74+
function OnHistoryPop({
75+
handler,
76+
}: {
77+
handler: Parameters<typeof useHistoryPopHandler>[0];
78+
}) {
79+
useHistoryPopHandler(handler);
80+
return null;
81+
}
82+
8483
export function NavbarMobileSidebarProvider({
8584
children,
8685
}: {
8786
children: ReactNode;
8887
}): ReactNode {
8988
const value = useContextValue();
90-
return <Context.Provider value={value}>{children}</Context.Provider>;
89+
return (
90+
<>
91+
{
92+
// Close mobile sidebar on navigation pop
93+
// Most likely firing when using the Android back button (but not only)
94+
// Important: we can only have a single history blocker at a time
95+
// That's why this needs to be rendered conditionally
96+
// See bug report https://github.com/facebook/docusaurus/issues/10988
97+
value.shown && (
98+
<OnHistoryPop
99+
handler={() => {
100+
value.toggle();
101+
// Prevent pop navigation; seems desirable enough
102+
// See https://github.com/facebook/docusaurus/pull/5462#issuecomment-911699846
103+
return false;
104+
}}
105+
/>
106+
)
107+
}
108+
<Context.Provider value={value}>{children}</Context.Provider>
109+
</>
110+
);
91111
}
92112

93113
export function useNavbarMobileSidebar(): ContextValue {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
import {useEffect, type ReactNode} from 'react';
8+
import {useHistory} from '@docusaurus/router';
9+
import Layout from '@theme/Layout';
10+
import Heading from '@theme/Heading';
11+
12+
// Test for https://github.com/facebook/docusaurus/issues/10988
13+
function BlockNavigation() {
14+
const history = useHistory();
15+
useEffect(() => {
16+
return history.block(() => {
17+
// eslint-disable-next-line no-alert
18+
alert('navigation blocked successfully');
19+
return false;
20+
});
21+
}, [history]);
22+
return false;
23+
}
24+
25+
export default function HistoryTestsPage(): ReactNode {
26+
return (
27+
<Layout>
28+
<Heading as="h1">History tests</Heading>
29+
<p>This page should block navigation</p>
30+
<BlockNavigation />
31+
</Layout>
32+
);
33+
}

website/_dogfooding/_pages tests/index.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ import Readme from "../README.mdx"
3939
- [Head metadata tests](/tests/pages/head-metadata)
4040
- [Unlisted page](/tests/pages/unlisted)
4141
- [Analytics](/tests/pages/analytics)
42+
- [History tests](/tests/pages/history-tests)
4243
- [Embeds](/tests/pages/embeds)

0 commit comments

Comments
 (0)