Trying out CodeMirror. I think I like it? Use it in readonly mode for view. Wrapping up for the day.
This commit is contained in:
2173
package-lock.json
generated
2173
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -96,7 +96,7 @@
|
|||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"@codemirror/view": "^6.36.8",
|
"@codemirror/view": "^6.36.8",
|
||||||
"@floating-ui/dom": "^1.6.0",
|
"@floating-ui/dom": "^1.6.0",
|
||||||
"@lucide/svelte": "^0.494.0",
|
"@lucide/svelte": "^0.510.0",
|
||||||
"@popperjs/core": "^2.11.0",
|
"@popperjs/core": "^2.11.0",
|
||||||
"@tiptap/extension-bullet-list": "^2.10.2",
|
"@tiptap/extension-bullet-list": "^2.10.2",
|
||||||
"@tiptap/extension-document": "^2.10.2",
|
"@tiptap/extension-document": "^2.10.2",
|
||||||
@@ -105,10 +105,10 @@
|
|||||||
"axios": "^1.7.0",
|
"axios": "^1.7.0",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"dexie": "^4.0.11",
|
"dexie": "^4.0.0",
|
||||||
"flowbite-svelte": "^0.48.00",
|
"flowbite-svelte": "^0.48.00",
|
||||||
"html5-qrcode": "^2.3.8",
|
"html5-qrcode": "^2.3.8",
|
||||||
"lucide-svelte": "^0.494.0",
|
"lucide-svelte": "^0.510.0",
|
||||||
"marked": "^15.0.7",
|
"marked": "^15.0.7",
|
||||||
"shadcn-svelte": "^0.14.0"
|
"shadcn-svelte": "^0.14.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,118 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
// *** Import Svelte version 5 specific
|
||||||
import { EditorView, keymap, placeholder as placeholderExt } from '@codemirror/view';
|
import { browser } from '$app/environment';
|
||||||
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
|
import { onMount, onDestroy, createEventDispatcher } from 'svelte';
|
||||||
export let content: string = 'test test test test';
|
import { EditorView, keymap, placeholder as placeholderExt } from '@codemirror/view';
|
||||||
export let new_content: string = '';
|
import { EditorState, StateEffect, type Extension } from '@codemirror/state';
|
||||||
export let language: Extension = javascript();
|
import { indentWithTab } from '@codemirror/commands';
|
||||||
export let theme: Extension = oneDark;
|
import { basicSetup } from 'codemirror';
|
||||||
export let extensions: Extension[] = [];
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
export let editable: boolean = true;
|
import { oneDark } from "@codemirror/theme-one-dark";
|
||||||
export let placeholder: string = 'Start typing...';
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{ change: string }>();
|
// 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...';
|
||||||
|
let classes = "";
|
||||||
|
export { classes as class };
|
||||||
|
|
||||||
let editor_element: HTMLDivElement;
|
let baseTheme = EditorView.baseTheme({
|
||||||
let editorView: EditorView;
|
".cm-o-replacement": {
|
||||||
|
display: "inline-block",
|
||||||
|
width: ".5em",
|
||||||
|
height: ".5em",
|
||||||
|
borderRadius: ".25em"
|
||||||
|
},
|
||||||
|
"&light .cm-o-replacement": {
|
||||||
|
backgroundColor: "#04c"
|
||||||
|
},
|
||||||
|
"&dark .cm-o-replacement": {
|
||||||
|
backgroundColor: "#5bf"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// theme == baseTheme;
|
||||||
|
|
||||||
// Reactive declaration for extensions
|
const dispatch = createEventDispatcher<{ change: string }>();
|
||||||
$: editor_extensions = [
|
|
||||||
basicSetup,
|
|
||||||
EditorView.editable.of(editable),
|
|
||||||
keymap.of([indentWithTab]),
|
|
||||||
placeholderExt(placeholder),
|
|
||||||
language,
|
|
||||||
theme,
|
|
||||||
...extensions
|
|
||||||
];
|
|
||||||
|
|
||||||
// Initialize CodeMirror on mount
|
let editor_element: HTMLDivElement;
|
||||||
onMount(() => {
|
let editorView: EditorView;
|
||||||
editorView = new EditorView({
|
|
||||||
state: EditorState.create({
|
// Reactive declaration for extensions
|
||||||
doc: content,
|
$: editor_extensions = [
|
||||||
extensions: editor_extensions,
|
basicSetup,
|
||||||
}),
|
EditorView.editable.of(editable),
|
||||||
parent: editor_element,
|
keymap.of([indentWithTab]),
|
||||||
dispatch: (transaction) => {
|
placeholderExt(placeholder),
|
||||||
editorView.update([transaction]);
|
language,
|
||||||
if (transaction.docChanged) {
|
theme,
|
||||||
new_content = editorView.state.doc.toString();
|
// baseTheme = {
|
||||||
const newContent = editorView.state.doc.toString();
|
// ".cm-o-replacement": {
|
||||||
dispatch('change', newContent);
|
// display: "inline-block",
|
||||||
}
|
// width: ".5em",
|
||||||
|
// height: ".5em",
|
||||||
|
// borderRadius: ".25em"
|
||||||
|
// },
|
||||||
|
// "&light .cm-o-replacement": {
|
||||||
|
// backgroundColor: "#04c"
|
||||||
|
// },
|
||||||
|
// "&dark .cm-o-replacement": {
|
||||||
|
// backgroundColor: "#5bf"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
...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
|
// Clean up on destroy
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
editorView?.destroy();
|
editorView?.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update editor content when `content` prop changes
|
// Update editor content when `content` prop changes
|
||||||
$: if (editorView && editorView.state.doc.toString() !== content) {
|
$: if (editorView && editorView.state.doc.toString() !== content) {
|
||||||
editorView.setState(
|
editorView.setState(
|
||||||
EditorState.create({
|
EditorState.create({
|
||||||
doc: content,
|
doc: content,
|
||||||
extensions: editor_extensions
|
extensions: editor_extensions
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={editor_element} class="codemirror-wrapper"></div>
|
{#if browser}
|
||||||
|
<div bind:this={editor_element} class="codemirror-wrapper {classes}"></div>
|
||||||
|
{:else}
|
||||||
|
<div class="scm-waiting {classes}">
|
||||||
|
<div class="scm-waiting__loading scm-loading">
|
||||||
|
<p class="scm-loading__text">Loading editor...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre class="scm-pre cm-editor">{value}</pre>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.codemirror-wrapper :global(.cm-focused) {
|
.codemirror-wrapper :global(.cm-focused) {
|
||||||
|
|||||||
@@ -1894,40 +1894,67 @@ tabindex={$ae_loc.edit_mode ? 0 : -1} -->
|
|||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="
|
|
||||||
flex-grow
|
|
||||||
h-full max-h-full
|
|
||||||
w-full min-w-full max-w-6xl"
|
|
||||||
> -->
|
|
||||||
<!-- disabled={tmp_entry_obj?.private && !$journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]} -->
|
|
||||||
<textarea
|
|
||||||
bind:value={tmp_entry_obj.content}
|
|
||||||
ondblclick={() => {
|
|
||||||
// if ($ae_loc.trusted_access && $ae_loc.edit_mode) {
|
|
||||||
// // Toggle edit mode
|
|
||||||
// $journals_loc.entry.edit = !$journals_loc.entry.edit;
|
|
||||||
// $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
|
||||||
// }
|
|
||||||
}}
|
|
||||||
|
|
||||||
class="
|
class="
|
||||||
flex-grow
|
flex-grow
|
||||||
flex-shrink-0
|
h-full max-h-full
|
||||||
basis-full
|
w-full min-w-full max-w-6xl"
|
||||||
h-max min-h-max max-h-full
|
> -->
|
||||||
w-full min-w-full max-w-6xl
|
<!-- disabled={tmp_entry_obj?.private && !$journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]} -->
|
||||||
p-2
|
|
||||||
space-y-1
|
{#if !$ae_loc.edit_mode || !$ae_loc.trusted_access}
|
||||||
font-mono
|
<textarea
|
||||||
bg-slate-100 text-gray-900
|
bind:value={tmp_entry_obj.content}
|
||||||
dark:bg-slate-900 dark:text-gray-100
|
ondblclick={() => {
|
||||||
shadow-lg rounded-lg
|
// if ($ae_loc.trusted_access && $ae_loc.edit_mode) {
|
||||||
border border-orange-200 dark:border-orange-700
|
// // Toggle edit mode
|
||||||
hover:border-orange-500 dark:hover:border-orange-500
|
// $journals_loc.entry.edit = !$journals_loc.entry.edit;
|
||||||
"
|
// $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
||||||
placeholder="Edit journal entry content here..."
|
// }
|
||||||
></textarea>
|
}}
|
||||||
|
|
||||||
|
class="
|
||||||
|
flex-grow
|
||||||
|
flex-shrink-0
|
||||||
|
basis-full
|
||||||
|
h-max min-h-max max-h-full
|
||||||
|
w-full min-w-full max-w-6xl
|
||||||
|
p-2
|
||||||
|
space-y-1
|
||||||
|
font-mono
|
||||||
|
bg-slate-100 text-gray-900
|
||||||
|
dark:bg-slate-900 dark:text-gray-100
|
||||||
|
shadow-lg rounded-lg
|
||||||
|
border border-orange-200 dark:border-orange-700
|
||||||
|
hover:border-orange-500 dark:hover:border-orange-500
|
||||||
|
"
|
||||||
|
placeholder="Edit journal entry content here..."
|
||||||
|
></textarea>
|
||||||
|
{:else}
|
||||||
|
|
||||||
|
<E_app_codemirror_v5
|
||||||
|
content={tmp_entry_obj?.content ?? ''}
|
||||||
|
bind:new_content={tmp_entry_obj.content}
|
||||||
|
language={markdown()}
|
||||||
|
placeholder="Write your JavaScript code here..."
|
||||||
|
classes="
|
||||||
|
flex-grow
|
||||||
|
flex-shrink-0
|
||||||
|
basis-full
|
||||||
|
h-max min-h-max max-h-full
|
||||||
|
w-full min-w-full max-w-6xl
|
||||||
|
p-2
|
||||||
|
space-y-1
|
||||||
|
font-mono
|
||||||
|
bg-slate-100 text-gray-900
|
||||||
|
dark:bg-slate-900 dark:text-gray-100
|
||||||
|
shadow-lg rounded-lg
|
||||||
|
border border-orange-200 dark:border-orange-700
|
||||||
|
hover:border-orange-500 dark:hover:border-orange-500
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
<!-- Only enable editing if the user has trusted access -->
|
<!-- Only enable editing if the user has trusted access -->
|
||||||
<button
|
<button
|
||||||
@@ -2054,16 +2081,16 @@ zzzz
|
|||||||
classes="editor"
|
classes="editor"
|
||||||
/> -->
|
/> -->
|
||||||
<!-- bind:content={tmp_entry_obj.content} -->
|
<!-- bind:content={tmp_entry_obj.content} -->
|
||||||
<E_app_codemirror_v5
|
<!-- <E_app_codemirror_v5
|
||||||
bind:content={tmp_entry_obj.content}
|
content={tmp_entry_obj?.content ?? ''}
|
||||||
bind:new_content={tmp_entry_obj.new_content}
|
bind:new_content={tmp_entry_obj.content}
|
||||||
language={markdown()}
|
language={markdown()}
|
||||||
placeholder="Write your JavaScript code here..."
|
placeholder="Write your JavaScript code here..."
|
||||||
/>
|
/> -->
|
||||||
|
|
||||||
<pre>
|
<!-- <pre>
|
||||||
{tmp_entry_obj.new_content}
|
{tmp_entry_obj.new_content}
|
||||||
</pre>
|
</pre> -->
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user