feat: code editor

This commit is contained in:
Timothy J. Baek 2024-06-10 16:02:23 -07:00
parent 5a3736f1ee
commit 8ad52f0fcc
2 changed files with 73 additions and 11 deletions

View File

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

View File

@ -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" />