src/components/AcrMarkdown.ts
:
import { LitElement, css, html } from "lit";
import { customElement, property, query } from "lit/decorators.js";
import ace from "ace-builds/src-min-noconflict/ace.js";
import { marked } from "marked";
@customElement("ace-markdown")
export class AceMarkdown extends LitElement {
@property({ type: String })
content = "";
@query("#editor")
editorElement!: HTMLDivElement;
@query("#previewer")
previewerElement!: HTMLDivElement;
firstUpdated() {
const editor = ace.edit(this.editorElement);
editor.renderer.attachToShadowRoot(); // !!!important
// editor.setTheme("ace/theme/monokai");
editor.session.setMode("ace/mode/markdown");
editor.session.setUseWrapMode(true);
editor.session.on('change', (delta) => {
this.content = editor.getValue();
this.previewerElement.innerHTML = marked(this.content).toString();
});
}
render() {
return html`
<div style="display: flex; height: 40vh">
<div style="flex: 50%">
<div id="editor" style="width: 100%; height: 100%;">${this.content}</div>
</div>
<div style="flex: 50%">
<div id="previewer" style="width: 100%; height: 100%; overflow: auto"></div>
</div>
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ace-markdown": AceMarkdown;
}
}
justfile
:
build:
#!/usr/bin/env bash
bun build src/components/ace.markdown.ts --outfile public/ace.markdown.js --minify
cp node_modules/ace-builds/src-min-noconflict/mode-markdown.js public/
cp node_modules/ace-builds/src-min-noconflict/theme-monokai.js public/