Convert YAMLTextArea to code mirror editor (#3980)

* Convert YAMLTextArea to code mirror editor

* Review comments

* Clean up
This commit is contained in:
Bram Kragten 2019-10-10 21:58:21 +02:00 committed by GitHub
parent ab75365636
commit 88c480759f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 56 deletions

View File

@ -3,9 +3,7 @@ import CodeMirror from "codemirror";
import "codemirror/mode/yaml/yaml";
// @ts-ignore
import codeMirrorCSS from "codemirror/lib/codemirror.css";
import { HomeAssistant } from "../../../types";
import { fireEvent } from "../../../common/dom/fire_event";
import { computeRTL } from "../../../common/util/compute_rtl";
import { fireEvent } from "../common/dom/fire_event";
import { customElement } from "lit-element";
declare global {
@ -17,12 +15,11 @@ declare global {
}
}
@customElement("hui-yaml-editor")
export class HuiYamlEditor extends HTMLElement {
public _hass?: HomeAssistant;
public codemirror!: any;
@customElement("ha-yaml-editor")
export class HaYamlEditor extends HTMLElement {
public codemirror?: any;
private _autofocus = false;
private _rtl = false;
private _value: string;
public constructor() {
@ -47,8 +44,11 @@ export class HuiYamlEditor extends HTMLElement {
background-color: var(--paper-dialog-background-color, var(--primary-background-color));
transition: 0.2s ease border-right;
}
:host(.error-state) .CodeMirror-gutters {
border-color: var(--error-state-color, red);
}
.CodeMirror-focused .CodeMirror-gutters {
border-right: 2px solid var(--paper-input-container-focus-color, var(--primary-color));;
border-right: 2px solid var(--paper-input-container-focus-color, var(--primary-color));
}
.CodeMirror-linenumber {
color: var(--paper-dialog-color, var(--primary-text-color));
@ -63,13 +63,6 @@ export class HuiYamlEditor extends HTMLElement {
</style>`;
}
set hass(hass: HomeAssistant) {
this._hass = hass;
if (this._hass) {
this.setScrollBarDirection();
}
}
set value(value: string) {
if (this.codemirror) {
if (value !== this.codemirror.getValue()) {
@ -83,6 +76,22 @@ export class HuiYamlEditor extends HTMLElement {
return this.codemirror.getValue();
}
set rtl(rtl: boolean) {
this._rtl = rtl;
this.setScrollBarDirection();
}
set autofocus(autofocus: boolean) {
this._autofocus = autofocus;
if (this.codemirror) {
this.codemirror.focus();
}
}
set error(error: boolean) {
this.classList.toggle("error-state", error);
}
get hasComments(): boolean {
return this.shadowRoot!.querySelector("span.cm-comment") ? true : false;
}
@ -96,16 +105,13 @@ export class HuiYamlEditor extends HTMLElement {
lineNumbers: true,
mode: "yaml",
tabSize: 2,
autofocus: true,
autofocus: this._autofocus,
viewportMargin: Infinity,
extraKeys: {
Tab: "indentMore",
"Shift-Tab": "indentLess",
},
gutters:
this._hass && computeRTL(this._hass!)
? ["rtl-gutter", "CodeMirror-linenumbers"]
: [],
gutters: this._rtl ? ["rtl-gutter", "CodeMirror-linenumbers"] : [],
}
);
this.setScrollBarDirection();
@ -120,18 +126,14 @@ export class HuiYamlEditor extends HTMLElement {
}
private setScrollBarDirection(): void {
if (!this.codemirror) {
return;
if (this.codemirror) {
this.codemirror.getWrapperElement().classList.toggle("rtl", this._rtl);
}
this.codemirror
.getWrapperElement()
.classList.toggle("rtl", computeRTL(this._hass!));
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-yaml-editor": HuiYamlEditor;
"ha-yaml-editor": HaYamlEditor;
}
}

View File

@ -20,6 +20,7 @@ declare global {
"ha-device-picker": any;
"ha-device-condition-picker": any;
"ha-textarea": any;
"ha-yaml-editor": any;
"ha-service-picker": any;
"mwc-button": any;
"ha-device-trigger-picker": any;

View File

@ -1,6 +1,8 @@
import { h, Component } from "preact";
import yaml from "js-yaml";
import "../../../components/ha-textarea";
import "../../../components/ha-yaml-editor";
// tslint:disable-next-line
import { HaYamlEditor } from "../../../components/ha-yaml-editor";
const isEmpty = (obj: object) => {
for (const key in obj) {
@ -12,6 +14,8 @@ const isEmpty = (obj: object) => {
};
export default class YAMLTextArea extends Component<any, any> {
private _yamlEditor!: HaYamlEditor;
constructor(props) {
super(props);
@ -34,7 +38,7 @@ export default class YAMLTextArea extends Component<any, any> {
}
public onChange(ev) {
const value = ev.target.value;
const value = ev.detail.value;
let parsed;
let isValid = true;
@ -59,22 +63,30 @@ export default class YAMLTextArea extends Component<any, any> {
}
}
public componentDidMount() {
setTimeout(() => {
this._yamlEditor.codemirror.refresh();
}, 1);
}
public render({ label }, { value, isValid }) {
const style: any = {
minWidth: 300,
width: "100%",
};
if (!isValid) {
style.border = "1px solid red";
}
return (
<ha-textarea
label={label}
value={value}
style={style}
onvalue-changed={this.onChange}
dir="ltr"
/>
<div>
<p>{label}</p>
<ha-yaml-editor
ref={this._storeYamlEditorRef}
style={style}
value={value}
error={isValid === false}
onyaml-changed={this.onChange}
/>
</div>
);
}
private _storeYamlEditorRef = (yamlEditor) => (this._yamlEditor = yamlEditor);
}

View File

@ -15,11 +15,12 @@ import { HomeAssistant } from "../../../../types";
import { LovelaceCardConfig } from "../../../../data/lovelace";
import { LovelaceCardEditor } from "../../types";
import { getCardElementTag } from "../../common/get-card-element-tag";
import { computeRTL } from "../../../../common/util/compute_rtl";
import "../../components/hui-yaml-editor";
import "../../../../components/ha-yaml-editor";
// This is not a duplicate import, one is for types, one is for element.
// tslint:disable-next-line
import { HuiYamlEditor } from "../../components/hui-yaml-editor";
import { HaYamlEditor } from "../../../../components/ha-yaml-editor";
import { fireEvent } from "../../../../common/dom/fire_event";
import { EntityConfig } from "../../entity-rows/types";
@ -43,7 +44,7 @@ export interface UIConfigChangedEvent extends Event {
@customElement("hui-card-editor")
export class HuiCardEditor extends LitElement {
@property() public hass?: HomeAssistant;
@property() public hass!: HomeAssistant;
@property() private _yaml?: string;
@property() private _config?: LovelaceCardConfig;
@ -93,8 +94,8 @@ export class HuiCardEditor extends LitElement {
return this._error !== undefined;
}
private get _yamlEditor(): HuiYamlEditor {
return this.shadowRoot!.querySelector("hui-yaml-editor")!;
private get _yamlEditor(): HaYamlEditor {
return this.shadowRoot!.querySelector("ha-yaml-editor")!;
}
public toggleMode() {
@ -120,11 +121,12 @@ export class HuiCardEditor extends LitElement {
`
: html`
<div class="yaml-editor">
<hui-yaml-editor
.hass=${this.hass}
<ha-yaml-editor
.autofocus=${true}
.rtl=${computeRTL(this.hass)}
.value=${this.yaml}
@yaml-changed=${this._handleYAMLChanged}
></hui-yaml-editor>
></ha-yaml-editor>
</div>
`}
${this._error

View File

@ -14,11 +14,12 @@ import { Lovelace } from "./types";
import "../../components/ha-icon";
import { haStyle } from "../../resources/styles";
import "./components/hui-yaml-editor";
import "../../components/ha-yaml-editor";
// This is not a duplicate import, one is for types, one is for element.
// tslint:disable-next-line
import { HuiYamlEditor } from "./components/hui-yaml-editor";
import { HaYamlEditor } from "../../components/ha-yaml-editor";
import { HomeAssistant } from "../../types";
import { computeRTL } from "../../common/util/compute_rtl";
const lovelaceStruct = struct.interface({
title: "string?",
@ -27,7 +28,7 @@ const lovelaceStruct = struct.interface({
});
class LovelaceFullConfigEditor extends LitElement {
public hass?: HomeAssistant;
public hass!: HomeAssistant;
public lovelace?: Lovelace;
public closeEditor?: () => void;
private _saving?: boolean;
@ -80,12 +81,14 @@ class LovelaceFullConfigEditor extends LitElement {
</app-toolbar>
</app-header>
<div class="content">
<hui-yaml-editor
<ha-yaml-editor
.autofocus=${true}
.rtl=${computeRTL(this.hass)}
.hass="${this.hass}"
@yaml-changed="${this._yamlChanged}"
@yaml-save="${this._handleSave}"
>
</hui-yaml-editor>
</ha-yaml-editor>
</div>
</app-header-layout>
`;
@ -205,8 +208,8 @@ class LovelaceFullConfigEditor extends LitElement {
this._changed = false;
}
private get yamlEditor(): HuiYamlEditor {
return this.shadowRoot!.querySelector("hui-yaml-editor")!;
private get yamlEditor(): HaYamlEditor {
return this.shadowRoot!.querySelector("ha-yaml-editor")!;
}
}

View File

@ -33,6 +33,8 @@ documentContainer.innerHTML = `<custom-style>
--scrollbar-thumb-color: rgb(194, 194, 194);
--error-state-color: #db4437;
/* states and badges */
--state-icon-color: #44739e;
--state-icon-active-color: #FDD835;