From 1d413e10a2d959c819732044882d7d985d1467a0 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:09:24 +0100 Subject: [PATCH] fix: monaco editor light and dark mode switching --- .../components/forms/monaco-editor.blade.php | 367 +----------------- 1 file changed, 17 insertions(+), 350 deletions(-) diff --git a/resources/views/components/forms/monaco-editor.blade.php b/resources/views/components/forms/monaco-editor.blade.php index d3793785b..a4bc88051 100644 --- a/resources/views/components/forms/monaco-editor.blade.php +++ b/resources/views/components/forms/monaco-editor.blade.php @@ -7,6 +7,9 @@ monacoLoader: true, monacoFontSize: '15px', monacoId: $id('monaco-editor'), + isDarkMode() { + return document.documentElement.classList.contains('dark') || localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches); + }, monacoEditor(editor) { editor.onDidChangeModelContent((e) => { this.monacoContent = editor.getValue(); @@ -41,357 +44,9 @@ let proxy = URL.createObjectURL(new Blob([` self.MonacoEnvironment = { baseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min' }; importScripts('https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min/vs/base/worker/workerMain.min.js');`], { type: 'text/javascript' })); window.MonacoEnvironment = { getWorkerUrl: () => proxy }; require(['vs/editor/editor.main'], () => { - monaco.editor.defineTheme('blackboard', { - 'base': 'vs-dark', - 'inherit': true, - 'rules': [{ - 'background': editorBackground, - 'token': '' - }, - { - 'foreground': '959da5', - 'token': 'comment' - }, - { - 'foreground': '959da5', - 'token': 'punctuation.definition.comment' - }, - { - 'foreground': '959da5', - 'token': 'string.comment' - }, - { - 'foreground': 'c8e1ff', - 'token': 'constant' - }, - { - 'foreground': 'c8e1ff', - 'token': 'entity.name.constant' - }, - { - 'foreground': 'c8e1ff', - 'token': 'variable.other.constant' - }, - { - 'foreground': 'c8e1ff', - 'token': 'variable.language' - }, - { - 'foreground': 'b392f0', - 'token': 'entity' - }, - { - 'foreground': 'b392f0', - 'token': 'entity.name' - }, - { - 'foreground': 'f6f8fa', - 'token': 'variable.parameter.function' - }, - { - 'foreground': '7bcc72', - 'token': 'entity.name.tag' - }, - { - 'foreground': 'ea4a5a', - 'token': 'keyword' - }, - { - 'foreground': 'ea4a5a', - 'token': 'storage' - }, - { - 'foreground': 'ea4a5a', - 'token': 'storage.type' - }, - { - 'foreground': 'f6f8fa', - 'token': 'storage.modifier.package' - }, - { - 'foreground': 'f6f8fa', - 'token': 'storage.modifier.import' - }, - { - 'foreground': 'f6f8fa', - 'token': 'storage.type.java' - }, - { - 'foreground': '79b8ff', - 'token': 'string' - }, - { - 'foreground': '79b8ff', - 'token': 'punctuation.definition.string' - }, - { - 'foreground': '79b8ff', - 'token': 'string punctuation.section.embedded source' - }, - { - 'foreground': 'c8e1ff', - 'token': 'support' - }, - { - 'foreground': 'c8e1ff', - 'token': 'meta.property-name' - }, - { - 'foreground': 'fb8532', - 'token': 'variable' - }, - { - 'foreground': 'f6f8fa', - 'token': 'variable.other' - }, - { - 'foreground': 'd73a49', - 'fontStyle': 'bold italic underline', - 'token': 'invalid.broken' - }, - { - 'foreground': 'd73a49', - 'fontStyle': 'bold italic underline', - 'token': 'invalid.deprecated' - }, - { - 'foreground': 'fafbfc', - 'background': 'd73a49', - 'fontStyle': 'italic underline', - 'token': 'invalid.illegal' - }, - { - 'foreground': 'fafbfc', - 'background': 'd73a49', - 'fontStyle': 'italic underline', - 'token': 'carriage-return' - }, - { - 'foreground': 'd73a49', - 'fontStyle': 'bold italic underline', - 'token': 'invalid.unimplemented' - }, - { - 'foreground': 'd73a49', - 'token': 'message.error' - }, - { - 'foreground': 'f6f8fa', - 'token': 'string source' - }, - { - 'foreground': 'c8e1ff', - 'token': 'string variable' - }, - { - 'foreground': '79b8ff', - 'token': 'source.regexp' - }, - { - 'foreground': '79b8ff', - 'token': 'string.regexp' - }, - { - 'foreground': '79b8ff', - 'token': 'string.regexp.character-class' - }, - { - 'foreground': '79b8ff', - 'token': 'string.regexp constant.character.escape' - }, - { - 'foreground': '79b8ff', - 'token': 'string.regexp source.ruby.embedded' - }, - { - 'foreground': '79b8ff', - 'token': 'string.regexp string.regexp.arbitrary-repitition' - }, - { - 'foreground': '7bcc72', - 'fontStyle': 'bold', - 'token': 'string.regexp constant.character.escape' - }, - { - 'foreground': 'c8e1ff', - 'token': 'support.constant' - }, - { - 'foreground': 'c8e1ff', - 'token': 'support.variable' - }, - { - 'foreground': 'c8e1ff', - 'token': 'meta.module-reference' - }, - { - 'foreground': 'fb8532', - 'token': 'markup.list' - }, - { - 'foreground': '0366d6', - 'fontStyle': 'bold', - 'token': 'markup.heading' - }, - { - 'foreground': '0366d6', - 'fontStyle': 'bold', - 'token': 'markup.heading entity.name' - }, - { - 'foreground': 'c8e1ff', - 'token': 'markup.quote' - }, - { - 'foreground': 'f6f8fa', - 'fontStyle': 'italic', - 'token': 'markup.italic' - }, - { - 'foreground': 'f6f8fa', - 'fontStyle': 'bold', - 'token': 'markup.bold' - }, - { - 'foreground': 'c8e1ff', - 'token': 'markup.raw' - }, - { - 'foreground': 'b31d28', - 'background': 'ffeef0', - 'token': 'markup.deleted' - }, - { - 'foreground': 'b31d28', - 'background': 'ffeef0', - 'token': 'meta.diff.header.from-file' - }, - { - 'foreground': 'b31d28', - 'background': 'ffeef0', - 'token': 'punctuation.definition.deleted' - }, - { - 'foreground': '176f2c', - 'background': 'f0fff4', - 'token': 'markup.inserted' - }, - { - 'foreground': '176f2c', - 'background': 'f0fff4', - 'token': 'meta.diff.header.to-file' - }, - { - 'foreground': '176f2c', - 'background': 'f0fff4', - 'token': 'punctuation.definition.inserted' - }, - { - 'foreground': 'b08800', - 'background': 'fffdef', - 'token': 'markup.changed' - }, - { - 'foreground': 'b08800', - 'background': 'fffdef', - 'token': 'punctuation.definition.changed' - }, - { - 'foreground': '2f363d', - 'background': '959da5', - 'token': 'markup.ignored' - }, - { - 'foreground': '2f363d', - 'background': '959da5', - 'token': 'markup.untracked' - }, - { - 'foreground': 'b392f0', - 'fontStyle': 'bold', - 'token': 'meta.diff.range' - }, - { - 'foreground': 'c8e1ff', - 'token': 'meta.diff.header' - }, - { - 'foreground': '0366d6', - 'fontStyle': 'bold', - 'token': 'meta.separator' - }, - { - 'foreground': '0366d6', - 'token': 'meta.output' - }, - { - 'foreground': 'ffeef0', - 'token': 'brackethighlighter.tag' - }, - { - 'foreground': 'ffeef0', - 'token': 'brackethighlighter.curly' - }, - { - 'foreground': 'ffeef0', - 'token': 'brackethighlighter.round' - }, - { - 'foreground': 'ffeef0', - 'token': 'brackethighlighter.square' - }, - { - 'foreground': 'ffeef0', - 'token': 'brackethighlighter.angle' - }, - { - 'foreground': 'ffeef0', - 'token': 'brackethighlighter.quote' - }, - { - 'foreground': 'd73a49', - 'token': 'brackethighlighter.unmatched' - }, - { - 'foreground': 'd73a49', - 'token': 'sublimelinter.mark.error' - }, - { - 'foreground': 'fb8532', - 'token': 'sublimelinter.mark.warning' - }, - { - 'foreground': '6a737d', - 'token': 'sublimelinter.gutter-mark' - }, - { - 'foreground': '79b8ff', - 'fontStyle': 'underline', - 'token': 'constant.other.reference.link' - }, - { - 'foreground': '79b8ff', - 'fontStyle': 'underline', - 'token': 'string.other.link' - } - ], - 'colors': { - 'editor.foreground': '#f6f8fa', - 'editor.background': editorBackground, - 'editor.selectionBackground': '#4c2889', - 'editor.inactiveSelectionBackground': '#444d56', - 'editor.lineHighlightBackground': '#444d56', - 'editorCursor.foreground': '#ffffff', - 'editorWhitespace.foreground': '#6a737d', - 'editorIndentGuide.background': '#6a737d', - 'editorIndentGuide.activeBackground': '#f6f8fa', - 'editor.selectionHighlightBorder': '#444d56' - } - }); - const editor = monaco.editor.create($refs.monacoEditorElement, { value: monacoContent, - theme: editorTheme, + theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs', wordWrap: 'on', readOnly: '{{ $readonly ?? false }}', minimap: { enabled: false }, @@ -399,7 +54,20 @@ lineNumbersMinChars: 3, automaticLayout: true, language: '{{ $language }}' + }); + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.attributeName === 'class') { + const isDark = document.documentElement.classList.contains('dark'); + monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs'); + } + }); + }); + + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class'] }); monacoEditor(editor); @@ -411,7 +79,6 @@ updatePlaceholder(editor.getValue()); - // Watch for changes in monacoContent from Livewire $watch('monacoContent', value => { if (editor.getValue() !== value) { editor.setValue(value);