From 62692d6b7bf9de3ffe86a58a6af589115b207e09 Mon Sep 17 00:00:00 2001 From: x0rgus Date: Fri, 13 Mar 2026 20:06:41 -0300 Subject: [PATCH 1/3] fix: normalize template literal indentation in CodeBlock --- .../code-block/code-block.stories.tsx | 49 +++++++++++++++++++ .../src/components/code-block/code-block.tsx | 16 ++++-- packages/components/src/utils/dedent.ts | 27 ++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 packages/components/src/utils/dedent.ts diff --git a/packages/components/src/components/code-block/code-block.stories.tsx b/packages/components/src/components/code-block/code-block.stories.tsx index b7dc7ca..418e510 100644 --- a/packages/components/src/components/code-block/code-block.stories.tsx +++ b/packages/components/src/components/code-block/code-block.stories.tsx @@ -464,3 +464,52 @@ export const WithCustomClassName: Story = { ), }; +export const TemplateLiteralSimple: Story = { + render: () => ( + + {` + echo hello + echo world + echo storybook + `} + + ), +}; +export const TemplateLiteralYaml: Story = { + render: () => ( + + {` + applications: + myapp: + source: + root: "/" + `} + + ), +}; +export const TemplateLiteralJavascript: Story = { + render: () => ( + + {` + function greet(name) { + console.log("Hello " + name); + } + + greet("Mintlify"); + `} + + ), +}; +export const TemplateLiteralWithEmptyLines: Story = { + render: () => ( + + {` + + npm install + + npm run build + + `} + + ), +}; diff --git a/packages/components/src/components/code-block/code-block.tsx b/packages/components/src/components/code-block/code-block.tsx index 61ac677..b6538a0 100644 --- a/packages/components/src/components/code-block/code-block.tsx +++ b/packages/components/src/components/code-block/code-block.tsx @@ -2,6 +2,7 @@ import type { ReactNode, RefObject } from "react"; import { Classes } from "@/constants/selectors"; import { cn } from "@/utils/cn"; +import { dedent } from "@/utils/dedent"; import { getNodeText } from "@/utils/get-node-text"; import type { CodeBlockTheme, CodeStyling } from "@/utils/shiki/code-styling"; @@ -96,9 +97,15 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) { askAiButton, feedbackButton, copyButtonProps, + ...rest } = params; - const codeString = getNodeText(children); + let codeString = getNodeText(children); + + if (typeof codeString === "string") { + codeString = dedent(codeString); + } + const hasGrayBackgroundContainer = !!filename || !!icon; return ( @@ -146,13 +153,16 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) { {askAiButton && askAiButton} )} + + > + {codeString} + ); }; diff --git a/packages/components/src/utils/dedent.ts b/packages/components/src/utils/dedent.ts new file mode 100644 index 0000000..395f2a8 --- /dev/null +++ b/packages/components/src/utils/dedent.ts @@ -0,0 +1,27 @@ +const INDENT_REGEX = /^[ \t]*/; + +export function dedent(code: string): string { + const lines = code.split("\n"); + + // remove empty lines at the start + while (lines.length && lines[0].trim() === "") { + lines.shift(); + } + + // remove empty lines at the end + while (lines.length && lines.at(-1)?.trim() === "") { + lines.pop(); + } + + if (lines.length === 0) { + return ""; + } + + const indents = lines + .filter((line) => line.trim().length > 0) + .map((line) => line.match(INDENT_REGEX)?.[0].length ?? 0); + + const minIndent = Math.min(...indents); + + return lines.map((line) => line.slice(minIndent)).join("\n"); +} From 73fa7a8f60ff7a8136f21c796ead6418a807c3aa Mon Sep 17 00:00:00 2001 From: x0rgus Date: Fri, 13 Mar 2026 20:11:13 -0300 Subject: [PATCH 2/3] regex --- packages/components/src/utils/dedent.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/components/src/utils/dedent.ts b/packages/components/src/utils/dedent.ts index 395f2a8..7311d48 100644 --- a/packages/components/src/utils/dedent.ts +++ b/packages/components/src/utils/dedent.ts @@ -1,14 +1,12 @@ -const INDENT_REGEX = /^[ \t]*/; +const INDENT_REGEX = /^[ ]*/; export function dedent(code: string): string { const lines = code.split("\n"); - // remove empty lines at the start while (lines.length && lines[0].trim() === "") { lines.shift(); } - // remove empty lines at the end while (lines.length && lines.at(-1)?.trim() === "") { lines.pop(); } @@ -24,4 +22,4 @@ export function dedent(code: string): string { const minIndent = Math.min(...indents); return lines.map((line) => line.slice(minIndent)).join("\n"); -} +} \ No newline at end of file From e76c01bb2ecc8ad42ee8afa68f220371f5252c8f Mon Sep 17 00:00:00 2001 From: x0rgus Date: Fri, 13 Mar 2026 20:33:32 -0300 Subject: [PATCH 3/3] fix: forward all props to BaseCodeBlock --- packages/components/src/components/code-block/code-block.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/components/src/components/code-block/code-block.tsx b/packages/components/src/components/code-block/code-block.tsx index b6538a0..0f899cf 100644 --- a/packages/components/src/components/code-block/code-block.tsx +++ b/packages/components/src/components/code-block/code-block.tsx @@ -97,7 +97,6 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) { askAiButton, feedbackButton, copyButtonProps, - ...rest } = params; let codeString = getNodeText(children); @@ -155,11 +154,11 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) { )} {codeString}