Entity state colors theming (#14831)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Paul Bottein 2023-01-23 09:28:38 +01:00 committed by GitHub
parent 1b922e0065
commit d15d339782
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 312 additions and 463 deletions

View File

@ -115,8 +115,8 @@ export class DemoHaBarSwitch extends LitElement {
font-weight: 600; font-weight: 600;
} }
.custom { .custom {
--switch-bar-on-color: rgb(var(--rgb-green-color)); --switch-bar-on-color: var(--green-color);
--switch-bar-off-color: rgb(var(--rgb-red-color)); --switch-bar-off-color: var(--red-color);
--switch-bar-thickness: 100px; --switch-bar-thickness: 100px;
--switch-bar-border-radius: 24px; --switch-bar-border-radius: 24px;
--switch-bar-padding: 6px; --switch-bar-padding: 6px;

View File

@ -104,16 +104,17 @@ const ENTITIES: HassEntity[] = [
createEntity("alarm_control_panel.disarming", "disarming"), createEntity("alarm_control_panel.disarming", "disarming"),
createEntity("alarm_control_panel.triggered", "triggered"), createEntity("alarm_control_panel.triggered", "triggered"),
// Alert // Alert
createEntity("alert.idle", "idle"),
createEntity("alert.off", "off"), createEntity("alert.off", "off"),
createEntity("alert.on", "on"), createEntity("alert.on", "on"),
createEntity("alert.idle", "idle"),
// Automation // Automation
createEntity("automation.off", "off"), createEntity("automation.off", "off"),
createEntity("automation.on", "on"), createEntity("automation.on", "on"),
// Binary Sensor // Binary Sensor
...BINARY_SENSOR_DEVICE_CLASSES.map((dc) => ...BINARY_SENSOR_DEVICE_CLASSES.map((dc) => [
createEntity(`binary_sensor.${dc}`, "on", dc) createEntity(`binary_sensor.${dc}`, "off", dc),
), createEntity(`binary_sensor.${dc}`, "on", dc),
]).reduce((arr, item) => [...arr, ...item], []),
// Button // Button
createEntity("button.restart", "unknown", "restart"), createEntity("button.restart", "unknown", "restart"),
createEntity("button.update", "unknown", "update"), createEntity("button.update", "unknown", "update"),
@ -142,6 +143,9 @@ const ENTITIES: HassEntity[] = [
createEntity("climate.auto_dry", "auto", undefined, { createEntity("climate.auto_dry", "auto", undefined, {
hvac_action: "drying", hvac_action: "drying",
}), }),
createEntity("climate.auto_fan", "auto", undefined, {
hvac_action: "fan",
}),
// Cover // Cover
createEntity("cover.closing", "closing"), createEntity("cover.closing", "closing"),
createEntity("cover.closed", "closed"), createEntity("cover.closed", "closed"),
@ -180,8 +184,8 @@ const ENTITIES: HassEntity[] = [
createEntity("light.off", "off"), createEntity("light.off", "off"),
createEntity("light.on", "on"), createEntity("light.on", "on"),
// Locks // Locks
createEntity("lock.unlocked", "unlocked"),
createEntity("lock.locked", "locked"), createEntity("lock.locked", "locked"),
createEntity("lock.unlocked", "unlocked"),
createEntity("lock.locking", "locking"), createEntity("lock.locking", "locking"),
createEntity("lock.unlocking", "unlocking"), createEntity("lock.unlocking", "unlocking"),
createEntity("lock.jammed", "jammed"), createEntity("lock.jammed", "jammed"),
@ -205,16 +209,23 @@ const ENTITIES: HassEntity[] = [
createEntity("media_player.speaker_playing", "playing", "speaker"), createEntity("media_player.speaker_playing", "playing", "speaker"),
createEntity("media_player.speaker_paused", "paused", "speaker"), createEntity("media_player.speaker_paused", "paused", "speaker"),
createEntity("media_player.speaker_standby", "standby", "speaker"), createEntity("media_player.speaker_standby", "standby", "speaker"),
// Plant
createEntity("plant.ok", "ok"),
createEntity("plant.problem", "problem"),
// Remote // Remote
createEntity("remote.off", "off"), createEntity("remote.off", "off"),
createEntity("remote.on", "on"), createEntity("remote.on", "on"),
// Schedule
createEntity("schedule.off", "off"),
createEntity("schedule.on", "on"),
// Script // Script
createEntity("script.off", "off"), createEntity("script.off", "off"),
createEntity("script.on", "on"), createEntity("script.on", "on"),
// Sensor // Sensor
...SENSOR_DEVICE_CLASSES.map((dc) => createEntity(`sensor.${dc}`, "10", dc)), ...SENSOR_DEVICE_CLASSES.map((dc) => createEntity(`sensor.${dc}`, "10", dc)),
// Battery sensor // Battery sensor
...[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) => ...[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, "unknown", "not_valid"].map(
(value) =>
createEntity(`sensor.battery_${value}`, value.toString(), "battery") createEntity(`sensor.battery_${value}`, value.toString(), "battery")
), ),
// Siren // Siren

View File

@ -19,7 +19,9 @@ export const THEME_COLORS = new Set([
"orange", "orange",
"deep-orange", "deep-orange",
"brown", "brown",
"light-grey",
"grey", "grey",
"dark-grey",
"blue-grey", "blue-grey",
"black", "black",
"white", "white",
@ -27,7 +29,7 @@ export const THEME_COLORS = new Set([
export function computeCssColor(color: string): string { export function computeCssColor(color: string): string {
if (THEME_COLORS.has(color)) { if (THEME_COLORS.has(color)) {
return `rgb(var(--rgb-${color}-color))`; return `var(--${color}-color)`;
} }
return color; return color;
} }

View File

@ -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;
}
};

View File

@ -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;
}
};

View File

@ -1,13 +1,15 @@
export const batteryStateColor = (state: string) => { export const batteryStateColorProperty = (
state: string
): string | undefined => {
const value = Number(state); const value = Number(state);
if (isNaN(value)) { if (isNaN(value)) {
return undefined; return undefined;
} }
if (value >= 70) { if (value >= 70) {
return "sensor-battery-high"; return "--state-sensor-battery-high-color";
} }
if (value >= 30) { if (value >= 30) {
return "sensor-battery-medium"; return "--state-sensor-battery-medium-color";
} }
return "sensor-battery-low"; return "--state-sensor-battery-low-color";
}; };

View File

@ -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";
};

View File

@ -1,29 +0,0 @@
import { HvacAction } from "../../../data/climate";
export const CLIMATE_HVAC_ACTION_COLORS: Record<HvacAction, string> = {
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;
}
};

View File

@ -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;
}
};

View File

@ -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";
}
};

View File

@ -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;
};

View File

@ -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";
};

View File

@ -1,96 +1,102 @@
/** Return an color representing a state. */ /** Return an color representing a state. */
import { HassEntity } from "home-assistant-js-websocket"; import { HassEntity } from "home-assistant-js-websocket";
import { UNAVAILABLE } from "../../data/entity"; import { UNAVAILABLE } from "../../data/entity";
import { alarmControlPanelColor } from "./color/alarm_control_panel_color"; import { computeCssVariable } from "../../resources/css-variables";
import { alertColor } from "./color/alert_color"; import { slugify } from "../string/slugify";
import { binarySensorColor } from "./color/binary_sensor_color"; import { batteryStateColorProperty } from "./color/battery_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 { computeDomain } from "./compute_domain"; import { computeDomain } from "./compute_domain";
import { stateActive } from "./state_active"; import { stateActive } from "./state_active";
const STATIC_ACTIVE_COLORED_DOMAIN = new Set([ const STATE_COLORED_DOMAIN = new Set([
"alarm_control_panel",
"alert",
"automation", "automation",
"binary_sensor",
"calendar", "calendar",
"camera", "camera",
"climate",
"cover", "cover",
"device_tracker",
"fan", "fan",
"group", "group",
"humidifier", "humidifier",
"input_boolean", "input_boolean",
"light", "light",
"lock",
"media_player", "media_player",
"person",
"plant", "plant",
"remote", "remote",
"schedule", "schedule",
"script", "script",
"siren", "siren",
"sun",
"switch", "switch",
"timer", "timer",
"update",
"vacuum", "vacuum",
]); ]);
export const stateColorCss = (stateObj: HassEntity, state?: string) => { export const stateColorCss = (stateObj: HassEntity, state?: string) => {
const compareState = state !== undefined ? state : stateObj?.state; const compareState = state !== undefined ? state : stateObj?.state;
if (compareState === UNAVAILABLE) { if (compareState === UNAVAILABLE) {
return `var(--rgb-state-unavailable-color)`; return `var(--state-unavailable-color)`;
} }
const domainColor = stateColor(stateObj, state); const properties = stateColorProperties(stateObj, state);
if (properties) {
if (domainColor) { return computeCssVariable(properties);
return `var(--rgb-state-${domainColor}-color)`;
}
if (!stateActive(stateObj, state)) {
return `var(--rgb-state-inactive-color)`;
} }
return undefined; 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 compareState = state !== undefined ? state : stateObj?.state;
const domain = computeDomain(stateObj.entity_id); const domain = computeDomain(stateObj.entity_id);
const dc = stateObj.attributes.device_class;
if ( // Special rules for battery coloring
STATIC_ACTIVE_COLORED_DOMAIN.has(domain) && if (domain === "sensor" && dc === "battery") {
stateActive(stateObj, state) const property = batteryStateColorProperty(compareState);
) { if (property) {
return domain.replace("_", "-"); return [property];
}
} }
switch (domain) { if (STATE_COLORED_DOMAIN.has(domain)) {
case "alarm_control_panel": return domainStateColorProperties(stateObj, state);
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);
} }
return undefined; return undefined;

View File

@ -22,6 +22,6 @@ export const iconColorCSS = css`
/* Color the icon if unavailable */ /* Color the icon if unavailable */
ha-state-icon[data-state="unavailable"] { ha-state-icon[data-state="unavailable"] {
color: rgb(var(--rgb-state-unavailable-color)); color: var(--state-unavailable-color);
} }
`; `;

View File

@ -1,11 +1,11 @@
import { HassEntity } from "home-assistant-js-websocket"; import { HassEntity } from "home-assistant-js-websocket";
import { getGraphColorByIndex } from "../../../common/color/colors"; 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 { labBrighten } from "../../../common/color/lab";
import { computeDomain } from "../../../common/entity/compute_domain"; import { computeDomain } from "../../../common/entity/compute_domain";
import { stateActive } from "../../../common/entity/state_active"; import { stateColorProperties } from "../../../common/entity/state_color";
import { stateColor } from "../../../common/entity/state_color"; import { UNAVAILABLE, UNKNOWN } from "../../../data/entity";
import { UNAVAILABLE } from "../../../data/entity"; import { computeCssValue } from "../../../resources/css-variables";
const DOMAIN_STATE_SHADES: Record<string, Record<string, number>> = { const DOMAIN_STATE_SHADES: Record<string, Record<string, number>> = {
media_player: { media_player: {
@ -17,61 +17,35 @@ const DOMAIN_STATE_SHADES: Record<string, Record<string, number>> = {
}, },
}; };
const cssColorMap: Map<string, [number, number, number]> = 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( function computeTimelineStateColor(
state: string, state: string,
computedStyles: CSSStyleDeclaration, computedStyles: CSSStyleDeclaration,
stateObj?: HassEntity stateObj?: HassEntity
): string | undefined { ): string | undefined {
if (!stateObj || state === UNAVAILABLE) { if (!stateObj || state === UNAVAILABLE) {
return "transparent"; return computeCssValue("--history-unavailable-color", computedStyles);
} }
const color = stateColor(stateObj, state); if (state === UNKNOWN) {
return computeCssValue("--history-unknown-color", computedStyles);
if (!color && !stateActive(stateObj, state)) {
const rgb = cssToRgb("--rgb-state-inactive-color", computedStyles);
if (!rgb) return undefined;
return rgb2hex(rgb);
} }
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; if (!rgb) return undefined;
const domain = computeDomain(stateObj.entity_id); const domain = computeDomain(stateObj.entity_id);
const shade = DOMAIN_STATE_SHADES[domain]?.[state] as number | number; const shade = DOMAIN_STATE_SHADES[domain]?.[state] as number | number;
if (!shade) { if (!shade) {
return rgb2hex(rgb); return rgb;
} }
return lab2hex(labBrighten(rgb2lab(rgb), shade)); return lab2hex(labBrighten(rgb2lab(hex2rgb(rgb)), shade));
} }
let colorIndex = 0; let colorIndex = 0;

View File

@ -11,13 +11,13 @@ import {
import { property, state } from "lit/decorators"; import { property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined"; import { ifDefined } from "lit/directives/if-defined";
import { styleMap } from "lit/directives/style-map"; 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 { computeDomain } from "../../common/entity/compute_domain";
import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { stateActive } from "../../common/entity/state_active"; import { stateActive } from "../../common/entity/state_active";
import { stateColorCss } from "../../common/entity/state_color"; import { stateColorCss } from "../../common/entity/state_color";
import { iconColorCSS } from "../../common/style/icon_color_css"; import { iconColorCSS } from "../../common/style/icon_color_css";
import { cameraUrlWithWidthHeight } from "../../data/camera"; import { cameraUrlWithWidthHeight } from "../../data/camera";
import { HVAC_ACTION_TO_MODE } from "../../data/climate";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
import "../ha-state-icon"; import "../ha-state-icon";
@ -115,7 +115,7 @@ export class StateBadge extends LitElement {
} else if (this._stateColor && stateActive(stateObj)) { } else if (this._stateColor && stateActive(stateObj)) {
const color = stateColorCss(stateObj); const color = stateColorCss(stateObj);
if (color) { if (color) {
iconStyle.color = `rgb(${color})`; iconStyle.color = color;
} }
if (stateObj.attributes.rgb_color) { if (stateObj.attributes.rgb_color) {
iconStyle.color = `rgb(${stateObj.attributes.rgb_color.join(",")})`; iconStyle.color = `rgb(${stateObj.attributes.rgb_color.join(",")})`;
@ -134,8 +134,11 @@ export class StateBadge extends LitElement {
} }
if (stateObj.attributes.hvac_action) { if (stateObj.attributes.hvac_action) {
const hvacAction = stateObj.attributes.hvac_action; const hvacAction = stateObj.attributes.hvac_action;
if (["heating", "cooling", "drying"].includes(hvacAction)) { if (["heating", "cooling", "drying", "fan"].includes(hvacAction)) {
iconStyle.color = `rgb(${CLIMATE_HVAC_ACTION_COLORS[hvacAction]})`; iconStyle.color = stateColorCss(
stateObj,
HVAC_ACTION_TO_MODE[hvacAction]
)!;
} else { } else {
delete iconStyle.color; delete iconStyle.color;
} }

View File

@ -271,8 +271,8 @@ export class HaBarSlider extends LitElement {
return css` return css`
:host { :host {
display: block; display: block;
--slider-bar-color: rgb(var(--rgb-primary-color)); --slider-bar-color: var(--primary-color);
--slider-bar-background: rgb(var(--rgb-disabled-color)); --slider-bar-background: var(--disabled-color);
--slider-bar-background-opacity: 0.2; --slider-bar-background-opacity: 0.2;
--slider-bar-thickness: 40px; --slider-bar-thickness: 40px;
--slider-bar-border-radius: 10px; --slider-bar-border-radius: 10px;
@ -401,7 +401,7 @@ export class HaBarSlider extends LitElement {
.slider .slider-track-cursor:after { .slider .slider-track-cursor:after {
display: block; display: block;
content: ""; content: "";
background-color: rgb(var(--rgb-secondary-text-color)); background-color: var(--secondary-text-color);
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;

View File

@ -92,8 +92,8 @@ export class HaBarSwitch extends LitElement {
return css` return css`
:host { :host {
display: block; display: block;
--switch-bar-on-color: rgb(var(--rgb-primary-color)); --switch-bar-on-color: var(--primary-color);
--switch-bar-off-color: rgb(var(--rgb-disabled-color)); --switch-bar-off-color: var(--disabled-color);
--switch-bar-background-opacity: 0.2; --switch-bar-background-opacity: 0.2;
--switch-bar-thickness: 40px; --switch-bar-thickness: 40px;
--switch-bar-border-radius: 12px; --switch-bar-border-radius: 12px;

View File

@ -21,8 +21,8 @@ export class HaTileBadge extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
:host { :host {
--tile-badge-background-color: rgb(var(--rgb-primary-color)); --tile-badge-background-color: var(--primary-color);
--tile-badge-icon-color: rgb(var(--rgb-white-color)); --tile-badge-icon-color: var(--white-color);
--mdc-icon-size: 12px; --mdc-icon-size: 12px;
} }
.badge { .badge {

View File

@ -82,9 +82,8 @@ export class HaTileButton extends LitElement {
return css` return css`
:host { :host {
--tile-button-icon-color: var(--primary-text-color); --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; --tile-button-background-opacity: 0.2;
--mdc-ripple-color: var(--tile-button-background-color);
width: 40px; width: 40px;
height: 40px; height: 40px;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
@ -107,6 +106,7 @@ export class HaTileButton extends LitElement {
outline: none; outline: none;
overflow: hidden; overflow: hidden;
background: none; background: none;
--mdc-ripple-color: var(--tile-button-background-color);
} }
.button::before { .button::before {
content: ""; content: "";
@ -128,7 +128,7 @@ export class HaTileButton extends LitElement {
} }
.button:disabled { .button:disabled {
cursor: not-allowed; 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-icon-color: var(--disabled-text-color);
--tile-button-background-opacity: 0.2; --tile-button-background-opacity: 0.2;
} }

View File

@ -22,7 +22,7 @@ export class HaTileIcon extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
:host { :host {
--tile-icon-color: rgb(var(--rgb-disabled-color)); --tile-icon-color: var(--disabled-color);
--mdc-icon-size: 24px; --mdc-icon-size: 24px;
} }
.shape::before { .shape::before {

View File

@ -47,13 +47,10 @@ export class HaTileSlider extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
ha-bar-slider { ha-bar-slider {
--slider-bar-color: var( --slider-bar-color: var(--tile-slider-color, var(--primary-color));
--tile-slider-color,
rgb(var(--rgb-primary-color))
);
--slider-bar-background: var( --slider-bar-background: var(
--tile-slider-background, --tile-slider-background,
rgb(var(--rgb-disabled-color)) var(--disabled-color)
); );
--slider-bar-background-opacity: var( --slider-bar-background-opacity: var(
--tile-slider-background-opacity, --tile-slider-background-opacity,

View File

@ -72,3 +72,12 @@ const hvacModeOrdering: { [key in HvacMode]: number } = {
export const compareClimateHvacModes = (mode1: HvacMode, mode2: HvacMode) => export const compareClimateHvacModes = (mode1: HvacMode, mode2: HvacMode) =>
hvacModeOrdering[mode1] - hvacModeOrdering[mode2]; hvacModeOrdering[mode1] - hvacModeOrdering[mode2];
export const HVAC_ACTION_TO_MODE: Record<HvacAction, HvacMode> = {
cooling: "cool",
drying: "dry",
fan: "fan_only",
heating: "heat",
idle: "off",
off: "off",
};

View File

@ -577,7 +577,7 @@ class HaLogbookRenderer extends LitElement {
} }
.indicator { .indicator {
background-color: rgb(var(--rgb-disabled-color)); background-color: var(--disabled-color);
height: 8px; height: 8px;
width: 8px; width: 8px;
border-radius: 4px; border-radius: 4px;

View File

@ -8,13 +8,15 @@ import {
} from "lit"; } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { alarmPanelIcon } from "../../../common/entity/alarm_panel_icon"; import { alarmPanelIcon } from "../../../common/entity/alarm_panel_icon";
import { stateColorCss } from "../../../common/entity/state_color";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-chip"; import "../../../components/ha-chip";
import type { HaTextField } from "../../../components/ha-textfield";
import "../../../components/ha-textfield"; import "../../../components/ha-textfield";
import type { HaTextField } from "../../../components/ha-textfield";
import { import {
callAlarmAction, callAlarmAction,
FORMAT_NUMBER, FORMAT_NUMBER,
@ -155,6 +157,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
stateLabel} stateLabel}
<ha-chip <ha-chip
hasIcon hasIcon
style=${styleMap({
"--alarm-state-color": stateColorCss(stateObj),
})}
class=${classMap({ [stateObj.state]: true })} class=${classMap({ [stateObj.state]: true })}
@click=${this._handleMoreInfo} @click=${this._handleMoreInfo}
> >
@ -269,7 +274,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
--alarm-state-color: rgb(var(--rgb-state-alarm-armed-color)); --alarm-state-color: var(--state-inactive-color);
} }
ha-chip { ha-chip {
@ -286,26 +291,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
box-sizing: border-box; box-sizing: border-box;
} }
.unavailable { .triggered,
--alarm-state-color: rgb(var(--rgb-state-unavailable-color)); .arming,
}
.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;
}
.pending { .pending {
--alarm-state-color: rgb(var(--rgb-state-alarm-pending-color));
animation: pulse 1s infinite; animation: pulse 1s infinite;
} }

View File

@ -563,7 +563,7 @@ export class HuiAreaCard
--mdc-icon-button-size: 44px; --mdc-icon-button-size: 44px;
} }
.on { .on {
color: rgb(var(--rgb-state-light-color)); color: var(--state-light-color);
} }
`; `;
} }

View File

@ -21,7 +21,6 @@ import { ifDefined } from "lit/directives/if-defined";
import { styleMap } from "lit/directives/style-map"; import { styleMap } from "lit/directives/style-map";
import { DOMAINS_TOGGLE } from "../../../common/const"; import { DOMAINS_TOGGLE } from "../../../common/const";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; 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 { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateDomain } from "../../../common/entity/compute_state_domain"; 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 { isValidEntityId } from "../../../common/entity/valid_entity_id";
import { iconColorCSS } from "../../../common/style/icon_color_css"; import { iconColorCSS } from "../../../common/style/icon_color_css";
import "../../../components/ha-card"; import "../../../components/ha-card";
import { HVAC_ACTION_TO_MODE } from "../../../data/climate";
import { LightEntity } from "../../../data/light"; import { LightEntity } from "../../../data/light";
import { ActionHandlerEvent } from "../../../data/lovelace"; import { ActionHandlerEvent } from "../../../data/lovelace";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
@ -324,14 +324,14 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
} }
if (stateObj.attributes.hvac_action) { if (stateObj.attributes.hvac_action) {
const hvacAction = stateObj.attributes.hvac_action; const hvacAction = stateObj.attributes.hvac_action;
if (["heating", "cooling", "drying"].includes(hvacAction)) { if (["heating", "cooling", "drying", "fan"].includes(hvacAction)) {
return `rgb(${CLIMATE_HVAC_ACTION_COLORS[hvacAction]})`; return stateColorCss(stateObj, HVAC_ACTION_TO_MODE[hvacAction]);
} }
return undefined; return undefined;
} }
const iconColor = stateColorCss(stateObj); const iconColor = stateColorCss(stateObj);
if (iconColor) { if (iconColor) {
return `rgb(${iconColor})`; return iconColor;
} }
return undefined; return undefined;
} }

View File

@ -12,7 +12,6 @@ import { ifDefined } from "lit/directives/if-defined";
import { styleMap } from "lit/directives/style-map"; import { styleMap } from "lit/directives/style-map";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { fireEvent } from "../../../common/dom/fire_event"; 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 { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
@ -27,6 +26,7 @@ import {
import { iconColorCSS } from "../../../common/style/icon_color_css"; import { iconColorCSS } from "../../../common/style/icon_color_css";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-icon"; import "../../../components/ha-icon";
import { HVAC_ACTION_TO_MODE } from "../../../data/climate";
import { isUnavailableState } from "../../../data/entity"; import { isUnavailableState } from "../../../data/entity";
import { formatAttributeValue } from "../../../data/entity_attributes"; import { formatAttributeValue } from "../../../data/entity_attributes";
import { LightEntity } from "../../../data/light"; import { LightEntity } from "../../../data/light";
@ -197,8 +197,8 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
private _computeColor(stateObj: HassEntity): string | undefined { private _computeColor(stateObj: HassEntity): string | undefined {
if (stateObj.attributes.hvac_action) { if (stateObj.attributes.hvac_action) {
const hvacAction = stateObj.attributes.hvac_action; const hvacAction = stateObj.attributes.hvac_action;
if (["heating", "cooling", "drying"].includes(hvacAction)) { if (["heating", "cooling", "drying", "fan"].includes(hvacAction)) {
return `rgb(${CLIMATE_HVAC_ACTION_COLORS[hvacAction]})`; return stateColorCss(stateObj, HVAC_ACTION_TO_MODE[hvacAction]);
} }
return undefined; return undefined;
} }
@ -207,7 +207,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
} }
const iconColor = stateColorCss(stateObj); const iconColor = stateColorCss(stateObj);
if (iconColor) { if (iconColor) {
return `rgb(${iconColor})`; return iconColor;
} }
return undefined; return undefined;
} }

View File

@ -330,7 +330,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
} }
.light-button.state-on { .light-button.state-on {
color: rgb(var(--rgb-state-light-color)); color: var(--state-light-color);
} }
.light-button.state-unavailable { .light-button.state-unavailable {

View File

@ -21,12 +21,14 @@ import {
} from "lit"; } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { UNIT_F } from "../../../common/const"; import { UNIT_F } from "../../../common/const";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateColorCss } from "../../../common/entity/state_color";
import { formatNumber } from "../../../common/number/format_number"; import { formatNumber } from "../../../common/number/format_number";
import "../../../components/ha-card"; import "../../../components/ha-card";
import type { HaCard } from "../../../components/ha-card"; import type { HaCard } from "../../../components/ha-card";
@ -249,8 +251,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
return html` return html`
<ha-card <ha-card
class=${classMap({ style=${styleMap({
[mode]: true, "--mode-color": stateColorCss(stateObj),
})} })}
> >
<ha-icon-button <ha-icon-button
@ -470,37 +472,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
--name-font-size: 1.2rem; --name-font-size: 1.2rem;
--brightness-font-size: 1.2rem; --brightness-font-size: 1.2rem;
--rail-border-color: transparent; --rail-border-color: transparent;
} --mode-color: var(--state-inactive-color);
.auto,
.heat_cool {
--mode-color: var(--state-climate-auto-color);
}
.cool {
--mode-color: var(--state-climate-cool-color);
}
.heat {
--mode-color: var(--state-climate-heat-color);
}
.manual {
--mode-color: var(--state-climate-manual-color);
}
.off {
--mode-color: var(--state-climate-off-color);
}
.fan_only {
--mode-color: var(--state-climate-fan_only-color);
}
.eco {
--mode-color: var(--state-climate-eco-color);
}
.dry {
--mode-color: var(--state-climate-dry-color);
}
.idle {
--mode-color: var(--state-climate-idle-color);
}
.unknown-mode {
--mode-color: var(--state-unknown-color);
} }
.more-info { .more-info {

View File

@ -11,9 +11,10 @@ import {
queryAsync, queryAsync,
state, state,
} from "lit/decorators"; } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map"; import { styleMap } from "lit/directives/style-map";
import { computeCssColor } from "../../../common/color/compute-color"; import { computeCssColor } from "../../../common/color/compute-color";
import { hsv2rgb, rgb2hsv } from "../../../common/color/convert-color"; import { hsv2rgb, rgb2hex, rgb2hsv } from "../../../common/color/convert-color";
import { DOMAINS_TOGGLE } from "../../../common/const"; import { DOMAINS_TOGGLE } from "../../../common/const";
import { computeDomain } from "../../../common/entity/compute_domain"; import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDisplay } from "../../../common/entity/compute_state_display";
@ -148,7 +149,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
computeDomain(entity.entity_id) === "person" || computeDomain(entity.entity_id) === "person" ||
computeDomain(entity.entity_id) === "device_tracker" computeDomain(entity.entity_id) === "device_tracker"
) { ) {
return "rgb(var(--rgb-state-default-color))"; return undefined;
} }
// Use light color if the light support rgb // Use light color if the light support rgb
@ -167,13 +168,11 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
hsvColor[1] = 0.4; hsvColor[1] = 0.4;
} }
} }
return `rgb(${hsv2rgb(hsvColor).join(",")})`; return rgb2hex(hsv2rgb(hsvColor));
} }
// Fallback to state color // Fallback to state color
const stateColor = return stateColorCss(entity);
stateColorCss(entity) ?? "var(--rgb-state-default-color)";
return `rgb(${stateColor})`;
}); });
private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string { private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string {
@ -271,7 +270,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
class="badge" class="badge"
.iconPath=${mdiExclamationThick} .iconPath=${mdiExclamationThick}
style=${styleMap({ style=${styleMap({
"--tile-badge-background-color": `rgb(var(--rgb-red-color))`, "--tile-badge-background-color": `var(--red-color)`,
})} })}
></ha-tile-badge> ></ha-tile-badge>
</div> </div>
@ -292,6 +291,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
const stateDisplay = this._computeStateDisplay(stateObj); const stateDisplay = this._computeStateDisplay(stateObj);
const active = stateActive(stateObj);
const color = this._computeStateColor(stateObj, this._config.color); const color = this._computeStateColor(stateObj, this._config.color);
const style = { const style = {
@ -308,7 +308,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
); );
return html` return html`
<ha-card style=${styleMap(style)}> <ha-card style=${styleMap(style)} class=${classMap({ active })}>
${this._shouldRenderRipple ? html`<mwc-ripple></mwc-ripple>` : null} ${this._shouldRenderRipple ? html`<mwc-ripple></mwc-ripple>` : null}
<div class="tile"> <div class="tile">
<div <div
@ -339,7 +339,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
.icon=${badge.icon} .icon=${badge.icon}
.iconPath=${badge.iconPath} .iconPath=${badge.iconPath}
style=${styleMap({ style=${styleMap({
"--tile-badge-background-color": `rgb(${badge.color})`, "--tile-badge-background-color": badge.color,
})} })}
></ha-tile-badge> ></ha-tile-badge>
` `
@ -407,7 +407,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
:host { :host {
--tile-color: rgb(var(--rgb-state-inactive-color)); --tile-color: var(--state-inactive-color);
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
ha-card:has(ha-tile-info:focus-visible) { ha-card:has(ha-tile-info:focus-visible) {
@ -421,8 +421,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
// For safari overflow hidden // For safari overflow hidden
z-index: 0; z-index: 0;
} }
ha-card.disabled { ha-card.active {
--tile-color: rgb(var(--rgb-disabled-color)); --tile-color: var(--state-icon-color);
} }
[role="button"] { [role="button"] {
cursor: pointer; cursor: pointer;

View File

@ -6,8 +6,12 @@ import {
mdiSnowflake, mdiSnowflake,
mdiWaterPercent, mdiWaterPercent,
} from "@mdi/js"; } from "@mdi/js";
import { CLIMATE_HVAC_ACTION_COLORS } from "../../../../../common/entity/color/climate_color"; import { stateColorCss } from "../../../../../common/entity/state_color";
import { ClimateEntity, HvacAction } from "../../../../../data/climate"; import {
ClimateEntity,
HvacAction,
HvacMode,
} from "../../../../../data/climate";
import { ComputeBadgeFunction } from "./tile-badge"; import { ComputeBadgeFunction } from "./tile-badge";
export const CLIMATE_HVAC_ACTION_ICONS: Record<HvacAction, string> = { export const CLIMATE_HVAC_ACTION_ICONS: Record<HvacAction, string> = {
@ -19,6 +23,15 @@ export const CLIMATE_HVAC_ACTION_ICONS: Record<HvacAction, string> = {
off: mdiPower, off: mdiPower,
}; };
export const CLIMATE_HVAC_ACTION_MODE: Record<HvacAction, HvacMode> = {
cooling: "cool",
drying: "dry",
fan: "fan_only",
heating: "heat",
idle: "off",
off: "off",
};
export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => { export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => {
const hvacAction = (stateObj as ClimateEntity).attributes.hvac_action; const hvacAction = (stateObj as ClimateEntity).attributes.hvac_action;
@ -28,6 +41,6 @@ export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => {
return { return {
iconPath: CLIMATE_HVAC_ACTION_ICONS[hvacAction], iconPath: CLIMATE_HVAC_ACTION_ICONS[hvacAction],
color: CLIMATE_HVAC_ACTION_COLORS[hvacAction], color: stateColorCss(stateObj, CLIMATE_HVAC_ACTION_MODE[hvacAction]),
}; };
}; };

View File

@ -1,5 +1,6 @@
import { mdiHome, mdiHomeExportOutline } from "@mdi/js"; import { mdiHome, mdiHomeExportOutline } from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket"; import { HassEntity } from "home-assistant-js-websocket";
import { stateColorCss } from "../../../../../common/entity/state_color";
import { HomeAssistant } from "../../../../../types"; import { HomeAssistant } from "../../../../../types";
import { ComputeBadgeFunction } from "./tile-badge"; import { ComputeBadgeFunction } from "./tile-badge";
@ -19,23 +20,12 @@ function personBadgeIcon(entity: HassEntity) {
return state === "not_home" ? mdiHomeExportOutline : mdiHome; 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) => { export const computePersonBadge: ComputeBadgeFunction = (stateObj, hass) => {
const zone = getZone(stateObj, hass); const zone = getZone(stateObj, hass);
return { return {
iconPath: personBadgeIcon(stateObj), iconPath: personBadgeIcon(stateObj),
icon: zone?.attributes.icon, icon: zone?.attributes.icon,
color: personBadgeColor(stateObj), color: stateColorCss(stateObj),
}; };
}; };

View File

@ -7,7 +7,7 @@ import { computeClimateBadge } from "./tile-badge-climate";
import { computePersonBadge } from "./tile-badge-person"; import { computePersonBadge } from "./tile-badge-person";
export type TileBadge = { export type TileBadge = {
color: string; color?: string;
icon?: string; icon?: string;
iconPath?: string; iconPath?: string;
}; };
@ -23,7 +23,7 @@ export const computeTileBadge: ComputeBadgeFunction = (stateObj, hass) => {
} }
if (stateObj.state === UNAVAILABLE) { if (stateObj.state === UNAVAILABLE) {
return { return {
color: "var(--rgb-orange-color)", color: "var(--orange-color)",
iconPath: mdiExclamationThick, iconPath: mdiExclamationThick,
}; };
} }

View File

@ -0,0 +1,31 @@
export function computeCssVariable(
props: string | string[]
): string | undefined {
if (Array.isArray(props)) {
return props
.reverse()
.reduce<string | undefined>(
(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;
}

View File

@ -57,30 +57,11 @@ documentContainer.innerHTML = `<custom-style>
--label-badge-yellow: #f4b400; --label-badge-yellow: #f4b400;
--label-badge-grey: #9e9e9e; --label-badge-grey: #9e9e9e;
/* states */ /* states icon */
--state-icon-color: #44739e; --state-icon-color: #44739e;
/* an error state is anything that would be considered an error */ /* an error state is anything that would be considered an error */
/* --state-icon-error-color: #db4437; derived from error-color */ /* --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 */
--energy-grid-consumption-color: #488fc2; --energy-grid-consumption-color: #488fc2;
--energy-grid-return-color: #8353d1; --energy-grid-return-color: #8353d1;
@ -106,87 +87,99 @@ documentContainer.innerHTML = `<custom-style>
/* rgb */ /* rgb */
--rgb-primary-color: 3, 169, 244; --rgb-primary-color: 3, 169, 244;
--rgb-accent-color: 255, 152, 0; --rgb-accent-color: 255, 152, 0;
--rgb-disabled-color: 189, 189, 189;
--rgb-primary-text-color: 33, 33, 33; --rgb-primary-text-color: 33, 33, 33;
--rgb-secondary-text-color: 114, 114, 114; --rgb-secondary-text-color: 114, 114, 114;
--rgb-text-primary-color: 255, 255, 255; --rgb-text-primary-color: 255, 255, 255;
--rgb-card-background-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 */ /* color */
--rgb-state-default-color: var(--rgb-dark-primary-color, 68, 115, 158); --disabled-color: #bdbdbd;
--rgb-state-inactive-color: var(--rgb-grey-color); --red-color: #f44336;
--rgb-state-unavailable-color: var(--rgb-disabled-color); --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 */ /* state color */
--rgb-state-alarm-armed-color: var(--rgb-green-color); --state-active-color: var(--amber-color);
--rgb-state-alarm-arming-color: var(--rgb-orange-color); --state-inactive-color: var(--grey-color);
--rgb-state-alarm-disarmed-color: var(--rgb-grey-color); --state-unavailable-color: var(--disabled-color);
--rgb-state-alarm-pending-color: var(--rgb-orange-color);
--rgb-state-alarm-triggered-color: var(--rgb-red-color); /* state domain colors */
--rgb-state-alert-color: var(--rgb-red-color); --state-alarm_control_panel-armed_away-color: var(--green-color);
--rgb-state-alert-off-color: var(--rgb-orange-color); --state-alarm_control_panel-armed_custom_bypass-color: var(--green-color);
--rgb-state-automation-color: var(--rgb-amber-color); --state-alarm_control_panel-armed_home-color: var(--green-color);
--rgb-state-binary-sensor-alerting-color: var(--rgb-red-color); --state-alarm_control_panel-armed_night-color: var(--green-color);
--rgb-state-binary-sensor-color: var(--rgb-amber-color); --state-alarm_control_panel-armed_vacation-color: var(--green-color);
--rgb-state-calendar-color: var(--rgb-amber-color); --state-alarm_control_panel-arming-color: var(--orange-color);
--rgb-state-camera-color: var(--rgb-amber-color); --state-alarm_control_panel-disarming-color: var(--orange-color);
--rgb-state-climate-auto-color: var(--rgb-green-color); --state-alarm_control_panel-pending-color: var(--orange-color);
--rgb-state-climate-cool-color: var(--rgb-blue-color); --state-alarm_control_panel-triggered-color: var(--red-color);
--rgb-state-climate-dry-color: var(--rgb-orange-color); --state-alert-off-color: var(--orange-color);
--rgb-state-climate-fan-only-color: var(--rgb-cyan-color); --state-alert-on-color: var(--red-color);
--rgb-state-climate-heat-color: var(--rgb-deep-orange-color); --state-binary_sensor-battery-on-color: var(--red-color);
--rgb-state-climate-heat-cool-color: var(--rgb-amber-color); --state-binary_sensor-carbon_monoxide-on-color: var(--red-color);
--rgb-state-climate-idle-color: var(--rgb-grey-color); --state-binary_sensor-color: var(--amber-color);
--rgb-state-cover-color: var(--rgb-purple-color); --state-binary_sensor-gas-on-color: var(--red-color);
--rgb-state-fan-color: var(--rgb-cyan-color); --state-binary_sensor-heat-on-color: var(--red-color);
--rgb-state-group-color: var(--rgb-amber-color); --state-binary_sensor-lock-on-color: var(--red-color);
--rgb-state-humidifier-color: var(--rgb-blue-color); --state-binary_sensor-moisture-on-color: var(--red-color);
--rgb-state-input-boolean-color: var(--rgb-amber-color); --state-binary_sensor-problem-on-color: var(--red-color);
--rgb-state-light-color: var(--rgb-amber-color); --state-binary_sensor-safety-on-color: var(--red-color);
--rgb-state-lock-jammed-color: var(--rgb-red-color); --state-binary_sensor-smoke-on-color: var(--red-color);
--rgb-state-lock-locked-color: var(--rgb-green-color); --state-binary_sensor-sound-on-color: var(--red-color);
--rgb-state-lock-pending-color: var(--rgb-orange-color); --state-binary_sensor-tamper-on-color: var(--red-color);
--rgb-state-lock-unlocked-color: var(--rgb-red-color); --state-climate-auto-color: var(--green-color);
--rgb-state-media-player-color: var(--rgb-light-blue-color); --state-climate-cool-color: var(--blue-color);
--rgb-state-person-home-color: var(--rgb-green-color); --state-climate-dry-color: var(--orange-color);
--rgb-state-person-not-home-color: var(--rgb-grey-color); --state-climate-fan_only-color: var(--cyan-color);
--rgb-state-person-zone-color: var(--rgb-blue-color); --state-climate-heat-color: var(--deep-orange-color);
--rgb-state-plant-color: var(--rgb-red-color); --state-climate-heat-cool-color: var(--amber-color);
--rgb-state-remote-color: var(--rgb-amber-color); --state-cover-active-color: var(--purple-color);
--rgb-state-schedule-color: var(--rgb-amber-color); --state-device_tracker-active-color: var(--blue-color);
--rgb-state-script-color: var(--rgb-amber-color); --state-device_tracker-home-color: var(--green-color);
--rgb-state-sensor-battery-high-color: var(--rgb-green-color); --state-fan-active-color: var(--cyan-color);
--rgb-state-sensor-battery-low-color: var(--rgb-red-color); --state-humidifier-active-color: var(--blue-color);
--rgb-state-sensor-battery-medium-color: var(--rgb-orange-color); --state-light-active-color: var(--amber-color);
--rgb-state-siren-color: var(--rgb-red-color); --state-lock-jammed-color: var(--red-color);
--rgb-state-sun-day-color: var(--rgb-amber-color); --state-lock-locked-color: var(--green-color);
--rgb-state-sun-night-color: var(--rgb-deep-purple-color); --state-lock-pending-color: var(--orange-color);
--rgb-state-switch-color: var(--rgb-amber-color); --state-lock-unlocked-color: var(--red-color);
--rgb-state-timer-color: var(--rgb-amber-color); --state-media_player-active-color: var(--light-blue-color);
--rgb-state-update-color: var(--rgb-green-color); --state-person-active-color: var(--blue-color);
--rgb-state-update-installing-color: var(--rgb-orange-color); --state-person-home-color: var(--green-color);
--rgb-state-vacuum-color: var(--rgb-teal-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 components */
--input-idle-line-color: rgba(0, 0, 0, 0.42); --input-idle-line-color: rgba(0, 0, 0, 0.42);

View File

@ -48,7 +48,7 @@ export const darkStyles = {
"energy-grid-return-color": "#a280db", "energy-grid-return-color": "#a280db",
"map-filter": "map-filter":
"invert(.9) hue-rotate(170deg) brightness(1.5) contrast(1.2) saturate(.3)", "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 = { export const derivedStyles = {

View File

@ -4344,7 +4344,9 @@
"orange": "Orange", "orange": "Orange",
"deep-orange": "Deep orange", "deep-orange": "Deep orange",
"brown": "Brown", "brown": "Brown",
"light-grey": "Light grey",
"grey": "Grey", "grey": "Grey",
"dark-grey": "Dark grey",
"blue-grey": "Blue grey", "blue-grey": "Blue grey",
"black": "Black", "black": "Black",
"white": "White" "white": "White"

View File