import { yaml } from '@codemirror/lang-yaml'; import { syntaxHighlighting } from '@codemirror/language'; import { MergeView } from '@codemirror/merge'; import { EditorView } from '@codemirror/view'; import classNames from 'classnames'; import { useEffect, useRef } from 'react'; import './DiffViewer.css'; import { readonlyExtensions, syntaxHighlightStyle } from './extensions'; interface Props { /** Original/previous version (left side) */ original: string; /** Modified/current version (right side) */ modified: string; className?: string; } export function DiffViewer({ original, modified, className }: Props) { const containerRef = useRef(null); const viewRef = useRef(null); useEffect(() => { if (!containerRef.current) return; // Clean up previous instance viewRef.current?.destroy(); const sharedExtensions = [ yaml(), syntaxHighlighting(syntaxHighlightStyle), ...readonlyExtensions, EditorView.lineWrapping, ]; viewRef.current = new MergeView({ a: { doc: original, extensions: sharedExtensions, }, b: { doc: modified, extensions: sharedExtensions, }, parent: containerRef.current, collapseUnchanged: { margin: 2, minSize: 3 }, highlightChanges: false, gutter: true, orientation: 'a-b', revertControls: undefined, }); return () => { viewRef.current?.destroy(); viewRef.current = null; }; }, [original, modified]); return (
); }