From e5116f52e1f398dedb9a5e24615d9ce87e8a1194 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 5 Jan 2024 13:05:30 +0100 Subject: [PATCH 1/2] Allow empty code blocks --- .../src/theme/MDXComponents/Code.tsx | 14 ++++++--- .../src/theme-live-codeblock.d.ts | 3 +- .../src/theme/Playground/index.tsx | 2 +- .../_pages tests/code-block-tests.mdx | 30 +++++++++++++++++++ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx index 97e1ac4d8dd7..6eab58ba4de9 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx @@ -10,12 +10,18 @@ import React from 'react'; import CodeBlock from '@theme/CodeBlock'; import type {Props} from '@theme/MDXComponents/Code'; -export default function MDXCode(props: Props): JSX.Element { - const shouldBeInline = React.Children.toArray(props.children).every( - (el) => typeof el === 'string' && !el.includes('\n'), +function shouldBeInline(props: Props) { + return ( + typeof props.children !== 'undefined' && + React.Children.toArray(props.children).every( + (el) => typeof el === 'string' && !el.includes('\n'), + ) ); +} - return shouldBeInline ? ( +export default function MDXCode(props: Props): JSX.Element { + const inline = shouldBeInline(props); + return inline ? ( ) : ( )} /> diff --git a/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts b/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts index b3670f476ddf..12bd27e8c786 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts +++ b/packages/docusaurus-theme-live-codeblock/src/theme-live-codeblock.d.ts @@ -24,7 +24,8 @@ declare module '@theme/Playground' { type LiveProviderProps = React.ComponentProps; export interface Props extends CodeBlockProps, LiveProviderProps { - children: string; + // Allow empty live playgrounds + children?: string; } export default function Playground(props: LiveProviderProps): JSX.Element; } diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx index a55915086532..1f36e69f570c 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx +++ b/packages/docusaurus-theme-live-codeblock/src/theme/Playground/index.tsx @@ -120,7 +120,7 @@ export default function Playground({ return (
``` + +## Empty code blocks edge cases + +Empty inline code block: `` + +Single space inline code block: ` ` + +Empty code block + +{/* prettier-ignore */} +``` +``` + +Empty 1 line code block + +``` + +``` + +Empty 2 line code block + +``` + +``` + +Empty live code block + +```js live + +``` From 19e5dada2e80c2fe4fa0d9d25ed0799ded460821 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Fri, 5 Jan 2024 13:25:15 +0100 Subject: [PATCH 2/2] extract CodeInline to make it simpler to customize --- .../src/theme-classic.d.ts | 8 ++++++++ .../src/theme/CodeInline/index.tsx | 16 ++++++++++++++++ .../src/theme/MDXComponents/Code.tsx | 8 +++++--- 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/CodeInline/index.tsx diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 053e036dc5eb..b894974807d8 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -363,6 +363,14 @@ declare module '@theme/CodeBlock' { export default function CodeBlock(props: Props): JSX.Element; } +declare module '@theme/CodeInline' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'code'> {} + + export default function CodeInline(props: Props): JSX.Element; +} + declare module '@theme/CodeBlock/CopyButton' { export interface Props { readonly code: string; diff --git a/packages/docusaurus-theme-classic/src/theme/CodeInline/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeInline/index.tsx new file mode 100644 index 000000000000..066ab2e61c5d --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/CodeInline/index.tsx @@ -0,0 +1,16 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import type {Props} from '@theme/CodeInline'; + +// Simple component used to render inline code blocks +// its purpose is to be swizzled and customized +// MDX 1 used to have a inlineCode comp, see https://mdxjs.com/migrating/v2/ +export default function CodeInline(props: Props): JSX.Element { + return ; +} diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx index 6eab58ba4de9..c666174b9cef 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Code.tsx @@ -8,10 +8,13 @@ import type {ComponentProps} from 'react'; import React from 'react'; import CodeBlock from '@theme/CodeBlock'; +import CodeInline from '@theme/CodeInline'; import type {Props} from '@theme/MDXComponents/Code'; function shouldBeInline(props: Props) { return ( + // empty code blocks have no props.children, + // see https://github.com/facebook/docusaurus/pull/9704 typeof props.children !== 'undefined' && React.Children.toArray(props.children).every( (el) => typeof el === 'string' && !el.includes('\n'), @@ -20,9 +23,8 @@ function shouldBeInline(props: Props) { } export default function MDXCode(props: Props): JSX.Element { - const inline = shouldBeInline(props); - return inline ? ( - + return shouldBeInline(props) ? ( + ) : ( )} /> );