Create card editor

This commit is contained in:
Paul Bottein 2024-08-21 16:14:10 +02:00
parent bde2fd8202
commit 36540aa8fb
No known key found for this signature in database
2 changed files with 139 additions and 10 deletions

View File

@ -0,0 +1,131 @@
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { LovelaceConfig } from "../../../../data/lovelace/config/types";
import { HomeAssistant } from "../../../../types";
import "./hui-card-element-editor";
import "./hui-card-layout-editor";
import "./hui-card-visibility-editor";
import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
import type { HuiCardElementEditor } from "./hui-card-element-editor";
import { fireEvent } from "../../../../common/dom/fire_event";
const TABS = ["config", "visibility", "layout"] as const;
@customElement("hui-card-editor")
class HuiCardEditor extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public lovelace!: LovelaceConfig;
@property({ attribute: false }) public config!: LovelaceCardConfig;
@property({ type: Boolean, attribute: "show-visibility-tab" })
public showVisibilityTab = false;
@property({ type: Boolean, attribute: "show-layout-tab" })
public showLayoutTab = false;
@query("hui-card-element-editor")
public elementEditor?: HuiCardElementEditor;
@state() private _selectedTab: (typeof TABS)[number] = TABS[0];
private _tabs = memoizeOne((showLayoutTab: boolean, cardType: string) =>
TABS.filter((tab) => {
if (tab === "visibility") return cardType !== "conditional";
if (tab === "layout") return showLayoutTab;
return true;
})
);
private renderContent() {
if (this._selectedTab === "config") {
return html`
<hui-card-element-editor
.hass=${this.hass}
.lovelace=${this.lovelace}
.value=${this.config}
></hui-card-element-editor>
`;
}
if (this._selectedTab === "visibility") {
return html`
<hui-card-visibility-editor
.hass=${this.hass}
.config=${this.config}
@value-changed=${this._configChanged}
></hui-card-visibility-editor>
`;
}
if (this._selectedTab === "layout") {
return html`
<hui-card-layout-editor
.hass=${this.hass}
.config=${this.config}
@value-changed=${this._configChanged}
>
</hui-card-layout-editor>
`;
}
return nothing;
}
private _configChanged(ev: CustomEvent): void {
ev.stopPropagation();
fireEvent(this, "config-changed", { config: ev.detail.value });
}
protected render() {
const cardType = this.config.type;
const tabs = this._tabs(this.showLayoutTab, cardType);
if (tabs.length <= 1) {
return this.renderContent();
}
return html`
<mwc-tab-bar
.activeIndex=${tabs.indexOf(this._selectedTab)}
@MDCTabBar:activated=${this._handleTabChanged}
>
${tabs.map(
(tab) => html`
<mwc-tab
.label=${this.hass.localize(
`ui.panel.lovelace.editor.edit_card.tab_${tab}`
)}
>
</mwc-tab>
`
)}
</mwc-tab-bar>
${this.renderContent()}
`;
}
private _handleTabChanged(ev: CustomEvent): void {
const cardType = this.config.type;
const tabs = this._tabs(this.showLayoutTab, cardType);
const newTab = tabs[ev.detail.index];
if (newTab === this._selectedTab) {
return;
}
this._selectedTab = newTab;
}
static get styles(): CSSResultGroup {
return css`
mwc-tab-bar {
text-transform: uppercase;
margin-bottom: 16px;
border-bottom: 1px solid var(--divider-color);
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-card-editor": HuiCardEditor;
}
}

View File

@ -37,7 +37,7 @@ import { getCardDocumentationURL } from "../get-dashboard-documentation-url";
import type { ConfigChangedEvent } from "../hui-element-editor"; import type { ConfigChangedEvent } from "../hui-element-editor";
import { findLovelaceContainer } from "../lovelace-path"; import { findLovelaceContainer } from "../lovelace-path";
import type { GUIModeChangedEvent } from "../types"; import type { GUIModeChangedEvent } from "../types";
import "./hui-card-element-editor"; import "./hui-card-editor";
import type { HuiCardElementEditor } from "./hui-card-element-editor"; import type { HuiCardElementEditor } from "./hui-card-element-editor";
import type { EditCardDialogParams } from "./show-edit-card-dialog"; import type { EditCardDialogParams } from "./show-edit-card-dialog";
@ -75,7 +75,7 @@ export class HuiDialogEditCard
@state() private _guiModeAvailable? = true; @state() private _guiModeAvailable? = true;
@query("hui-card-element-editor") @query("hui-card-editor")
private _cardEditorEl?: HuiCardElementEditor; private _cardEditorEl?: HuiCardElementEditor;
@state() private _GUImode = true; @state() private _GUImode = true;
@ -235,19 +235,17 @@ export class HuiDialogEditCard
</ha-dialog-header> </ha-dialog-header>
<div class="content"> <div class="content">
<div class="element-editor"> <div class="element-editor">
<hui-card-element-editor <hui-card-editor
.showVisibilityTab=${this._cardConfig?.type !== "conditional"} .containerConfig=${this._containerConfig}
.sectionConfig=${this._isInSection
? this._containerConfig
: undefined}
.hass=${this.hass} .hass=${this.hass}
.lovelace=${this._params.lovelaceConfig} .lovelace=${this._params.lovelaceConfig}
.value=${this._cardConfig} .config=${this._cardConfig}
@config-changed=${this._handleConfigChanged} @config-changed=${this._handleConfigChanged}
@GUImode-changed=${this._handleGUIModeChanged} @GUImode-changed=${this._handleGUIModeChanged}
@editor-save=${this._save} @editor-save=${this._save}
dialogInitialFocus dialogInitialFocus
></hui-card-element-editor> >
</hui-card-editor>
</div> </div>
<div class="element-preview"> <div class="element-preview">
${this._isInSection ${this._isInSection
@ -348,7 +346,7 @@ export class HuiDialogEditCard
private _opened() { private _opened() {
window.addEventListener("dialog-closed", this._enableEscapeKeyClose); window.addEventListener("dialog-closed", this._enableEscapeKeyClose);
window.addEventListener("hass-more-info", this._disableEscapeKeyClose); window.addEventListener("hass-more-info", this._disableEscapeKeyClose);
this._cardEditorEl?.focusYamlEditor(); // this._cardEditorEl?.focusYamlEditor();
} }
private get _isInSection() { private get _isInSection() {