Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(theme): dark and light AppStore menu fix #201

Merged
merged 5 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tall-laws-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'docusaurus-theme-redoc': patch
---

Dark and light AppStore menu fix
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;
}