import { property, state, query } from "lit/decorators.js";
import { msg, localized } from "@lit/localize";
import {
parse as yamlToJson,
stringify as yamlStringify,
YAMLParseError,
} from "yaml";
import LiteElement, { html } from "../utils/LiteElement";
/**
* Usage example:
* ```ts
*
*
* ```
*
* @event on-change
*/
@localized()
export class ConfigEditor extends LiteElement {
@property({ type: String })
value = "";
@state()
errorMessage = "";
@query("#config-editor-textarea")
textareaElem?: HTMLTextAreaElement;
render() {
return html`
${this.renderTextArea()}
${this.errorMessage
? html`
${this.errorMessage}
`
: ""}
`;
}
private renderTextArea() {
const lineCount = this.value.split("\n").length;
return html`
${[...new Array(lineCount)].map((line, i) => html`${i + 1}
`)}
`;
}
private handleParseError(error: Error) {
if (error instanceof YAMLParseError) {
const errorMessage = error.message.replace("YAMLParseError: ", "");
this.errorMessage = errorMessage;
} else {
this.errorMessage = msg("Invalid YAML or JSON");
console.debug(error);
}
}
private checkValidity(value: string) {
yamlToJson(value);
}
private onBlur(value: string) {
if (!value) {
this.textareaElem?.setCustomValidity(msg("Please fill out this field"));
this.textareaElem?.reportValidity();
}
}
private onChange(value: string) {
try {
this.checkValidity(value);
this.textareaElem?.setCustomValidity("");
this.errorMessage = "";
this.dispatchEvent(
new CustomEvent("on-change", {
detail: {
value: value,
},
})
);
} catch (e: any) {
this.textareaElem?.setCustomValidity(msg("Please fix errors"));
this.handleParseError(e);
}
this.textareaElem?.reportValidity();
}
/**
* Stop propgation of sl-select events.
* Prevents bug where sl-dialog closes when dropdown closes
* https://github.com/shoelace-style/shoelace/issues/170
*/
private stopProp(e: CustomEvent) {
e.stopPropagation();
}
}