@docusaurus/theme-live-codeblock 3.9.2 → 3.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/client/context.d.ts +16 -0
- package/lib/client/context.js +20 -0
- package/lib/client/index.d.ts +7 -0
- package/lib/client/index.js +7 -0
- package/lib/theme/CodeBlock/index.js +5 -1
- package/lib/theme/Playground/Buttons/ResetButton/index.d.ts +9 -0
- package/lib/theme/Playground/Buttons/ResetButton/index.js +45 -0
- package/lib/theme/Playground/Buttons/ResetButton/styles.module.css +36 -0
- package/lib/theme/Playground/Editor/index.js +2 -1
- package/lib/theme/Playground/Header/index.d.ts +2 -3
- package/lib/theme/Playground/Header/index.js +9 -2
- package/lib/theme/Playground/Header/styles.module.css +11 -3
- package/lib/theme/Playground/Layout/index.d.ts +2 -1
- package/lib/theme/Playground/Layout/index.js +4 -3
- package/lib/theme/Playground/Provider/index.d.ts +1 -1
- package/lib/theme/Playground/Provider/index.js +13 -2
- package/lib/theme/Playground/index.d.ts +1 -1
- package/lib/theme/Playground/index.js +7 -2
- package/package.json +19 -7
- package/src/client/context.tsx +36 -0
- package/src/client/index.ts +8 -0
- package/src/theme/CodeBlock/index.tsx +8 -2
- package/src/theme/Playground/Buttons/ResetButton/index.tsx +51 -0
- package/src/theme/Playground/Buttons/ResetButton/styles.module.css +36 -0
- package/src/theme/Playground/Editor/index.tsx +2 -2
- package/src/theme/Playground/Header/index.tsx +11 -4
- package/src/theme/Playground/Header/styles.module.css +11 -3
- package/src/theme/Playground/Layout/index.tsx +5 -3
- package/src/theme/Playground/Provider/index.tsx +15 -7
- package/src/theme/Playground/index.tsx +2 -1
- package/src/theme-live-codeblock.d.ts +43 -8
package/README.md
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { type ReactNode } from 'react';
|
|
8
|
+
type PlaygroundContextValue = {
|
|
9
|
+
reset: () => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function PlaygroundProvider({ value, children, }: {
|
|
12
|
+
value: PlaygroundContextValue;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}): ReactNode;
|
|
15
|
+
export declare function usePlayground(): PlaygroundContextValue;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { createContext, useContext } from 'react';
|
|
8
|
+
const PlaygroundContext = createContext(null);
|
|
9
|
+
export function PlaygroundProvider({ value, children, }) {
|
|
10
|
+
return (<PlaygroundContext.Provider value={value}>
|
|
11
|
+
{children}
|
|
12
|
+
</PlaygroundContext.Provider>);
|
|
13
|
+
}
|
|
14
|
+
export function usePlayground() {
|
|
15
|
+
const context = useContext(PlaygroundContext);
|
|
16
|
+
if (!context) {
|
|
17
|
+
throw new Error('usePlayground must be used within PlaygroundProvider');
|
|
18
|
+
}
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
@@ -8,7 +8,11 @@ import React from 'react';
|
|
|
8
8
|
import OriginalCodeBlock from '@theme-init/CodeBlock';
|
|
9
9
|
import LiveCodeBlock from '@theme/LiveCodeBlock';
|
|
10
10
|
function isLiveCodeBlock(props) {
|
|
11
|
-
return
|
|
11
|
+
return (
|
|
12
|
+
!!props.live &&
|
|
13
|
+
(typeof props.children === 'undefined' ||
|
|
14
|
+
typeof props.children === 'string')
|
|
15
|
+
);
|
|
12
16
|
}
|
|
13
17
|
export default function CodeBlockEnhancer(props) {
|
|
14
18
|
return isLiveCodeBlock(props) ? (
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { ReactNode } from 'react';
|
|
8
|
+
import type { Props } from '@theme/Playground/Buttons/ResetButton';
|
|
9
|
+
export default function ResetButton({ className }: Props): ReactNode;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import clsx from 'clsx';
|
|
8
|
+
import Translate from '@docusaurus/Translate';
|
|
9
|
+
import {usePlayground} from '@docusaurus/theme-live-codeblock/client';
|
|
10
|
+
import styles from './styles.module.css';
|
|
11
|
+
function Icon() {
|
|
12
|
+
return (
|
|
13
|
+
<svg
|
|
14
|
+
className={styles.resetButtonIcon}
|
|
15
|
+
viewBox="0 0 16 16"
|
|
16
|
+
fill="currentColor"
|
|
17
|
+
aria-hidden="true">
|
|
18
|
+
<path d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
|
19
|
+
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
|
20
|
+
</svg>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
function Label() {
|
|
24
|
+
return (
|
|
25
|
+
<Translate
|
|
26
|
+
id="theme.Playground.buttons.reset"
|
|
27
|
+
description="The reset button label for live code blocks">
|
|
28
|
+
Reset
|
|
29
|
+
</Translate>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
export default function ResetButton({className}) {
|
|
33
|
+
const {reset} = usePlayground();
|
|
34
|
+
return (
|
|
35
|
+
<button
|
|
36
|
+
type="button"
|
|
37
|
+
aria-label="Reset code to original"
|
|
38
|
+
title="Reset"
|
|
39
|
+
className={clsx('clean-btn', className, styles.resetButton)}
|
|
40
|
+
onClick={() => reset()}>
|
|
41
|
+
<Icon />
|
|
42
|
+
<Label />
|
|
43
|
+
</button>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.resetButton {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: 0.25rem;
|
|
12
|
+
padding: 0.25rem 0.5rem;
|
|
13
|
+
font-size: 0.875rem;
|
|
14
|
+
line-height: 1.5;
|
|
15
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
16
|
+
border-radius: var(--ifm-global-radius);
|
|
17
|
+
background: var(--ifm-button-background-color);
|
|
18
|
+
color: var(--ifm-font-color-base);
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
transition: all var(--ifm-transition-fast);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.resetButton:hover {
|
|
24
|
+
background: var(--ifm-color-emphasis-200);
|
|
25
|
+
border-color: var(--ifm-color-emphasis-400);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.resetButton:active {
|
|
29
|
+
background: var(--ifm-color-emphasis-300);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.resetButtonIcon {
|
|
33
|
+
width: 1rem;
|
|
34
|
+
height: 1rem;
|
|
35
|
+
flex-shrink: 0;
|
|
36
|
+
}
|
|
@@ -9,12 +9,13 @@ import {LiveEditor} from 'react-live';
|
|
|
9
9
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
10
10
|
import Translate from '@docusaurus/Translate';
|
|
11
11
|
import PlaygroundHeader from '@theme/Playground/Header';
|
|
12
|
+
import ResetButton from '@theme/Playground/Buttons/ResetButton';
|
|
12
13
|
import styles from './styles.module.css';
|
|
13
14
|
export default function PlaygroundEditor() {
|
|
14
15
|
const isBrowser = useIsBrowser();
|
|
15
16
|
return (
|
|
16
17
|
<>
|
|
17
|
-
<PlaygroundHeader>
|
|
18
|
+
<PlaygroundHeader buttons={<ResetButton />}>
|
|
18
19
|
<Translate
|
|
19
20
|
id="theme.Playground.liveEditor"
|
|
20
21
|
description="The live editor label of the live codeblocks">
|
|
@@ -5,6 +5,5 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { type ReactNode } from 'react';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}): ReactNode;
|
|
8
|
+
import type { Props } from '@theme/Playground/Header';
|
|
9
|
+
export default function PlaygroundHeader({ children, buttons, }: Props): ReactNode;
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import styles from './styles.module.css';
|
|
10
|
-
export default function PlaygroundHeader({children}) {
|
|
11
|
-
return
|
|
10
|
+
export default function PlaygroundHeader({children, buttons}) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={clsx(styles.playgroundHeader)}>
|
|
13
|
+
<div className={styles.playgroundHeaderContent}>{children}</div>
|
|
14
|
+
{buttons && (
|
|
15
|
+
<div className={styles.playgroundHeaderButtons}>{buttons}</div>
|
|
16
|
+
)}
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
12
19
|
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
.playgroundHeader {
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
align-items: center;
|
|
9
12
|
letter-spacing: 0.08rem;
|
|
10
13
|
padding: 0.75rem;
|
|
11
14
|
text-transform: uppercase;
|
|
@@ -15,7 +18,12 @@
|
|
|
15
18
|
font-size: var(--ifm-code-font-size);
|
|
16
19
|
}
|
|
17
20
|
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
.playgroundHeaderContent {
|
|
22
|
+
font-weight: var(--ifm-font-weight-bold);
|
|
23
|
+
font-size: 0.875rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.playgroundHeaderButtons {
|
|
27
|
+
display: flex;
|
|
28
|
+
gap: 0.5rem;
|
|
21
29
|
}
|
|
@@ -5,4 +5,5 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { type ReactNode } from 'react';
|
|
8
|
-
|
|
8
|
+
import type { Props } from '@theme/Playground/Layout';
|
|
9
|
+
export default function PlaygroundLayout(props: Props): ReactNode;
|
|
@@ -12,11 +12,12 @@ function useLiveCodeBlockThemeConfig() {
|
|
|
12
12
|
const themeConfig = useThemeConfig();
|
|
13
13
|
return themeConfig.liveCodeBlock;
|
|
14
14
|
}
|
|
15
|
-
export default function PlaygroundLayout() {
|
|
16
|
-
const
|
|
15
|
+
export default function PlaygroundLayout(props) {
|
|
16
|
+
const themeConfig = useLiveCodeBlockThemeConfig();
|
|
17
|
+
const position = props.position ?? themeConfig.playgroundPosition;
|
|
17
18
|
return (
|
|
18
19
|
<>
|
|
19
|
-
{
|
|
20
|
+
{position === 'top' ? (
|
|
20
21
|
<>
|
|
21
22
|
<PlaygroundPreview />
|
|
22
23
|
<PlaygroundEditor />
|
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React from 'react';
|
|
7
|
+
import React, {useCallback, useMemo, useState} from 'react';
|
|
8
8
|
import {LiveProvider} from 'react-live';
|
|
9
|
+
import {PlaygroundProvider as PlaygroundProviderComponent} from '@docusaurus/theme-live-codeblock/client';
|
|
9
10
|
import {usePrismTheme} from '@docusaurus/theme-common';
|
|
10
11
|
// this should rather be a stable function
|
|
11
12
|
// see https://github.com/facebook/docusaurus/issues/9630#issuecomment-1855682643
|
|
12
13
|
const DEFAULT_TRANSFORM_CODE = (code) => `${code};`;
|
|
13
|
-
|
|
14
|
+
function LiveProviderComponent({code, children, ...props}) {
|
|
14
15
|
const prismTheme = usePrismTheme();
|
|
15
16
|
const noInline = props.metastring?.includes('noInline') ?? false;
|
|
16
17
|
return (
|
|
@@ -24,3 +25,13 @@ export default function PlaygroundProvider({code, children, ...props}) {
|
|
|
24
25
|
</LiveProvider>
|
|
25
26
|
);
|
|
26
27
|
}
|
|
28
|
+
export default function PlaygroundProvider(props) {
|
|
29
|
+
const [resetKey, setResetKey] = useState(0);
|
|
30
|
+
const reset = useCallback(() => setResetKey((prev) => prev + 1), []);
|
|
31
|
+
const value = useMemo(() => ({reset}), [reset]);
|
|
32
|
+
return (
|
|
33
|
+
<PlaygroundProviderComponent key={resetKey} value={value}>
|
|
34
|
+
<LiveProviderComponent {...props} />
|
|
35
|
+
</PlaygroundProviderComponent>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type ReactNode } from 'react';
|
|
8
8
|
import type { Props } from '@theme/Playground';
|
|
9
|
-
export default function Playground({ children, transformCode, ...props }: Props): ReactNode;
|
|
9
|
+
export default function Playground({ children, transformCode, position, ...props }: Props): ReactNode;
|
|
@@ -8,11 +8,16 @@ import React from 'react';
|
|
|
8
8
|
import PlaygroundProvider from '@theme/Playground/Provider';
|
|
9
9
|
import PlaygroundContainer from '@theme/Playground/Container';
|
|
10
10
|
import PlaygroundLayout from '@theme/Playground/Layout';
|
|
11
|
-
export default function Playground({
|
|
11
|
+
export default function Playground({
|
|
12
|
+
children,
|
|
13
|
+
transformCode,
|
|
14
|
+
position,
|
|
15
|
+
...props
|
|
16
|
+
}) {
|
|
12
17
|
return (
|
|
13
18
|
<PlaygroundContainer>
|
|
14
19
|
<PlaygroundProvider code={children} {...props}>
|
|
15
|
-
<PlaygroundLayout />
|
|
20
|
+
<PlaygroundLayout position={position} />
|
|
16
21
|
</PlaygroundProvider>
|
|
17
22
|
</PlaygroundContainer>
|
|
18
23
|
);
|
package/package.json
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/theme-live-codeblock",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.1",
|
|
4
4
|
"description": "Docusaurus live code block component.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/theme-live-codeblock.d.ts",
|
|
7
7
|
"sideEffects": [
|
|
8
8
|
"lib/theme/Playground/*"
|
|
9
9
|
],
|
|
10
|
+
"exports": {
|
|
11
|
+
"./lib/*": "./lib/*",
|
|
12
|
+
"./src/*": "./src/*",
|
|
13
|
+
"./client": {
|
|
14
|
+
"type": "./lib/client/index.d.ts",
|
|
15
|
+
"default": "./lib/client/index.js"
|
|
16
|
+
},
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./src/theme-live-codeblock.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
10
22
|
"publishConfig": {
|
|
11
23
|
"access": "public"
|
|
12
24
|
},
|
|
@@ -23,10 +35,10 @@
|
|
|
23
35
|
},
|
|
24
36
|
"license": "MIT",
|
|
25
37
|
"dependencies": {
|
|
26
|
-
"@docusaurus/core": "3.
|
|
27
|
-
"@docusaurus/theme-common": "3.
|
|
28
|
-
"@docusaurus/theme-translations": "3.
|
|
29
|
-
"@docusaurus/utils-validation": "3.
|
|
38
|
+
"@docusaurus/core": "3.10.1",
|
|
39
|
+
"@docusaurus/theme-common": "3.10.1",
|
|
40
|
+
"@docusaurus/theme-translations": "3.10.1",
|
|
41
|
+
"@docusaurus/utils-validation": "3.10.1",
|
|
30
42
|
"@philpl/buble": "^0.19.7",
|
|
31
43
|
"clsx": "^2.0.0",
|
|
32
44
|
"fs-extra": "^11.1.1",
|
|
@@ -34,7 +46,7 @@
|
|
|
34
46
|
"tslib": "^2.6.0"
|
|
35
47
|
},
|
|
36
48
|
"devDependencies": {
|
|
37
|
-
"@docusaurus/types": "3.
|
|
49
|
+
"@docusaurus/types": "3.10.1",
|
|
38
50
|
"@types/buble": "^0.20.1"
|
|
39
51
|
},
|
|
40
52
|
"peerDependencies": {
|
|
@@ -44,5 +56,5 @@
|
|
|
44
56
|
"engines": {
|
|
45
57
|
"node": ">=20.0"
|
|
46
58
|
},
|
|
47
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "41c1a458ecb07d61b6df2761ea4bc1b13db49d12"
|
|
48
60
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {createContext, useContext, type ReactNode} from 'react';
|
|
9
|
+
|
|
10
|
+
type PlaygroundContextValue = {
|
|
11
|
+
reset: () => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const PlaygroundContext = createContext<PlaygroundContextValue | null>(null);
|
|
15
|
+
|
|
16
|
+
export function PlaygroundProvider({
|
|
17
|
+
value,
|
|
18
|
+
children,
|
|
19
|
+
}: {
|
|
20
|
+
value: PlaygroundContextValue;
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}): ReactNode {
|
|
23
|
+
return (
|
|
24
|
+
<PlaygroundContext.Provider value={value}>
|
|
25
|
+
{children}
|
|
26
|
+
</PlaygroundContext.Provider>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function usePlayground(): PlaygroundContextValue {
|
|
31
|
+
const context = useContext(PlaygroundContext);
|
|
32
|
+
if (!context) {
|
|
33
|
+
throw new Error('usePlayground must be used within PlaygroundProvider');
|
|
34
|
+
}
|
|
35
|
+
return context;
|
|
36
|
+
}
|
|
@@ -19,8 +19,14 @@ declare module '@theme/CodeBlock' {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function isLiveCodeBlock(
|
|
23
|
-
|
|
22
|
+
function isLiveCodeBlock(
|
|
23
|
+
props: CodeBlockProps,
|
|
24
|
+
): props is {live: true; children: string | undefined} {
|
|
25
|
+
return (
|
|
26
|
+
!!props.live &&
|
|
27
|
+
(typeof props.children === 'undefined' ||
|
|
28
|
+
typeof props.children === 'string')
|
|
29
|
+
);
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
export default function CodeBlockEnhancer(props: CodeBlockProps): ReactNode {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {ReactNode} from 'react';
|
|
9
|
+
import clsx from 'clsx';
|
|
10
|
+
import Translate from '@docusaurus/Translate';
|
|
11
|
+
import {usePlayground} from '@docusaurus/theme-live-codeblock/client';
|
|
12
|
+
import type {Props} from '@theme/Playground/Buttons/ResetButton';
|
|
13
|
+
import styles from './styles.module.css';
|
|
14
|
+
|
|
15
|
+
function Icon() {
|
|
16
|
+
return (
|
|
17
|
+
<svg
|
|
18
|
+
className={styles.resetButtonIcon}
|
|
19
|
+
viewBox="0 0 16 16"
|
|
20
|
+
fill="currentColor"
|
|
21
|
+
aria-hidden="true">
|
|
22
|
+
<path d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" />
|
|
23
|
+
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" />
|
|
24
|
+
</svg>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function Label() {
|
|
29
|
+
return (
|
|
30
|
+
<Translate
|
|
31
|
+
id="theme.Playground.buttons.reset"
|
|
32
|
+
description="The reset button label for live code blocks">
|
|
33
|
+
Reset
|
|
34
|
+
</Translate>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default function ResetButton({className}: Props): ReactNode {
|
|
39
|
+
const {reset} = usePlayground();
|
|
40
|
+
return (
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
aria-label="Reset code to original"
|
|
44
|
+
title="Reset"
|
|
45
|
+
className={clsx('clean-btn', className, styles.resetButton)}
|
|
46
|
+
onClick={() => reset()}>
|
|
47
|
+
<Icon />
|
|
48
|
+
<Label />
|
|
49
|
+
</button>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.resetButton {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: 0.25rem;
|
|
12
|
+
padding: 0.25rem 0.5rem;
|
|
13
|
+
font-size: 0.875rem;
|
|
14
|
+
line-height: 1.5;
|
|
15
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
16
|
+
border-radius: var(--ifm-global-radius);
|
|
17
|
+
background: var(--ifm-button-background-color);
|
|
18
|
+
color: var(--ifm-font-color-base);
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
transition: all var(--ifm-transition-fast);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.resetButton:hover {
|
|
24
|
+
background: var(--ifm-color-emphasis-200);
|
|
25
|
+
border-color: var(--ifm-color-emphasis-400);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.resetButton:active {
|
|
29
|
+
background: var(--ifm-color-emphasis-300);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.resetButtonIcon {
|
|
33
|
+
width: 1rem;
|
|
34
|
+
height: 1rem;
|
|
35
|
+
flex-shrink: 0;
|
|
36
|
+
}
|
|
@@ -10,14 +10,14 @@ import {LiveEditor} from 'react-live';
|
|
|
10
10
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
11
11
|
import Translate from '@docusaurus/Translate';
|
|
12
12
|
import PlaygroundHeader from '@theme/Playground/Header';
|
|
13
|
-
|
|
13
|
+
import ResetButton from '@theme/Playground/Buttons/ResetButton';
|
|
14
14
|
import styles from './styles.module.css';
|
|
15
15
|
|
|
16
16
|
export default function PlaygroundEditor(): ReactNode {
|
|
17
17
|
const isBrowser = useIsBrowser();
|
|
18
18
|
return (
|
|
19
19
|
<>
|
|
20
|
-
<PlaygroundHeader>
|
|
20
|
+
<PlaygroundHeader buttons={<ResetButton />}>
|
|
21
21
|
<Translate
|
|
22
22
|
id="theme.Playground.liveEditor"
|
|
23
23
|
description="The live editor label of the live codeblocks">
|
|
@@ -7,13 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
import React, {type ReactNode} from 'react';
|
|
9
9
|
import clsx from 'clsx';
|
|
10
|
+
import type {Props} from '@theme/Playground/Header';
|
|
10
11
|
|
|
11
12
|
import styles from './styles.module.css';
|
|
12
13
|
|
|
13
14
|
export default function PlaygroundHeader({
|
|
14
15
|
children,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
buttons,
|
|
17
|
+
}: Props): ReactNode {
|
|
18
|
+
return (
|
|
19
|
+
<div className={clsx(styles.playgroundHeader)}>
|
|
20
|
+
<div className={styles.playgroundHeaderContent}>{children}</div>
|
|
21
|
+
{buttons && (
|
|
22
|
+
<div className={styles.playgroundHeaderButtons}>{buttons}</div>
|
|
23
|
+
)}
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
19
26
|
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
.playgroundHeader {
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
align-items: center;
|
|
9
12
|
letter-spacing: 0.08rem;
|
|
10
13
|
padding: 0.75rem;
|
|
11
14
|
text-transform: uppercase;
|
|
@@ -15,7 +18,12 @@
|
|
|
15
18
|
font-size: var(--ifm-code-font-size);
|
|
16
19
|
}
|
|
17
20
|
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
.playgroundHeaderContent {
|
|
22
|
+
font-weight: var(--ifm-font-weight-bold);
|
|
23
|
+
font-size: 0.875rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.playgroundHeaderButtons {
|
|
27
|
+
display: flex;
|
|
28
|
+
gap: 0.5rem;
|
|
21
29
|
}
|
|
@@ -9,6 +9,7 @@ import React, {type ReactNode} from 'react';
|
|
|
9
9
|
import {useThemeConfig} from '@docusaurus/theme-common';
|
|
10
10
|
import PlaygroundPreview from '@theme/Playground/Preview';
|
|
11
11
|
import PlaygroundEditor from '@theme/Playground/Editor';
|
|
12
|
+
import type {Props} from '@theme/Playground/Layout';
|
|
12
13
|
|
|
13
14
|
import type {ThemeConfig} from '@docusaurus/theme-live-codeblock';
|
|
14
15
|
|
|
@@ -17,11 +18,12 @@ function useLiveCodeBlockThemeConfig() {
|
|
|
17
18
|
return themeConfig.liveCodeBlock;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
export default function PlaygroundLayout(): ReactNode {
|
|
21
|
-
const
|
|
21
|
+
export default function PlaygroundLayout(props: Props): ReactNode {
|
|
22
|
+
const themeConfig = useLiveCodeBlockThemeConfig();
|
|
23
|
+
const position = props.position ?? themeConfig.playgroundPosition;
|
|
22
24
|
return (
|
|
23
25
|
<>
|
|
24
|
-
{
|
|
26
|
+
{position === 'top' ? (
|
|
25
27
|
<>
|
|
26
28
|
<PlaygroundPreview />
|
|
27
29
|
<PlaygroundEditor />
|
|
@@ -5,21 +5,17 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, {type ReactNode} from 'react';
|
|
8
|
+
import React, {type ReactNode, useCallback, useMemo, useState} from 'react';
|
|
9
9
|
import {LiveProvider} from 'react-live';
|
|
10
|
+
import {PlaygroundProvider as PlaygroundProviderComponent} from '@docusaurus/theme-live-codeblock/client';
|
|
10
11
|
import {usePrismTheme} from '@docusaurus/theme-common';
|
|
11
|
-
|
|
12
12
|
import type {Props} from '@theme/Playground/Provider';
|
|
13
13
|
|
|
14
14
|
// this should rather be a stable function
|
|
15
15
|
// see https://github.com/facebook/docusaurus/issues/9630#issuecomment-1855682643
|
|
16
16
|
const DEFAULT_TRANSFORM_CODE = (code: string) => `${code};`;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
code,
|
|
20
|
-
children,
|
|
21
|
-
...props
|
|
22
|
-
}: Props): ReactNode {
|
|
18
|
+
function LiveProviderComponent({code, children, ...props}: Props): ReactNode {
|
|
23
19
|
const prismTheme = usePrismTheme();
|
|
24
20
|
const noInline = props.metastring?.includes('noInline') ?? false;
|
|
25
21
|
return (
|
|
@@ -33,3 +29,15 @@ export default function PlaygroundProvider({
|
|
|
33
29
|
</LiveProvider>
|
|
34
30
|
);
|
|
35
31
|
}
|
|
32
|
+
|
|
33
|
+
export default function PlaygroundProvider(props: Props): ReactNode {
|
|
34
|
+
const [resetKey, setResetKey] = useState(0);
|
|
35
|
+
const reset = useCallback(() => setResetKey((prev) => prev + 1), []);
|
|
36
|
+
const value = useMemo(() => ({reset}), [reset]);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<PlaygroundProviderComponent key={resetKey} value={value}>
|
|
40
|
+
<LiveProviderComponent {...props} />
|
|
41
|
+
</PlaygroundProviderComponent>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -15,12 +15,13 @@ import type {Props} from '@theme/Playground';
|
|
|
15
15
|
export default function Playground({
|
|
16
16
|
children,
|
|
17
17
|
transformCode,
|
|
18
|
+
position,
|
|
18
19
|
...props
|
|
19
20
|
}: Props): ReactNode {
|
|
20
21
|
return (
|
|
21
22
|
<PlaygroundContainer>
|
|
22
23
|
<PlaygroundProvider code={children} {...props}>
|
|
23
|
-
<PlaygroundLayout />
|
|
24
|
+
<PlaygroundLayout position={position} />
|
|
24
25
|
</PlaygroundProvider>
|
|
25
26
|
</PlaygroundContainer>
|
|
26
27
|
);
|
|
@@ -9,17 +9,24 @@
|
|
|
9
9
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
10
10
|
|
|
11
11
|
declare module '@docusaurus/theme-live-codeblock' {
|
|
12
|
+
import type {PlaygroundPosition} from '@theme/Playground';
|
|
13
|
+
|
|
12
14
|
export type ThemeConfig = {
|
|
13
15
|
liveCodeBlock: {
|
|
14
|
-
playgroundPosition:
|
|
16
|
+
playgroundPosition: PlaygroundPosition;
|
|
15
17
|
};
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
declare module '@theme/LiveCodeBlock' {
|
|
22
|
+
import type {ReactNode} from 'react';
|
|
20
23
|
import type {Props as BaseProps} from '@theme/CodeBlock';
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
type CodeBlockProps = Omit<BaseProps, 'children'>;
|
|
26
|
+
|
|
27
|
+
export interface Props extends CodeBlockProps {
|
|
28
|
+
children?: string;
|
|
29
|
+
}
|
|
23
30
|
|
|
24
31
|
export default function LiveCodeBlock(props: Props): ReactNode;
|
|
25
32
|
}
|
|
@@ -29,14 +36,21 @@ declare module '@theme/Playground' {
|
|
|
29
36
|
import type {Props as BaseProps} from '@theme/CodeBlock';
|
|
30
37
|
import type {LiveProvider} from 'react-live';
|
|
31
38
|
|
|
32
|
-
type CodeBlockProps = Omit<
|
|
39
|
+
type CodeBlockProps = Omit<
|
|
40
|
+
BaseProps,
|
|
41
|
+
'children' | 'className' | 'language' | 'title'
|
|
42
|
+
>;
|
|
33
43
|
type LiveProviderProps = React.ComponentProps<typeof LiveProvider>;
|
|
34
44
|
|
|
45
|
+
export type PlaygroundPosition = 'top' | 'bottom';
|
|
46
|
+
|
|
35
47
|
export interface Props extends CodeBlockProps, LiveProviderProps {
|
|
36
48
|
// Allow empty live playgrounds
|
|
37
49
|
children?: string;
|
|
50
|
+
position?: PlaygroundPosition;
|
|
38
51
|
}
|
|
39
|
-
|
|
52
|
+
|
|
53
|
+
export default function Playground(props: Props): ReactNode;
|
|
40
54
|
}
|
|
41
55
|
|
|
42
56
|
declare module '@theme/Playground/Provider' {
|
|
@@ -48,6 +62,13 @@ declare module '@theme/Playground/Provider' {
|
|
|
48
62
|
children: ReactNode;
|
|
49
63
|
}
|
|
50
64
|
|
|
65
|
+
export interface ResetContextValue {
|
|
66
|
+
resetKey: number;
|
|
67
|
+
reset: () => void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const PlaygroundResetContext: React.Context<ResetContextValue | null>;
|
|
71
|
+
export function usePlaygroundReset(): ResetContextValue;
|
|
51
72
|
export default function PlaygroundProvider(props: Props): ReactNode;
|
|
52
73
|
}
|
|
53
74
|
|
|
@@ -63,9 +84,11 @@ declare module '@theme/Playground/Container' {
|
|
|
63
84
|
|
|
64
85
|
declare module '@theme/Playground/Layout' {
|
|
65
86
|
import type {ReactNode} from 'react';
|
|
87
|
+
import type {PlaygroundPosition} from '@theme/Playground';
|
|
66
88
|
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
export interface Props {
|
|
90
|
+
position?: PlaygroundPosition;
|
|
91
|
+
}
|
|
69
92
|
|
|
70
93
|
export default function PlaygroundLayout(props: Props): ReactNode;
|
|
71
94
|
}
|
|
@@ -91,12 +114,24 @@ declare module '@theme/Playground/Editor' {
|
|
|
91
114
|
declare module '@theme/Playground/Header' {
|
|
92
115
|
import type {ReactNode} from 'react';
|
|
93
116
|
|
|
94
|
-
|
|
95
|
-
|
|
117
|
+
export interface Props {
|
|
118
|
+
children: ReactNode;
|
|
119
|
+
buttons?: ReactNode;
|
|
120
|
+
}
|
|
96
121
|
|
|
97
122
|
export default function PlaygroundHeader(props: Props): ReactNode;
|
|
98
123
|
}
|
|
99
124
|
|
|
125
|
+
declare module '@theme/Playground/Buttons/ResetButton' {
|
|
126
|
+
import type {ReactNode} from 'react';
|
|
127
|
+
|
|
128
|
+
export interface Props {
|
|
129
|
+
className?: string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export default function ResetButton(props: Props): ReactNode;
|
|
133
|
+
}
|
|
134
|
+
|
|
100
135
|
declare module '@theme/ReactLiveScope' {
|
|
101
136
|
type Scope = {
|
|
102
137
|
[key: string]: unknown;
|