@docusaurus/theme-classic 0.0.0-4865 → 0.0.0-4870

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.
@@ -11,6 +11,10 @@
11
11
  text-transform: uppercase;
12
12
  }
13
13
 
14
+ .admonition h5 code {
15
+ text-transform: none;
16
+ }
17
+
14
18
  .admonition-icon {
15
19
  display: inline-block;
16
20
  vertical-align: middle;
@@ -148,10 +148,10 @@ declare module '@theme/BlogLayout' {
148
148
  }
149
149
 
150
150
  declare module '@theme/CodeBlock' {
151
- import type {ReactElement} from 'react';
151
+ import type {ReactNode} from 'react';
152
152
 
153
153
  export interface Props {
154
- readonly children: string | ReactElement;
154
+ readonly children: ReactNode;
155
155
  readonly className?: string;
156
156
  readonly metastring?: string;
157
157
  readonly title?: string;
@@ -170,6 +170,56 @@ declare module '@theme/CodeBlock/CopyButton' {
170
170
  export default function CopyButton(props: Props): JSX.Element;
171
171
  }
172
172
 
173
+ declare module '@theme/CodeBlock/Container' {
174
+ import type {ComponentProps} from 'react';
175
+
176
+ export default function CodeBlockContainer<T extends 'div' | 'pre'>({
177
+ as: As,
178
+ ...props
179
+ }: {as: T} & ComponentProps<T>): JSX.Element;
180
+ }
181
+
182
+ declare module '@theme/CodeBlock/Content/Element' {
183
+ import type {Props} from '@theme/CodeBlock';
184
+
185
+ export type {Props};
186
+
187
+ export default function CodeBlockElementContent(props: Props): JSX.Element;
188
+ }
189
+
190
+ declare module '@theme/CodeBlock/Content/String' {
191
+ import type {Props as CodeBlockProps} from '@theme/CodeBlock';
192
+
193
+ export interface Props extends Omit<CodeBlockProps, 'children'> {
194
+ readonly children: string;
195
+ }
196
+
197
+ export default function CodeBlockStringContent(props: Props): JSX.Element;
198
+ }
199
+
200
+ declare module '@theme/CodeBlock/Line' {
201
+ import type {ComponentProps} from 'react';
202
+ import type Highlight from 'prism-react-renderer';
203
+
204
+ // Lib does not make this easy
205
+ type RenderProps = Parameters<
206
+ ComponentProps<typeof Highlight>['children']
207
+ >[0];
208
+ type GetLineProps = RenderProps['getLineProps'];
209
+ type GetTokenProps = RenderProps['getTokenProps'];
210
+ type Token = RenderProps['tokens'][number][number];
211
+
212
+ export interface Props {
213
+ readonly line: Token[];
214
+ readonly highlight: boolean;
215
+ readonly showLineNumbers: boolean;
216
+ readonly getLineProps: GetLineProps;
217
+ readonly getTokenProps: GetTokenProps;
218
+ }
219
+
220
+ export default function CodeBlockLine(props: Props): JSX.Element;
221
+ }
222
+
173
223
  declare module '@theme/DocCard' {
174
224
  import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
175
225
 
@@ -6,8 +6,12 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.ThemeConfigSchema = exports.DEFAULT_CONFIG = void 0;
7
7
  exports.validateThemeConfig = validateThemeConfig;
8
8
 
9
+ var _palenight = _interopRequireDefault(require("prism-react-renderer/themes/palenight"));
10
+
9
11
  var _utilsValidation = require("@docusaurus/utils-validation");
10
12
 
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+
11
15
  /**
12
16
  * Copyright (c) Facebook, Inc. and its affiliates.
13
17
  *
@@ -32,7 +36,8 @@ const DEFAULT_CONFIG = {
32
36
  docs: DEFAULT_DOCS_CONFIG,
33
37
  metadata: [],
34
38
  prism: {
35
- additionalLanguages: []
39
+ additionalLanguages: [],
40
+ theme: _palenight.default
36
41
  },
37
42
  navbar: {
38
43
  hideOnScroll: false,
@@ -277,7 +282,7 @@ const ThemeConfigSchema = _utilsValidation.Joi.object({
277
282
  theme: _utilsValidation.Joi.object({
278
283
  plain: _utilsValidation.Joi.alternatives().try(_utilsValidation.Joi.array(), _utilsValidation.Joi.object()).required(),
279
284
  styles: _utilsValidation.Joi.alternatives().try(_utilsValidation.Joi.array(), _utilsValidation.Joi.object()).required()
280
- }),
285
+ }).default(DEFAULT_CONFIG.prism.theme),
281
286
  darkTheme: _utilsValidation.Joi.object({
282
287
  plain: _utilsValidation.Joi.alternatives().try(_utilsValidation.Joi.array(), _utilsValidation.Joi.object()).required(),
283
288
  styles: _utilsValidation.Joi.alternatives().try(_utilsValidation.Joi.array(), _utilsValidation.Joi.object()).required()
@@ -0,0 +1,29 @@
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 {
10
+ usePrismTheme,
11
+ getPrismCssVariables,
12
+ ThemeClassNames,
13
+ } from '@docusaurus/theme-common';
14
+ import styles from './styles.module.css';
15
+ export default function CodeBlockContainer({as: As, ...props}) {
16
+ const prismTheme = usePrismTheme();
17
+ const prismCssVariables = getPrismCssVariables(prismTheme);
18
+ return (
19
+ <As // Polymorphic components are hard to type, without `oneOf` generics
20
+ {...props}
21
+ style={prismCssVariables}
22
+ className={clsx(
23
+ props.className,
24
+ styles.codeBlockContainer,
25
+ ThemeClassNames.common.codeBlock,
26
+ )}
27
+ />
28
+ );
29
+ }
@@ -0,0 +1,14 @@
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
+ .codeBlockContainer {
9
+ background: var(--prism-background-color);
10
+ color: var(--prism-color);
11
+ margin-bottom: var(--ifm-leading);
12
+ box-shadow: var(--ifm-global-shadow-lw);
13
+ border-radius: var(--ifm-code-border-radius);
14
+ }
@@ -0,0 +1,23 @@
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 Container from '@theme/CodeBlock/Container';
9
+ import clsx from 'clsx';
10
+ import styles from './styles.module.css'; // <pre> tags in markdown map to CodeBlocks. They may contain JSX children. When
11
+ // the children is not a simple string, we just return a styled block without
12
+ // actually highlighting.
13
+
14
+ export default function CodeBlockJSX({children, className}) {
15
+ return (
16
+ <Container
17
+ as="pre"
18
+ tabIndex={0}
19
+ className={clsx(styles.codeBlockStandalone, 'thin-scrollbar', className)}>
20
+ <code className={styles.codeBlockLines}>{children}</code>
21
+ </Container>
22
+ );
23
+ }
@@ -0,0 +1,87 @@
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 {
9
+ useThemeConfig,
10
+ parseCodeBlockTitle,
11
+ parseLanguage,
12
+ parseLines,
13
+ containsLineNumbers,
14
+ usePrismTheme,
15
+ } from '@docusaurus/theme-common';
16
+ import clsx from 'clsx';
17
+ import Highlight, {defaultProps} from 'prism-react-renderer';
18
+ import Line from '@theme/CodeBlock/Line';
19
+ import CopyButton from '@theme/CodeBlock/CopyButton';
20
+ import Container from '@theme/CodeBlock/Container';
21
+ import styles from './styles.module.css';
22
+ export default function CodeBlockString({
23
+ children,
24
+ className: blockClassName = '',
25
+ metastring,
26
+ title: titleProp,
27
+ showLineNumbers: showLineNumbersProp,
28
+ language: languageProp,
29
+ }) {
30
+ const {
31
+ prism: {defaultLanguage},
32
+ } = useThemeConfig();
33
+ const language =
34
+ languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage;
35
+ const prismTheme = usePrismTheme(); // We still parse the metastring in case we want to support more syntax in the
36
+ // future. Note that MDX doesn't strip quotes when parsing metastring:
37
+ // "title=\"xyz\"" => title: "\"xyz\""
38
+
39
+ const title = parseCodeBlockTitle(metastring) || titleProp;
40
+ const {highlightLines, code} = parseLines(children, metastring, language);
41
+ const showLineNumbers =
42
+ showLineNumbersProp || containsLineNumbers(metastring);
43
+ return (
44
+ <Container
45
+ as="div"
46
+ className={clsx(
47
+ blockClassName,
48
+ language &&
49
+ !blockClassName.includes(`language-${language}`) &&
50
+ `language-${language}`,
51
+ )}>
52
+ {title && <div className={styles.codeBlockTitle}>{title}</div>}
53
+ <div className={styles.codeBlockContent}>
54
+ <Highlight
55
+ {...defaultProps}
56
+ theme={prismTheme}
57
+ code={code}
58
+ language={language ?? 'text'}>
59
+ {({className, tokens, getLineProps, getTokenProps}) => (
60
+ <pre
61
+ /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
62
+ tabIndex={0}
63
+ className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
64
+ <code
65
+ className={clsx(
66
+ styles.codeBlockLines,
67
+ showLineNumbers && styles.codeBlockLinesWithNumbering,
68
+ )}>
69
+ {tokens.map((line, i) => (
70
+ <Line
71
+ key={i}
72
+ line={line}
73
+ getLineProps={getLineProps}
74
+ getTokenProps={getTokenProps}
75
+ highlight={highlightLines.includes(i)}
76
+ showLineNumbers={showLineNumbers}
77
+ />
78
+ ))}
79
+ </code>
80
+ </pre>
81
+ )}
82
+ </Highlight>
83
+ <CopyButton code={code} />
84
+ </div>
85
+ </Container>
86
+ );
87
+ }
@@ -5,12 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- .codeBlockContainer {
9
- margin-bottom: var(--ifm-leading);
10
- box-shadow: var(--ifm-global-shadow-lw);
11
- border-radius: var(--ifm-code-border-radius);
12
- }
13
-
14
8
  .codeBlockContent {
15
9
  position: relative;
16
10
  /* rtl:ignore */
@@ -28,7 +22,7 @@
28
22
  }
29
23
 
30
24
  .codeBlock {
31
- --ifm-pre-background: inherit;
25
+ --ifm-pre-background: var(--prism-background-color);
32
26
  margin: 0;
33
27
  padding: 0;
34
28
  }
@@ -44,7 +38,6 @@
44
38
 
45
39
  .codeBlockLines {
46
40
  font: inherit;
47
- background: var(--ifm-pre-background);
48
41
  /* rtl:ignore */
49
42
  float: left;
50
43
  min-width: 100%;
@@ -61,31 +54,3 @@
61
54
  white-space: pre-wrap;
62
55
  }
63
56
  }
64
-
65
- .codeLine {
66
- display: table-row;
67
- counter-increment: line-count;
68
- }
69
-
70
- .codeLineNumber {
71
- display: table-cell;
72
- text-align: right;
73
- width: 1%;
74
- position: sticky;
75
- left: 0;
76
- padding: 0 var(--ifm-pre-padding);
77
- background: var(--ifm-pre-background);
78
- }
79
-
80
- .codeLineNumber::before {
81
- content: counter(line-count);
82
- opacity: 0.4;
83
- }
84
-
85
- :global(.docusaurus-highlight-code-line) .codeLineNumber::before {
86
- opacity: 0.8;
87
- }
88
-
89
- .codeLineContent {
90
- padding-right: var(--ifm-pre-padding);
91
- }
@@ -7,7 +7,9 @@
7
7
 
8
8
  .copyButton {
9
9
  display: flex;
10
- background: inherit;
10
+ /* TODO: move to base button styling */
11
+ background: var(--prism-background-color);
12
+ color: var(--prism-color);
11
13
  border: 1px solid var(--ifm-color-emphasis-300);
12
14
  border-radius: var(--ifm-global-radius);
13
15
  padding: 0.4rem;
@@ -0,0 +1,55 @@
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 styles from './styles.module.css';
9
+ export default function CodeBlockLine({
10
+ line,
11
+ highlight,
12
+ showLineNumbers,
13
+ getLineProps,
14
+ getTokenProps,
15
+ }) {
16
+ if (line.length === 1 && line[0].content === '\n') {
17
+ line[0].content = '';
18
+ }
19
+
20
+ const lineProps = getLineProps({
21
+ line,
22
+ ...(showLineNumbers && {
23
+ className: styles.codeLine,
24
+ }),
25
+ });
26
+
27
+ if (highlight) {
28
+ lineProps.className += ' docusaurus-highlight-code-line';
29
+ }
30
+
31
+ const lineTokens = line.map((token, key) => (
32
+ <span
33
+ key={key}
34
+ {...getTokenProps({
35
+ token,
36
+ key,
37
+ })}
38
+ />
39
+ ));
40
+ return (
41
+ <span {...lineProps}>
42
+ {showLineNumbers ? (
43
+ <>
44
+ <span className={styles.codeLineNumber} />
45
+ <span className={styles.codeLineContent}>{lineTokens}</span>
46
+ </>
47
+ ) : (
48
+ <>
49
+ {lineTokens}
50
+ <br />
51
+ </>
52
+ )}
53
+ </span>
54
+ );
55
+ }
@@ -0,0 +1,34 @@
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
+ .codeLine {
9
+ display: table-row;
10
+ counter-increment: line-count;
11
+ }
12
+
13
+ .codeLineNumber {
14
+ display: table-cell;
15
+ text-align: right;
16
+ width: 1%;
17
+ position: sticky;
18
+ left: 0;
19
+ padding: 0 var(--ifm-pre-padding);
20
+ background: var(--ifm-pre-background);
21
+ }
22
+
23
+ .codeLineNumber::before {
24
+ content: counter(line-count);
25
+ opacity: 0.4;
26
+ }
27
+
28
+ :global(.docusaurus-highlight-code-line) .codeLineNumber::before {
29
+ opacity: 0.8;
30
+ }
31
+
32
+ .codeLineContent {
33
+ padding-right: var(--ifm-pre-padding);
34
+ }
@@ -4,166 +4,37 @@
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, {isValidElement, useEffect, useState} from 'react';
8
- import clsx from 'clsx';
9
- import Highlight, {defaultProps} from 'prism-react-renderer';
10
- import {
11
- useThemeConfig,
12
- parseCodeBlockTitle,
13
- parseLanguage,
14
- parseLines,
15
- containsLineNumbers,
16
- ThemeClassNames,
17
- usePrismTheme,
18
- } from '@docusaurus/theme-common';
19
- import CopyButton from '@theme/CodeBlock/CopyButton';
20
- import styles from './styles.module.css';
21
- export default function CodeBlock({
22
- children,
23
- className: blockClassName = '',
24
- metastring,
25
- title,
26
- showLineNumbers,
27
- language: languageProp,
28
- }) {
29
- const {prism} = useThemeConfig();
30
- const [mounted, setMounted] = useState(false); // The Prism theme on SSR is always the default theme but the site theme
31
- // can be in a different mode. React hydration doesn't update DOM styles
32
- // that come from SSR. Hence force a re-render after mounting to apply the
33
- // current relevant styles. There will be a flash seen of the original
34
- // styles seen using this current approach but that's probably ok. Fixing
35
- // the flash will require changing the theming approach and is not worth it
36
- // at this point.
37
-
38
- useEffect(() => {
39
- setMounted(true);
40
- }, []); // We still parse the metastring in case we want to support more syntax in the
41
- // future. Note that MDX doesn't strip quotes when parsing metastring:
42
- // "title=\"xyz\"" => title: "\"xyz\""
43
-
44
- const codeBlockTitle = parseCodeBlockTitle(metastring) || title;
45
- const prismTheme = usePrismTheme(); // <pre> tags in markdown map to CodeBlocks and they may contain JSX children.
46
- // When the children is not a simple string, we just return a styled block
47
- // without actually highlighting.
7
+ import React, {isValidElement} from 'react';
8
+ import useIsBrowser from '@docusaurus/useIsBrowser';
9
+ import ElementContent from '@theme/CodeBlock/Content/Element';
10
+ import StringContent from '@theme/CodeBlock/Content/String';
11
+ /**
12
+ * Best attempt to make the children a plain string so it is copyable. If there
13
+ * are react elements, we will not be able to copy the content, and it will
14
+ * return `children` as-is; otherwise, it concatenates the string children
15
+ * together.
16
+ */
48
17
 
18
+ function maybeStringifyChildren(children) {
49
19
  if (React.Children.toArray(children).some((el) => isValidElement(el))) {
50
- return (
51
- <Highlight
52
- {...defaultProps}
53
- key={String(mounted)}
54
- theme={prismTheme}
55
- code=""
56
- language={'text'}>
57
- {({className, style}) => (
58
- <pre
59
- /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
60
- tabIndex={0}
61
- className={clsx(
62
- className,
63
- styles.codeBlockStandalone,
64
- 'thin-scrollbar',
65
- styles.codeBlockContainer,
66
- blockClassName,
67
- ThemeClassNames.common.codeBlock,
68
- )}
69
- style={style}>
70
- <code className={styles.codeBlockLines}>{children}</code>
71
- </pre>
72
- )}
73
- </Highlight>
74
- );
20
+ return children;
75
21
  } // The children is now guaranteed to be one/more plain strings
76
22
 
77
- const content = Array.isArray(children) ? children.join('') : children;
78
- const language =
79
- languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
80
- const {highlightLines, code} = parseLines(content, metastring, language);
81
- const shouldShowLineNumbers =
82
- showLineNumbers || containsLineNumbers(metastring);
83
- return (
84
- <Highlight
85
- {...defaultProps}
86
- key={String(mounted)}
87
- theme={prismTheme}
88
- code={code}
89
- language={language ?? 'text'}>
90
- {({className, style, tokens, getLineProps, getTokenProps}) => (
91
- <div
92
- className={clsx(
93
- styles.codeBlockContainer,
94
- blockClassName,
95
- {
96
- [`language-${language}`]:
97
- language && !blockClassName.includes(`language-${language}`),
98
- },
99
- ThemeClassNames.common.codeBlock,
100
- )}>
101
- {codeBlockTitle && (
102
- <div style={style} className={styles.codeBlockTitle}>
103
- {codeBlockTitle}
104
- </div>
105
- )}
106
- <div className={styles.codeBlockContent} style={style}>
107
- <pre
108
- /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
109
- tabIndex={0}
110
- className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
111
- <code
112
- className={clsx(
113
- styles.codeBlockLines,
114
- shouldShowLineNumbers && styles.codeBlockLinesWithNumbering,
115
- )}>
116
- {tokens.map((line, i) => {
117
- if (line.length === 1 && line[0].content === '\n') {
118
- line[0].content = '';
119
- }
120
-
121
- const lineProps = getLineProps({
122
- line,
123
- key: i,
124
- ...(shouldShowLineNumbers && {
125
- className: styles.codeLine,
126
- }),
127
- });
128
-
129
- if (highlightLines.includes(i)) {
130
- lineProps.className += ' docusaurus-highlight-code-line';
131
- }
132
-
133
- const lineTokens = line.map((token, key) => (
134
- <span
135
- key={key}
136
- {...getTokenProps({
137
- token,
138
- key,
139
- })}
140
- />
141
- ));
142
- return (
143
- <span key={i} {...lineProps}>
144
- {shouldShowLineNumbers ? (
145
- <>
146
- <span className={styles.codeLineNumber} />
147
- <span className={styles.codeLineContent}>
148
- {lineTokens}
149
- </span>
150
- </>
151
- ) : (
152
- <>
153
- {lineTokens}
154
- <br />
155
- </>
156
- )}
157
- </span>
158
- );
159
- })}
160
- </code>
161
- </pre>
23
+ return Array.isArray(children) ? children.join('') : children;
24
+ }
162
25
 
163
- <CopyButton code={code} />
164
- </div>
165
- </div>
166
- )}
167
- </Highlight>
26
+ export default function CodeBlock({children: rawChildren, ...props}) {
27
+ // The Prism theme on SSR is always the default theme but the site theme can
28
+ // be in a different mode. React hydration doesn't update DOM styles that come
29
+ // from SSR. Hence force a re-render after mounting to apply the current
30
+ // relevant styles.
31
+ const isBrowser = useIsBrowser();
32
+ const children = maybeStringifyChildren(rawChildren);
33
+ const CodeBlockComp =
34
+ typeof children === 'string' ? StringContent : ElementContent;
35
+ return (
36
+ <CodeBlockComp key={String(isBrowser)} {...props}>
37
+ {children}
38
+ </CodeBlockComp>
168
39
  );
169
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/theme-classic",
3
- "version": "0.0.0-4865",
3
+ "version": "0.0.0-4870",
4
4
  "description": "Classic theme for Docusaurus",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/theme-classic.d.ts",
@@ -21,15 +21,15 @@
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-4865",
25
- "@docusaurus/plugin-content-blog": "0.0.0-4865",
26
- "@docusaurus/plugin-content-docs": "0.0.0-4865",
27
- "@docusaurus/plugin-content-pages": "0.0.0-4865",
28
- "@docusaurus/theme-common": "0.0.0-4865",
29
- "@docusaurus/theme-translations": "0.0.0-4865",
30
- "@docusaurus/utils": "0.0.0-4865",
31
- "@docusaurus/utils-common": "0.0.0-4865",
32
- "@docusaurus/utils-validation": "0.0.0-4865",
24
+ "@docusaurus/core": "0.0.0-4870",
25
+ "@docusaurus/plugin-content-blog": "0.0.0-4870",
26
+ "@docusaurus/plugin-content-docs": "0.0.0-4870",
27
+ "@docusaurus/plugin-content-pages": "0.0.0-4870",
28
+ "@docusaurus/theme-common": "0.0.0-4870",
29
+ "@docusaurus/theme-translations": "0.0.0-4870",
30
+ "@docusaurus/utils": "0.0.0-4870",
31
+ "@docusaurus/utils-common": "0.0.0-4870",
32
+ "@docusaurus/utils-validation": "0.0.0-4870",
33
33
  "@mdx-js/react": "^1.6.22",
34
34
  "clsx": "^1.1.1",
35
35
  "copy-text-to-clipboard": "^3.0.1",
@@ -45,8 +45,8 @@
45
45
  "@babel/cli": "^7.17.6",
46
46
  "@babel/core": "^7.17.9",
47
47
  "@babel/preset-typescript": "^7.16.7",
48
- "@docusaurus/module-type-aliases": "0.0.0-4865",
49
- "@docusaurus/types": "0.0.0-4865",
48
+ "@docusaurus/module-type-aliases": "0.0.0-4870",
49
+ "@docusaurus/types": "0.0.0-4870",
50
50
  "@types/mdx-js__react": "^1.5.5",
51
51
  "@types/prismjs": "^1.26.0",
52
52
  "@types/rtlcss": "^3.1.3",
@@ -62,5 +62,5 @@
62
62
  "engines": {
63
63
  "node": ">=14"
64
64
  },
65
- "gitHead": "3bfec620587180f9e7dad2bf2a2713172be65fe7"
65
+ "gitHead": "c5144875378d6edd9690388245488b54d5bf509c"
66
66
  }
@@ -11,6 +11,10 @@
11
11
  text-transform: uppercase;
12
12
  }
13
13
 
14
+ .admonition h5 code {
15
+ text-transform: none;
16
+ }
17
+
14
18
  .admonition-icon {
15
19
  display: inline-block;
16
20
  vertical-align: middle;
@@ -0,0 +1,35 @@
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, {type ComponentProps} from 'react';
9
+ import clsx from 'clsx';
10
+ import {
11
+ usePrismTheme,
12
+ getPrismCssVariables,
13
+ ThemeClassNames,
14
+ } from '@docusaurus/theme-common';
15
+ import styles from './styles.module.css';
16
+
17
+ export default function CodeBlockContainer<T extends 'div' | 'pre'>({
18
+ as: As,
19
+ ...props
20
+ }: {as: T} & ComponentProps<T>): JSX.Element {
21
+ const prismTheme = usePrismTheme();
22
+ const prismCssVariables = getPrismCssVariables(prismTheme);
23
+ return (
24
+ <As
25
+ // Polymorphic components are hard to type, without `oneOf` generics
26
+ {...(props as never)}
27
+ style={prismCssVariables}
28
+ className={clsx(
29
+ props.className,
30
+ styles.codeBlockContainer,
31
+ ThemeClassNames.common.codeBlock,
32
+ )}
33
+ />
34
+ );
35
+ }
@@ -0,0 +1,14 @@
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
+ .codeBlockContainer {
9
+ background: var(--prism-background-color);
10
+ color: var(--prism-color);
11
+ margin-bottom: var(--ifm-leading);
12
+ box-shadow: var(--ifm-global-shadow-lw);
13
+ border-radius: var(--ifm-code-border-radius);
14
+ }
@@ -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
+
8
+ import React from 'react';
9
+ import Container from '@theme/CodeBlock/Container';
10
+ import clsx from 'clsx';
11
+ import type {Props} from '@theme/CodeBlock/Content/Element';
12
+
13
+ import styles from './styles.module.css';
14
+
15
+ // <pre> tags in markdown map to CodeBlocks. They may contain JSX children. When
16
+ // the children is not a simple string, we just return a styled block without
17
+ // actually highlighting.
18
+ export default function CodeBlockJSX({
19
+ children,
20
+ className,
21
+ }: Props): JSX.Element {
22
+ return (
23
+ <Container
24
+ as="pre"
25
+ tabIndex={0}
26
+ className={clsx(styles.codeBlockStandalone, 'thin-scrollbar', className)}>
27
+ <code className={styles.codeBlockLines}>{children}</code>
28
+ </Container>
29
+ );
30
+ }
@@ -0,0 +1,94 @@
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 from 'react';
9
+ import {
10
+ useThemeConfig,
11
+ parseCodeBlockTitle,
12
+ parseLanguage,
13
+ parseLines,
14
+ containsLineNumbers,
15
+ usePrismTheme,
16
+ } from '@docusaurus/theme-common';
17
+ import clsx from 'clsx';
18
+ import Highlight, {defaultProps, type Language} from 'prism-react-renderer';
19
+ import Line from '@theme/CodeBlock/Line';
20
+ import CopyButton from '@theme/CodeBlock/CopyButton';
21
+ import Container from '@theme/CodeBlock/Container';
22
+ import type {Props} from '@theme/CodeBlock/Content/String';
23
+
24
+ import styles from './styles.module.css';
25
+
26
+ export default function CodeBlockString({
27
+ children,
28
+ className: blockClassName = '',
29
+ metastring,
30
+ title: titleProp,
31
+ showLineNumbers: showLineNumbersProp,
32
+ language: languageProp,
33
+ }: Props): JSX.Element {
34
+ const {
35
+ prism: {defaultLanguage},
36
+ } = useThemeConfig();
37
+ const language =
38
+ languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage;
39
+ const prismTheme = usePrismTheme();
40
+
41
+ // We still parse the metastring in case we want to support more syntax in the
42
+ // future. Note that MDX doesn't strip quotes when parsing metastring:
43
+ // "title=\"xyz\"" => title: "\"xyz\""
44
+ const title = parseCodeBlockTitle(metastring) || titleProp;
45
+
46
+ const {highlightLines, code} = parseLines(children, metastring, language);
47
+ const showLineNumbers =
48
+ showLineNumbersProp || containsLineNumbers(metastring);
49
+
50
+ return (
51
+ <Container
52
+ as="div"
53
+ className={clsx(
54
+ blockClassName,
55
+ language &&
56
+ !blockClassName.includes(`language-${language}`) &&
57
+ `language-${language}`,
58
+ )}>
59
+ {title && <div className={styles.codeBlockTitle}>{title}</div>}
60
+ <div className={styles.codeBlockContent}>
61
+ <Highlight
62
+ {...defaultProps}
63
+ theme={prismTheme}
64
+ code={code}
65
+ language={(language ?? 'text') as Language}>
66
+ {({className, tokens, getLineProps, getTokenProps}) => (
67
+ <pre
68
+ /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
69
+ tabIndex={0}
70
+ className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
71
+ <code
72
+ className={clsx(
73
+ styles.codeBlockLines,
74
+ showLineNumbers && styles.codeBlockLinesWithNumbering,
75
+ )}>
76
+ {tokens.map((line, i) => (
77
+ <Line
78
+ key={i}
79
+ line={line}
80
+ getLineProps={getLineProps}
81
+ getTokenProps={getTokenProps}
82
+ highlight={highlightLines.includes(i)}
83
+ showLineNumbers={showLineNumbers}
84
+ />
85
+ ))}
86
+ </code>
87
+ </pre>
88
+ )}
89
+ </Highlight>
90
+ <CopyButton code={code} />
91
+ </div>
92
+ </Container>
93
+ );
94
+ }
@@ -5,12 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- .codeBlockContainer {
9
- margin-bottom: var(--ifm-leading);
10
- box-shadow: var(--ifm-global-shadow-lw);
11
- border-radius: var(--ifm-code-border-radius);
12
- }
13
-
14
8
  .codeBlockContent {
15
9
  position: relative;
16
10
  /* rtl:ignore */
@@ -28,7 +22,7 @@
28
22
  }
29
23
 
30
24
  .codeBlock {
31
- --ifm-pre-background: inherit;
25
+ --ifm-pre-background: var(--prism-background-color);
32
26
  margin: 0;
33
27
  padding: 0;
34
28
  }
@@ -44,7 +38,6 @@
44
38
 
45
39
  .codeBlockLines {
46
40
  font: inherit;
47
- background: var(--ifm-pre-background);
48
41
  /* rtl:ignore */
49
42
  float: left;
50
43
  min-width: 100%;
@@ -61,31 +54,3 @@
61
54
  white-space: pre-wrap;
62
55
  }
63
56
  }
64
-
65
- .codeLine {
66
- display: table-row;
67
- counter-increment: line-count;
68
- }
69
-
70
- .codeLineNumber {
71
- display: table-cell;
72
- text-align: right;
73
- width: 1%;
74
- position: sticky;
75
- left: 0;
76
- padding: 0 var(--ifm-pre-padding);
77
- background: var(--ifm-pre-background);
78
- }
79
-
80
- .codeLineNumber::before {
81
- content: counter(line-count);
82
- opacity: 0.4;
83
- }
84
-
85
- :global(.docusaurus-highlight-code-line) .codeLineNumber::before {
86
- opacity: 0.8;
87
- }
88
-
89
- .codeLineContent {
90
- padding-right: var(--ifm-pre-padding);
91
- }
@@ -7,7 +7,9 @@
7
7
 
8
8
  .copyButton {
9
9
  display: flex;
10
- background: inherit;
10
+ /* TODO: move to base button styling */
11
+ background: var(--prism-background-color);
12
+ color: var(--prism-color);
11
13
  border: 1px solid var(--ifm-color-emphasis-300);
12
14
  border-radius: var(--ifm-global-radius);
13
15
  padding: 0.4rem;
@@ -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 React from 'react';
9
+ import type {Props} from '@theme/CodeBlock/Line';
10
+ import styles from './styles.module.css';
11
+
12
+ export default function CodeBlockLine({
13
+ line,
14
+ highlight,
15
+ showLineNumbers,
16
+ getLineProps,
17
+ getTokenProps,
18
+ }: Props): JSX.Element {
19
+ if (line.length === 1 && line[0]!.content === '\n') {
20
+ line[0]!.content = '';
21
+ }
22
+
23
+ const lineProps = getLineProps({
24
+ line,
25
+ ...(showLineNumbers && {className: styles.codeLine}),
26
+ });
27
+
28
+ if (highlight) {
29
+ lineProps.className += ' docusaurus-highlight-code-line';
30
+ }
31
+
32
+ const lineTokens = line.map((token, key) => (
33
+ <span key={key} {...getTokenProps({token, key})} />
34
+ ));
35
+
36
+ return (
37
+ <span {...lineProps}>
38
+ {showLineNumbers ? (
39
+ <>
40
+ <span className={styles.codeLineNumber} />
41
+ <span className={styles.codeLineContent}>{lineTokens}</span>
42
+ </>
43
+ ) : (
44
+ <>
45
+ {lineTokens}
46
+ <br />
47
+ </>
48
+ )}
49
+ </span>
50
+ );
51
+ }
@@ -0,0 +1,34 @@
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
+ .codeLine {
9
+ display: table-row;
10
+ counter-increment: line-count;
11
+ }
12
+
13
+ .codeLineNumber {
14
+ display: table-cell;
15
+ text-align: right;
16
+ width: 1%;
17
+ position: sticky;
18
+ left: 0;
19
+ padding: 0 var(--ifm-pre-padding);
20
+ background: var(--ifm-pre-background);
21
+ }
22
+
23
+ .codeLineNumber::before {
24
+ content: counter(line-count);
25
+ opacity: 0.4;
26
+ }
27
+
28
+ :global(.docusaurus-highlight-code-line) .codeLineNumber::before {
29
+ opacity: 0.8;
30
+ }
31
+
32
+ .codeLineContent {
33
+ padding-right: var(--ifm-pre-padding);
34
+ }
@@ -5,170 +5,41 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import React, {isValidElement, useEffect, useState} from 'react';
9
- import clsx from 'clsx';
10
- import Highlight, {defaultProps, type Language} from 'prism-react-renderer';
11
- import {
12
- useThemeConfig,
13
- parseCodeBlockTitle,
14
- parseLanguage,
15
- parseLines,
16
- containsLineNumbers,
17
- ThemeClassNames,
18
- usePrismTheme,
19
- } from '@docusaurus/theme-common';
20
- import CopyButton from '@theme/CodeBlock/CopyButton';
8
+ import React, {isValidElement, type ReactNode} from 'react';
9
+ import useIsBrowser from '@docusaurus/useIsBrowser';
21
10
  import type {Props} from '@theme/CodeBlock';
11
+ import ElementContent from '@theme/CodeBlock/Content/Element';
12
+ import StringContent from '@theme/CodeBlock/Content/String';
22
13
 
23
- import styles from './styles.module.css';
24
-
25
- export default function CodeBlock({
26
- children,
27
- className: blockClassName = '',
28
- metastring,
29
- title,
30
- showLineNumbers,
31
- language: languageProp,
32
- }: Props): JSX.Element {
33
- const {prism} = useThemeConfig();
34
-
35
- const [mounted, setMounted] = useState(false);
36
- // The Prism theme on SSR is always the default theme but the site theme
37
- // can be in a different mode. React hydration doesn't update DOM styles
38
- // that come from SSR. Hence force a re-render after mounting to apply the
39
- // current relevant styles. There will be a flash seen of the original
40
- // styles seen using this current approach but that's probably ok. Fixing
41
- // the flash will require changing the theming approach and is not worth it
42
- // at this point.
43
- useEffect(() => {
44
- setMounted(true);
45
- }, []);
46
-
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 codeBlockTitle = parseCodeBlockTitle(metastring) || title;
51
- const prismTheme = usePrismTheme();
52
-
53
- // <pre> tags in markdown map to CodeBlocks and they may contain JSX children.
54
- // When the children is not a simple string, we just return a styled block
55
- // without actually highlighting.
14
+ /**
15
+ * Best attempt to make the children a plain string so it is copyable. If there
16
+ * are react elements, we will not be able to copy the content, and it will
17
+ * return `children` as-is; otherwise, it concatenates the string children
18
+ * together.
19
+ */
20
+ function maybeStringifyChildren(children: ReactNode): ReactNode {
56
21
  if (React.Children.toArray(children).some((el) => isValidElement(el))) {
57
- return (
58
- <Highlight
59
- {...defaultProps}
60
- key={String(mounted)}
61
- theme={prismTheme}
62
- code=""
63
- language={'text' as Language}>
64
- {({className, style}) => (
65
- <pre
66
- /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
67
- tabIndex={0}
68
- className={clsx(
69
- className,
70
- styles.codeBlockStandalone,
71
- 'thin-scrollbar',
72
- styles.codeBlockContainer,
73
- blockClassName,
74
- ThemeClassNames.common.codeBlock,
75
- )}
76
- style={style}>
77
- <code className={styles.codeBlockLines}>{children}</code>
78
- </pre>
79
- )}
80
- </Highlight>
81
- );
22
+ return children;
82
23
  }
83
-
84
24
  // The children is now guaranteed to be one/more plain strings
85
- const content = Array.isArray(children)
86
- ? children.join('')
87
- : (children as string);
88
-
89
- const language =
90
- languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
91
- const {highlightLines, code} = parseLines(content, metastring, language);
92
- const shouldShowLineNumbers =
93
- showLineNumbers || containsLineNumbers(metastring);
25
+ return Array.isArray(children) ? children.join('') : (children as string);
26
+ }
94
27
 
28
+ export default function CodeBlock({
29
+ children: rawChildren,
30
+ ...props
31
+ }: Props): JSX.Element {
32
+ // The Prism theme on SSR is always the default theme but the site theme can
33
+ // be in a different mode. React hydration doesn't update DOM styles that come
34
+ // from SSR. Hence force a re-render after mounting to apply the current
35
+ // relevant styles.
36
+ const isBrowser = useIsBrowser();
37
+ const children = maybeStringifyChildren(rawChildren);
38
+ const CodeBlockComp =
39
+ typeof children === 'string' ? StringContent : ElementContent;
95
40
  return (
96
- <Highlight
97
- {...defaultProps}
98
- key={String(mounted)}
99
- theme={prismTheme}
100
- code={code}
101
- language={(language ?? 'text') as Language}>
102
- {({className, style, tokens, getLineProps, getTokenProps}) => (
103
- <div
104
- className={clsx(
105
- styles.codeBlockContainer,
106
- blockClassName,
107
- {
108
- [`language-${language}`]:
109
- language && !blockClassName.includes(`language-${language}`),
110
- },
111
- ThemeClassNames.common.codeBlock,
112
- )}>
113
- {codeBlockTitle && (
114
- <div style={style} className={styles.codeBlockTitle}>
115
- {codeBlockTitle}
116
- </div>
117
- )}
118
- <div className={styles.codeBlockContent} style={style}>
119
- <pre
120
- /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
121
- tabIndex={0}
122
- className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
123
- <code
124
- className={clsx(
125
- styles.codeBlockLines,
126
- shouldShowLineNumbers && styles.codeBlockLinesWithNumbering,
127
- )}>
128
- {tokens.map((line, i) => {
129
- if (line.length === 1 && line[0]!.content === '\n') {
130
- line[0]!.content = '';
131
- }
132
-
133
- const lineProps = getLineProps({
134
- line,
135
- key: i,
136
- ...(shouldShowLineNumbers && {className: styles.codeLine}),
137
- });
138
-
139
- if (highlightLines.includes(i)) {
140
- lineProps.className += ' docusaurus-highlight-code-line';
141
- }
142
-
143
- const lineTokens = line.map((token, key) => (
144
- <span key={key} {...getTokenProps({token, key})} />
145
- ));
146
-
147
- return (
148
- <span key={i} {...lineProps}>
149
- {shouldShowLineNumbers ? (
150
- <>
151
- <span className={styles.codeLineNumber} />
152
- <span className={styles.codeLineContent}>
153
- {lineTokens}
154
- </span>
155
- </>
156
- ) : (
157
- <>
158
- {lineTokens}
159
- <br />
160
- </>
161
- )}
162
- </span>
163
- );
164
- })}
165
- </code>
166
- </pre>
167
-
168
- <CopyButton code={code} />
169
- </div>
170
- </div>
171
- )}
172
- </Highlight>
41
+ <CodeBlockComp key={String(isBrowser)} {...props}>
42
+ {children as string}
43
+ </CodeBlockComp>
173
44
  );
174
45
  }
@@ -148,10 +148,10 @@ declare module '@theme/BlogLayout' {
148
148
  }
149
149
 
150
150
  declare module '@theme/CodeBlock' {
151
- import type {ReactElement} from 'react';
151
+ import type {ReactNode} from 'react';
152
152
 
153
153
  export interface Props {
154
- readonly children: string | ReactElement;
154
+ readonly children: ReactNode;
155
155
  readonly className?: string;
156
156
  readonly metastring?: string;
157
157
  readonly title?: string;
@@ -170,6 +170,56 @@ declare module '@theme/CodeBlock/CopyButton' {
170
170
  export default function CopyButton(props: Props): JSX.Element;
171
171
  }
172
172
 
173
+ declare module '@theme/CodeBlock/Container' {
174
+ import type {ComponentProps} from 'react';
175
+
176
+ export default function CodeBlockContainer<T extends 'div' | 'pre'>({
177
+ as: As,
178
+ ...props
179
+ }: {as: T} & ComponentProps<T>): JSX.Element;
180
+ }
181
+
182
+ declare module '@theme/CodeBlock/Content/Element' {
183
+ import type {Props} from '@theme/CodeBlock';
184
+
185
+ export type {Props};
186
+
187
+ export default function CodeBlockElementContent(props: Props): JSX.Element;
188
+ }
189
+
190
+ declare module '@theme/CodeBlock/Content/String' {
191
+ import type {Props as CodeBlockProps} from '@theme/CodeBlock';
192
+
193
+ export interface Props extends Omit<CodeBlockProps, 'children'> {
194
+ readonly children: string;
195
+ }
196
+
197
+ export default function CodeBlockStringContent(props: Props): JSX.Element;
198
+ }
199
+
200
+ declare module '@theme/CodeBlock/Line' {
201
+ import type {ComponentProps} from 'react';
202
+ import type Highlight from 'prism-react-renderer';
203
+
204
+ // Lib does not make this easy
205
+ type RenderProps = Parameters<
206
+ ComponentProps<typeof Highlight>['children']
207
+ >[0];
208
+ type GetLineProps = RenderProps['getLineProps'];
209
+ type GetTokenProps = RenderProps['getTokenProps'];
210
+ type Token = RenderProps['tokens'][number][number];
211
+
212
+ export interface Props {
213
+ readonly line: Token[];
214
+ readonly highlight: boolean;
215
+ readonly showLineNumbers: boolean;
216
+ readonly getLineProps: GetLineProps;
217
+ readonly getTokenProps: GetTokenProps;
218
+ }
219
+
220
+ export default function CodeBlockLine(props: Props): JSX.Element;
221
+ }
222
+
173
223
  declare module '@theme/DocCard' {
174
224
  import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
175
225
 
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ import defaultPrismTheme from 'prism-react-renderer/themes/palenight';
8
9
  import {Joi, URISchema} from '@docusaurus/utils-validation';
9
10
  import type {
10
11
  ThemeConfig,
@@ -32,6 +33,7 @@ export const DEFAULT_CONFIG = {
32
33
  metadata: [],
33
34
  prism: {
34
35
  additionalLanguages: [],
36
+ theme: defaultPrismTheme,
35
37
  },
36
38
  navbar: {
37
39
  hideOnScroll: false,
@@ -335,7 +337,7 @@ export const ThemeConfigSchema = Joi.object({
335
337
  theme: Joi.object({
336
338
  plain: Joi.alternatives().try(Joi.array(), Joi.object()).required(),
337
339
  styles: Joi.alternatives().try(Joi.array(), Joi.object()).required(),
338
- }),
340
+ }).default(DEFAULT_CONFIG.prism.theme),
339
341
  darkTheme: Joi.object({
340
342
  plain: Joi.alternatives().try(Joi.array(), Joi.object()).required(),
341
343
  styles: Joi.alternatives().try(Joi.array(), Joi.object()).required(),