Skip to content

Commit

Permalink
Merge pull request #198 from mauris/fix/store-menu-problem
Browse files Browse the repository at this point in the history
  • Loading branch information
rohit-gohri committed Jun 14, 2022
2 parents 6ff1bc2 + 30f4d88 commit f3cca29
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ const ApiSchema: React.FC<Props> = ({
...rest
}: Props): JSX.Element => {
const specProps = useSpecData(id);
const { store, darkStore, lightStore } = useSpec(specProps);
const { store } = useSpec(specProps);

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

return (
<ThemeProvider theme={store.options.theme}>
Expand Down
8 changes: 6 additions & 2 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ function Redoc(
},
): JSX.Element {
const { className, optionsOverrides, ...specProps } = props;
const { store, darkStore, lightStore, hasLogo } = useSpec(
const { store, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec(
specProps,
optionsOverrides,
);

return (
<>
<ServerStyles lightStore={lightStore} darkStore={darkStore} />
<ServerStyles
specProps={specProps}
lightThemeOptions={lightThemeOptions}
darkThemeOptions={darkThemeOptions}
/>
<div
className={clsx([
'redocusaurus',
Expand Down
16 changes: 11 additions & 5 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/ServerStyles.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import '../../global';
import { AppStore, Redoc } from 'redoc';
import useBaseUrl from '@docusaurus/useBaseUrl';
import { AppStore, Redoc, RedocRawOptions } from 'redoc';
// eslint-disable-next-line import/no-extraneous-dependencies
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
Expand Down Expand Up @@ -53,17 +54,21 @@ const LIGHT_MODE_PREFIX = "html:not([data-theme='dark'])";
const DARK_MODE_PREFIX = "html([data-theme='dark'])";

export function ServerStyles({
lightStore,
darkStore,
specProps,
lightThemeOptions,
darkThemeOptions,
}: {
lightStore: AppStore;
darkStore: AppStore;
specProps: SpecProps,
lightThemeOptions: RedocRawOptions,
darkThemeOptions: RedocRawOptions,
}) {
const fullUrl = useBaseUrl(specProps.url, { absolute: true });
const css = {
light: '',
dark: '',
};
const lightSheet = new ServerStyleSheet();
const lightStore = new AppStore(specProps.spec, fullUrl, lightThemeOptions);
renderToString(
lightSheet.collectStyles(React.createElement(Redoc, { store: lightStore })),
);
Expand All @@ -73,6 +78,7 @@ export function ServerStyles({
css.light = prefixCssSelectors(lightCss, LIGHT_MODE_PREFIX);

const darkSheet = new ServerStyleSheet();
const darkStore = new AppStore(specProps.spec, fullUrl, darkThemeOptions);
renderToString(
darkSheet.collectStyles(React.createElement(Redoc, { store: darkStore })),
);
Expand Down
7 changes: 4 additions & 3 deletions packages/docusaurus-theme-redoc/src/theme/Redoc/Styles.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react';
import '../../global';
import type { AppStore } from 'redoc';
import type { RedocRawOptions } from 'redoc';

/**
* Don't hydrate/replace server styles
* @see https://github.com/facebook/react/issues/10923#issuecomment-338715787
*/
export function ServerStyles(_props: {
lightStore: AppStore;
darkStore: AppStore;
specProps: SpecProps;
lightThemeOptions: RedocRawOptions;
darkThemeOptions: RedocRawOptions;
}) {
return <div className="redocusaurus-styles"></div>;
}
69 changes: 36 additions & 33 deletions packages/docusaurus-theme-redoc/src/utils/useSpec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from 'react';
import { useMemo, useEffect } from 'react';
import useBaseUrl from '@docusaurus/useBaseUrl';
import useIsBrowser from '@docusaurus/useIsBrowser';
import { usePluginData } from '@docusaurus/useGlobalData';
Expand All @@ -9,6 +9,9 @@ import { AppStore, RedocRawOptions } from 'redoc';
import { SpecProps } from '../types/common';
import { GlobalData } from '../types/options';

// the current store singleton in the app's instance
let currentStore: AppStore | null = null;

/**
* Redocusaurus
* https://rohit-gohri.github.io/redocusaurus/
Expand All @@ -27,7 +30,7 @@ export function useSpec(
themeId,
) as GlobalData;

const stores = useMemo(() => {
const result = useMemo(() => {
const { lightTheme, darkTheme, options: redocOptions } = themeOptions;

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

const lightStore = new AppStore(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
spec as any,
fullUrl,
merge(
{
...redocOptions,
...commonOptions,
theme: lightTheme,
},
optionsOverrides,
),
const lightThemeOptions: RedocRawOptions = merge(
{
...redocOptions,
...commonOptions,
theme: lightTheme,
},
optionsOverrides,
);

const darkThemeOptions: RedocRawOptions = merge(
{
...redocOptions,
...commonOptions,
theme: darkTheme,
},
optionsOverrides,
);

const darkStore = new AppStore(
if (currentStore !== null) {
currentStore.dispose();
}
currentStore = new AppStore(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
spec as any,
fullUrl,
merge(
{
...redocOptions,
...commonOptions,
theme: darkTheme,
},
optionsOverrides,
),
isBrowser && isDarkTheme ? darkThemeOptions : lightThemeOptions,
);

return {
lightStore,
darkStore,
};
}, [isBrowser, spec, fullUrl, themeOptions, optionsOverrides]);

const result = useMemo(() => {
return {
...stores,
darkThemeOptions,
lightThemeOptions,
// @ts-expect-error extra prop
hasLogo: !!spec.info?.['x-logo'],
store: isBrowser && isDarkTheme ? stores.darkStore : stores.lightStore,
store: currentStore,
};
}, [isBrowser, isDarkTheme, spec, stores]);
}, [isBrowser, spec, fullUrl, isDarkTheme, themeOptions, optionsOverrides]);

useEffect(() => {
// to ensure that menu is properly loaded when theme gets changed
// or when first load
result.store.onDidMount();
}, [result, isBrowser, isDarkTheme]);

return result;
}

0 comments on commit f3cca29

Please sign in to comment.