mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add stateValue parameter to ha-state-icon (#19508)
* Add state value option to entityIcon * Migrate lock, valve and cover more info to icon translations * Migrate tile card * Remove domain icon from area card * Use attribute
This commit is contained in:
parent
f6af73b222
commit
1c9ea0a9d9
@ -14,6 +14,8 @@ export class HaStateIcon extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public stateObj?: HassEntity;
|
@property({ attribute: false }) public stateObj?: HassEntity;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public stateValue?: string;
|
||||||
|
|
||||||
@property() public icon?: string;
|
@property() public icon?: string;
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
@ -30,12 +32,14 @@ export class HaStateIcon extends LitElement {
|
|||||||
if (!this.hass) {
|
if (!this.hass) {
|
||||||
return this._renderFallback();
|
return this._renderFallback();
|
||||||
}
|
}
|
||||||
const icon = entityIcon(this.hass, this.stateObj).then((icn) => {
|
const icon = entityIcon(this.hass, this.stateObj, this.stateValue).then(
|
||||||
if (icn) {
|
(icn) => {
|
||||||
return html`<ha-icon .icon=${icn}></ha-icon>`;
|
if (icn) {
|
||||||
|
return html`<ha-icon .icon=${icn}></ha-icon>`;
|
||||||
|
}
|
||||||
|
return this._renderFallback();
|
||||||
}
|
}
|
||||||
return this._renderFallback();
|
);
|
||||||
});
|
|
||||||
return html`${until(icon)}`;
|
return html`${until(icon)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement } from "lit/decorators";
|
||||||
import "../ha-icon";
|
import "../ha-icon";
|
||||||
|
|
||||||
@customElement("ha-tile-badge")
|
@customElement("ha-tile-badge")
|
||||||
export class HaTileBadge extends LitElement {
|
export class HaTileBadge extends LitElement {
|
||||||
@property() public iconPath?: string;
|
|
||||||
|
|
||||||
@property() public icon?: string;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<div class="badge">
|
<div class="badge">
|
||||||
${this.icon
|
<slot></slot>
|
||||||
? html`<ha-icon .icon=${this.icon}></ha-icon>`
|
|
||||||
: html`<ha-svg-icon .path=${this.iconPath}></ha-svg-icon>`}
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -36,8 +30,7 @@ export class HaTileBadge extends LitElement {
|
|||||||
background-color: var(--tile-badge-background-color);
|
background-color: var(--tile-badge-background-color);
|
||||||
transition: background-color 280ms ease-in-out;
|
transition: background-color 280ms ease-in-out;
|
||||||
}
|
}
|
||||||
.badge ha-icon,
|
.badge ::slotted(*) {
|
||||||
.badge ha-svg-icon {
|
|
||||||
color: var(--tile-badge-icon-color);
|
color: var(--tile-badge-icon-color);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
import { CSSResultGroup, html, css, LitElement, TemplateResult } from "lit";
|
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement } from "lit/decorators";
|
||||||
import "../ha-icon";
|
import "../ha-icon";
|
||||||
import "../ha-svg-icon";
|
import "../ha-svg-icon";
|
||||||
|
|
||||||
@customElement("ha-tile-icon")
|
@customElement("ha-tile-icon")
|
||||||
export class HaTileIcon extends LitElement {
|
export class HaTileIcon extends LitElement {
|
||||||
@property() public iconPath?: string;
|
|
||||||
|
|
||||||
@property() public icon?: string;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<div class="shape">
|
<div class="shape">
|
||||||
${this.icon
|
<slot></slot>
|
||||||
? html`<ha-icon .icon=${this.icon}></ha-icon>`
|
|
||||||
: html`<ha-svg-icon .path=${this.iconPath}></ha-svg-icon>`}
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -47,8 +41,7 @@ export class HaTileIcon extends LitElement {
|
|||||||
transition: color 180ms ease-in-out;
|
transition: color 180ms ease-in-out;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.shape ha-icon,
|
.shape ::slotted(*) {
|
||||||
.shape ha-svg-icon {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
color: var(--tile-icon-color);
|
color: var(--tile-icon-color);
|
||||||
transition: color 180ms ease-in-out;
|
transition: color 180ms ease-in-out;
|
||||||
|
@ -71,10 +71,15 @@ export const getComponentIcons = async (
|
|||||||
return resources.entity_component.then((res) => res[domain]);
|
return resources.entity_component.then((res) => res[domain]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const entityIcon = async (hass: HomeAssistant, state: HassEntity) => {
|
export const entityIcon = async (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
state: HassEntity,
|
||||||
|
stateValue?: string
|
||||||
|
) => {
|
||||||
let icon: string | undefined;
|
let icon: string | undefined;
|
||||||
const domain = computeStateDomain(state);
|
const domain = computeStateDomain(state);
|
||||||
const entity = hass.entities?.[state.entity_id];
|
const entity = hass.entities?.[state.entity_id];
|
||||||
|
const value = stateValue ?? state.state;
|
||||||
if (entity?.icon) {
|
if (entity?.icon) {
|
||||||
return entity.icon;
|
return entity.icon;
|
||||||
}
|
}
|
||||||
@ -82,18 +87,19 @@ export const entityIcon = async (hass: HomeAssistant, state: HassEntity) => {
|
|||||||
const platformIcons = await getPlatformIcons(hass, entity.platform);
|
const platformIcons = await getPlatformIcons(hass, entity.platform);
|
||||||
if (platformIcons) {
|
if (platformIcons) {
|
||||||
icon =
|
icon =
|
||||||
platformIcons[domain]?.[entity.translation_key]?.state?.[state.state] ||
|
platformIcons[domain]?.[entity.translation_key]?.state?.[value] ||
|
||||||
platformIcons[domain]?.[entity.translation_key]?.default;
|
platformIcons[domain]?.[entity.translation_key]?.default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
const entityComponentIcons = await getComponentIcons(hass, domain);
|
const entityComponentIcons = await getComponentIcons(hass, domain);
|
||||||
|
|
||||||
if (entityComponentIcons) {
|
if (entityComponentIcons) {
|
||||||
icon =
|
icon =
|
||||||
entityComponentIcons[state.attributes.device_class || "_"]?.state?.[
|
entityComponentIcons[state.attributes.device_class || "_"]?.state?.[
|
||||||
state.state
|
value
|
||||||
] ||
|
] ||
|
||||||
entityComponentIcons._?.state?.[state.state] ||
|
entityComponentIcons._?.state?.[value] ||
|
||||||
entityComponentIcons[state.attributes.device_class || "_"]?.default ||
|
entityComponentIcons[state.attributes.device_class || "_"]?.default ||
|
||||||
entityComponentIcons._?.default;
|
entityComponentIcons._?.default;
|
||||||
}
|
}
|
||||||
@ -110,13 +116,14 @@ export const attributeIcon = async (
|
|||||||
let icon: string | undefined;
|
let icon: string | undefined;
|
||||||
const domain = computeStateDomain(state);
|
const domain = computeStateDomain(state);
|
||||||
const entity = hass.entities?.[state.entity_id];
|
const entity = hass.entities?.[state.entity_id];
|
||||||
|
const value = attributeValue ?? state.attributes[attribute];
|
||||||
if (entity?.translation_key && entity.platform) {
|
if (entity?.translation_key && entity.platform) {
|
||||||
const platformIcons = await getPlatformIcons(hass, entity.platform);
|
const platformIcons = await getPlatformIcons(hass, entity.platform);
|
||||||
if (platformIcons) {
|
if (platformIcons) {
|
||||||
icon =
|
icon =
|
||||||
platformIcons[domain]?.[entity.translation_key]?.state_attributes?.[
|
platformIcons[domain]?.[entity.translation_key]?.state_attributes?.[
|
||||||
attribute
|
attribute
|
||||||
]?.state?.[attributeValue || state.attributes[attribute]];
|
]?.state?.[value];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
@ -124,12 +131,8 @@ export const attributeIcon = async (
|
|||||||
if (entityComponentIcons) {
|
if (entityComponentIcons) {
|
||||||
icon =
|
icon =
|
||||||
entityComponentIcons[state.attributes.device_class || "_"]
|
entityComponentIcons[state.attributes.device_class || "_"]
|
||||||
.state_attributes?.[attribute]?.state?.[
|
.state_attributes?.[attribute]?.state?.[value] ||
|
||||||
attributeValue || state.attributes[attribute]
|
entityComponentIcons._.state_attributes?.[attribute]?.state?.[value];
|
||||||
] ||
|
|
||||||
entityComponentIcons._.state_attributes?.[attribute]?.state?.[
|
|
||||||
attributeValue || state.attributes[attribute]
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return icon;
|
return icon;
|
||||||
|
@ -2,9 +2,9 @@ import { mdiShieldOff } from "@mdi/js";
|
|||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
|
||||||
import { stateColorCss } from "../../../common/entity/state_color";
|
import { stateColorCss } from "../../../common/entity/state_color";
|
||||||
import "../../../components/ha-outlined-button";
|
import "../../../components/ha-outlined-button";
|
||||||
|
import "../../../components/ha-state-icon";
|
||||||
import { AlarmControlPanelEntity } from "../../../data/alarm_control_panel";
|
import { AlarmControlPanelEntity } from "../../../data/alarm_control_panel";
|
||||||
import "../../../state-control/alarm_control_panel/ha-state-control-alarm_control_panel-modes";
|
import "../../../state-control/alarm_control_panel/ha-state-control-alarm_control_panel-modes";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
@ -59,9 +59,8 @@ class MoreInfoAlarmControlPanel extends LitElement {
|
|||||||
<div class="status">
|
<div class="status">
|
||||||
<span></span>
|
<span></span>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<ha-svg-icon
|
<ha-state-icon .hass=${this.hass} .stateObj=${this.stateObj}>
|
||||||
.path=${domainIcon("alarm_control_panel", this.stateObj)}
|
</ha-state-icon>
|
||||||
></ha-svg-icon>
|
|
||||||
</div>
|
</div>
|
||||||
<ha-outlined-button @click=${this._disarm}>
|
<ha-outlined-button @click=${this._disarm}>
|
||||||
${this.hass.localize("ui.card.alarm_control_panel.disarm")}
|
${this.hass.localize("ui.card.alarm_control_panel.disarm")}
|
||||||
|
@ -2,11 +2,11 @@ import { mdiDoorOpen, mdiLock, mdiLockOff } from "@mdi/js";
|
|||||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
|
||||||
import { stateColorCss } from "../../../common/entity/state_color";
|
import { stateColorCss } from "../../../common/entity/state_color";
|
||||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||||
import "../../../components/ha-attributes";
|
import "../../../components/ha-attributes";
|
||||||
import "../../../components/ha-outlined-icon-button";
|
import "../../../components/ha-outlined-icon-button";
|
||||||
|
import "../../../components/ha-state-icon";
|
||||||
import { UNAVAILABLE } from "../../../data/entity";
|
import { UNAVAILABLE } from "../../../data/entity";
|
||||||
import {
|
import {
|
||||||
LockEntity,
|
LockEntity,
|
||||||
@ -62,9 +62,10 @@ class MoreInfoLock extends LitElement {
|
|||||||
<div class="status">
|
<div class="status">
|
||||||
<span></span>
|
<span></span>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
.path=${domainIcon("lock", this.stateObj)}
|
.hass=${this.hass}
|
||||||
></ha-svg-icon>
|
.stateObj=${this.stateObj}
|
||||||
|
></ha-state-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import "@material/mwc-ripple";
|
import "@material/mwc-ripple";
|
||||||
import {
|
import {
|
||||||
|
mdiFan,
|
||||||
|
mdiFanOff,
|
||||||
mdiLightbulbMultiple,
|
mdiLightbulbMultiple,
|
||||||
mdiLightbulbMultipleOff,
|
mdiLightbulbMultipleOff,
|
||||||
mdiRun,
|
mdiRun,
|
||||||
@ -9,30 +11,30 @@ import {
|
|||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import {
|
import {
|
||||||
css,
|
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
html,
|
|
||||||
LitElement,
|
LitElement,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
nothing,
|
nothing,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, 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 { styleMap } from "lit/directives/style-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { STATES_OFF, FIXED_DEVICE_CLASS_ICONS } from "../../../common/const";
|
import { FIXED_DEVICE_CLASS_ICONS, STATES_OFF } from "../../../common/const";
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
|
||||||
import { binarySensorIcon } from "../../../common/entity/binary_sensor_icon";
|
import { binarySensorIcon } from "../../../common/entity/binary_sensor_icon";
|
||||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import {
|
import {
|
||||||
formatNumber,
|
formatNumber,
|
||||||
isNumericState,
|
isNumericState,
|
||||||
} from "../../../common/number/format_number";
|
} from "../../../common/number/format_number";
|
||||||
import { subscribeOne } from "../../../common/util/subscribe-one";
|
import { blankBeforeUnit } from "../../../common/translations/blank_before_unit";
|
||||||
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
|
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
|
||||||
|
import { subscribeOne } from "../../../common/util/subscribe-one";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
@ -56,7 +58,6 @@ import "../components/hui-image";
|
|||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
import { AreaCardConfig } from "./types";
|
import { AreaCardConfig } from "./types";
|
||||||
import { blankBeforeUnit } from "../../../common/translations/blank_before_unit";
|
|
||||||
|
|
||||||
export const DEFAULT_ASPECT_RATIO = "16:9";
|
export const DEFAULT_ASPECT_RATIO = "16:9";
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ export const DEVICE_CLASSES = {
|
|||||||
const DOMAIN_ICONS = {
|
const DOMAIN_ICONS = {
|
||||||
light: { on: mdiLightbulbMultiple, off: mdiLightbulbMultipleOff },
|
light: { on: mdiLightbulbMultiple, off: mdiLightbulbMultipleOff },
|
||||||
switch: { on: mdiToggleSwitch, off: mdiToggleSwitchOff },
|
switch: { on: mdiToggleSwitch, off: mdiToggleSwitchOff },
|
||||||
fan: { on: domainIcon("fan"), off: domainIcon("fan") },
|
fan: { on: mdiFan, off: mdiFanOff },
|
||||||
binary_sensor: {
|
binary_sensor: {
|
||||||
motion: mdiRun,
|
motion: mdiRun,
|
||||||
moisture: mdiWaterAlert,
|
moisture: mdiWaterAlert,
|
||||||
|
@ -28,8 +28,9 @@ import { DOMAINS_TOGGLE } from "../../../common/const";
|
|||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_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 { stateIconPath } from "../../../common/entity/state_icon_path";
|
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
|
import "../../../components/ha-state-icon";
|
||||||
|
import "../../../components/ha-svg-icon";
|
||||||
import "../../../components/tile/ha-tile-badge";
|
import "../../../components/tile/ha-tile-badge";
|
||||||
import "../../../components/tile/ha-tile-icon";
|
import "../../../components/tile/ha-tile-icon";
|
||||||
import "../../../components/tile/ha-tile-image";
|
import "../../../components/tile/ha-tile-image";
|
||||||
@ -48,7 +49,7 @@ import { handleAction } from "../common/handle-action";
|
|||||||
import { hasAction } from "../common/has-action";
|
import { hasAction } from "../common/has-action";
|
||||||
import "../components/hui-timestamp-display";
|
import "../components/hui-timestamp-display";
|
||||||
import type { LovelaceCard, LovelaceCardEditor } from "../types";
|
import type { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
import { computeTileBadge } from "./tile/badges/tile-badge";
|
import { renderTileBadge } from "./tile/badges/tile-badge";
|
||||||
import type { ThermostatCardConfig, TileCardConfig } from "./types";
|
import type { ThermostatCardConfig, TileCardConfig } from "./types";
|
||||||
|
|
||||||
const TIMESTAMP_STATE_DOMAINS = ["button", "input_button", "scene"];
|
const TIMESTAMP_STATE_DOMAINS = ["button", "input_button", "scene"];
|
||||||
@ -341,17 +342,14 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="content ${classMap(contentClasses)}">
|
<div class="content ${classMap(contentClasses)}">
|
||||||
<div class="icon-container">
|
<div class="icon-container">
|
||||||
<ha-tile-icon class="icon" .iconPath=${mdiHelp}></ha-tile-icon>
|
<ha-tile-icon>
|
||||||
<ha-tile-badge
|
<ha-svg-icon .path=${mdiHelp}></ha-svg-icon>
|
||||||
class="badge"
|
</ha-tile-icon>
|
||||||
.iconPath=${mdiExclamationThick}
|
<ha-tile-badge class="not-found">
|
||||||
style=${styleMap({
|
<ha-svg-icon .path=${mdiExclamationThick}></ha-svg-icon>
|
||||||
"--tile-badge-background-color": `var(--red-color)`,
|
</ha-tile-badge>
|
||||||
})}
|
|
||||||
></ha-tile-badge>
|
|
||||||
</div>
|
</div>
|
||||||
<ha-tile-info
|
<ha-tile-info
|
||||||
class="info"
|
|
||||||
.primary=${entityId}
|
.primary=${entityId}
|
||||||
secondary=${this.hass.localize("ui.card.tile.not_found")}
|
secondary=${this.hass.localize("ui.card.tile.not_found")}
|
||||||
></ha-tile-info>
|
></ha-tile-info>
|
||||||
@ -360,9 +358,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const icon = this._config.icon || stateObj.attributes.icon;
|
|
||||||
const iconPath = stateIconPath(stateObj);
|
|
||||||
|
|
||||||
const name = this._config.name || stateObj.attributes.friendly_name;
|
const name = this._config.name || stateObj.attributes.friendly_name;
|
||||||
|
|
||||||
const localizedState = this._config.hide_state
|
const localizedState = this._config.hide_state
|
||||||
@ -382,7 +377,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
const imageUrl = this._config.show_entity_picture
|
const imageUrl = this._config.show_entity_picture
|
||||||
? this._getImageUrl(stateObj)
|
? this._getImageUrl(stateObj)
|
||||||
: undefined;
|
: undefined;
|
||||||
const badge = computeTileBadge(stateObj, this.hass);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card style=${styleMap(style)} class=${classMap({ active })}>
|
<ha-card style=${styleMap(style)} class=${classMap({ active })}>
|
||||||
@ -420,7 +414,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
? html`
|
? html`
|
||||||
<ha-tile-image
|
<ha-tile-image
|
||||||
.imageStyle=${DOMAIN_IMAGE_STYLE[domain] || "circle"}
|
.imageStyle=${DOMAIN_IMAGE_STYLE[domain] || "circle"}
|
||||||
class="icon"
|
|
||||||
.imageUrl=${imageUrl}
|
.imageUrl=${imageUrl}
|
||||||
></ha-tile-image>
|
></ha-tile-image>
|
||||||
`
|
`
|
||||||
@ -428,27 +421,18 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
<ha-tile-icon
|
<ha-tile-icon
|
||||||
data-domain=${ifDefined(domain)}
|
data-domain=${ifDefined(domain)}
|
||||||
data-state=${ifDefined(stateObj?.state)}
|
data-state=${ifDefined(stateObj?.state)}
|
||||||
class="icon"
|
>
|
||||||
.icon=${icon}
|
<ha-state-icon
|
||||||
.iconPath=${iconPath}
|
.icon=${this._config.icon}
|
||||||
></ha-tile-icon>
|
.stateObj=${stateObj}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-state-icon>
|
||||||
|
</ha-tile-icon>
|
||||||
`}
|
`}
|
||||||
${badge
|
${renderTileBadge(stateObj, this.hass)}
|
||||||
? html`
|
|
||||||
<ha-tile-badge
|
|
||||||
class="badge"
|
|
||||||
.icon=${badge.icon}
|
|
||||||
.iconPath=${badge.iconPath}
|
|
||||||
style=${styleMap({
|
|
||||||
"--tile-badge-background-color": badge.color,
|
|
||||||
})}
|
|
||||||
></ha-tile-badge>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
</div>
|
</div>
|
||||||
<ha-tile-info
|
<ha-tile-info
|
||||||
id="info"
|
id="info"
|
||||||
class="info"
|
|
||||||
.primary=${name}
|
.primary=${name}
|
||||||
.secondary=${localizedState}
|
.secondary=${localizedState}
|
||||||
></ha-tile-info>
|
></ha-tile-info>
|
||||||
@ -516,7 +500,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
margin-inline-start: initial;
|
margin-inline-start: initial;
|
||||||
margin-inline-end: initial;
|
margin-inline-end: initial;
|
||||||
}
|
}
|
||||||
.vertical .info {
|
.vertical ha-tile-info {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.icon-container {
|
.icon-container {
|
||||||
@ -528,14 +512,15 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
transition: transform 180ms ease-in-out;
|
transition: transform 180ms ease-in-out;
|
||||||
}
|
}
|
||||||
.icon-container .icon {
|
.icon-container ha-tile-icon,
|
||||||
|
.icon-container ha-tile-image {
|
||||||
--tile-icon-color: var(--tile-color);
|
--tile-icon-color: var(--tile-color);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
}
|
}
|
||||||
.icon-container .badge {
|
.icon-container ha-tile-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -3px;
|
top: -3px;
|
||||||
right: -3px;
|
right: -3px;
|
||||||
@ -544,7 +529,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
.icon-container[role="button"]:active {
|
.icon-container[role="button"]:active {
|
||||||
transform: scale(1.2);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
.info {
|
ha-tile-info {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -564,6 +549,10 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
animation: pulse 1s infinite;
|
animation: pulse 1s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ha-tile-badge.not-found {
|
||||||
|
--tile-badge-background-color: var(--red-color);
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0% {
|
0% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -1,20 +1,36 @@
|
|||||||
|
import { html, nothing } from "lit";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { stateColorCss } from "../../../../../common/entity/state_color";
|
import { stateColorCss } from "../../../../../common/entity/state_color";
|
||||||
|
import "../../../../../components/ha-attribute-icon";
|
||||||
|
import "../../../../../components/tile/ha-tile-badge";
|
||||||
import {
|
import {
|
||||||
CLIMATE_HVAC_ACTION_ICONS,
|
|
||||||
CLIMATE_HVAC_ACTION_TO_MODE,
|
CLIMATE_HVAC_ACTION_TO_MODE,
|
||||||
ClimateEntity,
|
ClimateEntity,
|
||||||
} from "../../../../../data/climate";
|
} from "../../../../../data/climate";
|
||||||
import { ComputeBadgeFunction } from "./tile-badge";
|
import { RenderBadgeFunction } from "./tile-badge";
|
||||||
|
|
||||||
export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => {
|
export const renderClimateBadge: RenderBadgeFunction = (stateObj, hass) => {
|
||||||
const hvacAction = (stateObj as ClimateEntity).attributes.hvac_action;
|
const hvacAction = (stateObj as ClimateEntity).attributes.hvac_action;
|
||||||
|
|
||||||
if (!hvacAction || hvacAction === "off") {
|
if (!hvacAction || hvacAction === "off") {
|
||||||
return undefined;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return html`
|
||||||
iconPath: CLIMATE_HVAC_ACTION_ICONS[hvacAction],
|
<ha-tile-badge
|
||||||
color: stateColorCss(stateObj, CLIMATE_HVAC_ACTION_TO_MODE[hvacAction]),
|
style=${styleMap({
|
||||||
};
|
"--tile-badge-background-color": stateColorCss(
|
||||||
|
stateObj,
|
||||||
|
CLIMATE_HVAC_ACTION_TO_MODE[hvacAction]
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ha-attribute-icon
|
||||||
|
.hass=${hass}
|
||||||
|
.stateObj=${stateObj}
|
||||||
|
attribute="hvac_action"
|
||||||
|
>
|
||||||
|
</ha-attribute-icon>
|
||||||
|
</ha-tile-badge>
|
||||||
|
`;
|
||||||
};
|
};
|
||||||
|
@ -1,20 +1,32 @@
|
|||||||
|
import { html, nothing } from "lit";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { stateColorCss } from "../../../../../common/entity/state_color";
|
import { stateColorCss } from "../../../../../common/entity/state_color";
|
||||||
|
import "../../../../../components/ha-attribute-icon";
|
||||||
|
import "../../../../../components/tile/ha-tile-badge";
|
||||||
import {
|
import {
|
||||||
HUMIDIFIER_ACTION_ICONS,
|
|
||||||
HUMIDIFIER_ACTION_MODE,
|
HUMIDIFIER_ACTION_MODE,
|
||||||
HumidifierEntity,
|
HumidifierEntity,
|
||||||
} from "../../../../../data/humidifier";
|
} from "../../../../../data/humidifier";
|
||||||
import { ComputeBadgeFunction } from "./tile-badge";
|
import { RenderBadgeFunction } from "./tile-badge";
|
||||||
|
|
||||||
export const computeHumidifierBadge: ComputeBadgeFunction = (stateObj) => {
|
export const renderHumidifierBadge: RenderBadgeFunction = (stateObj, hass) => {
|
||||||
const hvacAction = (stateObj as HumidifierEntity).attributes.action;
|
const hvacAction = (stateObj as HumidifierEntity).attributes.action;
|
||||||
|
|
||||||
if (!hvacAction || hvacAction === "off") {
|
if (!hvacAction || hvacAction === "off") {
|
||||||
return undefined;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return html`
|
||||||
iconPath: HUMIDIFIER_ACTION_ICONS[hvacAction],
|
<ha-tile-badge
|
||||||
color: stateColorCss(stateObj, HUMIDIFIER_ACTION_MODE[hvacAction]),
|
style=${styleMap({
|
||||||
};
|
"--tile-badge-background-color": stateColorCss(
|
||||||
|
stateObj,
|
||||||
|
HUMIDIFIER_ACTION_MODE[hvacAction]
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ha-attribute-icon .hass=${hass} .stateObj=${stateObj} attribute="action">
|
||||||
|
</ha-attribute-icon>
|
||||||
|
</ha-tile-badge>
|
||||||
|
`;
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
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 { html } from "lit";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { stateColorCss } from "../../../../../common/entity/state_color";
|
import { stateColorCss } from "../../../../../common/entity/state_color";
|
||||||
|
import "../../../../../components/ha-icon";
|
||||||
|
import "../../../../../components/ha-svg-icon";
|
||||||
|
import "../../../../../components/tile/ha-tile-badge";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { ComputeBadgeFunction } from "./tile-badge";
|
import { RenderBadgeFunction } from "./tile-badge";
|
||||||
|
|
||||||
function getZone(entity: HassEntity, hass: HomeAssistant) {
|
function getZone(entity: HassEntity, hass: HomeAssistant) {
|
||||||
const state = entity.state;
|
const state = entity.state;
|
||||||
@ -15,17 +20,33 @@ function getZone(entity: HassEntity, hass: HomeAssistant) {
|
|||||||
return zones.find((z) => state === z.attributes.friendly_name);
|
return zones.find((z) => state === z.attributes.friendly_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function personBadgeIcon(entity: HassEntity) {
|
export const renderPersonBadge: RenderBadgeFunction = (stateObj, hass) => {
|
||||||
const state = entity.state;
|
|
||||||
return state === "not_home" ? mdiHomeExportOutline : mdiHome;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const computePersonBadge: ComputeBadgeFunction = (stateObj, hass) => {
|
|
||||||
const zone = getZone(stateObj, hass);
|
const zone = getZone(stateObj, hass);
|
||||||
|
|
||||||
return {
|
const zoneIcon = zone?.attributes.icon;
|
||||||
iconPath: personBadgeIcon(stateObj),
|
|
||||||
icon: zone?.attributes.icon,
|
if (zoneIcon) {
|
||||||
color: stateColorCss(stateObj),
|
return html`
|
||||||
};
|
<ha-tile-badge
|
||||||
|
style=${styleMap({
|
||||||
|
"--tile-badge-background-color": stateColorCss(stateObj),
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ha-icon .icon=${zoneIcon}></ha-icon>
|
||||||
|
</ha-tile-badge>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultIcon =
|
||||||
|
stateObj.state === "not_home" ? mdiHomeExportOutline : mdiHome;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-tile-badge
|
||||||
|
style=${styleMap({
|
||||||
|
"--tile-badge-background-color": stateColorCss(stateObj),
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ha-svg-icon .path=${defaultIcon}></ha-svg-icon>
|
||||||
|
</ha-tile-badge>
|
||||||
|
`;
|
||||||
};
|
};
|
||||||
|
@ -1,43 +1,46 @@
|
|||||||
import { mdiExclamationThick } from "@mdi/js";
|
import { mdiExclamationThick } from "@mdi/js";
|
||||||
import { HassEntity } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { TemplateResult, html, nothing } from "lit";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { computeDomain } from "../../../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../../../common/entity/compute_domain";
|
||||||
import { UNAVAILABLE, UNKNOWN } from "../../../../../data/entity";
|
import { UNAVAILABLE, UNKNOWN } from "../../../../../data/entity";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { computeClimateBadge } from "./tile-badge-climate";
|
import { renderClimateBadge } from "./tile-badge-climate";
|
||||||
import { computePersonBadge } from "./tile-badge-person";
|
import { renderHumidifierBadge } from "./tile-badge-humidifier";
|
||||||
import { computeHumidifierBadge } from "./tile-badge-humidifier";
|
import { renderPersonBadge } from "./tile-badge-person";
|
||||||
|
import "../../../../../components/tile/ha-tile-badge";
|
||||||
|
import "../../../../../components/ha-svg-icon";
|
||||||
|
|
||||||
export type TileBadge = {
|
export type RenderBadgeFunction = (
|
||||||
color?: string;
|
|
||||||
icon?: string;
|
|
||||||
iconPath?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ComputeBadgeFunction = (
|
|
||||||
stateObj: HassEntity,
|
stateObj: HassEntity,
|
||||||
hass: HomeAssistant
|
hass: HomeAssistant
|
||||||
) => TileBadge | undefined;
|
) => TemplateResult | typeof nothing;
|
||||||
|
|
||||||
export const computeTileBadge: ComputeBadgeFunction = (stateObj, hass) => {
|
export const renderTileBadge: RenderBadgeFunction = (stateObj, hass) => {
|
||||||
if (stateObj.state === UNKNOWN) {
|
if (stateObj.state === UNKNOWN) {
|
||||||
return undefined;
|
return nothing;
|
||||||
}
|
}
|
||||||
if (stateObj.state === UNAVAILABLE) {
|
if (stateObj.state === UNAVAILABLE) {
|
||||||
return {
|
return html`
|
||||||
color: "var(--orange-color)",
|
<ha-tile-badge
|
||||||
iconPath: mdiExclamationThick,
|
style=${styleMap({
|
||||||
};
|
"--tile-badge-background-color": "var(--orange-color)",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ha-svg-icon .path=${mdiExclamationThick}></ha-svg-icon>
|
||||||
|
</ha-tile-badge>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
const domain = computeDomain(stateObj.entity_id);
|
const domain = computeDomain(stateObj.entity_id);
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case "person":
|
case "person":
|
||||||
case "device_tracker":
|
case "device_tracker":
|
||||||
return computePersonBadge(stateObj, hass);
|
return renderPersonBadge(stateObj, hass);
|
||||||
case "climate":
|
case "climate":
|
||||||
return computeClimateBadge(stateObj, hass);
|
return renderClimateBadge(stateObj, hass);
|
||||||
case "humidifier":
|
case "humidifier":
|
||||||
return computeHumidifierBadge(stateObj, hass);
|
return renderHumidifierBadge(stateObj, hass);
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return nothing;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3,10 +3,10 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
|||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } 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 { styleMap } from "lit/directives/style-map";
|
||||||
import { domainIcon } from "../../common/entity/domain_icon";
|
|
||||||
import { stateColorCss } from "../../common/entity/state_color";
|
import { stateColorCss } from "../../common/entity/state_color";
|
||||||
import "../../components/ha-control-button";
|
import "../../components/ha-control-button";
|
||||||
import "../../components/ha-control-switch";
|
import "../../components/ha-control-switch";
|
||||||
|
import "../../components/ha-state-icon";
|
||||||
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||||
import { forwardHaptic } from "../../data/haptics";
|
import { forwardHaptic } from "../../data/haptics";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
@ -77,9 +77,11 @@ export class HaStateControlCoverToggle extends LitElement {
|
|||||||
"--color": onColor,
|
"--color": onColor,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
.path=${domainIcon("cover", this.stateObj, "open")}
|
.hass=${this.hass}
|
||||||
></ha-svg-icon>
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="open"
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-button>
|
</ha-control-button>
|
||||||
<ha-control-button
|
<ha-control-button
|
||||||
.label=${this.hass.localize("ui.card.cover.close_cover")}
|
.label=${this.hass.localize("ui.card.cover.close_cover")}
|
||||||
@ -92,9 +94,11 @@ export class HaStateControlCoverToggle extends LitElement {
|
|||||||
"--color": offColor,
|
"--color": offColor,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
.path=${domainIcon("cover", this.stateObj, "closed")}
|
.hass=${this.hass}
|
||||||
></ha-svg-icon>
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="closed"
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-button>
|
</ha-control-button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -102,8 +106,6 @@ export class HaStateControlCoverToggle extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-control-switch
|
<ha-control-switch
|
||||||
.pathOn=${domainIcon("cover", this.stateObj, "open")}
|
|
||||||
.pathOff=${domainIcon("cover", this.stateObj, "closed")}
|
|
||||||
vertical
|
vertical
|
||||||
reversed
|
reversed
|
||||||
.checked=${isOn}
|
.checked=${isOn}
|
||||||
@ -117,6 +119,18 @@ export class HaStateControlCoverToggle extends LitElement {
|
|||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
>
|
>
|
||||||
|
<ha-state-icon
|
||||||
|
slot="icon-on"
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="open"
|
||||||
|
></ha-state-icon>
|
||||||
|
<ha-state-icon
|
||||||
|
slot="icon-off"
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="closed"
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-switch>
|
</ha-control-switch>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ import {
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, 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 { styleMap } from "lit/directives/style-map";
|
||||||
import { domainIcon } from "../../common/entity/domain_icon";
|
|
||||||
import { stateColorCss } from "../../common/entity/state_color";
|
import { stateColorCss } from "../../common/entity/state_color";
|
||||||
import "../../components/ha-control-button";
|
import "../../components/ha-control-button";
|
||||||
import "../../components/ha-control-switch";
|
import "../../components/ha-control-switch";
|
||||||
|
import "../../components/ha-state-icon";
|
||||||
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||||
import { forwardHaptic } from "../../data/haptics";
|
import { forwardHaptic } from "../../data/haptics";
|
||||||
import { callProtectedLockService, LockEntity } from "../../data/lock";
|
import { callProtectedLockService, LockEntity } from "../../data/lock";
|
||||||
@ -81,18 +81,6 @@ export class HaStateControlLockToggle extends LitElement {
|
|||||||
|
|
||||||
const color = stateColorCss(this.stateObj);
|
const color = stateColorCss(this.stateObj);
|
||||||
|
|
||||||
const onIcon = domainIcon(
|
|
||||||
"lock",
|
|
||||||
this.stateObj,
|
|
||||||
locking ? "locking" : "locked"
|
|
||||||
);
|
|
||||||
|
|
||||||
const offIcon = domainIcon(
|
|
||||||
"lock",
|
|
||||||
this.stateObj,
|
|
||||||
unlocking ? "unlocking" : "unlocked"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.stateObj.state === UNKNOWN) {
|
if (this.stateObj.state === UNKNOWN) {
|
||||||
return html`
|
return html`
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
@ -100,13 +88,21 @@ export class HaStateControlLockToggle extends LitElement {
|
|||||||
.label=${this.hass.localize("ui.card.lock.lock")}
|
.label=${this.hass.localize("ui.card.lock.lock")}
|
||||||
@click=${this._turnOn}
|
@click=${this._turnOn}
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${onIcon}></ha-svg-icon>
|
<ha-state-icon
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
.stateValue=${locking ? "locking" : "locked"}
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-button>
|
</ha-control-button>
|
||||||
<ha-control-button
|
<ha-control-button
|
||||||
.label=${this.hass.localize("ui.card.lock.unlock")}
|
.label=${this.hass.localize("ui.card.lock.unlock")}
|
||||||
@click=${this._turnOff}
|
@click=${this._turnOff}
|
||||||
>
|
>
|
||||||
<ha-svg-icon .path=${offIcon}></ha-svg-icon>
|
<ha-state-icon
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
.stateValue=${unlocking ? "unlocking" : "unlocked"}
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-button>
|
</ha-control-button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -127,16 +123,20 @@ export class HaStateControlLockToggle extends LitElement {
|
|||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
slot="icon-on"
|
slot="icon-on"
|
||||||
.path=${onIcon}
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
.stateValue=${locking ? "locking" : "locked"}
|
||||||
class=${classMap({ pulse: locking })}
|
class=${classMap({ pulse: locking })}
|
||||||
></ha-svg-icon>
|
></ha-state-icon>
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
slot="icon-off"
|
slot="icon-off"
|
||||||
.path=${offIcon}
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
.stateValue=${unlocking ? "unlocking" : "unlocked"}
|
||||||
class=${classMap({ pulse: unlocking })}
|
class=${classMap({ pulse: unlocking })}
|
||||||
></ha-svg-icon>
|
></ha-state-icon>
|
||||||
</ha-control-switch>
|
</ha-control-switch>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
|||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } 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 { styleMap } from "lit/directives/style-map";
|
||||||
import { domainIcon } from "../../common/entity/domain_icon";
|
|
||||||
import { stateColorCss } from "../../common/entity/state_color";
|
import { stateColorCss } from "../../common/entity/state_color";
|
||||||
import "../../components/ha-control-button";
|
import "../../components/ha-control-button";
|
||||||
import "../../components/ha-control-switch";
|
import "../../components/ha-control-switch";
|
||||||
|
import "../../components/ha-state-icon";
|
||||||
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
|
||||||
import { forwardHaptic } from "../../data/haptics";
|
import { forwardHaptic } from "../../data/haptics";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
@ -77,9 +77,11 @@ export class HaStateControlValveToggle extends LitElement {
|
|||||||
"--color": onColor,
|
"--color": onColor,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
.path=${domainIcon("valve", this.stateObj, "open")}
|
.hass=${this.hass}
|
||||||
></ha-svg-icon>
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="open"
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-button>
|
</ha-control-button>
|
||||||
<ha-control-button
|
<ha-control-button
|
||||||
.label=${this.hass.localize("ui.card.valve.close_valve")}
|
.label=${this.hass.localize("ui.card.valve.close_valve")}
|
||||||
@ -92,9 +94,11 @@ export class HaStateControlValveToggle extends LitElement {
|
|||||||
"--color": offColor,
|
"--color": offColor,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<ha-svg-icon
|
<ha-state-icon
|
||||||
.path=${domainIcon("valve", this.stateObj, "closed")}
|
.hass=${this.hass}
|
||||||
></ha-svg-icon>
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="closed"
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-button>
|
</ha-control-button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -102,8 +106,6 @@ export class HaStateControlValveToggle extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-control-switch
|
<ha-control-switch
|
||||||
.pathOn=${domainIcon("valve", this.stateObj, "open")}
|
|
||||||
.pathOff=${domainIcon("valve", this.stateObj, "closed")}
|
|
||||||
vertical
|
vertical
|
||||||
reversed
|
reversed
|
||||||
.checked=${isOn}
|
.checked=${isOn}
|
||||||
@ -117,6 +119,18 @@ export class HaStateControlValveToggle extends LitElement {
|
|||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
>
|
>
|
||||||
|
<ha-state-icon
|
||||||
|
slot="icon-on"
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="open"
|
||||||
|
></ha-state-icon>
|
||||||
|
<ha-state-icon
|
||||||
|
slot="icon-off"
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
stateValue="closed"
|
||||||
|
></ha-state-icon>
|
||||||
</ha-control-switch>
|
</ha-control-switch>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user