This commit is contained in:
Bradlee Speice 2024-11-17 21:34:32 -05:00
parent f26afcccf9
commit b46993bd51
3 changed files with 179 additions and 1 deletions

View File

@ -1,7 +1,7 @@
// Hint: try increasing the iteration count // Hint: try increasing the iteration count
const iterations = 10000; const iterations = 10000;
// Hint: negating `x` and `y` also creates some interesting images // Hint: negating `x` and `y` creates some interesting images
const functions = [ const functions = [
(x, y) => [x / 2, y / 2], (x, y) => [x / 2, y / 2],
(x, y) => [(x + 1) / 2, y / 2], (x, y) => [(x + 1) / 2, y / 2],

View File

@ -0,0 +1,135 @@
import React from 'react';
import clsx from 'clsx';
import useIsBrowser from '@docusaurus/useIsBrowser';
import {LiveProvider, LiveEditor, LiveError, LivePreview} from 'react-live';
import Translate from '@docusaurus/Translate';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import BrowserOnly from '@docusaurus/BrowserOnly';
import {
ErrorBoundaryErrorMessageFallback,
usePrismTheme,
} from '@docusaurus/theme-common';
import ErrorBoundary from '@docusaurus/ErrorBoundary';
import type {Props} from '@theme/Playground';
import type {ThemeConfig} from '@docusaurus/theme-live-codeblock';
import styles from './styles.module.css';
function Header({children}: {children: React.ReactNode}) {
return <div className={clsx(styles.playgroundHeader)}>{children}</div>;
}
function LivePreviewLoader() {
// Is it worth improving/translating?
// eslint-disable-next-line @docusaurus/no-untranslated-text
return <div>Loading...</div>;
}
function Preview() {
// No SSR for the live preview
// See https://github.com/facebook/docusaurus/issues/5747
return (
<BrowserOnly fallback={<LivePreviewLoader />}>
{() => (
<>
<ErrorBoundary
fallback={(params) => (
<ErrorBoundaryErrorMessageFallback {...params} />
)}>
<LivePreview />
</ErrorBoundary>
<LiveError />
</>
)}
</BrowserOnly>
);
}
function ResultWithHeader() {
return (
<>
<Header>
<Translate
id="theme.Playground.result"
description="The result label of the live codeblocks">
Result
</Translate>
</Header>
{/* https://github.com/facebook/docusaurus/issues/5747 */}
<div className={styles.playgroundPreview}>
<Preview />
</div>
</>
);
}
function ThemedLiveEditor() {
const isBrowser = useIsBrowser();
return (
<LiveEditor
// We force remount the editor on hydration,
// otherwise dark prism theme is not applied
key={String(isBrowser)}
className={styles.playgroundEditor}
/>
);
}
function EditorWithHeader() {
return (
<>
<Header>
<Translate
id="theme.Playground.liveEditor"
description="The live editor label of the live codeblocks">
Live Editor
</Translate>
</Header>
<ThemedLiveEditor />
</>
);
}
// this should rather be a stable function
// see https://github.com/facebook/docusaurus/issues/9630#issuecomment-1855682643
const DEFAULT_TRANSFORM_CODE = (code: string) => `${code};`;
export default function Playground({
children,
transformCode,
...props
}: Props): JSX.Element {
const {
siteConfig: {themeConfig},
} = useDocusaurusContext();
const {
liveCodeBlock: {playgroundPosition},
} = themeConfig as ThemeConfig;
const prismTheme = usePrismTheme();
const noInline = props.metastring?.includes('noInline') ?? false;
return (
<div className={styles.playgroundContainer}>
<LiveProvider
code={children?.replace(/\n$/, '')}
noInline={noInline}
transformCode={transformCode ?? DEFAULT_TRANSFORM_CODE}
theme={prismTheme}
{...props}>
{playgroundPosition === 'top' ? (
<>
<ResultWithHeader />
<EditorWithHeader />
</>
) : (
<>
<EditorWithHeader />
<ResultWithHeader />
</>
)}
</LiveProvider>
</div>
);
}

View File

@ -0,0 +1,43 @@
.playgroundContainer {
margin-bottom: var(--ifm-leading);
border-radius: var(--ifm-global-radius);
box-shadow: var(--ifm-global-shadow-lw);
overflow: hidden;
}
.playgroundHeader {
letter-spacing: 0.08rem;
padding: 0.75rem;
text-transform: uppercase;
font-weight: bold;
background: var(--ifm-color-emphasis-200);
color: var(--ifm-color-content);
font-size: var(--ifm-code-font-size);
}
.playgroundHeader:first-of-type {
background: var(--ifm-color-emphasis-600);
color: var(--ifm-color-content-inverse);
}
.playgroundEditor {
font: var(--ifm-code-font-size) / var(--ifm-pre-line-height)
var(--ifm-font-family-monospace) !important;
/* rtl:ignore */
direction: ltr;
}
.playgroundPreview {
padding: 1rem;
background-color: var(--ifm-pre-background);
}
/*
Docusaurus global CSS applies a `border-radius` to `pre` that leads to a minor graphical issue
where the "LIVE EDITOR" title bar and code block meet - https://github.com/facebook/docusaurus/issues/6032#issuecomment-2481803877
This change disables the border radius so the edges properly join together
*/
.playgroundEditor > pre {
border-radius: 0;
}