Skip to content

Commit e086ee4

Browse files
authored
Merge pull request #24 from typelets/fix/web-app-performance
fix: improve Monaco editor theming and empty trash UX
2 parents d2125b7 + b5714a2 commit e086ee4

File tree

11 files changed

+405
-322
lines changed

11 files changed

+405
-322
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"@radix-ui/react-slot": "^1.2.3",
7171
"@radix-ui/react-tabs": "^1.1.13",
7272
"@tailwindcss/vite": "^4.1.13",
73+
"@tanstack/react-query": "^5.90.5",
7374
"@tiptap/core": "^3.4.4",
7475
"@tiptap/extension-code-block-lowlight": "^3.4.4",
7576
"@tiptap/extension-color": "^3.4.4",

pnpm-lock.yaml

Lines changed: 18 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: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { api } from '@/lib/api/api.ts';
1616
import { fileService } from '@/services/fileService';
1717
import { codeExecutionService } from '@/services/codeExecutionService';
1818
import { clearUserEncryptionData } from '@/lib/encryption';
19+
import { MonacoThemeProvider } from '@/contexts/MonacoThemeContext';
1920
import MainApp from '@/pages/MainApp';
2021

2122
function AppContent() {
@@ -91,5 +92,9 @@ function AppContent() {
9192
}
9293

9394
export default function App() {
94-
return <AppContent />;
95+
return (
96+
<MonacoThemeProvider>
97+
<AppContent />
98+
</MonacoThemeProvider>
99+
);
95100
}

src/components/editor/extensions/ExecutableCodeBlockNodeView.tsx

Lines changed: 10 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,10 @@ import {
1717
import Editor from '@monaco-editor/react';
1818
import * as monaco from 'monaco-editor';
1919
import type { Editor as TiptapEditor } from '@tiptap/react';
20+
import { useMonacoTheme } from '@/contexts/MonacoThemeContext';
2021

21-
// CSS styles for theme overrides
22-
const monacoThemeStyles = `
23-
.monaco-light-override .monaco-editor,
24-
.monaco-light-override .monaco-editor .margin,
25-
.monaco-light-override .monaco-editor .monaco-editor-background {
26-
background-color: #ffffff !important;
27-
color: #000000 !important;
28-
}
29-
30-
.monaco-light-override .monaco-editor .view-lines .view-line {
31-
color: #000000 !important;
32-
}
33-
34-
.monaco-light-override .monaco-editor .line-numbers {
35-
color: #237893 !important;
36-
}
37-
38-
.monaco-light-override .monaco-editor .current-line {
39-
background-color: #f0f0f0 !important;
40-
}
41-
42-
.monaco-light-override .monaco-editor .selected-text {
43-
background-color: #316ac5 !important;
44-
}
45-
46-
.monaco-dark-override .monaco-editor,
47-
.monaco-dark-override .monaco-editor .margin,
48-
.monaco-dark-override .monaco-editor .monaco-editor-background {
49-
background-color: #1e1e1e !important;
50-
color: #d4d4d4 !important;
51-
}
52-
53-
.monaco-dark-override .monaco-editor .view-lines .view-line {
54-
color: #d4d4d4 !important;
55-
}
56-
57-
.monaco-dark-override .monaco-editor .line-numbers {
58-
color: #858585 !important;
59-
}
60-
61-
.monaco-dark-override .monaco-editor .current-line {
62-
background-color: #2a2a2a !important;
63-
}
64-
65-
.monaco-dark-override .monaco-editor .selected-text {
66-
background-color: #316ac5 !important;
67-
}
68-
`;
22+
// Monaco Editor has built-in themes: "vs" (light) and "vs-dark" (dark)
23+
// We'll use the theme prop to set each editor's theme individually
6924

7025
interface ExecutableCodeBlockNodeViewProps {
7126
node: {
@@ -90,23 +45,6 @@ export function ExecutableCodeBlockNodeView({
9045
getPos,
9146
editor,
9247
}: ExecutableCodeBlockNodeViewProps) {
93-
// Inject custom CSS styles for theme overrides
94-
useEffect(() => {
95-
const styleId = 'monaco-theme-override-styles';
96-
let styleElement = document.getElementById(styleId) as HTMLStyleElement;
97-
98-
if (!styleElement) {
99-
styleElement = document.createElement('style');
100-
styleElement.id = styleId;
101-
styleElement.textContent = monacoThemeStyles;
102-
document.head.appendChild(styleElement);
103-
}
104-
105-
return () => {
106-
// Clean up when the last component unmounts
107-
// Note: This is a simple approach. In production, you might want to reference count
108-
};
109-
}, []);
11048
const [output, setOutput] = useState<ExecutionResult | null>(
11149
node.attrs.output || null
11250
);
@@ -119,9 +57,7 @@ export function ExecutableCodeBlockNodeView({
11957
const [code, setCode] = useState(node.textContent);
12058
const [editorHeight, setEditorHeight] = useState(300);
12159
const [isResizing, setIsResizing] = useState(false);
122-
const [monacoThemeOverride, setMonacoThemeOverride] = useState<
123-
'light' | 'dark'
124-
>('dark');
60+
const { theme: monacoTheme, toggleTheme } = useMonacoTheme();
12561
const nodeRef = useRef<HTMLDivElement>(null);
12662
const updateTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
12763
const monacoRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
@@ -339,15 +275,11 @@ export function ExecutableCodeBlockNodeView({
339275

340276
<div className="flex items-center gap-1">
341277
<button
342-
onClick={() => {
343-
setMonacoThemeOverride(
344-
monacoThemeOverride === 'light' ? 'dark' : 'light'
345-
);
346-
}}
278+
onClick={toggleTheme}
347279
className="rounded p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
348-
title={`Monaco theme: ${monacoThemeOverride} (click to toggle)`}
280+
title={`Monaco theme: ${monacoTheme} (click to toggle all code blocks)`}
349281
>
350-
{monacoThemeOverride === 'light' ? (
282+
{monacoTheme === 'light' ? (
351283
<Sun className="h-4 w-4" />
352284
) : (
353285
<Moon className="h-4 w-4" />
@@ -398,17 +330,15 @@ export function ExecutableCodeBlockNodeView({
398330
</div>
399331

400332
{/* Code Content */}
401-
<div
402-
className={`relative w-full ${monacoThemeOverride === 'light' ? 'monaco-light-override' : 'monaco-dark-override'}`}
403-
>
333+
<div className="relative w-full">
404334
<Editor
405335
key={`monaco-${node.attrs.language}-${getPos()}`}
406336
height={`${editorHeight}px`}
407337
width="100%"
408338
language={language}
409339
defaultValue={code}
410340
onChange={handleCodeChange}
411-
theme="vs-dark"
341+
theme={monacoTheme === 'light' ? 'vs' : 'vs-dark'}
412342
options={{
413343
minimap: { enabled: false },
414344
lineNumbers: 'on',
@@ -424,6 +354,7 @@ export function ExecutableCodeBlockNodeView({
424354
scrollbar: {
425355
verticalScrollbarSize: 10,
426356
horizontalScrollbarSize: 10,
357+
alwaysConsumeMouseWheel: false, // Allow scroll to pass through to parent
427358
},
428359
contextmenu: true,
429360
renderLineHighlight: 'gutter',

0 commit comments

Comments
 (0)