feat(theme): allow to load a Docusaurus page with theme from query-string: ?docusaurus-theme=dark (#8708)

This commit is contained in:
Sébastien Lorber 2023-03-03 12:54:35 +01:00 committed by GitHub
parent 50b1dc7db3
commit 0f7552accb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 7 deletions

View file

@ -26,6 +26,8 @@ const ContextReplacementPlugin = requireFromDocusaurusCore(
// Need to be inlined to prevent dark mode FOUC
// Make sure the key is the same as the one in `/theme/hooks/useTheme.js`
const ThemeStorageKey = 'theme';
const ThemeQueryStringKey = 'docusaurus-theme';
const noFlashColorMode = ({
defaultMode,
respectPrefersColorScheme,
@ -39,6 +41,14 @@ const noFlashColorMode = ({
document.documentElement.setAttribute('data-theme', theme);
}
function getQueryStringTheme() {
var theme = null;
try {
theme = new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
} catch(e) {}
return theme;
}
function getStoredTheme() {
var theme = null;
try {
@ -47,9 +57,9 @@ const noFlashColorMode = ({
return theme;
}
var storedTheme = getStoredTheme();
if (storedTheme !== null) {
setDataThemeAttribute(storedTheme);
var initialTheme = getQueryStringTheme() || getStoredTheme();
if (initialTheme !== null) {
setDataThemeAttribute(initialTheme);
} else {
if (
respectPrefersColorScheme &&

View file

@ -0,0 +1,43 @@
/**
* 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 React from 'react';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
import BrowserWindow from '@site/src/components/BrowserWindow';
function IframeTest({url}: {url: string}) {
return (
<div style={{padding: 10}}>
<BrowserWindow
url={url}
style={{minWidth: '40vw', maxWidth: 400}}
bodyStyle={{padding: 0}}>
<iframe src={url} title={url} style={{width: '100%', height: 300}} />
</BrowserWindow>
</div>
);
}
// See https://github.com/facebook/docusaurus/issues/8672
export default function Embeds(): JSX.Element {
return (
<Layout>
<div style={{padding: 10}}>
<Heading as="h1">Test Embeds</Heading>
<div style={{display: 'flex', flexWrap: 'wrap'}}>
<IframeTest url="/?docusaurus-theme=light" />
<IframeTest url="/?docusaurus-theme=dark" />
<IframeTest url="/?docusaurus-theme=unexpected-value" />
<IframeTest url="/" />
<IframeTest url="https://docusaurus.io/" />
<IframeTest url="https://tutorial.docusaurus.io/" />
</div>
</div>
</Layout>
);
}

View file

@ -33,3 +33,4 @@ import Readme from "../README.mdx"
- [Head metadata tests](/tests/pages/head-metadata)
- [Unlisted page](/tests/pages/unlisted)
- [Analytics](/tests/pages/analytics)
- [Embeds](/tests/pages/embeds)

View file

@ -127,6 +127,17 @@ In light mode, the `<html>` element has a `data-theme="light"` attribute; in dar
}
```
:::tip
It is possible to initialize the Docusaurus theme directly from a `docusaurus-theme` query string parameter.
Examples:
- [`https://docusaurus.io/?docusaurus-theme=dark`](https://docusaurus.io/?docusaurus-theme=dark)
- [`https://docusaurus.io/docs/configuration?docusaurus-theme=light`](https://docusaurus.io/docs/configuration?docusaurus-theme=light)
:::
### Mobile View {#mobile-view}
Docusaurus uses `996px` as the cutoff between mobile screen width and desktop. If you want your layout to be different in the mobile view, you can use media queries.

View file

@ -5,24 +5,28 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {type ReactNode} from 'react';
import React, {type CSSProperties, type ReactNode} from 'react';
import clsx from 'clsx';
import styles from './styles.module.css';
interface Props {
children: ReactNode;
minHeight: number;
minHeight?: number;
url: string;
style?: CSSProperties;
bodyStyle?: CSSProperties;
}
export default function BrowserWindow({
children,
minHeight,
url = 'http://localhost:3000',
style,
bodyStyle,
}: Props): JSX.Element {
return (
<div className={styles.browserWindow} style={{minHeight}}>
<div className={styles.browserWindow} style={{...style, minHeight}}>
<div className={styles.browserWindowHeader}>
<div className={styles.buttons}>
<span className={styles.dot} style={{background: '#f25f58'}} />
@ -41,7 +45,9 @@ export default function BrowserWindow({
</div>
</div>
<div className={styles.browserWindowBody}>{children}</div>
<div className={styles.browserWindowBody} style={bodyStyle}>
{children}
</div>
</div>
);
}