coolify/resources/views/components/forms/monaco-editor.blade.php

125 lines
6 KiB
PHP
Raw Permalink Normal View History

2024-06-23 18:33:22 +00:00
<div wire:key="{{ rand() }}" class="coolify-monaco-editor flex-1">
2024-06-24 09:21:39 +00:00
<div x-ref="monacoRef" x-data="{
monacoVersion: '0.52.2',
2024-06-23 18:33:22 +00:00
monacoContent: @entangle($id),
monacoLanguage: '',
monacoPlaceholder: true,
monacoPlaceholderText: 'Start typing here',
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);
},
2024-06-23 18:33:22 +00:00
monacoEditor(editor) {
editor.onDidChangeModelContent((e) => {
this.monacoContent = editor.getValue();
this.updatePlaceholder(editor.getValue());
});
editor.onDidBlurEditorWidget(() => {
this.updatePlaceholder(editor.getValue());
});
editor.onDidFocusEditorWidget(() => {
this.updatePlaceholder(editor.getValue());
});
},
updatePlaceholder(value) {
this.monacoPlaceholder = value === '';
},
monacoEditorFocus() {
2024-06-24 09:21:39 +00:00
document.getElementById(this.monacoId).dispatchEvent(new CustomEvent('monaco-editor-focused', { detail: { monacoId: this.monacoId } }));
2024-06-23 18:33:22 +00:00
},
monacoEditorAddLoaderScriptToHead() {
// Use a global flag to prevent duplicate script loading
if (!window.__coolifyMonacoLoaderAdding && typeof _amdLoaderGlobal === 'undefined') {
window.__coolifyMonacoLoaderAdding = true;
let script = document.createElement('script');
script.src = `/js/monaco-editor-${this.monacoVersion}/min/vs/loader.js`;
script.onload = () => {
window.__coolifyMonacoLoaderAdding = false;
};
script.onerror = () => {
window.__coolifyMonacoLoaderAdding = false;
};
document.head.appendChild(script);
}
2024-06-23 18:33:22 +00:00
}
2024-06-24 09:21:39 +00:00
}" x-modelable="monacoContent">
<div x-cloak x-init="if (typeof _amdLoaderGlobal == 'undefined' && !window.__coolifyMonacoLoaderAdding) {
2024-06-23 18:33:22 +00:00
monacoEditorAddLoaderScriptToHead();
}
2024-06-24 09:21:39 +00:00
checkTheme();
2024-06-23 18:33:22 +00:00
let monacoLoaderInterval = setInterval(() => {
2024-06-24 09:21:39 +00:00
if (typeof _amdLoaderGlobal !== 'undefined') {
require.config({ paths: { 'vs': `/js/monaco-editor-${monacoVersion}/min/vs` } });
let proxy = URL.createObjectURL(new Blob([`self.MonacoEnvironment={baseUrl:'${window.location.origin}/js/monaco-editor-${monacoVersion}/min'};importScripts('${window.location.origin}/js/monaco-editor-${monacoVersion}/min/vs/base/worker/workerMain.js');`], { type: 'text/javascript' }));
2024-06-23 18:33:22 +00:00
window.MonacoEnvironment = { getWorkerUrl: () => proxy };
require(['vs/editor/editor.main'], () => {
const editor = monaco.editor.create($refs.monacoEditorElement, {
value: monacoContent,
theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
2024-06-24 09:21:39 +00:00
wordWrap: 'on',
readOnly: '{{ $readonly ?? false }}',
minimap: { enabled: false },
2024-06-23 18:33:22 +00:00
fontSize: monacoFontSize,
lineNumbersMinChars: 3,
automaticLayout: true,
2025-01-14 07:49:03 +00:00
language: '{{ $language }}',
domReadOnly: '{{ $readonly ?? false }}',
contextmenu: '!{{ $readonly ?? false }}',
renderLineHighlight: '{{ $readonly ?? false }} ? none : all',
stickyScroll: { enabled: false }
});
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']
2024-06-23 18:33:22 +00:00
});
2024-06-23 18:33:22 +00:00
monacoEditor(editor);
2024-06-23 18:33:22 +00:00
document.getElementById(monacoId).editor = editor;
document.getElementById(monacoId).addEventListener('monaco-editor-focused', (event) => {
editor.focus();
});
2025-10-16 07:48:32 +00:00
2024-06-23 18:33:22 +00:00
updatePlaceholder(editor.getValue());
2025-10-16 07:48:32 +00:00
@if ($autofocus)
// Auto-focus the editor
setTimeout(() => editor.focus(), 100);
@endif
2024-06-23 18:33:22 +00:00
$watch('monacoContent', value => {
if (editor.getValue() !== value) {
editor.setValue(value);
}
});
2024-06-23 18:33:22 +00:00
});
clearInterval(monacoLoaderInterval);
monacoLoader = false;
2024-06-23 18:33:22 +00:00
}
2024-06-24 09:21:39 +00:00
}, 5);" :id="monacoId">
2024-06-23 18:33:22 +00:00
</div>
2024-06-24 09:21:39 +00:00
<div class="relative z-10 w-full h-full">
<div x-ref="monacoEditorElement" class="w-full text-md {{ $readonly ? 'opacity-65' : '' }}" style="height: var(--editor-height, calc(100vh - 20rem)); min-height: 300px;"></div>
2024-06-23 18:33:22 +00:00
<div x-ref="monacoPlaceholderElement" x-show="monacoPlaceholder" @click="monacoEditorFocus()"
2024-06-24 09:21:39 +00:00
:style="'font-size: ' + monacoFontSize"
class="w-full text-sm font-mono absolute z-50 text-gray-500 ml-14 -translate-x-0.5 mt-0.5 left-0 top-0"
x-text="monacoPlaceholderText"></div>
2024-06-23 18:33:22 +00:00
</div>
</div>
</div>