generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: unify code block display (#4182)
- Improve formatting to make things more consistent - Removes `highlight.js` and just reuses `codemirror` everywhere. - New component for showing code with a title - Better light mode handling - New `maxHeight` option BEFORE: ![Screenshot 2025-01-24 at 1 09 02 PM](https://github.com/user-attachments/assets/3834ea23-b040-4f02-9926-3ea620474da6) ![Screenshot 2025-01-24 at 1 09 10 PM](https://github.com/user-attachments/assets/585c6cb4-e705-4094-acd6-2341e09cdbf8) AFTER: ![Screenshot 2025-01-24 at 1 04 29 PM](https://github.com/user-attachments/assets/7bc9e342-3114-467f-95ae-e4e6b0df43a6) ![Screenshot 2025-01-24 at 1 04 36 PM](https://github.com/user-attachments/assets/4ecd901f-3978-4a63-8c83-0f8077debb96)
- Loading branch information
1 parent
965232d
commit 57cf1b9
Showing
16 changed files
with
112 additions
and
320 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,58 @@ | ||
import hljs from 'highlight.js/lib/core' | ||
import go from 'highlight.js/lib/languages/go' | ||
import graphql from 'highlight.js/lib/languages/graphql' | ||
import json from 'highlight.js/lib/languages/json' | ||
import plaintext from 'highlight.js/lib/languages/plaintext' | ||
import 'highlight.js/styles/atom-one-dark.css' | ||
import { json } from '@codemirror/lang-json' | ||
import { EditorState } from '@codemirror/state' | ||
import { EditorView } from '@codemirror/view' | ||
import { atomone } from '@uiw/codemirror-theme-atomone' | ||
import { githubLight } from '@uiw/codemirror-theme-github' | ||
import { useEffect, useRef } from 'react' | ||
import { useUserPreferences } from '../providers/user-preferences-provider' | ||
|
||
interface Props { | ||
code: string | ||
language: string | ||
maxHeight?: number | ||
} | ||
|
||
export const CodeBlock = ({ code, language, maxHeight }: Props) => { | ||
const codeRef = useRef<HTMLElement>(null) | ||
export const CodeBlock = ({ code, maxHeight = 300 }: Props) => { | ||
const editorContainerRef = useRef<HTMLDivElement>(null) | ||
const editorViewRef = useRef<EditorView | null>(null) | ||
const { isDarkMode } = useUserPreferences() | ||
|
||
useEffect(() => { | ||
hljs.configure({ ignoreUnescapedHTML: true }) | ||
hljs.registerLanguage('graphql', graphql) | ||
hljs.registerLanguage('json', json) | ||
hljs.registerLanguage('go', go) | ||
hljs.registerLanguage('plaintext', plaintext) | ||
if (editorContainerRef.current) { | ||
const state = EditorState.create({ | ||
doc: code, | ||
extensions: [ | ||
EditorState.readOnly.of(true), | ||
isDarkMode ? atomone : githubLight, | ||
json(), | ||
EditorView.theme({ | ||
'&': { | ||
minHeight: '2em', | ||
backgroundColor: isDarkMode ? '#282c34' : '#f6f8fa', | ||
}, | ||
'.cm-scroller': { | ||
overflow: 'auto', | ||
padding: '6px', | ||
maxHeight: maxHeight ? `${maxHeight}px` : 'none', | ||
}, | ||
'.cm-content': { | ||
minHeight: '2em', | ||
}, | ||
}), | ||
], | ||
}) | ||
|
||
if (codeRef.current) { | ||
codeRef.current.removeAttribute('data-highlighted') | ||
hljs.highlightElement(codeRef.current) | ||
} | ||
const view = new EditorView({ | ||
state, | ||
parent: editorContainerRef.current, | ||
}) | ||
|
||
editorViewRef.current = view | ||
|
||
return () => { | ||
if (codeRef.current) { | ||
codeRef.current.removeAttribute('data-highlighted') | ||
return () => { | ||
view.destroy() | ||
} | ||
} | ||
}, [code, language]) | ||
}, [code, isDarkMode, maxHeight]) | ||
|
||
return ( | ||
<pre style={{ maxHeight: maxHeight ? `${maxHeight}px` : 'auto' }}> | ||
<code ref={codeRef} className={`language-${language} text-xs`}> | ||
{code} | ||
</code> | ||
</pre> | ||
) | ||
return <div ref={editorContainerRef} className='rounded-md overflow-hidden border border-gray-200 dark:border-gray-600/20' /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { CodeBlock } from './CodeBlock' | ||
|
||
interface Props { | ||
title: string | ||
code: string | ||
maxHeight?: number | ||
} | ||
|
||
export const CodeBlockWithTitle = ({ title, code, maxHeight }: Props) => { | ||
const formattedCode = (() => { | ||
try { | ||
// If it's already a JSON string, parse and re-stringify to ensure consistent formatting | ||
const parsed = JSON.parse(code) | ||
return JSON.stringify(parsed, null, 2) | ||
} catch { | ||
// If it's not valid JSON, return as-is | ||
return code | ||
} | ||
})() | ||
|
||
return ( | ||
<div className='mt-4'> | ||
<div className='text-xs font-medium text-gray-600 dark:text-gray-400 mb-1 uppercase tracking-wider'>{title}</div> | ||
<CodeBlock code={formattedCode} maxHeight={maxHeight} /> | ||
</div> | ||
) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.