Skip to content

Commit f3cca29

Browse files
authored
Merge pull request #198 from mauris/fix/store-menu-problem
2 parents 6ff1bc2 + 30f4d88 commit f3cca29

File tree

5 files changed

+60
-47
lines changed

5 files changed

+60
-47
lines changed

packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@ const ApiSchema: React.FC<Props> = ({
1616
...rest
1717
}: Props): JSX.Element => {
1818
const specProps = useSpecData(id);
19-
const { store, darkStore, lightStore } = useSpec(specProps);
19+
const { store } = useSpec(specProps);
2020

2121
useEffect(() => {
2222
/**
2323
* @see https://github.com/Redocly/redoc/blob/823be24b313c3a2445df7e0801a0cc79c20bacd1/src/services/MenuStore.ts#L273-L276
2424
*/
25-
lightStore.menu.dispose();
26-
darkStore.menu.dispose();
27-
}, [lightStore, darkStore]);
25+
store.menu.dispose();
26+
}, [store]);
2827

2928
return (
3029
<ThemeProvider theme={store.options.theme}>

packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,18 @@ function Redoc(
2020
},
2121
): JSX.Element {
2222
const { className, optionsOverrides, ...specProps } = props;
23-
const { store, darkStore, lightStore, hasLogo } = useSpec(
23+
const { store, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec(
2424
specProps,
2525
optionsOverrides,
2626
);
2727

2828
return (
2929
<>
30-
<ServerStyles lightStore={lightStore} darkStore={darkStore} />
30+
<ServerStyles
31+
specProps={specProps}
32+
lightThemeOptions={lightThemeOptions}
33+
darkThemeOptions={darkThemeOptions}
34+
/>
3135
<div
3236
className={clsx([
3337
'redocusaurus',

packages/docusaurus-theme-redoc/src/theme/Redoc/ServerStyles.tsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import '../../global';
3-
import { AppStore, Redoc } from 'redoc';
3+
import useBaseUrl from '@docusaurus/useBaseUrl';
4+
import { AppStore, Redoc, RedocRawOptions } from 'redoc';
45
// eslint-disable-next-line import/no-extraneous-dependencies
56
import { renderToString } from 'react-dom/server';
67
import { ServerStyleSheet } from 'styled-components';
@@ -53,17 +54,21 @@ const LIGHT_MODE_PREFIX = "html:not([data-theme='dark'])";
5354
const DARK_MODE_PREFIX = "html([data-theme='dark'])";
5455

5556
export function ServerStyles({
56-
lightStore,
57-
darkStore,
57+
specProps,
58+
lightThemeOptions,
59+
darkThemeOptions,
5860
}: {
59-
lightStore: AppStore;
60-
darkStore: AppStore;
61+
specProps: SpecProps,
62+
lightThemeOptions: RedocRawOptions,
63+
darkThemeOptions: RedocRawOptions,
6164
}) {
65+
const fullUrl = useBaseUrl(specProps.url, { absolute: true });
6266
const css = {
6367
light: '',
6468
dark: '',
6569
};
6670
const lightSheet = new ServerStyleSheet();
71+
const lightStore = new AppStore(specProps.spec, fullUrl, lightThemeOptions);
6772
renderToString(
6873
lightSheet.collectStyles(React.createElement(Redoc, { store: lightStore })),
6974
);
@@ -73,6 +78,7 @@ export function ServerStyles({
7378
css.light = prefixCssSelectors(lightCss, LIGHT_MODE_PREFIX);
7479

7580
const darkSheet = new ServerStyleSheet();
81+
const darkStore = new AppStore(specProps.spec, fullUrl, darkThemeOptions);
7682
renderToString(
7783
darkSheet.collectStyles(React.createElement(Redoc, { store: darkStore })),
7884
);
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import React from 'react';
22
import '../../global';
3-
import type { AppStore } from 'redoc';
3+
import type { RedocRawOptions } from 'redoc';
44

55
/**
66
* Don't hydrate/replace server styles
77
* @see https://github.com/facebook/react/issues/10923#issuecomment-338715787
88
*/
99
export function ServerStyles(_props: {
10-
lightStore: AppStore;
11-
darkStore: AppStore;
10+
specProps: SpecProps;
11+
lightThemeOptions: RedocRawOptions;
12+
darkThemeOptions: RedocRawOptions;
1213
}) {
1314
return <div className="redocusaurus-styles"></div>;
1415
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from 'react';
1+
import { useMemo, useEffect } from 'react';
22
import useBaseUrl from '@docusaurus/useBaseUrl';
33
import useIsBrowser from '@docusaurus/useIsBrowser';
44
import { usePluginData } from '@docusaurus/useGlobalData';
@@ -9,6 +9,9 @@ import { AppStore, RedocRawOptions } from 'redoc';
99
import { SpecProps } from '../types/common';
1010
import { GlobalData } from '../types/options';
1111

12+
// the current store singleton in the app's instance
13+
let currentStore: AppStore | null = null;
14+
1215
/**
1316
* Redocusaurus
1417
* https://rohit-gohri.github.io/redocusaurus/
@@ -27,7 +30,7 @@ export function useSpec(
2730
themeId,
2831
) as GlobalData;
2932

30-
const stores = useMemo(() => {
33+
const result = useMemo(() => {
3134
const { lightTheme, darkTheme, options: redocOptions } = themeOptions;
3235

3336
const commonOptions: Partial<RedocRawOptions> = {
@@ -38,48 +41,48 @@ export function useSpec(
3841
: redocOptions.scrollYOffset,
3942
};
4043

41-
const lightStore = new AppStore(
42-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
43-
spec as any,
44-
fullUrl,
45-
merge(
46-
{
47-
...redocOptions,
48-
...commonOptions,
49-
theme: lightTheme,
50-
},
51-
optionsOverrides,
52-
),
44+
const lightThemeOptions: RedocRawOptions = merge(
45+
{
46+
...redocOptions,
47+
...commonOptions,
48+
theme: lightTheme,
49+
},
50+
optionsOverrides,
51+
);
52+
53+
const darkThemeOptions: RedocRawOptions = merge(
54+
{
55+
...redocOptions,
56+
...commonOptions,
57+
theme: darkTheme,
58+
},
59+
optionsOverrides,
5360
);
5461

55-
const darkStore = new AppStore(
62+
if (currentStore !== null) {
63+
currentStore.dispose();
64+
}
65+
currentStore = new AppStore(
5666
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5767
spec as any,
5868
fullUrl,
59-
merge(
60-
{
61-
...redocOptions,
62-
...commonOptions,
63-
theme: darkTheme,
64-
},
65-
optionsOverrides,
66-
),
69+
isBrowser && isDarkTheme ? darkThemeOptions : lightThemeOptions,
6770
);
6871

6972
return {
70-
lightStore,
71-
darkStore,
72-
};
73-
}, [isBrowser, spec, fullUrl, themeOptions, optionsOverrides]);
74-
75-
const result = useMemo(() => {
76-
return {
77-
...stores,
73+
darkThemeOptions,
74+
lightThemeOptions,
7875
// @ts-expect-error extra prop
7976
hasLogo: !!spec.info?.['x-logo'],
80-
store: isBrowser && isDarkTheme ? stores.darkStore : stores.lightStore,
77+
store: currentStore,
8178
};
82-
}, [isBrowser, isDarkTheme, spec, stores]);
79+
}, [isBrowser, spec, fullUrl, isDarkTheme, themeOptions, optionsOverrides]);
80+
81+
useEffect(() => {
82+
// to ensure that menu is properly loaded when theme gets changed
83+
// or when first load
84+
result.store.onDidMount();
85+
}, [result, isBrowser, isDarkTheme]);
8386

8487
return result;
8588
}

0 commit comments

Comments
 (0)