From c45281a5815706cc1b1ea37d92fe9420d20ea92d Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 30 Dec 2021 00:17:09 +0800 Subject: [PATCH] feat(theme-classic): usable CodeBlock outside markdown (#6216) --- .../src/theme-classic.d.ts | 1 + .../src/theme/CodeBlock/index.tsx | 12 ++++-- .../src/utils/codeBlockUtils.ts | 9 ++--- .../markdown-features-code-blocks.mdx | 39 ++++++++++++++++++- .../markdown-features-react.mdx | 10 +---- 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index c4d51f69ef..accafb0f96 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -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; diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx index bab753c075..8ae921488d 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx @@ -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}) => (
{codeBlockTitle && ( diff --git a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts index 77833da6e9..a279afc5fd 100644 --- a/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/codeBlockUtils.ts @@ -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; diff --git a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx index c362434897..d3638dd7ba 100644 --- a/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx +++ b/website/docs/guides/markdown-features/markdown-features-code-blocks.mdx @@ -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) { -## 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 ( +
+ {/* highlight-start */} + + {`function HelloCodeTitle(props) { + return

Hello, {props.name}

; +}`} +
+ {/* highlight-end */} +
+ ); +} +``` + + + + {`function HelloCodeTitle(props) { + return

Hello, {props.name}

; +}`} +
+
+ +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. diff --git a/website/docs/guides/markdown-features/markdown-features-react.mdx b/website/docs/guides/markdown-features/markdown-features-react.mdx index 4fcc5ae9ff..36108adce8 100644 --- a/website/docs/guides/markdown-features/markdown-features-react.mdx +++ b/website/docs/guides/markdown-features/markdown-features-react.mdx @@ -116,17 +116,11 @@ import MyComponentSource from '!!raw-loader!@site/src/pages/examples/_myComponen
``` -You can also pass `title` prop to `CodeBlock` component in order for it to appear as header above your code block: - -```jsx - - {MyComponentSource} - -``` +See [using code blocks in JSX](./markdown-features-code-blocks.mdx#usage-in-jsx) for more details of the `` component. :::note -You have to use `` 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 `` 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. :::