Improve weather forecast card layout (#23704)

* Improve weather forecast card layout

* fix units and improve naming

Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>

---------

Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
This commit is contained in:
Ingolf Becker 2025-02-04 06:32:30 +00:00 committed by GitHub
parent 077f5efe7e
commit f965a3504f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 29 deletions

View File

@ -134,12 +134,15 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
} }
public getCardSize(): number { public getCardSize(): number {
let cardSize = 0; let cardSize = 1;
if (this._config?.show_current !== false) { if (this._config?.show_current !== false) {
cardSize += 2; cardSize += 1;
} }
if (this._config?.show_forecast !== false) { if (this._config?.show_forecast !== false) {
cardSize += 3; cardSize += 1;
}
if (this._config?.forecast_type === "daily") {
cardSize += 1;
} }
return cardSize; return cardSize;
} }
@ -218,12 +221,19 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
this._forecastEvent, this._forecastEvent,
this._config?.forecast_type this._config?.forecast_type
); );
let itemsToShow = this._config?.forecast_slots ?? 5;
if (this._sizeController.value === "very-very-narrow") {
itemsToShow = Math.min(3, itemsToShow);
} else if (this._sizeController.value === "very-narrow") {
itemsToShow = Math.min(5, itemsToShow);
} else if (this._sizeController.value === "narrow") {
itemsToShow = Math.min(7, itemsToShow);
}
const forecast = const forecast =
this._config?.show_forecast !== false && forecastData?.forecast?.length this._config?.show_forecast !== false && forecastData?.forecast?.length
? forecastData.forecast.slice( ? forecastData.forecast.slice(0, itemsToShow)
0,
this._sizeController.value === "very-very-narrow" ? 3 : 5
)
: undefined; : undefined;
const weather = !forecast || this._config?.show_current !== false; const weather = !forecast || this._config?.show_current !== false;
@ -419,30 +429,24 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
} }
public getGridOptions(): LovelaceGridOptions { public getGridOptions(): LovelaceGridOptions {
if ( let rows = 1;
this._config?.show_current !== false && let min_rows = 1;
this._config?.show_forecast !== false if (this._config?.show_current !== false) {
) { rows += 1;
return { min_rows += 1;
columns: 12,
rows: 4,
min_columns: 6,
min_rows: 4,
};
} }
if (this._config?.show_forecast !== false) { if (this._config?.show_forecast !== false) {
return { rows += 1;
columns: 12, min_rows += 1;
rows: 3, }
min_columns: 6, if (this._config?.forecast_type === "daily") {
min_rows: 3, rows += 1;
};
} }
return { return {
columns: 12, columns: 12,
rows: 2, rows: rows,
min_columns: 6, min_columns: 6,
min_rows: 2, min_rows: min_rows,
}; };
} }
@ -462,7 +466,6 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
padding: 16px;
box-sizing: border-box; box-sizing: border-box;
} }
@ -471,6 +474,11 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0 16px;
}
.content + .forecast {
padding-top: 8px;
} }
.icon-image { .icon-image {
@ -549,7 +557,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
.forecast { .forecast {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
padding-top: 16px; padding: 0 16px;
} }
.forecast > div { .forecast > div {
@ -558,7 +566,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
.forecast .icon, .forecast .icon,
.forecast .temp { .forecast .temp {
margin: 4px 0; margin: 0;
} }
.forecast .temp { .forecast .temp {

View File

@ -507,6 +507,7 @@ export interface WeatherForecastCardConfig extends LovelaceCardConfig {
show_current?: boolean; show_current?: boolean;
show_forecast?: boolean; show_forecast?: boolean;
forecast_type?: ForecastType; forecast_type?: ForecastType;
forecast_slots?: number;
secondary_info_attribute?: keyof TranslationDict["ui"]["card"]["weather"]["attributes"]; secondary_info_attribute?: keyof TranslationDict["ui"]["card"]["weather"]["attributes"];
theme?: string; theme?: string;
tap_action?: ActionConfig; tap_action?: ActionConfig;

View File

@ -1,7 +1,15 @@
import { html, LitElement, nothing } from "lit"; import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { assert, assign, boolean, object, optional, string } from "superstruct"; import {
assert,
assign,
boolean,
object,
optional,
string,
number,
} from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import type { LocalizeFunc } from "../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../common/translations/localize";
import "../../../../components/ha-form/ha-form"; import "../../../../components/ha-form/ha-form";
@ -25,6 +33,7 @@ const cardConfigStruct = assign(
show_current: optional(boolean()), show_current: optional(boolean()),
show_forecast: optional(boolean()), show_forecast: optional(boolean()),
forecast_type: optional(string()), forecast_type: optional(string()),
forecast_slots: optional(number()),
secondary_info_attribute: optional(string()), secondary_info_attribute: optional(string()),
tap_action: optional(actionConfigStruct), tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct), hold_action: optional(actionConfigStruct),
@ -225,6 +234,11 @@ export class HuiWeatherForecastCardEditor
}, },
}, },
}, },
{
name: "forecast_slots",
selector: { number: { min: 1, max: 12 } },
default: 5,
},
] as const) ] as const)
: []), : []),
] as const ] as const
@ -304,6 +318,10 @@ export class HuiWeatherForecastCardEditor
return this.hass!.localize( return this.hass!.localize(
"ui.panel.lovelace.editor.card.weather-forecast.forecast_type" "ui.panel.lovelace.editor.card.weather-forecast.forecast_type"
); );
case "forecast_slots":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.weather-forecast.forecast_slots"
);
case "forecast": case "forecast":
return this.hass!.localize( return this.hass!.localize(
"ui.panel.lovelace.editor.card.weather-forecast.weather_to_show" "ui.panel.lovelace.editor.card.weather-forecast.weather_to_show"

View File

@ -7120,6 +7120,7 @@
"show_only_current": "Show only current Weather", "show_only_current": "Show only current Weather",
"show_only_forecast": "Show only forecast", "show_only_forecast": "Show only forecast",
"forecast_type": "Select forecast type", "forecast_type": "Select forecast type",
"forecast_slots": "Maximum number of forecast elements to show",
"no_type": "No type", "no_type": "No type",
"daily": "Daily", "daily": "Daily",
"hourly": "Hourly", "hourly": "Hourly",