@docusaurus/theme-classic 3.7.0-canary-6274 → 3.7.0-canary-6275

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.
@@ -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({ children, className: blockClassName, metastring, title: titleProp, showLineNumbers: showLineNumbersProp, language: languageProp, }: Props): ReactNode;
9
+ export default function CodeBlockString(props: Props): ReactNode;
@@ -8,11 +8,8 @@ import React from 'react';
8
8
  import clsx from 'clsx';
9
9
  import {useThemeConfig, usePrismTheme} from '@docusaurus/theme-common';
10
10
  import {
11
- parseCodeBlockTitle,
12
- parseLanguage,
13
- parseLines,
14
- getLineNumbersStart,
15
11
  useCodeWordWrap,
12
+ createCodeBlockMetadata,
16
13
  } from '@docusaurus/theme-common/internal';
17
14
  import useIsBrowser from '@docusaurus/useIsBrowser';
18
15
  import {Highlight} from 'prism-react-renderer';
@@ -21,99 +18,113 @@ import CopyButton from '@theme/CodeBlock/CopyButton';
21
18
  import WordWrapButton from '@theme/CodeBlock/WordWrapButton';
22
19
  import Container from '@theme/CodeBlock/Container';
23
20
  import styles from './styles.module.css';
24
- // Prism languages are always lowercase
25
- // We want to fail-safe and allow both "php" and "PHP"
26
- // See https://github.com/facebook/docusaurus/issues/9012
27
- function normalizeLanguage(language) {
28
- return language?.toLowerCase();
21
+ function CodeBlockTitle({children}) {
22
+ // Just a pass-through for now
23
+ return children;
29
24
  }
30
- export default function CodeBlockString({
31
- children,
32
- className: blockClassName = '',
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,
25
+ // TODO Docusaurus v4: remove useless forwardRef
26
+ const Pre = React.forwardRef((props, ref) => {
27
+ return (
28
+ <pre
29
+ ref={ref}
30
+ /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
31
+ tabIndex={0}
32
+ {...props}
33
+ className={clsx(props.className, styles.codeBlock, 'thin-scrollbar')}
34
+ />
35
+ );
36
+ });
37
+ function Code({metadata, ...props}) {
38
+ return (
39
+ <code
40
+ {...props}
41
+ className={clsx(
42
+ props.className,
43
+ styles.codeBlockLines,
44
+ metadata.lineNumbersStart !== undefined &&
45
+ styles.codeBlockLinesWithNumbering,
46
+ )}
47
+ style={{
48
+ ...props.style,
49
+ counterReset:
50
+ metadata.lineNumbersStart === undefined
51
+ ? undefined
52
+ : `line-count ${metadata.lineNumbersStart - 1}`,
53
+ }}
54
+ />
43
55
  );
56
+ }
57
+ function CodeBlockContent({metadata, wordWrap}) {
44
58
  const prismTheme = usePrismTheme();
45
- const wordWrap = useCodeWordWrap();
59
+ const {code, language, lineNumbersStart, lineClassNames} = metadata;
60
+ return (
61
+ <Highlight theme={prismTheme} code={code} language={language}>
62
+ {({className, style, tokens: lines, getLineProps, getTokenProps}) => (
63
+ <Pre ref={wordWrap.codeBlockRef} className={className} style={style}>
64
+ <Code metadata={metadata}>
65
+ {lines.map((line, i) => (
66
+ <Line
67
+ key={i}
68
+ line={line}
69
+ getLineProps={getLineProps}
70
+ getTokenProps={getTokenProps}
71
+ classNames={lineClassNames[i]}
72
+ showLineNumbers={lineNumbersStart !== undefined}
73
+ />
74
+ ))}
75
+ </Code>
76
+ </Pre>
77
+ )}
78
+ </Highlight>
79
+ );
80
+ }
81
+ function CodeBlockButtons({metadata, wordWrap}) {
82
+ return (
83
+ <div className={styles.buttonGroup}>
84
+ {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
85
+ <WordWrapButton
86
+ className={styles.codeButton}
87
+ onClick={() => wordWrap.toggle()}
88
+ isEnabled={wordWrap.isEnabled}
89
+ />
90
+ )}
91
+ <CopyButton className={styles.codeButton} code={metadata.code} />
92
+ </div>
93
+ );
94
+ }
95
+ function CodeBlockLayout({metadata}) {
46
96
  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
- });
97
+ const wordWrap = useCodeWordWrap();
60
98
  return (
61
- <Container
62
- as="div"
63
- className={clsx(
64
- blockClassName,
65
- language &&
66
- !blockClassName.includes(`language-${language}`) &&
67
- `language-${language}`,
68
- )}>
69
- {title && <div className={styles.codeBlockTitle}>{title}</div>}
99
+ <Container as="div" className={metadata.className}>
100
+ {metadata.title && (
101
+ <div className={styles.codeBlockTitle}>
102
+ <CodeBlockTitle>{metadata.title}</CodeBlockTitle>
103
+ </div>
104
+ )}
70
105
  <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}
106
+ <CodeBlockContent metadata={metadata} wordWrap={wordWrap} />
107
+ {isBrowser && (
108
+ <CodeBlockButtons metadata={metadata} wordWrap={wordWrap} />
109
+ )}
116
110
  </div>
117
111
  </Container>
118
112
  );
119
113
  }
114
+ function useCodeBlockMetadata(props) {
115
+ const {prism} = useThemeConfig();
116
+ return createCodeBlockMetadata({
117
+ code: props.children,
118
+ className: props.className,
119
+ metastring: props.metastring,
120
+ magicComments: prism.magicComments,
121
+ defaultLanguage: prism.defaultLanguage,
122
+ language: props.language,
123
+ title: props.title,
124
+ showLineNumbers: props.showLineNumbers,
125
+ });
126
+ }
127
+ export default function CodeBlockString(props) {
128
+ const metadata = useCodeBlockMetadata(props);
129
+ return <CodeBlockLayout metadata={metadata} />;
130
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/theme-classic",
3
- "version": "3.7.0-canary-6274",
3
+ "version": "3.7.0-canary-6275",
4
4
  "description": "Classic theme for Docusaurus",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/theme-classic.d.ts",
@@ -20,19 +20,19 @@
20
20
  "copy:watch": "node ../../admin/scripts/copyUntypedFiles.js --watch"
21
21
  },
22
22
  "dependencies": {
23
- "@docusaurus/core": "3.7.0-canary-6274",
24
- "@docusaurus/logger": "3.7.0-canary-6274",
25
- "@docusaurus/mdx-loader": "3.7.0-canary-6274",
26
- "@docusaurus/module-type-aliases": "3.7.0-canary-6274",
27
- "@docusaurus/plugin-content-blog": "3.7.0-canary-6274",
28
- "@docusaurus/plugin-content-docs": "3.7.0-canary-6274",
29
- "@docusaurus/plugin-content-pages": "3.7.0-canary-6274",
30
- "@docusaurus/theme-common": "3.7.0-canary-6274",
31
- "@docusaurus/theme-translations": "3.7.0-canary-6274",
32
- "@docusaurus/types": "3.7.0-canary-6274",
33
- "@docusaurus/utils": "3.7.0-canary-6274",
34
- "@docusaurus/utils-common": "3.7.0-canary-6274",
35
- "@docusaurus/utils-validation": "3.7.0-canary-6274",
23
+ "@docusaurus/core": "3.7.0-canary-6275",
24
+ "@docusaurus/logger": "3.7.0-canary-6275",
25
+ "@docusaurus/mdx-loader": "3.7.0-canary-6275",
26
+ "@docusaurus/module-type-aliases": "3.7.0-canary-6275",
27
+ "@docusaurus/plugin-content-blog": "3.7.0-canary-6275",
28
+ "@docusaurus/plugin-content-docs": "3.7.0-canary-6275",
29
+ "@docusaurus/plugin-content-pages": "3.7.0-canary-6275",
30
+ "@docusaurus/theme-common": "3.7.0-canary-6275",
31
+ "@docusaurus/theme-translations": "3.7.0-canary-6275",
32
+ "@docusaurus/types": "3.7.0-canary-6275",
33
+ "@docusaurus/utils": "3.7.0-canary-6275",
34
+ "@docusaurus/utils-common": "3.7.0-canary-6275",
35
+ "@docusaurus/utils-validation": "3.7.0-canary-6275",
36
36
  "@mdx-js/react": "^3.0.0",
37
37
  "clsx": "^2.0.0",
38
38
  "copy-text-to-clipboard": "^3.2.0",
@@ -62,5 +62,5 @@
62
62
  "engines": {
63
63
  "node": ">=18.0"
64
64
  },
65
- "gitHead": "c46c12c65ae718bb6352556f7e34e5adfd629856"
65
+ "gitHead": "2066932804271ce5f501655ad7fb6525186aa72d"
66
66
  }
@@ -5,18 +5,16 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import React, {type ReactNode} from 'react';
8
+ import React, {type ComponentProps, type ReactNode} from 'react';
9
9
  import clsx from 'clsx';
10
10
  import {useThemeConfig, usePrismTheme} from '@docusaurus/theme-common';
11
11
  import {
12
- parseCodeBlockTitle,
13
- parseLanguage,
14
- parseLines,
15
- getLineNumbersStart,
16
12
  useCodeWordWrap,
13
+ createCodeBlockMetadata,
14
+ type CodeBlockMetadata,
17
15
  } from '@docusaurus/theme-common/internal';
18
16
  import useIsBrowser from '@docusaurus/useIsBrowser';
19
- import {Highlight, type Language} from 'prism-react-renderer';
17
+ import {Highlight} from 'prism-react-renderer';
20
18
  import Line from '@theme/CodeBlock/Line';
21
19
  import CopyButton from '@theme/CodeBlock/CopyButton';
22
20
  import WordWrapButton from '@theme/CodeBlock/WordWrapButton';
@@ -25,107 +23,139 @@ import type {Props} from '@theme/CodeBlock/Content/String';
25
23
 
26
24
  import styles from './styles.module.css';
27
25
 
28
- // Prism languages are always lowercase
29
- // We want to fail-safe and allow both "php" and "PHP"
30
- // See https://github.com/facebook/docusaurus/issues/9012
31
- function normalizeLanguage(language: string | undefined): string | undefined {
32
- return language?.toLowerCase();
26
+ type WordWrap = ReturnType<typeof useCodeWordWrap>;
27
+
28
+ function CodeBlockTitle({children}: {children: ReactNode}): ReactNode {
29
+ // Just a pass-through for now
30
+ return children;
33
31
  }
34
32
 
35
- export default function CodeBlockString({
36
- children,
37
- className: blockClassName = '',
38
- metastring,
39
- title: titleProp,
40
- showLineNumbers: showLineNumbersProp,
41
- language: languageProp,
42
- }: Props): ReactNode {
43
- const {
44
- prism: {defaultLanguage, magicComments},
45
- } = useThemeConfig();
46
- const language = normalizeLanguage(
47
- languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage,
33
+ // TODO Docusaurus v4: remove useless forwardRef
34
+ const Pre = React.forwardRef<HTMLPreElement, ComponentProps<'pre'>>(
35
+ (props, ref) => {
36
+ return (
37
+ <pre
38
+ ref={ref}
39
+ /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
40
+ tabIndex={0}
41
+ {...props}
42
+ className={clsx(props.className, styles.codeBlock, 'thin-scrollbar')}
43
+ />
44
+ );
45
+ },
46
+ );
47
+
48
+ function Code({
49
+ metadata,
50
+ ...props
51
+ }: {metadata: CodeBlockMetadata} & ComponentProps<'code'>) {
52
+ return (
53
+ <code
54
+ {...props}
55
+ className={clsx(
56
+ props.className,
57
+ styles.codeBlockLines,
58
+ metadata.lineNumbersStart !== undefined &&
59
+ styles.codeBlockLinesWithNumbering,
60
+ )}
61
+ style={{
62
+ ...props.style,
63
+ counterReset:
64
+ metadata.lineNumbersStart === undefined
65
+ ? undefined
66
+ : `line-count ${metadata.lineNumbersStart - 1}`,
67
+ }}
68
+ />
48
69
  );
70
+ }
49
71
 
72
+ function CodeBlockContent({
73
+ metadata,
74
+ wordWrap,
75
+ }: {
76
+ metadata: CodeBlockMetadata;
77
+ wordWrap: WordWrap;
78
+ }): ReactNode {
50
79
  const prismTheme = usePrismTheme();
51
- const wordWrap = useCodeWordWrap();
52
- const isBrowser = useIsBrowser();
53
-
54
- // We still parse the metastring in case we want to support more syntax in the
55
- // future. Note that MDX doesn't strip quotes when parsing metastring:
56
- // "title=\"xyz\"" => title: "\"xyz\""
57
- const title = parseCodeBlockTitle(metastring) || titleProp;
80
+ const {code, language, lineNumbersStart, lineClassNames} = metadata;
81
+ return (
82
+ <Highlight theme={prismTheme} code={code} language={language}>
83
+ {({className, style, tokens: lines, getLineProps, getTokenProps}) => (
84
+ <Pre ref={wordWrap.codeBlockRef} className={className} style={style}>
85
+ <Code metadata={metadata}>
86
+ {lines.map((line, i) => (
87
+ <Line
88
+ key={i}
89
+ line={line}
90
+ getLineProps={getLineProps}
91
+ getTokenProps={getTokenProps}
92
+ classNames={lineClassNames[i]}
93
+ showLineNumbers={lineNumbersStart !== undefined}
94
+ />
95
+ ))}
96
+ </Code>
97
+ </Pre>
98
+ )}
99
+ </Highlight>
100
+ );
101
+ }
58
102
 
59
- const {lineClassNames, code} = parseLines(children, {
60
- metastring,
61
- language,
62
- magicComments,
63
- });
64
- const lineNumbersStart = getLineNumbersStart({
65
- showLineNumbers: showLineNumbersProp,
66
- metastring,
67
- });
103
+ function CodeBlockButtons({
104
+ metadata,
105
+ wordWrap,
106
+ }: {
107
+ metadata: CodeBlockMetadata;
108
+ wordWrap: WordWrap;
109
+ }): ReactNode {
110
+ return (
111
+ <div className={styles.buttonGroup}>
112
+ {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
113
+ <WordWrapButton
114
+ className={styles.codeButton}
115
+ onClick={() => wordWrap.toggle()}
116
+ isEnabled={wordWrap.isEnabled}
117
+ />
118
+ )}
119
+ <CopyButton className={styles.codeButton} code={metadata.code} />
120
+ </div>
121
+ );
122
+ }
68
123
 
124
+ function CodeBlockLayout({metadata}: {metadata: CodeBlockMetadata}): ReactNode {
125
+ const isBrowser = useIsBrowser();
126
+ const wordWrap = useCodeWordWrap();
69
127
  return (
70
- <Container
71
- as="div"
72
- className={clsx(
73
- blockClassName,
74
- language &&
75
- !blockClassName.includes(`language-${language}`) &&
76
- `language-${language}`,
77
- )}>
78
- {title && <div className={styles.codeBlockTitle}>{title}</div>}
128
+ <Container as="div" className={metadata.className}>
129
+ {metadata.title && (
130
+ <div className={styles.codeBlockTitle}>
131
+ <CodeBlockTitle>{metadata.title}</CodeBlockTitle>
132
+ </div>
133
+ )}
79
134
  <div className={styles.codeBlockContent}>
80
- <Highlight
81
- theme={prismTheme}
82
- code={code}
83
- language={(language ?? 'text') as Language}>
84
- {({className, style, tokens, getLineProps, getTokenProps}) => (
85
- <pre
86
- /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
87
- tabIndex={0}
88
- ref={wordWrap.codeBlockRef}
89
- className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
90
- style={style}>
91
- <code
92
- className={clsx(
93
- styles.codeBlockLines,
94
- lineNumbersStart !== undefined &&
95
- styles.codeBlockLinesWithNumbering,
96
- )}
97
- style={
98
- lineNumbersStart === undefined
99
- ? undefined
100
- : {counterReset: `line-count ${lineNumbersStart - 1}`}
101
- }>
102
- {tokens.map((line, i) => (
103
- <Line
104
- key={i}
105
- line={line}
106
- getLineProps={getLineProps}
107
- getTokenProps={getTokenProps}
108
- classNames={lineClassNames[i]}
109
- showLineNumbers={lineNumbersStart !== undefined}
110
- />
111
- ))}
112
- </code>
113
- </pre>
114
- )}
115
- </Highlight>
116
- {isBrowser ? (
117
- <div className={styles.buttonGroup}>
118
- {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && (
119
- <WordWrapButton
120
- className={styles.codeButton}
121
- onClick={() => wordWrap.toggle()}
122
- isEnabled={wordWrap.isEnabled}
123
- />
124
- )}
125
- <CopyButton className={styles.codeButton} code={code} />
126
- </div>
127
- ) : null}
135
+ <CodeBlockContent metadata={metadata} wordWrap={wordWrap} />
136
+ {isBrowser && (
137
+ <CodeBlockButtons metadata={metadata} wordWrap={wordWrap} />
138
+ )}
128
139
  </div>
129
140
  </Container>
130
141
  );
131
142
  }
143
+
144
+ function useCodeBlockMetadata(props: Props): CodeBlockMetadata {
145
+ const {prism} = useThemeConfig();
146
+ return createCodeBlockMetadata({
147
+ code: props.children,
148
+ className: props.className,
149
+ metastring: props.metastring,
150
+ magicComments: prism.magicComments,
151
+ defaultLanguage: prism.defaultLanguage,
152
+ language: props.language,
153
+ title: props.title,
154
+ showLineNumbers: props.showLineNumbers,
155
+ });
156
+ }
157
+
158
+ export default function CodeBlockString(props: Props): ReactNode {
159
+ const metadata = useCodeBlockMetadata(props);
160
+ return <CodeBlockLayout metadata={metadata} />;
161
+ }