From c42d9385d1b941957f5ecde7bebb35a9140d7449 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Fri, 26 Oct 2018 02:27:57 -0500 Subject: [PATCH] Convert hui-horizontal-stack-card to TypeScript/LitElement (#1851) * Convert horizontal-stack to TypeScript/LitElement Base stack-card class for horizontal and vertical stack cards to extend as their code overlaps a lot. Not sure if it should be in `common` or not * rename locale hass variable * Address review comments * Abstract getCardSize --- .../cards/hui-horizontal-stack-card.js | 92 ------------------- .../cards/hui-horizontal-stack-card.ts | 57 ++++++++++++ src/panels/lovelace/cards/hui-stack-card.ts | 65 +++++++++++++ .../lovelace/common/create-card-element.js | 2 +- 4 files changed, 123 insertions(+), 93 deletions(-) delete mode 100644 src/panels/lovelace/cards/hui-horizontal-stack-card.js create mode 100644 src/panels/lovelace/cards/hui-horizontal-stack-card.ts create mode 100644 src/panels/lovelace/cards/hui-stack-card.ts diff --git a/src/panels/lovelace/cards/hui-horizontal-stack-card.js b/src/panels/lovelace/cards/hui-horizontal-stack-card.js deleted file mode 100644 index 7f530d7e37..0000000000 --- a/src/panels/lovelace/cards/hui-horizontal-stack-card.js +++ /dev/null @@ -1,92 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag.js"; -import { PolymerElement } from "@polymer/polymer/polymer-element.js"; - -import computeCardSize from "../common/compute-card-size.js"; -import createCardElement from "../common/create-card-element.js"; - -class HuiHorizontalStackCard extends PolymerElement { - static get template() { - return html` - -
- `; - } - - static get properties() { - return { - hass: { - type: Object, - observer: "_hassChanged", - }, - }; - } - - constructor() { - super(); - this._elements = []; - } - - ready() { - super.ready(); - if (this._config) this._buildConfig(); - } - - getCardSize() { - let size = 1; - this._elements.forEach((element) => { - const elSize = computeCardSize(element); - if (elSize > size) size = elSize; - }); - return size; - } - - setConfig(config) { - if (!config || !config.cards || !Array.isArray(config.cards)) { - throw new Error("Card config incorrect."); - } - this._config = config; - if (this.$) this._buildConfig(); - } - - _buildConfig() { - const config = this._config; - this._elements = []; - const root = this.$.root; - - while (root.lastChild) { - root.removeChild(root.lastChild); - } - - const elements = []; - config.cards.forEach((card) => { - const element = createCardElement(card); - element.hass = this.hass; - elements.push(element); - root.appendChild(element); - }); - this._elements = elements; - } - - _hassChanged(hass) { - this._elements.forEach((element) => { - element.hass = hass; - }); - } -} - -customElements.define("hui-horizontal-stack-card", HuiHorizontalStackCard); diff --git a/src/panels/lovelace/cards/hui-horizontal-stack-card.ts b/src/panels/lovelace/cards/hui-horizontal-stack-card.ts new file mode 100644 index 0000000000..bd93a6c9e8 --- /dev/null +++ b/src/panels/lovelace/cards/hui-horizontal-stack-card.ts @@ -0,0 +1,57 @@ +import { html } from "@polymer/lit-element"; +import { TemplateResult } from "lit-html"; + +import computeCardSize from "../common/compute-card-size.js"; + +import { LovelaceCard, LovelaceConfig } from "../types"; +import HuiStackCard from "./hui-stack-card"; + +interface Config extends LovelaceConfig { + cards: LovelaceConfig[]; +} + +class HuiHorizontalStackCard extends HuiStackCard implements LovelaceCard { + protected config?: Config; + + public getCardSize(): number { + let totalSize = 0; + + if (this._cards) { + for (const element of this._cards) { + const elementSize = computeCardSize(element); + totalSize = elementSize > totalSize ? elementSize : totalSize; + } + } + + return totalSize; + } + + protected renderStyle(): TemplateResult { + return html` + + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-horitzontal-stack-card": HuiHorizontalStackCard; + } +} + +customElements.define("hui-horizontal-stack-card", HuiHorizontalStackCard); diff --git a/src/panels/lovelace/cards/hui-stack-card.ts b/src/panels/lovelace/cards/hui-stack-card.ts new file mode 100644 index 0000000000..95d0025a23 --- /dev/null +++ b/src/panels/lovelace/cards/hui-stack-card.ts @@ -0,0 +1,65 @@ +import { html, LitElement } from "@polymer/lit-element"; +import { TemplateResult } from "lit-html"; + +import createCardElement from "../common/create-card-element.js"; + +import { LovelaceCard, LovelaceConfig } from "../types"; +import { HomeAssistant } from "../../../types"; + +interface Config extends LovelaceConfig { + cards: LovelaceConfig[]; +} + +export default abstract class HuiStackCard extends LitElement + implements LovelaceCard { + protected config?: Config; + protected _cards?: LovelaceCard[]; + private _hass?: HomeAssistant; + + static get properties() { + return { + config: {}, + }; + } + + set hass(hass: HomeAssistant) { + this._hass = hass; + + if (!this._cards) { + return; + } + + for (const element of this._cards) { + element.hass = this._hass; + } + } + + public abstract getCardSize(): number; + + public setConfig(config: Config): void { + if (!config || !config.cards || !Array.isArray(config.cards)) { + throw new Error("Card config incorrect"); + } + this.config = config; + this._cards = config.cards.map((card) => { + const element = createCardElement(card) as LovelaceCard; + element.hass = this._hass; + return element; + }); + } + + protected render(): TemplateResult { + if (!this.config) { + return html``; + } + + return html` + ${this.renderStyle()} +
+ ${this._cards} +
+ `; + } + + protected abstract renderStyle(): TemplateResult; +} diff --git a/src/panels/lovelace/common/create-card-element.js b/src/panels/lovelace/common/create-card-element.js index cfdb50055b..f6465cb8a5 100644 --- a/src/panels/lovelace/common/create-card-element.js +++ b/src/panels/lovelace/common/create-card-element.js @@ -8,7 +8,7 @@ import "../cards/hui-entity-filter-card.js"; import "../cards/hui-error-card.ts"; import "../cards/hui-glance-card.ts"; import "../cards/hui-history-graph-card.js"; -import "../cards/hui-horizontal-stack-card.js"; +import "../cards/hui-horizontal-stack-card.ts"; import "../cards/hui-iframe-card.ts"; import "../cards/hui-map-card.js"; import "../cards/hui-markdown-card.ts";