mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-16 02:27:21 +02:00
feat(theme-classic): usable CodeBlock outside markdown (#6216)
This commit is contained in:
parent
96dbb8e7ef
commit
c45281a581
5 changed files with 53 additions and 18 deletions
|
@ -114,6 +114,7 @@ declare module '@theme/CodeBlock' {
|
|||
readonly className?: string;
|
||||
readonly metastring?: string;
|
||||
readonly title?: string;
|
||||
readonly language?: string;
|
||||
}
|
||||
|
||||
const CodeBlock: (props: Props) => JSX.Element;
|
||||
|
|
|
@ -24,9 +24,10 @@ import styles from './styles.module.css';
|
|||
|
||||
export default function CodeBlock({
|
||||
children,
|
||||
className: blockClassName,
|
||||
className: blockClassName = '',
|
||||
metastring,
|
||||
title,
|
||||
language: languageProp,
|
||||
}: Props): JSX.Element {
|
||||
const {prism} = useThemeConfig();
|
||||
|
||||
|
@ -85,8 +86,7 @@ export default function CodeBlock({
|
|||
: (children as string);
|
||||
|
||||
const language =
|
||||
parseLanguage(blockClassName) ??
|
||||
(prism.defaultLanguage as Language | undefined);
|
||||
languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
|
||||
const {highlightLines, code} = parseLines(content, metastring, language);
|
||||
|
||||
const handleCopyCode = () => {
|
||||
|
@ -102,12 +102,16 @@ export default function CodeBlock({
|
|||
key={String(mounted)}
|
||||
theme={prismTheme}
|
||||
code={code}
|
||||
language={language ?? ('text' as Language)}>
|
||||
language={(language ?? 'text') as Language}>
|
||||
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
||||
<div
|
||||
className={clsx(
|
||||
styles.codeBlockContainer,
|
||||
blockClassName,
|
||||
{
|
||||
[`language-${language}`]:
|
||||
language && !blockClassName.includes(`language-${language}`),
|
||||
},
|
||||
ThemeClassNames.common.codeBlock,
|
||||
)}>
|
||||
{codeBlockTitle && (
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import rangeParser from 'parse-numeric-range';
|
||||
import type {Language} from 'prism-react-renderer';
|
||||
|
||||
const codeBlockTitleRegex = /title=(["'])(.*?)\1/;
|
||||
const highlightLinesRangeRegex = /{([\d,-]+)}/;
|
||||
|
@ -93,11 +92,11 @@ export function parseCodeBlockTitle(metastring?: string): string {
|
|||
return metastring?.match(codeBlockTitleRegex)?.[2] ?? '';
|
||||
}
|
||||
|
||||
export function parseLanguage(className?: string): Language | undefined {
|
||||
export function parseLanguage(className: string): string | undefined {
|
||||
const languageClassName = className
|
||||
?.split(' ')
|
||||
.split(' ')
|
||||
.find((str) => str.startsWith('language-'));
|
||||
return languageClassName?.replace(/language-/, '') as Language | undefined;
|
||||
return languageClassName?.replace(/language-/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +106,7 @@ export function parseLanguage(className?: string): Language | undefined {
|
|||
export function parseLines(
|
||||
content: string,
|
||||
metastring?: string,
|
||||
language?: Language,
|
||||
language?: string,
|
||||
): {
|
||||
highlightLines: number[];
|
||||
code: string;
|
||||
|
|
|
@ -6,6 +6,7 @@ slug: /markdown-features/code-blocks
|
|||
---
|
||||
|
||||
import BrowserWindow from '@site/src/components/BrowserWindow';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
Code blocks within documentation are super-powered 💪.
|
||||
|
||||
|
@ -391,7 +392,7 @@ function MyPlayground(props) {
|
|||
|
||||
</BrowserWindow>
|
||||
|
||||
## Using JSX markup in code blocks
|
||||
## Using JSX markup in code blocks {using-jsx-markup}
|
||||
|
||||
Code block in Markdown always preserves its content as plain text, meaning you can't do something like:
|
||||
|
||||
|
@ -564,3 +565,39 @@ npm install @docusaurus/remark-plugin-npm2yarn
|
|||
````
|
||||
|
||||
Using the `{sync: true}` option would make all tab choices synced. Because the choice is stored under the same namespace `npm2yarn`, different `npm2yarn` plugin instances would also sync their choices.
|
||||
|
||||
## Usage in JSX {#usage-in-jsx}
|
||||
|
||||
Outside of Markdown, you can use the `@theme/CodeBlock` component to get the same output.
|
||||
|
||||
```jsx
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
export default function MyReactPage() {
|
||||
return (
|
||||
<div>
|
||||
{/* highlight-start */}
|
||||
<CodeBlock language="jsx" title="/src/components/HelloCodeTitle.js">
|
||||
{`function HelloCodeTitle(props) {
|
||||
return <h1>Hello, {props.name}</h1>;
|
||||
}`}
|
||||
</CodeBlock>
|
||||
{/* highlight-end */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
<BrowserWindow>
|
||||
<CodeBlock language="jsx" title="/src/components/HelloCodeTitle.js">
|
||||
{`function HelloCodeTitle(props) {
|
||||
return <h1>Hello, {props.name}</h1>;
|
||||
}`}
|
||||
</CodeBlock>
|
||||
</BrowserWindow>
|
||||
|
||||
The props accepted are `language` and `title`, in the same way as you write Markdown code blocks.
|
||||
|
||||
Although discouraged, you can also pass in a `metastring` prop like `metastring='{1-2} title="/src/components/HelloCodeTitle.js"'`, which is how Markdown code blocks are handled under the hood. However, we recommend you [use comments for highlighting lines](#highlighting-with-comments).
|
||||
|
||||
As [previously stated](#using-jsx-markup), syntax highlighting is only applied when the children is a simple string.
|
||||
|
|
|
@ -116,17 +116,11 @@ import MyComponentSource from '!!raw-loader!@site/src/pages/examples/_myComponen
|
|||
<br />
|
||||
```
|
||||
|
||||
You can also pass `title` prop to `CodeBlock` component in order for it to appear as header above your code block:
|
||||
|
||||
```jsx
|
||||
<CodeBlock className="language-jsx" title="/src/myComponent">
|
||||
{MyComponentSource}
|
||||
</CodeBlock>
|
||||
```
|
||||
See [using code blocks in JSX](./markdown-features-code-blocks.mdx#usage-in-jsx) for more details of the `<CodeBlock>` component.
|
||||
|
||||
:::note
|
||||
|
||||
You have to use `<CodeBlock>` rather than the Markdown triple-backtick ` ``` `, because the latter will ship out any of its content as-is, but you want JSX to insert the imported text here.
|
||||
You have to use `<CodeBlock>` rather than the Markdown triple-backtick ` ``` `, because the latter will ship out any of its content as-is, but you want to interpolate the imported text here.
|
||||
|
||||
:::
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue