mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Use new colors for state icon (#14358)
* Use new colors for state icon * feedbacks * Remove arming case
This commit is contained in:
parent
fcfdad3d94
commit
aeeacc6cad
@ -1,17 +0,0 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { UNAVAILABLE_STATES } from "../../data/entity";
|
||||
|
||||
export const computeActiveState = (stateObj: HassEntity): string => {
|
||||
if (UNAVAILABLE_STATES.includes(stateObj.state)) {
|
||||
return stateObj.state;
|
||||
}
|
||||
|
||||
const domain = stateObj.entity_id.split(".")[0];
|
||||
let state = stateObj.state;
|
||||
|
||||
if (domain === "climate") {
|
||||
state = stateObj.attributes.hvac_action;
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
@ -31,6 +31,8 @@ export function stateActive(stateObj: HassEntity, state?: string): boolean {
|
||||
return !["idle", "docked", "paused"].includes(compareState);
|
||||
case "plant":
|
||||
return compareState === "problem";
|
||||
case "group":
|
||||
return ["on", "home", "open", "locked", "problem"].includes(compareState);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
@ -1,60 +1,32 @@
|
||||
import { css } from "lit";
|
||||
|
||||
export const iconColorCSS = css`
|
||||
ha-state-icon[data-domain="alert"][data-state="on"],
|
||||
ha-state-icon[data-domain="automation"][data-state="on"],
|
||||
ha-state-icon[data-domain="binary_sensor"][data-state="on"],
|
||||
ha-state-icon[data-domain="calendar"][data-state="on"],
|
||||
ha-state-icon[data-domain="camera"][data-state="streaming"],
|
||||
ha-state-icon[data-domain="cover"][data-state="open"],
|
||||
ha-state-icon[data-domain="device_tracker"][data-state="home"],
|
||||
ha-state-icon[data-domain="fan"][data-state="on"],
|
||||
ha-state-icon[data-domain="humidifier"][data-state="on"],
|
||||
ha-state-icon[data-domain="light"][data-state="on"],
|
||||
ha-state-icon[data-domain="input_boolean"][data-state="on"],
|
||||
ha-state-icon[data-domain="lock"][data-state="unlocked"],
|
||||
ha-state-icon[data-domain="media_player"][data-state="on"],
|
||||
ha-state-icon[data-domain="media_player"][data-state="paused"],
|
||||
ha-state-icon[data-domain="media_player"][data-state="playing"],
|
||||
ha-state-icon[data-domain="remote"][data-state="on"],
|
||||
ha-state-icon[data-domain="script"][data-state="on"],
|
||||
ha-state-icon[data-domain="sun"][data-state="above_horizon"],
|
||||
ha-state-icon[data-domain="switch"][data-state="on"],
|
||||
ha-state-icon[data-domain="timer"][data-state="active"],
|
||||
ha-state-icon[data-domain="vacuum"][data-state="cleaning"],
|
||||
ha-state-icon[data-domain="group"][data-state="on"],
|
||||
ha-state-icon[data-domain="group"][data-state="home"],
|
||||
ha-state-icon[data-domain="group"][data-state="open"],
|
||||
ha-state-icon[data-domain="group"][data-state="locked"],
|
||||
ha-state-icon[data-domain="group"][data-state="problem"] {
|
||||
ha-state-icon[data-active][data-domain="alert"],
|
||||
ha-state-icon[data-active][data-domain="automation"],
|
||||
ha-state-icon[data-active][data-domain="binary_sensor"],
|
||||
ha-state-icon[data-active][data-domain="calendar"],
|
||||
ha-state-icon[data-active][data-domain="camera"],
|
||||
ha-state-icon[data-active][data-domain="cover"],
|
||||
ha-state-icon[data-active][data-domain="device_tracker"],
|
||||
ha-state-icon[data-active][data-domain="fan"],
|
||||
ha-state-icon[data-active][data-domain="humidifier"],
|
||||
ha-state-icon[data-active][data-domain="light"],
|
||||
ha-state-icon[data-active][data-domain="input_boolean"],
|
||||
ha-state-icon[data-active][data-domain="lock"],
|
||||
ha-state-icon[data-active][data-domain="media_player"],
|
||||
ha-state-icon[data-active][data-domain="remote"],
|
||||
ha-state-icon[data-active][data-domain="script"],
|
||||
ha-state-icon[data-active][data-domain="sun"],
|
||||
ha-state-icon[data-active][data-domain="switch"],
|
||||
ha-state-icon[data-active][data-domain="timer"],
|
||||
ha-state-icon[data-active][data-domain="vacuum"],
|
||||
ha-state-icon[data-active][data-domain="group"] {
|
||||
color: var(--paper-item-icon-active-color, #fdd835);
|
||||
}
|
||||
|
||||
ha-state-icon[data-domain="climate"][data-state="cooling"] {
|
||||
color: var(--cool-color, var(--state-climate-cool-color));
|
||||
}
|
||||
|
||||
ha-state-icon[data-domain="climate"][data-state="heating"] {
|
||||
color: var(--heat-color, var(--state-climate-heat-color));
|
||||
}
|
||||
|
||||
ha-state-icon[data-domain="climate"][data-state="drying"] {
|
||||
color: var(--dry-color, var(--state-climate-dry-color));
|
||||
}
|
||||
|
||||
ha-state-icon[data-domain="alarm_control_panel"] {
|
||||
color: var(--alarm-color-armed, var(--label-badge-red));
|
||||
}
|
||||
ha-state-icon[data-domain="alarm_control_panel"][data-state="disarmed"] {
|
||||
color: var(--alarm-color-disarmed, var(--label-badge-green));
|
||||
}
|
||||
ha-state-icon[data-domain="alarm_control_panel"][data-state="pending"],
|
||||
ha-state-icon[data-domain="alarm_control_panel"][data-state="arming"] {
|
||||
color: var(--alarm-color-pending, var(--label-badge-yellow));
|
||||
animation: pulse 1s infinite;
|
||||
}
|
||||
ha-state-icon[data-domain="alarm_control_panel"][data-state="triggered"] {
|
||||
color: var(--alarm-color-triggered, var(--label-badge-red));
|
||||
ha-state-icon[data-active][data-domain="alarm_control_panel"][data-state="pending"],
|
||||
ha-state-icon[data-active][data-domain="alarm_control_panel"][data-state="arming"],
|
||||
ha-state-icon[data-active][data-domain="alarm_control_panel"][data-state="triggered"] {
|
||||
animation: pulse 1s infinite;
|
||||
}
|
||||
|
||||
@ -70,10 +42,6 @@ export const iconColorCSS = css`
|
||||
}
|
||||
}
|
||||
|
||||
ha-state-icon[data-domain="plant"][data-state="problem"] {
|
||||
color: var(--state-icon-error-color);
|
||||
}
|
||||
|
||||
/* Color the icon if unavailable */
|
||||
ha-state-icon[data-state="unavailable"] {
|
||||
color: var(--state-unavailable-color);
|
||||
|
@ -11,9 +11,10 @@ import {
|
||||
import { property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { computeActiveState } from "../../common/entity/compute_active_state";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import { stateActive } from "../../common/entity/state_active";
|
||||
import { stateColor } from "../../common/entity/state_color";
|
||||
import { iconColorCSS } from "../../common/style/icon_color_css";
|
||||
import { cameraUrlWithWidthHeight } from "../../data/camera";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
@ -35,6 +36,13 @@ export class StateBadge extends LitElement {
|
||||
|
||||
@state() private _iconStyle: { [name: string]: string } = {};
|
||||
|
||||
private get _stateColor() {
|
||||
const domain = this.stateObj
|
||||
? computeStateDomain(this.stateObj)
|
||||
: undefined;
|
||||
return this.stateColor || (domain === "light" && this.stateColor !== false);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const stateObj = this.stateObj;
|
||||
|
||||
@ -50,15 +58,13 @@ export class StateBadge extends LitElement {
|
||||
}
|
||||
|
||||
const domain = stateObj ? computeStateDomain(stateObj) : undefined;
|
||||
const active = this._stateColor && stateObj ? stateActive(stateObj) : false;
|
||||
|
||||
return html`<ha-state-icon
|
||||
style=${styleMap(this._iconStyle)}
|
||||
data-domain=${ifDefined(
|
||||
this.stateColor || (domain === "light" && this.stateColor !== false)
|
||||
? domain
|
||||
: undefined
|
||||
)}
|
||||
data-state=${stateObj ? computeActiveState(stateObj) : ""}
|
||||
?data-active=${active}
|
||||
data-domain=${ifDefined(domain)}
|
||||
data-state=${ifDefined(stateObj?.state)}
|
||||
.icon=${this.overrideIcon}
|
||||
.state=${stateObj}
|
||||
></ha-state-icon>`;
|
||||
@ -69,7 +75,8 @@ export class StateBadge extends LitElement {
|
||||
if (
|
||||
!changedProps.has("stateObj") &&
|
||||
!changedProps.has("overrideImage") &&
|
||||
!changedProps.has("overrideIcon")
|
||||
!changedProps.has("overrideIcon") &&
|
||||
!changedProps.has("stateColor")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@ -100,11 +107,14 @@ export class StateBadge extends LitElement {
|
||||
}
|
||||
hostStyle.backgroundImage = `url(${imageUrl})`;
|
||||
this._showIcon = false;
|
||||
} else if (stateObj.state === "on") {
|
||||
if (this.stateColor !== false && stateObj.attributes.rgb_color) {
|
||||
} else if (stateActive(stateObj) && this._stateColor) {
|
||||
const iconColor = stateColor(stateObj);
|
||||
if (stateObj.attributes.rgb_color) {
|
||||
iconStyle.color = `rgb(${stateObj.attributes.rgb_color.join(",")})`;
|
||||
} else if (iconColor) {
|
||||
iconStyle.color = `rgb(var(--rgb-state-${iconColor}-color))`;
|
||||
}
|
||||
if (stateObj.attributes.brightness && this.stateColor !== false) {
|
||||
if (stateObj.attributes.brightness) {
|
||||
const brightness = stateObj.attributes.brightness;
|
||||
if (typeof brightness !== "number") {
|
||||
const errorMessage = `Type error: state-badge expected number, but type of ${
|
||||
|
@ -21,11 +21,12 @@ import { ifDefined } from "lit/directives/if-defined";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeActiveState } from "../../../common/entity/compute_active_state";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { stateColor } from "../../../common/entity/state_color";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
||||
import "../../../components/ha-card";
|
||||
@ -145,6 +146,13 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
const name = this._config.show_name
|
||||
? this._config.name || (stateObj ? computeStateName(stateObj) : "")
|
||||
: "";
|
||||
const domain = stateObj ? computeStateDomain(stateObj) : undefined;
|
||||
|
||||
const active =
|
||||
(this._config.state_color ||
|
||||
(domain === "light" && this._config.state_color !== false)) &&
|
||||
stateObj &&
|
||||
stateActive(stateObj);
|
||||
|
||||
return html`
|
||||
<ha-card
|
||||
@ -171,19 +179,17 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
? html`
|
||||
<ha-state-icon
|
||||
tabindex="-1"
|
||||
?data-active=${active}
|
||||
data-domain=${ifDefined(
|
||||
this._config.state_color && stateObj
|
||||
? computeStateDomain(stateObj)
|
||||
: undefined
|
||||
)}
|
||||
data-state=${ifDefined(
|
||||
stateObj ? computeActiveState(stateObj) : undefined
|
||||
stateObj ? computeStateDomain(stateObj) : undefined
|
||||
)}
|
||||
data-state=${ifDefined(stateObj?.state)}
|
||||
.icon=${this._config.icon}
|
||||
.state=${stateObj}
|
||||
style=${styleMap({
|
||||
filter: stateObj ? this._computeBrightness(stateObj) : "",
|
||||
color: stateObj ? this._computeColor(stateObj) : "",
|
||||
color: stateObj && active ? this._computeColor(stateObj) : "",
|
||||
filter:
|
||||
stateObj && active ? this._computeBrightness(stateObj) : "",
|
||||
height: this._config.icon_height
|
||||
? this._config.icon_height
|
||||
: "",
|
||||
@ -298,17 +304,21 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
private _computeBrightness(stateObj: HassEntity | LightEntity): string {
|
||||
if (!stateObj.attributes.brightness || !this._config?.state_color) {
|
||||
return "";
|
||||
if (!stateObj.attributes.brightness) {
|
||||
const brightness = stateObj.attributes.brightness;
|
||||
return `brightness(${(brightness + 245) / 5}%)`;
|
||||
}
|
||||
const brightness = stateObj.attributes.brightness;
|
||||
return `brightness(${(brightness + 245) / 5}%)`;
|
||||
return "";
|
||||
}
|
||||
|
||||
private _computeColor(stateObj: HassEntity | LightEntity): string {
|
||||
if (this._config?.state_color && stateObj.attributes.rgb_color) {
|
||||
if (stateObj.attributes.rgb_color) {
|
||||
return `rgb(${stateObj.attributes.rgb_color.join(",")})`;
|
||||
}
|
||||
const iconColor = stateColor(stateObj);
|
||||
if (iconColor) {
|
||||
return `rgb(var(--rgb-state-${iconColor}-color))`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResultGroup,
|
||||
@ -8,12 +9,14 @@ import {
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeActiveState } from "../../../common/entity/compute_active_state";
|
||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { stateColor } from "../../../common/entity/state_color";
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import {
|
||||
formatNumber,
|
||||
@ -25,6 +28,7 @@ import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon";
|
||||
import { UNAVAILABLE_STATES } from "../../../data/entity";
|
||||
import { formatAttributeValue } from "../../../data/entity_attributes";
|
||||
import { LightEntity } from "../../../data/light";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { computeCardSize } from "../common/compute-card-size";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
@ -120,6 +124,11 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
||||
|
||||
const name = this._config.name || computeStateName(stateObj);
|
||||
|
||||
const active =
|
||||
(this._config.state_color ||
|
||||
(domain === "light" && this._config.state_color !== false)) &&
|
||||
stateActive(stateObj);
|
||||
|
||||
return html`
|
||||
<ha-card @click=${this._handleClick} tabindex="0">
|
||||
<div class="header">
|
||||
@ -128,13 +137,15 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
||||
<ha-state-icon
|
||||
.icon=${this._config.icon}
|
||||
.state=${stateObj}
|
||||
data-domain=${ifDefined(
|
||||
this._config.state_color ||
|
||||
(domain === "light" && this._config.state_color !== false)
|
||||
? domain
|
||||
: undefined
|
||||
)}
|
||||
data-state=${stateObj ? computeActiveState(stateObj) : ""}
|
||||
?data-active=${active}
|
||||
data-domain=${ifDefined(domain)}
|
||||
data-state=${stateObj.state}
|
||||
style=${styleMap({
|
||||
color: active ? this._computeColor(stateObj) : "",
|
||||
height: this._config.icon_height
|
||||
? this._config.icon_height
|
||||
: "",
|
||||
})}
|
||||
></ha-state-icon>
|
||||
</div>
|
||||
</div>
|
||||
@ -174,6 +185,24 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
||||
`;
|
||||
}
|
||||
|
||||
private _computeColor(stateObj: HassEntity | LightEntity): string {
|
||||
const domain = computeStateDomain(stateObj);
|
||||
if (
|
||||
!(
|
||||
this._config?.state_color ||
|
||||
(domain === "light" && this._config?.state_color !== false)
|
||||
) ||
|
||||
!stateActive(stateObj)
|
||||
) {
|
||||
return "";
|
||||
}
|
||||
const iconColor = stateColor(stateObj);
|
||||
if (iconColor) {
|
||||
return `rgb(var(--rgb-state-${iconColor}-color))`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
// Side Effect used to update footer hass while keeping optimizations
|
||||
if (this._footerElement) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user