@docusaurus/theme-classic 0.0.0-4757 → 0.0.0-4761
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/theme-classic.d.ts +10 -1
- package/lib-next/theme/CodeBlock/CopyButton/index.js +60 -0
- package/lib-next/theme/CodeBlock/CopyButton/styles.module.css +66 -0
- package/lib-next/theme/CodeBlock/index.js +6 -36
- package/lib-next/theme/CodeBlock/styles.module.css +1 -19
- package/lib-next/theme/DocSidebarItem/index.js +2 -1
- package/package.json +14 -14
- package/src/theme/CodeBlock/CopyButton/index.tsx +65 -0
- package/src/theme/CodeBlock/CopyButton/styles.module.css +66 -0
- package/src/theme/CodeBlock/index.tsx +6 -36
- package/src/theme/CodeBlock/styles.module.css +1 -19
- package/src/theme/DocSidebarItem/index.tsx +2 -1
- package/src/theme-classic.d.ts +10 -1
package/lib/theme-classic.d.ts
CHANGED
|
@@ -126,6 +126,14 @@ declare module '@theme/CodeBlock' {
|
|
|
126
126
|
export default function CodeBlock(props: Props): JSX.Element;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
declare module '@theme/CodeBlock/CopyButton' {
|
|
130
|
+
export interface Props {
|
|
131
|
+
readonly code: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export default function CopyButton(props: Props): JSX.Element;
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
declare module '@theme/DocCard' {
|
|
130
138
|
import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
|
|
131
139
|
|
|
@@ -890,7 +898,8 @@ declare module '@theme/TagsListByLetter' {
|
|
|
890
898
|
}
|
|
891
899
|
|
|
892
900
|
declare module '@theme/TagsListInline' {
|
|
893
|
-
|
|
901
|
+
import type {Tag} from '@docusaurus/utils';
|
|
902
|
+
|
|
894
903
|
export interface Props {
|
|
895
904
|
readonly tags: readonly Tag[];
|
|
896
905
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
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, {useState} from 'react';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import copy from 'copy-text-to-clipboard';
|
|
10
|
+
import {translate} from '@docusaurus/Translate';
|
|
11
|
+
import styles from './styles.module.css';
|
|
12
|
+
export default function CopyButton({code}) {
|
|
13
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
14
|
+
|
|
15
|
+
const handleCopyCode = () => {
|
|
16
|
+
copy(code);
|
|
17
|
+
setIsCopied(true);
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
setIsCopied(false);
|
|
20
|
+
}, 2000);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<button
|
|
25
|
+
type="button"
|
|
26
|
+
aria-label={
|
|
27
|
+
isCopied
|
|
28
|
+
? translate({
|
|
29
|
+
id: 'theme.CodeBlock.copied',
|
|
30
|
+
message: 'Copied',
|
|
31
|
+
description: 'The copied button label on code blocks',
|
|
32
|
+
})
|
|
33
|
+
: translate({
|
|
34
|
+
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
35
|
+
message: 'Copy code to clipboard',
|
|
36
|
+
description: 'The ARIA label for copy code blocks button',
|
|
37
|
+
})
|
|
38
|
+
} // @todo: check it again later
|
|
39
|
+
title={translate({
|
|
40
|
+
id: 'theme.CodeBlock.copy',
|
|
41
|
+
message: 'Copy',
|
|
42
|
+
description: 'The copy button label on code blocks',
|
|
43
|
+
})}
|
|
44
|
+
className={clsx(
|
|
45
|
+
styles.copyButton,
|
|
46
|
+
'clean-btn',
|
|
47
|
+
isCopied && styles.copyButtonCopied,
|
|
48
|
+
)}
|
|
49
|
+
onClick={handleCopyCode}>
|
|
50
|
+
<span className={styles.copyButtonIcons} aria-hidden="true">
|
|
51
|
+
<svg className={styles.copyButtonIcon} viewBox="0 0 24 24">
|
|
52
|
+
<path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" />
|
|
53
|
+
</svg>
|
|
54
|
+
<svg className={styles.copyButtonSuccessIcon} viewBox="0 0 24 24">
|
|
55
|
+
<path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
|
|
56
|
+
</svg>
|
|
57
|
+
</span>
|
|
58
|
+
</button>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
.copyButton {
|
|
9
|
+
display: flex;
|
|
10
|
+
background: inherit;
|
|
11
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
12
|
+
border-radius: var(--ifm-global-radius);
|
|
13
|
+
padding: 0.4rem;
|
|
14
|
+
position: absolute;
|
|
15
|
+
right: calc(var(--ifm-pre-padding) / 2);
|
|
16
|
+
top: calc(var(--ifm-pre-padding) / 2);
|
|
17
|
+
transition: opacity 200ms ease-in-out;
|
|
18
|
+
opacity: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.copyButton:focus-visible,
|
|
22
|
+
.copyButton:hover,
|
|
23
|
+
:global(.theme-code-block:hover) .copyButtonCopied {
|
|
24
|
+
opacity: 1 !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:global(.theme-code-block:hover) .copyButton:not(.copyButtonCopied) {
|
|
28
|
+
opacity: 0.4;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.copyButtonIcons {
|
|
32
|
+
position: relative;
|
|
33
|
+
width: 1.125rem;
|
|
34
|
+
height: 1.125rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.copyButtonIcon,
|
|
38
|
+
.copyButtonSuccessIcon {
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: 0;
|
|
41
|
+
left: 0;
|
|
42
|
+
fill: currentColor;
|
|
43
|
+
opacity: inherit;
|
|
44
|
+
width: inherit;
|
|
45
|
+
height: inherit;
|
|
46
|
+
transition: all 0.15s ease;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.copyButtonSuccessIcon {
|
|
50
|
+
top: 50%;
|
|
51
|
+
left: 50%;
|
|
52
|
+
transform: translate(-50%, -50%) scale(0.33);
|
|
53
|
+
opacity: 0;
|
|
54
|
+
color: #00d600;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.copyButtonCopied .copyButtonIcon {
|
|
58
|
+
transform: scale(0.33);
|
|
59
|
+
opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.copyButtonCopied .copyButtonSuccessIcon {
|
|
63
|
+
transform: translate(-50%, -50%) scale(1);
|
|
64
|
+
opacity: 1;
|
|
65
|
+
transition-delay: 0.075s;
|
|
66
|
+
}
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
import React, {isValidElement, useEffect, useState} from 'react';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import Highlight, {defaultProps} from 'prism-react-renderer';
|
|
10
|
-
import copy from 'copy-text-to-clipboard';
|
|
11
|
-
import Translate, {translate} from '@docusaurus/Translate';
|
|
12
10
|
import {
|
|
13
11
|
useThemeConfig,
|
|
14
12
|
parseCodeBlockTitle,
|
|
@@ -17,6 +15,7 @@ import {
|
|
|
17
15
|
ThemeClassNames,
|
|
18
16
|
usePrismTheme,
|
|
19
17
|
} from '@docusaurus/theme-common';
|
|
18
|
+
import CopyButton from '@theme/CodeBlock/CopyButton';
|
|
20
19
|
import styles from './styles.module.css';
|
|
21
20
|
export default function CodeBlock({
|
|
22
21
|
children,
|
|
@@ -26,7 +25,6 @@ export default function CodeBlock({
|
|
|
26
25
|
language: languageProp,
|
|
27
26
|
}) {
|
|
28
27
|
const {prism} = useThemeConfig();
|
|
29
|
-
const [showCopied, setShowCopied] = useState(false);
|
|
30
28
|
const [mounted, setMounted] = useState(false); // The Prism theme on SSR is always the default theme but the site theme
|
|
31
29
|
// can be in a different mode. React hydration doesn't update DOM styles
|
|
32
30
|
// that come from SSR. Hence force a re-render after mounting to apply the
|
|
@@ -78,13 +76,6 @@ export default function CodeBlock({
|
|
|
78
76
|
const language =
|
|
79
77
|
languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
|
|
80
78
|
const {highlightLines, code} = parseLines(content, metastring, language);
|
|
81
|
-
|
|
82
|
-
const handleCopyCode = () => {
|
|
83
|
-
copy(code);
|
|
84
|
-
setShowCopied(true);
|
|
85
|
-
setTimeout(() => setShowCopied(false), 2000);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
79
|
return (
|
|
89
80
|
<Highlight
|
|
90
81
|
{...defaultProps}
|
|
@@ -108,12 +99,13 @@ export default function CodeBlock({
|
|
|
108
99
|
{codeBlockTitle}
|
|
109
100
|
</div>
|
|
110
101
|
)}
|
|
111
|
-
<div
|
|
102
|
+
<div
|
|
103
|
+
className={clsx(styles.codeBlockContent, language)}
|
|
104
|
+
style={style}>
|
|
112
105
|
<pre
|
|
113
106
|
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
|
114
107
|
tabIndex={0}
|
|
115
|
-
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
|
|
116
|
-
style={style}>
|
|
108
|
+
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
|
|
117
109
|
<code className={styles.codeBlockLines}>
|
|
118
110
|
{tokens.map((line, i) => {
|
|
119
111
|
if (line.length === 1 && line[0].content === '\n') {
|
|
@@ -147,29 +139,7 @@ export default function CodeBlock({
|
|
|
147
139
|
</code>
|
|
148
140
|
</pre>
|
|
149
141
|
|
|
150
|
-
<
|
|
151
|
-
type="button"
|
|
152
|
-
aria-label={translate({
|
|
153
|
-
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
154
|
-
message: 'Copy code to clipboard',
|
|
155
|
-
description: 'The ARIA label for copy code blocks button',
|
|
156
|
-
})}
|
|
157
|
-
className={clsx(styles.copyButton, 'clean-btn')}
|
|
158
|
-
onClick={handleCopyCode}>
|
|
159
|
-
{showCopied ? (
|
|
160
|
-
<Translate
|
|
161
|
-
id="theme.CodeBlock.copied"
|
|
162
|
-
description="The copied button label on code blocks">
|
|
163
|
-
Copied
|
|
164
|
-
</Translate>
|
|
165
|
-
) : (
|
|
166
|
-
<Translate
|
|
167
|
-
id="theme.CodeBlock.copy"
|
|
168
|
-
description="The copy button label on code blocks">
|
|
169
|
-
Copy
|
|
170
|
-
</Translate>
|
|
171
|
-
)}
|
|
172
|
-
</button>
|
|
142
|
+
<CopyButton code={code} />
|
|
173
143
|
</div>
|
|
174
144
|
</div>
|
|
175
145
|
)}
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
margin: 0;
|
|
31
31
|
padding: 0;
|
|
32
32
|
border-radius: var(--ifm-global-radius);
|
|
33
|
+
background-color: inherit;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
.codeBlockTitle + .codeBlockContent .codeBlock {
|
|
@@ -42,25 +43,6 @@
|
|
|
42
43
|
border-radius: var(--ifm-global-radius);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
.copyButton {
|
|
46
|
-
background: rgb(0 0 0 / 30%);
|
|
47
|
-
border-radius: var(--ifm-global-radius);
|
|
48
|
-
color: var(--ifm-color-white);
|
|
49
|
-
opacity: 0;
|
|
50
|
-
user-select: none;
|
|
51
|
-
padding: 0.4rem 0.5rem;
|
|
52
|
-
position: absolute;
|
|
53
|
-
right: calc(var(--ifm-pre-padding) / 2);
|
|
54
|
-
top: calc(var(--ifm-pre-padding) / 2);
|
|
55
|
-
transition: opacity 200ms ease-in-out;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.copyButton:focus,
|
|
59
|
-
.codeBlockContent:hover > .copyButton,
|
|
60
|
-
.codeBlockTitle:hover + .codeBlockContent .copyButton {
|
|
61
|
-
opacity: 1;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
46
|
.codeBlockLines {
|
|
65
47
|
font: inherit;
|
|
66
48
|
/* rtl:ignore */
|
|
@@ -143,7 +143,8 @@ function DocSidebarItemCategory({
|
|
|
143
143
|
})}>
|
|
144
144
|
<Link
|
|
145
145
|
className={clsx('menu__link', {
|
|
146
|
-
'menu__link--sublist': collapsible
|
|
146
|
+
'menu__link--sublist': collapsible,
|
|
147
|
+
'menu__link--sublist-caret': !href,
|
|
147
148
|
'menu__link--active': isActive,
|
|
148
149
|
})}
|
|
149
150
|
onClick={
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/theme-classic",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-4761",
|
|
4
4
|
"description": "Classic theme for Docusaurus",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/theme-classic.d.ts",
|
|
@@ -21,19 +21,19 @@
|
|
|
21
21
|
"format:lib-next": "prettier --config ../../.prettierrc --write \"lib-next/**/*.{js,ts,jsx,tsc}\""
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@docusaurus/core": "0.0.0-
|
|
25
|
-
"@docusaurus/plugin-content-blog": "0.0.0-
|
|
26
|
-
"@docusaurus/plugin-content-docs": "0.0.0-
|
|
27
|
-
"@docusaurus/plugin-content-pages": "0.0.0-
|
|
28
|
-
"@docusaurus/theme-common": "0.0.0-
|
|
29
|
-
"@docusaurus/theme-translations": "0.0.0-
|
|
30
|
-
"@docusaurus/utils": "0.0.0-
|
|
31
|
-
"@docusaurus/utils-common": "0.0.0-
|
|
32
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
24
|
+
"@docusaurus/core": "0.0.0-4761",
|
|
25
|
+
"@docusaurus/plugin-content-blog": "0.0.0-4761",
|
|
26
|
+
"@docusaurus/plugin-content-docs": "0.0.0-4761",
|
|
27
|
+
"@docusaurus/plugin-content-pages": "0.0.0-4761",
|
|
28
|
+
"@docusaurus/theme-common": "0.0.0-4761",
|
|
29
|
+
"@docusaurus/theme-translations": "0.0.0-4761",
|
|
30
|
+
"@docusaurus/utils": "0.0.0-4761",
|
|
31
|
+
"@docusaurus/utils-common": "0.0.0-4761",
|
|
32
|
+
"@docusaurus/utils-validation": "0.0.0-4761",
|
|
33
33
|
"@mdx-js/react": "^1.6.22",
|
|
34
34
|
"clsx": "^1.1.1",
|
|
35
35
|
"copy-text-to-clipboard": "^3.0.1",
|
|
36
|
-
"infima": "0.2.0-alpha.
|
|
36
|
+
"infima": "0.2.0-alpha.38",
|
|
37
37
|
"lodash": "^4.17.21",
|
|
38
38
|
"postcss": "^8.4.12",
|
|
39
39
|
"prism-react-renderer": "^1.3.1",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"rtlcss": "^3.5.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@docusaurus/module-type-aliases": "0.0.0-
|
|
46
|
-
"@docusaurus/types": "0.0.0-
|
|
45
|
+
"@docusaurus/module-type-aliases": "0.0.0-4761",
|
|
46
|
+
"@docusaurus/types": "0.0.0-4761",
|
|
47
47
|
"@types/mdx-js__react": "^1.5.5",
|
|
48
48
|
"@types/prismjs": "^1.26.0",
|
|
49
49
|
"@types/rtlcss": "^3.1.2",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"engines": {
|
|
60
60
|
"node": ">=14"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "5c8d0e164bf0b441f889420e235dda42f922d01e"
|
|
63
63
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
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 React, {useState} from 'react';
|
|
9
|
+
import clsx from 'clsx';
|
|
10
|
+
import copy from 'copy-text-to-clipboard';
|
|
11
|
+
import {translate} from '@docusaurus/Translate';
|
|
12
|
+
import type {Props} from '@theme/CodeBlock/CopyButton';
|
|
13
|
+
|
|
14
|
+
import styles from './styles.module.css';
|
|
15
|
+
|
|
16
|
+
export default function CopyButton({code}: Props): JSX.Element {
|
|
17
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
18
|
+
const handleCopyCode = () => {
|
|
19
|
+
copy(code);
|
|
20
|
+
setIsCopied(true);
|
|
21
|
+
|
|
22
|
+
setTimeout(() => {
|
|
23
|
+
setIsCopied(false);
|
|
24
|
+
}, 2000);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<button
|
|
29
|
+
type="button"
|
|
30
|
+
aria-label={
|
|
31
|
+
isCopied
|
|
32
|
+
? translate({
|
|
33
|
+
id: 'theme.CodeBlock.copied',
|
|
34
|
+
message: 'Copied',
|
|
35
|
+
description: 'The copied button label on code blocks',
|
|
36
|
+
})
|
|
37
|
+
: translate({
|
|
38
|
+
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
39
|
+
message: 'Copy code to clipboard',
|
|
40
|
+
description: 'The ARIA label for copy code blocks button',
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
// @todo: check it again later
|
|
44
|
+
title={translate({
|
|
45
|
+
id: 'theme.CodeBlock.copy',
|
|
46
|
+
message: 'Copy',
|
|
47
|
+
description: 'The copy button label on code blocks',
|
|
48
|
+
})}
|
|
49
|
+
className={clsx(
|
|
50
|
+
styles.copyButton,
|
|
51
|
+
'clean-btn',
|
|
52
|
+
isCopied && styles.copyButtonCopied,
|
|
53
|
+
)}
|
|
54
|
+
onClick={handleCopyCode}>
|
|
55
|
+
<span className={styles.copyButtonIcons} aria-hidden="true">
|
|
56
|
+
<svg className={styles.copyButtonIcon} viewBox="0 0 24 24">
|
|
57
|
+
<path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" />
|
|
58
|
+
</svg>
|
|
59
|
+
<svg className={styles.copyButtonSuccessIcon} viewBox="0 0 24 24">
|
|
60
|
+
<path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
|
|
61
|
+
</svg>
|
|
62
|
+
</span>
|
|
63
|
+
</button>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
.copyButton {
|
|
9
|
+
display: flex;
|
|
10
|
+
background: inherit;
|
|
11
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
12
|
+
border-radius: var(--ifm-global-radius);
|
|
13
|
+
padding: 0.4rem;
|
|
14
|
+
position: absolute;
|
|
15
|
+
right: calc(var(--ifm-pre-padding) / 2);
|
|
16
|
+
top: calc(var(--ifm-pre-padding) / 2);
|
|
17
|
+
transition: opacity 200ms ease-in-out;
|
|
18
|
+
opacity: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.copyButton:focus-visible,
|
|
22
|
+
.copyButton:hover,
|
|
23
|
+
:global(.theme-code-block:hover) .copyButtonCopied {
|
|
24
|
+
opacity: 1 !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:global(.theme-code-block:hover) .copyButton:not(.copyButtonCopied) {
|
|
28
|
+
opacity: 0.4;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.copyButtonIcons {
|
|
32
|
+
position: relative;
|
|
33
|
+
width: 1.125rem;
|
|
34
|
+
height: 1.125rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.copyButtonIcon,
|
|
38
|
+
.copyButtonSuccessIcon {
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: 0;
|
|
41
|
+
left: 0;
|
|
42
|
+
fill: currentColor;
|
|
43
|
+
opacity: inherit;
|
|
44
|
+
width: inherit;
|
|
45
|
+
height: inherit;
|
|
46
|
+
transition: all 0.15s ease;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.copyButtonSuccessIcon {
|
|
50
|
+
top: 50%;
|
|
51
|
+
left: 50%;
|
|
52
|
+
transform: translate(-50%, -50%) scale(0.33);
|
|
53
|
+
opacity: 0;
|
|
54
|
+
color: #00d600;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.copyButtonCopied .copyButtonIcon {
|
|
58
|
+
transform: scale(0.33);
|
|
59
|
+
opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.copyButtonCopied .copyButtonSuccessIcon {
|
|
63
|
+
transform: translate(-50%, -50%) scale(1);
|
|
64
|
+
opacity: 1;
|
|
65
|
+
transition-delay: 0.075s;
|
|
66
|
+
}
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
import React, {isValidElement, useEffect, useState} from 'react';
|
|
9
9
|
import clsx from 'clsx';
|
|
10
10
|
import Highlight, {defaultProps, type Language} from 'prism-react-renderer';
|
|
11
|
-
import copy from 'copy-text-to-clipboard';
|
|
12
|
-
import Translate, {translate} from '@docusaurus/Translate';
|
|
13
11
|
import {
|
|
14
12
|
useThemeConfig,
|
|
15
13
|
parseCodeBlockTitle,
|
|
@@ -18,6 +16,7 @@ import {
|
|
|
18
16
|
ThemeClassNames,
|
|
19
17
|
usePrismTheme,
|
|
20
18
|
} from '@docusaurus/theme-common';
|
|
19
|
+
import CopyButton from '@theme/CodeBlock/CopyButton';
|
|
21
20
|
import type {Props} from '@theme/CodeBlock';
|
|
22
21
|
|
|
23
22
|
import styles from './styles.module.css';
|
|
@@ -31,7 +30,6 @@ export default function CodeBlock({
|
|
|
31
30
|
}: Props): JSX.Element {
|
|
32
31
|
const {prism} = useThemeConfig();
|
|
33
32
|
|
|
34
|
-
const [showCopied, setShowCopied] = useState(false);
|
|
35
33
|
const [mounted, setMounted] = useState(false);
|
|
36
34
|
// The Prism theme on SSR is always the default theme but the site theme
|
|
37
35
|
// can be in a different mode. React hydration doesn't update DOM styles
|
|
@@ -90,13 +88,6 @@ export default function CodeBlock({
|
|
|
90
88
|
languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
|
|
91
89
|
const {highlightLines, code} = parseLines(content, metastring, language);
|
|
92
90
|
|
|
93
|
-
const handleCopyCode = () => {
|
|
94
|
-
copy(code);
|
|
95
|
-
setShowCopied(true);
|
|
96
|
-
|
|
97
|
-
setTimeout(() => setShowCopied(false), 2000);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
91
|
return (
|
|
101
92
|
<Highlight
|
|
102
93
|
{...defaultProps}
|
|
@@ -120,12 +111,13 @@ export default function CodeBlock({
|
|
|
120
111
|
{codeBlockTitle}
|
|
121
112
|
</div>
|
|
122
113
|
)}
|
|
123
|
-
<div
|
|
114
|
+
<div
|
|
115
|
+
className={clsx(styles.codeBlockContent, language)}
|
|
116
|
+
style={style}>
|
|
124
117
|
<pre
|
|
125
118
|
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
|
126
119
|
tabIndex={0}
|
|
127
|
-
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
|
|
128
|
-
style={style}>
|
|
120
|
+
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
|
|
129
121
|
<code className={styles.codeBlockLines}>
|
|
130
122
|
{tokens.map((line, i) => {
|
|
131
123
|
if (line.length === 1 && line[0]!.content === '\n') {
|
|
@@ -150,29 +142,7 @@ export default function CodeBlock({
|
|
|
150
142
|
</code>
|
|
151
143
|
</pre>
|
|
152
144
|
|
|
153
|
-
<
|
|
154
|
-
type="button"
|
|
155
|
-
aria-label={translate({
|
|
156
|
-
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
157
|
-
message: 'Copy code to clipboard',
|
|
158
|
-
description: 'The ARIA label for copy code blocks button',
|
|
159
|
-
})}
|
|
160
|
-
className={clsx(styles.copyButton, 'clean-btn')}
|
|
161
|
-
onClick={handleCopyCode}>
|
|
162
|
-
{showCopied ? (
|
|
163
|
-
<Translate
|
|
164
|
-
id="theme.CodeBlock.copied"
|
|
165
|
-
description="The copied button label on code blocks">
|
|
166
|
-
Copied
|
|
167
|
-
</Translate>
|
|
168
|
-
) : (
|
|
169
|
-
<Translate
|
|
170
|
-
id="theme.CodeBlock.copy"
|
|
171
|
-
description="The copy button label on code blocks">
|
|
172
|
-
Copy
|
|
173
|
-
</Translate>
|
|
174
|
-
)}
|
|
175
|
-
</button>
|
|
145
|
+
<CopyButton code={code} />
|
|
176
146
|
</div>
|
|
177
147
|
</div>
|
|
178
148
|
)}
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
margin: 0;
|
|
31
31
|
padding: 0;
|
|
32
32
|
border-radius: var(--ifm-global-radius);
|
|
33
|
+
background-color: inherit;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
.codeBlockTitle + .codeBlockContent .codeBlock {
|
|
@@ -42,25 +43,6 @@
|
|
|
42
43
|
border-radius: var(--ifm-global-radius);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
.copyButton {
|
|
46
|
-
background: rgb(0 0 0 / 30%);
|
|
47
|
-
border-radius: var(--ifm-global-radius);
|
|
48
|
-
color: var(--ifm-color-white);
|
|
49
|
-
opacity: 0;
|
|
50
|
-
user-select: none;
|
|
51
|
-
padding: 0.4rem 0.5rem;
|
|
52
|
-
position: absolute;
|
|
53
|
-
right: calc(var(--ifm-pre-padding) / 2);
|
|
54
|
-
top: calc(var(--ifm-pre-padding) / 2);
|
|
55
|
-
transition: opacity 200ms ease-in-out;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.copyButton:focus,
|
|
59
|
-
.codeBlockContent:hover > .copyButton,
|
|
60
|
-
.codeBlockTitle:hover + .codeBlockContent .copyButton {
|
|
61
|
-
opacity: 1;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
46
|
.codeBlockLines {
|
|
65
47
|
font: inherit;
|
|
66
48
|
/* rtl:ignore */
|
|
@@ -160,7 +160,8 @@ function DocSidebarItemCategory({
|
|
|
160
160
|
})}>
|
|
161
161
|
<Link
|
|
162
162
|
className={clsx('menu__link', {
|
|
163
|
-
'menu__link--sublist': collapsible
|
|
163
|
+
'menu__link--sublist': collapsible,
|
|
164
|
+
'menu__link--sublist-caret': !href,
|
|
164
165
|
'menu__link--active': isActive,
|
|
165
166
|
})}
|
|
166
167
|
onClick={
|
package/src/theme-classic.d.ts
CHANGED
|
@@ -126,6 +126,14 @@ declare module '@theme/CodeBlock' {
|
|
|
126
126
|
export default function CodeBlock(props: Props): JSX.Element;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
declare module '@theme/CodeBlock/CopyButton' {
|
|
130
|
+
export interface Props {
|
|
131
|
+
readonly code: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export default function CopyButton(props: Props): JSX.Element;
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
declare module '@theme/DocCard' {
|
|
130
138
|
import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
|
|
131
139
|
|
|
@@ -890,7 +898,8 @@ declare module '@theme/TagsListByLetter' {
|
|
|
890
898
|
}
|
|
891
899
|
|
|
892
900
|
declare module '@theme/TagsListInline' {
|
|
893
|
-
|
|
901
|
+
import type {Tag} from '@docusaurus/utils';
|
|
902
|
+
|
|
894
903
|
export interface Props {
|
|
895
904
|
readonly tags: readonly Tag[];
|
|
896
905
|
}
|