Skip to content

Commit

Permalink
Use resize controller for weather card
Browse files Browse the repository at this point in the history
  • Loading branch information
piitaya committed Feb 15, 2024
1 parent 8136cc8 commit af6342b
Showing 1 changed file with 38 additions and 73 deletions.
111 changes: 38 additions & 73 deletions src/panels/lovelace/cards/hui-weather-forecast-card.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ResizeController } from "@lit-labs/observers/resize-controller";
import {
CSSResultGroup,
LitElement,
Expand All @@ -14,7 +15,6 @@ import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_elemen
import { computeStateName } from "../../../common/entity/compute_state_name";
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
import { formatNumber } from "../../../common/number/format_number";
import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-card";
import "../../../components/ha-svg-icon";
import { UNAVAILABLE } from "../../../data/entity";
Expand All @@ -31,7 +31,6 @@ import {
weatherAttrIcons,
weatherSVGStyles,
} from "../../../data/weather";
import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill";
import type { HomeAssistant } from "../../../types";
import { actionHandler } from "../common/directives/action-handler-directive";
import { findEntities } from "../common/find-entities";
Expand Down Expand Up @@ -75,10 +74,25 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {

@state() private _subscribed?: Promise<() => void>;

// @todo Consider reworking to eliminate need for attribute since it is manipulated internally
@property({ type: Boolean, reflect: true }) public veryVeryNarrow = false;
private _sizeController = new ResizeController(this, {
callback: (entries) => {
const width = entries[0]?.contentRect.width;
if (width < 245) {
return "very-very-narrow";
}
if (width < 300) {
return "very-narrow";
}
if (width < 375) {
return "narrow";
}
return "regular";
},
});

private _resizeObserver?: ResizeObserver;
protected firstUpdated(): void {
this._sizeController.observe(this.shadowRoot!.querySelector("ha-card")!);
}

private _needForecastSubscription() {
return (
Expand Down Expand Up @@ -119,14 +133,10 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
if (this.hasUpdated && this._config && this.hass) {
this._subscribeForecastEvents();
}
this.updateComplete.then(() => this._attachObserver());
}

public disconnectedCallback(): void {
super.disconnectedCallback();
if (this._resizeObserver) {
this._resizeObserver.disconnect();
}
this._unsubscribeForecastEvents();
}

Expand Down Expand Up @@ -160,16 +170,6 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
);
}

public willUpdate(): void {
if (!this.hasUpdated) {
this._measureCard();
}
}

protected firstUpdated(): void {
this._attachObserver();
}

protected updated(changedProps: PropertyValues): void {
super.updated(changedProps);
if (!this._config || !this.hass) {
Expand Down Expand Up @@ -227,7 +227,10 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
);
const forecast =
this._config?.show_forecast !== false && forecastData?.forecast?.length
? forecastData.forecast.slice(0, this.veryVeryNarrow ? 3 : 5)
? forecastData.forecast.slice(
0,
this._sizeController.value === "very-very-narrow" ? 3 : 5
)
: undefined;
const weather = !forecast || this._config?.show_current !== false;

Expand All @@ -239,6 +242,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {

return html`
<ha-card
class=${ifDefined(this._sizeController.value)}
@action=${this._handleAction}
.actionHandler=${actionHandler({
hasHold: hasAction(this._config!.hold_action),
Expand Down Expand Up @@ -417,45 +421,6 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
handleAction(this, this.hass!, this._config!, ev.detail.action!);
}

private async _attachObserver(): Promise<void> {
if (!this._resizeObserver) {
await loadPolyfillIfNeeded();
this._resizeObserver = new ResizeObserver(
debounce(() => this._measureCard(), 250, false)
);
}
const card = this.shadowRoot!.querySelector("ha-card");
// If we show an error or warning there is no ha-card
if (!card) {
return;
}
this._resizeObserver.observe(card);
}

private _measureCard() {
if (!this.isConnected) {
return;
}

const card = this.shadowRoot!.querySelector("ha-card");
// If we show an error or warning there is no ha-card
if (!card) {
return;
}

if (card.offsetWidth < 375) {
this.setAttribute("narrow", "");
} else {
this.removeAttribute("narrow");
}
if (card.offsetWidth < 300) {
this.setAttribute("verynarrow", "");
} else {
this.removeAttribute("verynarrow");
}
this.veryVeryNarrow = card.offsetWidth < 245;
}

private _showValue(item?: any): boolean {
return typeof item !== "undefined" && item !== null;
}
Expand Down Expand Up @@ -614,67 +579,67 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
/* ============= NARROW ============= */
:host([narrow]) .icon-image {
[class*="narrow"] .icon-image {
min-width: 52px;
}
:host([narrow]) .weather-image {
[class*="narrow"] .weather-image {
flex: 0 0 52px;
width: 52px;
}
:host([narrow]) .icon-image .weather-icon {
[class*="narrow"] .icon-image .weather-icon {
--mdc-icon-size: 52px;
}
:host([narrow]) .state,
:host([narrow]) .temp-attribute .temp {
[class*="narrow"] .state,
[class*="narrow"] .temp-attribute .temp {
font-size: 22px;
}
:host([narrow]) .temp-attribute .temp {
[class*="narrow"] .temp-attribute .temp {
margin-right: 16px;
margin-inline-end: 16px;
margin-inline-start: initial;
}
:host([narrow]) .temp span {
[class*="narrow"] .temp span {
top: 1px;
font-size: 16px;
}
/* ============= VERY NARROW ============= */
:host([veryNarrow]) .name,
:host([veryNarrow]) .attribute {
[class*="very-narrow"] .name,
[class*="very-narrow"] .attribute {
display: none;
}
:host([veryNarrow]) .info {
[class*="very-narrow"] .info {
flex-direction: column;
align-items: flex-start;
}
:host([veryNarrow]) .name-state {
[class*="very-narrow"] .name-state {
padding-right: 0;
padding-inline-end: 0;
padding-inline-start: initial;
}
/* ============= VERY VERY NARROW ============= */
:host([veryVeryNarrow]) .info {
[class*="very-very-narrow"] .info {
padding-top: 4px;
align-items: center;
}
:host([veryVeryNarrow]) .content {
[class*="very-very-narrow"] .content {
flex-wrap: wrap;
justify-content: center;
flex-direction: column;
}
:host([veryVeryNarrow]) .icon-image {
[class*="very-very-narrow"] .icon-image {
margin-right: 0;
margin-inline-end: 0;
margin-inline-start: initial;
Expand Down

0 comments on commit af6342b

Please sign in to comment.