From 967784a48e29c88ac7ce7c9f5929bfea63080160 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 20 Jun 2024 15:50:27 +0200 Subject: [PATCH 1/5] Better resizing support for thermostat card --- .../lovelace/cards/hui-humidifier-card.ts | 87 +++++++++++++++--- .../lovelace/cards/hui-thermostat-card.ts | 90 +++++++++++++++---- 2 files changed, 148 insertions(+), 29 deletions(-) diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index 990d0faaf7d7..2efb7d4a85c6 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -7,7 +7,7 @@ import { html, nothing, } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; @@ -26,6 +26,39 @@ import { HumidifierCardConfig } from "./types"; @customElement("hui-humidifier-card") export class HuiHumidifierCard extends LitElement implements LovelaceCard { + private _resizeObserver?: ResizeObserver; + + public connectedCallback(): void { + super.connectedCallback(); + this._attachObserver(); + } + + public disconnectedCallback(): void { + super.disconnectedCallback(); + this._detachObserver(); + } + + @query(".container") private _container!: HTMLElement; + + private _attachObserver(): void { + if (!this._resizeObserver && this._container) { + this._resizeObserver = new ResizeObserver(() => { + this._container.style.setProperty( + "--height", + `${this._container.clientHeight}px` + ); + }); + this._resizeObserver.observe(this._container); + } + } + + private _detachObserver(): void { + if (this._resizeObserver) { + this._resizeObserver.disconnect(); + this._resizeObserver = undefined; + } + } + public static async getConfigElement(): Promise { await import("../editor/config-elements/hui-humidifier-card-editor"); return document.createElement("hui-humidifier-card-editor"); @@ -82,6 +115,8 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); + this._attachObserver(); + if ( !this._config || !this.hass || @@ -126,13 +161,15 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { return html`

${name}

- +
+ +
* { + padding: 8px; + max-width: var(--height, 100%); + height: 100%; + } + .more-info { position: absolute; cursor: pointer; @@ -201,6 +259,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { hui-card-features { width: 100%; + flex: none; } `; } diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index cfa34d81e86f..d07bf0acb2a3 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -7,7 +7,7 @@ import { html, nothing, } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; @@ -18,14 +18,47 @@ import "../../../components/ha-icon-button"; import { ClimateEntity } from "../../../data/climate"; import "../../../state-control/climate/ha-state-control-climate-temperature"; import { HomeAssistant } from "../../../types"; +import "../card-features/hui-card-features"; import { findEntities } from "../common/find-entities"; import { createEntityNotFoundWarning } from "../components/hui-warning"; -import "../card-features/hui-card-features"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { ThermostatCardConfig } from "./types"; @customElement("hui-thermostat-card") export class HuiThermostatCard extends LitElement implements LovelaceCard { + private _resizeObserver?: ResizeObserver; + + public connectedCallback(): void { + super.connectedCallback(); + this._attachObserver(); + } + + public disconnectedCallback(): void { + super.disconnectedCallback(); + this._detachObserver(); + } + + @query(".container") private _container!: HTMLElement; + + private _attachObserver(): void { + if (!this._resizeObserver && this._container) { + this._resizeObserver = new ResizeObserver(() => { + this._container.style.setProperty( + "--height", + `${this._container.clientHeight}px` + ); + }); + this._resizeObserver.observe(this._container); + } + } + + private _detachObserver(): void { + if (this._resizeObserver) { + this._resizeObserver.disconnect(); + this._resizeObserver = undefined; + } + } + public static async getConfigElement(): Promise { await import("../editor/config-elements/hui-thermostat-card-editor"); return document.createElement("hui-thermostat-card-editor"); @@ -74,6 +107,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); + this._attachObserver(); + if ( !this._config || !this.hass || @@ -118,13 +153,15 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { return html`

${name}

- +
+ +
* { + padding: 8px; + max-width: var(--height, 100%); + height: 100%; + aspect-ratio: 1 / 1; + } + .more-info { position: absolute; cursor: pointer; @@ -193,6 +252,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { hui-card-features { width: 100%; + flex: none; } `; } From c6b885ef3feef39d2de7a113918b8004f88422a6 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 24 Jun 2024 11:28:06 +0200 Subject: [PATCH 2/5] Use resize controller --- .../lovelace/cards/hui-humidifier-card.ts | 45 +++++------------- .../lovelace/cards/hui-thermostat-card.ts | 46 +++++-------------- 2 files changed, 22 insertions(+), 69 deletions(-) diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index 2efb7d4a85c6..7cc39d3ec010 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -1,3 +1,4 @@ +import { ResizeController } from "@lit-labs/observers/resize-controller"; import { mdiDotsVertical } from "@mdi/js"; import { CSSResultGroup, @@ -26,38 +27,16 @@ import { HumidifierCardConfig } from "./types"; @customElement("hui-humidifier-card") export class HuiHumidifierCard extends LitElement implements LovelaceCard { - private _resizeObserver?: ResizeObserver; + @query(".container") private _container?: HTMLElement; - public connectedCallback(): void { - super.connectedCallback(); - this._attachObserver(); - } - - public disconnectedCallback(): void { - super.disconnectedCallback(); - this._detachObserver(); - } - - @query(".container") private _container!: HTMLElement; - - private _attachObserver(): void { - if (!this._resizeObserver && this._container) { - this._resizeObserver = new ResizeObserver(() => { - this._container.style.setProperty( - "--height", - `${this._container.clientHeight}px` - ); - }); - this._resizeObserver.observe(this._container); - } - } - - private _detachObserver(): void { - if (this._resizeObserver) { - this._resizeObserver.disconnect(); - this._resizeObserver = undefined; - } - } + // @ts-ignore + private _resizeController = new ResizeController(this, { + callback: () => { + const height = this._container?.clientHeight; + if (!height) return; + this._container.style.setProperty("--height", `${height}px`); + }, + }); public static async getConfigElement(): Promise { await import("../editor/config-elements/hui-humidifier-card-editor"); @@ -115,8 +94,6 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); - this._attachObserver(); - if ( !this._config || !this.hass || @@ -231,6 +208,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { overflow: hidden; max-width: 100%; box-sizing: border-box; + flex: 1; } .container:before { @@ -242,7 +220,6 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { .container > * { padding: 8px; max-width: var(--height, 100%); - height: 100%; } .more-info { diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index d07bf0acb2a3..e94fd0925c1f 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -1,3 +1,4 @@ +import { ResizeController } from "@lit-labs/observers/resize-controller"; import { mdiDotsVertical } from "@mdi/js"; import { CSSResultGroup, @@ -26,38 +27,16 @@ import { ThermostatCardConfig } from "./types"; @customElement("hui-thermostat-card") export class HuiThermostatCard extends LitElement implements LovelaceCard { - private _resizeObserver?: ResizeObserver; + @query(".container") private _container?: HTMLElement; - public connectedCallback(): void { - super.connectedCallback(); - this._attachObserver(); - } - - public disconnectedCallback(): void { - super.disconnectedCallback(); - this._detachObserver(); - } - - @query(".container") private _container!: HTMLElement; - - private _attachObserver(): void { - if (!this._resizeObserver && this._container) { - this._resizeObserver = new ResizeObserver(() => { - this._container.style.setProperty( - "--height", - `${this._container.clientHeight}px` - ); - }); - this._resizeObserver.observe(this._container); - } - } - - private _detachObserver(): void { - if (this._resizeObserver) { - this._resizeObserver.disconnect(); - this._resizeObserver = undefined; - } - } + // @ts-ignore + private _resizeController = new ResizeController(this, { + callback: () => { + const height = this._container?.clientHeight; + if (!height) return; + this._container.style.setProperty("--height", `${height}px`); + }, + }); public static async getConfigElement(): Promise { await import("../editor/config-elements/hui-thermostat-card-editor"); @@ -107,8 +86,6 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); - this._attachObserver(); - if ( !this._config || !this.hass || @@ -223,6 +200,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { overflow: hidden; max-width: 100%; box-sizing: border-box; + flex: 1; } .container:before { @@ -234,8 +212,6 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { .container > * { padding: 8px; max-width: var(--height, 100%); - height: 100%; - aspect-ratio: 1 / 1; } .more-info { From c5a2591447d0194317dcdc5987a2ec0d7da342b6 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 24 Jun 2024 11:35:09 +0200 Subject: [PATCH 3/5] Fix typings --- src/panels/lovelace/cards/hui-humidifier-card.ts | 2 +- src/panels/lovelace/cards/hui-thermostat-card.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index 7cc39d3ec010..cebdbd0cb86c 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -34,7 +34,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { callback: () => { const height = this._container?.clientHeight; if (!height) return; - this._container.style.setProperty("--height", `${height}px`); + this._container!.style.setProperty("--height", `${height}px`); }, }); diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index e94fd0925c1f..887c1e2d0e0f 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -34,7 +34,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { callback: () => { const height = this._container?.clientHeight; if (!height) return; - this._container.style.setProperty("--height", `${height}px`); + this._container!.style.setProperty("--height", `${height}px`); }, }); From 5103bae559ba1640b56a65c6e99eea20946d1d88 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 24 Jun 2024 11:52:19 +0200 Subject: [PATCH 4/5] Don't use query --- src/panels/lovelace/cards/hui-humidifier-card.ts | 15 ++++++++------- src/panels/lovelace/cards/hui-thermostat-card.ts | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index cebdbd0cb86c..c791b8fbd9c8 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -8,7 +8,7 @@ import { html, nothing, } from "lit"; -import { customElement, property, query, state } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; @@ -27,14 +27,15 @@ import { HumidifierCardConfig } from "./types"; @customElement("hui-humidifier-card") export class HuiHumidifierCard extends LitElement implements LovelaceCard { - @query(".container") private _container?: HTMLElement; - // @ts-ignore private _resizeController = new ResizeController(this, { - callback: () => { - const height = this._container?.clientHeight; - if (!height) return; - this._container!.style.setProperty("--height", `${height}px`); + callback: async (entries) => { + const container = entries[0]?.target.shadowRoot?.querySelector( + ".container" + ) as HTMLElement | undefined; + if (!container) return; + const height = container.clientHeight; + container.style.setProperty("--height", `${height}px`); }, }); diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 887c1e2d0e0f..9f1fbad86596 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -8,7 +8,7 @@ import { html, nothing, } from "lit"; -import { customElement, property, query, state } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; @@ -27,14 +27,15 @@ import { ThermostatCardConfig } from "./types"; @customElement("hui-thermostat-card") export class HuiThermostatCard extends LitElement implements LovelaceCard { - @query(".container") private _container?: HTMLElement; - // @ts-ignore private _resizeController = new ResizeController(this, { - callback: () => { - const height = this._container?.clientHeight; - if (!height) return; - this._container!.style.setProperty("--height", `${height}px`); + callback: async (entries) => { + const container = entries[0]?.target.shadowRoot?.querySelector( + ".container" + ) as HTMLElement | undefined; + if (!container) return; + const height = container.clientHeight; + container.style.setProperty("--height", `${height}px`); }, }); From 37440ba572280575f9cd820b06b5c147d38ca61d Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 24 Jun 2024 22:23:09 +0200 Subject: [PATCH 5/5] Use render to set style --- src/panels/lovelace/cards/hui-humidifier-card.ts | 15 +++++++++------ src/panels/lovelace/cards/hui-thermostat-card.ts | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index c791b8fbd9c8..f964148c0a64 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -27,15 +27,12 @@ import { HumidifierCardConfig } from "./types"; @customElement("hui-humidifier-card") export class HuiHumidifierCard extends LitElement implements LovelaceCard { - // @ts-ignore private _resizeController = new ResizeController(this, { - callback: async (entries) => { + callback: (entries) => { const container = entries[0]?.target.shadowRoot?.querySelector( ".container" ) as HTMLElement | undefined; - if (!container) return; - const height = container.clientHeight; - container.style.setProperty("--height", `${height}px`); + return container?.clientHeight; }, }); @@ -136,11 +133,18 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { const color = stateColorCss(stateObj); + const controlMaxWidth = this._resizeController.value + ? `${this._resizeController.value}px` + : undefined; + return html`

${name}

* { padding: 8px; - max-width: var(--height, 100%); } .more-info { diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 9f1fbad86596..d8d58ee9c776 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -27,15 +27,12 @@ import { ThermostatCardConfig } from "./types"; @customElement("hui-thermostat-card") export class HuiThermostatCard extends LitElement implements LovelaceCard { - // @ts-ignore private _resizeController = new ResizeController(this, { - callback: async (entries) => { + callback: (entries) => { const container = entries[0]?.target.shadowRoot?.querySelector( ".container" ) as HTMLElement | undefined; - if (!container) return; - const height = container.clientHeight; - container.style.setProperty("--height", `${height}px`); + return container?.clientHeight; }, }); @@ -128,11 +125,18 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { const color = stateColorCss(stateObj); + const controlMaxWidth = this._resizeController.value + ? `${this._resizeController.value}px` + : undefined; + return html`

${name}

* { padding: 8px; - max-width: var(--height, 100%); } .more-info {