feat(CodeEditor): migrate to svelte code editor

This commit is contained in:
sethburkart123
2024-10-01 20:09:36 +10:00
parent 8b0de97bc6
commit b6e91b2254
4 changed files with 46 additions and 33 deletions
+1
View File
@@ -54,6 +54,7 @@
"@bedframe/cli": "^0.0.85", "@bedframe/cli": "^0.0.85",
"@codemirror/lang-css": "^6.3.0", "@codemirror/lang-css": "^6.3.0",
"@codemirror/lang-less": "^6.0.2", "@codemirror/lang-less": "^6.0.2",
"@codemirror/theme-one-dark": "^6.1.2",
"@million/lint": "latest", "@million/lint": "latest",
"@sveltejs/vite-plugin-svelte": "4.0.0-next.7", "@sveltejs/vite-plugin-svelte": "4.0.0-next.7",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.9",
@@ -2,26 +2,27 @@
import { EditorState } from '@codemirror/state'; import { EditorState } from '@codemirror/state';
import { highlightSelectionMatches } from '@codemirror/search'; import { highlightSelectionMatches } from '@codemirror/search';
import { indentWithTab, history, defaultKeymap, historyKeymap } from '@codemirror/commands'; import { indentWithTab, history, defaultKeymap, historyKeymap } from '@codemirror/commands';
import { foldGutter, indentOnInput, indentUnit, bracketMatching, foldKeymap, syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language'; import { indentOnInput, indentUnit, bracketMatching, foldKeymap, syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete'; import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete';
import { lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, rectangularSelection, crosshairCursor, highlightActiveLine, keymap, EditorView } from '@codemirror/view'; // dropCursor import { highlightSpecialChars, drawSelection, rectangularSelection, crosshairCursor, highlightActiveLine, keymap, EditorView } from '@codemirror/view'; // dropCursor
// Theme // Theme
import { oneDark } from "@codemirror/theme-one-dark"; import { oneDark } from "@codemirror/theme-one-dark";
// Language // Language
import { css } from "@codemirror/lang-css"; import { css } from "@codemirror/lang-css";
import { onMount } from 'svelte' import { onDestroy, onMount } from 'svelte'
function createEditorState(initialContents: string, options = {}) { let editor = $state<HTMLDivElement | null>(null)
let view: EditorView | null = null;
let { value, onChange } = $props<{value: string, onChange: (value: string) => void}>()
function createEditorState(initialContents: string, options = {oneDark: false}) {
let extensions = [ let extensions = [
/* lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(), highlightSpecialChars(),
history(), history(),
foldGutter(),
drawSelection(), drawSelection(),
indentUnit.of(" "), indentUnit.of(" "),
EditorState.allowMultipleSelections.of(true), EditorState.allowMultipleSelections.of(true),
indentOnInput(), indentOnInput(),
bracketMatching(), bracketMatching(),
@@ -38,13 +39,18 @@
...historyKeymap, ...historyKeymap,
...foldKeymap, ...foldKeymap,
...completionKeymap, ...completionKeymap,
]), */ ]),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
onChange(update.state.doc.toString())
}
}),
css(), css(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }), syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
]; ];
/* if (options.oneDark) if (options.oneDark)
extensions.push(oneDark); */ extensions.push(oneDark);
return EditorState.create({ return EditorState.create({
doc: initialContents, doc: initialContents,
@@ -52,19 +58,22 @@
}); });
} }
function createEditorView(state: any, parent: HTMLElement) { function createEditorView(state: EditorState, parent: HTMLElement) {
return new EditorView({ state, parent }); return new EditorView({ state, parent });
} }
onMount(() => { onMount(() => {
const editor = document.querySelector('#cm-target');
if (editor) { if (editor) {
const state = createEditorState('body {\n color: red;\n}'); const state = createEditorState(value);
const view = createEditorView(state, editor as HTMLElement); view = createEditorView(state, editor as HTMLElement);
console.log(view)
} }
}); });
onDestroy(() => {
if (view) {
view.destroy();
}
})
</script> </script>
<div id="cm-target"></div> <div class="rounded-lg text-[13px] overflow-clip w-full bg-white dark:bg-zinc-900" bind:this={editor}></div>
+5
View File
@@ -39,4 +39,9 @@ input {
to { to {
opacity: 1; opacity: 1;
} }
}
.cm-editor {
width: 100%;
min-height: 100px;
} }
+13 -15
View File
@@ -32,7 +32,6 @@
}) })
onMount(async () => { onMount(async () => {
console.log(themeID)
if (themeID) { if (themeID) {
const tempTheme = await getTheme(themeID) const tempTheme = await getTheme(themeID)
@@ -66,19 +65,17 @@
<h2 class="text-sm font-bold">{item.title}</h2> <h2 class="text-sm font-bold">{item.title}</h2>
<p class="text-xs">{item.description}</p> <p class="text-xs">{item.description}</p>
</div> </div>
<div> {#if item.type === 'switch'}
{#if item.type === 'switch'} <Switch {...(item.props as SwitchProps)} />
<Switch {...(item.props as SwitchProps)} /> {:else if item.type === 'button'}
{:else if item.type === 'button'} <Button {...(item.props as ButtonProps)} />
<Button {...(item.props as ButtonProps)} /> {:else if item.type === 'slider'}
{:else if item.type === 'slider'} <Slider {...(item.props as SliderProps)} />
<Slider {...(item.props as SliderProps)} /> {:else if item.type === 'colourPicker'}
{:else if item.type === 'colourPicker'} <ColourPicker savePresets={false} standalone={true} {...(item.props)} />
<ColourPicker savePresets={false} standalone={true} {...(item.props)} /> {:else if item.type === 'codeEditor'}
{:else if item.type === 'codeEditor'} <CodeEditor {...(item.props as CodeEditorProps)} />
<CodeEditor /> <!-- {/*...(item.props as CodeEditorProps)*/} --> {/if}
{/if}
</div>
</div> </div>
{/snippet} {/snippet}
@@ -148,9 +145,10 @@
type: 'codeEditor', type: 'codeEditor',
title: 'Custom CSS', title: 'Custom CSS',
description: 'Add custom CSS to your theme', description: 'Add custom CSS to your theme',
direction: 'vertical',
props: { props: {
value: theme.CustomCSS, value: theme.CustomCSS,
onChange: (value) => theme.CustomCSS = value onChange: (value) => { theme.CustomCSS = value; console.log(theme.CustomCSS) }
} }
} }
] as SettingItem[] as setting} ] as SettingItem[] as setting}