diff --git a/gallery/src/pages/components/ha-bar-switch.ts b/gallery/src/pages/components/ha-bar-switch.ts index aeca191bff..7cf6bf64ef 100644 --- a/gallery/src/pages/components/ha-bar-switch.ts +++ b/gallery/src/pages/components/ha-bar-switch.ts @@ -115,8 +115,8 @@ export class DemoHaBarSwitch extends LitElement { font-weight: 600; } .custom { - --switch-bar-on-color: rgb(var(--rgb-green-color)); - --switch-bar-off-color: rgb(var(--rgb-red-color)); + --switch-bar-on-color: var(--green-color); + --switch-bar-off-color: var(--red-color); --switch-bar-thickness: 100px; --switch-bar-border-radius: 24px; --switch-bar-padding: 6px; diff --git a/gallery/src/pages/misc/entity-state.ts b/gallery/src/pages/misc/entity-state.ts index 2d3326c3b7..abd6e7c4f3 100644 --- a/gallery/src/pages/misc/entity-state.ts +++ b/gallery/src/pages/misc/entity-state.ts @@ -104,16 +104,17 @@ const ENTITIES: HassEntity[] = [ createEntity("alarm_control_panel.disarming", "disarming"), createEntity("alarm_control_panel.triggered", "triggered"), // Alert + createEntity("alert.idle", "idle"), createEntity("alert.off", "off"), createEntity("alert.on", "on"), - createEntity("alert.idle", "idle"), // Automation createEntity("automation.off", "off"), createEntity("automation.on", "on"), // Binary Sensor - ...BINARY_SENSOR_DEVICE_CLASSES.map((dc) => - createEntity(`binary_sensor.${dc}`, "on", dc) - ), + ...BINARY_SENSOR_DEVICE_CLASSES.map((dc) => [ + createEntity(`binary_sensor.${dc}`, "off", dc), + createEntity(`binary_sensor.${dc}`, "on", dc), + ]).reduce((arr, item) => [...arr, ...item], []), // Button createEntity("button.restart", "unknown", "restart"), createEntity("button.update", "unknown", "update"), @@ -142,6 +143,9 @@ const ENTITIES: HassEntity[] = [ createEntity("climate.auto_dry", "auto", undefined, { hvac_action: "drying", }), + createEntity("climate.auto_fan", "auto", undefined, { + hvac_action: "fan", + }), // Cover createEntity("cover.closing", "closing"), createEntity("cover.closed", "closed"), @@ -180,8 +184,8 @@ const ENTITIES: HassEntity[] = [ createEntity("light.off", "off"), createEntity("light.on", "on"), // Locks - createEntity("lock.unlocked", "unlocked"), createEntity("lock.locked", "locked"), + createEntity("lock.unlocked", "unlocked"), createEntity("lock.locking", "locking"), createEntity("lock.unlocking", "unlocking"), createEntity("lock.jammed", "jammed"), @@ -205,17 +209,24 @@ const ENTITIES: HassEntity[] = [ createEntity("media_player.speaker_playing", "playing", "speaker"), createEntity("media_player.speaker_paused", "paused", "speaker"), createEntity("media_player.speaker_standby", "standby", "speaker"), + // Plant + createEntity("plant.ok", "ok"), + createEntity("plant.problem", "problem"), // Remote createEntity("remote.off", "off"), createEntity("remote.on", "on"), + // Schedule + createEntity("schedule.off", "off"), + createEntity("schedule.on", "on"), // Script createEntity("script.off", "off"), createEntity("script.on", "on"), // Sensor ...SENSOR_DEVICE_CLASSES.map((dc) => createEntity(`sensor.${dc}`, "10", dc)), // Battery sensor - ...[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) => - createEntity(`sensor.battery_${value}`, value.toString(), "battery") + ...[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, "unknown", "not_valid"].map( + (value) => + createEntity(`sensor.battery_${value}`, value.toString(), "battery") ), // Siren createEntity("siren.off", "off"), diff --git a/src/common/color/compute-color.ts b/src/common/color/compute-color.ts index 9408b1e7ac..bd28631c13 100644 --- a/src/common/color/compute-color.ts +++ b/src/common/color/compute-color.ts @@ -19,7 +19,9 @@ export const THEME_COLORS = new Set([ "orange", "deep-orange", "brown", + "light-grey", "grey", + "dark-grey", "blue-grey", "black", "white", @@ -27,7 +29,7 @@ export const THEME_COLORS = new Set([ export function computeCssColor(color: string): string { if (THEME_COLORS.has(color)) { - return `rgb(var(--rgb-${color}-color))`; + return `var(--${color}-color)`; } return color; } diff --git a/src/common/entity/color/alarm_control_panel_color.ts b/src/common/entity/color/alarm_control_panel_color.ts deleted file mode 100644 index deb8846088..0000000000 --- a/src/common/entity/color/alarm_control_panel_color.ts +++ /dev/null @@ -1,21 +0,0 @@ -export const alarmControlPanelColor = (state?: string): string | undefined => { - switch (state) { - case "armed_away": - case "armed_vacation": - case "armed_home": - case "armed_night": - case "armed_custom_bypass": - return "alarm-armed"; - case "pending": - return "alarm-pending"; - case "arming": - case "disarming": - return "alarm-arming"; - case "triggered": - return "alarm-triggered"; - case "disarmed": - return "alarm-disarmed"; - default: - return undefined; - } -}; diff --git a/src/common/entity/color/alert_color.ts b/src/common/entity/color/alert_color.ts deleted file mode 100644 index 3e3ccbe6a4..0000000000 --- a/src/common/entity/color/alert_color.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const alertColor = (state?: string): string | undefined => { - switch (state) { - case "on": - return "alert"; - case "off": - return "alert-off"; - default: - return undefined; - } -}; diff --git a/src/common/entity/color/battery_color.ts b/src/common/entity/color/battery_color.ts index b10c5144fe..bbf62f1b09 100644 --- a/src/common/entity/color/battery_color.ts +++ b/src/common/entity/color/battery_color.ts @@ -1,13 +1,15 @@ -export const batteryStateColor = (state: string) => { +export const batteryStateColorProperty = ( + state: string +): string | undefined => { const value = Number(state); if (isNaN(value)) { return undefined; } if (value >= 70) { - return "sensor-battery-high"; + return "--state-sensor-battery-high-color"; } if (value >= 30) { - return "sensor-battery-medium"; + return "--state-sensor-battery-medium-color"; } - return "sensor-battery-low"; + return "--state-sensor-battery-low-color"; }; diff --git a/src/common/entity/color/binary_sensor_color.ts b/src/common/entity/color/binary_sensor_color.ts deleted file mode 100644 index 90f7247be4..0000000000 --- a/src/common/entity/color/binary_sensor_color.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { HassEntity } from "home-assistant-js-websocket"; -import { stateActive } from "../state_active"; - -const ALERTING_DEVICE_CLASSES = new Set([ - "battery", - "carbon_monoxide", - "gas", - "heat", - "lock", - "moisture", - "problem", - "safety", - "smoke", - "tamper", -]); - -export const binarySensorColor = ( - stateObj: HassEntity, - state: string -): string | undefined => { - const deviceClass = stateObj?.attributes.device_class; - - if (!stateActive(stateObj, state)) { - return undefined; - } - return deviceClass && ALERTING_DEVICE_CLASSES.has(deviceClass) - ? "binary-sensor-alerting" - : "binary-sensor"; -}; diff --git a/src/common/entity/color/climate_color.ts b/src/common/entity/color/climate_color.ts deleted file mode 100644 index 390e9ab739..0000000000 --- a/src/common/entity/color/climate_color.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { HvacAction } from "../../../data/climate"; - -export const CLIMATE_HVAC_ACTION_COLORS: Record = { - cooling: "var(--rgb-state-climate-cool-color)", - drying: "var(--rgb-state-climate-dry-color)", - fan: "var(--rgb-state-climate-fan-only-color)", - heating: "var(--rgb-state-climate-heat-color)", - idle: "var(--rgb-state-climate-idle-color)", - off: "var(--rgb-state-climate-off-color)", -}; - -export const climateColor = (state: string): string | undefined => { - switch (state) { - case "auto": - return "climate-auto"; - case "cool": - return "climate-cool"; - case "dry": - return "climate-dry"; - case "fan_only": - return "climate-fan-only"; - case "heat": - return "climate-heat"; - case "heat_cool": - return "climate-heat-cool"; - default: - return undefined; - } -}; diff --git a/src/common/entity/color/lock_color.ts b/src/common/entity/color/lock_color.ts deleted file mode 100644 index 6d0ec06665..0000000000 --- a/src/common/entity/color/lock_color.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const lockColor = (state?: string): string | undefined => { - switch (state) { - case "unlocked": - return "lock-unlocked"; - case "locked": - return "lock-locked"; - case "jammed": - return "lock-jammed"; - case "locking": - case "unlocking": - return "lock-pending"; - default: - return undefined; - } -}; diff --git a/src/common/entity/color/person_color.ts b/src/common/entity/color/person_color.ts deleted file mode 100644 index efdabbd33d..0000000000 --- a/src/common/entity/color/person_color.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const personColor = (state: string): string | undefined => { - switch (state) { - case "home": - return "person-home"; - case "not_home": - return "person-not-home"; - default: - return "person-zone"; - } -}; diff --git a/src/common/entity/color/sensor_color.ts b/src/common/entity/color/sensor_color.ts deleted file mode 100644 index 298f996f26..0000000000 --- a/src/common/entity/color/sensor_color.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { HassEntity } from "home-assistant-js-websocket"; -import { batteryStateColor } from "./battery_color"; - -export const sensorColor = ( - stateObj: HassEntity, - state: string -): string | undefined => { - const deviceClass = stateObj?.attributes.device_class; - - if (deviceClass === "battery") { - return batteryStateColor(state); - } - - return undefined; -}; diff --git a/src/common/entity/color/update_color.ts b/src/common/entity/color/update_color.ts deleted file mode 100644 index b034239e95..0000000000 --- a/src/common/entity/color/update_color.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { HassEntity } from "home-assistant-js-websocket"; -import { UpdateEntity, updateIsInstalling } from "../../../data/update"; -import { stateActive } from "../state_active"; - -export const updateColor = ( - stateObj: HassEntity, - state: string -): string | undefined => { - if (!stateActive(stateObj, state)) { - return undefined; - } - return updateIsInstalling(stateObj as UpdateEntity) - ? "update-installing" - : "update"; -}; diff --git a/src/common/entity/state_color.ts b/src/common/entity/state_color.ts index 6d3848fc90..32d0be425b 100644 --- a/src/common/entity/state_color.ts +++ b/src/common/entity/state_color.ts @@ -1,96 +1,102 @@ /** Return an color representing a state. */ import { HassEntity } from "home-assistant-js-websocket"; import { UNAVAILABLE } from "../../data/entity"; -import { alarmControlPanelColor } from "./color/alarm_control_panel_color"; -import { alertColor } from "./color/alert_color"; -import { binarySensorColor } from "./color/binary_sensor_color"; -import { climateColor } from "./color/climate_color"; -import { lockColor } from "./color/lock_color"; -import { personColor } from "./color/person_color"; -import { sensorColor } from "./color/sensor_color"; -import { updateColor } from "./color/update_color"; +import { computeCssVariable } from "../../resources/css-variables"; +import { slugify } from "../string/slugify"; +import { batteryStateColorProperty } from "./color/battery_color"; import { computeDomain } from "./compute_domain"; import { stateActive } from "./state_active"; -const STATIC_ACTIVE_COLORED_DOMAIN = new Set([ +const STATE_COLORED_DOMAIN = new Set([ + "alarm_control_panel", + "alert", "automation", + "binary_sensor", "calendar", "camera", + "climate", "cover", + "device_tracker", "fan", "group", "humidifier", "input_boolean", "light", + "lock", "media_player", + "person", "plant", "remote", "schedule", "script", "siren", + "sun", "switch", "timer", + "update", "vacuum", ]); export const stateColorCss = (stateObj: HassEntity, state?: string) => { const compareState = state !== undefined ? state : stateObj?.state; if (compareState === UNAVAILABLE) { - return `var(--rgb-state-unavailable-color)`; + return `var(--state-unavailable-color)`; } - const domainColor = stateColor(stateObj, state); - - if (domainColor) { - return `var(--rgb-state-${domainColor}-color)`; - } - - if (!stateActive(stateObj, state)) { - return `var(--rgb-state-inactive-color)`; + const properties = stateColorProperties(stateObj, state); + if (properties) { + return computeCssVariable(properties); } return undefined; }; -export const stateColor = (stateObj: HassEntity, state?: string) => { +export const domainStateColorProperties = ( + stateObj: HassEntity, + state?: string +): string[] => { + const compareState = state !== undefined ? state : stateObj.state; + const domain = computeDomain(stateObj.entity_id); + const active = stateActive(stateObj, state); + + const properties: string[] = []; + + const stateKey = slugify(compareState, "_"); + const activeKey = active ? "active" : "inactive"; + + const dc = stateObj.attributes.device_class; + + if (dc) { + properties.push(`--state-${domain}-${dc}-${stateKey}-color`); + } + + properties.push( + `--state-${domain}-${stateKey}-color`, + `--state-${domain}-${activeKey}-color`, + `--state-${activeKey}-color` + ); + + return properties; +}; + +export const stateColorProperties = ( + stateObj: HassEntity, + state?: string +): string[] | undefined => { const compareState = state !== undefined ? state : stateObj?.state; const domain = computeDomain(stateObj.entity_id); + const dc = stateObj.attributes.device_class; - if ( - STATIC_ACTIVE_COLORED_DOMAIN.has(domain) && - stateActive(stateObj, state) - ) { - return domain.replace("_", "-"); + // Special rules for battery coloring + if (domain === "sensor" && dc === "battery") { + const property = batteryStateColorProperty(compareState); + if (property) { + return [property]; + } } - switch (domain) { - case "alarm_control_panel": - return alarmControlPanelColor(compareState); - - case "alert": - return alertColor(compareState); - - case "binary_sensor": - return binarySensorColor(stateObj, compareState); - - case "climate": - return climateColor(compareState); - - case "lock": - return lockColor(compareState); - - case "person": - case "device_tracker": - return personColor(compareState); - - case "sensor": - return sensorColor(stateObj, compareState); - - case "sun": - return compareState === "above_horizon" ? "sun-day" : "sun-night"; - - case "update": - return updateColor(stateObj, compareState); + if (STATE_COLORED_DOMAIN.has(domain)) { + return domainStateColorProperties(stateObj, state); } return undefined; diff --git a/src/common/style/icon_color_css.ts b/src/common/style/icon_color_css.ts index 2b717c13cc..e7ff6d4728 100644 --- a/src/common/style/icon_color_css.ts +++ b/src/common/style/icon_color_css.ts @@ -22,6 +22,6 @@ export const iconColorCSS = css` /* Color the icon if unavailable */ ha-state-icon[data-state="unavailable"] { - color: rgb(var(--rgb-state-unavailable-color)); + color: var(--state-unavailable-color); } `; diff --git a/src/components/chart/timeline-chart/timeline-color.ts b/src/components/chart/timeline-chart/timeline-color.ts index ecbf9a78cc..3a08adea4d 100644 --- a/src/components/chart/timeline-chart/timeline-color.ts +++ b/src/components/chart/timeline-chart/timeline-color.ts @@ -1,11 +1,11 @@ import { HassEntity } from "home-assistant-js-websocket"; import { getGraphColorByIndex } from "../../../common/color/colors"; -import { lab2hex, rgb2hex, rgb2lab } from "../../../common/color/convert-color"; +import { hex2rgb, lab2hex, rgb2lab } from "../../../common/color/convert-color"; import { labBrighten } from "../../../common/color/lab"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { stateActive } from "../../../common/entity/state_active"; -import { stateColor } from "../../../common/entity/state_color"; -import { UNAVAILABLE } from "../../../data/entity"; +import { stateColorProperties } from "../../../common/entity/state_color"; +import { UNAVAILABLE, UNKNOWN } from "../../../data/entity"; +import { computeCssValue } from "../../../resources/css-variables"; const DOMAIN_STATE_SHADES: Record> = { media_player: { @@ -17,61 +17,35 @@ const DOMAIN_STATE_SHADES: Record> = { }, }; -const cssColorMap: Map = new Map(); - -function cssToRgb( - cssVariable: string, - computedStyles: CSSStyleDeclaration -): [number, number, number] | undefined { - if (!cssVariable.startsWith("--rgb")) { - return undefined; - } - - if (cssColorMap.has(cssVariable)) { - return cssColorMap.get(cssVariable)!; - } - - const value = computedStyles.getPropertyValue(cssVariable); - - if (!value) return undefined; - - const rgb = value.split(",").map((v) => Number(v)) as [ - number, - number, - number - ]; - cssColorMap.set(cssVariable, rgb); - - return rgb; -} - function computeTimelineStateColor( state: string, computedStyles: CSSStyleDeclaration, stateObj?: HassEntity ): string | undefined { if (!stateObj || state === UNAVAILABLE) { - return "transparent"; + return computeCssValue("--history-unavailable-color", computedStyles); } - const color = stateColor(stateObj, state); - - if (!color && !stateActive(stateObj, state)) { - const rgb = cssToRgb("--rgb-state-inactive-color", computedStyles); - if (!rgb) return undefined; - return rgb2hex(rgb); + if (state === UNKNOWN) { + return computeCssValue("--history-unknown-color", computedStyles); } - const rgb = cssToRgb(`--rgb-state-${color}-color`, computedStyles); + const properties = stateColorProperties(stateObj, state); + + if (!properties) { + return undefined; + } + + const rgb = computeCssValue(properties, computedStyles); if (!rgb) return undefined; const domain = computeDomain(stateObj.entity_id); const shade = DOMAIN_STATE_SHADES[domain]?.[state] as number | number; if (!shade) { - return rgb2hex(rgb); + return rgb; } - return lab2hex(labBrighten(rgb2lab(rgb), shade)); + return lab2hex(labBrighten(rgb2lab(hex2rgb(rgb)), shade)); } let colorIndex = 0; diff --git a/src/components/entity/state-badge.ts b/src/components/entity/state-badge.ts index 99ab8a9575..0a77c66b98 100644 --- a/src/components/entity/state-badge.ts +++ b/src/components/entity/state-badge.ts @@ -11,13 +11,13 @@ import { import { property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; -import { CLIMATE_HVAC_ACTION_COLORS } from "../../common/entity/color/climate_color"; import { computeDomain } from "../../common/entity/compute_domain"; import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { stateActive } from "../../common/entity/state_active"; import { stateColorCss } from "../../common/entity/state_color"; import { iconColorCSS } from "../../common/style/icon_color_css"; import { cameraUrlWithWidthHeight } from "../../data/camera"; +import { HVAC_ACTION_TO_MODE } from "../../data/climate"; import type { HomeAssistant } from "../../types"; import "../ha-state-icon"; @@ -115,7 +115,7 @@ export class StateBadge extends LitElement { } else if (this._stateColor && stateActive(stateObj)) { const color = stateColorCss(stateObj); if (color) { - iconStyle.color = `rgb(${color})`; + iconStyle.color = color; } if (stateObj.attributes.rgb_color) { iconStyle.color = `rgb(${stateObj.attributes.rgb_color.join(",")})`; @@ -134,8 +134,11 @@ export class StateBadge extends LitElement { } if (stateObj.attributes.hvac_action) { const hvacAction = stateObj.attributes.hvac_action; - if (["heating", "cooling", "drying"].includes(hvacAction)) { - iconStyle.color = `rgb(${CLIMATE_HVAC_ACTION_COLORS[hvacAction]})`; + if (["heating", "cooling", "drying", "fan"].includes(hvacAction)) { + iconStyle.color = stateColorCss( + stateObj, + HVAC_ACTION_TO_MODE[hvacAction] + )!; } else { delete iconStyle.color; } diff --git a/src/components/ha-bar-slider.ts b/src/components/ha-bar-slider.ts index ccbf1dbf55..51bd09df6a 100644 --- a/src/components/ha-bar-slider.ts +++ b/src/components/ha-bar-slider.ts @@ -271,8 +271,8 @@ export class HaBarSlider extends LitElement { return css` :host { display: block; - --slider-bar-color: rgb(var(--rgb-primary-color)); - --slider-bar-background: rgb(var(--rgb-disabled-color)); + --slider-bar-color: var(--primary-color); + --slider-bar-background: var(--disabled-color); --slider-bar-background-opacity: 0.2; --slider-bar-thickness: 40px; --slider-bar-border-radius: 10px; @@ -401,7 +401,7 @@ export class HaBarSlider extends LitElement { .slider .slider-track-cursor:after { display: block; content: ""; - background-color: rgb(var(--rgb-secondary-text-color)); + background-color: var(--secondary-text-color); position: absolute; top: 0; left: 0; diff --git a/src/components/ha-bar-switch.ts b/src/components/ha-bar-switch.ts index 5b20e0bfa7..c2e6b9d782 100644 --- a/src/components/ha-bar-switch.ts +++ b/src/components/ha-bar-switch.ts @@ -92,8 +92,8 @@ export class HaBarSwitch extends LitElement { return css` :host { display: block; - --switch-bar-on-color: rgb(var(--rgb-primary-color)); - --switch-bar-off-color: rgb(var(--rgb-disabled-color)); + --switch-bar-on-color: var(--primary-color); + --switch-bar-off-color: var(--disabled-color); --switch-bar-background-opacity: 0.2; --switch-bar-thickness: 40px; --switch-bar-border-radius: 12px; diff --git a/src/components/tile/ha-tile-badge.ts b/src/components/tile/ha-tile-badge.ts index 183f217109..dea713e069 100644 --- a/src/components/tile/ha-tile-badge.ts +++ b/src/components/tile/ha-tile-badge.ts @@ -21,8 +21,8 @@ export class HaTileBadge extends LitElement { static get styles(): CSSResultGroup { return css` :host { - --tile-badge-background-color: rgb(var(--rgb-primary-color)); - --tile-badge-icon-color: rgb(var(--rgb-white-color)); + --tile-badge-background-color: var(--primary-color); + --tile-badge-icon-color: var(--white-color); --mdc-icon-size: 12px; } .badge { diff --git a/src/components/tile/ha-tile-button.ts b/src/components/tile/ha-tile-button.ts index c6555b3e11..321536d8eb 100644 --- a/src/components/tile/ha-tile-button.ts +++ b/src/components/tile/ha-tile-button.ts @@ -82,9 +82,8 @@ export class HaTileButton extends LitElement { return css` :host { --tile-button-icon-color: var(--primary-text-color); - --tile-button-background-color: rgb(var(--rgb-disabled-color)); + --tile-button-background-color: var(--disabled-color); --tile-button-background-opacity: 0.2; - --mdc-ripple-color: var(--tile-button-background-color); width: 40px; height: 40px; -webkit-tap-highlight-color: transparent; @@ -107,6 +106,7 @@ export class HaTileButton extends LitElement { outline: none; overflow: hidden; background: none; + --mdc-ripple-color: var(--tile-button-background-color); } .button::before { content: ""; @@ -128,7 +128,7 @@ export class HaTileButton extends LitElement { } .button:disabled { cursor: not-allowed; - --tile-button-background-color: rgb(var(--rgb-disabled-color)); + --tile-button-background-color: var(--disabled-color); --tile-button-icon-color: var(--disabled-text-color); --tile-button-background-opacity: 0.2; } diff --git a/src/components/tile/ha-tile-icon.ts b/src/components/tile/ha-tile-icon.ts index a03643b10d..5bf889575f 100644 --- a/src/components/tile/ha-tile-icon.ts +++ b/src/components/tile/ha-tile-icon.ts @@ -22,7 +22,7 @@ export class HaTileIcon extends LitElement { static get styles(): CSSResultGroup { return css` :host { - --tile-icon-color: rgb(var(--rgb-disabled-color)); + --tile-icon-color: var(--disabled-color); --mdc-icon-size: 24px; } .shape::before { diff --git a/src/components/tile/ha-tile-slider.ts b/src/components/tile/ha-tile-slider.ts index 60f45378b5..c010f151dd 100644 --- a/src/components/tile/ha-tile-slider.ts +++ b/src/components/tile/ha-tile-slider.ts @@ -47,13 +47,10 @@ export class HaTileSlider extends LitElement { static get styles(): CSSResultGroup { return css` ha-bar-slider { - --slider-bar-color: var( - --tile-slider-color, - rgb(var(--rgb-primary-color)) - ); + --slider-bar-color: var(--tile-slider-color, var(--primary-color)); --slider-bar-background: var( --tile-slider-background, - rgb(var(--rgb-disabled-color)) + var(--disabled-color) ); --slider-bar-background-opacity: var( --tile-slider-background-opacity, diff --git a/src/data/climate.ts b/src/data/climate.ts index 6ed6fa7523..b72f845cbf 100644 --- a/src/data/climate.ts +++ b/src/data/climate.ts @@ -72,3 +72,12 @@ const hvacModeOrdering: { [key in HvacMode]: number } = { export const compareClimateHvacModes = (mode1: HvacMode, mode2: HvacMode) => hvacModeOrdering[mode1] - hvacModeOrdering[mode2]; + +export const HVAC_ACTION_TO_MODE: Record = { + cooling: "cool", + drying: "dry", + fan: "fan_only", + heating: "heat", + idle: "off", + off: "off", +}; diff --git a/src/panels/logbook/ha-logbook-renderer.ts b/src/panels/logbook/ha-logbook-renderer.ts index 47edea75ce..270387b7bb 100644 --- a/src/panels/logbook/ha-logbook-renderer.ts +++ b/src/panels/logbook/ha-logbook-renderer.ts @@ -577,7 +577,7 @@ class HaLogbookRenderer extends LitElement { } .indicator { - background-color: rgb(var(--rgb-disabled-color)); + background-color: var(--disabled-color); height: 8px; width: 8px; border-radius: 4px; diff --git a/src/panels/lovelace/cards/hui-alarm-panel-card.ts b/src/panels/lovelace/cards/hui-alarm-panel-card.ts index 4ec7cda0a9..1f2d2bb6c5 100644 --- a/src/panels/lovelace/cards/hui-alarm-panel-card.ts +++ b/src/panels/lovelace/cards/hui-alarm-panel-card.ts @@ -8,13 +8,15 @@ import { } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; +import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; import { alarmPanelIcon } from "../../../common/entity/alarm_panel_icon"; +import { stateColorCss } from "../../../common/entity/state_color"; import "../../../components/ha-card"; import "../../../components/ha-chip"; -import type { HaTextField } from "../../../components/ha-textfield"; import "../../../components/ha-textfield"; +import type { HaTextField } from "../../../components/ha-textfield"; import { callAlarmAction, FORMAT_NUMBER, @@ -155,6 +157,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { stateLabel} @@ -269,7 +274,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { flex-direction: column; align-items: center; box-sizing: border-box; - --alarm-state-color: rgb(var(--rgb-state-alarm-armed-color)); + --alarm-state-color: var(--state-inactive-color); } ha-chip { @@ -286,26 +291,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { box-sizing: border-box; } - .unavailable { - --alarm-state-color: rgb(var(--rgb-state-unavailable-color)); - } - - .disarmed { - --alarm-state-color: rgb(var(--rgb-state-alarm-disarmed-color)); - } - - .triggered { - --alarm-state-color: rgb(var(--rgb-state-alarm-triggered-color)); - animation: pulse 1s infinite; - } - - .arming { - --alarm-state-color: rgb(var(--rgb-state-alarm-arming-color)); - animation: pulse 1s infinite; - } - + .triggered, + .arming, .pending { - --alarm-state-color: rgb(var(--rgb-state-alarm-pending-color)); animation: pulse 1s infinite; } diff --git a/src/panels/lovelace/cards/hui-area-card.ts b/src/panels/lovelace/cards/hui-area-card.ts index adfcbe04c1..b394774462 100644 --- a/src/panels/lovelace/cards/hui-area-card.ts +++ b/src/panels/lovelace/cards/hui-area-card.ts @@ -563,7 +563,7 @@ export class HuiAreaCard --mdc-icon-button-size: 44px; } .on { - color: rgb(var(--rgb-state-light-color)); + color: var(--state-light-color); } `; } diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index 4b41c6d02b..b30b106c31 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -21,7 +21,6 @@ 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 { CLIMATE_HVAC_ACTION_COLORS } from "../../../common/entity/color/climate_color"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; @@ -31,6 +30,7 @@ import { stateColorCss } 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"; +import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { LightEntity } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; @@ -324,14 +324,14 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { } if (stateObj.attributes.hvac_action) { const hvacAction = stateObj.attributes.hvac_action; - if (["heating", "cooling", "drying"].includes(hvacAction)) { - return `rgb(${CLIMATE_HVAC_ACTION_COLORS[hvacAction]})`; + if (["heating", "cooling", "drying", "fan"].includes(hvacAction)) { + return stateColorCss(stateObj, HVAC_ACTION_TO_MODE[hvacAction]); } return undefined; } const iconColor = stateColorCss(stateObj); if (iconColor) { - return `rgb(${iconColor})`; + return iconColor; } return undefined; } diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index a0abc1a25c..7bf7c526de 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -12,7 +12,6 @@ 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 { CLIMATE_HVAC_ACTION_COLORS } from "../../../common/entity/color/climate_color"; import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; @@ -27,6 +26,7 @@ import { import { iconColorCSS } from "../../../common/style/icon_color_css"; import "../../../components/ha-card"; import "../../../components/ha-icon"; +import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { isUnavailableState } from "../../../data/entity"; import { formatAttributeValue } from "../../../data/entity_attributes"; import { LightEntity } from "../../../data/light"; @@ -197,8 +197,8 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { private _computeColor(stateObj: HassEntity): string | undefined { if (stateObj.attributes.hvac_action) { const hvacAction = stateObj.attributes.hvac_action; - if (["heating", "cooling", "drying"].includes(hvacAction)) { - return `rgb(${CLIMATE_HVAC_ACTION_COLORS[hvacAction]})`; + if (["heating", "cooling", "drying", "fan"].includes(hvacAction)) { + return stateColorCss(stateObj, HVAC_ACTION_TO_MODE[hvacAction]); } return undefined; } @@ -207,7 +207,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { } const iconColor = stateColorCss(stateObj); if (iconColor) { - return `rgb(${iconColor})`; + return iconColor; } return undefined; } diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 2b60d831cb..6fa001d3b3 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -330,7 +330,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard { } .light-button.state-on { - color: rgb(var(--rgb-state-light-color)); + color: var(--state-light-color); } .light-button.state-unavailable { diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 9ce9f8fa62..58983fecf5 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -21,12 +21,14 @@ import { } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; +import { styleMap } from "lit/directives/style-map"; import { UNIT_F } from "../../../common/const"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; +import { stateColorCss } from "../../../common/entity/state_color"; import { formatNumber } from "../../../common/number/format_number"; import "../../../components/ha-card"; import type { HaCard } from "../../../components/ha-card"; @@ -249,8 +251,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { return html` @@ -292,6 +291,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { const stateDisplay = this._computeStateDisplay(stateObj); + const active = stateActive(stateObj); const color = this._computeStateColor(stateObj, this._config.color); const style = { @@ -308,7 +308,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { ); return html` - + ${this._shouldRenderRipple ? html`` : null}
` @@ -407,7 +407,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { static get styles(): CSSResultGroup { return css` :host { - --tile-color: rgb(var(--rgb-state-inactive-color)); + --tile-color: var(--state-inactive-color); -webkit-tap-highlight-color: transparent; } ha-card:has(ha-tile-info:focus-visible) { @@ -421,8 +421,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard { // For safari overflow hidden z-index: 0; } - ha-card.disabled { - --tile-color: rgb(var(--rgb-disabled-color)); + ha-card.active { + --tile-color: var(--state-icon-color); } [role="button"] { cursor: pointer; diff --git a/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts b/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts index db6c4324f5..81e7346983 100644 --- a/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts +++ b/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts @@ -6,8 +6,12 @@ import { mdiSnowflake, mdiWaterPercent, } from "@mdi/js"; -import { CLIMATE_HVAC_ACTION_COLORS } from "../../../../../common/entity/color/climate_color"; -import { ClimateEntity, HvacAction } from "../../../../../data/climate"; +import { stateColorCss } from "../../../../../common/entity/state_color"; +import { + ClimateEntity, + HvacAction, + HvacMode, +} from "../../../../../data/climate"; import { ComputeBadgeFunction } from "./tile-badge"; export const CLIMATE_HVAC_ACTION_ICONS: Record = { @@ -19,6 +23,15 @@ export const CLIMATE_HVAC_ACTION_ICONS: Record = { off: mdiPower, }; +export const CLIMATE_HVAC_ACTION_MODE: Record = { + cooling: "cool", + drying: "dry", + fan: "fan_only", + heating: "heat", + idle: "off", + off: "off", +}; + export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => { const hvacAction = (stateObj as ClimateEntity).attributes.hvac_action; @@ -28,6 +41,6 @@ export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => { return { iconPath: CLIMATE_HVAC_ACTION_ICONS[hvacAction], - color: CLIMATE_HVAC_ACTION_COLORS[hvacAction], + color: stateColorCss(stateObj, CLIMATE_HVAC_ACTION_MODE[hvacAction]), }; }; diff --git a/src/panels/lovelace/cards/tile/badges/tile-badge-person.ts b/src/panels/lovelace/cards/tile/badges/tile-badge-person.ts index d4ad3d64c0..6d58f5af81 100644 --- a/src/panels/lovelace/cards/tile/badges/tile-badge-person.ts +++ b/src/panels/lovelace/cards/tile/badges/tile-badge-person.ts @@ -1,5 +1,6 @@ import { mdiHome, mdiHomeExportOutline } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; +import { stateColorCss } from "../../../../../common/entity/state_color"; import { HomeAssistant } from "../../../../../types"; import { ComputeBadgeFunction } from "./tile-badge"; @@ -19,23 +20,12 @@ function personBadgeIcon(entity: HassEntity) { return state === "not_home" ? mdiHomeExportOutline : mdiHome; } -function personBadgeColor(entity: HassEntity) { - switch (entity.state) { - case "home": - return "var(--rgb-state-person-home-color)"; - case "not_home": - return "var(--rgb-state-person-not-home-color)"; - default: - return "var(--rgb-state-person-zone-color)"; - } -} - export const computePersonBadge: ComputeBadgeFunction = (stateObj, hass) => { const zone = getZone(stateObj, hass); return { iconPath: personBadgeIcon(stateObj), icon: zone?.attributes.icon, - color: personBadgeColor(stateObj), + color: stateColorCss(stateObj), }; }; diff --git a/src/panels/lovelace/cards/tile/badges/tile-badge.ts b/src/panels/lovelace/cards/tile/badges/tile-badge.ts index b446097553..e303c49129 100644 --- a/src/panels/lovelace/cards/tile/badges/tile-badge.ts +++ b/src/panels/lovelace/cards/tile/badges/tile-badge.ts @@ -7,7 +7,7 @@ import { computeClimateBadge } from "./tile-badge-climate"; import { computePersonBadge } from "./tile-badge-person"; export type TileBadge = { - color: string; + color?: string; icon?: string; iconPath?: string; }; @@ -23,7 +23,7 @@ export const computeTileBadge: ComputeBadgeFunction = (stateObj, hass) => { } if (stateObj.state === UNAVAILABLE) { return { - color: "var(--rgb-orange-color)", + color: "var(--orange-color)", iconPath: mdiExclamationThick, }; } diff --git a/src/resources/css-variables.ts b/src/resources/css-variables.ts new file mode 100644 index 0000000000..fe74704f9a --- /dev/null +++ b/src/resources/css-variables.ts @@ -0,0 +1,31 @@ +export function computeCssVariable( + props: string | string[] +): string | undefined { + if (Array.isArray(props)) { + return props + .reverse() + .reduce( + (str, variable) => `var(${variable}${str ? `, ${str}` : ""})`, + undefined + ); + } + return `var(${props})`; +} + +export function computeCssValue( + prop: string | string[], + computedStyles: CSSStyleDeclaration +): string | undefined { + if (Array.isArray(prop)) { + for (const property of prop) { + const value = computeCssValue(property, computedStyles); + if (value) return value; + } + return undefined; + } + + if (!prop.endsWith("-color")) { + return undefined; + } + return computedStyles.getPropertyValue(prop).trim() || undefined; +} diff --git a/src/resources/ha-style.ts b/src/resources/ha-style.ts index e04247ac30..4dd57f2c7f 100644 --- a/src/resources/ha-style.ts +++ b/src/resources/ha-style.ts @@ -57,30 +57,11 @@ documentContainer.innerHTML = ` --label-badge-yellow: #f4b400; --label-badge-grey: #9e9e9e; - /* states */ + /* states icon */ --state-icon-color: #44739e; /* an error state is anything that would be considered an error */ /* --state-icon-error-color: #db4437; derived from error-color */ - --state-on-color: #66a61e; - --state-off-color: #ff0029; - --state-home-color: #66a61e; - --state-not_home-color: #ff0029; - /* --state-unavailable-color: #a0a0a0; derived from disabled-text-color */ - --state-unknown-color: #606060; - --state-idle-color: #7990a3; - - /* climate state colors */ - --state-climate-auto-color: #008000; - --state-climate-eco-color: #00ff7f; - --state-climate-cool-color: #2b9af9; - --state-climate-heat-color: #ff8100; - --state-climate-manual-color: #44739e; - --state-climate-off-color: #8a8a8a; - --state-climate-fan_only-color: #8a8a8a; - --state-climate-dry-color: #efbd07; - --state-climate-idle-color: #8a8a8a; - /* energy */ --energy-grid-consumption-color: #488fc2; --energy-grid-return-color: #8353d1; @@ -106,87 +87,99 @@ documentContainer.innerHTML = ` /* rgb */ --rgb-primary-color: 3, 169, 244; --rgb-accent-color: 255, 152, 0; - --rgb-disabled-color: 189, 189, 189; --rgb-primary-text-color: 33, 33, 33; --rgb-secondary-text-color: 114, 114, 114; --rgb-text-primary-color: 255, 255, 255; --rgb-card-background-color: 255, 255, 255; - --rgb-red-color: 244, 67, 54; - --rgb-pink-color: 233, 30, 99; - --rgb-purple-color: 156, 39, 176; - --rgb-deep-purple-color: 103, 58, 183; - --rgb-indigo-color: 63, 81, 181; - --rgb-blue-color: 33, 150, 243; - --rgb-light-blue-color: 3, 169, 244; - --rgb-cyan-color: 0, 188, 212; - --rgb-teal-color: 0, 150, 136; - --rgb-green-color: 76, 175, 80; - --rgb-light-green-color: 139, 195, 74; - --rgb-lime-color: 205, 220, 57; - --rgb-yellow-color: 255, 235, 59; - --rgb-amber-color: 255, 193, 7; - --rgb-orange-color: 255, 152, 0; - --rgb-deep-orange-color: 255, 87, 34; - --rgb-brown-color: 121, 85, 72; - --rgb-grey-color: 158, 158, 158; - --rgb-blue-grey-color: 96, 125, 139; - --rgb-black-color: 0, 0, 0; - --rgb-white-color: 255, 255, 255; - /* rgb state color */ - --rgb-state-default-color: var(--rgb-dark-primary-color, 68, 115, 158); - --rgb-state-inactive-color: var(--rgb-grey-color); - --rgb-state-unavailable-color: var(--rgb-disabled-color); + /* color */ + --disabled-color: #bdbdbd; + --red-color: #f44336; + --pink-color: #e91e63; + --purple-color: #9c27b0; + --deep-purple-color: #673ab7; + --indigo-color: #3f51b5; + --blue-color: #2196f3; + --light-blue-color: #03a9f4; + --cyan-color: #00bcd4; + --teal-color: #009688; + --green-color: #4caf50; + --light-green-color: #8bc34a; + --lime-color: #cddc39; + --yellow-color: #ffeb3b; + --amber-color: #ffc107; + --orange-color: #ff9800; + --deep-orange-color: #ff5722; + --brown-color: #795548; + --light-grey-color: #bdbdbd; + --grey-color: #9e9e9e; + --dark-grey-color: #606060; + --blue-grey-color: #607d8b; + --black-color: #000000; + --white-color: #ffffff; - /* rgb state domain colors */ - --rgb-state-alarm-armed-color: var(--rgb-green-color); - --rgb-state-alarm-arming-color: var(--rgb-orange-color); - --rgb-state-alarm-disarmed-color: var(--rgb-grey-color); - --rgb-state-alarm-pending-color: var(--rgb-orange-color); - --rgb-state-alarm-triggered-color: var(--rgb-red-color); - --rgb-state-alert-color: var(--rgb-red-color); - --rgb-state-alert-off-color: var(--rgb-orange-color); - --rgb-state-automation-color: var(--rgb-amber-color); - --rgb-state-binary-sensor-alerting-color: var(--rgb-red-color); - --rgb-state-binary-sensor-color: var(--rgb-amber-color); - --rgb-state-calendar-color: var(--rgb-amber-color); - --rgb-state-camera-color: var(--rgb-amber-color); - --rgb-state-climate-auto-color: var(--rgb-green-color); - --rgb-state-climate-cool-color: var(--rgb-blue-color); - --rgb-state-climate-dry-color: var(--rgb-orange-color); - --rgb-state-climate-fan-only-color: var(--rgb-cyan-color); - --rgb-state-climate-heat-color: var(--rgb-deep-orange-color); - --rgb-state-climate-heat-cool-color: var(--rgb-amber-color); - --rgb-state-climate-idle-color: var(--rgb-grey-color); - --rgb-state-cover-color: var(--rgb-purple-color); - --rgb-state-fan-color: var(--rgb-cyan-color); - --rgb-state-group-color: var(--rgb-amber-color); - --rgb-state-humidifier-color: var(--rgb-blue-color); - --rgb-state-input-boolean-color: var(--rgb-amber-color); - --rgb-state-light-color: var(--rgb-amber-color); - --rgb-state-lock-jammed-color: var(--rgb-red-color); - --rgb-state-lock-locked-color: var(--rgb-green-color); - --rgb-state-lock-pending-color: var(--rgb-orange-color); - --rgb-state-lock-unlocked-color: var(--rgb-red-color); - --rgb-state-media-player-color: var(--rgb-light-blue-color); - --rgb-state-person-home-color: var(--rgb-green-color); - --rgb-state-person-not-home-color: var(--rgb-grey-color); - --rgb-state-person-zone-color: var(--rgb-blue-color); - --rgb-state-plant-color: var(--rgb-red-color); - --rgb-state-remote-color: var(--rgb-amber-color); - --rgb-state-schedule-color: var(--rgb-amber-color); - --rgb-state-script-color: var(--rgb-amber-color); - --rgb-state-sensor-battery-high-color: var(--rgb-green-color); - --rgb-state-sensor-battery-low-color: var(--rgb-red-color); - --rgb-state-sensor-battery-medium-color: var(--rgb-orange-color); - --rgb-state-siren-color: var(--rgb-red-color); - --rgb-state-sun-day-color: var(--rgb-amber-color); - --rgb-state-sun-night-color: var(--rgb-deep-purple-color); - --rgb-state-switch-color: var(--rgb-amber-color); - --rgb-state-timer-color: var(--rgb-amber-color); - --rgb-state-update-color: var(--rgb-green-color); - --rgb-state-update-installing-color: var(--rgb-orange-color); - --rgb-state-vacuum-color: var(--rgb-teal-color); + /* state color */ + --state-active-color: var(--amber-color); + --state-inactive-color: var(--grey-color); + --state-unavailable-color: var(--disabled-color); + + /* state domain colors */ + --state-alarm_control_panel-armed_away-color: var(--green-color); + --state-alarm_control_panel-armed_custom_bypass-color: var(--green-color); + --state-alarm_control_panel-armed_home-color: var(--green-color); + --state-alarm_control_panel-armed_night-color: var(--green-color); + --state-alarm_control_panel-armed_vacation-color: var(--green-color); + --state-alarm_control_panel-arming-color: var(--orange-color); + --state-alarm_control_panel-disarming-color: var(--orange-color); + --state-alarm_control_panel-pending-color: var(--orange-color); + --state-alarm_control_panel-triggered-color: var(--red-color); + --state-alert-off-color: var(--orange-color); + --state-alert-on-color: var(--red-color); + --state-binary_sensor-battery-on-color: var(--red-color); + --state-binary_sensor-carbon_monoxide-on-color: var(--red-color); + --state-binary_sensor-color: var(--amber-color); + --state-binary_sensor-gas-on-color: var(--red-color); + --state-binary_sensor-heat-on-color: var(--red-color); + --state-binary_sensor-lock-on-color: var(--red-color); + --state-binary_sensor-moisture-on-color: var(--red-color); + --state-binary_sensor-problem-on-color: var(--red-color); + --state-binary_sensor-safety-on-color: var(--red-color); + --state-binary_sensor-smoke-on-color: var(--red-color); + --state-binary_sensor-sound-on-color: var(--red-color); + --state-binary_sensor-tamper-on-color: var(--red-color); + --state-climate-auto-color: var(--green-color); + --state-climate-cool-color: var(--blue-color); + --state-climate-dry-color: var(--orange-color); + --state-climate-fan_only-color: var(--cyan-color); + --state-climate-heat-color: var(--deep-orange-color); + --state-climate-heat-cool-color: var(--amber-color); + --state-cover-active-color: var(--purple-color); + --state-device_tracker-active-color: var(--blue-color); + --state-device_tracker-home-color: var(--green-color); + --state-fan-active-color: var(--cyan-color); + --state-humidifier-active-color: var(--blue-color); + --state-light-active-color: var(--amber-color); + --state-lock-jammed-color: var(--red-color); + --state-lock-locked-color: var(--green-color); + --state-lock-pending-color: var(--orange-color); + --state-lock-unlocked-color: var(--red-color); + --state-media_player-active-color: var(--light-blue-color); + --state-person-active-color: var(--blue-color); + --state-person-home-color: var(--green-color); + --state-plant-active-color: var(--red-color); + --state-siren-active-color: var(--red-color); + --state-sun-above_horizon-color: var(--amber-color); + --state-sun-below_horizon-color: var(--indigo-color); + --state-switch-active-color: var(--amber-color); + --state-update-active-color: var(--orange-color); + --state-vacuum-active-color: var(--teal-color); + --state-sensor-battery-high-color: var(--green-color); + --state-sensor-battery-low-color: var(--red-color); + --state-sensor-battery-medium-color: var(--orange-color); + + /* history colors */ + --history-unavailable-color: transparent; + --history-unknown-color: var(--dark-grey-color); /* input components */ --input-idle-line-color: rgba(0, 0, 0, 0.42); diff --git a/src/resources/styles.ts b/src/resources/styles.ts index 3f18eb7445..852cb41943 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -48,7 +48,7 @@ export const darkStyles = { "energy-grid-return-color": "#a280db", "map-filter": "invert(.9) hue-rotate(170deg) brightness(1.5) contrast(1.2) saturate(.3)", - "rgb-disabled-color": "70, 70, 70", + "disabled-color": "#464646", }; export const derivedStyles = { diff --git a/src/translations/en.json b/src/translations/en.json index 319dff5b71..6b6201928e 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4344,7 +4344,9 @@ "orange": "Orange", "deep-orange": "Deep orange", "brown": "Brown", + "light-grey": "Light grey", "grey": "Grey", + "dark-grey": "Dark grey", "blue-grey": "Blue grey", "black": "Black", "white": "White" diff --git a/test/common/entity/state_color.ts b/test/common/entity/state_color.ts new file mode 100644 index 0000000000..e69de29bb2