From e6ac0258e394296eb29572a1d412421ebb572bee Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 4 Dec 2019 22:58:35 +0100 Subject: [PATCH] Use dynamicElement directive in ha-form (#4317) * Use dynamicContentDirective * Turn around * Remove attributes * Rename to dynamicElement --- ...ective.ts => dynamic-element-directive.ts} | 20 ++++--- src/components/ha-form/ha-form.ts | 53 ++++--------------- .../trigger/ha-automation-trigger-row.ts | 4 +- 3 files changed, 25 insertions(+), 52 deletions(-) rename src/common/dom/{dynamic-content-directive.ts => dynamic-element-directive.ts} (66%) diff --git a/src/common/dom/dynamic-content-directive.ts b/src/common/dom/dynamic-element-directive.ts similarity index 66% rename from src/common/dom/dynamic-content-directive.ts rename to src/common/dom/dynamic-element-directive.ts index 31a8a1ead7..25ca9cfec8 100644 --- a/src/common/dom/dynamic-content-directive.ts +++ b/src/common/dom/dynamic-element-directive.ts @@ -1,7 +1,7 @@ import { directive, Part, NodePart } from "lit-html"; -export const dynamicContentDirective = directive( - (tag: string, properties: { [key: string]: any }) => (part: Part): void => { +export const dynamicElement = directive( + (tag: string, properties?: { [key: string]: any }) => (part: Part): void => { if (!(part instanceof NodePart)) { throw new Error( "dynamicContentDirective can only be used in content bindings" @@ -14,16 +14,20 @@ export const dynamicContentDirective = directive( element !== undefined && tag.toUpperCase() === (element as HTMLElement).tagName ) { - Object.entries(properties).forEach(([key, value]) => { - element![key] = value; - }); + if (properties) { + Object.entries(properties).forEach(([key, value]) => { + element![key] = value; + }); + } return; } element = document.createElement(tag); - Object.entries(properties).forEach(([key, value]) => { - element![key] = value; - }); + if (properties) { + Object.entries(properties).forEach(([key, value]) => { + element![key] = value; + }); + } part.setValue(element); } ); diff --git a/src/components/ha-form/ha-form.ts b/src/components/ha-form/ha-form.ts index 651db6a4ac..5925dee226 100644 --- a/src/components/ha-form/ha-form.ts +++ b/src/components/ha-form/ha-form.ts @@ -3,10 +3,8 @@ import { LitElement, html, property, - query, CSSResult, css, - PropertyValues, } from "lit-element"; import "./ha-form-string"; @@ -16,6 +14,7 @@ import "./ha-form-boolean"; import "./ha-form-select"; import "./ha-form-positive_time_period_dict"; import { fireEvent } from "../../common/dom/fire_event"; +import { dynamicElement } from "../../common/dom/dynamic-element-directive"; export type HaFormSchema = | HaFormStringSchema @@ -100,20 +99,14 @@ export class HaForm extends LitElement implements HaFormElement { @property() public computeError?: (schema: HaFormSchema, error) => string; @property() public computeLabel?: (schema: HaFormSchema) => string; @property() public computeSuffix?: (schema: HaFormSchema) => string; - @query("ha-form") private _childForm?: HaForm; - @query("#element") private _elementContainer?: HTMLDivElement; public focus() { - const input = this._childForm - ? this._childForm - : this._elementContainer - ? this._elementContainer.lastChild - : undefined; - + const input = + this.shadowRoot!.getElementById("child-form") || + this.shadowRoot!.querySelector("ha-form"); if (!input) { return; } - (input as HTMLElement).focus(); } @@ -151,40 +144,16 @@ export class HaForm extends LitElement implements HaFormElement { ` : ""} -
+ ${dynamicElement(`ha-form-${this.schema.type}`, { + schema: this.schema, + data: this.data, + label: this._computeLabel(this.schema), + suffix: this._computeSuffix(this.schema), + id: "child-form", + })} `; } - protected updated(changedProperties: PropertyValues) { - const schemaChanged = changedProperties.has("schema"); - const oldSchema = schemaChanged - ? changedProperties.get("schema") - : undefined; - if ( - !Array.isArray(this.schema) && - schemaChanged && - (!oldSchema || (oldSchema as HaFormSchema).type !== this.schema.type) - ) { - const element = document.createElement( - `ha-form-${this.schema.type}` - ) as HaFormElement; - element.schema = this.schema; - element.data = this.data; - element.label = this._computeLabel(this.schema); - element.suffix = this._computeSuffix(this.schema); - if (this._elementContainer!.lastChild) { - this._elementContainer!.removeChild(this._elementContainer!.lastChild); - } - this._elementContainer!.appendChild(element); - } else if (this._elementContainer && this._elementContainer.lastChild) { - const element = this._elementContainer!.lastChild as HaFormElement; - element.schema = this.schema; - element.data = this.data; - element.label = this._computeLabel(this.schema); - element.suffix = this._computeSuffix(this.schema); - } - } - private _computeLabel(schema: HaFormSchema) { return this.computeLabel ? this.computeLabel(schema) diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index ea5b52b387..90e4baf0a2 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -12,7 +12,7 @@ import { LitElement, property, } from "lit-element"; -import { dynamicContentDirective } from "../../../../common/dom/dynamic-content-directive"; +import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-card"; import { HomeAssistant } from "../../../../types"; @@ -266,7 +266,7 @@ export default class HaAutomationTriggerRow extends LitElement {
- ${dynamicContentDirective( + ${dynamicElement( `ha-automation-trigger-${this.trigger.platform}`, { hass: this.hass, trigger: this.trigger } )}