瀏覽代碼

feat: code editor

Timothy J. Baek 11 月之前
父節點
當前提交
8ad52f0fcc
共有 2 個文件被更改,包括 73 次插入11 次删除
  1. 9 0
      src/app.css
  2. 64 11
      src/lib/components/common/CodeEditor.svelte

+ 9 - 0
src/app.css

@@ -24,6 +24,15 @@ math {
 	margin-top: 1rem;
 }
 
+.cm-editor {
+	height: 100%;
+	width: 100%;
+}
+
+.cm-editor.cm-focused {
+	outline: none;
+}
+
 .hljs {
 	@apply rounded-lg;
 }

+ 64 - 11
src/lib/components/common/CodeEditor.svelte

@@ -1,7 +1,7 @@
 <script lang="ts">
 	import { basicSetup, EditorView } from 'codemirror';
 	import { keymap, placeholder } from '@codemirror/view';
-	import { EditorState } from '@codemirror/state';
+	import { Compartment, EditorState } from '@codemirror/state';
 
 	import { acceptCompletion } from '@codemirror/autocomplete';
 	import { indentWithTab } from '@codemirror/commands';
@@ -13,22 +13,75 @@
 
 	export let value = '';
 
+	let codeEditor;
+
+	let isDarkMode = false;
+	let editorTheme = new Compartment();
+
+	let extensions = [
+		basicSetup,
+		keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]),
+		python(),
+		placeholder('Enter your code here...'),
+		EditorView.updateListener.of((e) => {
+			if (e.docChanged) {
+				console.log(e);
+				value = e.state.doc.toString();
+			}
+		}),
+		editorTheme.of([])
+	];
+
 	onMount(() => {
+		// Check if html class has dark mode
+		isDarkMode = document.documentElement.classList.contains('dark');
+
 		// python code editor, highlight python code
-		const codeEditor = new EditorView({
+		codeEditor = new EditorView({
 			state: EditorState.create({
-				doc: value,
-				extensions: [
-					basicSetup,
-					keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]),
-					python(),
-					oneDark,
-					placeholder('Enter your code here...')
-				]
+				doc: '',
+				extensions: extensions
 			}),
 			parent: document.getElementById('code-textarea')
 		});
+
+		if (isDarkMode) {
+			codeEditor.dispatch({
+				effects: editorTheme.reconfigure(oneDark)
+			});
+		}
+
+		// listen to html class changes this should fire only when dark mode is toggled
+		const observer = new MutationObserver((mutations) => {
+			mutations.forEach((mutation) => {
+				if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
+					const _isDarkMode = document.documentElement.classList.contains('dark');
+
+					if (_isDarkMode !== isDarkMode) {
+						isDarkMode = _isDarkMode;
+						if (_isDarkMode) {
+							codeEditor.dispatch({
+								effects: editorTheme.reconfigure(oneDark)
+							});
+						} else {
+							codeEditor.dispatch({
+								effects: editorTheme.reconfigure()
+							});
+						}
+					}
+				}
+			});
+		});
+
+		observer.observe(document.documentElement, {
+			attributes: true,
+			attributeFilter: ['class']
+		});
+
+		return () => {
+			observer.disconnect();
+		};
 	});
 </script>
 
-<div id="code-textarea" />
+<div id="code-textarea" class="h-full w-full" />