Skip to content

Commit 7cc48ba

Browse files
committed
Adding the monaco editor element
1 parent 377b5bb commit 7cc48ba

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

data.json

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"image-gallery" : "Image Gallery",
1919
"menubar" : "Menu Bar",
2020
"modal" : "Modal",
21+
"monaco-editor" : "Monaco Editor",
2122
"navigation-menu" : "Navigation Menu",
2223
"pagination" : "Pagination",
2324
"popover" : "Popover",
@@ -56,6 +57,7 @@
5657
"hover-card" : "A hover element card preview.",
5758
"image-gallery" : "A simple image gallery element for showing images.",
5859
"modal" : "A simple modal element that can be used to show and hide content.",
60+
"monaco-editor" : "A simple code editor using the Monaco editor library.",
5961
"menubar" : "A visually persistent menu common in desktop applications, offering convenient access to a consistent set of commands.",
6062
"navigation-menu" : "A simple navigation menu element",
6163
"pagination" : "A pagination element that can be used to navigate through pages of content.",
@@ -95,6 +97,7 @@
9597
"hover-card" : "w-full sm:p-10 p-4 box-border flex items-center justify-center",
9698
"image-gallery" : "w-full sm:p-10 p-4 box-border flex items-center justify-center",
9799
"modal" : "w-full sm:p-10 p-4 box-border flex items-center justify-center",
100+
"monaco-editor" : "w-full h-full box-border flex overflow-hidden items-stretch justify-center",
98101
"menubar" : "w-full sm:p-10 p-4 box-border flex items-center justify-center",
99102
"navigation-menu" : "w-full sm:p-10 p-4 box-border flex items-center justify-center",
100103
"pagination" : "w-full flex items-end justify-center",

elements/monaco-editor.html

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<div x-data="{
2+
monacoContent: '',
3+
monacoLanguage: 'html',
4+
monacoPlaceholder: true,
5+
monacoPlaceholderText: 'Start typing here',
6+
monacoLoader: true,
7+
monacoFontSize: '15px',
8+
monacoId: $id('monaco-editor'),
9+
monacoEditor(editor){
10+
editor.onDidChangeModelContent((e) => {
11+
this.monacoContent = editor.getValue();
12+
this.updatePlaceholder(editor.getValue());
13+
});
14+
15+
editor.onDidBlurEditorWidget(() => {
16+
this.updatePlaceholder(editor.getValue());
17+
});
18+
19+
editor.onDidFocusEditorWidget(() => {
20+
this.updatePlaceholder(editor.getValue());
21+
});
22+
},
23+
updatePlaceholder: function(value) {
24+
if (value == '') {
25+
this.monacoPlaceholder = true;
26+
return;
27+
}
28+
this.monacoPlaceholder = false;
29+
},
30+
monacoEditorFocus(){
31+
document.getElementById(this.monacoId).dispatchEvent(new CustomEvent('monaco-editor-focused', { monacoId: this.monacoId }));
32+
},
33+
monacoEditorAddLoaderScriptToHead() {
34+
script = document.createElement('script');
35+
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min/vs/loader.min.js';
36+
document.head.appendChild(script);
37+
}
38+
}"
39+
x-init="
40+
41+
if(typeof _amdLoaderGlobal == 'undefined'){
42+
monacoEditorAddLoaderScriptToHead();
43+
}
44+
45+
monacoLoaderInterval = setInterval(function(){
46+
if(typeof _amdLoaderGlobal !== 'undefined'){
47+
48+
// Based on https://jsfiddle.net/developit/bwgkr6uq/ which works without needing service worker. Provided by loader.min.js.
49+
require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.39.0/min/vs' }});
50+
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' }));
51+
window.MonacoEnvironment = { getWorkerUrl: () => proxy };
52+
53+
require(['vs/editor/editor.main'], function() {
54+
55+
monacoTheme = {'base':'vs-dark','inherit':true,'rules':[{'background':'0C1021','token':''},{'foreground':'aeaeae','token':'comment'},{'foreground':'d8fa3c','token':'constant'},{'foreground':'ff6400','token':'entity'},{'foreground':'fbde2d','token':'keyword'},{'foreground':'fbde2d','token':'storage'},{'foreground':'61ce3c','token':'string'},{'foreground':'61ce3c','token':'meta.verbatim'},{'foreground':'8da6ce','token':'support'},{'foreground':'ab2a1d','fontStyle':'italic','token':'invalid.deprecated'},{'foreground':'f8f8f8','background':'9d1e15','token':'invalid.illegal'},{'foreground':'ff6400','fontStyle':'italic','token':'entity.other.inherited-class'},{'foreground':'ff6400','token':'string constant.other.placeholder'},{'foreground':'becde6','token':'meta.function-call.py'},{'foreground':'7f90aa','token':'meta.tag'},{'foreground':'7f90aa','token':'meta.tag entity'},{'foreground':'ffffff','token':'entity.name.section'},{'foreground':'d5e0f3','token':'keyword.type.variant'},{'foreground':'f8f8f8','token':'source.ocaml keyword.operator.symbol'},{'foreground':'8da6ce','token':'source.ocaml keyword.operator.symbol.infix'},{'foreground':'8da6ce','token':'source.ocaml keyword.operator.symbol.prefix'},{'fontStyle':'underline','token':'source.ocaml keyword.operator.symbol.infix.floating-point'},{'fontStyle':'underline','token':'source.ocaml keyword.operator.symbol.prefix.floating-point'},{'fontStyle':'underline','token':'source.ocaml constant.numeric.floating-point'},{'background':'ffffff08','token':'text.tex.latex meta.function.environment'},{'background':'7a96fa08','token':'text.tex.latex meta.function.environment meta.function.environment'},{'foreground':'fbde2d','token':'text.tex.latex support.function'},{'foreground':'ffffff','token':'source.plist string.unquoted'},{'foreground':'ffffff','token':'source.plist keyword.operator'}],'colors':{'editor.foreground':'#F8F8F8','editor.background':'#0C1021','editor.selectionBackground':'#253B76','editor.lineHighlightBackground':'#FFFFFF0F','editorCursor.foreground':'#FFFFFFA6','editorWhitespace.foreground':'#FFFFFF40'}};
56+
monaco.editor.defineTheme('blackboard', monacoTheme);
57+
document.getElementById(monacoId).editor = monaco.editor.create($refs.monacoEditorElement, {
58+
value: monacoContent,
59+
theme: 'blackboard',
60+
fontSize: monacoFontSize,
61+
lineNumbersMinChars: 3,
62+
automaticLayout: true,
63+
language: monacoLanguage
64+
});
65+
monacoEditor(document.getElementById(monacoId).editor);
66+
document.getElementById(monacoId).addEventListener('monaco-editor-focused', function(event){
67+
document.getElementById(monacoId).editor.focus();
68+
});
69+
updatePlaceholder(document.getElementById(monacoId).editor.getValue());
70+
71+
});
72+
73+
clearInterval(monacoLoaderInterval);
74+
monacoLoader = false;
75+
}
76+
}, 5);
77+
" :id="monacoId" class="flex flex-col items-center relative justify-start w-full bg-[#0C1021] min-h-[250px] pt-3 h-100">
78+
<div x-show="monacoLoader" class="absolute inset-0 z-20 flex items-center justify-center w-full h-full duration-1000 ease-out">
79+
<svg class="w-4 h-4 text-gray-400 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
80+
</div>
81+
82+
<div x-show="!monacoLoader" class="relative z-10 w-full h-full">
83+
<div x-ref="monacoEditorElement" class="w-full h-full text-lg"></div>
84+
<div x-ref="monacoPlaceholderElement" x-show="monacoPlaceholder" @click="monacoEditorFocus()" :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>
85+
</div>
86+
</div>

elements/monaco-editor.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"data" : {
3+
"monacoContent" : "The initial value inside of the editor",
4+
"monacoLanguage" : "The language that should be used for syntax highlighting",
5+
"monacoPlaceholder" : "Sepcify whether or not you want a placeholder in the editor when there is not code in the editor",
6+
"monacoPlaceholderText" : "The placeholder text to be used inside of the editor when no code is present",
7+
"monacoLoader" : "This is used to show a loading indicator before the editor has been initialized and ready",
8+
"monacoFontSize" : "The font size to be used inside of the editor (may need to adjust the placeholder when changing this)",
9+
"monacoId" : "Used to add a unique ID to this element, allowing you to have multiple editors on the same page",
10+
"monacoEditor(editor)" : "This is the method that you can use to add your Monaco Events (learn more below)",
11+
"updatePlaceholder(value)" : "This method is used to update the placeholder text inside of the editor",
12+
"monacoEditorFocus" : "This method is used to focus the editor",
13+
"monacoEditorAddLoaderScriptToHead" : "This method is used to add the monaco editor loader script to the head of the document"
14+
},
15+
"alert_notification" : {
16+
"title" : "Monaco Editor Library",
17+
"description" : "This element uses the <a href=\"https://microsoft.github.io/monaco-editor/\" target=\"_blank\" class=\"underline\">Monaco Editor</a>, You can add events and listeners for <a href=\"https://microsoft.github.io/monaco-editor/docs.html#modules/editor.html\" target=\"_blank\" class=\"underline\">the editor</a> object inside of the <strong>monacoEditor(editor)</strong> method."
18+
},
19+
"additional" : {
20+
"description" : "<p>Inside of the <strong>x-init</strong> method, after the editor is loaded, you'll find a variable definition like so: <strong>monacoTheme = {}</strong>, you can change the theme by adding your own or including it from the <a href=\"https://github.com/brijeshb42/monaco-themes\" target=\"_blank\" class=\"underline\">monaco themes repo here</a>. View a <a href=\"https://editor.bitwiser.in\" target=\"_blank\" class=\"underline\">demo of all the available themes here</a>.</p>"
21+
}
22+
}

0 commit comments

Comments
 (0)