From da12233ade8045b98743d821b7e60c0ca9f87f11 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 2 Nov 2020 10:46:52 +0100 Subject: [PATCH] Add dark mode toggle to gallery cards (#7532) --- gallery/src/components/demo-cards.js | 35 +++++++-- gallery/src/components/demo-more-info.js | 9 +-- gallery/src/components/more-info-content.ts | 73 ------------------- .../src/demos/demo-hui-alarm-panel-card.ts | 19 ++++- .../src/demos/demo-hui-entity-button-card.ts | 2 +- gallery/src/demos/demo-more-info-light.ts | 8 +- src/dialogs/more-info/ha-more-info-dialog.ts | 31 ++------ src/dialogs/more-info/more-info-content.ts | 57 +++++++++++++++ src/fake_data/provide_hass.ts | 26 ++++--- 9 files changed, 131 insertions(+), 129 deletions(-) delete mode 100644 gallery/src/components/more-info-content.ts create mode 100644 src/dialogs/more-info/more-info-content.ts diff --git a/gallery/src/components/demo-cards.js b/gallery/src/components/demo-cards.js index 26ac82e3f7..9e076371c4 100644 --- a/gallery/src/components/demo-cards.js +++ b/gallery/src/components/demo-cards.js @@ -5,11 +5,16 @@ import { PolymerElement } from "@polymer/polymer/polymer-element"; import "../../../src/components/ha-switch"; import "../../../src/components/ha-formfield"; import "./demo-card"; +import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; class DemoCards extends PolymerElement { static get template() { return html`
@@ -31,16 +39,21 @@ class DemoCards extends PolymerElement { + + +
-
- +
+
+ +
`; } @@ -59,6 +72,12 @@ class DemoCards extends PolymerElement { _showConfigToggled(ev) { this._showConfig = ev.target.checked; } + + _darkThemeToggled(ev) { + applyThemesOnElement(this.$.container, { themes: {} }, "default", { + dark: ev.target.checked, + }); + } } customElements.define("demo-cards", DemoCards); diff --git a/gallery/src/components/demo-more-info.js b/gallery/src/components/demo-more-info.js index 9e4a34023f..0805e77c37 100644 --- a/gallery/src/components/demo-more-info.js +++ b/gallery/src/components/demo-more-info.js @@ -3,7 +3,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; import "../../../src/components/ha-card"; import "../../../src/state-summary/state-card-content"; -import "./more-info-content"; +import "../../../src/dialogs/more-info/more-info-content"; class DemoMoreInfo extends PolymerElement { static get template() { @@ -16,15 +16,12 @@ class DemoMoreInfo extends PolymerElement { ha-card { width: 333px; + padding: 20px 24px; } state-card-content { display: block; - padding: 16px; - } - - more-info-content { - padding: 0 16px; + margin-bottom: 16px; } pre { diff --git a/gallery/src/components/more-info-content.ts b/gallery/src/components/more-info-content.ts deleted file mode 100644 index 549ac4fa2d..0000000000 --- a/gallery/src/components/more-info-content.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { HassEntity } from "home-assistant-js-websocket"; -import { property, PropertyValues, UpdatingElement } from "lit-element"; -import dynamicContentUpdater from "../../../src/common/dom/dynamic_content_updater"; -import { stateMoreInfoType } from "../../../src/dialogs/more-info/state_more_info_control"; -import "../../../src/dialogs/more-info/controls/more-info-alarm_control_panel"; -import "../../../src/dialogs/more-info/controls/more-info-automation"; -import "../../../src/dialogs/more-info/controls/more-info-camera"; -import "../../../src/dialogs/more-info/controls/more-info-climate"; -import "../../../src/dialogs/more-info/controls/more-info-configurator"; -import "../../../src/dialogs/more-info/controls/more-info-counter"; -import "../../../src/dialogs/more-info/controls/more-info-cover"; -import "../../../src/dialogs/more-info/controls/more-info-default"; -import "../../../src/dialogs/more-info/controls/more-info-fan"; -import "../../../src/dialogs/more-info/controls/more-info-group"; -import "../../../src/dialogs/more-info/controls/more-info-humidifier"; -import "../../../src/dialogs/more-info/controls/more-info-input_datetime"; -import "../../../src/dialogs/more-info/controls/more-info-light"; -import "../../../src/dialogs/more-info/controls/more-info-lock"; -import "../../../src/dialogs/more-info/controls/more-info-media_player"; -import "../../../src/dialogs/more-info/controls/more-info-person"; -import "../../../src/dialogs/more-info/controls/more-info-script"; -import "../../../src/dialogs/more-info/controls/more-info-sun"; -import "../../../src/dialogs/more-info/controls/more-info-timer"; -import "../../../src/dialogs/more-info/controls/more-info-vacuum"; -import "../../../src/dialogs/more-info/controls/more-info-water_heater"; -import "../../../src/dialogs/more-info/controls/more-info-weather"; -import { HomeAssistant } from "../../../src/types"; - -class MoreInfoContent extends UpdatingElement { - @property({ attribute: false }) public hass?: HomeAssistant; - - @property() public stateObj?: HassEntity; - - private _detachedChild?: ChildNode; - - protected firstUpdated(): void { - this.style.position = "relative"; - this.style.display = "block"; - } - - // This is not a lit element, but an updating element, so we implement update - protected update(changedProps: PropertyValues): void { - super.update(changedProps); - const stateObj = this.stateObj; - const hass = this.hass; - - if (!stateObj || !hass) { - if (this.lastChild) { - this._detachedChild = this.lastChild; - // Detach child to prevent it from doing work. - this.removeChild(this.lastChild); - } - return; - } - - if (this._detachedChild) { - this.appendChild(this._detachedChild); - this._detachedChild = undefined; - } - - const moreInfoType = - stateObj.attributes && "custom_ui_more_info" in stateObj.attributes - ? stateObj.attributes.custom_ui_more_info - : "more-info-" + stateMoreInfoType(stateObj); - - dynamicContentUpdater(this, moreInfoType.toUpperCase(), { - hass, - stateObj, - }); - } -} - -customElements.define("more-info-content", MoreInfoContent); diff --git a/gallery/src/demos/demo-hui-alarm-panel-card.ts b/gallery/src/demos/demo-hui-alarm-panel-card.ts index 12b5f130b4..73d46b53fd 100644 --- a/gallery/src/demos/demo-hui-alarm-panel-card.ts +++ b/gallery/src/demos/demo-hui-alarm-panel-card.ts @@ -15,6 +15,10 @@ const ENTITIES = [ getEntity("alarm_control_panel", "unavailable", "unavailable", { friendly_name: "Alarm", }), + getEntity("alarm_control_panel", "alarm_code", "disarmed", { + friendly_name: "Alarm", + code_format: "number", + }), ]; const CONFIGS = [ @@ -30,7 +34,14 @@ const CONFIGS = [ config: ` - type: alarm-panel entity: alarm_control_panel.alarm_armed - title: My Alarm + name: My Alarm + `, + }, + { + heading: "Code Example", + config: ` +- type: alarm-panel + entity: alarm_control_panel.alarm_code `, }, { @@ -83,8 +94,12 @@ class DemoAlarmPanelEntity extends PolymerElement { public ready() { super.ready(); + this._setupDemo(); + } + + private async _setupDemo() { const hass = provideHass(this.$.demos); - hass.updateTranslations(null, "en"); + await hass.updateTranslations(null, "en"); hass.addEntities(ENTITIES); } } diff --git a/gallery/src/demos/demo-hui-entity-button-card.ts b/gallery/src/demos/demo-hui-entity-button-card.ts index 8c4c77e100..5b89327432 100644 --- a/gallery/src/demos/demo-hui-entity-button-card.ts +++ b/gallery/src/demos/demo-hui-entity-button-card.ts @@ -98,4 +98,4 @@ class DemoButtonEntity extends PolymerElement { } } -customElements.define("demo-hui-button-card", DemoButtonEntity); +customElements.define("demo-hui-entity-button-card", DemoButtonEntity); diff --git a/gallery/src/demos/demo-more-info-light.ts b/gallery/src/demos/demo-more-info-light.ts index 8c5ac611e9..70b77560d9 100644 --- a/gallery/src/demos/demo-more-info-light.ts +++ b/gallery/src/demos/demo-more-info-light.ts @@ -6,7 +6,7 @@ import { SUPPORT_BRIGHTNESS } from "../../../src/data/light"; import { getEntity } from "../../../src/fake_data/entity"; import { provideHass } from "../../../src/fake_data/provide_hass"; import "../components/demo-more-infos"; -import "../components/more-info-content"; +import "../../../src/dialogs/more-info/more-info-content"; const ENTITIES = [ getEntity("light", "bed_light", "on", { @@ -40,8 +40,12 @@ class DemoMoreInfoLight extends PolymerElement { public ready() { super.ready(); + this._setupDemo(); + } + + private async _setupDemo() { const hass = provideHass(this); - hass.updateTranslations(null, "en"); + await hass.updateTranslations(null, "en"); hass.addEntities(ENTITIES); } } diff --git a/src/dialogs/more-info/ha-more-info-dialog.ts b/src/dialogs/more-info/ha-more-info-dialog.ts index 10a4b1f15b..836273f07f 100644 --- a/src/dialogs/more-info/ha-more-info-dialog.ts +++ b/src/dialogs/more-info/ha-more-info-dialog.ts @@ -17,14 +17,10 @@ import { DOMAINS_MORE_INFO_NO_HISTORY, DOMAINS_WITH_MORE_INFO, } from "../../common/const"; -import { dynamicElement } from "../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../common/dom/fire_event"; import { computeDomain } from "../../common/entity/compute_domain"; import { computeStateName } from "../../common/entity/compute_state_name"; -import { - stateMoreInfoType, - importMoreInfoControl, -} from "./state_more_info_control"; + import { navigate } from "../../common/navigate"; import "../../components/ha-dialog"; import "../../components/ha-header-bar"; @@ -39,6 +35,7 @@ import "./ha-more-info-history"; import "./ha-more-info-logbook"; import "./controls/more-info-default"; import { CONTINUOUS_DOMAINS } from "../../data/logbook"; +import "./more-info-content"; const DOMAINS_NO_INFO = ["camera", "configurator"]; /** @@ -63,8 +60,6 @@ export class MoreInfoDialog extends LitElement { @internalProperty() private _entityId?: string | null; - @internalProperty() private _moreInfoType?: string; - @internalProperty() private _currTabIndex = 0; public showDialog(params: MoreInfoDialogParams) { @@ -74,18 +69,6 @@ export class MoreInfoDialog extends LitElement { return; } this.large = false; - - const stateObj = this.hass.states[this._entityId]; - if (!stateObj) { - return; - } - if (stateObj.attributes && "custom_ui_more_info" in stateObj.attributes) { - this._moreInfoType = stateObj.attributes.custom_ui_more_info; - } else { - const type = stateMoreInfoType(stateObj); - importMoreInfoControl(type); - this._moreInfoType = type === "hidden" ? undefined : `more-info-${type}`; - } } public closeDialog() { @@ -218,12 +201,10 @@ export class MoreInfoDialog extends LitElement { .hass=${this.hass} .entityId=${this._entityId} >`} - ${this._moreInfoType - ? dynamicElement(this._moreInfoType, { - hass: this.hass, - stateObj, - }) - : ""} + ${stateObj.attributes.restored ? html`

diff --git a/src/dialogs/more-info/more-info-content.ts b/src/dialogs/more-info/more-info-content.ts new file mode 100644 index 0000000000..47570226fa --- /dev/null +++ b/src/dialogs/more-info/more-info-content.ts @@ -0,0 +1,57 @@ +import { HassEntity } from "home-assistant-js-websocket"; +import { property, PropertyValues, UpdatingElement } from "lit-element"; + +import { HomeAssistant } from "../../types"; +import dynamicContentUpdater from "../../common/dom/dynamic_content_updater"; +import { stateMoreInfoType } from "./state_more_info_control"; +import { importMoreInfoControl } from "../../panels/lovelace/custom-card-helpers"; + +class MoreInfoContent extends UpdatingElement { + @property({ attribute: false }) public hass?: HomeAssistant; + + @property() public stateObj?: HassEntity; + + private _detachedChild?: ChildNode; + + // This is not a lit element, but an updating element, so we implement update + protected update(changedProps: PropertyValues): void { + super.update(changedProps); + const stateObj = this.stateObj; + const hass = this.hass; + + if (!stateObj || !hass) { + if (this.lastChild) { + this._detachedChild = this.lastChild; + // Detach child to prevent it from doing work. + this.removeChild(this.lastChild); + } + return; + } + + if (this._detachedChild) { + this.appendChild(this._detachedChild); + this._detachedChild = undefined; + } + + let moreInfoType: string | undefined; + + if (stateObj.attributes && "custom_ui_more_info" in stateObj.attributes) { + moreInfoType = stateObj.attributes.custom_ui_more_info; + } else { + const type = stateMoreInfoType(stateObj); + importMoreInfoControl(type); + moreInfoType = type === "hidden" ? undefined : `more-info-${type}`; + } + + if (!moreInfoType) { + return; + } + + dynamicContentUpdater(this, moreInfoType.toUpperCase(), { + hass, + stateObj, + }); + } +} + +customElements.define("more-info-content", MoreInfoContent); diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts index 0bc58b1040..3407ecbb18 100644 --- a/src/fake_data/provide_hass.ts +++ b/src/fake_data/provide_hass.ts @@ -53,19 +53,21 @@ export const provideHass = ( } = {}; const entities = {}; - function updateTranslations(fragment: null | string, language?: string) { + async function updateTranslations( + fragment: null | string, + language?: string + ) { const lang = language || getLocalLanguage(); - getTranslation(fragment, lang).then(async (translation) => { - const resources = { - [lang]: { - ...(hass().resources && hass().resources[lang]), - ...translation.data, - }, - }; - hass().updateHass({ - resources, - localize: await computeLocalize(elements[0], lang, resources), - }); + const translation = await getTranslation(fragment, lang); + const resources = { + [lang]: { + ...(hass().resources && hass().resources[lang]), + ...translation.data, + }, + }; + hass().updateHass({ + resources, + localize: await computeLocalize(elements[0], lang, resources), }); }