fix: Keep default background color for color_type: card when off

Fix #737
This commit is contained in:
Jérôme Wiedemann 2023-07-30 20:33:04 +00:00
parent f7371077b5
commit 41dea3f72a
4 changed files with 71 additions and 31 deletions

View File

@ -19,6 +19,7 @@ import {
CustomFieldCard, CustomFieldCard,
ButtonCardEmbeddedCards, ButtonCardEmbeddedCards,
ButtonCardEmbeddedCardsConfig, ButtonCardEmbeddedCardsConfig,
ColorType,
} from './types/types'; } from './types/types';
import { actionHandler } from './action-handler'; import { actionHandler } from './action-handler';
import { import {
@ -37,6 +38,7 @@ import {
durationToSeconds, durationToSeconds,
computeStateDomain, computeStateDomain,
stateActive, stateActive,
computeCssVariable,
} from './helpers'; } from './helpers';
import { createThing } from './common/create-thing'; import { createThing } from './common/create-thing';
import { styles } from './styles'; import { styles } from './styles';
@ -45,7 +47,13 @@ import copy from 'fast-copy';
import * as pjson from '../package.json'; import * as pjson from '../package.json';
import { deepEqual } from './deep-equal'; import { deepEqual } from './deep-equal';
import { stateColorCss } from './common/state_color'; import { stateColorCss } from './common/state_color';
import { AUTO_COLORS, DOMAINS_TOGGLE } from './common/const'; import {
AUTO_COLORS,
DEFAULT_COLOR,
DOMAINS_TOGGLE,
OVERRIDE_CARD_BACKGROUND_COLOR_COLORS,
OVERRIDE_CARD_BACKGROUND_COLOR_COLOR_TYPE,
} from './common/const';
import { handleAction } from './handle-action'; import { handleAction } from './handle-action';
import { fireEvent } from './common/fire-event'; import { fireEvent } from './common/fire-event';
import { HomeAssistant } from './types/homeassistant'; import { HomeAssistant } from './types/homeassistant';
@ -468,40 +476,43 @@ class ButtonCard extends LitElement {
} }
} }
private _getColorForLightEntity(state: HassEntity | undefined, useTemperature: boolean): string { private _getColorForLightEntity(
let color: string = this._config!.default_color; state: HassEntity | undefined,
useTemperature: boolean,
cardColorType?: ColorType,
): string {
let color: string = DEFAULT_COLOR;
if (OVERRIDE_CARD_BACKGROUND_COLOR_COLOR_TYPE.includes(color)) {
color = computeCssVariable(OVERRIDE_CARD_BACKGROUND_COLOR_COLORS)!;
}
if (state) { if (state) {
// we have en entity
if (stateActive(state)) { if (stateActive(state)) {
// entity is on
if (state.attributes.rgb_color) { if (state.attributes.rgb_color) {
// entity has RGB attributes
color = `rgb(${state.attributes.rgb_color.join(',')})`; color = `rgb(${state.attributes.rgb_color.join(',')})`;
if (state.attributes.brightness) {
color = applyBrightnessToColor(this, color, (state.attributes.brightness + 245) / 5);
}
} else if ( } else if (
useTemperature && useTemperature &&
state.attributes.color_temp && state.attributes.color_temp &&
state.attributes.min_mireds && state.attributes.min_mireds &&
state.attributes.max_mireds state.attributes.max_mireds
) { ) {
// entity has color temperature and we want it
color = getLightColorBasedOnTemperature( color = getLightColorBasedOnTemperature(
state.attributes.color_temp, state.attributes.color_temp,
state.attributes.min_mireds, state.attributes.min_mireds,
state.attributes.max_mireds, state.attributes.max_mireds,
); );
if (state.attributes.brightness) {
color = applyBrightnessToColor(this, color, (state.attributes.brightness + 245) / 5);
}
} else if (state.attributes.brightness) {
color = applyBrightnessToColor(
this,
stateColorCss(state, state.state) || this._config!.default_color,
(state.attributes.brightness + 245) / 5,
);
} else { } else {
color = stateColorCss(state, state.state) || this._config!.default_color; // all the other lights
color = stateColorCss(state, state.state, cardColorType) || DEFAULT_COLOR;
}
if (state.attributes.brightness) {
color = applyBrightnessToColor(this, color, (state.attributes.brightness + 245) / 5);
} }
} else { } else {
color = stateColorCss(state, state.state) || this._config!.default_color; color = stateColorCss(state, state.state, cardColorType) || DEFAULT_COLOR;
} }
} }
return color; return color;
@ -516,13 +527,21 @@ class ButtonCard extends LitElement {
colorValue = this._config!.color; colorValue = this._config!.color;
} }
if (AUTO_COLORS.includes(colorValue)) { if (AUTO_COLORS.includes(colorValue)) {
color = this._getColorForLightEntity(state, colorValue !== 'auto-no-temperature'); if (!state || (state && !(computeDomain(state.entity_id) !== 'light'))) {
colorValue = '';
}
}
if (AUTO_COLORS.includes(colorValue)) {
// I'm a light
color = this._getColorForLightEntity(state, colorValue !== 'auto-no-temperature', this._config?.color_type);
} else if (colorValue) { } else if (colorValue) {
// Color is forced but not auto
color = colorValue; color = colorValue;
} else if (state) { } else if (state) {
color = stateColorCss(state, state.state) || this._config!.default_color; // based on state
color = stateColorCss(state, state.state, this._config?.color_type) || DEFAULT_COLOR;
} else { } else {
color = this._config!.default_color; color = DEFAULT_COLOR;
} }
return color; return color;
} }
@ -1157,7 +1176,6 @@ class ButtonCard extends LitElement {
show_live_stream: false, show_live_stream: false,
card_size: 3, card_size: 3,
...template, ...template,
default_color: 'DUMMY',
lock: { lock: {
enabled: false, enabled: false,
duration: 5, duration: 5,
@ -1181,7 +1199,6 @@ class ButtonCard extends LitElement {
...this._config, ...this._config,
}; };
} }
this._config!.default_color = 'var(--primary-text-color)';
const jsonConfig = JSON.stringify(this._config); const jsonConfig = JSON.stringify(this._config);
this._entities = []; this._entities = [];

View File

@ -19,3 +19,8 @@ export const isOffState = arrayLiteralIncludes(OFF_STATES);
export const DOMAINS_TOGGLE = new Set(['fan', 'input_boolean', 'light', 'switch', 'group', 'automation', 'humidifier']); export const DOMAINS_TOGGLE = new Set(['fan', 'input_boolean', 'light', 'switch', 'group', 'automation', 'humidifier']);
export const AUTO_COLORS = ['auto', 'auto-no-temperature']; export const AUTO_COLORS = ['auto', 'auto-no-temperature'];
export const OVERRIDE_CARD_BACKGROUND_COLOR_COLOR_TYPE = ['card', 'label-card'];
export const OVERRIDE_CARD_BACKGROUND_COLOR_COLORS = ['--ha-card-background', '--card-background-color'];
export const DEFAULT_COLOR = 'var(--primary-text-color)';

View File

@ -1,11 +1,12 @@
/** 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 './const'; import { OVERRIDE_CARD_BACKGROUND_COLOR_COLOR_TYPE, OVERRIDE_CARD_BACKGROUND_COLOR_COLORS, UNAVAILABLE } from './const';
import { computeGroupDomain, GroupEntity } from '../helpers'; import { computeGroupDomain, GroupEntity } from '../helpers';
import { computeCssVariable } from '../helpers'; import { computeCssVariable } from '../helpers';
import { computeDomain, slugify } from '../helpers'; import { computeDomain, slugify } from '../helpers';
import { batteryStateColorProperty } from '../helpers'; import { batteryStateColorProperty } from '../helpers';
import { stateActive } from '../helpers'; import { stateActive } from '../helpers';
import { ColorType } from '../types/types';
const STATE_COLORED_DOMAIN = new Set([ const STATE_COLORED_DOMAIN = new Set([
'alarm_control_panel', 'alarm_control_panel',
@ -37,13 +38,13 @@ const STATE_COLORED_DOMAIN = new Set([
'vacuum', 'vacuum',
]); ]);
export const stateColorCss = (stateObj: HassEntity, state?: string): undefined | string => { export const stateColorCss = (stateObj: HassEntity, state?: string, cardColorType?: ColorType): undefined | string => {
const compareState = state !== undefined ? state : stateObj?.state; const compareState = state !== undefined ? state : stateObj?.state;
if (compareState === UNAVAILABLE) { if (compareState === UNAVAILABLE) {
return `var(--state-unavailable-color)`; return `var(--state-unavailable-color)`;
} }
const properties = stateColorProperties(stateObj, state); const properties = stateColorProperties(stateObj, state, cardColorType);
if (properties) { if (properties) {
return computeCssVariable(properties); return computeCssVariable(properties);
} }
@ -51,7 +52,12 @@ export const stateColorCss = (stateObj: HassEntity, state?: string): undefined |
return undefined; return undefined;
}; };
export const domainStateColorProperties = (domain: string, stateObj: HassEntity, state?: string): string[] => { export const domainStateColorProperties = (
domain: string,
stateObj: HassEntity,
state?: string,
cardColorType?: ColorType,
): string[] => {
const compareState = state !== undefined ? state : stateObj.state; const compareState = state !== undefined ? state : stateObj.state;
const active = stateActive(stateObj, state); const active = stateActive(stateObj, state);
@ -60,6 +66,10 @@ export const domainStateColorProperties = (domain: string, stateObj: HassEntity,
const stateKey = slugify(compareState, '_'); const stateKey = slugify(compareState, '_');
const activeKey = active ? 'active' : 'inactive'; const activeKey = active ? 'active' : 'inactive';
if (cardColorType && OVERRIDE_CARD_BACKGROUND_COLOR_COLOR_TYPE.includes(cardColorType) && activeKey == 'inactive') {
return OVERRIDE_CARD_BACKGROUND_COLOR_COLORS;
}
const dc = stateObj.attributes.device_class; const dc = stateObj.attributes.device_class;
if (dc) { if (dc) {
@ -75,7 +85,11 @@ export const domainStateColorProperties = (domain: string, stateObj: HassEntity,
return properties; return properties;
}; };
export const stateColorProperties = (stateObj: HassEntity, state?: string): string[] | undefined => { export const stateColorProperties = (
stateObj: HassEntity,
state?: string,
cardColorType?: ColorType,
): 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; const dc = stateObj.attributes.device_class;
@ -92,14 +106,17 @@ export const stateColorProperties = (stateObj: HassEntity, state?: string): stri
if (domain === 'group') { if (domain === 'group') {
const groupDomain = computeGroupDomain(stateObj as GroupEntity); const groupDomain = computeGroupDomain(stateObj as GroupEntity);
if (groupDomain && STATE_COLORED_DOMAIN.has(groupDomain)) { if (groupDomain && STATE_COLORED_DOMAIN.has(groupDomain)) {
return domainStateColorProperties(groupDomain, stateObj, state); return domainStateColorProperties(groupDomain, stateObj, state, cardColorType);
} }
} }
if (STATE_COLORED_DOMAIN.has(domain)) { if (STATE_COLORED_DOMAIN.has(domain)) {
return domainStateColorProperties(domain, stateObj, state); return domainStateColorProperties(domain, stateObj, state, cardColorType);
} }
if (cardColorType && OVERRIDE_CARD_BACKGROUND_COLOR_COLOR_TYPE.includes(cardColorType)) {
return OVERRIDE_CARD_BACKGROUND_COLOR_COLORS;
}
return undefined; return undefined;
}; };

View File

@ -10,7 +10,7 @@ export interface ButtonCardConfig {
entity?: string; entity?: string;
name?: string; name?: string;
icon?: string; icon?: string;
color_type: 'icon' | 'card' | 'label-card' | 'blank-card'; color_type: ColorType;
color?: 'auto' | 'auto-no-temperature' | string; color?: 'auto' | 'auto-no-temperature' | string;
size: string; size: string;
aspect_ratio?: string; aspect_ratio?: string;
@ -36,7 +36,6 @@ export interface ButtonCardConfig {
confirmation?: string; confirmation?: string;
layout: Layout; layout: Layout;
entity_picture_style?: CssStyleConfig[]; entity_picture_style?: CssStyleConfig[];
default_color: string;
custom_fields?: CustomFields; custom_fields?: CustomFields;
variables?: Variables; variables?: Variables;
extra_styles?: string; extra_styles?: string;
@ -93,6 +92,8 @@ export type Layout =
| 'icon_state_name2nd' | 'icon_state_name2nd'
| 'icon_label'; | 'icon_label';
export type ColorType = 'icon' | 'card' | 'label-card' | 'blank-card';
export interface LockConfig { export interface LockConfig {
enabled: boolean; enabled: boolean;
duration: number; duration: number;