dees-editor/ts_web/elements/dees-editor.ts

127 lines
3.2 KiB
TypeScript
Raw Normal View History

2022-05-20 14:26:03 +00:00
import {
DeesElement,
property,
html,
customElement,
2023-09-21 18:16:32 +00:00
type TemplateResult,
2022-05-20 14:26:03 +00:00
css,
cssManager,
2023-09-21 18:16:32 +00:00
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
2022-03-10 16:25:29 +00:00
import type * as monaco from 'monaco-editor';
declare global {
interface HTMLElementTagNameMap {
2022-03-10 16:36:11 +00:00
'dees-editor': DeesEditor;
2022-03-10 16:25:29 +00:00
}
}
@customElement('dees-editor')
export class DeesEditor extends DeesElement {
2022-05-20 14:26:03 +00:00
// 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.rxjs.Subject<string>();
@property({
type: Boolean
})
public wordWrap: monaco.editor.IStandaloneEditorConstructionOptions['wordWrap'] = 'off';
2022-03-10 16:25:29 +00:00
constructor() {
super();
domtools.DomTools.setupDomTools();
}
public static styles = [
domtools.elementBasic.staticStyles,
css`
:host {
}
* {
box-sizing: border-box;
}
#container {
position: absolute;
height: 100%;
width: 100%;
}
2022-05-20 14:26:03 +00:00
`,
];
2022-03-10 16:25:29 +00:00
2022-05-20 14:26:03 +00:00
public render(): TemplateResult {
2022-03-10 16:25:29 +00:00
return html`
<div class="mainbox">
<div id="container"></div>
</div>
`;
}
2022-05-20 14:26:03 +00:00
public async firstUpdated(
_changedProperties: Map<string | number | symbol, unknown>
): Promise<void> {
2022-03-10 16:25:29 +00:00
super.firstUpdated(_changedProperties);
const container = this.shadowRoot.getElementById('container');
2022-05-20 14:26:03 +00:00
if (!DeesEditor.monacoDeferred) {
DeesEditor.monacoDeferred = domtools.plugins.smartpromise.defer();
2022-03-10 16:25:29 +00:00
const scriptUrl = `https://cdn.jsdelivr.net/npm/monaco-editor/min/vs/loader.js`;
const script = document.createElement('script');
script.src = scriptUrl;
script.onload = () => {
2022-05-20 14:26:03 +00:00
DeesEditor.monacoDeferred.resolve();
};
2022-03-10 16:25:29 +00:00
document.head.appendChild(script);
}
2022-05-20 14:26:03 +00:00
await DeesEditor.monacoDeferred.promise;
2022-03-10 16:25:29 +00:00
(window as any).require.config({
2022-05-20 14:26:03 +00:00
paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor/min/vs' },
2022-03-10 16:25:29 +00:00
});
2022-05-20 14:26:03 +00:00
(window as any).require(['vs/editor/editor.main'], async () => {
2022-05-19 11:51:11 +00:00
const editor = ((window as any).monaco.editor as typeof monaco.editor).create(container, {
2022-05-20 14:26:03 +00:00
value: this.content,
language: this.language,
2022-03-10 16:25:29 +00:00
theme: 'vs-dark',
2022-05-19 11:51:11 +00:00
useShadowDOM: true,
fontSize: 16,
automaticLayout: true,
2022-05-20 14:26:03 +00:00
wordWrap: this.wordWrap
2022-03-10 16:25:29 +00:00
});
2022-05-20 14:26:03 +00:00
this.editorDeferred.resolve(editor);
2022-03-10 16:25:29 +00:00
});
2022-05-20 14:26:03 +00:00
const css = await (
await fetch('https://cdn.jsdelivr.net/npm/monaco-editor/min/vs/editor/editor.main.css')
).text();
2022-05-18 01:19:55 +00:00
const styleElement = document.createElement('style');
styleElement.textContent = css;
this.shadowRoot.append(styleElement);
2022-05-20 14:26:03 +00:00
// 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());
2022-03-10 16:25:29 +00:00
}
2022-05-20 14:26:03 +00:00
}