Add Grid card (#7476)

This commit is contained in:
Paulus Schoutsen 2020-10-29 10:31:14 +01:00 committed by GitHub
parent d63493a859
commit c3718ff7dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 250 additions and 185 deletions

View File

@ -7,8 +7,8 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
cards: [
{ type: "custom:ha-demo-card" },
{
cards: [
{
type: "grid",
columns: 4,
cards: [
{
image: "/assets/teachingbirds/isa_square.jpg",
@ -77,11 +77,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
],
type: "picture-elements",
},
],
type: "horizontal-stack",
},
{
cards: [
{
show_name: false,
type: "picture-entity",
@ -104,8 +100,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
type: "picture-entity",
state_image: {
Mail: "/assets/teachingbirds/mailbox_square.jpg",
"Package and mail":
"/assets/teachingbirds/mailbox_square.jpg",
"Package and mail": "/assets/teachingbirds/mailbox_square.jpg",
Empty: "/assets/teachingbirds/mailbox_bw_square.jpg",
Package: "/assets/teachingbirds/mailbox_square.jpg",
},
@ -121,11 +116,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
image: "/assets/teachingbirds/trash_bear_bw_square.jpg",
entity: "sensor.trash_status",
},
],
type: "horizontal-stack",
},
{
cards: [
{
state_image: {
Idle: "/assets/teachingbirds/washer_square.jpg",
@ -167,15 +158,10 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
entity: "input_boolean.cleaning_day",
},
],
type: "horizontal-stack",
},
],
type: "vertical-stack",
},
{
type: "vertical-stack",
cards: [
{
type: "grid",
columns: 2,
cards: [
{
graph: "line",
@ -188,11 +174,6 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
name: "S's room",
entity: "sensor.temperature_stefan",
},
],
type: "horizontal-stack",
},
{
cards: [
{
graph: "line",
type: "sensor",
@ -205,9 +186,6 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
entity: "sensor.temperature_downstairs_bathroom",
},
],
type: "horizontal-stack",
},
],
},
{
entities: [

View File

@ -0,0 +1,75 @@
import { css, CSSResult } from "lit-element";
import { computeCardSize } from "../common/compute-card-size";
import { HuiStackCard } from "./hui-stack-card";
import { GridCardConfig } from "./types";
const DEFAULT_COLUMNS = 3;
class HuiGridCard extends HuiStackCard<GridCardConfig> {
public async getCardSize(): Promise<number> {
if (!this._cards || !this._config) {
return 0;
}
const promises: Array<Promise<number> | number> = [];
for (const element of this._cards) {
promises.push(computeCardSize(element));
}
const results = await Promise.all(promises);
const maxCardSize = Math.max(...results);
return maxCardSize * (this._cards.length / this.columns);
}
get columns() {
return this._config!.columns || DEFAULT_COLUMNS;
}
setConfig(config: GridCardConfig) {
super.setConfig(config);
this.style.setProperty("--grid-card-column-count", String(this.columns));
this.toggleAttribute("square", config.square !== false);
}
static get styles(): CSSResult[] {
return [
super.sharedStyles,
css`
#root {
display: grid;
grid-template-columns: repeat(
var(--grid-card-column-count, ${DEFAULT_COLUMNS}),
minmax(0, 1fr)
);
grid-gap: var(--grid-card-gap, 8px);
}
:host([square]) #root {
grid-auto-rows: 1fr;
}
:host([square]) #root::before {
content: "";
width: 0;
padding-bottom: 100%;
grid-row: 1 / 1;
grid-column: 1 / 1;
}
:host([square]) #root > *:first-child {
grid-row: 1 / 1;
grid-column: 1 / 1;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-grid-card": HuiGridCard;
}
}
customElements.define("hui-grid-card", HuiGridCard);

View File

@ -14,7 +14,9 @@ import { createCardElement } from "../create-element/create-card-element";
import { LovelaceCard, LovelaceCardEditor } from "../types";
import { StackCardConfig } from "./types";
export abstract class HuiStackCard extends LitElement implements LovelaceCard {
export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
extends LitElement
implements LovelaceCard {
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import(
/* webpackChunkName: "hui-stack-card-editor" */ "../editor/config-elements/hui-stack-card-editor"
@ -32,13 +34,13 @@ export abstract class HuiStackCard extends LitElement implements LovelaceCard {
@property() protected _cards?: LovelaceCard[];
@internalProperty() private _config?: StackCardConfig;
@internalProperty() protected _config?: T;
public getCardSize(): number | Promise<number> {
return 1;
}
public setConfig(config: StackCardConfig): void {
public setConfig(config: T): void {
if (!config || !config.cards || !Array.isArray(config.cards)) {
throw new Error("Card config incorrect");
}

View File

@ -288,6 +288,11 @@ export interface StackCardConfig extends LovelaceCardConfig {
title?: string;
}
export interface GridCardConfig extends StackCardConfig {
columns?: number;
square?: boolean;
}
export interface ThermostatCardConfig extends LovelaceCardConfig {
entity: string;
theme?: string;

View File

@ -37,6 +37,7 @@ const LAZY_LOAD_TYPES = {
"alarm-panel": () => import("../cards/hui-alarm-panel-card"),
error: () => import("../cards/hui-error-card"),
"empty-state": () => import("../cards/hui-empty-state-card"),
grid: () => import("../cards/hui-grid-card"),
starting: () => import("../cards/hui-starting-card"),
"entity-filter": () => import("../cards/hui-entity-filter-card"),
humidifier: () => import("../cards/hui-humidifier-card"),

View File

@ -29,6 +29,10 @@ export const coreCards: Card[] = [
type: "glance",
showElement: true,
},
{
type: "grid",
showElement: true,
},
{
type: "history-graph",
showElement: true,