Real work on getting CodeMirror working. I at least have a fancy highlighter and basic editor.
This commit is contained in:
76
src/lib/e_app_codemirror_v5.svelte
Normal file
76
src/lib/e_app_codemirror_v5.svelte
Normal file
@@ -0,0 +1,76 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
||||
import { EditorView, keymap, placeholder as placeholderExt } from '@codemirror/view';
|
||||
import { EditorState, StateEffect, type Extension } from '@codemirror/state';
|
||||
import { indentWithTab } from '@codemirror/commands';
|
||||
import { basicSetup } from 'codemirror';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from "@codemirror/theme-one-dark";
|
||||
|
||||
// Props
|
||||
export let content: string = 'test test test test';
|
||||
export let new_content: string = '';
|
||||
export let language: Extension = javascript();
|
||||
export let theme: Extension = oneDark;
|
||||
export let extensions: Extension[] = [];
|
||||
export let editable: boolean = true;
|
||||
export let placeholder: string = 'Start typing...';
|
||||
|
||||
const dispatch = createEventDispatcher<{ change: string }>();
|
||||
|
||||
let editor_element: HTMLDivElement;
|
||||
let editorView: EditorView;
|
||||
|
||||
// Reactive declaration for extensions
|
||||
$: editor_extensions = [
|
||||
basicSetup,
|
||||
EditorView.editable.of(editable),
|
||||
keymap.of([indentWithTab]),
|
||||
placeholderExt(placeholder),
|
||||
language,
|
||||
theme,
|
||||
...extensions
|
||||
];
|
||||
|
||||
// Initialize CodeMirror on mount
|
||||
onMount(() => {
|
||||
editorView = new EditorView({
|
||||
state: EditorState.create({
|
||||
doc: content,
|
||||
extensions: editor_extensions,
|
||||
}),
|
||||
parent: editor_element,
|
||||
dispatch: (transaction) => {
|
||||
editorView.update([transaction]);
|
||||
if (transaction.docChanged) {
|
||||
new_content = editorView.state.doc.toString();
|
||||
const newContent = editorView.state.doc.toString();
|
||||
dispatch('change', newContent);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Clean up on destroy
|
||||
onDestroy(() => {
|
||||
editorView?.destroy();
|
||||
});
|
||||
|
||||
// Update editor content when `content` prop changes
|
||||
$: if (editorView && editorView.state.doc.toString() !== content) {
|
||||
editorView.setState(
|
||||
EditorState.create({
|
||||
doc: content,
|
||||
extensions: editor_extensions
|
||||
})
|
||||
);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div bind:this={editor_element} class="codemirror-wrapper"></div>
|
||||
|
||||
<style>
|
||||
.codemirror-wrapper :global(.cm-focused) {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user