Update to use card-tools. Fixes #6. Fixes #16. Fixes #18. Check #19

This commit is contained in:
Thomas Lovén 2018-12-14 09:14:08 +01:00
parent 0636ee9522
commit b895b8f954
2 changed files with 102 additions and 155 deletions

View File

@ -3,6 +3,8 @@ fold-entity-row
Make a group from entities in a lovelace entities card - and fold them away when you don't want to see them. Make a group from entities in a lovelace entities card - and fold them away when you don't want to see them.
This card requires [card-tools](https://github.com/thomasloven/lovelace-card-tools) to be installed.
## Options ## Options
| Name | Type | Default | Description | Name | Type | Default | Description

View File

@ -1,181 +1,126 @@
class FoldRow extends Polymer.Element { var LitElement = LitElement || Object.getPrototypeOf(customElements.get('hui-error-entity-row'));
class FoldEntityRow extends LitElement {
static get template() { static get properties() {
return Polymer.html` return {
<style> _closed: Boolean,
li, ul { };
list-style: none;
} }
ul {
transition: max-height 0.5s; render() {
-webkit-transition: max-height 0.5s; return window.cardTools.litHtml`
overflow: hidden; ${this._renderStyle()}
<div id=head>
<div id=entity>
${this._head}
</div>
<div id=toggle>
<ha-icon @click=${this._toggle} icon="${this._closed ? "mdi:chevron-down" : "mdi:chevron-up"}"></ha-icon>
</div>
</div>
<div id=items ?closed=${this._closed}>
${this._entities}
</div>
`;
}
_renderStyle() {
return window.cardTools.litHtml`
<style>
#items {
padding: 0 0 0 40px; padding: 0 0 0 40px;
margin: 0; margin: 0;
} }
.closed > ul { [closed] > div {
overflow: hidden;
max-height: 0; max-height: 0;
} }
#head { #head {
display: flex; display: flex;
align-items: center;
} }
.toggle { #entity {
width: 40px; flex: 1 1 auto;
height: 40px; width: 0px;
align-items: center; }
#toggle {
flex: 0 1 40px;
display: flex; display: flex;
align-items: center;
} }
.toggle ha-icon { ha-icon {
flex: 0 0 40px; width: 40px;
}
#bar.closed {
max-height: 0;
}
#bar.open {
height: 1px;
background-color: var(--secondary-text-color);
opacity: 0.25;
margin-left: -16px;
margin-right: -16px;
margin-top: 8px;
margin-bottom: 8px;
} }
</style> </style>
<div id=topbar class=nobar></div> `;
<div id=head>
<div class=toggle on-click="doToggle">
<ha-icon icon="[[_icon]]"></ha-icon>
</div>
</div>
<li id="rows" class="closed">
</li>
`
}
update() {
this._icon = this.closed ? 'mdi:chevron-down' : 'mdi:chevron-up';
if(this.$) {
this.$.rows.className = this.closed ? 'closed' : 'open';
}
}
doToggle(ev) {
this.closed = !this.closed;
this.update();
ev.stopPropagation();
} }
ready() { firstUpdated() {
super.ready(); this.hass = this._hass;
let conf = [];
let head = this._config.head;
let items = this._config.items;
if(typeof head === 'string') {
head = {entity: head};
}
conf.push(head);
if(head.entity && head.entity.startsWith('group')) {
items = this._hass.states[head.entity].attributes.entity_id;
}
items.forEach((i) => {
if(typeof i === 'string') i = {entity: i};
conf.push(Object.assign(i, this._config.group_config));
});
this.items = [];
this.dummy = document.createElement('hui-entities-card');
this.dummy.setConfig({entities: conf});
this.dummy.hass = this._hass;
this.appendChild(this.dummy);
const nextChild = (root) => {
let child = root.firstChild;
while(child && child.nodeType != 1) child = child.nextSibling;
return child;
} }
this.dummy.updateComplete.then( () => { _toggle()
let divs = this.dummy.shadowRoot.querySelector("ha-card").querySelector("#states");
let child = nextChild(divs)
this._addHeader(child, conf.shift())
while(child = nextChild(divs)) {
this._addRow(child, conf.shift());
}
this.update();
});
}
_addHeader(row, data)
{ {
this.$.head.insertBefore(row, this.$.head.firstChild); this._closed = !this._closed;
row.style.width = '100%';
if(row.tagName === 'DIV') {
row = row.children[0];
}
this.items.push(row);
if(row.tagName === 'HUI-SECTION-ROW'){
if(row.updateComplete) {
row.updateComplete.then( () => {
row.shadowRoot.querySelector('.divider').style.marginRight = '-53px';
if (!this.parentElement.previousElementSibling) {
row.shadowRoot.querySelector('.divider').style.visibility = 'hidden';
row.shadowRoot.querySelector('.divider').style.marginTop = '0';
} }
_renderElement(conf, options) {
conf = (typeof conf === "string") ? {entity: conf} : conf;
conf = Object.assign(conf, options);
const element = window.cardTools.createEntityRow(conf);
const DOMAINS_HIDE_MORE_INFO = [
"input_number",
"input_select",
"input_text",
"scene",
"weblink",
];
if (conf.entity && !DOMAINS_HIDE_MORE_INFO.includes(conf.entity.split(".")[0])) {
element.classList.add("state-card-dialog");
element.addEventListener("click", () => {
window.cardTools.moreInfo(conf.entity);
}); });
} else {
row.shadowRoot.querySelector('.divider').style.marginRight = '-53px';
if (!this.parentElement.previousElementSibling) {
row.shadowRoot.querySelector('.divider').style.visibility = 'hidden';
row.shadowRoot.querySelector('.divider').style.marginTop = '0';
} }
return element;
} }
}
} _renderHead(conf) {
_addRow(row, data) const element = this._renderElement(conf);
{
if(row.tagName === 'DIV') { // Stretch the line above section rows
this.items.push(row.children[0]); if (conf.type && conf.type === "section") {
} else { element.updateComplete.then(() => {
this.items.push(row); const divider = element.shadowRoot.querySelector(".divider");
} divider.style.marginRight = "-53px";
let item = document.createElement('ul');
item.appendChild(row);
row.classList.add('state-card-dialog');
row.addEventListener('click', (e) => {
let ev = new Event('hass-more-info', {
bubbles: true,
cancelable: false,
composed: true,
}); });
const entityId = data.entity; }
ev.detail = { entityId }; return element;
this.dispatchEvent(ev); }
e.stopPropagation();
}); _renderItem(conf, options) {
this.$.rows.appendChild(item); const element = this._renderElement(conf, options);
return window.cardTools.litHtml`<div> ${element} </div>`;
} }
setConfig(config) { setConfig(config) {
if (config.entity || config.config) {
throw new Error("Breaking changes have been introduced. Please see https://github.com/thomasloven/lovelace-fold-entity-row");
}
this._config = config; this._config = config;
this.closed = !this._config.open; this._closed = !config.open;
this.update();
this._head = this._renderHead(config.head);
const head = (typeof config.head === "string") ? config.head : config.head.entity;
if (head && head.split('.')[0] === "group")
config.items = window.cardTools.hass().states[head].attributes.entity_id;
this._entities = config.items.map((e) => this._renderItem(e, config.group_config));
} }
set hass(hass) { set hass(hass) {
this._hass = hass; this._hass = hass;
if(this.dummy) this._head.hass = hass;
this.dummy.hass = hass; this.shadowRoot.querySelectorAll("#items > div > *").forEach((e) => e.hass = hass);
if(this.items && this.items.forEach)
this.items.forEach( (c) => c.hass = hass);
} }
} }
customElements.define('fold-entity-row', FoldRow); customElements.define('fold-entity-row', FoldEntityRow);