1
0
mirror of https://github.com/home-assistant/frontend.git synced 2025-12-24 20:55:49 +00:00
Files
frontend/src/components/entity/state-badge.ts
Paulus Schoutsen 1b9286db76 Fix lit warnings (#9204)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2021-05-18 15:01:43 -07:00

174 lines
5.0 KiB
TypeScript

import type { HassEntity } from "home-assistant-js-websocket";
import {
css,
CSSResultGroup,
html,
LitElement,
PropertyValues,
TemplateResult,
} from "lit";
import { property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { styleMap } from "lit/directives/style-map";
import { computeActiveState } from "../../common/entity/compute_active_state";
import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { stateIcon } from "../../common/entity/state_icon";
import { iconColorCSS } from "../../common/style/icon_color_css";
import type { HomeAssistant } from "../../types";
import "../ha-icon";
export class StateBadge extends LitElement {
public hass?: HomeAssistant;
@property() public stateObj?: HassEntity;
@property() public overrideIcon?: string;
@property() public overrideImage?: string;
@property({ type: Boolean }) public stateColor?: boolean;
@property({ type: Boolean, reflect: true, attribute: "icon" })
private _showIcon = true;
@state() private _iconStyle: { [name: string]: string } = {};
protected render(): TemplateResult {
const stateObj = this.stateObj;
// We either need a `stateObj` or one override
if (!stateObj && !this.overrideIcon && !this.overrideImage) {
return html`<div class="missing">
<ha-icon icon="hass:alert"></ha-icon>
</div>`;
}
if (!this._showIcon) {
return html``;
}
const domain = stateObj ? computeStateDomain(stateObj) : undefined;
return html`
<ha-icon
style=${styleMap(this._iconStyle)}
data-domain=${ifDefined(
this.stateColor || (domain === "light" && this.stateColor !== false)
? domain
: undefined
)}
data-state=${stateObj ? computeActiveState(stateObj) : ""}
.icon=${this.overrideIcon || (stateObj ? stateIcon(stateObj) : "")}
></ha-icon>
`;
}
public willUpdate(changedProps: PropertyValues) {
super.willUpdate(changedProps);
if (
!changedProps.has("stateObj") &&
!changedProps.has("overrideImage") &&
!changedProps.has("overrideIcon")
) {
return;
}
const stateObj = this.stateObj;
const iconStyle: { [name: string]: string } = {};
const hostStyle: Partial<CSSStyleDeclaration> = {
backgroundImage: "",
};
this._showIcon = true;
if (stateObj) {
// hide icon if we have entity picture
if (
((stateObj.attributes.entity_picture_local ||
stateObj.attributes.entity_picture) &&
!this.overrideIcon) ||
this.overrideImage
) {
let imageUrl =
this.overrideImage ||
stateObj.attributes.entity_picture_local ||
stateObj.attributes.entity_picture;
if (this.hass) {
imageUrl = this.hass.hassUrl(imageUrl);
}
hostStyle.backgroundImage = `url(${imageUrl})`;
this._showIcon = false;
} else if (stateObj.state === "on") {
if (this.stateColor !== false && stateObj.attributes.rgb_color) {
iconStyle.color = `rgb(${stateObj.attributes.rgb_color.join(",")})`;
}
if (stateObj.attributes.brightness && this.stateColor !== false) {
const brightness = stateObj.attributes.brightness;
if (typeof brightness !== "number") {
const errorMessage = `Type error: state-badge expected number, but type of ${
stateObj.entity_id
}.attributes.brightness is ${typeof brightness} (${brightness})`;
// eslint-disable-next-line
console.warn(errorMessage);
}
// lowest brightness will be around 50% (that's pretty dark)
iconStyle.filter = `brightness(${(brightness + 245) / 5}%)`;
}
}
} else if (this.overrideImage) {
let imageUrl = this.overrideImage;
if (this.hass) {
imageUrl = this.hass.hassUrl(imageUrl);
}
hostStyle.backgroundImage = `url(${imageUrl})`;
this._showIcon = false;
}
this._iconStyle = iconStyle;
Object.assign(this.style, hostStyle);
}
static get styles(): CSSResultGroup {
return css`
:host {
position: relative;
display: inline-block;
width: 40px;
color: var(--paper-item-icon-color, #44739e);
border-radius: 50%;
height: 40px;
text-align: center;
background-size: cover;
line-height: 40px;
vertical-align: middle;
box-sizing: border-box;
}
:host(:focus) {
outline: none;
}
:host(:not([icon]):focus) {
border: 2px solid var(--divider-color);
}
:host([icon]:focus) {
background: var(--divider-color);
}
ha-icon {
transition: color 0.3s ease-in-out, filter 0.3s ease-in-out;
}
.missing {
color: #fce588;
}
${iconColorCSS}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"state-badge": StateBadge;
}
}
customElements.define("state-badge", StateBadge);