diff --git a/package.json b/package.json index 5e8cd30f1..9e41466a1 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "@tanstack/ai-client": "^0.11.3", "@tanstack/ai-openai": "^0.9.5", "@tanstack/create": "^0.69.0", - "@tanstack/highlight": "^0.0.7", + "@tanstack/highlight": "^0.0.8", "@tanstack/markdown": "^0.0.11", "@tanstack/pacer": "^0.21.1", "@tanstack/react-hotkeys": "^0.10.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a47a7a31..fb0131cc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,8 +100,8 @@ importers: specifier: ^0.69.0 version: 0.69.0(tslib@2.8.1) '@tanstack/highlight': - specifier: ^0.0.7 - version: 0.0.7 + specifier: ^0.0.8 + version: 0.0.8 '@tanstack/markdown': specifier: ^0.0.11 version: 0.0.11(react@19.2.3) @@ -3323,8 +3323,8 @@ packages: peerDependencies: solid-js: '>=1.9.7' - '@tanstack/highlight@0.0.7': - resolution: {integrity: sha512-i7GwU+BNROlPGn4jA94iI7qcQa3nVprcveg3eYWRwQA5mJbtQmgZP97tl1A0eulTln+YoCQ82xoNmHJkuviEfA==} + '@tanstack/highlight@0.0.8': + resolution: {integrity: sha512-v+QMPdA/g8ni3/wpd6UzRVvpBvKlxBXwe6XlCOZIUbamUaMWcBBFdrk4fvKKh2ArgFghWcP0rAQc5X8iQGNDYg==} engines: {node: '>=18'} '@tanstack/history@1.162.0': @@ -9641,7 +9641,7 @@ snapshots: - csstype - utf-8-validate - '@tanstack/highlight@0.0.7': {} + '@tanstack/highlight@0.0.8': {} '@tanstack/history@1.162.0': {} diff --git a/src/components/markdown/CodeBlock.tsx b/src/components/markdown/CodeBlock.tsx index 5ae9a727f..d9e9378f8 100644 --- a/src/components/markdown/CodeBlock.tsx +++ b/src/components/markdown/CodeBlock.tsx @@ -1,4 +1,5 @@ -import { renderCodeBlockData } from '@tanstack/highlight' +import { defaultHighlighter } from '@tanstack/highlight' +import { renderCodeFence } from '@tanstack/highlight/markdown' import * as React from 'react' import { CodeBlockView } from './CodeBlockView' import { MermaidBlock } from './MermaidBlock' @@ -37,7 +38,7 @@ function HighlightedCodeBlock({ title?: string }) { const rendered = React.useMemo(() => { - return renderCodeBlockData({ code, lang, title }) + return renderCodeFence({ code, lang, title }, defaultHighlighter) }, [code, lang, title]) return ( diff --git a/src/styles/app.css b/src/styles/app.css index 0b7c57b69..5ec2c8c77 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -707,25 +707,17 @@ pre { @apply text-black overflow-x-auto relative leading-tight; } -span.line { - display: inline-block; - width: 100%; -} - -pre.has-diff span.diff { - width: calc(100% + 20px); - margin-left: -10px; - padding-right: 20px; - padding-left: 10px; - padding-top: 4px; - padding-bottom: 4px; +.th-line--deleted, +.th-line--inserted { + margin-inline: -1rem; + padding-inline: 1rem; } -pre.has-diff span.remove { +.th-line--deleted { background-color: #f43f5e29; } -pre.has-diff span.add { +.th-line--inserted { background-color: #10b98129; } /* Visually differentiates twoslash code samples */ diff --git a/tests/code-highlighting.test.ts b/tests/code-highlighting.test.ts new file mode 100644 index 000000000..e6ffcd418 --- /dev/null +++ b/tests/code-highlighting.test.ts @@ -0,0 +1,25 @@ +import assert from 'node:assert/strict' +import test from 'node:test' +import { defaultHighlighter } from '@tanstack/highlight' +import { renderCodeFence } from '@tanstack/highlight/markdown' + +test('inline diff notation renders as line decorations', () => { + const rendered = renderCodeFence( + { + code: [ + `- const oldValue = true // [!code --]`, + `+ const newValue = true // [!code ++]`, + ].join('\n'), + lang: 'tsx', + }, + defaultHighlighter, + ) + + assert.equal( + rendered.copyText, + [`- const oldValue = true`, `+ const newValue = true`].join('\n'), + ) + assert.match(rendered.htmlMarkup, /th-line--deleted/) + assert.match(rendered.htmlMarkup, /th-line--inserted/) + assert.doesNotMatch(rendered.htmlMarkup, /!code/) +})