Skip to content

Commit d4c3fe4

Browse files
committed
feat: intergate with monaco editor
1 parent 8051af0 commit d4c3fe4

File tree

6 files changed

+144
-87
lines changed

6 files changed

+144
-87
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"license": "MIT",
2121
"packageManager": "pnpm@10.15.1",
2222
"dependencies": {
23+
"@monaco-editor/react": "4.7.0-rc.0",
2324
"@tailwindcss/vite": "^4.1.13",
2425
"react": "^19.1.1",
2526
"react-dom": "^19.1.1",

pnpm-lock.yaml

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App.tsx

Lines changed: 10 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,21 @@
1-
import { Layout } from './components/layout';
2-
import { useDynamicFavicon } from './hooks/useDynamicFavicon';
1+
import { Layout } from "./components/layout";
2+
import { DiffEditor } from "./components/DiffEditor";
3+
import { useDynamicFavicon } from "./hooks/useDynamicFavicon";
34

45
function App() {
56
useDynamicFavicon();
67

78
return (
89
<>
910
<Layout>
10-
<div className="text-center">
11-
<h1 className="text-4xl font-bold text-gray-900 dark:text-white mb-8">
12-
Welcome to Diff Viewer
13-
</h1>
14-
15-
<div className="max-w-2xl mx-auto">
16-
<p className="text-lg text-gray-600 dark:text-gray-400 mb-8">
17-
A powerful tool for comparing files and visualizing differences.
18-
Upload your files and see the changes side by side.
19-
</p>
20-
21-
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-8 mb-8">
22-
<h2 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">
23-
Get Started
24-
</h2>
25-
<p className="text-gray-600 dark:text-gray-400 mb-6">
26-
Choose how you'd like to compare files:
27-
</p>
28-
29-
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
30-
<button className="bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg font-medium transition-colors">
31-
Upload Files
32-
</button>
33-
<button className="bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-900 dark:text-white px-6 py-3 rounded-lg font-medium transition-colors">
34-
Paste Text
35-
</button>
36-
</div>
37-
</div>
38-
39-
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
40-
<div className="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
41-
<div className="w-12 h-12 bg-blue-100 dark:bg-blue-900 rounded-lg flex items-center justify-center mb-4 mx-auto">
42-
<svg className="w-6 h-6 text-blue-600 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
43-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
44-
</svg>
45-
</div>
46-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">File Comparison</h3>
47-
<p className="text-gray-600 dark:text-gray-400 text-sm">
48-
Compare any text files, code files, or documents side by side
49-
</p>
50-
</div>
51-
52-
<div className="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
53-
<div className="w-12 h-12 bg-green-100 dark:bg-green-900 rounded-lg flex items-center justify-center mb-4 mx-auto">
54-
<svg className="w-6 h-6 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
55-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
56-
</svg>
57-
</div>
58-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">Fast & Accurate</h3>
59-
<p className="text-gray-600 dark:text-gray-400 text-sm">
60-
Lightning-fast comparison with precise difference highlighting
61-
</p>
62-
</div>
63-
64-
<div className="bg-white dark:bg-gray-800 rounded-lg p-6 shadow">
65-
<div className="w-12 h-12 bg-purple-100 dark:bg-purple-900 rounded-lg flex items-center justify-center mb-4 mx-auto">
66-
<svg className="w-6 h-6 text-purple-600 dark:text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
67-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
68-
</svg>
69-
</div>
70-
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">Dark Mode</h3>
71-
<p className="text-gray-600 dark:text-gray-400 text-sm">
72-
Beautiful interface with full dark mode support
73-
</p>
74-
</div>
75-
</div>
76-
</div>
77-
</div>
78-
</Layout>
11+
<p className="text-gray-600 dark:text-gray-200 text-center mb-8">
12+
Compare files and visualize differences in real-time
13+
</p>
14+
15+
<DiffEditor />
16+
</Layout>
7917
</>
8018
);
8119
}
8220

83-
export default App
21+
export default App;

src/components/DiffEditor.tsx

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { useState, useRef } from 'react';
2+
import { DiffEditor as MonacoDiffEditor, type MonacoDiffEditor as MonacoDiffEditorType } from '@monaco-editor/react';
3+
import { useTheme } from '../hooks/useTheme';
4+
5+
interface DiffEditorProps {
6+
className?: string;
7+
}
8+
9+
export const DiffEditor = ({ className = '' }: DiffEditorProps) => {
10+
const [originalText, setOriginalText] = useState('function hello() {\n console.log("Hello World");\n}');
11+
const [modifiedText, setModifiedText] = useState('function hello() {\n console.log("Hello, World!");\n return "Hello";\n}');
12+
const editorRef = useRef<MonacoDiffEditorType | null>(null);
13+
const { theme } = useTheme();
14+
15+
const handleEditorDidMount = (editor: MonacoDiffEditorType) => {
16+
editorRef.current = editor;
17+
};
18+
19+
const refreshEditor = () => {
20+
if (editorRef.current && editorRef.current.getOriginalEditor && editorRef.current.getModifiedEditor) {
21+
editorRef.current.getOriginalEditor().setValue(originalText);
22+
editorRef.current.getModifiedEditor().setValue(modifiedText);
23+
}
24+
};
25+
26+
const clearContent = () => {
27+
setOriginalText('');
28+
setModifiedText('');
29+
refreshEditor();
30+
};
31+
32+
const loadSampleData = () => {
33+
const newOriginal = 'function hello() {\n console.log("Hello World");\n}';
34+
const newModified = 'function hello() {\n console.log("Hello, World!");\n return "Hello";\n}';
35+
36+
setOriginalText(newOriginal);
37+
setModifiedText(newModified);
38+
refreshEditor();
39+
};
40+
41+
return (
42+
<div className={`flex-1 flex flex-col bg-white dark:bg-gray-800 rounded-lg shadow-lg ${className}`}>
43+
{/* Toolbar */}
44+
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
45+
<div className="flex items-center space-x-4 text-xs text-gray-500 dark:text-gray-400">
46+
<span>Original: {originalText.split('\n').length} lines</span>
47+
<span>Modified: {modifiedText.split('\n').length} lines</span>
48+
</div>
49+
50+
<div className="flex items-center space-x-2">
51+
<button
52+
onClick={loadSampleData}
53+
className="px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded-md cursor-pointer transition-colors"
54+
>
55+
Load Sample
56+
</button>
57+
<button
58+
onClick={clearContent}
59+
className="px-3 py-1 bg-gray-500 hover:bg-gray-600 text-white text-sm rounded-md cursor-pointer transition-colors"
60+
>
61+
Clear
62+
</button>
63+
</div>
64+
</div>
65+
66+
{/* Diff Editor */}
67+
<MonacoDiffEditor
68+
wrapperProps={{
69+
className: 'flex-1',
70+
}}
71+
theme={theme === 'dark' ? 'vs-dark' : 'vs'}
72+
original={originalText}
73+
modified={modifiedText}
74+
onMount={handleEditorDidMount}
75+
options={{
76+
readOnly: false,
77+
minimap: { enabled: false },
78+
scrollBeyondLastLine: false,
79+
fontSize: 14,
80+
lineNumbers: 'on',
81+
renderSideBySide: true,
82+
enableSplitViewResizing: true,
83+
ignoreTrimWhitespace: false,
84+
renderIndicators: true,
85+
originalEditable: true,
86+
}}
87+
/>
88+
</div>
89+
);
90+
};

src/components/layout/Layout.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ export const Layout = ({ children, className = '' }: LayoutProps) => {
1313
<Header />
1414

1515
{/* Main Content Area */}
16-
<main className="flex-1">
17-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
18-
{children}
19-
</div>
16+
<main className="flex-1 max-w-7xl mx-auto flex flex-col px-4 sm:px-6 lg:px-8 py-8 w-full">
17+
{children}
2018
</main>
2119

2220
<Footer />

src/index.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,6 @@ body {
6161
}
6262
}
6363

64-
/* Focus styles */
65-
*:focus {
66-
outline: 2px solid transparent;
67-
outline-offset: 2px;
68-
}
69-
70-
*:focus-visible {
71-
outline: 2px solid #3b82f6;
72-
outline-offset: 2px;
73-
}
74-
7564
/* Selection styles */
7665
::selection {
7766
background-color: rgba(59, 130, 246, 0.2);

0 commit comments

Comments
 (0)