@docusaurus/theme-classic 3.7.0-canary-6274 → 3.7.0-canary-6276
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/lib/getSwizzleConfig.js +1 -1
- package/lib/theme/CodeBlock/{WordWrapButton → Buttons/Button}/index.d.ts +2 -2
- package/lib/theme/CodeBlock/Buttons/Button/index.js +13 -0
- package/lib/theme/CodeBlock/Buttons/CopyButton/index.d.ts +9 -0
- package/lib/theme/CodeBlock/{CopyButton → Buttons/CopyButton}/index.js +36 -25
- package/lib/theme/CodeBlock/Buttons/WordWrapButton/index.d.ts +9 -0
- package/lib/theme/CodeBlock/{WordWrapButton → Buttons/WordWrapButton}/index.js +12 -7
- package/lib/theme/CodeBlock/{CopyButton → Buttons}/index.d.ts +2 -2
- package/lib/theme/CodeBlock/Buttons/index.js +27 -0
- package/lib/theme/CodeBlock/Buttons/styles.module.css +37 -0
- package/lib/theme/CodeBlock/Content/Element.js +4 -2
- package/lib/theme/CodeBlock/Content/String.d.ts +1 -1
- package/lib/theme/CodeBlock/Content/String.js +22 -104
- package/lib/theme/CodeBlock/Content/index.d.ts +9 -0
- package/lib/theme/CodeBlock/Content/index.js +74 -0
- package/lib/theme/CodeBlock/Content/styles.module.css +0 -52
- package/lib/theme/CodeBlock/Layout/index.d.ts +9 -0
- package/lib/theme/CodeBlock/Layout/index.js +30 -0
- package/lib/theme/CodeBlock/Layout/styles.module.css +27 -0
- package/lib/theme/CodeBlock/Line/Token/index.d.ts +9 -0
- package/lib/theme/CodeBlock/Line/Token/index.js +11 -0
- package/lib/theme/CodeBlock/Line/index.js +9 -3
- package/lib/theme/CodeBlock/Title/index.d.ts +9 -0
- package/lib/theme/CodeBlock/Title/index.js +10 -0
- package/package.json +15 -15
- package/src/getSwizzleConfig.ts +1 -1
- package/src/theme/CodeBlock/Buttons/Button/index.tsx +19 -0
- package/src/theme/CodeBlock/{CopyButton → Buttons/CopyButton}/index.tsx +42 -26
- package/src/theme/CodeBlock/{WordWrapButton → Buttons/WordWrapButton}/index.tsx +15 -12
- package/src/theme/CodeBlock/Buttons/index.tsx +32 -0
- package/src/theme/CodeBlock/Buttons/styles.module.css +37 -0
- package/src/theme/CodeBlock/Content/Element.tsx +4 -2
- package/src/theme/CodeBlock/Content/String.tsx +24 -113
- package/src/theme/CodeBlock/Content/index.tsx +84 -0
- package/src/theme/CodeBlock/Content/styles.module.css +0 -52
- package/src/theme/CodeBlock/Layout/index.tsx +34 -0
- package/src/theme/CodeBlock/Layout/styles.module.css +27 -0
- package/src/theme/CodeBlock/Line/Token/index.tsx +18 -0
- package/src/theme/CodeBlock/Line/index.tsx +9 -3
- package/src/theme/CodeBlock/Title/index.tsx +15 -0
- package/src/theme-classic.d.ts +79 -10
- /package/lib/theme/CodeBlock/{CopyButton → Buttons/CopyButton}/styles.module.css +0 -0
- /package/lib/theme/CodeBlock/{WordWrapButton → Buttons/WordWrapButton}/styles.module.css +0 -0
- /package/src/theme/CodeBlock/{CopyButton → Buttons/CopyButton}/styles.module.css +0 -0
- /package/src/theme/CodeBlock/{WordWrapButton → Buttons/WordWrapButton}/styles.module.css +0 -0
package/lib/getSwizzleConfig.js
CHANGED
|
@@ -148,7 +148,7 @@ function getSwizzleConfig() {
|
|
|
148
148
|
'CodeBlock/Content': {
|
|
149
149
|
actions: {
|
|
150
150
|
eject: 'unsafe',
|
|
151
|
-
wrap: '
|
|
151
|
+
wrap: 'unsafe',
|
|
152
152
|
},
|
|
153
153
|
description: 'The folder containing components responsible for rendering different types of CodeBlock content.',
|
|
154
154
|
},
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { type ReactNode } from 'react';
|
|
8
|
-
import type { Props } from '@theme/CodeBlock/
|
|
9
|
-
export default function
|
|
8
|
+
import type { Props } from '@theme/CodeBlock/Buttons/Button';
|
|
9
|
+
export default function CodeBlockButton({ className, ...props }: Props): ReactNode;
|
|
@@ -0,0 +1,13 @@
|
|
|
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 React from 'react';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
export default function CodeBlockButton({className, ...props}) {
|
|
10
|
+
return (
|
|
11
|
+
<button type="button" {...props} className={clsx('clean-btn', className)} />
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -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/CodeBlock/Buttons/CopyButton';
|
|
9
|
+
export default function CopyButton({ className }: Props): ReactNode;
|
|
@@ -8,13 +8,38 @@ import React, {useCallback, useState, useRef, useEffect} from 'react';
|
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import copy from 'copy-text-to-clipboard';
|
|
10
10
|
import {translate} from '@docusaurus/Translate';
|
|
11
|
+
import {useCodeBlockContext} from '@docusaurus/theme-common/internal';
|
|
12
|
+
import Button from '@theme/CodeBlock/Buttons/Button';
|
|
11
13
|
import IconCopy from '@theme/Icon/Copy';
|
|
12
14
|
import IconSuccess from '@theme/Icon/Success';
|
|
13
15
|
import styles from './styles.module.css';
|
|
14
|
-
|
|
16
|
+
function title() {
|
|
17
|
+
return translate({
|
|
18
|
+
id: 'theme.CodeBlock.copy',
|
|
19
|
+
message: 'Copy',
|
|
20
|
+
description: 'The copy button label on code blocks',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function ariaLabel(isCopied) {
|
|
24
|
+
return isCopied
|
|
25
|
+
? translate({
|
|
26
|
+
id: 'theme.CodeBlock.copied',
|
|
27
|
+
message: 'Copied',
|
|
28
|
+
description: 'The copied button label on code blocks',
|
|
29
|
+
})
|
|
30
|
+
: translate({
|
|
31
|
+
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
32
|
+
message: 'Copy code to clipboard',
|
|
33
|
+
description: 'The ARIA label for copy code blocks button',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function useCopyButton() {
|
|
37
|
+
const {
|
|
38
|
+
metadata: {code},
|
|
39
|
+
} = useCodeBlockContext();
|
|
15
40
|
const [isCopied, setIsCopied] = useState(false);
|
|
16
41
|
const copyTimeout = useRef(undefined);
|
|
17
|
-
const
|
|
42
|
+
const copyCode = useCallback(() => {
|
|
18
43
|
copy(code);
|
|
19
44
|
setIsCopied(true);
|
|
20
45
|
copyTimeout.current = window.setTimeout(() => {
|
|
@@ -22,38 +47,24 @@ export default function CopyButton({code, className}) {
|
|
|
22
47
|
}, 1000);
|
|
23
48
|
}, [code]);
|
|
24
49
|
useEffect(() => () => window.clearTimeout(copyTimeout.current), []);
|
|
50
|
+
return {copyCode, isCopied};
|
|
51
|
+
}
|
|
52
|
+
export default function CopyButton({className}) {
|
|
53
|
+
const {copyCode, isCopied} = useCopyButton();
|
|
25
54
|
return (
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
isCopied
|
|
30
|
-
? translate({
|
|
31
|
-
id: 'theme.CodeBlock.copied',
|
|
32
|
-
message: 'Copied',
|
|
33
|
-
description: 'The copied button label on code blocks',
|
|
34
|
-
})
|
|
35
|
-
: translate({
|
|
36
|
-
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
37
|
-
message: 'Copy code to clipboard',
|
|
38
|
-
description: 'The ARIA label for copy code blocks button',
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
title={translate({
|
|
42
|
-
id: 'theme.CodeBlock.copy',
|
|
43
|
-
message: 'Copy',
|
|
44
|
-
description: 'The copy button label on code blocks',
|
|
45
|
-
})}
|
|
55
|
+
<Button
|
|
56
|
+
aria-label={ariaLabel(isCopied)}
|
|
57
|
+
title={title()}
|
|
46
58
|
className={clsx(
|
|
47
|
-
'clean-btn',
|
|
48
59
|
className,
|
|
49
60
|
styles.copyButton,
|
|
50
61
|
isCopied && styles.copyButtonCopied,
|
|
51
62
|
)}
|
|
52
|
-
onClick={
|
|
63
|
+
onClick={copyCode}>
|
|
53
64
|
<span className={styles.copyButtonIcons} aria-hidden="true">
|
|
54
65
|
<IconCopy className={styles.copyButtonIcon} />
|
|
55
66
|
<IconSuccess className={styles.copyButtonSuccessIcon} />
|
|
56
67
|
</span>
|
|
57
|
-
</
|
|
68
|
+
</Button>
|
|
58
69
|
);
|
|
59
70
|
}
|
|
@@ -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/CodeBlock/Buttons/WordWrapButton';
|
|
9
|
+
export default function WordWrapButton({ className }: Props): ReactNode;
|
|
@@ -7,9 +7,16 @@
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import {translate} from '@docusaurus/Translate';
|
|
10
|
+
import {useCodeBlockContext} from '@docusaurus/theme-common/internal';
|
|
11
|
+
import Button from '@theme/CodeBlock/Buttons/Button';
|
|
10
12
|
import IconWordWrap from '@theme/Icon/WordWrap';
|
|
11
13
|
import styles from './styles.module.css';
|
|
12
|
-
export default function WordWrapButton({className
|
|
14
|
+
export default function WordWrapButton({className}) {
|
|
15
|
+
const {wordWrap} = useCodeBlockContext();
|
|
16
|
+
const canShowButton = wordWrap.isEnabled || wordWrap.isCodeScrollable;
|
|
17
|
+
if (!canShowButton) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
13
20
|
const title = translate({
|
|
14
21
|
id: 'theme.CodeBlock.wordWrapToggle',
|
|
15
22
|
message: 'Toggle word wrap',
|
|
@@ -17,17 +24,15 @@ export default function WordWrapButton({className, onClick, isEnabled}) {
|
|
|
17
24
|
'The title attribute for toggle word wrapping button of code block lines',
|
|
18
25
|
});
|
|
19
26
|
return (
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
onClick={onClick}
|
|
27
|
+
<Button
|
|
28
|
+
onClick={() => wordWrap.toggle()}
|
|
23
29
|
className={clsx(
|
|
24
|
-
'clean-btn',
|
|
25
30
|
className,
|
|
26
|
-
isEnabled && styles.wordWrapButtonEnabled,
|
|
31
|
+
wordWrap.isEnabled && styles.wordWrapButtonEnabled,
|
|
27
32
|
)}
|
|
28
33
|
aria-label={title}
|
|
29
34
|
title={title}>
|
|
30
35
|
<IconWordWrap className={styles.wordWrapButtonIcon} aria-hidden="true" />
|
|
31
|
-
</
|
|
36
|
+
</Button>
|
|
32
37
|
);
|
|
33
38
|
}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { type ReactNode } from 'react';
|
|
8
|
-
import type { Props } from '@theme/CodeBlock/
|
|
9
|
-
export default function
|
|
8
|
+
import type { Props } from '@theme/CodeBlock/Buttons';
|
|
9
|
+
export default function CodeBlockButtons({ className }: Props): ReactNode;
|
|
@@ -0,0 +1,27 @@
|
|
|
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 React from 'react';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import BrowserOnly from '@docusaurus/BrowserOnly';
|
|
10
|
+
import CopyButton from '@theme/CodeBlock/Buttons/CopyButton';
|
|
11
|
+
import WordWrapButton from '@theme/CodeBlock/Buttons/WordWrapButton';
|
|
12
|
+
import styles from './styles.module.css';
|
|
13
|
+
// Code block buttons are not server-rendered on purpose
|
|
14
|
+
// Adding them to the initial HTML is useless and expensive (due to JSX SVG)
|
|
15
|
+
// They are hidden by default and require React to become interactive
|
|
16
|
+
export default function CodeBlockButtons({className}) {
|
|
17
|
+
return (
|
|
18
|
+
<BrowserOnly>
|
|
19
|
+
{() => (
|
|
20
|
+
<div className={clsx(className, styles.buttonGroup)}>
|
|
21
|
+
<WordWrapButton />
|
|
22
|
+
<CopyButton />
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
</BrowserOnly>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
.buttonGroup {
|
|
9
|
+
display: flex;
|
|
10
|
+
column-gap: 0.2rem;
|
|
11
|
+
position: absolute;
|
|
12
|
+
/* rtl:ignore */
|
|
13
|
+
right: calc(var(--ifm-pre-padding) / 2);
|
|
14
|
+
top: calc(var(--ifm-pre-padding) / 2);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.buttonGroup button {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
background: var(--prism-background-color);
|
|
21
|
+
color: var(--prism-color);
|
|
22
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
23
|
+
border-radius: var(--ifm-global-radius);
|
|
24
|
+
padding: 0.4rem;
|
|
25
|
+
line-height: 0;
|
|
26
|
+
transition: opacity var(--ifm-transition-fast) ease-in-out;
|
|
27
|
+
opacity: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.buttonGroup button:focus-visible,
|
|
31
|
+
.buttonGroup button:hover {
|
|
32
|
+
opacity: 1 !important;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:global(.theme-code-block:hover) .buttonGroup button {
|
|
36
|
+
opacity: 0.4;
|
|
37
|
+
}
|
|
@@ -8,8 +8,10 @@ import React from 'react';
|
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import Container from '@theme/CodeBlock/Container';
|
|
10
10
|
import styles from './styles.module.css';
|
|
11
|
-
//
|
|
12
|
-
//
|
|
11
|
+
// TODO Docusaurus v4: move this component at the root?
|
|
12
|
+
// This component only handles a rare edge-case: <pre><MyComp/></pre> in MDX
|
|
13
|
+
// <pre> tags in markdown map to CodeBlocks. They may contain JSX children.
|
|
14
|
+
// When children is not a simple string, we just return a styled block without
|
|
13
15
|
// actually highlighting.
|
|
14
16
|
export default function CodeBlockJSX({children, className}) {
|
|
15
17
|
return (
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type ReactNode } from 'react';
|
|
8
8
|
import type { Props } from '@theme/CodeBlock/Content/String';
|
|
9
|
-
export default function CodeBlockString(
|
|
9
|
+
export default function CodeBlockString(props: Props): ReactNode;
|
|
@@ -5,115 +5,33 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
import
|
|
9
|
-
import {useThemeConfig, usePrismTheme} from '@docusaurus/theme-common';
|
|
8
|
+
import {useThemeConfig} from '@docusaurus/theme-common';
|
|
10
9
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
parseLines,
|
|
14
|
-
getLineNumbersStart,
|
|
10
|
+
CodeBlockContextProvider,
|
|
11
|
+
createCodeBlockMetadata,
|
|
15
12
|
useCodeWordWrap,
|
|
16
13
|
} from '@docusaurus/theme-common/internal';
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
import CodeBlockLayout from '@theme/CodeBlock/Layout';
|
|
15
|
+
function useCodeBlockMetadata(props) {
|
|
16
|
+
const {prism} = useThemeConfig();
|
|
17
|
+
return createCodeBlockMetadata({
|
|
18
|
+
code: props.children,
|
|
19
|
+
className: props.className,
|
|
20
|
+
metastring: props.metastring,
|
|
21
|
+
magicComments: prism.magicComments,
|
|
22
|
+
defaultLanguage: prism.defaultLanguage,
|
|
23
|
+
language: props.language,
|
|
24
|
+
title: props.title,
|
|
25
|
+
showLineNumbers: props.showLineNumbers,
|
|
26
|
+
});
|
|
29
27
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
metastring,
|
|
34
|
-
title: titleProp,
|
|
35
|
-
showLineNumbers: showLineNumbersProp,
|
|
36
|
-
language: languageProp,
|
|
37
|
-
}) {
|
|
38
|
-
const {
|
|
39
|
-
prism: {defaultLanguage, magicComments},
|
|
40
|
-
} = useThemeConfig();
|
|
41
|
-
const language = normalizeLanguage(
|
|
42
|
-
languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage,
|
|
43
|
-
);
|
|
44
|
-
const prismTheme = usePrismTheme();
|
|
28
|
+
// TODO Docusaurus v4: move this component at the root?
|
|
29
|
+
export default function CodeBlockString(props) {
|
|
30
|
+
const metadata = useCodeBlockMetadata(props);
|
|
45
31
|
const wordWrap = useCodeWordWrap();
|
|
46
|
-
const isBrowser = useIsBrowser();
|
|
47
|
-
// We still parse the metastring in case we want to support more syntax in the
|
|
48
|
-
// future. Note that MDX doesn't strip quotes when parsing metastring:
|
|
49
|
-
// "title=\"xyz\"" => title: "\"xyz\""
|
|
50
|
-
const title = parseCodeBlockTitle(metastring) || titleProp;
|
|
51
|
-
const {lineClassNames, code} = parseLines(children, {
|
|
52
|
-
metastring,
|
|
53
|
-
language,
|
|
54
|
-
magicComments,
|
|
55
|
-
});
|
|
56
|
-
const lineNumbersStart = getLineNumbersStart({
|
|
57
|
-
showLineNumbers: showLineNumbersProp,
|
|
58
|
-
metastring,
|
|
59
|
-
});
|
|
60
32
|
return (
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
blockClassName,
|
|
65
|
-
language &&
|
|
66
|
-
!blockClassName.includes(`language-${language}`) &&
|
|
67
|
-
`language-${language}`,
|
|
68
|
-
)}>
|
|
69
|
-
{title && <div className={styles.codeBlockTitle}>{title}</div>}
|
|
70
|
-
<div className={styles.codeBlockContent}>
|
|
71
|
-
<Highlight theme={prismTheme} code={code} language={language ?? 'text'}>
|
|
72
|
-
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
|
73
|
-
<pre
|
|
74
|
-
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
|
75
|
-
tabIndex={0}
|
|
76
|
-
ref={wordWrap.codeBlockRef}
|
|
77
|
-
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
|
|
78
|
-
style={style}>
|
|
79
|
-
<code
|
|
80
|
-
className={clsx(
|
|
81
|
-
styles.codeBlockLines,
|
|
82
|
-
lineNumbersStart !== undefined &&
|
|
83
|
-
styles.codeBlockLinesWithNumbering,
|
|
84
|
-
)}
|
|
85
|
-
style={
|
|
86
|
-
lineNumbersStart === undefined
|
|
87
|
-
? undefined
|
|
88
|
-
: {counterReset: `line-count ${lineNumbersStart - 1}`}
|
|
89
|
-
}>
|
|
90
|
-
{tokens.map((line, i) => (
|
|
91
|
-
<Line
|
|
92
|
-
key={i}
|
|
93
|
-
line={line}
|
|
94
|
-
getLineProps={getLineProps}
|
|
95
|
-
getTokenProps={getTokenProps}
|
|
96
|
-
classNames={lineClassNames[i]}
|
|
97
|
-
showLineNumbers={lineNumbersStart !== undefined}
|
|
98
|
-
/>
|
|
99
|
-
))}
|
|
100
|
-
</code>
|
|
101
|
-
</pre>
|
|
102
|
-
)}
|
|
103
|
-
</Highlight>
|
|
104
|
-
{isBrowser ? (
|
|
105
|
-
<div className={styles.buttonGroup}>
|
|
106
|
-
{(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
|
|
107
|
-
<WordWrapButton
|
|
108
|
-
className={styles.codeButton}
|
|
109
|
-
onClick={() => wordWrap.toggle()}
|
|
110
|
-
isEnabled={wordWrap.isEnabled}
|
|
111
|
-
/>
|
|
112
|
-
)}
|
|
113
|
-
<CopyButton className={styles.codeButton} code={code} />
|
|
114
|
-
</div>
|
|
115
|
-
) : null}
|
|
116
|
-
</div>
|
|
117
|
-
</Container>
|
|
33
|
+
<CodeBlockContextProvider metadata={metadata} wordWrap={wordWrap}>
|
|
34
|
+
<CodeBlockLayout />
|
|
35
|
+
</CodeBlockContextProvider>
|
|
118
36
|
);
|
|
119
37
|
}
|
|
@@ -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/CodeBlock/Content';
|
|
9
|
+
export default function CodeBlockContent({ className: classNameProp, }: Props): ReactNode;
|
|
@@ -0,0 +1,74 @@
|
|
|
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 React from 'react';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import {useCodeBlockContext} from '@docusaurus/theme-common/internal';
|
|
10
|
+
import {usePrismTheme} from '@docusaurus/theme-common';
|
|
11
|
+
import {Highlight} from 'prism-react-renderer';
|
|
12
|
+
import Line from '@theme/CodeBlock/Line';
|
|
13
|
+
import styles from './styles.module.css';
|
|
14
|
+
// TODO Docusaurus v4: remove useless forwardRef
|
|
15
|
+
const Pre = React.forwardRef((props, ref) => {
|
|
16
|
+
return (
|
|
17
|
+
<pre
|
|
18
|
+
ref={ref}
|
|
19
|
+
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
|
20
|
+
tabIndex={0}
|
|
21
|
+
{...props}
|
|
22
|
+
className={clsx(props.className, styles.codeBlock, 'thin-scrollbar')}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
function Code(props) {
|
|
27
|
+
const {metadata} = useCodeBlockContext();
|
|
28
|
+
return (
|
|
29
|
+
<code
|
|
30
|
+
{...props}
|
|
31
|
+
className={clsx(
|
|
32
|
+
props.className,
|
|
33
|
+
styles.codeBlockLines,
|
|
34
|
+
metadata.lineNumbersStart !== undefined &&
|
|
35
|
+
styles.codeBlockLinesWithNumbering,
|
|
36
|
+
)}
|
|
37
|
+
style={{
|
|
38
|
+
...props.style,
|
|
39
|
+
counterReset:
|
|
40
|
+
metadata.lineNumbersStart === undefined
|
|
41
|
+
? undefined
|
|
42
|
+
: `line-count ${metadata.lineNumbersStart - 1}`,
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
export default function CodeBlockContent({className: classNameProp}) {
|
|
48
|
+
const {metadata, wordWrap} = useCodeBlockContext();
|
|
49
|
+
const prismTheme = usePrismTheme();
|
|
50
|
+
const {code, language, lineNumbersStart, lineClassNames} = metadata;
|
|
51
|
+
return (
|
|
52
|
+
<Highlight theme={prismTheme} code={code} language={language}>
|
|
53
|
+
{({className, style, tokens: lines, getLineProps, getTokenProps}) => (
|
|
54
|
+
<Pre
|
|
55
|
+
ref={wordWrap.codeBlockRef}
|
|
56
|
+
className={clsx(classNameProp, className)}
|
|
57
|
+
style={style}>
|
|
58
|
+
<Code>
|
|
59
|
+
{lines.map((line, i) => (
|
|
60
|
+
<Line
|
|
61
|
+
key={i}
|
|
62
|
+
line={line}
|
|
63
|
+
getLineProps={getLineProps}
|
|
64
|
+
getTokenProps={getTokenProps}
|
|
65
|
+
classNames={lineClassNames[i]}
|
|
66
|
+
showLineNumbers={lineNumbersStart !== undefined}
|
|
67
|
+
/>
|
|
68
|
+
))}
|
|
69
|
+
</Code>
|
|
70
|
+
</Pre>
|
|
71
|
+
)}
|
|
72
|
+
</Highlight>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -5,33 +5,12 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
.codeBlockContent {
|
|
9
|
-
position: relative;
|
|
10
|
-
/* rtl:ignore */
|
|
11
|
-
direction: ltr;
|
|
12
|
-
border-radius: inherit;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.codeBlockTitle {
|
|
16
|
-
border-bottom: 1px solid var(--ifm-color-emphasis-300);
|
|
17
|
-
font-size: var(--ifm-code-font-size);
|
|
18
|
-
font-weight: 500;
|
|
19
|
-
padding: 0.75rem var(--ifm-pre-padding);
|
|
20
|
-
border-top-left-radius: inherit;
|
|
21
|
-
border-top-right-radius: inherit;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
8
|
.codeBlock {
|
|
25
9
|
--ifm-pre-background: var(--prism-background-color);
|
|
26
10
|
margin: 0;
|
|
27
11
|
padding: 0;
|
|
28
12
|
}
|
|
29
13
|
|
|
30
|
-
.codeBlockTitle + .codeBlockContent .codeBlock {
|
|
31
|
-
border-top-left-radius: 0;
|
|
32
|
-
border-top-right-radius: 0;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
14
|
.codeBlockStandalone {
|
|
36
15
|
padding: 0;
|
|
37
16
|
}
|
|
@@ -54,34 +33,3 @@
|
|
|
54
33
|
white-space: pre-wrap;
|
|
55
34
|
}
|
|
56
35
|
}
|
|
57
|
-
|
|
58
|
-
.buttonGroup {
|
|
59
|
-
display: flex;
|
|
60
|
-
column-gap: 0.2rem;
|
|
61
|
-
position: absolute;
|
|
62
|
-
/* rtl:ignore */
|
|
63
|
-
right: calc(var(--ifm-pre-padding) / 2);
|
|
64
|
-
top: calc(var(--ifm-pre-padding) / 2);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.buttonGroup button {
|
|
68
|
-
display: flex;
|
|
69
|
-
align-items: center;
|
|
70
|
-
background: var(--prism-background-color);
|
|
71
|
-
color: var(--prism-color);
|
|
72
|
-
border: 1px solid var(--ifm-color-emphasis-300);
|
|
73
|
-
border-radius: var(--ifm-global-radius);
|
|
74
|
-
padding: 0.4rem;
|
|
75
|
-
line-height: 0;
|
|
76
|
-
transition: opacity var(--ifm-transition-fast) ease-in-out;
|
|
77
|
-
opacity: 0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.buttonGroup button:focus-visible,
|
|
81
|
-
.buttonGroup button:hover {
|
|
82
|
-
opacity: 1 !important;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
:global(.theme-code-block:hover) .buttonGroup button {
|
|
86
|
-
opacity: 0.4;
|
|
87
|
-
}
|
|
@@ -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/CodeBlock/Layout';
|
|
9
|
+
export default function CodeBlockLayout({ className }: Props): ReactNode;
|
|
@@ -0,0 +1,30 @@
|
|
|
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 React from 'react';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import {useCodeBlockContext} from '@docusaurus/theme-common/internal';
|
|
10
|
+
import Container from '@theme/CodeBlock/Container';
|
|
11
|
+
import Title from '@theme/CodeBlock/Title';
|
|
12
|
+
import Content from '@theme/CodeBlock/Content';
|
|
13
|
+
import Buttons from '@theme/CodeBlock/Buttons';
|
|
14
|
+
import styles from './styles.module.css';
|
|
15
|
+
export default function CodeBlockLayout({className}) {
|
|
16
|
+
const {metadata} = useCodeBlockContext();
|
|
17
|
+
return (
|
|
18
|
+
<Container as="div" className={clsx(className, metadata.className)}>
|
|
19
|
+
{metadata.title && (
|
|
20
|
+
<div className={styles.codeBlockTitle}>
|
|
21
|
+
<Title>{metadata.title}</Title>
|
|
22
|
+
</div>
|
|
23
|
+
)}
|
|
24
|
+
<div className={styles.codeBlockContent}>
|
|
25
|
+
<Content />
|
|
26
|
+
<Buttons />
|
|
27
|
+
</div>
|
|
28
|
+
</Container>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
.codeBlockContent {
|
|
9
|
+
position: relative;
|
|
10
|
+
/* rtl:ignore */
|
|
11
|
+
direction: ltr;
|
|
12
|
+
border-radius: inherit;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.codeBlockTitle {
|
|
16
|
+
border-bottom: 1px solid var(--ifm-color-emphasis-300);
|
|
17
|
+
font-size: var(--ifm-code-font-size);
|
|
18
|
+
font-weight: 500;
|
|
19
|
+
padding: 0.75rem var(--ifm-pre-padding);
|
|
20
|
+
border-top-left-radius: inherit;
|
|
21
|
+
border-top-right-radius: inherit;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.codeBlockTitle + .codeBlockContent .codeBlock {
|
|
25
|
+
border-top-left-radius: 0;
|
|
26
|
+
border-top-right-radius: 0;
|
|
27
|
+
}
|
|
@@ -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/CodeBlock/Line/Token';
|
|
9
|
+
export default function CodeBlockLineToken({ line, token, ...props }: Props): ReactNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
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 React from 'react';
|
|
8
|
+
// Pass-through components that users can swizzle and customize
|
|
9
|
+
export default function CodeBlockLineToken({line, token, ...props}) {
|
|
10
|
+
return <span {...props} />;
|
|
11
|
+
}
|