Compare commits

...

4 Commits

Author SHA1 Message Date
Thomas Lovén
aecbfeaaa0 Force editor rebuild on stack card switch 2022-05-31 11:39:56 +00:00
Thomas Lovén
498732566e Highlight cards in stacks 2022-05-31 11:18:37 +00:00
Thomas Lovén
b22c51bc2c Highlight entities card rows 2022-05-31 11:16:02 +00:00
Thomas Lovén
5bc2fd059c Allow data passed from editor to preview 2022-05-31 11:13:41 +00:00
8 changed files with 115 additions and 13 deletions

View File

@@ -6,7 +6,8 @@ import {
PropertyValues,
TemplateResult,
} from "lit";
import { customElement, state } from "lit/decorators";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { DOMAINS_TOGGLE } from "../../../common/const";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { computeDomain } from "../../../common/entity/compute_domain";
@@ -54,6 +55,8 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
return { type: "entities", entities: foundEntities };
}
@property() public editMode?: boolean | any;
@state() private _config?: EntitiesCardConfig;
private _hass?: HomeAssistant;
@@ -217,9 +220,15 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
`}
</h1>
`}
<div id="states" class="card-content">
${this._configEntities!.map((entityConf) =>
this.renderEntity(entityConf)
<div
id="states"
class=${classMap({
"card-content": true,
highlight: this.editMode?.selectedRow !== undefined,
})}
>
${this._configEntities!.map((entityConf, idx) =>
this.renderEntity(entityConf, idx)
)}
</div>
@@ -272,6 +281,12 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
#states > div {
position: relative;
}
#states.highlight > div.selected {
opacity: 1;
}
#states.highlight > div {
opacity: 0.5;
}
.icon {
padding: 0px 18px 0px 8px;
@@ -293,7 +308,10 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
`;
}
private renderEntity(entityConf: LovelaceRowConfig): TemplateResult {
private renderEntity(
entityConf: LovelaceRowConfig,
idx: number
): TemplateResult {
const element = createRowElement(
(!("type" in entityConf) || entityConf.type === "conditional") &&
this._config!.state_color
@@ -307,7 +325,13 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
element.hass = this._hass;
}
return html`<div>${element}</div>`;
return html`<div
class=${classMap({
selected: this.editMode?.selectedRow === idx,
})}
>
${element}
</div>`;
}
}

View File

@@ -7,6 +7,7 @@ import {
TemplateResult,
} from "lit";
import { property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { LovelaceCardConfig } from "../../../data/lovelace";
import { HomeAssistant } from "../../../types";
import { createCardElement } from "../create-element/create-card-element";
@@ -28,7 +29,7 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
@property({ attribute: false }) public hass?: HomeAssistant;
@property() public editMode?: boolean;
@property() public editMode?: any;
@property() protected _cards?: LovelaceCard[];
@@ -43,8 +44,16 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
throw new Error("Invalid configuration");
}
this._config = config;
this._cards = config.cards.map((card) => {
this._cards = config.cards.map((card, idx) => {
const element = this._createCardElement(card) as LovelaceCard;
if (this.editMode !== undefined) {
if (this.editMode?.selected === idx) {
element.classList.add("selected");
element.editMode = this.editMode.data;
} else {
element.editMode = true;
}
}
return element;
});
}
@@ -58,12 +67,18 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
return;
}
for (const element of this._cards) {
for (const [idx, element] of this._cards.entries()) {
if (this.hass) {
element.hass = this.hass;
}
if (this.editMode !== undefined) {
element.editMode = this.editMode;
if (this.editMode.selected === idx) {
element.editMode = this.editMode.data ?? true;
element.classList.add("selected");
} else {
element.editMode = true;
element.classList.remove("selected");
}
}
}
}
@@ -77,7 +92,12 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
${this._config.title
? html`<h1 class="card-header">${this._config.title}</h1>`
: ""}
<div id="root">${this._cards}</div>
<div
id="root"
class=${classMap({ highlight: this.editMode?.selected !== undefined })}
>
${this._cards}
</div>
`;
}
@@ -95,6 +115,12 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
display: block;
padding: 24px 16px 16px;
}
#root.highlight > *.selected {
opacity: 1;
}
#root.highlight > * {
opacity: 0.5;
}
`;
}

View File

@@ -12,6 +12,8 @@ export class HuiCardPreview extends ReactiveElement {
@property() public config?: LovelaceCardConfig;
@property() public editMode = true;
private _element?: LovelaceCard;
private get _error() {
@@ -81,6 +83,9 @@ export class HuiCardPreview extends ReactiveElement {
this._element.hass = this.hass;
}
}
if (changedProperties.has("editMode")) {
this._element!.editMode = this.editMode;
}
}
private _createCard(configValue: LovelaceCardConfig): void {
@@ -90,6 +95,7 @@ export class HuiCardPreview extends ReactiveElement {
if (this.hass) {
this._element!.hass = this.hass;
}
this._element!.editMode = this.editMode;
this.appendChild(this._element!);
}

View File

@@ -43,6 +43,13 @@ declare global {
interface HTMLElementEventMap {
"reload-lovelace": HASSDomEvent<undefined>;
}
interface HASSDomEvents {
"edit-mode-changed": any;
}
interface HTMLElementEventMap {
"edit-mode-changed": HASSDomEvent<any>;
}
}
@customElement("hui-dialog-edit-card")
@@ -77,10 +84,13 @@ export class HuiDialogEditCard
@state() private _isEscapeEnabled = true;
@state() private _editMode = true;
public async showDialog(params: EditCardDialogParams): Promise<void> {
this._params = params;
this._GUImode = true;
this._guiModeAvailable = true;
this._editMode = true;
const [view, card] = params.path;
this._viewConfig = params.lovelaceConfig.views[view];
this._cardConfig =
@@ -205,6 +215,7 @@ export class HuiDialogEditCard
.lovelace=${this._params.lovelaceConfig}
.value=${this._cardConfig}
@config-changed=${this._handleConfigChanged}
@edit-mode-changed=${this._handleEditModeChanged}
@GUImode-changed=${this._handleGUIModeChanged}
@editor-save=${this._save}
dialogInitialFocus
@@ -214,6 +225,7 @@ export class HuiDialogEditCard
<hui-card-preview
.hass=${this.hass}
.config=${this._cardConfig}
.editMode=${this._editMode}
class=${this._error ? "blur" : ""}
></hui-card-preview>
${this._error
@@ -284,6 +296,10 @@ export class HuiDialogEditCard
this._dirty = true;
}
private _handleEditModeChanged(ev: HASSDomEvent<any>) {
this._editMode = ev.detail ?? true;
}
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
ev.stopPropagation();
this._GUImode = ev.detail.guiMode;

View File

@@ -408,10 +408,15 @@ export class HuiEntitiesCardEditor
private _editDetailElement(ev: HASSDomEvent<EditSubElementEvent>): void {
this._subElementEditorConfig = ev.detail.subElementConfig;
fireEvent(this, "edit-mode-changed", {
selectedRow: ev.detail.subElementConfig?.index,
});
}
private _goBack(): void {
this._subElementEditorConfig = undefined;
fireEvent(this, "edit-mode-changed", true);
}
static get styles(): CSSResultGroup {

View File

@@ -144,6 +144,7 @@ export class HuiStackCardEditor
.lovelace=${this.lovelace}
@config-changed=${this._handleConfigChanged}
@GUImode-changed=${this._handleGUIModeChanged}
@edit-mode-changed=${this._handleEditModeChanged}
></hui-card-element-editor>
`
: html`
@@ -166,6 +167,9 @@ export class HuiStackCardEditor
this._setMode(true);
this._guiModeAvailable = true;
this._selectedCard = parseInt(ev.detail.selected, 10);
if (this._cardEditorEl) {
this._cardEditorEl.forceRebuild = true;
}
}
protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
@@ -226,6 +230,14 @@ export class HuiStackCardEditor
this._guiModeAvailable = ev.detail.guiModeAvailable;
}
protected _handleEditModeChanged(ev: HASSDomEvent<any>) {
ev.stopPropagation();
fireEvent(this, "edit-mode-changed", {
selected: this._selectedCard,
data: ev.detail,
});
}
protected _toggleMode(): void {
this._cardEditorEl?.toggleMode();
}
@@ -237,6 +249,13 @@ export class HuiStackCardEditor
}
}
protected updated(changedProperties) {
if (changedProperties.has("_selectedCard"))
fireEvent(this, "edit-mode-changed", {
selected: this._selectedCard,
});
}
static get styles(): CSSResultGroup {
return [
configElementStyle,

View File

@@ -53,6 +53,8 @@ export abstract class HuiElementEditor<T> extends LitElement {
@property({ attribute: false }) public lovelace?: LovelaceConfig;
public forceRebuild = false;
@state() private _yaml?: string;
@state() private _config?: T;
@@ -292,7 +294,11 @@ export abstract class HuiElementEditor<T> extends LitElement {
this._errors = undefined;
this._warnings = undefined;
if (this._configElementType !== this.configElementType) {
if (
this._configElementType !== this.configElementType ||
this.forceRebuild
) {
this.forceRebuild = false;
// If the type has changed, we need to load a new GUI editor
this._guiSupported = undefined;
this._configElement = undefined;

View File

@@ -38,7 +38,7 @@ export interface LovelaceBadge extends HTMLElement {
export interface LovelaceCard extends HTMLElement {
hass?: HomeAssistant;
isPanel?: boolean;
editMode?: boolean;
editMode?: any;
getCardSize(): number | Promise<number>;
setConfig(config: LovelaceCardConfig): void;
}