Use resize controller for weather card
This commit is contained in:
parent
8136cc8008
commit
af6342b917
|
@ -1,3 +1,4 @@
|
|||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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 (
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -614,48 +579,48 @@ 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;
|
||||
|
@ -663,18 +628,18 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
|||
|
||||
/* ============= 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;
|
||||
|
|
Loading…
Reference in New Issue