mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 14:56:37 +00:00
Button Card - Lovelace Addition (#1766)
* Initial Commit - Button Card * Fixing Coloring Review * Resolving Reviews * Updating last Reviews
This commit is contained in:
parent
48f6d1dfec
commit
794808d3a7
95
gallery/src/demos/demo-hui-entity-button-card.js
Normal file
95
gallery/src/demos/demo-hui-entity-button-card.js
Normal file
@ -0,0 +1,95 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||
|
||||
import getEntity from "../data/entity.js";
|
||||
import provideHass from "../data/provide_hass.js";
|
||||
import "../components/demo-cards.js";
|
||||
|
||||
const ENTITIES = [
|
||||
getEntity("light", "bed_light", "on", {
|
||||
friendly_name: "Bed Light",
|
||||
}),
|
||||
];
|
||||
|
||||
const CONFIGS = [
|
||||
{
|
||||
heading: "Basic example",
|
||||
config: `
|
||||
- type: entity-button
|
||||
entity: light.bed_light
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "With Name",
|
||||
config: `
|
||||
- type: entity-button
|
||||
name: Bedroom
|
||||
entity: light.bed_light
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "With Icon",
|
||||
config: `
|
||||
- type: entity-button
|
||||
entity: light.bed_light
|
||||
icon: mdi:hotel
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "Without State",
|
||||
config: `
|
||||
- type: entity-button
|
||||
entity: light.bed_light
|
||||
show_state: false
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "Custom Tap Action (toggle)",
|
||||
config: `
|
||||
- type: entity-button
|
||||
entity: light.bed_light
|
||||
tap_action: toggle
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "Running Service",
|
||||
config: `
|
||||
- type: entity-button
|
||||
entity: light.bed_light
|
||||
service: light.toggle
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "Invalid Entity",
|
||||
config: `
|
||||
- type: entity-button
|
||||
entity: sensor.invalid_entity
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
class DemoEntityButtonEntity extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<demo-cards id='demos' hass='[[hass]]' configs="[[_configs]]"></demo-cards>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
_configs: {
|
||||
type: Object,
|
||||
value: CONFIGS,
|
||||
},
|
||||
hass: Object,
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
const hass = provideHass(this.$.demos);
|
||||
hass.addEntities(ENTITIES);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("demo-hui-entity-button-card", DemoEntityButtonEntity);
|
161
src/panels/lovelace/cards/hui-entity-button-card.js
Normal file
161
src/panels/lovelace/cards/hui-entity-button-card.js
Normal file
@ -0,0 +1,161 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||
import { fireEvent } from "../../../common/dom/fire_event.js";
|
||||
|
||||
import "../../../components/ha-card.js";
|
||||
|
||||
import toggleEntity from "../common/entity/toggle-entity.js";
|
||||
import stateIcon from "../../../common/entity/state_icon.js";
|
||||
import computeStateDomain from "../../../common/entity/compute_state_domain.js";
|
||||
import computeStateName from "../../../common/entity/compute_state_name.js";
|
||||
import EventsMixin from "../../../mixins/events-mixin.js";
|
||||
import LocalizeMixin from "../../../mixins/localize-mixin.js";
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
*/
|
||||
class HuiEntityButtonCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ha-icon {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
color: var(--paper-item-icon-color, #44739e);
|
||||
}
|
||||
ha-icon[data-domain=light][data-state=on],
|
||||
ha-icon[data-domain=switch][data-state=on],
|
||||
ha-icon[data-domain=binary_sensor][data-state=on],
|
||||
ha-icon[data-domain=fan][data-state=on],
|
||||
ha-icon[data-domain=sun][data-state=above_horizon] {
|
||||
color: var(--paper-item-icon-active-color, #FDD835);
|
||||
}
|
||||
ha-icon[data-state=unavailable] {
|
||||
color: var(--state-icon-unavailable-color);
|
||||
}
|
||||
state-badge {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
width:40%;
|
||||
height:40%;
|
||||
}
|
||||
paper-button {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.not-found {
|
||||
flex: 1;
|
||||
background-color: yellow;
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
<ha-card on-click="_handleClick">
|
||||
<paper-button>
|
||||
<div class$="[[_computeClassName(_stateObj)]]">
|
||||
<ha-icon id="ButtonIcon"
|
||||
data-domain$="[[_computeDomain(_stateObj)]]"
|
||||
data-state$="[[_stateObj.state]]"
|
||||
icon="[[_computeIcon(_stateObj)]]"></ha-icon>
|
||||
<span>[[_computeName(_stateObj)]]</span>
|
||||
</div>
|
||||
</paper-button>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
_config: Object,
|
||||
_stateObj: {
|
||||
type: Object,
|
||||
computed: "_computeStateObj(hass.states, _config.entity)",
|
||||
observer: "stateObjChanged",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getCardSize() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
setConfig(config) {
|
||||
if (!config || !config.entity) {
|
||||
throw new Error("Invalid card configuration");
|
||||
}
|
||||
this._config = { show_state: true, ...config };
|
||||
}
|
||||
|
||||
_computeStateObj(states, entityId) {
|
||||
return states && entityId in states ? states[entityId] : null;
|
||||
}
|
||||
|
||||
stateObjChanged() {
|
||||
const stateObj = this._stateObj;
|
||||
if (!stateObj) return;
|
||||
|
||||
const iconStyle = {
|
||||
color: "",
|
||||
filter: "",
|
||||
};
|
||||
if (stateObj.attributes.hs_color) {
|
||||
const hue = stateObj.attributes.hs_color[0];
|
||||
const sat = stateObj.attributes.hs_color[1];
|
||||
if (sat > 10) iconStyle.color = `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
||||
}
|
||||
if (stateObj.attributes.brightness) {
|
||||
const brightness = stateObj.attributes.brightness;
|
||||
iconStyle.filter = `brightness(${(brightness + 245) / 5}%)`;
|
||||
}
|
||||
Object.assign(this.$.ButtonIcon.style, iconStyle);
|
||||
}
|
||||
|
||||
_computeDomain(stateObj) {
|
||||
if (!stateObj) return "";
|
||||
return computeStateDomain(stateObj);
|
||||
}
|
||||
|
||||
_computeName(stateObj) {
|
||||
const config = this._config;
|
||||
if (!stateObj) return "Entity not available: " + this._config.entity;
|
||||
return config.name ? config.name : computeStateName(stateObj);
|
||||
}
|
||||
|
||||
_computeIcon(stateObj) {
|
||||
const config = this._config;
|
||||
if (!stateObj) return "";
|
||||
return config.icon ? config.icon : stateIcon(stateObj);
|
||||
}
|
||||
|
||||
_computeClassName(stateObj) {
|
||||
if (!stateObj) return "not-found";
|
||||
return "";
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (!this._stateObj) return;
|
||||
const config = this._config;
|
||||
const stateObj = this._stateObj;
|
||||
var entityId = stateObj.entity_id;
|
||||
switch (config.tap_action) {
|
||||
case "toggle":
|
||||
toggleEntity(this.hass, entityId);
|
||||
break;
|
||||
case "call-service": {
|
||||
const [domain, service] = config.service.split(".", 2);
|
||||
const serviceData = { entity_id: entityId, ...config.service_data };
|
||||
this.hass.callService(domain, service, serviceData);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fireEvent(this, "hass-more-info", { entityId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("hui-entity-button-card", HuiEntityButtonCard);
|
@ -3,6 +3,7 @@ import { fireEvent } from "../../../common/dom/fire_event.js";
|
||||
import "../cards/hui-alarm-panel-card.js";
|
||||
import "../cards/hui-conditional-card.js";
|
||||
import "../cards/hui-entities-card.js";
|
||||
import "../cards/hui-entity-button-card.js";
|
||||
import "../cards/hui-entity-filter-card.js";
|
||||
import "../cards/hui-error-card.js";
|
||||
import "../cards/hui-glance-card.ts";
|
||||
@ -28,6 +29,7 @@ const CARD_TYPES = new Set([
|
||||
"alarm-panel",
|
||||
"conditional",
|
||||
"entities",
|
||||
"entity-button",
|
||||
"entity-filter",
|
||||
"error",
|
||||
"gauge",
|
||||
|
Loading…
x
Reference in New Issue
Block a user