import { LitElement, html } from "lit"; import { state, property } from "lit/decorators.js"; import { guard } from "lit/directives/guard.js"; import { createWysimark } from "@wysimark/standalone"; import { getHelpText } from "../utils/form"; export type MarkdownChangeEvent = CustomEvent<{ value: string; }>; /** * Edit and preview text in markdown * * @event on-change MarkdownChangeEvent */ export class MarkdownEditor extends LitElement { @property({ type: String }) initialValue = ""; @property({ type: String }) name = "markdown"; @property({ type: Number }) maxlength?: number; @state() value = ""; createRenderRoot() { // Disable shadow DOM for styles to work return this; } protected updated(changedProperties: Map) { if (changedProperties.has("initialValue") && this.initialValue) { this.value = this.initialValue; this.initEditor(); } } protected firstUpdated(): void { if (!this.initialValue) { this.initEditor(); } } render() { const isInvalid = this.maxlength && this.value.length > this.maxlength; return html`
${guard( [this.initialValue], () => html`
` )} ${this.maxlength ? html`
${getHelpText(this.maxlength, this.value.length)}
` : ""}
`; } private initEditor() { const editor = createWysimark(this.querySelector(".markdown-editor")!, { initialMarkdown: this.initialValue, onChange: async () => { const value = editor.getMarkdown(); const input = this.querySelector( `input[name=${this.name}]` ) as HTMLTextAreaElement; input.value = value; this.value = value; await this.updateComplete; this.dispatchEvent( new CustomEvent("on-change", { detail: { value: value, }, }) ); }, }); } }