mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
♻️ change entity-button to button card (#4581)
* ♻️ change entity-button to button card
* maintain separate entity-button class
This commit is contained in:
parent
b2243f480c
commit
3f7c29a6f6
@ -395,7 +395,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
entity: "script.air_cleaner_quiet",
|
entity: "script.air_cleaner_quiet",
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
name: "AC bed",
|
name: "AC bed",
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "call-service",
|
action: "call-service",
|
||||||
@ -408,7 +408,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
entity: "script.air_cleaner_auto",
|
entity: "script.air_cleaner_auto",
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
name: "AC bed",
|
name: "AC bed",
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "call-service",
|
action: "call-service",
|
||||||
@ -421,7 +421,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
entity: "script.air_cleaner_turbo",
|
entity: "script.air_cleaner_turbo",
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
name: "AC bed",
|
name: "AC bed",
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "call-service",
|
action: "call-service",
|
||||||
@ -434,7 +434,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
entity: "script.ac_off",
|
entity: "script.ac_off",
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
name: "AC",
|
name: "AC",
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "call-service",
|
action: "call-service",
|
||||||
@ -447,7 +447,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
entity: "script.ac_on",
|
entity: "script.ac_on",
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
name: "AC",
|
name: "AC",
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "call-service",
|
action: "call-service",
|
||||||
@ -658,7 +658,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
action: "call-service",
|
action: "call-service",
|
||||||
service: "script.goodnight",
|
service: "script.goodnight",
|
||||||
},
|
},
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
icon: "mdi:weather-night",
|
icon: "mdi:weather-night",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -670,7 +670,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
service: "scene.turn_on",
|
service: "scene.turn_on",
|
||||||
},
|
},
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
icon: "mdi:coffee-outline",
|
icon: "mdi:coffee-outline",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -682,7 +682,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
service: "scene.turn_on",
|
service: "scene.turn_on",
|
||||||
},
|
},
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
icon: "mdi:television-classic",
|
icon: "mdi:television-classic",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -743,7 +743,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
service: "light.toggle",
|
service: "light.toggle",
|
||||||
},
|
},
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
icon: "mdi:page-layout-footer",
|
icon: "mdi:page-layout-footer",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -755,7 +755,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
},
|
},
|
||||||
service: "light.toggle",
|
service: "light.toggle",
|
||||||
},
|
},
|
||||||
type: "entity-button",
|
type: "button",
|
||||||
icon: "mdi:page-layout-header",
|
icon: "mdi:page-layout-header",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -15,14 +15,14 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "Basic example",
|
heading: "Basic example",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "With Name",
|
heading: "With Name",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
name: Bedroom
|
name: Bedroom
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`,
|
`,
|
||||||
@ -30,7 +30,7 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "With Icon",
|
heading: "With Icon",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
icon: mdi:hotel
|
icon: mdi:hotel
|
||||||
`,
|
`,
|
||||||
@ -38,7 +38,7 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "Without State",
|
heading: "Without State",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
show_state: false
|
show_state: false
|
||||||
`,
|
`,
|
||||||
@ -46,7 +46,7 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "Custom Tap Action (toggle)",
|
heading: "Custom Tap Action (toggle)",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
tap_action:
|
tap_action:
|
||||||
action: toggle
|
action: toggle
|
||||||
@ -55,7 +55,7 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "Running Service",
|
heading: "Running Service",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
service: light.toggle
|
service: light.toggle
|
||||||
`,
|
`,
|
||||||
@ -63,13 +63,13 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "Invalid Entity",
|
heading: "Invalid Entity",
|
||||||
config: `
|
config: `
|
||||||
- type: entity-button
|
- type: button
|
||||||
entity: sensor.invalid_entity
|
entity: sensor.invalid_entity
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoEntityButtonEntity extends PolymerElement {
|
class DemoButtonEntity extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<demo-cards
|
<demo-cards
|
||||||
@ -97,4 +97,4 @@ class DemoEntityButtonEntity extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-entity-button-card", DemoEntityButtonEntity);
|
customElements.define("demo-hui-button-card", DemoButtonEntity);
|
||||||
|
256
src/panels/lovelace/cards/hui-button-card.ts
Normal file
256
src/panels/lovelace/cards/hui-button-card.ts
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
import {
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
TemplateResult,
|
||||||
|
CSSResult,
|
||||||
|
css,
|
||||||
|
customElement,
|
||||||
|
property,
|
||||||
|
} from "lit-element";
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { styleMap } from "lit-html/directives/style-map";
|
||||||
|
import { ifDefined } from "lit-html/directives/if-defined";
|
||||||
|
import "@material/mwc-ripple";
|
||||||
|
|
||||||
|
import "../../../components/ha-card";
|
||||||
|
import "../components/hui-warning";
|
||||||
|
|
||||||
|
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
|
import { stateIcon } from "../../../common/entity/state_icon";
|
||||||
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
|
|
||||||
|
import { HomeAssistant, LightEntity } from "../../../types";
|
||||||
|
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
|
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||||
|
import { ButtonCardConfig } from "./types";
|
||||||
|
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||||
|
import { hasAction } from "../common/has-action";
|
||||||
|
import { handleAction } from "../common/handle-action";
|
||||||
|
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||||
|
import { computeActiveState } from "../../../common/entity/compute_active_state";
|
||||||
|
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
||||||
|
|
||||||
|
@customElement("hui-button-card")
|
||||||
|
export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||||
|
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
||||||
|
await import(
|
||||||
|
/* webpackChunkName: "hui-button-card-editor" */ "../editor/config-elements/hui-button-card-editor"
|
||||||
|
);
|
||||||
|
return document.createElement("hui-button-card-editor");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getStubConfig(): object {
|
||||||
|
return {
|
||||||
|
tap_action: { action: "toggle" },
|
||||||
|
hold_action: { action: "more-info" },
|
||||||
|
show_icon: true,
|
||||||
|
show_name: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@property() public hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@property() private _config?: ButtonCardConfig;
|
||||||
|
|
||||||
|
public getCardSize(): number {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setConfig(config: ButtonCardConfig): void {
|
||||||
|
if (config.entity && !isValidEntityId(config.entity)) {
|
||||||
|
throw new Error("Invalid Entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._config = {
|
||||||
|
theme: "default",
|
||||||
|
hold_action: { action: "more-info" },
|
||||||
|
double_tap_action: { action: "none" },
|
||||||
|
show_icon: true,
|
||||||
|
show_name: true,
|
||||||
|
...config,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (config.entity && DOMAINS_TOGGLE.has(computeDomain(config.entity))) {
|
||||||
|
this._config = {
|
||||||
|
tap_action: {
|
||||||
|
action: "toggle",
|
||||||
|
},
|
||||||
|
...this._config,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this._config = {
|
||||||
|
tap_action: {
|
||||||
|
action: "more-info",
|
||||||
|
},
|
||||||
|
...this._config,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||||
|
if (changedProps.has("_config")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!oldHass ||
|
||||||
|
oldHass.themes !== this.hass!.themes ||
|
||||||
|
oldHass.language !== this.hass!.language
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
Boolean(this._config!.entity) &&
|
||||||
|
oldHass.states[this._config!.entity!] !==
|
||||||
|
this.hass!.states[this._config!.entity!]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this._config || !this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
const stateObj = this._config.entity
|
||||||
|
? this.hass.states[this._config.entity]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (this._config.entity && !stateObj) {
|
||||||
|
return html`
|
||||||
|
<hui-warning
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.warning.entity_not_found",
|
||||||
|
"entity",
|
||||||
|
this._config.entity
|
||||||
|
)}</hui-warning
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-card
|
||||||
|
@action=${this._handleAction}
|
||||||
|
.actionHandler=${actionHandler({
|
||||||
|
hasHold: hasAction(this._config!.hold_action),
|
||||||
|
hasDoubleClick: hasAction(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
|
tabindex=${ifDefined(
|
||||||
|
hasAction(this._config.tap_action) ? "0" : undefined
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
${this._config.show_icon
|
||||||
|
? html`
|
||||||
|
<ha-icon
|
||||||
|
data-domain=${ifDefined(
|
||||||
|
stateObj ? computeStateDomain(stateObj) : undefined
|
||||||
|
)}
|
||||||
|
data-state=${ifDefined(
|
||||||
|
stateObj ? computeActiveState(stateObj) : undefined
|
||||||
|
)}
|
||||||
|
.icon=${this._config.icon ||
|
||||||
|
(stateObj ? stateIcon(stateObj) : "")}
|
||||||
|
style=${styleMap({
|
||||||
|
filter: stateObj ? this._computeBrightness(stateObj) : "",
|
||||||
|
color: stateObj ? this._computeColor(stateObj) : "",
|
||||||
|
height: this._config.icon_height
|
||||||
|
? this._config.icon_height
|
||||||
|
: "auto",
|
||||||
|
})}
|
||||||
|
></ha-icon>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this._config.show_name
|
||||||
|
? html`
|
||||||
|
<span>
|
||||||
|
${this._config.name ||
|
||||||
|
(stateObj ? computeStateName(stateObj) : "")}
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
<mwc-ripple></mwc-ripple>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps: PropertyValues): void {
|
||||||
|
super.updated(changedProps);
|
||||||
|
if (!this._config || !this.hass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
|
const oldConfig = changedProps.get("_config") as
|
||||||
|
| ButtonCardConfig
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!oldHass ||
|
||||||
|
!oldConfig ||
|
||||||
|
oldHass.themes !== this.hass.themes ||
|
||||||
|
oldConfig.theme !== this._config.theme
|
||||||
|
) {
|
||||||
|
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
ha-card {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4% 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-card:focus {
|
||||||
|
outline: none;
|
||||||
|
background: var(--divider-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-icon {
|
||||||
|
width: 40%;
|
||||||
|
height: auto;
|
||||||
|
color: var(--paper-item-icon-color, #44739e);
|
||||||
|
}
|
||||||
|
|
||||||
|
${iconColorCSS}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeBrightness(stateObj: HassEntity | LightEntity): string {
|
||||||
|
if (!stateObj.attributes.brightness) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const brightness = stateObj.attributes.brightness;
|
||||||
|
return `brightness(${(brightness + 245) / 5}%)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeColor(stateObj: HassEntity | LightEntity): string {
|
||||||
|
if (!stateObj.attributes.hs_color) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const [hue, sat] = stateObj.attributes.hs_color;
|
||||||
|
if (sat <= 10) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleAction(ev: ActionHandlerEvent) {
|
||||||
|
handleAction(this, this.hass!, this._config!, ev.detail.action!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-button-card": HuiButtonCard;
|
||||||
|
}
|
||||||
|
}
|
@ -1,246 +1,9 @@
|
|||||||
import {
|
import { customElement } from "lit-element";
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
TemplateResult,
|
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
customElement,
|
|
||||||
property,
|
|
||||||
} from "lit-element";
|
|
||||||
import { HassEntity } from "home-assistant-js-websocket";
|
|
||||||
import { styleMap } from "lit-html/directives/style-map";
|
|
||||||
import { ifDefined } from "lit-html/directives/if-defined";
|
|
||||||
import "@material/mwc-ripple";
|
|
||||||
|
|
||||||
import "../../../components/ha-card";
|
import { HuiButtonCard } from "./hui-button-card";
|
||||||
import "../components/hui-warning";
|
|
||||||
|
|
||||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
|
||||||
import { stateIcon } from "../../../common/entity/state_icon";
|
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
|
||||||
|
|
||||||
import { HomeAssistant, LightEntity } from "../../../types";
|
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
|
||||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
|
||||||
import { EntityButtonCardConfig } from "./types";
|
|
||||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
|
||||||
import { hasAction } from "../common/has-action";
|
|
||||||
import { handleAction } from "../common/handle-action";
|
|
||||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
|
||||||
import { computeActiveState } from "../../../common/entity/compute_active_state";
|
|
||||||
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
|
||||||
|
|
||||||
@customElement("hui-entity-button-card")
|
@customElement("hui-entity-button-card")
|
||||||
class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
class HuiEntityButtonCard extends HuiButtonCard {}
|
||||||
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
|
||||||
await import(
|
|
||||||
/* webpackChunkName: "hui-entity-button-card-editor" */ "../editor/config-elements/hui-entity-button-card-editor"
|
|
||||||
);
|
|
||||||
return document.createElement("hui-entity-button-card-editor");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static getStubConfig(): object {
|
|
||||||
return {
|
|
||||||
tap_action: { action: "toggle" },
|
|
||||||
hold_action: { action: "more-info" },
|
|
||||||
show_icon: true,
|
|
||||||
show_name: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@property() public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@property() private _config?: EntityButtonCardConfig;
|
|
||||||
|
|
||||||
public getCardSize(): number {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setConfig(config: EntityButtonCardConfig): void {
|
|
||||||
if (!isValidEntityId(config.entity)) {
|
|
||||||
throw new Error("Invalid Entity");
|
|
||||||
}
|
|
||||||
|
|
||||||
this._config = {
|
|
||||||
theme: "default",
|
|
||||||
hold_action: { action: "more-info" },
|
|
||||||
double_tap_action: { action: "none" },
|
|
||||||
show_icon: true,
|
|
||||||
show_name: true,
|
|
||||||
...config,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (DOMAINS_TOGGLE.has(computeDomain(config.entity))) {
|
|
||||||
this._config = {
|
|
||||||
tap_action: {
|
|
||||||
action: "toggle",
|
|
||||||
},
|
|
||||||
...this._config,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
this._config = {
|
|
||||||
tap_action: {
|
|
||||||
action: "more-info",
|
|
||||||
},
|
|
||||||
...this._config,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
|
||||||
if (changedProps.has("_config")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!oldHass ||
|
|
||||||
oldHass.themes !== this.hass!.themes ||
|
|
||||||
oldHass.language !== this.hass!.language
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
oldHass.states[this._config!.entity] !==
|
|
||||||
this.hass!.states[this._config!.entity]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
|
||||||
if (!this._config || !this.hass) {
|
|
||||||
return html``;
|
|
||||||
}
|
|
||||||
const stateObj = this.hass.states[this._config.entity];
|
|
||||||
|
|
||||||
if (!stateObj) {
|
|
||||||
return html`
|
|
||||||
<hui-warning
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.lovelace.warning.entity_not_found",
|
|
||||||
"entity",
|
|
||||||
this._config.entity
|
|
||||||
)}</hui-warning
|
|
||||||
>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<ha-card
|
|
||||||
@action=${this._handleAction}
|
|
||||||
.actionHandler=${actionHandler({
|
|
||||||
hasHold: hasAction(this._config!.hold_action),
|
|
||||||
hasDoubleClick: hasAction(this._config!.double_tap_action),
|
|
||||||
})}
|
|
||||||
tabindex=${ifDefined(
|
|
||||||
hasAction(this._config.tap_action) ||
|
|
||||||
this._config.tap_action === undefined
|
|
||||||
? "0"
|
|
||||||
: undefined
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
${this._config.show_icon
|
|
||||||
? html`
|
|
||||||
<ha-icon
|
|
||||||
data-domain=${computeStateDomain(stateObj)}
|
|
||||||
data-state=${computeActiveState(stateObj)}
|
|
||||||
.icon=${this._config.icon || stateIcon(stateObj)}
|
|
||||||
style=${styleMap({
|
|
||||||
filter: this._computeBrightness(stateObj),
|
|
||||||
color: this._computeColor(stateObj),
|
|
||||||
height: this._config.icon_height
|
|
||||||
? this._config.icon_height
|
|
||||||
: "auto",
|
|
||||||
})}
|
|
||||||
></ha-icon>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${this._config.show_name
|
|
||||||
? html`
|
|
||||||
<span>
|
|
||||||
${this._config.name || computeStateName(stateObj)}
|
|
||||||
</span>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
<mwc-ripple></mwc-ripple>
|
|
||||||
</ha-card>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues): void {
|
|
||||||
super.updated(changedProps);
|
|
||||||
if (!this._config || !this.hass) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
|
||||||
const oldConfig = changedProps.get("_config") as
|
|
||||||
| EntityButtonCardConfig
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!oldHass ||
|
|
||||||
!oldConfig ||
|
|
||||||
oldHass.themes !== this.hass.themes ||
|
|
||||||
oldConfig.theme !== this._config.theme
|
|
||||||
) {
|
|
||||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
|
||||||
return css`
|
|
||||||
ha-card {
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
padding: 4% 0;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ha-card:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ha-icon {
|
|
||||||
width: 40%;
|
|
||||||
height: auto;
|
|
||||||
color: var(--paper-item-icon-color, #44739e);
|
|
||||||
}
|
|
||||||
|
|
||||||
${iconColorCSS}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _computeBrightness(stateObj: HassEntity | LightEntity): string {
|
|
||||||
if (!stateObj.attributes.brightness) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const brightness = stateObj.attributes.brightness;
|
|
||||||
return `brightness(${(brightness + 245) / 5}%)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _computeColor(stateObj: HassEntity | LightEntity): string {
|
|
||||||
if (!stateObj.attributes.hs_color) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const [hue, sat] = stateObj.attributes.hs_color;
|
|
||||||
if (sat <= 10) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleAction(ev: ActionHandlerEvent) {
|
|
||||||
handleAction(this, this.hass!, this._config!, ev.detail.action!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
|
@ -47,8 +47,8 @@ export interface EntitiesCardConfig extends LovelaceCardConfig {
|
|||||||
state_color?: boolean;
|
state_color?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EntityButtonCardConfig extends LovelaceCardConfig {
|
export interface ButtonCardConfig extends LovelaceCardConfig {
|
||||||
entity: string;
|
entity?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
show_name?: boolean;
|
show_name?: boolean;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import "../cards/hui-entities-card";
|
import "../cards/hui-entities-card";
|
||||||
|
import "../cards/hui-button-card";
|
||||||
import "../cards/hui-entity-button-card";
|
import "../cards/hui-entity-button-card";
|
||||||
import "../cards/hui-glance-card";
|
import "../cards/hui-glance-card";
|
||||||
import "../cards/hui-history-graph-card";
|
import "../cards/hui-history-graph-card";
|
||||||
@ -14,6 +15,7 @@ import { createLovelaceElement } from "./create-element-base";
|
|||||||
|
|
||||||
const ALWAYS_LOADED_TYPES = new Set([
|
const ALWAYS_LOADED_TYPES = new Set([
|
||||||
"entities",
|
"entities",
|
||||||
|
"button",
|
||||||
"entity-button",
|
"entity-button",
|
||||||
"error",
|
"error",
|
||||||
"glance",
|
"glance",
|
||||||
|
@ -18,7 +18,7 @@ const cards: string[] = [
|
|||||||
"alarm-panel",
|
"alarm-panel",
|
||||||
"conditional",
|
"conditional",
|
||||||
"entities",
|
"entities",
|
||||||
"entity-button",
|
"button",
|
||||||
"entity-filter",
|
"entity-filter",
|
||||||
"gauge",
|
"gauge",
|
||||||
"glance",
|
"glance",
|
||||||
|
@ -22,7 +22,7 @@ import { LovelaceCardEditor } from "../../types";
|
|||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { configElementStyle } from "./config-elements-style";
|
import { configElementStyle } from "./config-elements-style";
|
||||||
import { ActionConfig } from "../../../../data/lovelace";
|
import { ActionConfig } from "../../../../data/lovelace";
|
||||||
import { EntityButtonCardConfig } from "../../cards/types";
|
import { ButtonCardConfig } from "../../cards/types";
|
||||||
|
|
||||||
const cardConfigStruct = struct({
|
const cardConfigStruct = struct({
|
||||||
type: "string",
|
type: "string",
|
||||||
@ -37,14 +37,14 @@ const cardConfigStruct = struct({
|
|||||||
theme: "string?",
|
theme: "string?",
|
||||||
});
|
});
|
||||||
|
|
||||||
@customElement("hui-entity-button-card-editor")
|
@customElement("hui-button-card-editor")
|
||||||
export class HuiEntityButtonCardEditor extends LitElement
|
export class HuiButtonCardEditor extends LitElement
|
||||||
implements LovelaceCardEditor {
|
implements LovelaceCardEditor {
|
||||||
@property() public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property() private _config?: EntityButtonCardConfig;
|
@property() private _config?: ButtonCardConfig;
|
||||||
|
|
||||||
public setConfig(config: EntityButtonCardConfig): void {
|
public setConfig(config: ButtonCardConfig): void {
|
||||||
config = cardConfigStruct(config);
|
config = cardConfigStruct(config);
|
||||||
this._config = config;
|
this._config = config;
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ export class HuiEntityButtonCardEditor extends LitElement
|
|||||||
.label="${this.hass.localize(
|
.label="${this.hass.localize(
|
||||||
"ui.panel.lovelace.editor.card.generic.entity"
|
"ui.panel.lovelace.editor.card.generic.entity"
|
||||||
)} (${this.hass.localize(
|
)} (${this.hass.localize(
|
||||||
"ui.panel.lovelace.editor.card.config.required"
|
"ui.panel.lovelace.editor.card.config.optional"
|
||||||
)})"
|
)})"
|
||||||
.hass="${this.hass}"
|
.hass="${this.hass}"
|
||||||
.value="${this._entity}"
|
.value="${this._entity}"
|
||||||
@ -250,6 +250,6 @@ export class HuiEntityButtonCardEditor extends LitElement
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
"hui-entity-button-card-editor": HuiEntityButtonCardEditor;
|
"hui-button-card-editor": HuiButtonCardEditor;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1811,8 +1811,8 @@
|
|||||||
"show_header_toggle": "Show Header Toggle?",
|
"show_header_toggle": "Show Header Toggle?",
|
||||||
"toggle": "Toggle entities."
|
"toggle": "Toggle entities."
|
||||||
},
|
},
|
||||||
"entity-button": {
|
"button": {
|
||||||
"name": "Entity Button"
|
"name": "Button"
|
||||||
},
|
},
|
||||||
"entity-filter": {
|
"entity-filter": {
|
||||||
"name": "Entity Filter"
|
"name": "Entity Filter"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user