diff --git a/src/panels/lovelace/cards/hui-grid-card.ts b/src/panels/lovelace/cards/hui-grid-card.ts index d4914780ce..bffbf1eada 100644 --- a/src/panels/lovelace/cards/hui-grid-card.ts +++ b/src/panels/lovelace/cards/hui-grid-card.ts @@ -2,10 +2,16 @@ import { css, CSSResult } from "lit-element"; import { computeCardSize } from "../common/compute-card-size"; import { HuiStackCard } from "./hui-stack-card"; import { GridCardConfig } from "./types"; +import { LovelaceCardEditor } from "../types"; const DEFAULT_COLUMNS = 3; class HuiGridCard extends HuiStackCard { + public static async getConfigElement(): Promise { + await import("../editor/config-elements/hui-grid-card-editor"); + return document.createElement("hui-grid-card-editor"); + } + public async getCardSize(): Promise { if (!this._cards || !this._config) { return 0; diff --git a/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts new file mode 100644 index 0000000000..0e4a62867b --- /dev/null +++ b/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts @@ -0,0 +1,98 @@ +import { customElement, html, TemplateResult } from "lit-element"; +import { + any, + array, + assert, + boolean, + number, + object, + optional, + string, +} from "superstruct"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import { computeRTLDirection } from "../../../../common/util/compute_rtl"; +import { GridCardConfig } from "../../cards/types"; +import { HuiStackCardEditor } from "./hui-stack-card-editor"; + +const cardConfigStruct = object({ + type: string(), + cards: array(any()), + title: optional(string()), + square: optional(boolean()), + columns: optional(number()), +}); + +@customElement("hui-grid-card-editor") +export class HuiGridCardEditor extends HuiStackCardEditor { + public setConfig(config: Readonly): void { + assert(config, cardConfigStruct); + this._config = config; + } + + protected render(): TemplateResult { + if (!this.hass || !this._config) { + return html``; + } + + return html` +
+
+ + + + +
+
+ ${super.render()} + `; + } + + private _handleColumnsChanged(ev): void { + if (!this._config) { + return; + } + + this._config = { + ...this._config, + columns: Number(ev.target.value), + }; + fireEvent(this, "config-changed", { config: this._config }); + } + + private _handleSquareChanged(ev): void { + if (!this._config) { + return; + } + + this._config = { + ...this._config, + square: ev.target.checked, + }; + fireEvent(this, "config-changed", { config: this._config }); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-grid-card-editor": HuiGridCardEditor; + } +} diff --git a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts index e5beba3c6b..b707e0f119 100644 --- a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts @@ -12,16 +12,7 @@ import { query, TemplateResult, } from "lit-element"; -import { - any, - array, - assert, - boolean, - number, - object, - optional, - string, -} from "superstruct"; +import { any, array, assert, object, optional, string } from "superstruct"; import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace"; import { HomeAssistant } from "../../../../types"; @@ -32,13 +23,12 @@ import type { HuiCardElementEditor } from "../card-editor/hui-card-element-edito import "../card-editor/hui-card-picker"; import type { ConfigChangedEvent } from "../hui-element-editor"; import { GUIModeChangedEvent } from "../types"; +import { configElementStyle } from "./config-elements-style"; const cardConfigStruct = object({ type: string(), cards: array(any()), title: optional(string()), - square: optional(boolean()), - columns: optional(number()), }); @customElement("hui-stack-card-editor") @@ -48,16 +38,16 @@ export class HuiStackCardEditor extends LitElement @property({ attribute: false }) public lovelace?: LovelaceConfig; - @internalProperty() private _config?: StackCardConfig; + @internalProperty() protected _config?: StackCardConfig; - @internalProperty() private _selectedCard = 0; + @internalProperty() protected _selectedCard = 0; - @internalProperty() private _GUImode = true; + @internalProperty() protected _GUImode = true; - @internalProperty() private _guiModeAvailable? = true; + @internalProperty() protected _guiModeAvailable? = true; @query("hui-card-element-editor") - private _cardEditorEl?: HuiCardElementEditor; + protected _cardEditorEl?: HuiCardElementEditor; public setConfig(config: Readonly): void { assert(config, cardConfigStruct); @@ -170,7 +160,7 @@ export class HuiStackCardEditor extends LitElement `; } - private _handleSelectedCard(ev) { + protected _handleSelectedCard(ev) { if (ev.target.id === "add-card") { this._selectedCard = this._config!.cards.length; return; @@ -180,7 +170,7 @@ export class HuiStackCardEditor extends LitElement this._selectedCard = parseInt(ev.detail.selected, 10); } - private _handleConfigChanged(ev: HASSDomEvent) { + protected _handleConfigChanged(ev: HASSDomEvent) { ev.stopPropagation(); if (!this._config) { return; @@ -192,7 +182,7 @@ export class HuiStackCardEditor extends LitElement fireEvent(this, "config-changed", { config: this._config }); } - private _handleCardPicked(ev) { + protected _handleCardPicked(ev) { ev.stopPropagation(); if (!this._config) { return; @@ -203,7 +193,7 @@ export class HuiStackCardEditor extends LitElement fireEvent(this, "config-changed", { config: this._config }); } - private _handleDeleteCard() { + protected _handleDeleteCard() { if (!this._config) { return; } @@ -214,7 +204,7 @@ export class HuiStackCardEditor extends LitElement fireEvent(this, "config-changed", { config: this._config }); } - private _handleMove(ev: Event) { + protected _handleMove(ev: Event) { if (!this._config) { return; } @@ -232,60 +222,63 @@ export class HuiStackCardEditor extends LitElement fireEvent(this, "config-changed", { config: this._config }); } - private _handleGUIModeChanged(ev: HASSDomEvent): void { + protected _handleGUIModeChanged(ev: HASSDomEvent): void { ev.stopPropagation(); this._GUImode = ev.detail.guiMode; this._guiModeAvailable = ev.detail.guiModeAvailable; } - private _toggleMode(): void { + protected _toggleMode(): void { this._cardEditorEl?.toggleMode(); } - private _setMode(value: boolean): void { + protected _setMode(value: boolean): void { this._GUImode = value; if (this._cardEditorEl) { this._cardEditorEl!.GUImode = value; } } - static get styles(): CSSResult { - return css` - .toolbar { - display: flex; - --paper-tabs-selection-bar-color: var(--primary-color); - --paper-tab-ink: var(--primary-color); - } - paper-tabs { - display: flex; - font-size: 14px; - flex-grow: 1; - } - #add-card { - max-width: 32px; - padding: 0; - } - - #card-options { - display: flex; - justify-content: flex-end; - width: 100%; - } - - #editor { - border: 1px solid var(--divider-color); - padding: 12px; - } - @media (max-width: 450px) { - #editor { - margin: 0 -12px; + static get styles(): CSSResult[] { + return [ + configElementStyle, + css` + .toolbar { + display: flex; + --paper-tabs-selection-bar-color: var(--primary-color); + --paper-tab-ink: var(--primary-color); + } + paper-tabs { + display: flex; + font-size: 14px; + flex-grow: 1; + } + #add-card { + max-width: 32px; + padding: 0; } - } - .gui-mode-button { - margin-right: auto; - } - `; + #card-options { + display: flex; + justify-content: flex-end; + width: 100%; + } + + #editor { + border: 1px solid var(--divider-color); + padding: 12px; + } + @media (max-width: 450px) { + #editor { + margin: 0 -12px; + } + } + + .gui-mode-button { + margin-right: auto; + } + `, + ]; } } diff --git a/src/translations/en.json b/src/translations/en.json index 6444a5d3a7..d4b29bdeb9 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2696,7 +2696,9 @@ }, "grid": { "name": "Grid", - "description": "The Grid card allows you to show multiple cards in a grid." + "description": "The Grid card allows you to show multiple cards in a grid.", + "columns": "Columns", + "square": "Render cards as squares" }, "logbook": { "name": "Logbook",