From 05813f3a00c208c40a4152240bc552876de23b2e Mon Sep 17 00:00:00 2001 From: Ofek Ashery Date: Sun, 3 Jan 2021 19:12:04 +0200 Subject: [PATCH] Fix card size issues Closes #96 #80 --- LICENSE | 2 +- VERSION | 2 +- vertical-stack-in-card.js | 93 ++++++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 43 deletions(-) diff --git a/LICENSE b/LICENSE index cde38ca..29c3e99 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Ofek Ashery +Copyright (c) 2021 Ofek Ashery Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/VERSION b/VERSION index 1c09c74..1d0ba9e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.3 +0.4.0 diff --git a/vertical-stack-in-card.js b/vertical-stack-in-card.js index 4b7fe23..f220c2d 100644 --- a/vertical-stack-in-card.js +++ b/vertical-stack-in-card.js @@ -1,57 +1,60 @@ -const vsinVersion = '0.3.3'; -console.log(`%cvertical-stack-in-card\n%cVersion: ${vsinVersion}`, 'color: #1976d2; font-weight: bold;', ''); +console.log(`%cvertical-stack-in-card\n%cVersion: ${'0.4.0'}`, 'color: #1976d2; font-weight: bold;', ''); class VerticalStackInCard extends HTMLElement { constructor() { super(); } - async setConfig(config) { + setConfig(config) { + this._cardSize = {}; + this._cardSize.promise = new Promise((resolve) => (this._cardSize.resolve = resolve)); + if (!config || !config.cards || !Array.isArray(config.cards)) { throw new Error('Card config incorrect'); } this._config = config; this._refCards = []; - - if (window.loadCardHelpers) { - this.helpers = await window.loadCardHelpers(); - } - this.renderCard(); } - renderCard() { + async renderCard() { const config = this._config; + if (window.loadCardHelpers) { + this.helpers = await window.loadCardHelpers(); + } const promises = config.cards.map((config) => this.createCardElement(config)); - Promise.all(promises).then((cards) => { - cards.forEach((card) => { - if (card.updateComplete) { - card.updateComplete.then(() => this.styleCard(card)); - } else { - this.styleCard(card); - } - }); + this._refCards = await Promise.all(promises); - this._refCards = cards; - const card = document.createElement('ha-card'); - const cardContent = document.createElement('div'); - card.header = config.title; - card.style.overflow = 'hidden'; - cards.forEach((card) => cardContent.appendChild(card)); - if (config.horizontal) { - cardContent.style.display = 'flex'; - cardContent.childNodes.forEach((card) => { - card.style.flex = '1 1 0'; - card.style.minWidth = 0; - }); - } - card.appendChild(cardContent); - - while (this.hasChildNodes()) { - this.removeChild(this.lastChild); + // Style cards + this._refCards.forEach((card) => { + if (card.updateComplete) { + card.updateComplete.then(() => this.styleCard(card)); + } else { + this.styleCard(card); } - this.appendChild(card); }); + + // Create the card + const card = document.createElement('ha-card'); + const cardContent = document.createElement('div'); + card.header = config.title; + card.style.overflow = 'hidden'; + this._refCards.forEach((card) => cardContent.appendChild(card)); + if (config.horizontal) { + cardContent.style.display = 'flex'; + cardContent.childNodes.forEach((card) => { + card.style.flex = '1 1 0'; + card.style.minWidth = 0; + }); + } + card.appendChild(cardContent); + while (this.hasChildNodes()) { + this.removeChild(this.lastChild); + } + this.appendChild(card); + + // Calculate card size + this._cardSize.resolve(); } async createCardElement(cardConfig) { @@ -151,12 +154,20 @@ class VerticalStackInCard extends HTMLElement { } } - getCardSize() { - let totalSize = 0; - this._refCards.forEach((element) => { - totalSize += typeof element.getCardSize === 'function' ? element.getCardSize() : 1; - }); - return totalSize; + _computeCardSize(card) { + if (typeof card.getCardSize === 'function') { + return card.getCardSize(); + } + return customElements + .whenDefined(card.localName) + .then(() => this._computeCardSize(card)) + .catch(() => 1); + } + + async getCardSize() { + await this._cardSize.promise; + const sizes = await Promise.all(this._refCards.map(this._computeCardSize)); + return sizes.reduce((a, b) => a + b); } }