Entity state colors theming (#14831)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
1b922e0065
commit
d15d339782
|
@ -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;
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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";
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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";
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -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<string, Record<string, number>> = {
|
||||
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(
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<HvacAction, HvacMode> = {
|
||||
cooling: "cool",
|
||||
drying: "dry",
|
||||
fan: "fan_only",
|
||||
heating: "heat",
|
||||
idle: "off",
|
||||
off: "off",
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
<ha-chip
|
||||
hasIcon
|
||||
style=${styleMap({
|
||||
"--alarm-state-color": stateColorCss(stateObj),
|
||||
})}
|
||||
class=${classMap({ [stateObj.state]: true })}
|
||||
@click=${this._handleMoreInfo}
|
||||
>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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`
|
||||
<ha-card
|
||||
class=${classMap({
|
||||
[mode]: true,
|
||||
style=${styleMap({
|
||||
"--mode-color": stateColorCss(stateObj),
|
||||
})}
|
||||
>
|
||||
<ha-icon-button
|
||||
|
@ -470,37 +472,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
|||
--name-font-size: 1.2rem;
|
||||
--brightness-font-size: 1.2rem;
|
||||
--rail-border-color: transparent;
|
||||
}
|
||||
.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);
|
||||
--mode-color: var(--state-inactive-color);
|
||||
}
|
||||
|
||||
.more-info {
|
||||
|
|
|
@ -11,9 +11,10 @@ import {
|
|||
queryAsync,
|
||||
state,
|
||||
} from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
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 { computeDomain } from "../../../common/entity/compute_domain";
|
||||
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) === "device_tracker"
|
||||
) {
|
||||
return "rgb(var(--rgb-state-default-color))";
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Use light color if the light support rgb
|
||||
|
@ -167,13 +168,11 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||
hsvColor[1] = 0.4;
|
||||
}
|
||||
}
|
||||
return `rgb(${hsv2rgb(hsvColor).join(",")})`;
|
||||
return rgb2hex(hsv2rgb(hsvColor));
|
||||
}
|
||||
|
||||
// Fallback to state color
|
||||
const stateColor =
|
||||
stateColorCss(entity) ?? "var(--rgb-state-default-color)";
|
||||
return `rgb(${stateColor})`;
|
||||
return stateColorCss(entity);
|
||||
});
|
||||
|
||||
private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string {
|
||||
|
@ -271,7 +270,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||
class="badge"
|
||||
.iconPath=${mdiExclamationThick}
|
||||
style=${styleMap({
|
||||
"--tile-badge-background-color": `rgb(var(--rgb-red-color))`,
|
||||
"--tile-badge-background-color": `var(--red-color)`,
|
||||
})}
|
||||
></ha-tile-badge>
|
||||
</div>
|
||||
|
@ -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`
|
||||
<ha-card style=${styleMap(style)}>
|
||||
<ha-card style=${styleMap(style)} class=${classMap({ active })}>
|
||||
${this._shouldRenderRipple ? html`<mwc-ripple></mwc-ripple>` : null}
|
||||
<div class="tile">
|
||||
<div
|
||||
|
@ -339,7 +339,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||
.icon=${badge.icon}
|
||||
.iconPath=${badge.iconPath}
|
||||
style=${styleMap({
|
||||
"--tile-badge-background-color": `rgb(${badge.color})`,
|
||||
"--tile-badge-background-color": badge.color,
|
||||
})}
|
||||
></ha-tile-badge>
|
||||
`
|
||||
|
@ -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;
|
||||
|
|
|
@ -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<HvacAction, string> = {
|
||||
|
@ -19,6 +23,15 @@ export const CLIMATE_HVAC_ACTION_ICONS: Record<HvacAction, string> = {
|
|||
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) => {
|
||||
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]),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -57,30 +57,11 @@ documentContainer.innerHTML = `<custom-style>
|
|||
--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 = `<custom-style>
|
|||
/* 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);
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue