diff --git a/src/components/ha-control-select-menu.ts b/src/components/ha-control-select-menu.ts
index 3dc78ef957..7659675391 100644
--- a/src/components/ha-control-select-menu.ts
+++ b/src/components/ha-control-select-menu.ts
@@ -1,11 +1,9 @@
import { mdiMenuDown } from "@mdi/js";
-import type { HassEntity } from "home-assistant-js-websocket";
+import type { TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one";
-import type { HomeAssistant } from "../types";
-import "./ha-attribute-icon";
import "./ha-dropdown";
import "./ha-dropdown-item";
import "./ha-icon";
@@ -16,17 +14,10 @@ export interface SelectOption {
value: string;
iconPath?: string;
icon?: string;
- attributeIcon?: {
- stateObj: HassEntity;
- attribute: string;
- attributeValue?: string;
- };
}
@customElement("ha-control-select-menu")
export class HaControlSelectMenu extends LitElement {
- @property({ attribute: false }) public hass!: HomeAssistant;
-
@property({ type: Boolean, attribute: "show-arrow" })
public showArrow = false;
@@ -47,6 +38,9 @@ export class HaControlSelectMenu extends LitElement {
@property({ attribute: false }) public options: SelectOption[] = [];
+ @property({ attribute: false })
+ public renderIcon?: (value: string) => TemplateResult<1> | typeof nothing;
+
@query("button") private _triggerButton!: HTMLButtonElement;
public override render() {
@@ -94,14 +88,8 @@ export class HaControlSelectMenu extends LitElement {
? html``
: option.icon
? html``
- : option.attributeIcon
- ? html``
+ : this.renderIcon
+ ? html`${this.renderIcon(option.value)}`
: nothing}
${option.label}`;
@@ -119,24 +107,20 @@ export class HaControlSelectMenu extends LitElement {
}
private _renderIcon() {
- const { iconPath, icon, attributeIcon } =
- this.getValueObject(this.options, this.value) ?? {};
+ const value = this.getValueObject(this.options, this.value);
const defaultIcon = this.querySelector("[slot='icon']");
return html`
- ${iconPath
- ? html``
- : icon
- ? html``
- : attributeIcon
- ? html``
+ ${value?.iconPath
+ ? html``
+ : value?.icon
+ ? html``
+ : this.renderIcon && this.value
+ ? this.renderIcon(this.value)
: defaultIcon
? html``
: nothing}
diff --git a/src/dialogs/more-info/controls/more-info-climate.ts b/src/dialogs/more-info/controls/more-info-climate.ts
index 79a153e773..01552bc7fd 100644
--- a/src/dialogs/more-info/controls/more-info-climate.ts
+++ b/src/dialogs/more-info/controls/more-info-climate.ts
@@ -9,6 +9,7 @@ import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { supportsFeature } from "../../../common/entity/supports-feature";
+import "../../../components/ha-attribute-icon";
import "../../../components/ha-control-select-menu";
import "../../../components/ha-icon-button-group";
import "../../../components/ha-icon-button-toggle";
@@ -39,6 +40,38 @@ class MoreInfoClimate extends LitElement {
@state() private _mainControl: MainControl = "temperature";
+ private _renderPresetModeIcon = (value: string) =>
+ html``;
+
+ private _renderFanModeIcon = (value: string) =>
+ html``;
+
+ private _renderSwingModeIcon = (value: string) =>
+ html``;
+
+ private _renderSwingHorizontalModeIcon = (value: string) =>
+ html``;
+
protected willUpdate(changedProps: PropertyValues): void {
if (
changedProps.has("stateObj") &&
@@ -205,12 +238,8 @@ class MoreInfoClimate extends LitElement {
"preset_mode",
mode
),
- attributeIcon: {
- stateObj,
- attribute: "preset_mode",
- attributeValue: mode,
- },
}))}
+ .renderIcon=${this._renderPresetModeIcon}
>
@@ -234,12 +263,8 @@ class MoreInfoClimate extends LitElement {
"fan_mode",
mode
),
- attributeIcon: {
- stateObj,
- attribute: "fan_mode",
- attributeValue: mode,
- },
}))}
+ .renderIcon=${this._renderFanModeIcon}
>
@@ -263,12 +288,8 @@ class MoreInfoClimate extends LitElement {
"swing_mode",
mode
),
- attributeIcon: {
- stateObj,
- attribute: "swing_mode",
- attributeValue: mode,
- },
}))}
+ .renderIcon=${this._renderSwingModeIcon}
>
+ html``;
+
+ private _renderDirectionIcon = (value: string) =>
+ html``;
+
private _toggle = () => {
const service = this.stateObj?.state === "on" ? "turn_off" : "turn_on";
forwardHaptic(this, "light");
@@ -192,15 +208,9 @@ class MoreInfoFan extends LitElement {
"preset_mode",
mode
),
- attributeIcon: this.stateObj
- ? {
- stateObj: this.stateObj,
- attribute: "preset_mode",
- attributeValue: mode,
- }
- : undefined,
})
)}
+ .renderIcon=${this._renderPresetModeIcon}
>
@@ -226,14 +236,8 @@ class MoreInfoFan extends LitElement {
direction
)
: direction,
- attributeIcon: this.stateObj
- ? {
- stateObj: this.stateObj,
- attribute: "direction",
- attributeValue: direction,
- }
- : undefined,
}))}
+ .renderIcon=${this._renderDirectionIcon}
>
+ html``;
+
protected willUpdate(changedProps: PropertyValues): void {
super.willUpdate(changedProps);
if (changedProps.has("stateObj")) {
@@ -106,14 +114,8 @@ class MoreInfoHumidifier extends LitElement {
mode
)
: mode,
- attributeIcon: stateObj
- ? {
- stateObj,
- attribute: "mode",
- attributeValue: mode,
- }
- : undefined,
})) || []}
+ .renderIcon=${this._renderModeIcon}
>
diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts
index 9379c86a24..3035829276 100644
--- a/src/dialogs/more-info/controls/more-info-light.ts
+++ b/src/dialogs/more-info/controls/more-info-light.ts
@@ -55,6 +55,14 @@ class MoreInfoLight extends LitElement {
@state() private _mainControl: MainControl = "brightness";
+ private _renderEffectIcon = (value: string) =>
+ html``;
+
protected updated(changedProps: PropertyValues): void {
if (changedProps.has("stateObj")) {
this._effect = this.stateObj?.attributes.effect;
@@ -271,15 +279,9 @@ class MoreInfoLight extends LitElement {
effect
)
: effect,
- attributeIcon: this.stateObj
- ? {
- stateObj: this.stateObj,
- attribute: "effect",
- attributeValue: effect,
- }
- : undefined,
})
)}
+ .renderIcon=${this._renderEffectIcon}
>
diff --git a/src/dialogs/more-info/controls/more-info-water_heater.ts b/src/dialogs/more-info/controls/more-info-water_heater.ts
index d9d1a0543e..09ba21a381 100644
--- a/src/dialogs/more-info/controls/more-info-water_heater.ts
+++ b/src/dialogs/more-info/controls/more-info-water_heater.ts
@@ -24,6 +24,14 @@ class MoreInfoWaterHeater extends LitElement {
@property({ attribute: false }) public stateObj?: WaterHeaterEntity;
+ private _renderOperationModeIcon = (value: string) =>
+ html``;
+
protected render() {
if (!this.stateObj) {
return nothing;
@@ -85,12 +93,8 @@ class MoreInfoWaterHeater extends LitElement {
.map((mode) => ({
value: mode,
label: this.hass.formatEntityState(stateObj, mode),
- attributeIcon: {
- stateObj,
- attribute: "operation_mode",
- attributeValue: mode,
- },
}))}
+ .renderIcon=${this._renderOperationModeIcon}
>
diff --git a/src/panels/lovelace/card-features/hui-climate-fan-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-climate-fan-modes-card-feature.ts
index 1a7259f12f..fc03ed3fbd 100644
--- a/src/panels/lovelace/card-features/hui-climate-fan-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-climate-fan-modes-card-feature.ts
@@ -49,6 +49,14 @@ class HuiClimateFanModesCardFeature
@state() _currentFanMode?: string;
+ private _renderFanModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -175,14 +183,8 @@ class HuiClimateFanModesCardFeature
.value=${this._currentFanMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj: stateObj,
- attribute: "fan_mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderFanModeIcon}
>
`;
diff --git a/src/panels/lovelace/card-features/hui-climate-preset-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-climate-preset-modes-card-feature.ts
index d13941c40d..df92172317 100644
--- a/src/panels/lovelace/card-features/hui-climate-preset-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-climate-preset-modes-card-feature.ts
@@ -48,6 +48,14 @@ class HuiClimatePresetModesCardFeature
@state() _currentPresetMode?: string;
+ private _renderPresetModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -179,14 +187,8 @@ class HuiClimatePresetModesCardFeature
.value=${this._currentPresetMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj: stateObj,
- attribute: "preset_mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderPresetModeIcon}
>
diff --git a/src/panels/lovelace/card-features/hui-climate-swing-horizontal-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-climate-swing-horizontal-modes-card-feature.ts
index cfc0386575..946dd32f95 100644
--- a/src/panels/lovelace/card-features/hui-climate-swing-horizontal-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-climate-swing-horizontal-modes-card-feature.ts
@@ -48,6 +48,14 @@ class HuiClimateSwingHorizontalModesCardFeature
@state() _currentSwingHorizontalMode?: string;
+ private _renderSwingHorizontalModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -187,14 +195,8 @@ class HuiClimateSwingHorizontalModesCardFeature
.value=${this._currentSwingHorizontalMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj: stateObj,
- attribute: "swing_horizontal_mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderSwingHorizontalModeIcon}
>
diff --git a/src/panels/lovelace/card-features/hui-climate-swing-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-climate-swing-modes-card-feature.ts
index 5cc902591c..4b2c9d5ded 100644
--- a/src/panels/lovelace/card-features/hui-climate-swing-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-climate-swing-modes-card-feature.ts
@@ -48,6 +48,14 @@ class HuiClimateSwingModesCardFeature
@state() _currentSwingMode?: string;
+ private _renderSwingModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -179,14 +187,8 @@ class HuiClimateSwingModesCardFeature
.value=${this._currentSwingMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj,
- attribute: "swing_mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderSwingModeIcon}
>
`;
diff --git a/src/panels/lovelace/card-features/hui-fan-preset-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-fan-preset-modes-card-feature.ts
index 2f71cadec3..b63acb8aae 100644
--- a/src/panels/lovelace/card-features/hui-fan-preset-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-fan-preset-modes-card-feature.ts
@@ -47,6 +47,14 @@ class HuiFanPresetModesCardFeature
@state() _currentPresetMode?: string;
+ private _renderPresetModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -173,14 +181,8 @@ class HuiFanPresetModesCardFeature
.value=${this._currentPresetMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj: stateObj,
- attribute: "preset_mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderPresetModeIcon}
>
diff --git a/src/panels/lovelace/card-features/hui-humidifier-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-humidifier-modes-card-feature.ts
index 07a10e7848..f65b7582b9 100644
--- a/src/panels/lovelace/card-features/hui-humidifier-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-humidifier-modes-card-feature.ts
@@ -48,6 +48,14 @@ class HuiHumidifierModesCardFeature
@state() _currentMode?: string;
+ private _renderModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -174,14 +182,8 @@ class HuiHumidifierModesCardFeature
.value=${this._currentMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj,
- attribute: "mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderModeIcon}
>
diff --git a/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts
index 8a9f554b88..7b007ab28e 100644
--- a/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts
+++ b/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts
@@ -49,6 +49,14 @@ class HuiWaterHeaterOperationModeCardFeature
@state() _currentOperationMode?: OperationMode;
+ private _renderOperationModeIcon = (value: string) =>
+ html``;
+
private get _stateObj() {
if (!this.hass || !this.context || !this.context.entity_id) {
return undefined;
@@ -153,14 +161,8 @@ class HuiWaterHeaterOperationModeCardFeature
.value=${this._currentOperationMode}
.disabled=${this._stateObj.state === UNAVAILABLE}
@wa-select=${this._valueChanged}
- .options=${options.map((option) => ({
- ...option,
- attributeIcon: {
- stateObj: this._stateObj,
- attribute: "operation_mode",
- attributeValue: option.value,
- },
- }))}
+ .options=${options}
+ .renderIcon=${this._renderOperationModeIcon}
>