feat: enable Prism-based syntax highlighting in code blocks

- Register CodeHighlightNode in the editor node set
- Add CodeHighlightPlugin that calls registerCodeHighlighting
- Map codeHighlight theme keys to mc-tok-* CSS classes
- Add dark-theme token colors for 20+ Prism token types

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-25 19:52:41 +01:00
co-authored by Copilot
parent 38d7e339a2
commit 8240468d1e
3 changed files with 68 additions and 2 deletions
+43 -1
View File
@@ -20,7 +20,7 @@ import {
$convertFromMarkdownString,
$convertToMarkdownString,
} from '@lexical/markdown';
import { $isCodeNode, $createCodeNode, CodeNode } from '@lexical/code';
import { $isCodeNode, $createCodeNode, CodeNode, registerCodeHighlighting } from '@lexical/code';
import {
$isListNode,
INSERT_ORDERED_LIST_COMMAND,
@@ -73,6 +73,38 @@ const editorTheme: EditorThemeClasses = {
},
quote: 'mc-blockquote',
code: 'mc-code-block',
codeHighlight: {
atrule: 'mc-tok-atrule',
attr: 'mc-tok-attr',
boolean: 'mc-tok-boolean',
builtin: 'mc-tok-builtin',
cdata: 'mc-tok-comment',
char: 'mc-tok-string',
class: 'mc-tok-function',
'class-name': 'mc-tok-function',
comment: 'mc-tok-comment',
constant: 'mc-tok-constant',
deleted: 'mc-tok-deleted',
doctype: 'mc-tok-comment',
entity: 'mc-tok-symbol',
function: 'mc-tok-function',
important: 'mc-tok-keyword',
inserted: 'mc-tok-inserted',
keyword: 'mc-tok-keyword',
namespace: 'mc-tok-namespace',
number: 'mc-tok-number',
operator: 'mc-tok-operator',
prolog: 'mc-tok-comment',
property: 'mc-tok-property',
punctuation: 'mc-tok-punctuation',
regex: 'mc-tok-regex',
selector: 'mc-tok-selector',
string: 'mc-tok-string',
symbol: 'mc-tok-symbol',
tag: 'mc-tok-tag',
url: 'mc-tok-string',
variable: 'mc-tok-variable',
},
link: 'mc-link',
};
@@ -146,6 +178,15 @@ function EditorRefPlugin({ editorRef }: { editorRef: React.MutableRefObject<Lexi
return null;
}
/** Enables Prism-based syntax highlighting inside CodeNodes. */
function CodeHighlightPlugin() {
const [editor] = useLexicalComposerContext();
useEffect(() => {
return registerCodeHighlighting(editor);
}, [editor]);
return null;
}
/** Syncs the React `disabled` prop to the Lexical editable state. */
function EditablePlugin({ disabled }: { disabled: boolean }) {
const [editor] = useLexicalComposerContext();
@@ -556,6 +597,7 @@ export const MarkdownComposer = forwardRef<MarkdownComposerHandle, MarkdownCompo
<HistoryPlugin />
<ListPlugin />
<LinkPlugin />
<CodeHighlightPlugin />
<MarkdownShortcutPlugin transformers={[...markdownEditorTransformers]} />
<ClearEditorPlugin />
<ContentTrackingPlugin onContentChange={onContentChange} />