diff --git a/gallery/src/components/demo-card.js b/gallery/src/components/demo-card.js
index 04be1de04c..c6137fc9ed 100644
--- a/gallery/src/components/demo-card.js
+++ b/gallery/src/components/demo-card.js
@@ -15,6 +15,10 @@ class DemoCard extends PolymerElement {
margin: 0 0 20px;
color: var(--primary-color);
}
+ h2 small {
+ font-size: 0.5em;
+ color: var(--primary-text-color);
+ }
#card {
max-width: 400px;
width: 100vw;
@@ -34,7 +38,12 @@ class DemoCard extends PolymerElement {
}
}
-
[[config.heading]]
+
+ [[config.heading]]
+
+ (size [[_size]])
+
+
@@ -55,6 +64,9 @@ class DemoCard extends PolymerElement {
observer: "_configChanged",
},
showConfig: Boolean,
+ _size: {
+ type: Number,
+ },
};
}
@@ -70,6 +82,17 @@ class DemoCard extends PolymerElement {
const el = this._createCardElement(safeLoad(config.config)[0]);
card.appendChild(el);
+ this._getSize(el);
+ }
+
+ async _getSize(el) {
+ await customElements.whenDefined(el.localName);
+
+ if (!("getCardSize" in el)) {
+ this._size = undefined;
+ return;
+ }
+ this._size = await el.getCardSize();
}
_createCardElement(cardConfig) {
diff --git a/gallery/src/demos/demo-hui-stack-card.ts b/gallery/src/demos/demo-hui-grid-and-stack-card.ts
similarity index 75%
rename from gallery/src/demos/demo-hui-stack-card.ts
rename to gallery/src/demos/demo-hui-grid-and-stack-card.ts
index 26f03c4051..8beb16a20d 100644
--- a/gallery/src/demos/demo-hui-stack-card.ts
+++ b/gallery/src/demos/demo-hui-grid-and-stack-card.ts
@@ -49,6 +49,100 @@ const ENTITIES = [
];
const CONFIGS = [
+ {
+ heading: "Default Grid",
+ config: `
+- type: grid
+ cards:
+ - type: entity
+ entity: light.kitchen_lights
+ - type: entity
+ entity: light.bed_light
+ - type: entity
+ entity: device_tracker.demo_paulus
+ - type: sensor
+ entity: sensor.illumination
+ graph: line
+ - type: entity
+ entity: device_tracker.demo_anne_therese
+ `,
+ },
+ {
+ heading: "Non-square Grid with 2 columns",
+ config: `
+- type: grid
+ columns: 2
+ square: false
+ cards:
+ - type: entity
+ entity: light.kitchen_lights
+ - type: entity
+ entity: light.bed_light
+ - type: entity
+ entity: device_tracker.demo_paulus
+ - type: sensor
+ entity: sensor.illumination
+ graph: line
+ `,
+ },
+ {
+ heading: "Default Grid with title",
+ config: `
+- type: grid
+ title: Kitchen
+ cards:
+ - type: entity
+ entity: light.kitchen_lights
+ - type: entity
+ entity: light.bed_light
+ - type: entity
+ entity: device_tracker.demo_paulus
+ - type: sensor
+ entity: sensor.illumination
+ graph: line
+ - type: entity
+ entity: device_tracker.demo_anne_therese
+ `,
+ },
+ {
+ heading: "Columns 4",
+ config: `
+- type: grid
+ cards:
+ - type: entity
+ entity: light.kitchen_lights
+ - type: entity
+ entity: light.bed_light
+ - type: entity
+ entity: device_tracker.demo_paulus
+ - type: sensor
+ entity: sensor.illumination
+ graph: line
+ `,
+ },
+ {
+ heading: "Columns 2",
+ config: `
+- type: grid
+ columns: 2
+ cards:
+ - type: entity
+ entity: light.kitchen_lights
+ - type: entity
+ entity: light.bed_light
+ `,
+ },
+ {
+ heading: "Columns 1",
+ config: `
+- type: grid
+ columns: 1
+ cards:
+ - type: entity
+ entity: light.kitchen_lights
+ `,
+ },
+
{
heading: "Vertical Stack",
config: `
@@ -99,45 +193,9 @@ const CONFIGS = [
entity: light.bed_light
`,
},
- {
- heading: "Default Grid",
- config: `
-- type: grid
- cards:
- - type: entity
- entity: light.kitchen_lights
- - type: entity
- entity: light.bed_light
- - type: entity
- entity: device_tracker.demo_paulus
- - type: sensor
- entity: sensor.illumination
- graph: line
- - type: entity
- entity: device_tracker.demo_anne_therese
- `,
- },
- {
- heading: "Non-square Grid with 2 columns",
- config: `
-- type: grid
- columns: 2
- square: false
- cards:
- - type: entity
- entity: light.kitchen_lights
- - type: entity
- entity: light.bed_light
- - type: entity
- entity: device_tracker.demo_paulus
- - type: sensor
- entity: sensor.illumination
- graph: line
- `,
- },
];
-@customElement("demo-hui-stack-card")
+@customElement("demo-hui-grid-and-stack-card")
class DemoStack extends LitElement {
@query("#demos") private _demoRoot!: HTMLElement;
@@ -155,4 +213,8 @@ class DemoStack extends LitElement {
}
}
-customElements.define("demo-hui-stack-card", DemoStack);
+declare global {
+ interface HTMLElementTagNameMap {
+ "demo-hui-grid-and-stack-card": DemoStack;
+ }
+}
diff --git a/src/panels/lovelace/cards/hui-grid-card.ts b/src/panels/lovelace/cards/hui-grid-card.ts
index bffbf1eada..256d889a12 100644
--- a/src/panels/lovelace/cards/hui-grid-card.ts
+++ b/src/panels/lovelace/cards/hui-grid-card.ts
@@ -5,6 +5,11 @@ import { GridCardConfig } from "./types";
import { LovelaceCardEditor } from "../types";
const DEFAULT_COLUMNS = 3;
+const SQUARE_ROW_HEIGHTS_BY_COLUMNS = {
+ 1: 5,
+ 2: 3,
+ 3: 2,
+};
class HuiGridCard extends HuiStackCard {
public static async getConfigElement(): Promise {
@@ -18,8 +23,11 @@ class HuiGridCard extends HuiStackCard {
}
if (this.square) {
- // When we're square, each row is size 2.
- return (this._cards.length / this.columns) * 2;
+ const rowHeight = SQUARE_ROW_HEIGHTS_BY_COLUMNS[this.columns] || 1;
+ return (
+ (this._cards.length / this.columns) * rowHeight +
+ (this._config.title ? 1 : 0)
+ );
}
const promises: Array | number> = [];
@@ -28,11 +36,16 @@ class HuiGridCard extends HuiStackCard {
promises.push(computeCardSize(element));
}
- const results = await Promise.all(promises);
+ const cardSizes = await Promise.all(promises);
- const maxCardSize = Math.max(...results);
+ let totalHeight = this._config.title ? 1 : 0;
- return maxCardSize * (this._cards.length / this.columns);
+ // Each column will adjust to max card size of it's row
+ for (let start = 0; start < cardSizes.length; start += this.columns) {
+ totalHeight += Math.max(...cardSizes.slice(start, start + this.columns));
+ }
+
+ return totalHeight;
}
get columns() {
diff --git a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts
index f13f90b9f6..c5e028379d 100644
--- a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts
+++ b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts
@@ -104,7 +104,7 @@ export class HuiGraphHeaderFooter extends LitElement
if (!this._coordinates) {
return html`
-
+
`;
}
@@ -210,7 +210,7 @@ export class HuiGraphHeaderFooter extends LitElement
return css`
ha-circular-progress {
position: absolute;
- top: calc(50% - 28px);
+ top: calc(50% - 14px);
}
.container {
display: flex;