From bef4d34c437c78700d8f6b682a6cfb0350929163 Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Thu, 28 May 2026 19:29:55 +0200 Subject: [PATCH] feat(dashboard): CodeEditor readOnly prop Threads readOnly through to EditorState.readOnly + EditorView.editable so script-detail can render a viewer-only editor without intercepting keystrokes upstream. Co-Authored-By: Claude Opus 4.7 (1M context) --- dashboard/src/lib/CodeEditor.svelte | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dashboard/src/lib/CodeEditor.svelte b/dashboard/src/lib/CodeEditor.svelte index bae940d..fe2de69 100644 --- a/dashboard/src/lib/CodeEditor.svelte +++ b/dashboard/src/lib/CodeEditor.svelte @@ -25,12 +25,18 @@ value = $bindable(''), language = 'rhai' as Language, placeholder = '', - minHeight = '12rem' + minHeight = '12rem', + readOnly = false }: { value?: string; language?: Language; placeholder?: string; minHeight?: string; + /** When true the editor renders without a cursor and rejects + * keystrokes. Parent-driven `value` changes still apply via + * the dispatch path below — this only blocks user edits. + * Not reactive after mount; re-mount via `{#key}` if needed. */ + readOnly?: boolean; } = $props(); let host: HTMLDivElement | null = null; @@ -48,6 +54,12 @@ keymap.of([indentWithTab]), dashboardSyntaxHighlighting, dashboardTheme, + // readOnly + editable together: readOnly blocks the + // underlying transactions, editable suppresses the caret + // + selection visuals so the user can see it's not + // editable. + EditorState.readOnly.of(readOnly), + EditorView.editable.of(!readOnly), EditorView.updateListener.of((update) => { if (update.docChanged && !pushingFromOutside) { value = update.state.doc.toString();