Add "columns" and "square" to grid card editor (#7888)

This commit is contained in:
Philip Allgaier 2021-01-16 16:25:13 +01:00 committed by GitHub
parent 40f4c35b42
commit 84a9ca59ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 160 additions and 61 deletions

View File

@ -2,10 +2,16 @@ import { css, CSSResult } from "lit-element";
import { computeCardSize } from "../common/compute-card-size"; import { computeCardSize } from "../common/compute-card-size";
import { HuiStackCard } from "./hui-stack-card"; import { HuiStackCard } from "./hui-stack-card";
import { GridCardConfig } from "./types"; import { GridCardConfig } from "./types";
import { LovelaceCardEditor } from "../types";
const DEFAULT_COLUMNS = 3; const DEFAULT_COLUMNS = 3;
class HuiGridCard extends HuiStackCard<GridCardConfig> { class HuiGridCard extends HuiStackCard<GridCardConfig> {
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import("../editor/config-elements/hui-grid-card-editor");
return document.createElement("hui-grid-card-editor");
}
public async getCardSize(): Promise<number> { public async getCardSize(): Promise<number> {
if (!this._cards || !this._config) { if (!this._cards || !this._config) {
return 0; return 0;

View File

@ -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<GridCardConfig>): void {
assert(config, cardConfigStruct);
this._config = config;
}
protected render(): TemplateResult {
if (!this.hass || !this._config) {
return html``;
}
return html`
<div class="card-config">
<div class="side-by-side">
<paper-input
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.grid.columns"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
type="number"
.value=${(this._config as GridCardConfig).columns}
.configValue=${"columns"}
@value-changed=${this._handleColumnsChanged}
></paper-input>
<ha-formfield
.label=${this.hass.localize(
"ui.panel.lovelace.editor.card.grid.square"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-switch
.checked=${(this._config as GridCardConfig).square}
.configValue=${"square"}
@change=${this._handleSquareChanged}
></ha-switch>
</ha-formfield>
</div>
</div>
${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;
}
}

View File

@ -12,16 +12,7 @@ import {
query, query,
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import { import { any, array, assert, object, optional, string } from "superstruct";
any,
array,
assert,
boolean,
number,
object,
optional,
string,
} from "superstruct";
import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace"; import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types"; 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 "../card-editor/hui-card-picker";
import type { ConfigChangedEvent } from "../hui-element-editor"; import type { ConfigChangedEvent } from "../hui-element-editor";
import { GUIModeChangedEvent } from "../types"; import { GUIModeChangedEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({ const cardConfigStruct = object({
type: string(), type: string(),
cards: array(any()), cards: array(any()),
title: optional(string()), title: optional(string()),
square: optional(boolean()),
columns: optional(number()),
}); });
@customElement("hui-stack-card-editor") @customElement("hui-stack-card-editor")
@ -48,16 +38,16 @@ export class HuiStackCardEditor extends LitElement
@property({ attribute: false }) public lovelace?: LovelaceConfig; @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") @query("hui-card-element-editor")
private _cardEditorEl?: HuiCardElementEditor; protected _cardEditorEl?: HuiCardElementEditor;
public setConfig(config: Readonly<StackCardConfig>): void { public setConfig(config: Readonly<StackCardConfig>): void {
assert(config, cardConfigStruct); assert(config, cardConfigStruct);
@ -170,7 +160,7 @@ export class HuiStackCardEditor extends LitElement
`; `;
} }
private _handleSelectedCard(ev) { protected _handleSelectedCard(ev) {
if (ev.target.id === "add-card") { if (ev.target.id === "add-card") {
this._selectedCard = this._config!.cards.length; this._selectedCard = this._config!.cards.length;
return; return;
@ -180,7 +170,7 @@ export class HuiStackCardEditor extends LitElement
this._selectedCard = parseInt(ev.detail.selected, 10); this._selectedCard = parseInt(ev.detail.selected, 10);
} }
private _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) { protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
ev.stopPropagation(); ev.stopPropagation();
if (!this._config) { if (!this._config) {
return; return;
@ -192,7 +182,7 @@ export class HuiStackCardEditor extends LitElement
fireEvent(this, "config-changed", { config: this._config }); fireEvent(this, "config-changed", { config: this._config });
} }
private _handleCardPicked(ev) { protected _handleCardPicked(ev) {
ev.stopPropagation(); ev.stopPropagation();
if (!this._config) { if (!this._config) {
return; return;
@ -203,7 +193,7 @@ export class HuiStackCardEditor extends LitElement
fireEvent(this, "config-changed", { config: this._config }); fireEvent(this, "config-changed", { config: this._config });
} }
private _handleDeleteCard() { protected _handleDeleteCard() {
if (!this._config) { if (!this._config) {
return; return;
} }
@ -214,7 +204,7 @@ export class HuiStackCardEditor extends LitElement
fireEvent(this, "config-changed", { config: this._config }); fireEvent(this, "config-changed", { config: this._config });
} }
private _handleMove(ev: Event) { protected _handleMove(ev: Event) {
if (!this._config) { if (!this._config) {
return; return;
} }
@ -232,60 +222,63 @@ export class HuiStackCardEditor extends LitElement
fireEvent(this, "config-changed", { config: this._config }); fireEvent(this, "config-changed", { config: this._config });
} }
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void { protected _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
ev.stopPropagation(); ev.stopPropagation();
this._GUImode = ev.detail.guiMode; this._GUImode = ev.detail.guiMode;
this._guiModeAvailable = ev.detail.guiModeAvailable; this._guiModeAvailable = ev.detail.guiModeAvailable;
} }
private _toggleMode(): void { protected _toggleMode(): void {
this._cardEditorEl?.toggleMode(); this._cardEditorEl?.toggleMode();
} }
private _setMode(value: boolean): void { protected _setMode(value: boolean): void {
this._GUImode = value; this._GUImode = value;
if (this._cardEditorEl) { if (this._cardEditorEl) {
this._cardEditorEl!.GUImode = value; this._cardEditorEl!.GUImode = value;
} }
} }
static get styles(): CSSResult { static get styles(): CSSResult[] {
return css` return [
.toolbar { configElementStyle,
display: flex; css`
--paper-tabs-selection-bar-color: var(--primary-color); .toolbar {
--paper-tab-ink: var(--primary-color); display: flex;
} --paper-tabs-selection-bar-color: var(--primary-color);
paper-tabs { --paper-tab-ink: var(--primary-color);
display: flex; }
font-size: 14px; paper-tabs {
flex-grow: 1; display: flex;
} font-size: 14px;
#add-card { flex-grow: 1;
max-width: 32px; }
padding: 0; #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;
} }
}
.gui-mode-button { #card-options {
margin-right: auto; 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;
}
`,
];
} }
} }

View File

@ -2696,7 +2696,9 @@
}, },
"grid": { "grid": {
"name": "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": { "logbook": {
"name": "Logbook", "name": "Logbook",