127 lines
3.3 KiB
TypeScript
127 lines
3.3 KiB
TypeScript
import {
|
|
DeesElement,
|
|
property,
|
|
html,
|
|
customElement,
|
|
type TemplateResult,
|
|
css,
|
|
cssManager,
|
|
} from '@design.estate/dees-element';
|
|
import * as domtools from '@design.estate/dees-domtools';
|
|
|
|
import type * as monaco from 'monaco-editor';
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
'dees-editor': DeesEditor;
|
|
}
|
|
}
|
|
|
|
@customElement('dees-editor')
|
|
export class DeesEditor extends DeesElement {
|
|
// DEMO
|
|
public static demo = () => html` <dees-editor></dees-editor> `;
|
|
|
|
// STATIC
|
|
public static monacoDeferred: ReturnType<typeof domtools.plugins.smartpromise.defer>;
|
|
|
|
// INSTANCE
|
|
public editorDeferred = domtools.plugins.smartpromise.defer<monaco.editor.IStandaloneCodeEditor>();
|
|
public language = 'typescript';
|
|
|
|
@property({
|
|
type: String
|
|
})
|
|
public content = "function hello() {\n\talert('Hello world!');\n}";
|
|
|
|
@property({
|
|
type: Object
|
|
})
|
|
public contentSubject = new domtools.plugins.smartrx.rxjs.Subject<string>();
|
|
|
|
@property({
|
|
type: Boolean
|
|
})
|
|
public wordWrap: monaco.editor.IStandaloneEditorConstructionOptions['wordWrap'] = 'off';
|
|
|
|
constructor() {
|
|
super();
|
|
domtools.DomTools.setupDomTools();
|
|
}
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
css`
|
|
:host {
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
#container {
|
|
position: absolute;
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
`,
|
|
];
|
|
|
|
public render(): TemplateResult {
|
|
return html`
|
|
<div class="mainbox">
|
|
<div id="container"></div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
public async firstUpdated(
|
|
_changedProperties: Map<string | number | symbol, unknown>
|
|
): Promise<void> {
|
|
super.firstUpdated(_changedProperties);
|
|
const container = this.shadowRoot.getElementById('container');
|
|
|
|
if (!DeesEditor.monacoDeferred) {
|
|
DeesEditor.monacoDeferred = domtools.plugins.smartpromise.defer();
|
|
const scriptUrl = `https://cdn.jsdelivr.net/npm/monaco-editor/min/vs/loader.js`;
|
|
const script = document.createElement('script');
|
|
script.src = scriptUrl;
|
|
script.onload = () => {
|
|
DeesEditor.monacoDeferred.resolve();
|
|
};
|
|
document.head.appendChild(script);
|
|
}
|
|
await DeesEditor.monacoDeferred.promise;
|
|
|
|
(window as any).require.config({
|
|
paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor/min/vs' },
|
|
});
|
|
(window as any).require(['vs/editor/editor.main'], async () => {
|
|
const editor = ((window as any).monaco.editor as typeof monaco.editor).create(container, {
|
|
value: this.content,
|
|
language: this.language,
|
|
theme: 'vs-dark',
|
|
useShadowDOM: true,
|
|
fontSize: 16,
|
|
automaticLayout: true,
|
|
wordWrap: this.wordWrap
|
|
});
|
|
this.editorDeferred.resolve(editor);
|
|
});
|
|
const css = await (
|
|
await fetch('https://cdn.jsdelivr.net/npm/monaco-editor/min/vs/editor/editor.main.css')
|
|
).text();
|
|
const styleElement = document.createElement('style');
|
|
styleElement.textContent = css;
|
|
this.shadowRoot.append(styleElement);
|
|
|
|
|
|
// editor is setup let do the rest
|
|
const editor = await this.editorDeferred.promise;
|
|
editor.onDidChangeModelContent(async eventArg => {
|
|
this.contentSubject.next(editor.getValue());
|
|
});
|
|
this.contentSubject.next(editor.getValue());
|
|
}
|
|
}
|