From a839494a1e3f54ef50a5ae705f5825fd7489462a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 7 Oct 2021 12:21:35 -0700 Subject: [PATCH 001/115] Use MWC components for ha-form (#10120) --- gallery/src/demos/demo-ha-form.ts | 224 ++++++++++++++--- .../addon-view/config/hassio-addon-config.ts | 2 +- package.json | 3 + src/auth/ha-auth-flow.ts | 102 ++++---- src/auth/ha-authorize.ts | 4 + src/auth/ha-password-manager-polyfill.ts | 4 +- src/components/ha-duration-input.ts | 2 - .../ha-form/compute-initial-ha-form-data.ts | 37 +++ src/components/ha-form/ha-form-boolean.ts | 31 +-- src/components/ha-form/ha-form-constant.ts | 19 +- src/components/ha-form/ha-form-float.ts | 61 +++-- src/components/ha-form/ha-form-integer.ts | 174 ++++++++----- .../ha-form/ha-form-multi_select.ts | 238 ++++++++++-------- .../ha-form-positive_time_period_dict.ts | 4 +- src/components/ha-form/ha-form-select.ts | 137 +++++----- src/components/ha-form/ha-form-string.ts | 95 ++++--- src/components/ha-form/ha-form.ts | 218 +++++----------- src/components/ha-form/types.ts | 86 +++++++ src/data/data_entry_flow.ts | 2 +- src/data/device_automation.ts | 2 +- src/data/hassio/addon.ts | 2 +- src/data/zha.ts | 2 +- .../show-dialog-data-entry-flow.ts | 2 +- src/dialogs/config-flow/step-flow-form.ts | 77 +++--- src/dialogs/config-flow/styles.ts | 4 +- src/resources/ha-style.ts | 16 +- src/resources/styles.ts | 49 ++++ src/translations/en.json | 2 +- yarn.lock | 146 ++++++++++- 29 files changed, 1121 insertions(+), 624 deletions(-) create mode 100644 src/components/ha-form/compute-initial-ha-form-data.ts create mode 100644 src/components/ha-form/types.ts diff --git a/gallery/src/demos/demo-ha-form.ts b/gallery/src/demos/demo-ha-form.ts index 9f5f9a3d54..38266cd602 100644 --- a/gallery/src/demos/demo-ha-form.ts +++ b/gallery/src/demos/demo-ha-form.ts @@ -1,23 +1,26 @@ /* eslint-disable lit/no-template-arrow */ +import "@material/mwc-button"; import { LitElement, TemplateResult, css, html } from "lit"; import { customElement } from "lit/decorators"; -import "../../../src/components/ha-form/ha-form"; +import { computeInitialHaFormData } from "../../../src/components/ha-form/compute-initial-ha-form-data"; import "../../../src/components/ha-card"; import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; -import type { HaFormSchema } from "../../../src/components/ha-form/ha-form"; +import type { HaFormSchema } from "../../../src/components/ha-form/types"; +import "../../../src/components/ha-form/ha-form"; const SCHEMAS: { title: string; translations?: Record; error?: Record; schema: HaFormSchema[]; + data?: Record; }[] = [ { title: "Authentication", translations: { username: "Username", password: "Password", - invalid_login: "Invalid login", + invalid_login: "Invalid username or password", }, error: { base: "invalid_login", @@ -57,6 +60,11 @@ const SCHEMAS: { optional: true, default: 10, }, + { + type: "float", + name: "float", + required: true, + }, { type: "string", name: "string", @@ -83,6 +91,80 @@ const SCHEMAS: { optional: true, default: ["default"], }, + { + type: "positive_time_period_dict", + name: "time", + required: true, + }, + ], + }, + { + title: "Numbers", + schema: [ + { + type: "integer", + name: "int", + required: true, + }, + { + type: "integer", + name: "int with default", + optional: true, + default: 10, + }, + { + type: "integer", + name: "int range required", + required: true, + default: 5, + valueMin: 0, + valueMax: 10, + }, + { + type: "integer", + name: "int range optional", + optional: true, + valueMin: 0, + valueMax: 10, + }, + ], + }, + { + title: "select", + schema: [ + { + type: "select", + options: [ + ["default", "Default"], + ["other", "Other"], + ], + name: "select", + required: true, + default: "default", + }, + { + type: "select", + options: [ + ["default", "Default"], + ["other", "Other"], + ], + name: "select optional", + optional: true, + }, + { + type: "select", + options: [ + ["default", "Default"], + ["other", "Other"], + ["uno", "mas"], + ["one", "more"], + ["and", "another_one"], + ["option", "1000"], + ], + name: "select many otions", + optional: true, + default: "default", + }, ], }, { @@ -95,7 +177,7 @@ const SCHEMAS: { other: "Other", }, name: "multi", - optional: true, + required: true, default: ["default"], }, { @@ -108,19 +190,46 @@ const SCHEMAS: { and: "another_one", option: "1000", }, - name: "multi", + name: "multi many otions", optional: true, default: ["default"], }, ], }, + { + title: "Field specific error", + data: { + new_password: "hello", + new_password_2: "bye", + }, + translations: { + new_password: "New Password", + new_password_2: "Re-type Password", + not_match: "The passwords do not match", + }, + error: { + new_password_2: "not_match", + }, + schema: [ + { + type: "string", + name: "new_password", + required: true, + }, + { + type: "string", + name: "new_password_2", + required: true, + }, + ], + }, ]; @customElement("demo-ha-form") class DemoHaForm extends LitElement { - private lightModeData: any = []; - - private darkModeData: any = []; + private data = SCHEMAS.map( + ({ schema, data }) => data || computeInitialHaFormData(schema) + ); protected render(): TemplateResult { return html` @@ -130,38 +239,58 @@ class DemoHaForm extends LitElement { translations[schema.name] || schema.name; const computeError = (error) => translations[error] || error; - return [ - [this.lightModeData, "light"], - [this.darkModeData, "dark"], - ].map( - ([data, type]) => html` -
+ return html` +
+
{ - data[idx] = e.detail.value; + this.data[idx] = e.detail.value; this.requestUpdate(); }} >
+
+ Submit +
-
${JSON.stringify(data[idx], undefined, 2)}
- ` - ); +
+ +
+ { + this.data[idx] = e.detail.value; + this.requestUpdate(); + }} + > +
+
+ Submit +
+
+
${JSON.stringify(this.data[idx], undefined, 2)}
+
+
+ `; })} `; } firstUpdated(changedProps) { super.firstUpdated(changedProps); - this.shadowRoot!.querySelectorAll("[data-type=dark]").forEach((el) => { + this.shadowRoot!.querySelectorAll(".dark").forEach((el) => { applyThemesOnElement( el, { @@ -178,28 +307,63 @@ class DemoHaForm extends LitElement { static styles = css` .row { - margin: 0 auto; - max-width: 800px; display: flex; - padding: 50px; + } + .content { + padding: 50px 0; background-color: var(--primary-background-color); } + .light { + flex: 1; + padding-left: 50px; + padding-right: 50px; + box-sizing: border-box; + } + .light ha-card { + margin-left: auto; + } + .dark { + display: flex; + flex: 1; + padding-left: 50px; + box-sizing: border-box; + flex-wrap: wrap; + } ha-card { - width: 100%; - max-width: 384px; + width: 400px; } pre { - width: 400px; - margin: 0 16px; + width: 300px; + margin: 0 16px 0; overflow: auto; color: var(--primary-text-color); } - @media only screen and (max-width: 800px) { - .row { + .card-actions { + display: flex; + flex-direction: row-reverse; + border-top: none; + } + @media only screen and (max-width: 1500px) { + .light { + flex: initial; + } + } + @media only screen and (max-width: 1000px) { + .light, + .dark { + padding: 16px; + } + .row, + .dark { flex-direction: column; } + ha-card { + margin: 0 auto; + width: 100%; + max-width: 400px; + } pre { - margin: 16px 0; + margin: 16px auto; } } `; diff --git a/hassio/src/addon-view/config/hassio-addon-config.ts b/hassio/src/addon-view/config/hassio-addon-config.ts index ed9ed11c42..4d2ef2acd8 100644 --- a/hassio/src/addon-view/config/hassio-addon-config.ts +++ b/hassio/src/addon-view/config/hassio-addon-config.ts @@ -19,7 +19,7 @@ import "../../../../src/components/ha-button-menu"; import "../../../../src/components/ha-card"; import "../../../../src/components/ha-alert"; import "../../../../src/components/ha-form/ha-form"; -import type { HaFormSchema } from "../../../../src/components/ha-form/ha-form"; +import type { HaFormSchema } from "../../../../src/components/ha-form/types"; import "../../../../src/components/ha-formfield"; import "../../../../src/components/ha-switch"; import "../../../../src/components/ha-yaml-editor"; diff --git a/package.json b/package.json index 3a3dfe5645..fcd9afa372 100644 --- a/package.json +++ b/package.json @@ -60,9 +60,12 @@ "@material/mwc-menu": "0.25.1", "@material/mwc-radio": "0.25.1", "@material/mwc-ripple": "0.25.1", + "@material/mwc-select": "^0.25.1", + "@material/mwc-slider": "^0.25.1", "@material/mwc-switch": "0.25.1", "@material/mwc-tab": "0.25.1", "@material/mwc-tab-bar": "0.25.1", + "@material/mwc-textfield": "^0.25.1", "@material/top-app-bar": "13.0.0-canary.65125b3a6.0", "@mdi/js": "6.2.95", "@mdi/svg": "6.2.95", diff --git a/src/auth/ha-auth-flow.ts b/src/auth/ha-auth-flow.ts index d046ca6dae..e8062334e1 100644 --- a/src/auth/ha-auth-flow.ts +++ b/src/auth/ha-auth-flow.ts @@ -11,12 +11,14 @@ import "./ha-password-manager-polyfill"; import { property, state } from "lit/decorators"; import "../components/ha-form/ha-form"; import "../components/ha-markdown"; +import "../components/ha-alert"; import { AuthProvider } from "../data/auth"; import { DataEntryFlowStep, DataEntryFlowStepForm, } from "../data/data_entry_flow"; import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin"; +import { computeInitialHaFormData } from "../components/ha-form/compute-initial-ha-form-data"; type State = "loading" | "error" | "step"; @@ -31,12 +33,40 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { @state() private _state: State = "loading"; - @state() private _stepData: any = {}; + @state() private _stepData?: Record; @state() private _step?: DataEntryFlowStep; @state() private _errorMessage?: string; + willUpdate(changedProps: PropertyValues) { + super.willUpdate(changedProps); + + if (!changedProps.has("_step")) { + return; + } + + if (!this._step) { + this._stepData = undefined; + return; + } + + const oldStep = changedProps.get("_step") as HaAuthFlow["_step"]; + + if ( + !oldStep || + this._step.flow_id !== oldStep.flow_id || + (this._step.type === "form" && + oldStep.type === "form" && + this._step.step_id !== oldStep.step_id) + ) { + this._stepData = + this._step.type === "form" + ? computeInitialHaFormData(this._step.data_schema) + : undefined; + } + } + protected render() { return html`
${this._renderForm()}
@@ -76,6 +106,24 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { if (changedProps.has("authProvider")) { this._providerChanged(this.authProvider); } + + if (!changedProps.has("_step") || this._step?.type !== "form") { + return; + } + + // 100ms to give all the form elements time to initialize. + setTimeout(() => { + const form = this.renderRoot.querySelector("ha-form"); + if (form) { + (form as any).focus(); + } + }, 100); + + setTimeout(() => { + this.renderRoot.querySelector( + "ha-password-manager-polyfill" + )!.boundingRect = this.getBoundingClientRect(); + }, 500); } private _renderForm(): TemplateResult { @@ -98,16 +146,20 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { `; case "error": return html` -
+ ${this.localize( "ui.panel.page-authorize.form.error", "error", this._errorMessage )} -
+ `; case "loading": - return html` ${this.localize("ui.panel.page-authorize.form.working")} `; + return html` + + ${this.localize("ui.panel.page-authorize.form.working")} + + `; default: return html``; } @@ -189,7 +241,8 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { return; } - await this._updateStep(data); + this._step = data; + this._state = "step"; } else { this._state = "error"; this._errorMessage = data.message; @@ -220,39 +273,6 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { document.location.assign(url); } - private async _updateStep(step: DataEntryFlowStep) { - let stepData: any = null; - if ( - this._step && - (step.flow_id !== this._step.flow_id || - (step.type === "form" && - this._step.type === "form" && - step.step_id !== this._step.step_id)) - ) { - stepData = {}; - } - this._step = step; - this._state = "step"; - if (stepData != null) { - this._stepData = stepData; - } - - await this.updateComplete; - // 100ms to give all the form elements time to initialize. - setTimeout(() => { - const form = this.renderRoot.querySelector("ha-form"); - if (form) { - (form as any).focus(); - } - }, 100); - - setTimeout(() => { - this.renderRoot.querySelector( - "ha-password-manager-polyfill" - )!.boundingRect = this.getBoundingClientRect(); - }, 500); - } - private _stepDataChanged(ev: CustomEvent) { this._stepData = ev.detail.value; } @@ -316,7 +336,8 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { this._redirect(newStep.result); return; } - await this._updateStep(newStep); + this._step = newStep; + this._state = "step"; } catch (err: any) { // eslint-disable-next-line no-console console.error("Error submitting step", err); @@ -337,9 +358,6 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { margin: 24px 0 8px; text-align: center; } - .error { - color: red; - } `; } } diff --git a/src/auth/ha-authorize.ts b/src/auth/ha-authorize.ts index 9608ad0642..acd98952c9 100644 --- a/src/auth/ha-authorize.ts +++ b/src/auth/ha-authorize.ts @@ -174,6 +174,10 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) { display: block; margin-top: 48px; } + ha-auth-flow { + display: block; + margin-top: 24px; + } `; } } diff --git a/src/auth/ha-password-manager-polyfill.ts b/src/auth/ha-password-manager-polyfill.ts index c0c46c0ab0..a0f2488b78 100644 --- a/src/auth/ha-password-manager-polyfill.ts +++ b/src/auth/ha-password-manager-polyfill.ts @@ -2,8 +2,8 @@ import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; -import { HaFormSchema } from "../components/ha-form/ha-form"; -import { DataEntryFlowStep } from "../data/data_entry_flow"; +import type { HaFormSchema } from "../components/ha-form/types"; +import type { DataEntryFlowStep } from "../data/data_entry_flow"; declare global { interface HTMLElementTagNameMap { diff --git a/src/components/ha-duration-input.ts b/src/components/ha-duration-input.ts index 32651cb2c2..4af165b74d 100644 --- a/src/components/ha-duration-input.ts +++ b/src/components/ha-duration-input.ts @@ -16,8 +16,6 @@ class HaDurationInput extends LitElement { @property() public label?: string; - @property() public suffix?: string; - @property({ type: Boolean }) public required?: boolean; @property({ type: Boolean }) public enableMillisecond?: boolean; diff --git a/src/components/ha-form/compute-initial-ha-form-data.ts b/src/components/ha-form/compute-initial-ha-form-data.ts new file mode 100644 index 0000000000..0e80433c74 --- /dev/null +++ b/src/components/ha-form/compute-initial-ha-form-data.ts @@ -0,0 +1,37 @@ +import { HaFormSchema } from "./types"; + +export const computeInitialHaFormData = ( + schema: HaFormSchema[] +): Record => { + const data = {}; + schema.forEach((field) => { + if (field.description?.suggested_value) { + data[field.name] = field.description.suggested_value; + } else if ("default" in field) { + data[field.name] = field.default; + } else if (!field.required) { + // Do nothing. + } else if (field.type === "boolean") { + data[field.name] = false; + } else if (field.type === "string") { + data[field.name] = ""; + } else if (field.type === "integer") { + data[field.name] = "valueMin" in field ? field.valueMin : 0; + } else if (field.type === "constant") { + data[field.name] = field.value; + } else if (field.type === "float") { + data[field.name] = 0.0; + } else if (field.type === "select") { + if (field.options.length) { + data[field.name] = field.options[0][0]; + } + } else if (field.type === "positive_time_period_dict") { + data[field.name] = { + hours: 0, + minutes: 0, + seconds: 0, + }; + } + }); + return data; +}; diff --git a/src/components/ha-form/ha-form-boolean.ts b/src/components/ha-form/ha-form-boolean.ts index 2bf264a498..f348013504 100644 --- a/src/components/ha-form/ha-form-boolean.ts +++ b/src/components/ha-form/ha-form-boolean.ts @@ -1,13 +1,14 @@ -import "@polymer/paper-checkbox/paper-checkbox"; -import type { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import "@material/mwc-formfield"; +import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import type { HaFormBooleanData, HaFormBooleanSchema, HaFormElement, -} from "./ha-form"; +} from "./types"; +import type { HaCheckbox } from "../ha-checkbox"; +import "../ha-checkbox"; @customElement("ha-form-boolean") export class HaFormBoolean extends LitElement implements HaFormElement { @@ -17,8 +18,6 @@ export class HaFormBoolean extends LitElement implements HaFormElement { @property() public label!: string; - @property() public suffix!: string; - @query("paper-checkbox", true) private _input?: HTMLElement; public focus() { @@ -29,26 +28,20 @@ export class HaFormBoolean extends LitElement implements HaFormElement { protected render(): TemplateResult { return html` - - ${this.label} - + + + `; } private _valueChanged(ev: Event) { fireEvent(this, "value-changed", { - value: (ev.target as PaperCheckboxElement).checked, + value: (ev.target as HaCheckbox).checked, }); } - - static get styles(): CSSResultGroup { - return css` - paper-checkbox { - display: block; - padding: 22px 0; - } - `; - } } declare global { diff --git a/src/components/ha-form/ha-form-constant.ts b/src/components/ha-form/ha-form-constant.ts index d05e9ac5f6..f20c057dfc 100644 --- a/src/components/ha-form/ha-form-constant.ts +++ b/src/components/ha-form/ha-form-constant.ts @@ -1,14 +1,6 @@ -import { - css, - CSSResultGroup, - html, - LitElement, - PropertyValues, - TemplateResult, -} from "lit"; +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import { fireEvent } from "../../common/dom/fire_event"; -import { HaFormConstantSchema, HaFormElement } from "./ha-form"; +import { HaFormConstantSchema, HaFormElement } from "./types"; @customElement("ha-form-constant") export class HaFormConstant extends LitElement implements HaFormElement { @@ -16,13 +8,6 @@ export class HaFormConstant extends LitElement implements HaFormElement { @property() public label!: string; - protected firstUpdated(changedProps: PropertyValues) { - super.firstUpdated(changedProps); - fireEvent(this, "value-changed", { - value: this.schema.value, - }); - } - protected render(): TemplateResult { return html`${this.label}: ${this.schema.value}`; } diff --git a/src/components/ha-form/ha-form-float.ts b/src/components/ha-form/ha-form-float.ts index 698667eca4..032956a7e5 100644 --- a/src/components/ha-form/ha-form-float.ts +++ b/src/components/ha-form/ha-form-float.ts @@ -1,9 +1,9 @@ -import "@polymer/paper-input/paper-input"; -import type { PaperInputElement } from "@polymer/paper-input/paper-input"; -import { html, LitElement, TemplateResult } from "lit"; +import "@material/mwc-textfield"; +import type { TextField } from "@material/mwc-textfield"; +import { css, html, LitElement, TemplateResult, PropertyValues } from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; -import { HaFormElement, HaFormFloatData, HaFormFloatSchema } from "./ha-form"; +import { HaFormElement, HaFormFloatData, HaFormFloatSchema } from "./types"; @customElement("ha-form-float") export class HaFormFloat extends LitElement implements HaFormElement { @@ -13,9 +13,7 @@ export class HaFormFloat extends LitElement implements HaFormElement { @property() public label!: string; - @property() public suffix!: string; - - @query("paper-input", true) private _input?: HTMLElement; + @query("mwc-textfield") private _input?: HTMLElement; public focus() { if (this._input) { @@ -25,33 +23,58 @@ export class HaFormFloat extends LitElement implements HaFormElement { protected render(): TemplateResult { return html` - - ${this.suffix} - + .suffix=${this.schema.description?.suffix} + .validationMessage=${this.schema.required ? "Required" : undefined} + @input=${this._valueChanged} + > `; } - private get _value() { - return this.data; + protected updated(changedProps: PropertyValues): void { + if (changedProps.has("schema")) { + this.toggleAttribute("own-margin", !!this.schema.required); + } } private _valueChanged(ev: Event) { - const value: number | undefined = (ev.target as PaperInputElement).value - ? Number((ev.target as PaperInputElement).value) - : undefined; - if (this._value === value) { + const source = ev.target as TextField; + const rawValue = source.value; + + let value: number | undefined; + + if (rawValue !== "") { + value = parseFloat(rawValue); + } + + // Detect anything changed + if (this.data === value) { + // parseFloat will drop invalid text at the end, in that case update textfield + const newRawValue = value === undefined ? "" : String(value); + if (source.value !== newRawValue) { + source.value = newRawValue; + return; + } return; } + fireEvent(this, "value-changed", { value, }); } + + static styles = css` + :host([own-margin]) { + margin-bottom: 5px; + } + mwc-textfield { + display: block; + } + `; } declare global { diff --git a/src/components/ha-form/ha-form-integer.ts b/src/components/ha-form/ha-form-integer.ts index 9cb7da2496..9aa54a2e43 100644 --- a/src/components/ha-form/ha-form-integer.ts +++ b/src/components/ha-form/ha-form-integer.ts @@ -1,16 +1,19 @@ -import "@polymer/paper-input/paper-input"; -import type { PaperInputElement } from "@polymer/paper-input/paper-input"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import "@material/mwc-textfield"; +import type { TextField } from "@material/mwc-textfield"; +import "@material/mwc-slider"; +import type { Slider } from "@material/mwc-slider"; +import { + css, + CSSResultGroup, + html, + LitElement, + TemplateResult, + PropertyValues, +} from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import { HaCheckbox } from "../ha-checkbox"; -import "../ha-slider"; -import type { HaSlider } from "../ha-slider"; -import { - HaFormElement, - HaFormIntegerData, - HaFormIntegerSchema, -} from "./ha-form"; +import { HaFormElement, HaFormIntegerData, HaFormIntegerSchema } from "./types"; @customElement("ha-form-integer") export class HaFormInteger extends LitElement implements HaFormElement { @@ -20,10 +23,10 @@ export class HaFormInteger extends LitElement implements HaFormElement { @property() public label?: string; - @property() public suffix?: string; - @query("paper-input ha-slider") private _input?: HTMLElement; + private _lastValue?: HaFormIntegerData; + public focus() { if (this._input) { this._input.focus(); @@ -31,66 +34,112 @@ export class HaFormInteger extends LitElement implements HaFormElement { } protected render(): TemplateResult { - return "valueMin" in this.schema && "valueMax" in this.schema - ? html` -
- ${this.label} -
- ${this.schema.optional && this.schema.default === undefined - ? html` - - ` - : ""} - -
+ if ("valueMin" in this.schema && "valueMax" in this.schema) { + return html` +
+ ${this.label} +
+ ${this.schema.optional + ? html` + + ` + : ""} +
- ` - : html` - - `; +
+ `; + } + + return html` + + `; + } + + protected updated(changedProps: PropertyValues): void { + if (changedProps.has("schema")) { + this.toggleAttribute( + "own-margin", + !("valueMin" in this.schema && "valueMax" in this.schema) && + !!this.schema.required + ); + } } private get _value() { - return ( - this.data || - this.schema.description?.suggested_value || - this.schema.default || - 0 - ); + if (this.data !== undefined) { + return this.data; + } + + if (this.schema.optional) { + return 0; + } + + return this.schema.description?.suggested_value || this.schema.default || 0; } private _handleCheckboxChange(ev: Event) { const checked = (ev.target as HaCheckbox).checked; + let value: HaFormIntegerData | undefined; + if (checked) { + for (const candidate of [ + this._lastValue, + this.schema.description?.suggested_value as HaFormIntegerData, + this.schema.default, + 0, + ]) { + if (candidate !== undefined) { + value = candidate; + break; + } + } + } else { + // We track last value so user can disable and enable a field without losing + // their value. + this._lastValue = this.data; + } fireEvent(this, "value-changed", { - value: checked ? this._value : undefined, + value, }); } private _valueChanged(ev: Event) { - const value = Number((ev.target as PaperInputElement | HaSlider).value); - if (this._value === value) { + const source = ev.target as TextField | Slider; + const rawValue = source.value; + + let value: number | undefined; + + if (rawValue !== "") { + value = parseInt(String(rawValue)); + } + + if (this.data === value) { + // parseInt will drop invalid text at the end, in that case update textfield + const newRawValue = value === undefined ? "" : String(value); + if (source.value !== newRawValue) { + source.value = newRawValue; + } return; } + fireEvent(this, "value-changed", { value, }); @@ -98,12 +147,17 @@ export class HaFormInteger extends LitElement implements HaFormElement { static get styles(): CSSResultGroup { return css` + :host([own-margin]) { + margin-bottom: 5px; + } .flex { display: flex; } - ha-slider { - width: 100%; - margin-right: 16px; + mwc-slider { + flex: 1; + } + mwc-textfield { + display: block; } `; } diff --git a/src/components/ha-form/ha-form-multi_select.ts b/src/components/ha-form/ha-form-multi_select.ts index b947e5ac79..7267856322 100644 --- a/src/components/ha-form/ha-form-multi_select.ts +++ b/src/components/ha-form/ha-form-multi_select.ts @@ -1,19 +1,35 @@ -import { mdiMenuDown } from "@mdi/js"; -import "@polymer/paper-checkbox/paper-checkbox"; -import "@polymer/paper-input/paper-input"; -import "@polymer/paper-item/paper-icon-item"; -import "@polymer/paper-listbox/paper-listbox"; -import "@polymer/paper-menu-button/paper-menu-button"; -import "@polymer/paper-ripple/paper-ripple"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state, query } from "lit/decorators"; +import { mdiMenuDown, mdiMenuUp } from "@mdi/js"; +import "@material/mwc-textfield"; +import "@material/mwc-formfield"; +import { + css, + CSSResultGroup, + html, + LitElement, + TemplateResult, + PropertyValues, +} from "lit"; +import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; -import "../ha-svg-icon"; +import "../ha-button-menu"; +import "../ha-icon"; import { HaFormElement, HaFormMultiSelectData, HaFormMultiSelectSchema, -} from "./ha-form"; +} from "./types"; +import "../ha-checkbox"; +import type { HaCheckbox } from "../ha-checkbox"; + +function optionValue(item: string | string[]): string { + return Array.isArray(item) ? item[0] : item; +} + +function optionLabel(item: string | string[]): string { + return Array.isArray(item) ? item[1] || item[0] : item; +} + +const SHOW_ALL_ENTRIES_LIMIT = 6; @customElement("ha-form-multi_select") export class HaFormMultiSelect extends LitElement implements HaFormElement { @@ -23,9 +39,7 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { @property() public label!: string; - @property() public suffix!: string; - - @state() private _init = false; + @state() private _opened = false; @query("paper-menu-button", true) private _input?: HTMLElement; @@ -36,118 +50,136 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { } protected render(): TemplateResult { - const options = Array.isArray(this.schema.options) - ? this.schema.options - : Object.entries(this.schema.options!); - + const options = Object.entries(this.schema.options); const data = this.data || []; + + const renderedOptions = options.map((item: string | [string, string]) => { + const value = optionValue(item); + return html` + + + + `; + }); + + // We will just render all checkboxes. + if (options.length < SHOW_ALL_ENTRIES_LIMIT) { + return html`
${this.label}${renderedOptions}
`; + } + return html` - - - - ${ - // TS doesn't work with union array types https://github.com/microsoft/TypeScript/issues/36390 - // @ts-ignore - options.map((item: string | [string, string]) => { - const value = this._optionValue(item); - return html` - - - ${this._optionLabel(item)} - - `; - }) - } - - + + this.schema.options![value] || value) + .join(", ")} + tabindex="-1" + > + + ${renderedOptions} + `; } protected firstUpdated() { this.updateComplete.then(() => { - const input = ( - this.shadowRoot?.querySelector("paper-input")?.inputElement as any - )?.inputElement; - if (input) { - input.style.textOverflow = "ellipsis"; + const { formElement, mdcRoot } = + this.shadowRoot?.querySelector("mwc-textfield") || ({} as any); + if (formElement) { + formElement.style.textOverflow = "ellipsis"; + formElement.style.cursor = "pointer"; + formElement.setAttribute("readonly", ""); + } + if (mdcRoot) { + mdcRoot.style.cursor = "pointer"; } }); } - private _optionValue(item: string | string[]): string { - return Array.isArray(item) ? item[0] : item; - } - - private _optionLabel(item: string | string[]): string { - return Array.isArray(item) ? item[1] || item[0] : item; - } - - private _onSelect(ev: Event) { - ev.stopPropagation(); + protected updated(changedProps: PropertyValues): void { + if (changedProps.has("schema")) { + this.toggleAttribute( + "own-margin", + Object.keys(this.schema.options).length >= SHOW_ALL_ENTRIES_LIMIT && + !!this.schema.required + ); + } } private _valueChanged(ev: CustomEvent): void { - if (!ev.detail.value || !this._init) { - // ignore first call because that is the init of the component - this._init = true; - return; + const { value, checked } = ev.target as HaCheckbox; + + let newValue: string[]; + + if (checked) { + if (!this.data) { + newValue = [value]; + } else if (this.data.includes(value)) { + return; + } else { + newValue = [...this.data, value]; + } + } else { + if (!this.data.includes(value)) { + return; + } + newValue = this.data.filter((v) => v !== value); } - fireEvent( - this, - "value-changed", - { - value: ev.detail.value.map((element) => element.itemValue), - }, - { bubbles: false } - ); + fireEvent(this, "value-changed", { + value: newValue, + }); + } + + private _handleOpen(ev: Event): void { + ev.stopPropagation(); + this._opened = true; + this.toggleAttribute("opened", true); + } + + private _handleClose(ev: Event): void { + ev.stopPropagation(); + this._opened = false; + this.toggleAttribute("opened", false); } static get styles(): CSSResultGroup { return css` - paper-menu-button { + :host([own-margin]) { + margin-bottom: 5px; + } + ha-button-menu, + mwc-textfield, + mwc-formfield { display: block; - padding: 0; - --paper-item-icon-width: 34px; } - paper-ripple { - top: 12px; - left: 0px; - bottom: 8px; - right: 0px; + ha-svg-icon { + color: var(--input-dropdown-icon-color); + position: absolute; + right: 1em; + top: 1em; + cursor: pointer; } - paper-input { - text-overflow: ellipsis; + :host([opened]) ha-svg-icon { + color: var(--primary-color); + } + :host([opened]) ha-button-menu { + --mdc-text-field-idle-line-color: var(--input-hover-line-color); + --mdc-text-field-label-ink-color: var(--primary-color); } `; } diff --git a/src/components/ha-form/ha-form-positive_time_period_dict.ts b/src/components/ha-form/ha-form-positive_time_period_dict.ts index 7806e5c685..918dd7147b 100644 --- a/src/components/ha-form/ha-form-positive_time_period_dict.ts +++ b/src/components/ha-form/ha-form-positive_time_period_dict.ts @@ -1,7 +1,7 @@ import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; import "../ha-duration-input"; -import { HaFormElement, HaFormTimeData, HaFormTimeSchema } from "./ha-form"; +import { HaFormElement, HaFormTimeData, HaFormTimeSchema } from "./types"; @customElement("ha-form-positive_time_period_dict") export class HaFormTimePeriod extends LitElement implements HaFormElement { @@ -11,8 +11,6 @@ export class HaFormTimePeriod extends LitElement implements HaFormElement { @property() public label!: string; - @property() public suffix!: string; - @query("ha-time-input", true) private _input?: HTMLElement; public focus() { diff --git a/src/components/ha-form/ha-form-select.ts b/src/components/ha-form/ha-form-select.ts index c796bc8baf..62bd1ec528 100644 --- a/src/components/ha-form/ha-form-select.ts +++ b/src/components/ha-form/ha-form-select.ts @@ -1,15 +1,15 @@ -import "@material/mwc-icon-button/mwc-icon-button"; -import { mdiClose, mdiMenuDown } from "@mdi/js"; -import "@polymer/paper-input/paper-input"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-listbox/paper-listbox"; -import "@polymer/paper-menu-button/paper-menu-button"; -import "@polymer/paper-ripple/paper-ripple"; +import "@material/mwc-select"; +import type { Select } from "@material/mwc-select"; +import "@material/mwc-list/mwc-list-item"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import "../ha-svg-icon"; -import { HaFormElement, HaFormSelectData, HaFormSelectSchema } from "./ha-form"; +import "../ha-radio"; +import { HaFormElement, HaFormSelectData, HaFormSelectSchema } from "./types"; + +import { stopPropagation } from "../../common/dom/stop_propagation"; +import type { HaRadio } from "../ha-radio"; @customElement("ha-form-select") export class HaFormSelect extends LitElement implements HaFormElement { @@ -19,9 +19,7 @@ export class HaFormSelect extends LitElement implements HaFormElement { @property() public label!: string; - @property() public suffix!: string; - - @query("ha-paper-dropdown-menu", true) private _input?: HTMLElement; + @query("mwc-select", true) private _input?: HTMLElement; public focus() { if (this._input) { @@ -30,90 +28,67 @@ export class HaFormSelect extends LitElement implements HaFormElement { } protected render(): TemplateResult { - return html` - - ` + : this.schema.description?.suffix} + .validationMessage=${this.schema.required ? "Required" : undefined} + @input=${this._valueChanged} + > + ${isPassword + ? html` - - ` - : html` - - `; + ` + : ""} + `; + } + + protected updated(changedProps: PropertyValues): void { + if (changedProps.has("schema")) { + this.toggleAttribute("own-margin", !!this.schema.required); + } } private _toggleUnmaskedPassword(): void { @@ -76,10 +87,13 @@ export class HaFormString extends LitElement implements HaFormElement { } private _valueChanged(ev: Event): void { - const value = (ev.target as PaperInputElement).value; + let value: string | undefined = (ev.target as TextField).value; if (this.data === value) { return; } + if (value === "" && this.schema.optional) { + value = undefined; + } fireEvent(this, "value-changed", { value, }); @@ -99,7 +113,20 @@ export class HaFormString extends LitElement implements HaFormElement { static get styles(): CSSResultGroup { return css` + :host { + display: block; + position: relative; + } + :host([own-margin]) { + margin-bottom: 5px; + } + mwc-textfield { + display: block; + } mwc-icon-button { + position: absolute; + top: 1em; + right: 12px; --mdc-icon-button-size: 24px; color: var(--secondary-text-color); } diff --git a/src/components/ha-form/ha-form.ts b/src/components/ha-form/ha-form.ts index 49b19a8328..eae854c4f9 100644 --- a/src/components/ha-form/ha-form.ts +++ b/src/components/ha-form/ha-form.ts @@ -2,7 +2,7 @@ import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { dynamicElement } from "../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../common/dom/fire_event"; -import { HaDurationData } from "../ha-duration-input"; +import "../ha-alert"; import "./ha-form-boolean"; import "./ha-form-constant"; import "./ha-form-float"; @@ -11,160 +11,79 @@ import "./ha-form-multi_select"; import "./ha-form-positive_time_period_dict"; import "./ha-form-select"; import "./ha-form-string"; +import { HaFormElement, HaFormDataContainer, HaFormSchema } from "./types"; -export type HaFormSchema = - | HaFormConstantSchema - | HaFormStringSchema - | HaFormIntegerSchema - | HaFormFloatSchema - | HaFormBooleanSchema - | HaFormSelectSchema - | HaFormMultiSelectSchema - | HaFormTimeSchema; - -export interface HaFormBaseSchema { - name: string; - default?: HaFormData; - required?: boolean; - optional?: boolean; - description?: { suffix?: string; suggested_value?: HaFormData }; -} - -export interface HaFormConstantSchema extends HaFormBaseSchema { - type: "constant"; - value: string; -} - -export interface HaFormIntegerSchema extends HaFormBaseSchema { - type: "integer"; - default?: HaFormIntegerData; - valueMin?: number; - valueMax?: number; -} - -export interface HaFormSelectSchema extends HaFormBaseSchema { - type: "select"; - options?: string[] | Array<[string, string]>; -} - -export interface HaFormMultiSelectSchema extends HaFormBaseSchema { - type: "multi_select"; - options?: Record | string[] | Array<[string, string]>; -} - -export interface HaFormFloatSchema extends HaFormBaseSchema { - type: "float"; -} - -export interface HaFormStringSchema extends HaFormBaseSchema { - type: "string"; - format?: string; -} - -export interface HaFormBooleanSchema extends HaFormBaseSchema { - type: "boolean"; -} - -export interface HaFormTimeSchema extends HaFormBaseSchema { - type: "positive_time_period_dict"; -} - -export interface HaFormDataContainer { - [key: string]: HaFormData; -} - -export type HaFormData = - | HaFormStringData - | HaFormIntegerData - | HaFormFloatData - | HaFormBooleanData - | HaFormSelectData - | HaFormMultiSelectData - | HaFormTimeData; - -export type HaFormStringData = string; -export type HaFormIntegerData = number; -export type HaFormFloatData = number; -export type HaFormBooleanData = boolean; -export type HaFormSelectData = string; -export type HaFormMultiSelectData = string[]; -export type HaFormTimeData = HaDurationData; - -export interface HaFormElement extends LitElement { - schema: HaFormSchema | HaFormSchema[]; - data?: HaFormDataContainer | HaFormData; - label?: string; - suffix?: string; -} +const getValue = (obj, item) => (obj ? obj[item.name] : null); @customElement("ha-form") export class HaForm extends LitElement implements HaFormElement { - @property() public data!: HaFormDataContainer | HaFormData; + @property() public data!: HaFormDataContainer; - @property() public schema!: HaFormSchema | HaFormSchema[]; + @property() public schema!: HaFormSchema[]; - @property() public error; + @property() public error?: Record; @property() public computeError?: (schema: HaFormSchema, error) => string; @property() public computeLabel?: (schema: HaFormSchema) => string; - @property() public computeSuffix?: (schema: HaFormSchema) => string; - public focus() { - const input = - this.shadowRoot!.getElementById("child-form") || - this.shadowRoot!.querySelector("ha-form"); - if (!input) { + const root = this.shadowRoot?.querySelector(".root"); + if (!root) { return; } - (input as HTMLElement).focus(); + for (const child of root.children) { + if (child.tagName !== "HA-ALERT") { + (child as HTMLElement).focus(); + break; + } + } } protected render() { - if (Array.isArray(this.schema)) { - return html` + return html` +
${this.error && this.error.base ? html` -
+ ${this._computeError(this.error.base, this.schema)} -
+ ` : ""} - ${this.schema.map( - (item) => html` - - ` - )} - `; - } - - return html` - ${this.error - ? html` -
- ${this._computeError(this.error, this.schema)} -
- ` - : ""} - ${dynamicElement(`ha-form-${this.schema.type}`, { - schema: this.schema, - data: this.data, - label: this._computeLabel(this.schema), - suffix: this._computeSuffix(this.schema), - id: "child-form", - })} + ${this.schema.map((item) => { + const error = getValue(this.error, item); + return html` + ${error + ? html` + + ${this._computeError(error, item)} + + ` + : ""} + ${dynamicElement(`ha-form-${item.type}`, { + schema: item, + data: getValue(this.data, item), + label: this._computeLabel(item), + })} + `; + })} +
`; } + protected createRenderRoot() { + const root = super.createRenderRoot(); + // attach it as soon as possible to make sure we fetch all events. + root.addEventListener("value-changed", (ev) => { + ev.stopPropagation(); + const schema = (ev.target as HaFormElement).schema as HaFormSchema; + fireEvent(this, "value-changed", { + value: { ...this.data, [schema.name]: ev.detail.value }, + }); + }); + return root; + } + private _computeLabel(schema: HaFormSchema) { return this.computeLabel ? this.computeLabel(schema) @@ -173,38 +92,25 @@ export class HaForm extends LitElement implements HaFormElement { : ""; } - private _computeSuffix(schema: HaFormSchema) { - return this.computeSuffix - ? this.computeSuffix(schema) - : schema && schema.description - ? schema.description.suffix - : ""; - } - private _computeError(error, schema: HaFormSchema | HaFormSchema[]) { return this.computeError ? this.computeError(error, schema) : error; } - private _getValue(obj, item) { - if (obj) { - return obj[item.name]; - } - return null; - } - - private _valueChanged(ev: CustomEvent) { - ev.stopPropagation(); - const schema = (ev.target as HaFormElement).schema as HaFormSchema; - const data = this.data as HaFormDataContainer; - fireEvent(this, "value-changed", { - value: { ...data, [schema.name]: ev.detail.value }, - }); - } - static get styles(): CSSResultGroup { + // .root has overflow: auto to avoid margin collapse return css` - .error { - color: var(--error-color); + .root { + margin-bottom: -24px; + overflow: auto; + } + .root > * { + display: block; + } + .root > *:not([own-margin]) { + margin-bottom: 24px; + } + ha-alert[own-margin] { + margin-bottom: 4px; } `; } diff --git a/src/components/ha-form/types.ts b/src/components/ha-form/types.ts new file mode 100644 index 0000000000..ad740b625f --- /dev/null +++ b/src/components/ha-form/types.ts @@ -0,0 +1,86 @@ +import type { LitElement } from "lit"; +import type { HaDurationData } from "../ha-duration-input"; + +export type HaFormSchema = + | HaFormConstantSchema + | HaFormStringSchema + | HaFormIntegerSchema + | HaFormFloatSchema + | HaFormBooleanSchema + | HaFormSelectSchema + | HaFormMultiSelectSchema + | HaFormTimeSchema; + +export interface HaFormBaseSchema { + name: string; + default?: HaFormData; + required?: boolean; + optional?: boolean; + description?: { suffix?: string; suggested_value?: HaFormData }; +} + +export interface HaFormConstantSchema extends HaFormBaseSchema { + type: "constant"; + value: string; +} + +export interface HaFormIntegerSchema extends HaFormBaseSchema { + type: "integer"; + default?: HaFormIntegerData; + valueMin?: number; + valueMax?: number; +} + +export interface HaFormSelectSchema extends HaFormBaseSchema { + type: "select"; + options: Array<[string, string]>; +} + +export interface HaFormMultiSelectSchema extends HaFormBaseSchema { + type: "multi_select"; + options: Record; +} + +export interface HaFormFloatSchema extends HaFormBaseSchema { + type: "float"; +} + +export interface HaFormStringSchema extends HaFormBaseSchema { + type: "string"; + format?: string; +} + +export interface HaFormBooleanSchema extends HaFormBaseSchema { + type: "boolean"; +} + +export interface HaFormTimeSchema extends HaFormBaseSchema { + type: "positive_time_period_dict"; +} + +export interface HaFormDataContainer { + [key: string]: HaFormData; +} + +export type HaFormData = + | HaFormStringData + | HaFormIntegerData + | HaFormFloatData + | HaFormBooleanData + | HaFormSelectData + | HaFormMultiSelectData + | HaFormTimeData; + +export type HaFormStringData = string; +export type HaFormIntegerData = number; +export type HaFormFloatData = number; +export type HaFormBooleanData = boolean; +export type HaFormSelectData = string; +export type HaFormMultiSelectData = string[]; +export type HaFormTimeData = HaDurationData; + +export interface HaFormElement extends LitElement { + schema: HaFormSchema | HaFormSchema[]; + data?: HaFormDataContainer | HaFormData; + label?: string; +} diff --git a/src/data/data_entry_flow.ts b/src/data/data_entry_flow.ts index 8be5367632..d617b37020 100644 --- a/src/data/data_entry_flow.ts +++ b/src/data/data_entry_flow.ts @@ -1,5 +1,5 @@ import { Connection } from "home-assistant-js-websocket"; -import { HaFormSchema } from "../components/ha-form/ha-form"; +import type { HaFormSchema } from "../components/ha-form/types"; import { ConfigEntry } from "./config_entries"; export interface DataEntryFlowProgressedEvent { diff --git a/src/data/device_automation.ts b/src/data/device_automation.ts index 0131a451a2..b047f87f1e 100644 --- a/src/data/device_automation.ts +++ b/src/data/device_automation.ts @@ -1,5 +1,5 @@ import { computeStateName } from "../common/entity/compute_state_name"; -import { HaFormSchema } from "../components/ha-form/ha-form"; +import type { HaFormSchema } from "../components/ha-form/types"; import { HomeAssistant } from "../types"; import { BaseTrigger } from "./automation"; diff --git a/src/data/hassio/addon.ts b/src/data/hassio/addon.ts index c2e43ac046..93ac68c506 100644 --- a/src/data/hassio/addon.ts +++ b/src/data/hassio/addon.ts @@ -1,5 +1,5 @@ import { atLeastVersion } from "../../common/config/version"; -import { HaFormSchema } from "../../components/ha-form/ha-form"; +import type { HaFormSchema } from "../../components/ha-form/types"; import { HomeAssistant } from "../../types"; import { SupervisorArch } from "../supervisor/supervisor"; import { diff --git a/src/data/zha.ts b/src/data/zha.ts index b3b3944f1b..b8c99e0e24 100644 --- a/src/data/zha.ts +++ b/src/data/zha.ts @@ -1,5 +1,5 @@ import { HassEntity } from "home-assistant-js-websocket"; -import { HaFormSchema } from "../components/ha-form/ha-form"; +import type { HaFormSchema } from "../components/ha-form/types"; import { HomeAssistant } from "../types"; export interface ZHAEntityReference extends HassEntity { diff --git a/src/dialogs/config-flow/show-dialog-data-entry-flow.ts b/src/dialogs/config-flow/show-dialog-data-entry-flow.ts index 45a914acf8..c1141d729a 100644 --- a/src/dialogs/config-flow/show-dialog-data-entry-flow.ts +++ b/src/dialogs/config-flow/show-dialog-data-entry-flow.ts @@ -1,6 +1,6 @@ import { TemplateResult } from "lit"; import { fireEvent } from "../../common/dom/fire_event"; -import { HaFormSchema } from "../../components/ha-form/ha-form"; +import type { HaFormSchema } from "../../components/ha-form/types"; import { DataEntryFlowStep, DataEntryFlowStepAbort, diff --git a/src/dialogs/config-flow/step-flow-form.ts b/src/dialogs/config-flow/step-flow-form.ts index 1c2d017826..1b7865bd4b 100644 --- a/src/dialogs/config-flow/step-flow-form.ts +++ b/src/dialogs/config-flow/step-flow-form.ts @@ -11,9 +11,11 @@ import { import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-circular-progress"; +import { computeInitialHaFormData } from "../../components/ha-form/compute-initial-ha-form-data"; +import type { HaFormSchema } from "../../components/ha-form/types"; import "../../components/ha-form/ha-form"; -import type { HaFormSchema } from "../../components/ha-form/ha-form"; import "../../components/ha-markdown"; +import "../../components/ha-alert"; import type { DataEntryFlowStepForm } from "../../data/data_entry_flow"; import type { HomeAssistant } from "../../types"; import type { FlowConfig } from "./show-dialog-data-entry-flow"; @@ -37,24 +39,13 @@ class StepFlowForm extends LitElement { const step = this.step; const stepData = this._stepDataProcessed; - const allRequiredInfoFilledIn = - stepData === undefined - ? // If no data filled in, just check that any field is required - step.data_schema.find((field) => !field.optional) === undefined - : // If data is filled in, make sure all required fields are - stepData && - step.data_schema.every( - (field) => - field.optional || !["", undefined].includes(stepData![field.name]) - ); - return html`

${this.flowConfig.renderShowFormStepHeader(this.hass, this.step)}

- ${this._errorMsg - ? html`
${this._errorMsg}
` - : ""} ${this.flowConfig.renderShowFormStepDescription(this.hass, this.step)} + ${this._errorMsg + ? html`${this._errorMsg}` + : ""} - ${this.hass.localize( + + ${this.hass.localize( `ui.panel.config.integrations.config_flow.${ this.step.last_step === false ? "next" : "submit" }` )} - - ${!allRequiredInfoFilledIn - ? html` - ${this.hass.localize( - "ui.panel.config.integrations.config_flow.not_all_required_fields" - )} - - ` - : html``}
`}
@@ -113,25 +92,35 @@ class StepFlowForm extends LitElement { return this._stepData; } - const data = {}; - this.step.data_schema.forEach((field) => { - if (field.description?.suggested_value) { - data[field.name] = field.description.suggested_value; - } else if ("default" in field) { - data[field.name] = field.default; - } - }); - - this._stepData = data; - return data; + this._stepData = computeInitialHaFormData(this.step.data_schema); + return this._stepData; } private async _submitStep(): Promise { + const stepData = this._stepData || {}; + + const allRequiredInfoFilledIn = + stepData === undefined + ? // If no data filled in, just check that any field is required + this.step.data_schema.find((field) => !field.optional) === undefined + : // If data is filled in, make sure all required fields are + stepData && + this.step.data_schema.every( + (field) => + field.optional || !["", undefined].includes(stepData![field.name]) + ); + + if (!allRequiredInfoFilledIn) { + this._errorMsg = this.hass.localize( + "ui.panel.config.integrations.config_flow.not_all_required_fields" + ); + return; + } + this._loading = true; this._errorMsg = undefined; const flowId = this.step.flow_id; - const stepData = this._stepData || {}; const toSendData = {}; Object.keys(stepData).forEach((key) => { @@ -188,6 +177,12 @@ class StepFlowForm extends LitElement { .submit-spinner { margin-right: 16px; } + + ha-alert, + ha-form { + margin-top: 24px; + display: block; + } `, ]; } diff --git a/src/dialogs/config-flow/styles.ts b/src/dialogs/config-flow/styles.ts index 008fed7c1b..3f9d14b3c4 100644 --- a/src/dialogs/config-flow/styles.ts +++ b/src/dialogs/config-flow/styles.ts @@ -26,8 +26,8 @@ export const configFlowContentStyles = css` .buttons { position: relative; - padding: 8px 8px 8px 24px; - margin: 0; + padding: 8px 16px 8px 24px; + margin: 8px 0 0; color: var(--primary-color); display: flex; justify-content: flex-end; diff --git a/src/resources/ha-style.ts b/src/resources/ha-style.ts index a570a73c22..053efc7991 100644 --- a/src/resources/ha-style.ts +++ b/src/resources/ha-style.ts @@ -59,7 +59,7 @@ documentContainer.innerHTML = ` /* states */ --state-icon-color: #44739e; - /* an active state is anything that would require attention */ + /* an active state is anything that would require attention */ --state-icon-active-color: #FDD835; /* an error state is anything that would be considered an error */ /* --state-icon-error-color: #db4437; derived from error-color */ @@ -112,6 +112,20 @@ documentContainer.innerHTML = ` --rgb-text-primary-color: 255, 255, 255; --rgb-card-background-color: 255, 255, 255; + /* input components */ + --input-idle-line-color: rgba(0, 0, 0, 0.42); + --input-hover-line-color: rgba(0, 0, 0, 0.87); + --input-disabled-line-color: rgba(0, 0, 0, 0.06); + --input-outlined-idle-border-color: rgba(0, 0, 0, 0.38); + --input-outlined-hover-border-color: rgba(0, 0, 0, 0.87); + --input-outlined-disabled-border-color: rgba(0, 0, 0, 0.06); + --input-fill-color: rgb(245, 245, 245); + --input-disabled-fill-color: rgb(250, 250, 250); + --input-ink-color: rgba(0, 0, 0, 0.87); + --input-label-ink-color: rgba(0, 0, 0, 0.6); + --input-disabled-ink-color: rgba(0, 0, 0, 0.37); + --input-dropdown-icon-color: rgba(0, 0, 0, 0.54); + /* Vaadin typography */ --material-h6-font-size: 1.25rem; --material-small-font-size: 0.875rem; diff --git a/src/resources/styles.ts b/src/resources/styles.ts index 6f7cb696ab..19d0e34433 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -13,6 +13,20 @@ export const darkStyles = { "switch-unchecked-track-color": "#9b9b9b", "divider-color": "rgba(225, 225, 225, .12)", "mdc-ripple-color": "#AAAAAA", + + "input-idle-line-color": "rgba(255, 255, 255, 0.42)", + "input-hover-line-color": "rgba(255, 255, 255, 0.87)", + "input-disabled-line-color": "rgba(255, 255, 255, 0.06)", + "input-outlined-idle-border-color": "rgba(255, 255, 255, 0.38)", + "input-outlined-hover-border-color": "rgba(255, 255, 255, 0.87)", + "input-outlined-disabled-border-color": "rgba(255, 255, 255, 0.06)", + "input-fill-color": "rgb(10, 10, 10)", + "input-disabled-fill-color": "rgb(5, 5, 5)", + "input-ink-color": "rgba(255, 255, 255, 0.87)", + "input-label-ink-color": "rgba(255, 255, 255, 0.6)", + "input-disabled-ink-color": "rgba(255, 255, 255, 0.37)", + "input-dropdown-icon-color": "rgba(255, 255, 255, 0.54)", + "codemirror-keyword": "#C792EA", "codemirror-operator": "#89DDFF", "codemirror-variable": "#f07178", @@ -69,6 +83,8 @@ export const derivedStyles = { "paper-slider-container-color": "var(--slider-track-color)", "data-table-background-color": "var(--card-background-color)", "markdown-code-background-color": "var(--primary-background-color)", + + // https://github.com/material-components/material-web/blob/master/docs/theming.md "mdc-theme-primary": "var(--primary-color)", "mdc-theme-secondary": "var(--accent-color)", "mdc-theme-background": "var(--primary-background-color)", @@ -80,6 +96,7 @@ export const derivedStyles = { "mdc-theme-text-primary-on-background": "var(--primary-text-color)", "mdc-theme-text-secondary-on-background": "var(--secondary-text-color)", "mdc-theme-text-icon-on-background": "var(--secondary-text-color)", + "mdc-theme-error": "var(--error-color)", "app-header-text-color": "var(--text-primary-color)", "app-header-background-color": "var(--primary-color)", "mdc-checkbox-unchecked-color": "rgba(var(--rgb-primary-text-color), 0.54)", @@ -90,6 +107,38 @@ export const derivedStyles = { "mdc-button-disabled-ink-color": "var(--disabled-text-color)", "mdc-button-outline-color": "var(--divider-color)", "mdc-dialog-scroll-divider-color": "var(--divider-color)", + + "mdc-text-field-idle-line-color": "var(--input-idle-line-color)", + "mdc-text-field-hover-line-color": "var(--input-hover-line-color)", + "mdc-text-field-disabled-line-color": "var(--input-disabled-line-color)", + "mdc-text-field-outlined-idle-border-color": + "var(--input-outlined-idle-border-color)", + "mdc-text-field-outlined-hover-border-color": + "var(--input-outlined-hover-border-color)", + "mdc-text-field-outlined-disabled-border-color": + "var(--input-outlined-disabled-border-color)", + "mdc-text-field-fill-color": "var(--input-fill-color)", + "mdc-text-field-disabled-fill-color": "var(--input-disabled-fill-color)", + "mdc-text-field-ink-color": "var(--input-ink-color)", + "mdc-text-field-label-ink-color": "var(--input-label-ink-color)", + "mdc-text-field-disabled-ink-color": "var(--input-disabled-ink-color)", + + "mdc-select-idle-line-color": "var(--input-idle-line-color)", + "mdc-select-hover-line-color": "var(--input-hover-line-color)", + "mdc-select-outlined-idle-border-color": + "var(--input-outlined-idle-border-color)", + "mdc-select-outlined-hover-border-color": + "var(--input-outlined-hover-border-color)", + "mdc-select-outlined-disabled-border-color": + "var(--input-outlined-disabled-border-color)", + "mdc-select-fill-color": "var(--input-fill-color)", + "mdc-select-disabled-fill-color": "var(--input-disabled-fill-color)", + "mdc-select-ink-color": "var(--input-ink-color)", + "mdc-select-label-ink-color": "var(--input-label-ink-color)", + "mdc-select-disabled-ink-color": "var(--input-disabled-ink-color)", + "mdc-select-dropdown-icon-color": "var(--input-dropdown-icon-color)", + "mdc-select-disabled-dropdown-icon-color": "var(--input-disabled-ink-color)", + "chip-background-color": "rgba(var(--rgb-primary-text-color), 0.15)", // Vaadin "material-body-text-color": "var(--primary-text-color)", diff --git a/src/translations/en.json b/src/translations/en.json index 25c2034d3e..56c4430ea7 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3520,7 +3520,7 @@ "form": { "working": "Please wait", "unknown_error": "Something went wrong", - "next": "Next", + "next": "Login", "start_over": "Start over", "error": "Error: {error}", "providers": { diff --git a/yarn.lock b/yarn.lock index 9292abb467..597e15e935 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2149,7 +2149,7 @@ __metadata: languageName: node linkType: hard -"@material/floating-label@npm:13.0.0-canary.65125b3a6.0": +"@material/floating-label@npm:13.0.0-canary.65125b3a6.0, @material/floating-label@npm:=13.0.0-canary.65125b3a6.0": version: 13.0.0-canary.65125b3a6.0 resolution: "@material/floating-label@npm:13.0.0-canary.65125b3a6.0" dependencies: @@ -2197,7 +2197,7 @@ __metadata: languageName: node linkType: hard -"@material/line-ripple@npm:13.0.0-canary.65125b3a6.0": +"@material/line-ripple@npm:13.0.0-canary.65125b3a6.0, @material/line-ripple@npm:=13.0.0-canary.65125b3a6.0": version: 13.0.0-canary.65125b3a6.0 resolution: "@material/line-ripple@npm:13.0.0-canary.65125b3a6.0" dependencies: @@ -2359,6 +2359,18 @@ __metadata: languageName: node linkType: hard +"@material/mwc-floating-label@npm:^0.25.1": + version: 0.25.1 + resolution: "@material/mwc-floating-label@npm:0.25.1" + dependencies: + "@material/floating-label": =13.0.0-canary.65125b3a6.0 + lit-element: ^3.0.0 + lit-html: ^2.0.0 + tslib: ^2.0.1 + checksum: 22d91998c1d01115e8ac59b71b5fe35cb8dc7c781bedb191377659536c0f190d99d5965cab41e67fe3bfc5100fdcdb0659c3f52b3712e89e4ae3994f5dc8319e + languageName: node + linkType: hard + "@material/mwc-formfield@npm:0.25.1": version: 0.25.1 resolution: "@material/mwc-formfield@npm:0.25.1" @@ -2393,6 +2405,18 @@ __metadata: languageName: node linkType: hard +"@material/mwc-line-ripple@npm:^0.25.1": + version: 0.25.1 + resolution: "@material/mwc-line-ripple@npm:0.25.1" + dependencies: + "@material/line-ripple": =13.0.0-canary.65125b3a6.0 + lit-element: ^3.0.0 + lit-html: ^2.0.0 + tslib: ^2.0.1 + checksum: 5897f55cd11e134a2adea03b4cffaa46bf5d8fb71dff2c0601a53960f4ff35a4ba82ea443bdbe72daca801d3abc1b7a459bd980dbeab59dbd7b216b5e10fc1f2 + languageName: node + linkType: hard + "@material/mwc-linear-progress@npm:0.25.1": version: 0.25.1 resolution: "@material/mwc-linear-progress@npm:0.25.1" @@ -2425,7 +2449,7 @@ __metadata: languageName: node linkType: hard -"@material/mwc-menu@npm:0.25.1": +"@material/mwc-menu@npm:0.25.1, @material/mwc-menu@npm:^0.25.1": version: 0.25.1 resolution: "@material/mwc-menu@npm:0.25.1" dependencies: @@ -2442,6 +2466,19 @@ __metadata: languageName: node linkType: hard +"@material/mwc-notched-outline@npm:^0.25.1": + version: 0.25.1 + resolution: "@material/mwc-notched-outline@npm:0.25.1" + dependencies: + "@material/mwc-base": ^0.25.1 + "@material/notched-outline": =13.0.0-canary.65125b3a6.0 + lit-element: ^3.0.0 + lit-html: ^2.0.0 + tslib: ^2.0.1 + checksum: e86709d2f0b6b118a8ba606055c1e8a633919a834e05b4bf897d472206a6031e9ec20b20cdcccbc1d364939ea948e60aea4132eb17c4225938cc059ab370f301 + languageName: node + linkType: hard + "@material/mwc-radio@npm:0.25.1, @material/mwc-radio@npm:^0.25.1": version: 0.25.1 resolution: "@material/mwc-radio@npm:0.25.1" @@ -2469,6 +2506,44 @@ __metadata: languageName: node linkType: hard +"@material/mwc-select@npm:^0.25.1": + version: 0.25.1 + resolution: "@material/mwc-select@npm:0.25.1" + dependencies: + "@material/dom": =13.0.0-canary.65125b3a6.0 + "@material/floating-label": =13.0.0-canary.65125b3a6.0 + "@material/line-ripple": =13.0.0-canary.65125b3a6.0 + "@material/list": =13.0.0-canary.65125b3a6.0 + "@material/mwc-base": ^0.25.1 + "@material/mwc-floating-label": ^0.25.1 + "@material/mwc-icon": ^0.25.1 + "@material/mwc-line-ripple": ^0.25.1 + "@material/mwc-list": ^0.25.1 + "@material/mwc-menu": ^0.25.1 + "@material/mwc-notched-outline": ^0.25.1 + "@material/select": =13.0.0-canary.65125b3a6.0 + lit-element: ^3.0.0 + lit-html: ^2.0.0 + tslib: ^2.0.1 + checksum: 542c24e93e16d0a9f101765679c14e823a0c6fd3932b6f33e6a0bd440e436265c2571505db850be3dcff09e0a05d79ffecdc55e0e1340ba8722e181ed3667529 + languageName: node + linkType: hard + +"@material/mwc-slider@npm:^0.25.1": + version: 0.25.1 + resolution: "@material/mwc-slider@npm:0.25.1" + dependencies: + "@material/dom": =13.0.0-canary.65125b3a6.0 + "@material/mwc-base": ^0.25.1 + "@material/mwc-ripple": ^0.25.1 + "@material/slider": =13.0.0-canary.65125b3a6.0 + lit-element: ^3.0.0 + lit-html: ^2.0.0 + tslib: ^2.0.1 + checksum: 964ba94e12b2aee8e67b19e0d4fc7b8a8a4945be8bef82aa3a305247b2e318709d1d3ffd9761f87a920f85538a863aca59c2746f8bd85e82125c1d15f98c8768 + languageName: node + linkType: hard + "@material/mwc-switch@npm:0.25.1": version: 0.25.1 resolution: "@material/mwc-switch@npm:0.25.1" @@ -2538,7 +2613,25 @@ __metadata: languageName: node linkType: hard -"@material/notched-outline@npm:13.0.0-canary.65125b3a6.0": +"@material/mwc-textfield@npm:^0.25.1": + version: 0.25.1 + resolution: "@material/mwc-textfield@npm:0.25.1" + dependencies: + "@material/floating-label": =13.0.0-canary.65125b3a6.0 + "@material/line-ripple": =13.0.0-canary.65125b3a6.0 + "@material/mwc-base": ^0.25.1 + "@material/mwc-floating-label": ^0.25.1 + "@material/mwc-line-ripple": ^0.25.1 + "@material/mwc-notched-outline": ^0.25.1 + "@material/textfield": =13.0.0-canary.65125b3a6.0 + lit-element: ^3.0.0 + lit-html: ^2.0.0 + tslib: ^2.0.1 + checksum: 31a0235c4b50dcbff28d913c90be114b2972edceb753b17eb84f47cdb46459716a70ee939e9853b8e9ce86af0105e48fea31700e8bac5c30dfadba0f1d5b2235 + languageName: node + linkType: hard + +"@material/notched-outline@npm:13.0.0-canary.65125b3a6.0, @material/notched-outline@npm:=13.0.0-canary.65125b3a6.0": version: 13.0.0-canary.65125b3a6.0 resolution: "@material/notched-outline@npm:13.0.0-canary.65125b3a6.0" dependencies: @@ -2604,7 +2697,7 @@ __metadata: languageName: node linkType: hard -"@material/select@npm:13.0.0-canary.65125b3a6.0": +"@material/select@npm:13.0.0-canary.65125b3a6.0, @material/select@npm:=13.0.0-canary.65125b3a6.0": version: 13.0.0-canary.65125b3a6.0 resolution: "@material/select@npm:13.0.0-canary.65125b3a6.0" dependencies: @@ -2641,6 +2734,24 @@ __metadata: languageName: node linkType: hard +"@material/slider@npm:=13.0.0-canary.65125b3a6.0": + version: 13.0.0-canary.65125b3a6.0 + resolution: "@material/slider@npm:13.0.0-canary.65125b3a6.0" + dependencies: + "@material/animation": 13.0.0-canary.65125b3a6.0 + "@material/base": 13.0.0-canary.65125b3a6.0 + "@material/dom": 13.0.0-canary.65125b3a6.0 + "@material/elevation": 13.0.0-canary.65125b3a6.0 + "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 + "@material/ripple": 13.0.0-canary.65125b3a6.0 + "@material/rtl": 13.0.0-canary.65125b3a6.0 + "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/typography": 13.0.0-canary.65125b3a6.0 + tslib: ^2.1.0 + checksum: 26f6de62b296296b196cfa31193e137f91da8a4eb6c1e8c7209a73eac3c2d4bbbb412e020b715942ab861632701a6c9931e8b845a4f7cc92b6700f43b811c50c + languageName: node + linkType: hard + "@material/switch@npm:=13.0.0-canary.65125b3a6.0": version: 13.0.0-canary.65125b3a6.0 resolution: "@material/switch@npm:13.0.0-canary.65125b3a6.0" @@ -2724,6 +2835,28 @@ __metadata: languageName: node linkType: hard +"@material/textfield@npm:=13.0.0-canary.65125b3a6.0": + version: 13.0.0-canary.65125b3a6.0 + resolution: "@material/textfield@npm:13.0.0-canary.65125b3a6.0" + dependencies: + "@material/animation": 13.0.0-canary.65125b3a6.0 + "@material/base": 13.0.0-canary.65125b3a6.0 + "@material/density": 13.0.0-canary.65125b3a6.0 + "@material/dom": 13.0.0-canary.65125b3a6.0 + "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 + "@material/floating-label": 13.0.0-canary.65125b3a6.0 + "@material/line-ripple": 13.0.0-canary.65125b3a6.0 + "@material/notched-outline": 13.0.0-canary.65125b3a6.0 + "@material/ripple": 13.0.0-canary.65125b3a6.0 + "@material/rtl": 13.0.0-canary.65125b3a6.0 + "@material/shape": 13.0.0-canary.65125b3a6.0 + "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/typography": 13.0.0-canary.65125b3a6.0 + tslib: ^2.1.0 + checksum: 1be6d8c1941729a580cb56fd9079049e9cb0dc9c648708af19683a11bd2f14b21b212cc8cf41f77c8cac9441438fe1f17696b70264daf8e0ff72f22baec7136a + languageName: node + linkType: hard + "@material/theme@npm:13.0.0-canary.65125b3a6.0, @material/theme@npm:=13.0.0-canary.65125b3a6.0": version: 13.0.0-canary.65125b3a6.0 resolution: "@material/theme@npm:13.0.0-canary.65125b3a6.0" @@ -8978,9 +9111,12 @@ fsevents@^1.2.7: "@material/mwc-menu": 0.25.1 "@material/mwc-radio": 0.25.1 "@material/mwc-ripple": 0.25.1 + "@material/mwc-select": ^0.25.1 + "@material/mwc-slider": ^0.25.1 "@material/mwc-switch": 0.25.1 "@material/mwc-tab": 0.25.1 "@material/mwc-tab-bar": 0.25.1 + "@material/mwc-textfield": ^0.25.1 "@material/top-app-bar": 13.0.0-canary.65125b3a6.0 "@mdi/js": 6.2.95 "@mdi/svg": 6.2.95 From 807ce468d6cabda61e7e763f38edadd3ace3957a Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 7 Oct 2021 23:27:35 +0200 Subject: [PATCH 002/115] Dont create icon for supervisor (#10191) --- build-scripts/gulp/hassio.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/build-scripts/gulp/hassio.js b/build-scripts/gulp/hassio.js index 696e742a05..08370ad7c6 100644 --- a/build-scripts/gulp/hassio.js +++ b/build-scripts/gulp/hassio.js @@ -17,7 +17,6 @@ gulp.task( process.env.NODE_ENV = "development"; }, "clean-hassio", - "gen-icons-json", "gen-index-hassio-dev", "build-supervisor-translations", "copy-translations-supervisor", @@ -34,7 +33,6 @@ gulp.task( process.env.NODE_ENV = "production"; }, "clean-hassio", - "gen-icons-json", "build-supervisor-translations", "copy-translations-supervisor", "build-locale-data", From 84c4bbd3801cf8695d848ed090328906d0544d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Fri, 8 Oct 2021 16:41:21 +0200 Subject: [PATCH 003/115] Fix import (#10206) --- src/components/ha-form/ha-form-multi_select.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ha-form/ha-form-multi_select.ts b/src/components/ha-form/ha-form-multi_select.ts index 7267856322..ede546e43e 100644 --- a/src/components/ha-form/ha-form-multi_select.ts +++ b/src/components/ha-form/ha-form-multi_select.ts @@ -12,7 +12,7 @@ import { import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import "../ha-button-menu"; -import "../ha-icon"; +import "../ha-svg-icon"; import { HaFormElement, HaFormMultiSelectData, From 038033cf27fb72ef502c1e0b5efe47fadd6305b1 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 8 Oct 2021 17:16:44 +0200 Subject: [PATCH 004/115] Add "gas" device_class to customize (and sort existing ones) (#10196) --- src/common/const.ts | 11 ++++++----- src/util/hass-attributes-util.ts | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/common/const.ts b/src/common/const.ts index 75413b8044..dbc9ba4aac 100644 --- a/src/common/const.ts +++ b/src/common/const.ts @@ -57,28 +57,29 @@ export const FIXED_DOMAIN_ICONS = { export const FIXED_DEVICE_CLASS_ICONS = { aqi: "hass:air-filter", - current: "hass:current-ac", + battery: "hass:battery", carbon_dioxide: "mdi:molecule-co2", carbon_monoxide: "mdi:molecule-co", + current: "hass:current-ac", date: "hass:calendar", energy: "hass:lightning-bolt", gas: "hass:gas-cylinder", humidity: "hass:water-percent", illuminance: "hass:brightness-5", + monetary: "mdi:cash", nitrogen_dioxide: "mdi:molecule", nitrogen_monoxide: "mdi:molecule", nitrous_oxide: "mdi:molecule", ozone: "mdi:molecule", - temperature: "hass:thermometer", - monetary: "mdi:cash", - pm25: "mdi:molecule", pm1: "mdi:molecule", pm10: "mdi:molecule", - pressure: "hass:gauge", + pm25: "mdi:molecule", power: "hass:flash", power_factor: "hass:angle-acute", + pressure: "hass:gauge", signal_strength: "hass:wifi", sulphur_dioxide: "mdi:molecule", + temperature: "hass:thermometer", timestamp: "hass:clock", volatile_organic_compounds: "mdi:molecule", voltage: "hass:sine-wave", diff --git a/src/util/hass-attributes-util.ts b/src/util/hass-attributes-util.ts index 5025aa1766..f237e082ce 100644 --- a/src/util/hass-attributes-util.ts +++ b/src/util/hass-attributes-util.ts @@ -58,19 +58,20 @@ const hassAttributeUtil = { "current", "date", "energy", + "gas", "humidity", "illuminance", + "monetary", "nitrogen_dioxide", "nitrogen_monoxide", "nitrous_oxide", "ozone", - "pm25", "pm1", "pm10", + "pm25", "power", "power_factor", "pressure", - "monetary", "signal_strength", "sulphur_dioxide", "temperature", From 588ee2c3b13f10db1c7f172cd9956d21f5b79c4b Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Fri, 8 Oct 2021 17:17:41 +0200 Subject: [PATCH 005/115] Make zone names readable on map in dark mode (#10195) --- src/components/map/ha-map.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/map/ha-map.ts b/src/components/map/ha-map.ts index c34a819d51..2835ebb2fc 100644 --- a/src/components/map/ha-map.ts +++ b/src/components/map/ha-map.ts @@ -484,6 +484,7 @@ export class HaMap extends ReactiveElement { justify-content: center; flex-direction: column; text-align: center; + color: var(--primary-text-color); } `; } From ad031d4bda119e52800853e82e07dc44e7d910d8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 8 Oct 2021 08:19:02 -0700 Subject: [PATCH 006/115] Tweak ha-form (#10194) --- src/components/ha-form/ha-form-float.ts | 1 + src/components/ha-form/ha-form-integer.ts | 1 + src/components/ha-form/ha-form-multi_select.ts | 13 +++++++++---- src/components/paper-time-input.js | 3 +++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/components/ha-form/ha-form-float.ts b/src/components/ha-form/ha-form-float.ts index 032956a7e5..0571b43c83 100644 --- a/src/components/ha-form/ha-form-float.ts +++ b/src/components/ha-form/ha-form-float.ts @@ -24,6 +24,7 @@ export class HaFormFloat extends LitElement implements HaFormElement { protected render(): TemplateResult { return html` Date: Fri, 8 Oct 2021 10:48:39 -0700 Subject: [PATCH 007/115] Extract black/white row into component (#10212) * Extract black/white row into component * Remove unused import --- .../src/components/demo-black-white-row.ts | 122 ++++++++++++++ gallery/src/demos/demo-ha-form.ts | 151 +++--------------- 2 files changed, 143 insertions(+), 130 deletions(-) create mode 100644 gallery/src/components/demo-black-white-row.ts diff --git a/gallery/src/components/demo-black-white-row.ts b/gallery/src/components/demo-black-white-row.ts new file mode 100644 index 0000000000..002d7510c2 --- /dev/null +++ b/gallery/src/components/demo-black-white-row.ts @@ -0,0 +1,122 @@ +import { html, LitElement, css, TemplateResult } from "lit"; +import { customElement, property } from "lit/decorators"; +import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; + +@customElement("demo-black-white-row") +class DemoBlackWhiteRow extends LitElement { + @property() title!: string; + + @property() value!: any; + + protected render(): TemplateResult { + return html` +
+
+ +
+ +
+
+ Submit +
+
+
+
+ +
+ +
+
+ Submit +
+
+
${JSON.stringify(this.value, undefined, 2)}
+
+
+ `; + } + + firstUpdated(changedProps) { + super.firstUpdated(changedProps); + applyThemesOnElement( + this.shadowRoot!.querySelector(".dark"), + { + default_theme: "default", + default_dark_theme: "default", + themes: {}, + darkMode: false, + }, + "default", + { dark: true } + ); + } + + static styles = css` + .row { + display: flex; + } + .content { + padding: 50px 0; + background-color: var(--primary-background-color); + } + .light { + flex: 1; + padding-left: 50px; + padding-right: 50px; + box-sizing: border-box; + } + .light ha-card { + margin-left: auto; + } + .dark { + display: flex; + flex: 1; + padding-left: 50px; + box-sizing: border-box; + flex-wrap: wrap; + } + ha-card { + width: 400px; + } + pre { + width: 300px; + margin: 0 16px 0; + overflow: auto; + color: var(--primary-text-color); + } + .card-actions { + display: flex; + flex-direction: row-reverse; + border-top: none; + } + @media only screen and (max-width: 1500px) { + .light { + flex: initial; + } + } + @media only screen and (max-width: 1000px) { + .light, + .dark { + padding: 16px; + } + .row, + .dark { + flex-direction: column; + } + ha-card { + margin: 0 auto; + width: 100%; + max-width: 400px; + } + pre { + margin: 16px auto; + } + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-black-white-row": DemoBlackWhiteRow; + } +} diff --git a/gallery/src/demos/demo-ha-form.ts b/gallery/src/demos/demo-ha-form.ts index 38266cd602..5dc69ece51 100644 --- a/gallery/src/demos/demo-ha-form.ts +++ b/gallery/src/demos/demo-ha-form.ts @@ -1,12 +1,11 @@ /* eslint-disable lit/no-template-arrow */ import "@material/mwc-button"; -import { LitElement, TemplateResult, css, html } from "lit"; +import { LitElement, TemplateResult, html } from "lit"; import { customElement } from "lit/decorators"; import { computeInitialHaFormData } from "../../../src/components/ha-form/compute-initial-ha-form-data"; -import "../../../src/components/ha-card"; -import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; import type { HaFormSchema } from "../../../src/components/ha-form/types"; import "../../../src/components/ha-form/ha-form"; +import "../components/demo-black-white-row"; const SCHEMAS: { title: string; @@ -235,138 +234,30 @@ class DemoHaForm extends LitElement { return html` ${SCHEMAS.map((info, idx) => { const translations = info.translations || {}; - const computeLabel = (schema) => - translations[schema.name] || schema.name; - const computeError = (error) => translations[error] || error; - return html` -
-
- -
- { - this.data[idx] = e.detail.value; - this.requestUpdate(); - }} - > -
-
- Submit -
-
-
-
- -
- { - this.data[idx] = e.detail.value; - this.requestUpdate(); - }} - > -
-
- Submit -
-
-
${JSON.stringify(this.data[idx], undefined, 2)}
-
-
+ + ${["light", "dark"].map( + (slot) => html` + translations[error] || error} + .computeLabel=${(schema) => + translations[schema.name] || schema.name} + @value-changed=${(e) => { + this.data[idx] = e.detail.value; + this.requestUpdate(); + }} + > + ` + )} + `; })} `; } - - firstUpdated(changedProps) { - super.firstUpdated(changedProps); - this.shadowRoot!.querySelectorAll(".dark").forEach((el) => { - applyThemesOnElement( - el, - { - default_theme: "default", - default_dark_theme: "default", - themes: {}, - darkMode: false, - }, - "default", - { dark: true } - ); - }); - } - - static styles = css` - .row { - display: flex; - } - .content { - padding: 50px 0; - background-color: var(--primary-background-color); - } - .light { - flex: 1; - padding-left: 50px; - padding-right: 50px; - box-sizing: border-box; - } - .light ha-card { - margin-left: auto; - } - .dark { - display: flex; - flex: 1; - padding-left: 50px; - box-sizing: border-box; - flex-wrap: wrap; - } - ha-card { - width: 400px; - } - pre { - width: 300px; - margin: 0 16px 0; - overflow: auto; - color: var(--primary-text-color); - } - .card-actions { - display: flex; - flex-direction: row-reverse; - border-top: none; - } - @media only screen and (max-width: 1500px) { - .light { - flex: initial; - } - } - @media only screen and (max-width: 1000px) { - .light, - .dark { - padding: 16px; - } - .row, - .dark { - flex-direction: column; - } - ha-card { - margin: 0 auto; - width: 100%; - max-width: 400px; - } - pre { - margin: 16px auto; - } - } - `; } declare global { From 4358b7f92466150604873f75d0d2749613ff11a2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 8 Oct 2021 20:32:13 +0200 Subject: [PATCH 008/115] Fix dirty check/leaving automation editor (#10211) --- src/panels/config/automation/ha-automation-editor.ts | 4 +++- src/panels/config/automation/manual-automation-editor.ts | 5 ++++- .../config/automation/trigger/ha-automation-trigger-row.ts | 2 +- src/panels/config/scene/ha-scene-editor.ts | 5 +++-- src/panels/config/script/ha-script-editor.ts | 4 +++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 8ab69fa05f..e25751c3ef 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -443,7 +443,9 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ), confirmText: this.hass!.localize("ui.common.leave"), dismissText: this.hass!.localize("ui.common.stay"), - confirm: () => history.back(), + confirm: () => { + setTimeout(() => history.back()); + }, }); } else { history.back(); diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index 97ea0d1d40..ff70b33195 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -267,7 +267,10 @@ export class HaManualAutomationEditor extends LitElement { const mode = ((ev.target as PaperListboxElement)?.selectedItem as any) ?.mode; - if (mode === this.config!.mode) { + if ( + mode === this.config!.mode || + (!this.config!.mode && mode === MODES[0]) + ) { return; } const value = { diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index 5d4b88933d..6444b6aaef 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -263,7 +263,7 @@ export default class HaAutomationTriggerRow extends LitElement { private _idChanged(ev: CustomEvent) { const newId = ev.detail.value; - if (newId === this.trigger.id) { + if (newId === (this.trigger.id ?? "")) { return; } const value = { ...this.trigger }; diff --git a/src/panels/config/scene/ha-scene-editor.ts b/src/panels/config/scene/ha-scene-editor.ts index 6c51a61af4..45bbf6740a 100644 --- a/src/panels/config/scene/ha-scene-editor.ts +++ b/src/panels/config/scene/ha-scene-editor.ts @@ -555,7 +555,7 @@ export class HaSceneEditor extends SubscribeMixin( try { config = await getSceneConfig(this.hass, this.sceneId!); } catch (err: any) { - showAlertDialog(this, { + await showAlertDialog(this, { text: err.status_code === 404 ? this.hass.localize( @@ -566,7 +566,8 @@ export class HaSceneEditor extends SubscribeMixin( "err_no", err.status_code ), - }).then(() => history.back()); + }); + history.back(); return; } diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index ccba2b3ecd..315f2dc2f3 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -586,7 +586,9 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ), confirmText: this.hass!.localize("ui.common.leave"), dismissText: this.hass!.localize("ui.common.stay"), - confirm: () => history.back(), + confirm: () => { + setTimeout(() => history.back()); + }, }); } else { history.back(); From 6f6fc759cc90f39966983b55d19d289003155722 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 8 Oct 2021 11:56:32 -0700 Subject: [PATCH 009/115] Add selector demo to gallery (#10213) --- build-scripts/bundle.js | 3 + build-scripts/gulp/webpack.js | 1 + demo/src/stubs/area_registry.ts | 7 ++ demo/src/stubs/device_registry.ts | 7 ++ demo/src/stubs/entity_registry.ts | 7 ++ demo/src/stubs/hassio_supervisor.ts | 59 ++++++++++++ gallery/src/demos/demo-ha-selector.ts | 131 ++++++++++++++++++++++++++ src/common/config/version.ts | 4 + 8 files changed, 219 insertions(+) create mode 100644 demo/src/stubs/area_registry.ts create mode 100644 demo/src/stubs/device_registry.ts create mode 100644 demo/src/stubs/entity_registry.ts create mode 100644 demo/src/stubs/hassio_supervisor.ts create mode 100644 gallery/src/demos/demo-ha-selector.ts diff --git a/build-scripts/bundle.js b/build-scripts/bundle.js index 277fa54bee..c15e1ab1dc 100644 --- a/build-scripts/bundle.js +++ b/build-scripts/bundle.js @@ -210,6 +210,9 @@ module.exports.config = { publicPath: publicPath(latestBuild), isProdBuild, latestBuild, + defineOverlay: { + __DEMO__: true, + }, }; }, }; diff --git a/build-scripts/gulp/webpack.js b/build-scripts/gulp/webpack.js index e257fd58a7..2d6e0a863f 100644 --- a/build-scripts/gulp/webpack.js +++ b/build-scripts/gulp/webpack.js @@ -173,6 +173,7 @@ gulp.task("webpack-dev-server-gallery", () => compiler: webpack(bothBuilds(createGalleryConfig, { isProdBuild: false })), contentBase: paths.gallery_output_root, port: 8100, + listenHost: "0.0.0.0", }) ); diff --git a/demo/src/stubs/area_registry.ts b/demo/src/stubs/area_registry.ts new file mode 100644 index 0000000000..b7d8e5a34b --- /dev/null +++ b/demo/src/stubs/area_registry.ts @@ -0,0 +1,7 @@ +import { AreaRegistryEntry } from "../../../src/data/area_registry"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockAreaRegistry = ( + hass: MockHomeAssistant, + data: AreaRegistryEntry[] = [] +) => hass.mockWS("config/area_registry/list", () => data); diff --git a/demo/src/stubs/device_registry.ts b/demo/src/stubs/device_registry.ts new file mode 100644 index 0000000000..28c47e4a96 --- /dev/null +++ b/demo/src/stubs/device_registry.ts @@ -0,0 +1,7 @@ +import { DeviceRegistryEntry } from "../../../src/data/device_registry"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockDeviceRegistry = ( + hass: MockHomeAssistant, + data: DeviceRegistryEntry[] = [] +) => hass.mockWS("config/device_registry/list", () => data); diff --git a/demo/src/stubs/entity_registry.ts b/demo/src/stubs/entity_registry.ts new file mode 100644 index 0000000000..8f548629e7 --- /dev/null +++ b/demo/src/stubs/entity_registry.ts @@ -0,0 +1,7 @@ +import { EntityRegistryEntry } from "../../../src/data/entity_registry"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockEntityRegistry = ( + hass: MockHomeAssistant, + data: EntityRegistryEntry[] = [] +) => hass.mockWS("config/entity_registry/list", () => data); diff --git a/demo/src/stubs/hassio_supervisor.ts b/demo/src/stubs/hassio_supervisor.ts new file mode 100644 index 0000000000..95c0d330d4 --- /dev/null +++ b/demo/src/stubs/hassio_supervisor.ts @@ -0,0 +1,59 @@ +import { HassioSupervisorInfo } from "../../../src/data/hassio/supervisor"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockHassioSupervisor = (hass: MockHomeAssistant) => { + hass.config.components.push("hassio"); + hass.mockWS("supervisor/api", (msg) => { + if (msg.endpoint === "/supervisor/info") { + const data: HassioSupervisorInfo = { + version: "2021.10.dev0805", + version_latest: "2021.10.dev0806", + update_available: true, + channel: "dev", + arch: "aarch64", + supported: true, + healthy: true, + ip_address: "172.30.32.2", + wait_boot: 5, + timezone: "America/Los_Angeles", + logging: "info", + debug: false, + debug_block: false, + diagnostics: true, + addons: [ + { + name: "Visual Studio Code", + slug: "a0d7b954_vscode", + description: + "Fully featured VSCode experience, to edit your HA config in the browser, including auto-completion!", + state: "started", + version: "3.6.2", + version_latest: "3.6.2", + update_available: false, + repository: "a0d7b954", + icon: true, + logo: true, + }, + { + name: "Z-Wave JS", + slug: "core_zwave_js", + description: + "Control a ZWave network with Home Assistant Z-Wave JS", + state: "started", + version: "0.1.45", + version_latest: "0.1.45", + update_available: false, + repository: "core", + icon: true, + logo: true, + }, + ] as any, + addons_repositories: [ + "https://github.com/hassio-addons/repository", + ] as any, + }; + return data; + } + return Promise.reject(`${msg.method} ${msg.endpoint} is not implemented`); + }); +}; diff --git a/gallery/src/demos/demo-ha-selector.ts b/gallery/src/demos/demo-ha-selector.ts new file mode 100644 index 0000000000..919a2c2419 --- /dev/null +++ b/gallery/src/demos/demo-ha-selector.ts @@ -0,0 +1,131 @@ +/* eslint-disable lit/no-template-arrow */ +import "@material/mwc-button"; +import { LitElement, TemplateResult, css, html } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../src/components/ha-selector/ha-selector"; +import "../../../src/components/ha-settings-row"; +import { provideHass } from "../../../src/fake_data/provide_hass"; +import type { HomeAssistant } from "../../../src/types"; +import "../components/demo-black-white-row"; +import { BlueprintInput } from "../../../src/data/blueprint"; +import { mockEntityRegistry } from "../../../demo/src/stubs/entity_registry"; +import { mockDeviceRegistry } from "../../../demo/src/stubs/device_registry"; +import { mockAreaRegistry } from "../../../demo/src/stubs/area_registry"; +import { mockHassioSupervisor } from "../../../demo/src/stubs/hassio_supervisor"; + +const SCHEMAS: { + name: string; + input: Record; +}[] = [ + { + name: "One of each", + input: { + entity: { name: "Entity", selector: { entity: {} } }, + device: { name: "Device", selector: { device: {} } }, + addon: { name: "Addon", selector: { addon: {} } }, + area: { name: "Area", selector: { area: {} } }, + target: { name: "Target", selector: { target: {} } }, + number_box: { + name: "Number Box", + selector: { + number: { + min: 0, + max: 10, + mode: "box", + }, + }, + }, + number_slider: { + name: "Number Slider", + selector: { + number: { + min: 0, + max: 10, + mode: "slider", + }, + }, + }, + boolean: { name: "Boolean", selector: { boolean: {} } }, + time: { name: "Time", selector: { time: {} } }, + action: { name: "Action", selector: { action: {} } }, + text: { name: "Text", selector: { text: { multiline: false } } }, + text_multiline: { + name: "Text multiline", + selector: { text: { multiline: true } }, + }, + object: { name: "Object", selector: { object: {} } }, + select: { + name: "Select", + selector: { select: { options: ["Option 1", "Option 2"] } }, + }, + }, + }, +]; + +@customElement("demo-ha-selector") +class DemoHaSelector extends LitElement { + @state() private hass!: HomeAssistant; + + private data = SCHEMAS.map(() => ({})); + + constructor() { + super(); + const hass = provideHass(this); + hass.updateTranslations(null, "en"); + hass.updateTranslations("config", "en"); + mockEntityRegistry(hass); + mockDeviceRegistry(hass); + mockAreaRegistry(hass); + mockHassioSupervisor(hass); + } + + protected render(): TemplateResult { + return html` + ${SCHEMAS.map((info, idx) => { + const data = this.data[idx]; + const valueChanged = (ev) => { + this.data[idx] = { + ...data, + [ev.target.key]: ev.detail.value, + }; + this.requestUpdate(); + }; + return html` + + ${["light", "dark"].map((slot) => + Object.entries(info.input).map( + ([key, value]) => + html` + + ${value?.name || key} + ${value?.description} + + + ` + ) + )} + + `; + })} + `; + } + + static styles = css` + paper-input, + ha-selector { + width: 60; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-ha-selector": DemoHaSelector; + } +} diff --git a/src/common/config/version.ts b/src/common/config/version.ts index ca9b8ae7af..ec89a3407e 100644 --- a/src/common/config/version.ts +++ b/src/common/config/version.ts @@ -4,6 +4,10 @@ export const atLeastVersion = ( minor: number, patch?: number ): boolean => { + if (__DEMO__) { + return true; + } + const [haMajor, haMinor, haPatch] = version.split(".", 3); return ( From aaa3964bb3d0864d8978f70117937f5305f0458c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Sat, 9 Oct 2021 12:30:51 +0200 Subject: [PATCH 010/115] Fix icon overlay for person badges (#10201) --- src/components/entity/ha-state-label-badge.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/entity/ha-state-label-badge.ts b/src/components/entity/ha-state-label-badge.ts index b7001ab861..fa84be3fc2 100644 --- a/src/components/entity/ha-state-label-badge.ts +++ b/src/components/entity/ha-state-label-badge.ts @@ -73,6 +73,12 @@ export class HaStateLabelBadge extends LitElement { const value = this._computeValue(domain, entityState); const icon = this.icon ? this.icon : this._computeIcon(domain, entityState); + const image = this.icon + ? "" + : this.image + ? this.image + : entityState.attributes.entity_picture_local || + entityState.attributes.entity_picture; return html` - ${icon ? html`` : ""} + ${!image && icon ? html`` : ""} ${value && (this.icon || !this.image) ? html` 4 ? "big" : ""} >${value} Date: Sat, 9 Oct 2021 03:39:37 -0700 Subject: [PATCH 011/115] Convert iframe panel to Lit (#10216) --- src/panels/iframe/ha-panel-iframe.js | 44 ------------------- src/panels/iframe/ha-panel-iframe.ts | 63 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 44 deletions(-) delete mode 100644 src/panels/iframe/ha-panel-iframe.js create mode 100644 src/panels/iframe/ha-panel-iframe.ts diff --git a/src/panels/iframe/ha-panel-iframe.js b/src/panels/iframe/ha-panel-iframe.js deleted file mode 100644 index 8dcc0e4670..0000000000 --- a/src/panels/iframe/ha-panel-iframe.js +++ /dev/null @@ -1,44 +0,0 @@ -import "@polymer/app-layout/app-toolbar/app-toolbar"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import "../../components/ha-menu-button"; -import "../../styles/polymer-ha-style"; - -class HaPanelIframe extends PolymerElement { - static get template() { - return html` - - - -
[[panel.title]]
-
- - - `; - } - - static get properties() { - return { - hass: Object, - narrow: Boolean, - panel: Object, - }; - } -} - -customElements.define("ha-panel-iframe", HaPanelIframe); diff --git a/src/panels/iframe/ha-panel-iframe.ts b/src/panels/iframe/ha-panel-iframe.ts new file mode 100644 index 0000000000..14aec1fdcd --- /dev/null +++ b/src/panels/iframe/ha-panel-iframe.ts @@ -0,0 +1,63 @@ +import { html, css, LitElement } from "lit"; +import { customElement, property } from "lit/decorators"; +import "../../layouts/hass-error-screen"; +import "../../layouts/hass-subpage"; +import { HomeAssistant, PanelInfo } from "../../types"; + +@customElement("ha-panel-iframe") +class HaPanelIframe extends LitElement { + @property() hass!: HomeAssistant; + + @property({ type: Boolean }) narrow!: boolean; + + @property() panel!: PanelInfo<{ url: string }>; + + render() { + if ( + location.protocol === "https:" && + new URL(this.panel.config.url, location.toString()).protocol !== "https:" + ) { + return html` + + `; + } + + return html` + + + + `; + } + + static styles = css` + iframe { + border: 0; + width: 100%; + position: absolute; + height: 100%; + background-color: var(--primary-background-color); + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-panel-iframe": HaPanelIframe; + } +} From 9bf41a37b458adc46e5dd4b080837fa46ebc812f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 9 Oct 2021 03:41:36 -0700 Subject: [PATCH 012/115] Allow disabling an ha-form (#10218) --- .../src/components/demo-black-white-row.ts | 25 +++++++++++++++-- gallery/src/demos/demo-ha-form.ts | 17 +++++++++++- src/auth/ha-auth-flow.ts | 27 +++++++++---------- src/components/ha-duration-input.ts | 3 +++ src/components/ha-form/ha-form-boolean.ts | 3 +++ src/components/ha-form/ha-form-float.ts | 3 +++ src/components/ha-form/ha-form-integer.ts | 7 ++++- .../ha-form/ha-form-multi_select.ts | 5 ++++ .../ha-form-positive_time_period_dict.ts | 3 +++ src/components/ha-form/ha-form-select.ts | 4 +++ src/components/ha-form/ha-form-string.ts | 3 +++ src/components/ha-form/ha-form.ts | 3 +++ 12 files changed, 85 insertions(+), 18 deletions(-) diff --git a/gallery/src/components/demo-black-white-row.ts b/gallery/src/components/demo-black-white-row.ts index 002d7510c2..a3b1233ffb 100644 --- a/gallery/src/components/demo-black-white-row.ts +++ b/gallery/src/components/demo-black-white-row.ts @@ -1,6 +1,8 @@ +import { Button } from "@material/mwc-button"; import { html, LitElement, css, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; +import { fireEvent } from "../../../src/common/dom/fire_event"; @customElement("demo-black-white-row") class DemoBlackWhiteRow extends LitElement { @@ -8,6 +10,8 @@ class DemoBlackWhiteRow extends LitElement { @property() value!: any; + @property() disabled = false; + protected render(): TemplateResult { return html`
@@ -17,7 +21,12 @@ class DemoBlackWhiteRow extends LitElement {
- Submit + + Submit +
@@ -27,7 +36,12 @@ class DemoBlackWhiteRow extends LitElement {
- Submit + + Submit +
${JSON.stringify(this.value, undefined, 2)}
@@ -51,6 +65,13 @@ class DemoBlackWhiteRow extends LitElement { ); } + handleSubmit(ev) { + const content = (ev.target as Button).closest(".content")!; + fireEvent(this, "submitted" as any, { + slot: content.classList.contains("light") ? "light" : "dark", + }); + } + static styles = css` .row { display: flex; diff --git a/gallery/src/demos/demo-ha-form.ts b/gallery/src/demos/demo-ha-form.ts index 5dc69ece51..abc2cca571 100644 --- a/gallery/src/demos/demo-ha-form.ts +++ b/gallery/src/demos/demo-ha-form.ts @@ -230,12 +230,26 @@ class DemoHaForm extends LitElement { ({ schema, data }) => data || computeInitialHaFormData(schema) ); + private disabled = SCHEMAS.map(() => false); + protected render(): TemplateResult { return html` ${SCHEMAS.map((info, idx) => { const translations = info.translations || {}; return html` - + { + this.disabled[idx] = true; + this.requestUpdate(); + setTimeout(() => { + this.disabled[idx] = false; + this.requestUpdate(); + }, 2000); + }} + > ${["light", "dark"].map( (slot) => html` translations[error] || error} .computeLabel=${(schema) => translations[schema.name] || schema.name} diff --git a/src/auth/ha-auth-flow.ts b/src/auth/ha-auth-flow.ts index e8062334e1..c9abd00d3a 100644 --- a/src/auth/ha-auth-flow.ts +++ b/src/auth/ha-auth-flow.ts @@ -39,6 +39,8 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { @state() private _errorMessage?: string; + @state() private _submitting = false; + willUpdate(changedProps: PropertyValues) { super.willUpdate(changedProps); @@ -135,13 +137,15 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { return html` ${this._renderStep(this._step)}
- ${this._step.type === "form" - ? this.localize("ui.panel.page-authorize.form.next") - : this.localize( - "ui.panel.page-authorize.form.start_over" - )} + ${this._step.type === "form" + ? this.localize("ui.panel.page-authorize.form.next") + : this.localize("ui.panel.page-authorize.form.start_over")} +
`; case "error": @@ -192,6 +196,7 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { .data=${this._stepData} .schema=${step.data_schema} .error=${step.errors} + .disabled=${this._submitting} .computeLabel=${this._computeLabelCallback(step)} .computeError=${this._computeErrorCallback(step)} @value-changed=${this._stepDataChanged} @@ -317,9 +322,7 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { this._providerChanged(this.authProvider); return; } - this._state = "loading"; - // To avoid a jumping UI. - this.style.setProperty("min-height", `${this.offsetHeight}px`); + this._submitting = true; const postData = { ...this._stepData, client_id: this.clientId }; @@ -344,16 +347,12 @@ class HaAuthFlow extends litLocalizeLiteMixin(LitElement) { this._state = "error"; this._errorMessage = this._unknownError(); } finally { - this.style.setProperty("min-height", ""); + this._submitting = false; } } static get styles(): CSSResultGroup { return css` - :host { - /* So we can set min-height to avoid jumping during loading */ - display: block; - } .action { margin: 24px 0 8px; text-align: center; diff --git a/src/components/ha-duration-input.ts b/src/components/ha-duration-input.ts index 4af165b74d..d2f06d2c7d 100644 --- a/src/components/ha-duration-input.ts +++ b/src/components/ha-duration-input.ts @@ -20,6 +20,8 @@ class HaDurationInput extends LitElement { @property({ type: Boolean }) public enableMillisecond?: boolean; + @property({ type: Boolean }) public disabled = false; + @query("paper-time-input", true) private _input?: HTMLElement; public focus() { @@ -34,6 +36,7 @@ class HaDurationInput extends LitElement { .label=${this.label} .required=${this.required} .autoValidate=${this.required} + .disabled=${this.disabled} error-message="Required" enable-second .enableMillisecond=${this.enableMillisecond} diff --git a/src/components/ha-form/ha-form-boolean.ts b/src/components/ha-form/ha-form-boolean.ts index f348013504..d55876859d 100644 --- a/src/components/ha-form/ha-form-boolean.ts +++ b/src/components/ha-form/ha-form-boolean.ts @@ -18,6 +18,8 @@ export class HaFormBoolean extends LitElement implements HaFormElement { @property() public label!: string; + @property({ type: Boolean }) public disabled = false; + @query("paper-checkbox", true) private _input?: HTMLElement; public focus() { @@ -31,6 +33,7 @@ export class HaFormBoolean extends LitElement implements HaFormElement { diff --git a/src/components/ha-form/ha-form-float.ts b/src/components/ha-form/ha-form-float.ts index 0571b43c83..f27c669247 100644 --- a/src/components/ha-form/ha-form-float.ts +++ b/src/components/ha-form/ha-form-float.ts @@ -13,6 +13,8 @@ export class HaFormFloat extends LitElement implements HaFormElement { @property() public label!: string; + @property({ type: Boolean }) public disabled = false; + @query("mwc-textfield") private _input?: HTMLElement; public focus() { @@ -27,6 +29,7 @@ export class HaFormFloat extends LitElement implements HaFormElement { inputMode="decimal" .label=${this.label} .value=${this.data !== undefined ? this.data : ""} + .disabled=${this.disabled} .required=${this.schema.required} .autoValidate=${this.schema.required} .suffix=${this.schema.description?.suffix} diff --git a/src/components/ha-form/ha-form-integer.ts b/src/components/ha-form/ha-form-integer.ts index 1e210ee4db..c8668b25de 100644 --- a/src/components/ha-form/ha-form-integer.ts +++ b/src/components/ha-form/ha-form-integer.ts @@ -23,6 +23,8 @@ export class HaFormInteger extends LitElement implements HaFormElement { @property() public label?: string; + @property({ type: Boolean }) public disabled = false; + @query("paper-input ha-slider") private _input?: HTMLElement; private _lastValue?: HaFormIntegerData; @@ -44,6 +46,7 @@ export class HaFormInteger extends LitElement implements HaFormElement { ` : ""} @@ -52,7 +55,8 @@ export class HaFormInteger extends LitElement implements HaFormElement { .value=${this._value} .min=${this.schema.valueMin} .max=${this.schema.valueMax} - .disabled=${this.data === undefined && this.schema.optional} + .disabled=${this.disabled || + (this.data === undefined && this.schema.optional)} @change=${this._valueChanged} > @@ -66,6 +70,7 @@ export class HaFormInteger extends LitElement implements HaFormElement { inputMode="numeric" .label=${this.label} .value=${this.data !== undefined ? this.data : ""} + .disabled=${this.disabled} .required=${this.schema.required} .autoValidate=${this.schema.required} .suffix=${this.schema.description?.suffix} diff --git a/src/components/ha-form/ha-form-multi_select.ts b/src/components/ha-form/ha-form-multi_select.ts index d7cdd4441a..3162868317 100644 --- a/src/components/ha-form/ha-form-multi_select.ts +++ b/src/components/ha-form/ha-form-multi_select.ts @@ -39,6 +39,8 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { @property() public label!: string; + @property({ type: Boolean }) public disabled = false; + @state() private _opened = false; @query("paper-menu-button", true) private _input?: HTMLElement; @@ -60,6 +62,7 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { @@ -73,6 +76,7 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { return html` this.schema.options![value] || value) .join(", ")} + .disabled=${this.disabled} tabindex="-1" > `; } diff --git a/src/components/ha-form/ha-form-select.ts b/src/components/ha-form/ha-form-select.ts index 62bd1ec528..0c4788a6d5 100644 --- a/src/components/ha-form/ha-form-select.ts +++ b/src/components/ha-form/ha-form-select.ts @@ -19,6 +19,8 @@ export class HaFormSelect extends LitElement implements HaFormElement { @property() public label!: string; + @property({ type: Boolean }) public disabled = false; + @query("mwc-select", true) private _input?: HTMLElement; public focus() { @@ -38,6 +40,7 @@ export class HaFormSelect extends LitElement implements HaFormElement { @@ -52,6 +55,7 @@ export class HaFormSelect extends LitElement implements HaFormElement { fixedMenuPosition .label=${this.label} .value=${this.data} + .disabled=${this.disabled} @closed=${stopPropagation} @selected=${this._valueChanged} > diff --git a/src/components/ha-form/ha-form-string.ts b/src/components/ha-form/ha-form-string.ts index abfb677e2c..2abccb47f7 100644 --- a/src/components/ha-form/ha-form-string.ts +++ b/src/components/ha-form/ha-form-string.ts @@ -28,6 +28,8 @@ export class HaFormString extends LitElement implements HaFormElement { @property() public label!: string; + @property({ type: Boolean }) public disabled = false; + @state() private _unmaskedPassword = false; @query("mwc-textfield") private _input?: HTMLElement; @@ -51,6 +53,7 @@ export class HaFormString extends LitElement implements HaFormElement { : "password"} .label=${this.label} .value=${this.data || ""} + .disabled=${this.disabled} .required=${this.schema.required} .autoValidate=${this.schema.required} .suffix=${isPassword diff --git a/src/components/ha-form/ha-form.ts b/src/components/ha-form/ha-form.ts index eae854c4f9..6a5da55448 100644 --- a/src/components/ha-form/ha-form.ts +++ b/src/components/ha-form/ha-form.ts @@ -23,6 +23,8 @@ export class HaForm extends LitElement implements HaFormElement { @property() public error?: Record; + @property({ type: Boolean }) public disabled = false; + @property() public computeError?: (schema: HaFormSchema, error) => string; @property() public computeLabel?: (schema: HaFormSchema) => string; @@ -64,6 +66,7 @@ export class HaForm extends LitElement implements HaFormElement { schema: item, data: getValue(this.data, item), label: this._computeLabel(item), + disabled: this.disabled, })} `; })} From 83f405b695fc51fed71a43770b844eb2e0f47846 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sat, 9 Oct 2021 16:17:50 +0200 Subject: [PATCH 013/115] Fix alarm panel badge (#10221) --- src/panels/lovelace/cards/hui-alarm-panel-card.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/cards/hui-alarm-panel-card.ts b/src/panels/lovelace/cards/hui-alarm-panel-card.ts index 00a3f61792..8565b47cdd 100644 --- a/src/panels/lovelace/cards/hui-alarm-panel-card.ts +++ b/src/panels/lovelace/cards/hui-alarm-panel-card.ts @@ -152,10 +152,11 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { > + > + +
${(stateObj.state === "disarmed" ? this._config.states! From dc8d837e8896b9dcb1f0e005a047346e28428eaf Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sat, 9 Oct 2021 19:17:02 +0200 Subject: [PATCH 014/115] Add missing validation text (#10225) --- src/translations/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/translations/en.json b/src/translations/en.json index 56c4430ea7..4953259207 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1102,6 +1102,10 @@ "title": "Unexpected state class", "description": "The following entities do not have the expected state class:" }, + "entity_unexpected_device_class": { + "title": "Unexpected device class", + "description": "The following entities do not have the expected device class:" + }, "entity_state_class_measurement_no_last_reset": { "title": "Last reset missing", "description": "The following entities have state class 'measurement' but 'last_reset' is missing:" From 5bc0feacf0e01bb918adb816c5824a738676613a Mon Sep 17 00:00:00 2001 From: Jack Wilsdon Date: Sun, 10 Oct 2021 13:33:42 +0100 Subject: [PATCH 015/115] Apply flat polyfill globally (#10222) --- src/entrypoints/authorize.ts | 1 + src/entrypoints/onboarding.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/entrypoints/authorize.ts b/src/entrypoints/authorize.ts index 6150ebb7e0..36954a3fcf 100644 --- a/src/entrypoints/authorize.ts +++ b/src/entrypoints/authorize.ts @@ -4,6 +4,7 @@ import "../auth/ha-authorize"; import "../resources/ha-style"; import "../resources/roboto"; import "../resources/safari-14-attachshadow-patch"; +import "../resources/array.flat.polyfill"; /* polyfill for paper-dropdown */ setTimeout( diff --git a/src/entrypoints/onboarding.ts b/src/entrypoints/onboarding.ts index 9c085ed82f..44a67890ab 100644 --- a/src/entrypoints/onboarding.ts +++ b/src/entrypoints/onboarding.ts @@ -4,6 +4,7 @@ import "../onboarding/ha-onboarding"; import "../resources/ha-style"; import "../resources/roboto"; import "../resources/safari-14-attachshadow-patch"; +import "../resources/array.flat.polyfill"; declare global { interface Window { From b6c470edf19c4aae197da5d5ff6056bc4f260067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 12 Oct 2021 11:38:43 +0200 Subject: [PATCH 016/115] Add ha-bar to gallery (#10242) --- gallery/src/demos/demo-ha-bar.ts | 85 ++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 gallery/src/demos/demo-ha-bar.ts diff --git a/gallery/src/demos/demo-ha-bar.ts b/gallery/src/demos/demo-ha-bar.ts new file mode 100644 index 0000000000..83f47f5dd6 --- /dev/null +++ b/gallery/src/demos/demo-ha-bar.ts @@ -0,0 +1,85 @@ +import { html, css, LitElement, TemplateResult } from "lit"; +import { customElement } from "lit/decorators"; +import { classMap } from "lit/directives/class-map"; +import "../../../src/components/ha-bar"; +import "../../../src/components/ha-card"; + +const bars: { + min?: number; + max?: number; + value: number; + warning?: number; + error?: number; +}[] = [ + { + value: 33, + }, + { + value: 150, + }, + { + min: -10, + value: 0, + }, + { + value: 80, + }, + { + value: 200, + max: 13, + }, + { + value: 4, + min: 13, + }, +]; + +@customElement("demo-ha-bar") +export class DemoHaBar extends LitElement { + protected render(): TemplateResult { + return html` + ${bars + .map((bar) => ({ min: 0, max: 100, warning: 70, error: 90, ...bar })) + .map( + (bar) => html` + +
+
Config: ${JSON.stringify(bar)}
+ bar.warning, + error: bar.value > bar.error, + })} + .min=${bar.min} + .max=${bar.max} + .value=${bar.value} + > + +
+
+ ` + )} + `; + } + + static get styles() { + return css` + ha-card { + max-width: 600px; + margin: 24px auto; + } + .warning { + --ha-bar-primary-color: var(--warning-color); + } + .error { + --ha-bar-primary-color: var(--error-color); + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-ha-bar": DemoHaBar; + } +} From 56bd7313612f352fdbac35858c7cae3f285cf7d3 Mon Sep 17 00:00:00 2001 From: Josh McCarty Date: Tue, 12 Oct 2021 02:51:52 -0700 Subject: [PATCH 017/115] Handle text overflow for tabs (#10239) --- src/components/ha-tab.ts | 8 ++++++++ src/layouts/hass-tabs-subpage.ts | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/components/ha-tab.ts b/src/components/ha-tab.ts index 5b326f61fb..da172e1fab 100644 --- a/src/components/ha-tab.ts +++ b/src/components/ha-tab.ts @@ -96,6 +96,7 @@ export class HaTab extends LitElement { box-sizing: border-box; align-items: center; justify-content: center; + width: 100%; height: var(--header-height); cursor: pointer; position: relative; @@ -104,6 +105,9 @@ export class HaTab extends LitElement { .name { white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; } :host([active]) { @@ -120,6 +124,10 @@ export class HaTab extends LitElement { justify-content: center; overflow: hidden; } + + :host([narrow]) div { + padding: 0 4px; + } `; } } diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index 14767f4a0e..9b009aefc9 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -234,6 +234,12 @@ class HassTabsSubpage extends LitElement { #tabbar { display: flex; font-size: 14px; + overflow: hidden; + } + + #tabbar > a { + overflow: hidden; + max-width: 45%; } #tabbar.bottom-bar { From 4a00957b719fd696a5731db3c582bc863895e1e7 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Tue, 12 Oct 2021 13:40:44 +0200 Subject: [PATCH 018/115] Remove "battery" device class from fixed icon list (#10246) --- src/common/const.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/const.ts b/src/common/const.ts index dbc9ba4aac..fd2590bccd 100644 --- a/src/common/const.ts +++ b/src/common/const.ts @@ -57,7 +57,7 @@ export const FIXED_DOMAIN_ICONS = { export const FIXED_DEVICE_CLASS_ICONS = { aqi: "hass:air-filter", - battery: "hass:battery", + // battery: "hass:battery", => not included by design since `sensorIcon()` will dynamically determine the icon carbon_dioxide: "mdi:molecule-co2", carbon_monoxide: "mdi:molecule-co", current: "hass:current-ac", From a3d4969d7b68fdd956940457bae4ec393fdb65e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 12 Oct 2021 21:19:09 +0200 Subject: [PATCH 019/115] Add ha-chip to gallery (#10252) --- gallery/src/demos/demo-ha-chip.ts | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 gallery/src/demos/demo-ha-chip.ts diff --git a/gallery/src/demos/demo-ha-chip.ts b/gallery/src/demos/demo-ha-chip.ts new file mode 100644 index 0000000000..8344d4eb64 --- /dev/null +++ b/gallery/src/demos/demo-ha-chip.ts @@ -0,0 +1,61 @@ +import { mdiHomeAssistant } from "@mdi/js"; +import { css, html, LitElement, TemplateResult } from "lit"; +import { customElement } from "lit/decorators"; +import "../../../src/components/ha-card"; +import "../../../src/components/ha-chip"; +import "../../../src/components/ha-svg-icon"; + +const chips: { + icon?: string; + content?: string; +}[] = [ + {}, + { + icon: mdiHomeAssistant, + }, + { + content: "Content", + }, + { + icon: mdiHomeAssistant, + content: "Content", + }, +]; + +@customElement("demo-ha-chip") +export class DemoHaChip extends LitElement { + protected render(): TemplateResult { + return html` + +
+ ${chips.map( + (chip) => html` + + ${chip.icon + ? html` + ` + : ""} + ${chip.content} + + ` + )} +
+
+ `; + } + + static get styles() { + return css` + ha-card { + max-width: 600px; + margin: 24px auto; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-ha-chip": DemoHaChip; + } +} From 56deb15bca7d8c9f1db04ffd229c1057e93e310b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 12 Oct 2021 22:47:53 +0200 Subject: [PATCH 020/115] Add netlify build script for gallery (#10253) --- gallery/script/netlify_build_gallery | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100755 gallery/script/netlify_build_gallery diff --git a/gallery/script/netlify_build_gallery b/gallery/script/netlify_build_gallery new file mode 100755 index 0000000000..a1d5bb09a9 --- /dev/null +++ b/gallery/script/netlify_build_gallery @@ -0,0 +1,35 @@ +#!/bin/bash + +TARGET_LABEL="Needs gallery preview" + +if [[ "$NETLIFY" != "true" ]]; then + echo "This script can only be run on Netlify" + exit 1 +fi + +function createStatus() { + state="$1" + description="$2" + target_url="$3" + curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/home-assistant/frontend/statuses/$COMMIT_REF" \ + -d '{"state": "'"${state}"'", "context": "Netlify/Gallery Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}' +} + + +if [[ "${PULL_REQUEST}" == "false" ]]; then + gulp build-gallery +else + if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then + createStatus "pending" "Building gallery preview" "$DEPLOY_URL" + gulp build-gallery + if [ $? -eq 0 ]; then + createStatus "success" "Build complete" "$DEPLOY_URL" + else + createStatus "error" "Build failed" "$DEPLOY_URL" + fi + else + createStatus "success" "Build was not requested by PR label" + fi +fi From 9e7acacb06cee14e914c559fed93ea4e4fc1ea78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 13 Oct 2021 10:05:44 +0200 Subject: [PATCH 021/115] Add ha-label-badge to gallery (#10248) --- gallery/src/demos/demo-ha-label-badge.ts | 122 +++++++++++++++++++++++ src/components/ha-label-badge.ts | 1 - 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 gallery/src/demos/demo-ha-label-badge.ts diff --git a/gallery/src/demos/demo-ha-label-badge.ts b/gallery/src/demos/demo-ha-label-badge.ts new file mode 100644 index 0000000000..277c539040 --- /dev/null +++ b/gallery/src/demos/demo-ha-label-badge.ts @@ -0,0 +1,122 @@ +import { html, css, LitElement, TemplateResult } from "lit"; +import { customElement } from "lit/decorators"; +import "../../../src/components/ha-label-badge"; +import "../../../src/components/ha-card"; + +const colors = ["#03a9f4", "#ffa600", "#43a047"]; + +const badges: { + label?: string; + description?: string; + image?: string; +}[] = [ + { + label: "label", + }, + { + label: "label", + description: "Description", + }, + { + description: "Description", + }, + { + label: "label", + description: "Description", + image: "/images/living_room.png", + }, + { + description: "Description", + image: "/images/living_room.png", + }, + { + label: "label", + image: "/images/living_room.png", + }, + { + image: "/images/living_room.png", + }, + { + label: "big label", + }, + { + label: "big label", + description: "Description", + }, + { + label: "big label", + description: "Description", + image: "/images/living_room.png", + }, +]; + +@customElement("demo-ha-label-badge") +export class DemoHaLabelBadge extends LitElement { + protected render(): TemplateResult { + return html` + +
+ ${badges.map( + (badge) => html` + + + ` + )} +
+
+ +
+ ${badges.map( + (badge) => html` +
+ + +
${JSON.stringify(badge, null, 2)}
+
+ ` + )} +
+
+ `; + } + + static get styles() { + return css` + ha-card { + max-width: 600px; + margin: 24px auto; + } + pre { + margin-left: 16px; + background-color: var(--markdown-code-background-color); + padding: 8px; + } + .badge { + display: flex; + flex-direction: row; + margin-bottom: 16px; + align-items: center; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-ha-label-badge": DemoHaLabelBadge; + } +} diff --git a/src/components/ha-label-badge.ts b/src/components/ha-label-badge.ts index 7c1d633f43..a8bbf838a5 100644 --- a/src/components/ha-label-badge.ts +++ b/src/components/ha-label-badge.ts @@ -8,7 +8,6 @@ import { } from "lit"; import { property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; -import "./ha-svg-icon"; class HaLabelBadge extends LitElement { @property() public label?: string; From e52118db936d5e2b6a86c67a3d5651ec459cdb5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 13 Oct 2021 10:08:10 +0200 Subject: [PATCH 022/115] Use correct build url (#10258) --- gallery/script/netlify_build_gallery | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gallery/script/netlify_build_gallery b/gallery/script/netlify_build_gallery index a1d5bb09a9..173b77d73f 100755 --- a/gallery/script/netlify_build_gallery +++ b/gallery/script/netlify_build_gallery @@ -22,12 +22,12 @@ if [[ "${PULL_REQUEST}" == "false" ]]; then else if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then - createStatus "pending" "Building gallery preview" "$DEPLOY_URL" + createStatus "pending" "Building gallery preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID" gulp build-gallery if [ $? -eq 0 ]; then createStatus "success" "Build complete" "$DEPLOY_URL" else - createStatus "error" "Build failed" "$DEPLOY_URL" + createStatus "error" "Build failed" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID" fi else createStatus "success" "Build was not requested by PR label" From 164c9c8e7311b24ab9d37cd3a654041955ea0c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 13 Oct 2021 10:08:56 +0200 Subject: [PATCH 023/115] Remove "Hass.io" from translation (#10257) --- src/translations/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/translations/en.json b/src/translations/en.json index 4953259207..78d240f811 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1879,7 +1879,7 @@ "title": "Cloud Login", "introduction": "Home Assistant Cloud provides you with a secure remote connection to your instance while away from home. It also allows you to connect with cloud-only services: Amazon Alexa and Google Assistant.", "introduction2": "This service is run by our partner ", - "introduction2a": ", a company founded by the founders of Home Assistant and Hass.io.", + "introduction2a": ", a company founded by the founders of Home Assistant.", "introduction3": "Home Assistant Cloud is a subscription service with a free one month trial. No payment information necessary.", "learn_more_link": "Learn more about Home Assistant Cloud", "dismiss": "Dismiss", @@ -1913,7 +1913,7 @@ "feature_amazon_alexa": "Integration with Amazon Alexa", "feature_webhook_apps": "Easy integration with webhook-based apps like OwnTracks", "information3": "This service is run by our partner ", - "information3a": ", a company founded by the founders of Home Assistant and Hass.io.", + "information3a": ", a company founded by the founders of Home Assistant.", "information4": "By registering an account you agree to the following terms and conditions.", "link_terms_conditions": "Terms and Conditions", "link_privacy_policy": "Privacy Policy", From 7472545204a38ef444c39e644eaef61aed2306e0 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 13 Oct 2021 10:09:28 +0200 Subject: [PATCH 024/115] Update demo template (#10256) --- src/panels/developer-tools/template/developer-tools-template.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/developer-tools/template/developer-tools-template.ts b/src/panels/developer-tools/template/developer-tools-template.ts index 9ad752a4b9..952815a91f 100644 --- a/src/panels/developer-tools/template/developer-tools-template.ts +++ b/src/panels/developer-tools/template/developer-tools-template.ts @@ -25,7 +25,7 @@ The temperature is {{ my_test_json.temperature }} {{ my_test_json.unit }}. {% if is_state("sun.sun", "above_horizon") -%} The sun rose {{ relative_time(states.sun.sun.last_changed) }} ago. {%- else -%} - The sun will rise at {{ as_timestamp(strptime(state_attr("sun.sun", "next_rising"), "")) | timestamp_local }}. + The sun will rise at {{ as_timestamp(state_attr("sun.sun", "next_rising")) | timestamp_local }}. {%- endif %} For loop example getting entity values in the weather domain: From 4ad005f0bfe7ced82be683929b2cecdab66c2495 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Wed, 13 Oct 2021 01:14:33 -0700 Subject: [PATCH 025/115] Add WebRTC stream player (#10193) Co-authored-by: Bram Kragten --- src/components/ha-camera-stream.ts | 95 +++++++----- src/components/ha-web-rtc-player.ts | 135 ++++++++++++++++++ src/data/camera.ts | 19 +++ .../more-info/controls/more-info-camera.ts | 6 +- 4 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 src/components/ha-web-rtc-player.ts diff --git a/src/components/ha-camera-stream.ts b/src/components/ha-camera-stream.ts index 7444e98c27..c19ee6d71f 100644 --- a/src/components/ha-camera-stream.ts +++ b/src/components/ha-camera-stream.ts @@ -15,9 +15,12 @@ import { CAMERA_SUPPORT_STREAM, computeMJPEGStreamUrl, fetchStreamUrl, + STREAM_TYPE_HLS, + STREAM_TYPE_WEB_RTC, } from "../data/camera"; import { HomeAssistant } from "../types"; import "./ha-hls-player"; +import "./ha-web-rtc-player"; @customElement("ha-camera-stream") class HaCameraStream extends LitElement { @@ -34,8 +37,8 @@ class HaCameraStream extends LitElement { @property({ type: Boolean, attribute: "allow-exoplayer" }) public allowExoPlayer = false; - // We keep track if we should force MJPEG with a string - // that way it automatically resets if we change entity. + // We keep track if we should force MJPEG if there was a failure + // to get the HLS stream url. This is reset if we change entities. @state() private _forceMJPEG?: string; @state() private _url?: string; @@ -48,7 +51,8 @@ class HaCameraStream extends LitElement { !this._shouldRenderMJPEG && this.stateObj && (changedProps.get("stateObj") as CameraEntity | undefined)?.entity_id !== - this.stateObj.entity_id + this.stateObj.entity_id && + this.stateObj!.attributes.stream_type === STREAM_TYPE_HLS ) { this._forceMJPEG = undefined; this._url = undefined; @@ -70,43 +74,64 @@ class HaCameraStream extends LitElement { if (!this.stateObj) { return html``; } - - return html` - ${__DEMO__ || this._shouldRenderMJPEG - ? html` - - ` - : this._url - ? html` - - ` - : ""} - `; + if (__DEMO__ || this._shouldRenderMJPEG) { + return html` `; + } + if (this.stateObj.attributes.stream_type === STREAM_TYPE_HLS && true) { + return this._url + ? html` ` + : html``; + } + if (this.stateObj.attributes.stream_type === STREAM_TYPE_WEB_RTC) { + return html` `; + } + return html``; } private get _shouldRenderMJPEG() { - return ( - this._forceMJPEG === this.stateObj!.entity_id || + if (this._forceMJPEG === this.stateObj!.entity_id) { + // Fallback when unable to fetch stream url + return true; + } + if ( !isComponentLoaded(this.hass!, "stream") || !supportsFeature(this.stateObj!, CAMERA_SUPPORT_STREAM) - ); + ) { + // Steaming is not supported by the camera so fallback to MJPEG stream + return true; + } + if ( + this.stateObj!.attributes.stream_type === STREAM_TYPE_WEB_RTC && + typeof RTCPeerConnection === "undefined" + ) { + // Stream requires WebRTC but browser does not support, so fallback to + // MJPEG stream. + return true; + } + // Render stream + return false; } private async _getStreamUrl(): Promise { diff --git a/src/components/ha-web-rtc-player.ts b/src/components/ha-web-rtc-player.ts new file mode 100644 index 0000000000..99faf1953f --- /dev/null +++ b/src/components/ha-web-rtc-player.ts @@ -0,0 +1,135 @@ +import { + css, + CSSResultGroup, + html, + LitElement, + PropertyValues, + TemplateResult, +} from "lit"; +import { customElement, property, state, query } from "lit/decorators"; +import { handleWebRtcOffer, WebRtcAnswer } from "../data/camera"; +import type { HomeAssistant } from "../types"; +import "./ha-alert"; + +/** + * A WebRTC stream is established by first sending an offer through a signal + * path via an integration. An answer is returned, then the rest of the stream + * is handled entirely client side. + */ +@customElement("ha-web-rtc-player") +class HaWebRtcPlayer extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public entityid!: string; + + @property({ type: Boolean, attribute: "controls" }) + public controls = false; + + @property({ type: Boolean, attribute: "muted" }) + public muted = false; + + @property({ type: Boolean, attribute: "autoplay" }) + public autoPlay = false; + + @property({ type: Boolean, attribute: "playsinline" }) + public playsInline = false; + + @state() private _error?: string; + + // don't cache this, as we remove it on disconnects + @query("#remote-stream") private _videoEl!: HTMLVideoElement; + + protected render(): TemplateResult { + if (this._error) { + return html`${this._error}`; + } + return html` + + `; + } + + public disconnectedCallback() { + super.disconnectedCallback(); + this._cleanUp(); + } + + protected updated(changedProperties: PropertyValues) { + if (!changedProperties.has("entityid")) { + return; + } + if (!this._videoEl) { + return; + } + this._startWebRtc(); + } + + private async _startWebRtc(): Promise { + this._error = undefined; + const peerConnection = new RTCPeerConnection(); + // Some cameras (such as nest) require a data channel to establish a stream + // however, not used by any integrations. + peerConnection.createDataChannel("dataSendChannel"); + const offerOptions: RTCOfferOptions = { + offerToReceiveAudio: true, + offerToReceiveVideo: true, + }; + const offer: RTCSessionDescriptionInit = await peerConnection.createOffer( + offerOptions + ); + await peerConnection.setLocalDescription(offer); + + let webRtcAnswer: WebRtcAnswer; + try { + webRtcAnswer = await handleWebRtcOffer( + this.hass, + this.entityid, + offer.sdp! + ); + } catch (err: any) { + this._error = "Failed to start WebRTC stream: " + err.message; + return; + } + + // Setup callbacks to render remote stream once media tracks are discovered. + const remoteStream = new MediaStream(); + peerConnection.addEventListener("track", (event) => { + remoteStream.addTrack(event.track); + this._videoEl.srcObject = remoteStream; + }); + + // Initiate the stream with the remote device + const remoteDesc = new RTCSessionDescription({ + type: "answer", + sdp: webRtcAnswer.answer, + }); + await peerConnection.setRemoteDescription(remoteDesc); + } + + private _cleanUp() { + if (this._videoEl) { + const videoEl = this._videoEl; + videoEl.removeAttribute("src"); + videoEl.load(); + } + } + + static get styles(): CSSResultGroup { + return css` + video { + display: block; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-web-rtc-player": HaWebRtcPlayer; + } +} diff --git a/src/data/camera.ts b/src/data/camera.ts index 945fe474f9..e2a3f04d68 100644 --- a/src/data/camera.ts +++ b/src/data/camera.ts @@ -9,11 +9,15 @@ import { getSignedPath } from "./auth"; export const CAMERA_SUPPORT_ON_OFF = 1; export const CAMERA_SUPPORT_STREAM = 2; +export const STREAM_TYPE_HLS = "hls"; +export const STREAM_TYPE_WEB_RTC = "web_rtc"; + interface CameraEntityAttributes extends HassEntityAttributeBase { model_name: string; access_token: string; brand: string; motion_detection: boolean; + stream_type: string; } export interface CameraEntity extends HassEntityBase { @@ -33,6 +37,10 @@ export interface Stream { url: string; } +export interface WebRtcAnswer { + answer: string; +} + export const computeMJPEGStreamUrl = (entity: CameraEntity) => `/api/camera_proxy_stream/${entity.entity_id}?token=${entity.attributes.access_token}`; @@ -78,6 +86,17 @@ export const fetchStreamUrl = async ( return stream; }; +export const handleWebRtcOffer = ( + hass: HomeAssistant, + entityId: string, + offer: string +) => + hass.callWS({ + type: "camera/web_rtc_offer", + entity_id: entityId, + offer: offer, + }); + export const fetchCameraPrefs = (hass: HomeAssistant, entityId: string) => hass.callWS({ type: "camera/get_prefs", diff --git a/src/dialogs/more-info/controls/more-info-camera.ts b/src/dialogs/more-info/controls/more-info-camera.ts index ce3b02140f..58b7096c3c 100644 --- a/src/dialogs/more-info/controls/more-info-camera.ts +++ b/src/dialogs/more-info/controls/more-info-camera.ts @@ -17,6 +17,7 @@ import { CameraPreferences, CAMERA_SUPPORT_STREAM, fetchCameraPrefs, + STREAM_TYPE_HLS, updateCameraPrefs, } from "../../../data/camera"; import type { HomeAssistant } from "../../../types"; @@ -82,7 +83,10 @@ class MoreInfoCamera extends LitElement { if ( curEntityId && isComponentLoaded(this.hass!, "stream") && - supportsFeature(this.stateObj!, CAMERA_SUPPORT_STREAM) + supportsFeature(this.stateObj!, CAMERA_SUPPORT_STREAM) && + // The stream component for HLS streams supports a server-side pre-load + // option that client initiated WebRTC streams do not + this.stateObj!.attributes.stream_type === STREAM_TYPE_HLS ) { // Fetch in background while we set up the video. this._fetchCameraPrefs(); From a91d25b27d1838099b8d3885fb21aaaf897088b3 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 14 Oct 2021 12:22:07 +0200 Subject: [PATCH 026/115] Add tamper device class for binary sensor (#10268) --- src/common/entity/binary_sensor_icon.ts | 1 + src/components/chart/state-history-chart-timeline.ts | 1 + src/data/logbook.ts | 9 +++++++++ src/translations/en.json | 4 +++- src/util/hass-attributes-util.ts | 1 + 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/common/entity/binary_sensor_icon.ts b/src/common/entity/binary_sensor_icon.ts index da18e0d01f..8ee9864e77 100644 --- a/src/common/entity/binary_sensor_icon.ts +++ b/src/common/entity/binary_sensor_icon.ts @@ -22,6 +22,7 @@ export const binarySensorIcon = (state?: string, stateObj?: HassEntity) => { case "gas": case "problem": case "safety": + case "tamper": return is_off ? "hass:check-circle" : "hass:alert-circle"; case "smoke": return is_off ? "hass:check-circle" : "hass:smoke"; diff --git a/src/components/chart/state-history-chart-timeline.ts b/src/components/chart/state-history-chart-timeline.ts index 6aa8c2951b..4dd857bcfe 100644 --- a/src/components/chart/state-history-chart-timeline.ts +++ b/src/components/chart/state-history-chart-timeline.ts @@ -26,6 +26,7 @@ const BINARY_SENSOR_DEVICE_CLASS_COLOR_INVERTED = new Set([ "problem", "safety", "smoke", + "tamper", "window", ]); diff --git a/src/data/logbook.ts b/src/data/logbook.ts index b67e602d6c..4671a6f2e8 100644 --- a/src/data/logbook.ts +++ b/src/data/logbook.ts @@ -279,6 +279,15 @@ export const getLogbookMessage = ( ); } break; + + case "tamper": + if (isOn) { + return hass.localize(`${LOGBOOK_LOCALIZE_PATH}.detected_tampering`); + } + if (isOff) { + return hass.localize(`${LOGBOOK_LOCALIZE_PATH}.cleared_tampering`); + } + break; } break; diff --git a/src/translations/en.json b/src/translations/en.json index 78d240f811..9755fff8ab 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -333,7 +333,9 @@ "turned_off": "turned off", "turned_on": "turned on", "changed_to_state": "changed to {state}", - "became_unavailable": "became unavailable" + "became_unavailable": "became unavailable", + "detected_tampering": "detected tampering", + "cleared_tampering": "cleared tampering" } }, "entity": { diff --git a/src/util/hass-attributes-util.ts b/src/util/hass-attributes-util.ts index f237e082ce..8aeaf49b13 100644 --- a/src/util/hass-attributes-util.ts +++ b/src/util/hass-attributes-util.ts @@ -34,6 +34,7 @@ const hassAttributeUtil = { "safety", "smoke", "sound", + "tamper", "vibration", "window", ], From bddb505b7f592a65583e1f097de11b021725150b Mon Sep 17 00:00:00 2001 From: chriss158 Date: Thu, 14 Oct 2021 12:28:11 +0200 Subject: [PATCH 027/115] Fix missing translatable energy texts (#10230) --- .../components/ha-energy-battery-settings.ts | 12 +- .../components/ha-energy-device-settings.ts | 14 ++- .../components/ha-energy-gas-settings.ts | 12 +- .../components/ha-energy-grid-settings.ts | 37 ++++-- .../components/ha-energy-solar-settings.ts | 12 +- .../dialogs/dialog-energy-battery-settings.ts | 12 +- .../dialogs/dialog-energy-device-settings.ts | 8 +- .../dialogs/dialog-energy-gas-settings.ts | 10 +- .../dialogs/dialog-energy-solar-settings.ts | 33 +++-- src/panels/config/energy/ha-config-energy.ts | 3 +- .../energy/strategies/energy-strategy.ts | 16 ++- .../hui-energy-carbon-consumed-gauge-card.ts | 20 +++- .../energy/hui-energy-devices-graph-card.ts | 4 +- .../energy/hui-energy-distribution-card.ts | 46 +++++-- .../cards/energy/hui-energy-gas-graph-card.ts | 6 +- .../hui-energy-grid-neutrality-gauge-card.ts | 26 ++-- .../hui-energy-solar-consumed-gauge-card.ts | 30 +++-- .../energy/hui-energy-solar-graph-card.ts | 26 ++-- .../energy/hui-energy-sources-table-card.ts | 30 +++-- .../energy/hui-energy-usage-graph-card.ts | 34 ++++-- .../components/hui-energy-period-selector.ts | 52 ++++++-- src/translations/en.json | 113 +++++++++++++++++- 22 files changed, 434 insertions(+), 122 deletions(-) diff --git a/src/panels/config/energy/components/ha-energy-battery-settings.ts b/src/panels/config/energy/components/ha-energy-battery-settings.ts index a6c96d4a7d..5a3c688e10 100644 --- a/src/panels/config/energy/components/ha-energy-battery-settings.ts +++ b/src/panels/config/energy/components/ha-energy-battery-settings.ts @@ -78,7 +78,11 @@ export class EnergyBatterySettings extends LitElement { ` )} -

Battery systems

+

+ ${this.hass.localize( + "ui.panel.config.energy.battery.battery_systems" + )} +

${batterySources.map((source) => { const fromEntityState = this.hass.states[source.stat_energy_from]; const toEntityState = this.hass.states[source.stat_energy_to]; @@ -113,7 +117,9 @@ export class EnergyBatterySettings extends LitElement {
Add battery system${this.hass.localize( + "ui.panel.config.energy.battery.add_battery_system" + )}
@@ -154,7 +160,7 @@ export class EnergyBatterySettings extends LitElement { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this source?", + title: this.hass.localize("ui.panel.config.energy.delete_source"), })) ) { return; diff --git a/src/panels/config/energy/components/ha-energy-device-settings.ts b/src/panels/config/energy/components/ha-energy-device-settings.ts index ad277fd0e4..eae9906b36 100644 --- a/src/panels/config/energy/components/ha-energy-device-settings.ts +++ b/src/panels/config/energy/components/ha-energy-device-settings.ts @@ -69,7 +69,11 @@ export class EnergyDeviceSettings extends LitElement { > ` )} -

Devices

+

+ ${this.hass.localize( + "ui.panel.config.energy.device_consumption.devices" + )} +

${this.preferences.device_consumption.map((device) => { const entityState = this.hass.states[device.stat_consumption]; return html` @@ -88,7 +92,11 @@ export class EnergyDeviceSettings extends LitElement { })}
- Add device + ${this.hass.localize( + "ui.panel.config.energy.device_consumption.add_device" + )}
@@ -113,7 +121,7 @@ export class EnergyDeviceSettings extends LitElement { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this device?", + title: this.hass.localize("ui.panel.config.energy.delete_source"), })) ) { return; diff --git a/src/panels/config/energy/components/ha-energy-gas-settings.ts b/src/panels/config/energy/components/ha-energy-gas-settings.ts index 9a92798b2b..13ff04c2a7 100644 --- a/src/panels/config/energy/components/ha-energy-gas-settings.ts +++ b/src/panels/config/energy/components/ha-energy-gas-settings.ts @@ -75,7 +75,9 @@ export class EnergyGasSettings extends LitElement { > ` )} -

Gas consumption

+

+ ${this.hass.localize("ui.panel.config.energy.gas.gas_consumption")} +

${gasSources.map((source) => { const entityState = this.hass.states[source.stat_energy_from]; return html` @@ -101,7 +103,11 @@ export class EnergyGasSettings extends LitElement { })}
- Add gas source + ${this.hass.localize( + "ui.panel.config.energy.gas.add_gas_source" + )}
@@ -143,7 +149,7 @@ export class EnergyGasSettings extends LitElement { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this source?", + title: this.hass.localize("ui.panel.config.energy.delete_source"), })) ) { return; diff --git a/src/panels/config/energy/components/ha-energy-grid-settings.ts b/src/panels/config/energy/components/ha-energy-grid-settings.ts index 6f31cd8394..652a7e01f2 100644 --- a/src/panels/config/energy/components/ha-energy-grid-settings.ts +++ b/src/panels/config/energy/components/ha-energy-grid-settings.ts @@ -109,7 +109,11 @@ export class EnergyGridSettings extends LitElement { ` : ""} -

Grid consumption

+

+ ${this.hass.localize( + "ui.panel.config.energy.grid.grid_consumption" + )} +

${gridSource.flow_from.map((flow) => { const entityState = this.hass.states[flow.stat_energy_from]; return html` @@ -138,11 +142,15 @@ export class EnergyGridSettings extends LitElement {
Add consumption${this.hass.localize( + "ui.panel.config.energy.grid.add_consumption" + )}
-

Return to grid

+

+ ${this.hass.localize("ui.panel.config.energy.grid.return_to_grid")} +

${gridSource.flow_to.map((flow) => { const entityState = this.hass.states[flow.stat_energy_to]; return html` @@ -170,10 +178,18 @@ export class EnergyGridSettings extends LitElement { })}
- Add return + ${this.hass.localize( + "ui.panel.config.energy.grid.add_return" + )}
-

Grid carbon footprint

+

+ ${this.hass.localize( + "ui.panel.config.energy.grid.grid_carbon_footprint" + )} +

${this._configEntries?.map( (entry) => html`
- Add CO2 signal integration + ${this.hass.localize( + "ui.panel.config.energy.grid.add_co2_signal" + )}
` @@ -236,8 +254,7 @@ export class EnergyGridSettings extends LitElement { const entryId = ev.currentTarget.closest(".row").entry.entry_id; if ( !(await showConfirmationDialog(this, { - title: - "Are you sure you want to delete this integration? It will remove the entities it provides", + title: this.hass.localize("ui.panel.config.energy.delete_integration"), })) ) { return; @@ -374,7 +391,7 @@ export class EnergyGridSettings extends LitElement { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this source?", + title: this.hass.localize("ui.panel.config.energy.delete_source"), })) ) { return; @@ -404,7 +421,7 @@ export class EnergyGridSettings extends LitElement { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this source?", + title: this.hass.localize("ui.panel.config.energy.delete_source"), })) ) { return; diff --git a/src/panels/config/energy/components/ha-energy-solar-settings.ts b/src/panels/config/energy/components/ha-energy-solar-settings.ts index eaec9ded9a..9f1bbd3712 100644 --- a/src/panels/config/energy/components/ha-energy-solar-settings.ts +++ b/src/panels/config/energy/components/ha-energy-solar-settings.ts @@ -81,7 +81,11 @@ export class EnergySolarSettings extends LitElement { ` )} -

Solar production

+

+ ${this.hass.localize( + "ui.panel.config.energy.solar.solar_production" + )} +

${solarSources.map((source) => { const entityState = this.hass.states[source.stat_energy_from]; return html` @@ -114,7 +118,9 @@ export class EnergySolarSettings extends LitElement {
- Add solar production + ${this.hass.localize( + "ui.panel.config.energy.solar.add_solar_production" + )}
` @@ -159,7 +165,7 @@ export class EnergySolarSettings extends LitElement { if ( !(await showConfirmationDialog(this, { - title: "Are you sure you want to delete this source?", + title: this.hass.localize("ui.panel.config.energy.delete_source"), })) ) { return; diff --git a/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts index 61f4841168..12ad6a67cc 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts @@ -58,7 +58,9 @@ export class DialogEnergyBatterySettings .path=${mdiBatteryHigh} style="--mdc-icon-size: 32px;" >
- Configure battery system`} + ${this.hass.localize( + "ui.panel.config.energy.battery.dialog.header" + )}`} @closed=${this.closeDialog} > ${this._error ? html`

${this._error}

` : ""} @@ -68,7 +70,9 @@ export class DialogEnergyBatterySettings .includeUnitOfMeasurement=${energyUnits} .includeDeviceClasses=${energyDeviceClasses} .value=${this._source.stat_energy_to} - .label=${`Energy going in to the battery (kWh)`} + .label=${this.hass.localize( + "ui.panel.config.energy.battery.dialog.energy_into_battery" + )} entities-only @value-changed=${this._statisticToChanged} > @@ -78,7 +82,9 @@ export class DialogEnergyBatterySettings .includeUnitOfMeasurement=${energyUnits} .includeDeviceClasses=${energyDeviceClasses} .value=${this._source.stat_energy_from} - .label=${`Energy coming out of the battery (kWh)`} + .label=${this.hass.localize( + "ui.panel.config.energy.battery.dialog.energy_out_of_battery" + )} entities-only @value-changed=${this._statisticFromChanged} > diff --git a/src/panels/config/energy/dialogs/dialog-energy-device-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-device-settings.ts index 758874ff42..4a7002a8e3 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-device-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-device-settings.ts @@ -55,7 +55,9 @@ export class DialogEnergyDeviceSettings .path=${mdiDevices} style="--mdc-icon-size: 32px;" > - Add a device`} + ${this.hass.localize( + "ui.panel.config.energy.device_consumption.dialog.header" + )}`} @closed=${this.closeDialog} > ${this._error ? html`

${this._error}

` : ""} @@ -69,7 +71,9 @@ export class DialogEnergyDeviceSettings .hass=${this.hass} .includeUnitOfMeasurement=${energyUnits} .includeDeviceClasses=${energyDeviceClasses} - .label=${`Device consumption energy (kWh)`} + .label=${this.hass.localize( + "ui.panel.config.energy.device_consumption.dialog.device_consumption_energy" + )} entities-only @value-changed=${this._statisticChanged} > diff --git a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts index 595ec1c942..e4a4bf98ce 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts @@ -82,7 +82,7 @@ export class DialogEnergyGasSettings .path=${mdiFire} style="--mdc-icon-size: 32px;" > - Configure Gas consumption`} + ${this.hass.localize("ui.panel.config.energy.gas.dialog.header")}`} @closed=${this.closeDialog} > ${this._error ? html`

${this._error}

` : ""} @@ -95,9 +95,13 @@ export class DialogEnergyGasSettings ? ENERGY_GAS_ENERGY_UNITS : ENERGY_GAS_VOLUME_UNITS} .value=${this._source.stat_energy_from} - .label=${`Gas usage (${ + .label=${`${this.hass.localize( + "ui.panel.config.energy.gas.dialog.gas_usage" + )} (${ this._params.unit === undefined - ? "m³ or kWh" + ? this.hass.localize( + "ui.panel.config.energy.gas.dialog.m3_or_kWh" + ) : this._params.unit === "energy" ? "kWh" : "m³" diff --git a/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts index d4cdd03676..bcb5786097 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts @@ -72,7 +72,7 @@ export class DialogEnergySolarSettings .path=${mdiSolarPower} style="--mdc-icon-size: 32px;" > - Configure solar panels`} + ${this.hass.localize("ui.panel.config.energy.solar.dialog.header")}`} @closed=${this.closeDialog} > ${this._error ? html`

${this._error}

` : ""} @@ -82,18 +82,29 @@ export class DialogEnergySolarSettings .includeUnitOfMeasurement=${energyUnits} .includeDeviceClasses=${energyDeviceClasses} .value=${this._source.stat_energy_from} - .label=${`Solar production energy (kWh)`} + .label=${this.hass.localize( + "ui.panel.config.energy.solar.dialog.solar_production_energy" + )} entities-only @value-changed=${this._statisticChanged} > -

Solar production forecast

+

+ ${this.hass.localize( + "ui.panel.config.energy.solar.dialog.solar_production_forecast" + )} +

- Adding solar production forecast information will allow you to quickly - see your expected production for today. + ${this.hass.localize( + "ui.panel.config.energy.solar.dialog.solar_production_forecast_description" + )}

- + - + ` )} - Add forecast + ${this.hass.localize( + "ui.panel.config.energy.solar.dialog.add_forecast" + )} ` : ""} diff --git a/src/panels/config/energy/ha-config-energy.ts b/src/panels/config/energy/ha-config-energy.ts index e9c21120c8..83e1ef20e2 100644 --- a/src/panels/config/energy/ha-config-energy.ts +++ b/src/panels/config/energy/ha-config-energy.ts @@ -79,8 +79,7 @@ class HaConfigEnergy extends LitElement { .tabs=${configSections.experiences} > - After setting up a new device, it can take up to 2 hours for new data - to arrive in your energy dashboard. + ${this.hass.localize("ui.panel.config.energy.new_device_info")}
- This card indicates how much of the energy consumed by your - home was generated using non-fossil fuels like solar, wind and - nuclear. The higher, the better! + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.carbon_consumed_gauge.card_indicates_energy_used" + )} -
Non-fossil energy consumed
+
+ ${this.hass.localize( + "ui.panel.lovelace.cards.energy.carbon_consumed_gauge.non_fossil_energy_consumed" + )} +
` - : html`Consumed non-fossil energy couldn't be calculated`} + : html`${this.hass.localize( + "ui.panel.lovelace.cards.energy.carbon_consumed_gauge.non_fossil_energy_not_calculated" + )}`} `; } diff --git a/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts index 5d24f900d5..5006808340 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-devices-graph-card.ts @@ -170,7 +170,9 @@ export class HuiEnergyDevicesGraphCard const datasets: ChartDataset<"bar", ParsedDataType<"bar">[]>[] = [ { - label: "Energy usage", + label: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_devices_graph.energy_usage" + ), borderColor, backgroundColor, data, diff --git a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts index 3a71b8d80b..83835855b6 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts @@ -70,7 +70,9 @@ class HuiEnergyDistrubutionCard } if (!this._data) { - return html`Loading…`; + return html`${this.hass.localize( + "ui.panel.lovelace.cards.energy.loading" + )}`; } const prefs = this._data.prefs; @@ -267,7 +269,11 @@ class HuiEnergyDistrubutionCard ${lowCarbonEnergy === undefined ? html`
` : html`
` @@ -659,7 +685,11 @@ class HuiEnergyDistrubutionCard ? html`
Go to the energy dashboard + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_distribution.go_to_energy_dashboard" + )} +
` diff --git a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts index 4175f55bee..b9516234c0 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts @@ -110,8 +110,10 @@ export class HuiEnergyGasGraphCard ${!this._chartData.datasets.length ? html`
${isToday(this._start) - ? "There is no data to show. It can take up to 2 hours for new data to arrive after you configure your energy dashboard." - : "There is no data for this period."} + ? this.hass.localize("ui.panel.lovelace.cards.energy.no_data") + : this.hass.localize( + "ui.panel.lovelace.cards.energy.no_data_period" + )}
` : ""} diff --git a/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts b/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts index 1f7e9d3f94..2a900769a9 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts @@ -61,7 +61,9 @@ class HuiEnergyGridGaugeCard } if (!this._data) { - return html`Loading...`; + return html`${this.hass.localize( + "ui.panel.lovelace.cards.energy.loading" + )}`; } const prefs = this._data.prefs; @@ -102,11 +104,13 @@ class HuiEnergyGridGaugeCard - This card represents your energy dependency. + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.energy_dependency" + )}

- If it's green, it means you produced more energy than that you - consumed from the grid. If it's in the red, it means that you - relied on the grid for part of your home's energy consumption. + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.red_green_color_explain" + )}
@@ -126,11 +130,17 @@ class HuiEnergyGridGaugeCard >
${returnedToGrid! >= consumedFromGrid! - ? "Net returned to the grid" - : "Net consumed from the grid"} + ? this.hass.localize( + "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.net_returned_grid" + ) + : this.hass.localize( + "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.net_consumed_grid" + )}
` - : "Grid neutrality could not be calculated"} + : this.hass.localize( + "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.grid_neutrality_not_calculated" + )} `; } diff --git a/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts b/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts index 6f54631658..578ae00fd5 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts @@ -54,7 +54,9 @@ class HuiEnergySolarGaugeCard } if (!this._data) { - return html`Loading...`; + return html`${this.hass.localize( + "ui.panel.lovelace.cards.energy.loading" + )}`; } const prefs = this._data.prefs; @@ -91,13 +93,13 @@ class HuiEnergySolarGaugeCard - This card indicates how much of the solar energy you produced - was used by your home instead of being returned to the grid. + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.solar_consumed_gauge.card_indicates_solar_energy_used" + )}

- If this number is typically very low, indicating excess solar - production, you might want to consider charging a home battery - or electric car from your solar panels at times of high solar - production. + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.solar_consumed_gauge.card_indicates_solar_energy_used_charge_home_bat" + )}
-
Self-consumed solar energy
+
+ ${this.hass.localize( + "ui.panel.lovelace.cards.energy.solar_consumed_gauge.self_consumed_solar_energy" + )} +
` : totalSolarProduction === 0 - ? "You have not produced any solar energy" - : "Self-consumed solar energy couldn't be calculated"} + ? this.hass.localize( + "ui.panel.lovelace.cards.energy.solar_consumed_gauge.not_produced_solar_energy" + ) + : this.hass.localize( + "ui.panel.lovelace.cards.energy.solar_consumed_gauge.self_consumed_solar_could_not_calc" + )} `; } diff --git a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts index fb595bf124..fc5ace1bf8 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts @@ -108,8 +108,10 @@ export class HuiEnergySolarGraphCard ${!this._chartData.datasets.length ? html`
${isToday(this._start) - ? "There is no data to show. It can take up to 2 hours for new data to arrive after you configure your energy dashboard." - : "There is no data for this period."} + ? this.hass.localize("ui.panel.lovelace.cards.energy.no_data") + : this.hass.localize( + "ui.panel.lovelace.cards.energy.no_data_period" + )}
` : ""} @@ -306,9 +308,12 @@ export class HuiEnergySolarGraphCard if (solarProductionData.length) { data.push({ - label: `Production ${ - entity ? computeStateName(entity) : source.stat_energy_from - }`, + label: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_solar_graph.production", + { + name: entity ? computeStateName(entity) : source.stat_energy_from, + } + ), borderColor, backgroundColor: borderColor + "7F", data: solarProductionData, @@ -361,9 +366,14 @@ export class HuiEnergySolarGraphCard if (solarForecastData.length) { data.push({ type: "line", - label: `Forecast ${ - entity ? computeStateName(entity) : source.stat_energy_from - }`, + label: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_solar_graph.forecast", + { + name: entity + ? computeStateName(entity) + : source.stat_energy_from, + } + ), fill: false, stepped: false, borderColor: computedStyles.getPropertyValue( diff --git a/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts b/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts index e91ecd9fee..bd6a0f3756 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts @@ -69,7 +69,9 @@ export class HuiEnergySourcesTableCard } if (!this._data) { - return html`Loading...`; + return html`${this.hass.localize( + "ui.panel.lovelace.cards.energy.loading" + )}`; } let totalGrid = 0; @@ -134,14 +136,18 @@ export class HuiEnergySourcesTableCard role="columnheader" scope="col" > - Source + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_sources_table.source" + )} - Energy + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_sources_table.energy" + )} ${showCosts ? html` - Cost + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_sources_table.cost" + )} ` : ""} @@ -290,7 +298,9 @@ export class HuiEnergySourcesTableCard ? html` - Battery total + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_sources_table.battery_total" + )} - Grid total + + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_sources_table.grid_total" + )} + @@ -524,7 +538,9 @@ export class HuiEnergySourcesTableCard ? html` - Total costs + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_sources_table.total_costs" + )} dataset.data.length) ? html`
${isToday(this._start) - ? "There is no data to show. It can take up to 2 hours for new data to arrive after you configure your energy dashboard." - : "There is no data for this period."} + ? this.hass.localize("ui.panel.lovelace.cards.energy.no_data") + : this.hass.localize( + "ui.panel.lovelace.cards.energy.no_data_period" + )}
` : ""} @@ -204,16 +206,16 @@ export class HuiEnergyUsageGraphCard } return [ totalConsumed - ? `Total consumed: ${formatNumber( - totalConsumed, - locale - )} kWh` + ? this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_usage_graph.total_consumed", + { num: formatNumber(totalConsumed, locale) } + ) : "", totalReturned - ? `Total returned: ${formatNumber( - totalReturned, - locale - )} kWh` + ? this.hass.localize( + "ui.panel.lovelace.cards.energyenergy_usage_graph.total_returned", + { num: formatNumber(totalReturned, locale) } + ) : "", ].filter(Boolean); }, @@ -344,9 +346,15 @@ export class HuiEnergyUsageGraphCard .trim(), }; const labels = { - used_grid: "Combined from grid", - used_solar: "Consumed solar", - used_battery: "Consumed battery", + used_grid: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_usage_graph.combined_from_grid" + ), + used_solar: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_usage_graph.consumed_solar" + ), + used_battery: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_usage_graph.consumed_battery" + ), }; const backgroundColor = computedStyles diff --git a/src/panels/lovelace/components/hui-energy-period-selector.ts b/src/panels/lovelace/components/hui-energy-period-selector.ts index d2515d7dd9..95bdb8a060 100644 --- a/src/panels/lovelace/components/hui-energy-period-selector.ts +++ b/src/panels/lovelace/components/hui-energy-period-selector.ts @@ -35,13 +35,6 @@ import "@material/mwc-button/mwc-button"; import "../../../components/ha-button-toggle-group"; import { toggleAttribute } from "../../../common/dom/toggle_attribute"; -const viewButtons: ToggleButton[] = [ - { label: "Day", value: "day" }, - { label: "Week", value: "week" }, - { label: "Month", value: "month" }, - { label: "Year", value: "year" }, -]; - @customElement("hui-energy-period-selector") export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; @@ -72,6 +65,33 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { return html``; } + const viewButtons: ToggleButton[] = [ + { + label: this.hass.localize( + "ui.panel.lovelace.components.energy_period_selector.day" + ), + value: "day", + }, + { + label: this.hass.localize( + "ui.panel.lovelace.components.energy_period_selector.week" + ), + value: "week", + }, + { + label: this.hass.localize( + "ui.panel.lovelace.components.energy_period_selector.month" + ), + value: "month", + }, + { + label: this.hass.localize( + "ui.panel.lovelace.components.energy_period_selector.year" + ), + value: "year", + }, + ]; + return html`
@@ -88,14 +108,26 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { this._endDate || new Date(), this.hass.locale )}`} - + - + - Today + ${this.hass.localize( + "ui.panel.lovelace.components.energy_period_selector.today" + )}
diff --git a/src/translations/en.json b/src/translations/en.json index 9755fff8ab..65c982211e 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -986,10 +986,19 @@ "energy": { "caption": "Energy", "description": "Monitor your energy production and consumption", + "new_device_info": "After setting up a new device, it can take up to 2 hours for new data to arrive in your energy dashboard.", + "delete_source": "Are you sure you want to delete this source?", + "delete_integration": "Are you sure you want to delete this integration? It will remove the entities it provides", "grid": { "title": "Electricity grid", "sub": "Configure the amount of energy that you consume from the grid and, if you produce energy, give back to the grid. This allows Home Assistant to track your whole home energy usage.", "learn_more": "More information on how to get started.", + "grid_consumption": "Grid consumption", + "add_consumption": "Add consumption", + "return_to_grid": "Return to grid", + "add_return": "Add return", + "grid_carbon_footprint": "Grid carbon footprint", + "add_co2_signal": "Add CO2 signal integration", "flow_dialog": { "from": { "header": "Configure grid consumption", @@ -1025,19 +1034,39 @@ "title": "Solar Panels", "sub": "Let Home Assistant monitor your solar panels and give you insight on their performance.", "learn_more": "More information on how to get started.", + "solar_production": "Solar production", + "add_solar_production": "Add solar production", "stat_production": "Your solar energy production", "stat_return_to_grid": "Solar energy returned to the grid", - "stat_predicted_production": "Prediction of your solar energy production" + "stat_predicted_production": "Prediction of your solar energy production", + "dialog": { + "header": "Configure solar panels", + "solar_production_energy": "Solar production energy (kWh)", + "solar_production_forecast": "Solar production forecast", + "solar_production_forecast_description": "Adding solar production forecast information will allow you to quickly see your expected production for today.", + "dont_forecast_production": "Don't forecast production", + "forecast_production": "Forecast Production", + "add_forecast": "Add forecast" + } }, "battery": { "title": "Home Battery Storage", "sub": "If you have a battery system, you can configure it to monitor how much energy was stored and used from your battery.", - "learn_more": "More information on how to get started." + "learn_more": "More information on how to get started.", + "battery_systems": "Battery systems", + "add_battery_system": "Add battery system", + "dialog": { + "header": "Configure battery system", + "energy_into_battery": "Energy going in to the battery (kWh)", + "energy_out_of_battery": "Energy coming out of the battery (kWh)" + } }, "gas": { "title": "Gas Consumption", "sub": "Let Home Assistant monitor your gas usage.", "learn_more": "More information on how to get started.", + "gas_consumption": "Gas consumption", + "add_gas_source": "Add gas source", "dialog": { "header": "Configure gas consumption", "paragraph": "Gas consumption is the volume of gas that flows to your home.", @@ -1049,7 +1078,9 @@ "cost_entity": "Use an entity with current price", "cost_entity_input": "Entity with the current price per {unit}", "cost_number": "Use a static price", - "cost_number_input": "Price per {unit}" + "cost_number_input": "Price per {unit}", + "gas_usage": "Gas usage", + "m3_or_kWh": "m³ or kWh" } }, "device_consumption": { @@ -1058,7 +1089,11 @@ "learn_more": "More information on how to get started.", "add_stat": "Pick entity to track energy of", "selected_stat": "Tracking energy for", + "devices": "Devices", + "add_device": "Add device", "dialog": { + "header": "Add a device", + "device_consumption_energy": "Device consumption energy (kWh)", "selected_stat_intro": "Select the entity that represents the device energy usage." } }, @@ -2928,6 +2963,61 @@ }, "starting": { "description": "Home Assistant is starting, please wait…" + }, + "energy": { + "loading": "Loading...", + "no_data": "There is no data to show. It can take up to 2 hours for new data to arrive after you configure your energy dashboard.", + "no_data_period": "There is no data for this period.", + "energy_usage_graph": { + "total_consumed": "Total consumed {num} kWh", + "total_returned": "Total returned {num} kWh", + "combined_from_grid": "Combined from grid", + "consumed_solar": "Consumed solar", + "consumed_battery": "Consumed battery" + }, + "energy_sources_table": { + "grid_total": "Grid total", + "source": "Source", + "energy": "Energy", + "cost": "Cost", + "battery_total": "Battery total", + "total_costs": "Total costs" + }, + "energy_solar_graph": { + "production": "Production {name}", + "forecast": "Forecast {name}" + }, + "solar_consumed_gauge": { + "card_indicates_solar_energy_used": "This card indicates how much of the solar energy you produced was used by your home instead of being returned to the grid.", + "card_indicates_solar_energy_used_charge_home_bat": "If this number is typically very low, indicating excess solar production, you might want to consider charging a home battery or electric car from your solar panels at times of high solar production.", + "self_consumed_solar_energy": "Self-consumed solar energy", + "not_produced_solar_energy": "You have not produced any solar energy", + "self_consumed_solar_could_not_calc": "Self-consumed solar energy couldn't be calculated" + }, + "grid_neutrality_gauge": { + "energy_dependency": "This card represents your energy dependency.", + "red_green_color_explain": "If it's green, it means you produced more energy than that you consumed from the grid. If it's in the red, it means that you relied on the grid for part of your home's energy consumption.", + "net_returned_grid": "Net returned to the grid", + "net_consumed_grid": "Net consumed from the grid", + "grid_neutrality_not_calculated": "Grid neutrality could not be calculated" + }, + "energy_distribution": { + "grid": "Grid", + "gas": "Gas", + "solar": "Solar", + "non_fossil": "Non-fossil", + "home": "Home", + "battery": "Battery", + "go_to_energy_dashboard": "Go to the energy dashboard" + }, + "energy_devices_graph": { + "energy_usage": "Energy usage" + }, + "carbon_consumed_gauge": { + "card_indicates_energy_used": "This card indicates how much of the energy consumed by your home was generated using non-fossil fuels like solar, wind and nuclear. The higher, the better!", + "non_fossil_energy_consumed": "Non-fossil energy consumed", + "non_fossil_energy_not_calculated": "Consumed non-fossil energy couldn't be calculated" + } } }, "unused_entities": { @@ -3362,6 +3452,15 @@ "timestamp-display": { "invalid": "Invalid timestamp", "invalid_format": "Invalid display format" + }, + "energy_period_selector": { + "today": "Today", + "day": "Day", + "week": "Week", + "month": "Month", + "year": "Year", + "previous": "Previous", + "next": "Next" } }, "reload_lovelace": "Reload UI" @@ -3823,6 +3922,14 @@ "stat_house_energy_meter": "Total energy consumption", "solar": "Solar", "by_device": "Consumption by device" + }, + "cards": { + "energy_usage_graph_title": "Energy usage", + "energy_solar_graph_title": "Solar production", + "energy_gas_graph_title": "Gas consumption", + "energy_distribution_title": "Energy distribution", + "energy_sources_table_title": "Sources", + "energy_devices_graph_title": "Monitor individual devices" } } } From 0c940be5fb002f7df938055997d2be71d6e50903 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Thu, 14 Oct 2021 15:44:20 +0200 Subject: [PATCH 028/115] Consolidate all icon button logic into `` + ensure tooltip (#9230) --- gallery/src/ha-gallery.js | 5 +- hassio/src/addon-store/hassio-addon-store.ts | 12 ++-- .../addon-view/config/hassio-addon-config.ts | 11 +-- .../src/addon-view/info/hassio-addon-info.ts | 4 +- hassio/src/backups/hassio-backups.ts | 28 +++++--- hassio/src/components/hassio-upload-backup.ts | 5 +- .../backup/dialog-hassio-backup-upload.ts | 10 ++- .../dialogs/backup/dialog-hassio-backup.ts | 22 +++--- .../hardware/dialog-hassio-hardware.ts | 12 ++-- .../dialogs/network/dialog-hassio-network.ts | 12 ++-- .../registries/dialog-hassio-registries.ts | 14 ++-- .../dialog-hassio-repositories.ts | 12 ++-- .../update/dialog-supervisor-update.ts | 1 - .../src/ingress-view/hassio-ingress-view.ts | 12 ++-- hassio/src/system/hassio-host-info.ts | 9 ++- src/common/search/search-input.ts | 18 ++--- src/components/data-table/ha-data-table.ts | 4 ++ .../device/ha-area-devices-picker.ts | 20 +++--- src/components/device/ha-device-picker.ts | 2 +- .../entity/ha-entity-attribute-picker.ts | 20 +++--- src/components/entity/ha-entity-picker.ts | 20 +++--- src/components/entity/ha-entity-toggle.ts | 9 +-- src/components/entity/ha-statistic-picker.ts | 3 +- src/components/ha-alert.ts | 13 ++-- src/components/ha-area-picker.ts | 20 +++--- .../ha-button-related-filter-menu.ts | 10 +-- src/components/ha-button-toggle-group.ts | 27 ++++--- src/components/ha-climate-control.js | 15 ++-- src/components/ha-combo-box.ts | 21 +++--- src/components/ha-cover-controls.ts | 14 ++-- src/components/ha-cover-tilt-controls.ts | 13 ++-- src/components/ha-dialog.ts | 12 ++-- src/components/ha-file-upload.ts | 24 ++++--- src/components/ha-form/ha-form-select.ts | 1 - src/components/ha-form/ha-form-string.ts | 22 +++--- src/components/ha-icon-button-arrow-next.ts | 16 ++--- src/components/ha-icon-button-arrow-prev.ts | 10 ++- src/components/ha-icon-button-next.ts | 10 ++- src/components/ha-icon-button-prev.ts | 10 ++- src/components/ha-icon-button.ts | 18 +++-- src/components/ha-menu-button.ts | 12 ++-- src/components/ha-picture-upload.ts | 3 +- src/components/ha-service-control.ts | 11 ++- src/components/ha-sidebar.ts | 35 +++++---- src/components/ha-target-picker.ts | 30 ++++---- src/components/ha-water_heater-control.js | 15 ++-- .../media-player/ha-media-player-browse.ts | 42 +++++------ src/components/trace/hat-script-graph.ts | 25 +++---- src/components/user/ha-users-picker.ts | 18 +++-- .../config-flow/dialog-data-entry-flow.ts | 5 +- .../config-flow/step-flow-pick-handler.ts | 1 + .../more-info/controls/more-info-fan.js | 11 +-- .../more-info/controls/more-info-light.ts | 3 +- .../controls/more-info-media_player.ts | 36 ++++++---- .../more-info/controls/more-info-vacuum.ts | 27 ++++--- src/dialogs/more-info/ha-more-info-dialog.ts | 24 +++---- .../notifications/notification-drawer.js | 1 - src/dialogs/quick-bar/ha-quick-bar.ts | 12 ++-- .../ha-voice-command-dialog.ts | 3 +- src/layouts/hass-tabs-subpage-data-table.ts | 2 + src/panels/calendar/ha-full-calendar.ts | 25 ++++--- src/panels/calendar/ha-panel-calendar.ts | 5 +- .../config/areas/ha-config-area-page.ts | 5 +- .../config/areas/ha-config-areas-dashboard.ts | 5 +- .../action/ha-automation-action-row.ts | 34 ++++----- .../types/ha-automation-action-choose.ts | 12 ++-- .../condition/ha-automation-condition-row.ts | 10 +-- .../config/automation/ha-automation-editor.ts | 9 ++- .../config/automation/ha-automation-picker.ts | 34 +++++---- .../config/automation/ha-automation-trace.ts | 72 +++++++++++-------- .../trigger/ha-automation-trigger-row.ts | 9 ++- .../config/blueprint/ha-blueprint-overview.ts | 33 +++++---- src/panels/config/cloud/alexa/cloud-alexa.ts | 23 +++--- .../cloud-google-assistant.ts | 23 +++--- src/panels/config/cloud/login/cloud-login.js | 8 ++- .../customize/ha-customize-attribute.js | 9 ++- .../config/dashboard/ha-config-dashboard.ts | 1 - .../dialog-device-registry-detail.ts | 2 +- .../config/devices/ha-config-device-page.ts | 48 +++++++------ .../devices/ha-config-devices-dashboard.ts | 11 ++- .../components/ha-energy-battery-settings.ts | 17 +++-- .../components/ha-energy-device-settings.ts | 11 +-- .../components/ha-energy-gas-settings.ts | 21 +++--- .../components/ha-energy-grid-settings.ts | 40 ++++++----- .../components/ha-energy-solar-settings.ts | 15 ++-- src/panels/config/energy/components/styles.ts | 2 +- src/panels/config/energy/ha-config-energy.ts | 1 - .../config/entities/dialog-entity-editor.ts | 17 ++--- .../config/entities/ha-config-entities.ts | 36 +++++----- .../helpers/forms/ha-input_select-form.ts | 7 +- src/panels/config/info/system-health-card.ts | 11 +-- .../integrations/ha-config-integrations.ts | 13 ++-- .../integrations/ha-integration-card.ts | 21 +++--- .../zha/dialog-zha-device-children.ts | 1 + .../zha/zha-cluster-attributes.ts | 4 +- .../zha/zha-cluster-commands.ts | 4 +- .../zha/zha-clusters-data-table.ts | 1 + .../integration-panels/zha/zha-clusters.ts | 4 +- .../zha/zha-device-binding.ts | 4 +- .../zha/zha-device-endpoint-data-table.ts | 1 + .../zha/zha-group-binding.ts | 4 +- .../integration-panels/zha/zha-group-page.ts | 4 +- .../zha/zha-network-visualization-page.ts | 3 +- .../zwave/ha-config-zwave.js | 9 ++- .../integration-panels/zwave/zwave-network.ts | 4 +- .../zwave_js/zwave_js-config-dashboard.ts | 11 +-- .../zwave_js/zwave_js-logs.ts | 14 ++-- .../zwave_js/zwave_js-node-config.ts | 1 - .../config/logs/dialog-system-log-detail.ts | 23 +++--- src/panels/config/logs/error-log-card.ts | 4 +- .../ha-config-lovelace-dashboards.ts | 7 +- src/panels/config/scene/ha-scene-dashboard.ts | 40 +++++------ src/panels/config/scene/ha-scene-editor.ts | 17 +++-- src/panels/config/script/ha-script-editor.ts | 9 ++- src/panels/config/script/ha-script-picker.ts | 47 ++++++------ src/panels/config/script/ha-script-trace.ts | 58 +++++++-------- src/panels/config/tags/ha-config-tags.ts | 38 +++++----- src/panels/config/zone/ha-config-zone.ts | 47 ++++++------ .../service/developer-tools-service.ts | 12 ++-- .../state/developer-tools-state.js | 7 +- src/panels/energy/ha-panel-energy.ts | 2 +- src/panels/history/ha-panel-history.ts | 9 +-- src/panels/logbook/ha-panel-logbook.ts | 10 +-- .../lovelace/cards/hui-humidifier-card.ts | 3 +- src/panels/lovelace/cards/hui-light-card.ts | 19 +++-- src/panels/lovelace/cards/hui-map-card.ts | 13 ++-- .../lovelace/cards/hui-media-control-card.ts | 25 +++---- .../lovelace/cards/hui-picture-glance-card.ts | 8 ++- .../lovelace/cards/hui-thermostat-card.ts | 17 +++-- .../lovelace/components/hui-card-options.ts | 40 +++++------ .../components/hui-energy-period-selector.ts | 45 ++++++------ .../components/hui-input-list-editor.ts | 4 +- .../editor/card-editor/hui-card-picker.ts | 1 + .../card-editor/hui-dialog-edit-card.ts | 7 +- .../card-editor/hui-entity-picker-table.ts | 1 + .../hui-alarm-panel-card-editor.ts | 14 ++-- .../config-elements/hui-stack-card-editor.ts | 30 ++++---- .../hui-header-footer-editor.ts | 32 ++++----- .../lovelace/editor/hui-dialog-save-config.ts | 10 +-- .../editor/hui-entities-card-row-editor.ts | 20 +++--- .../lovelace/editor/hui-sub-element-editor.ts | 11 +-- .../hui-media-player-entity-row.ts | 41 +++++++---- src/panels/lovelace/hui-editor.ts | 4 +- src/panels/lovelace/hui-root.ts | 72 +++++++------------ src/panels/lovelace/views/hui-sidebar-view.ts | 2 +- .../mailbox/ha-dialog-show-audio-message.js | 10 +-- src/panels/map/ha-panel-map.ts | 15 ++-- .../media-browser/ha-panel-media-browser.ts | 1 - .../ha-long-lived-access-tokens-card.ts | 14 ++-- src/panels/profile/ha-refresh-tokens-card.ts | 14 ++-- .../shopping-list/ha-panel-shopping-list.ts | 8 +-- src/translations/en.json | 35 ++++++++- 152 files changed, 1222 insertions(+), 1120 deletions(-) diff --git a/gallery/src/ha-gallery.js b/gallery/src/ha-gallery.js index 9d09da0119..7f53dd717a 100644 --- a/gallery/src/ha-gallery.js +++ b/gallery/src/ha-gallery.js @@ -65,10 +65,11 @@ class HaGallery extends PolymerElement { + > + +
[[_withDefault(_demo, "Home Assistant Gallery")]]
diff --git a/hassio/src/addon-store/hassio-addon-store.ts b/hassio/src/addon-store/hassio-addon-store.ts index a1dbe3237f..4cc55898a1 100644 --- a/hassio/src/addon-store/hassio-addon-store.ts +++ b/hassio/src/addon-store/hassio-addon-store.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiDotsVertical } from "@mdi/js"; @@ -18,7 +17,7 @@ import { navigate } from "../../../src/common/navigate"; import "../../../src/common/search/search-input"; import { extractSearchParam } from "../../../src/common/url/search-params"; import "../../../src/components/ha-button-menu"; -import "../../../src/components/ha-svg-icon"; +import "../../../src/components/ha-icon-button"; import { HassioAddonInfo, HassioAddonRepository, @@ -92,9 +91,11 @@ class HassioAddonStore extends LitElement { slot="toolbar-icon" @action=${this._handleAction} > - - - + ${this.supervisor.localize("store.repositories")} @@ -113,6 +114,7 @@ class HassioAddonStore extends LitElement { : html` ${this._restoringBackup @@ -110,9 +113,11 @@ class HassioBackupDialog @action=${this._handleMenuAction} @closed=${stopPropagation} > - - - + Download Backup Delete Backup ` @@ -126,9 +131,6 @@ class HassioBackupDialog haStyle, haStyleDialog, css` - ha-svg-icon { - color: var(--primary-text-color); - } ha-circular-progress { display: block; text-align: center; diff --git a/hassio/src/dialogs/hardware/dialog-hassio-hardware.ts b/hassio/src/dialogs/hardware/dialog-hassio-hardware.ts index a8d1481c84..b3e82c46d2 100755 --- a/hassio/src/dialogs/hardware/dialog-hassio-hardware.ts +++ b/hassio/src/dialogs/hardware/dialog-hassio-hardware.ts @@ -7,6 +7,7 @@ import "../../../../src/common/search/search-input"; import { stringCompare } from "../../../../src/common/string/compare"; import "../../../../src/components/ha-dialog"; import "../../../../src/components/ha-expansion-panel"; +import "../../../../src/components/ha-icon-button"; import { HassioHardwareInfo } from "../../../../src/data/hassio/hardware"; import { dump } from "../../../../src/resources/js-yaml-dump"; import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; @@ -70,10 +71,13 @@ class HassioHardwareDialog extends LitElement {

${this._dialogParams.supervisor.localize("dialog.hardware.title")}

- - - + ${this.supervisor.localize("dialog.network.title")} - - - + ${this._interfaces.length > 1 ? html` - - - + > ` ) @@ -234,7 +232,7 @@ class HassioRegistriesDialog extends LitElement { mwc-button { margin-left: 8px; } - mwc-icon-button { + ha-icon-button { color: var(--error-color); margin: -10px; } diff --git a/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts b/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts index 64eb324a20..03f1fc0395 100644 --- a/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts +++ b/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts @@ -1,5 +1,4 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiDelete } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; @@ -13,7 +12,7 @@ import { caseInsensitiveStringCompare } from "../../../../src/common/string/comp import "../../../../src/components/ha-alert"; import "../../../../src/components/ha-circular-progress"; import { createCloseHeading } from "../../../../src/components/ha-dialog"; -import "../../../../src/components/ha-svg-icon"; +import "../../../../src/components/ha-icon-button"; import { fetchHassioAddonsInfo, HassioAddonRepository, @@ -90,15 +89,14 @@ class HassioRepositoriesDialog extends LitElement {
${repo.maintainer}
${repo.url}
- - - + > ` ) diff --git a/hassio/src/dialogs/update/dialog-supervisor-update.ts b/hassio/src/dialogs/update/dialog-supervisor-update.ts index ca832ff776..cc4f80bb09 100644 --- a/hassio/src/dialogs/update/dialog-supervisor-update.ts +++ b/hassio/src/dialogs/update/dialog-supervisor-update.ts @@ -6,7 +6,6 @@ import "../../../../src/components/ha-alert"; import "../../../../src/components/ha-circular-progress"; import "../../../../src/components/ha-dialog"; import "../../../../src/components/ha-settings-row"; -import "../../../../src/components/ha-svg-icon"; import "../../../../src/components/ha-switch"; import { extractApiErrorMessage, diff --git a/hassio/src/ingress-view/hassio-ingress-view.ts b/hassio/src/ingress-view/hassio-ingress-view.ts index 91c338a3e5..9deb9bb45a 100644 --- a/hassio/src/ingress-view/hassio-ingress-view.ts +++ b/hassio/src/ingress-view/hassio-ingress-view.ts @@ -12,6 +12,7 @@ import { fireEvent } from "../../../src/common/dom/fire_event"; import { navigate } from "../../../src/common/navigate"; import { extractSearchParam } from "../../../src/common/url/search-params"; import { nextRender } from "../../../src/common/util/render-status"; +import "../../../src/components/ha-icon-button"; import { fetchHassioAddonInfo, HassioAddonDetails, @@ -72,12 +73,11 @@ class HassioIngressView extends LitElement { return html`${this.narrow || this.hass.dockedSidebar === "always_hidden" ? html`
- - - + >
${this._addon.name}
${iframe}` @@ -241,7 +241,7 @@ class HassioIngressView extends LitElement { flex-grow: 1; } - mwc-icon-button { + ha-icon-button { pointer-events: auto; } diff --git a/hassio/src/system/hassio-host-info.ts b/hassio/src/system/hassio-host-info.ts index 89aab52da9..64b7f90e8f 100644 --- a/hassio/src/system/hassio-host-info.ts +++ b/hassio/src/system/hassio-host-info.ts @@ -9,6 +9,7 @@ import { fireEvent } from "../../../src/common/dom/fire_event"; import "../../../src/components/buttons/ha-progress-button"; import "../../../src/components/ha-button-menu"; import "../../../src/components/ha-card"; +import "../../../src/components/ha-icon-button"; import "../../../src/components/ha-settings-row"; import { extractApiErrorMessage, @@ -181,9 +182,11 @@ class HassioHostInfo extends LitElement { : ""} - - - + ${this.filter && html` - - - + .label=${this.hass.localize("ui.common.clear")} + .path=${mdiClose} + > `} `; @@ -90,10 +92,10 @@ class SearchInput extends LitElement { static get styles(): CSSResultGroup { return css` ha-svg-icon, - mwc-icon-button { + ha-icon-button { color: var(--primary-text-color); } - mwc-icon-button { + ha-icon-button { --mdc-icon-button-size: 24px; } ha-svg-icon.prefix { diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index 6419406adf..c3c34b80bb 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -30,6 +30,7 @@ import "../ha-checkbox"; import type { HaCheckbox } from "../ha-checkbox"; import "../ha-svg-icon"; import { filterData, sortData } from "./sort-filter"; +import { HomeAssistant } from "../../types"; declare global { // for fire event @@ -93,6 +94,8 @@ export interface SortableColumnContainer { @customElement("ha-data-table") export class HaDataTable extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + @property({ type: Object }) public columns: DataTableColumnContainer = {}; @property({ type: Array }) public data: DataTableRowData[] = []; @@ -232,6 +235,7 @@ export class HaDataTable extends LitElement { ? html`
${this.value - ? html` - - ` + > ` : ""} ${areas.length > 0 ? html` - - - + > ` : ""}
@@ -408,7 +404,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) { .suffix { display: flex; } - mwc-icon-button { + ha-icon-button { --mdc-icon-button-size: 24px; padding: 0px 2px; color: var(--secondary-text-color); diff --git a/src/components/device/ha-device-picker.ts b/src/components/device/ha-device-picker.ts index daf9969af1..3b13c963e1 100644 --- a/src/components/device/ha-device-picker.ts +++ b/src/components/device/ha-device-picker.ts @@ -338,7 +338,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { static get styles(): CSSResultGroup { return css` - paper-input > mwc-icon-button { + paper-input > ha-icon-button { --mdc-icon-button-size: 24px; padding: 2px; color: var(--secondary-text-color); diff --git a/src/components/entity/ha-entity-attribute-picker.ts b/src/components/entity/ha-entity-attribute-picker.ts index 778a7c991c..a4e45e57ed 100644 --- a/src/components/entity/ha-entity-attribute-picker.ts +++ b/src/components/entity/ha-entity-attribute-picker.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiCheck, mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; @@ -18,6 +17,7 @@ import { fireEvent } from "../../common/dom/fire_event"; import { PolymerChangedEvent } from "../../polymer-types"; import { HomeAssistant } from "../../types"; import { formatAttributeName } from "../../util/hass-attributes-util"; +import "../ha-icon-button"; import "../ha-svg-icon"; import "./state-badge"; @@ -114,31 +114,27 @@ class HaEntityAttributePicker extends LitElement {
${this.value ? html` - - - + > ` : ""} - - - + >
@@ -178,7 +174,7 @@ class HaEntityAttributePicker extends LitElement { .suffix { display: flex; } - mwc-icon-button { + ha-icon-button { --mdc-icon-button-size: 24px; padding: 0px 2px; color: var(--secondary-text-color); diff --git a/src/components/entity/ha-entity-picker.ts b/src/components/entity/ha-entity-picker.ts index 40816b289e..016684e6c2 100644 --- a/src/components/entity/ha-entity-picker.ts +++ b/src/components/entity/ha-entity-picker.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiCheck, mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-icon-item"; @@ -21,6 +20,7 @@ import { computeDomain } from "../../common/entity/compute_domain"; import { computeStateName } from "../../common/entity/compute_state_name"; import { PolymerChangedEvent } from "../../polymer-types"; import { HomeAssistant } from "../../types"; +import "../ha-icon-button"; import "../ha-svg-icon"; import "./state-badge"; @@ -267,31 +267,27 @@ export class HaEntityPicker extends LitElement {
${this.value && !this.hideClearIcon ? html` - - - + > ` : ""} - - - + >
@@ -340,7 +336,7 @@ export class HaEntityPicker extends LitElement { .suffix { display: flex; } - mwc-icon-button { + ha-icon-button { --mdc-icon-button-size: 24px; padding: 0px 2px; color: var(--secondary-text-color); diff --git a/src/components/entity/ha-entity-toggle.ts b/src/components/entity/ha-entity-toggle.ts index 5a3942d5d3..962af59b92 100644 --- a/src/components/entity/ha-entity-toggle.ts +++ b/src/components/entity/ha-entity-toggle.ts @@ -1,3 +1,4 @@ +import { mdiFlash, mdiFlashOff } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { css, @@ -41,15 +42,15 @@ export class HaEntityToggle extends LitElement { if (this.stateObj.attributes.assumed_state) { return html` mwc-icon-button { + paper-input > ha-icon-button { --mdc-icon-button-size: 24px; padding: 2px; color: var(--secondary-text-color); diff --git a/src/components/ha-alert.ts b/src/components/ha-alert.ts index ddd3c641e7..25c3975ac6 100644 --- a/src/components/ha-alert.ts +++ b/src/components/ha-alert.ts @@ -1,5 +1,4 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiAlertCircleOutline, mdiAlertOutline, @@ -11,6 +10,7 @@ import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../common/dom/fire_event"; +import "./ha-icon-button"; import "./ha-svg-icon"; const ALERT_ICONS = { @@ -66,12 +66,11 @@ class HaAlert extends LitElement { .label=${this.actionText} >` : this.dismissable - ? html` - - ` + label="Dismiss alert" + .path=${mdiClose} + >` : ""}
@@ -140,7 +139,7 @@ class HaAlert extends LitElement { mwc-button { --mdc-theme-primary: var(--primary-text-color); } - mwc-icon-button { + ha-icon-button { --mdc-icon-button-size: 36px; } .issue-type.info > .icon { diff --git a/src/components/ha-area-picker.ts b/src/components/ha-area-picker.ts index 2b991869b3..b79abb66a4 100644 --- a/src/components/ha-area-picker.ts +++ b/src/components/ha-area-picker.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiCheck, mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; @@ -42,6 +41,7 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin"; import { PolymerChangedEvent } from "../polymer-types"; import { HomeAssistant } from "../types"; import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker"; +import "./ha-icon-button"; import "./ha-svg-icon"; const rowRenderer: ComboBoxLitRenderer = ( @@ -362,28 +362,24 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { > ${this.value ? html` - - - + > ` : ""} - - - + > `; @@ -457,7 +453,7 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { static get styles(): CSSResultGroup { return css` - paper-input > mwc-icon-button { + paper-input > ha-icon-button { --mdc-icon-button-size: 24px; padding: 2px; color: var(--secondary-text-color); diff --git a/src/components/ha-button-related-filter-menu.ts b/src/components/ha-button-related-filter-menu.ts index 02db7f1e20..afbfff1966 100644 --- a/src/components/ha-button-related-filter-menu.ts +++ b/src/components/ha-button-related-filter-menu.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import type { Corner } from "@material/mwc-menu"; import "@material/mwc-menu/mwc-menu-surface"; import { mdiFilterVariant } from "@mdi/js"; @@ -12,7 +11,7 @@ import type { HomeAssistant } from "../types"; import "./device/ha-device-picker"; import "./entity/ha-entity-picker"; import "./ha-area-picker"; -import "./ha-svg-icon"; +import "./ha-icon-button"; declare global { // for fire event @@ -55,9 +54,10 @@ export class HaRelatedFilterButtonMenu extends LitElement { protected render(): TemplateResult { return html` - - - + ${this.buttons.map((button) => button.iconPath - ? html` - - ` + >` : html`[[value]] [[units]]
- + + +
- + + +
`; diff --git a/src/components/ha-combo-box.ts b/src/components/ha-combo-box.ts index 8abeaf24ba..afcd9c8911 100644 --- a/src/components/ha-combo-box.ts +++ b/src/components/ha-combo-box.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; @@ -11,7 +10,7 @@ import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { PolymerChangedEvent } from "../polymer-types"; import { HomeAssistant } from "../types"; -import "./ha-svg-icon"; +import "./ha-icon-button"; // eslint-disable-next-line lit/prefer-static-styles const defaultRowRenderer: ComboBoxLitRenderer = (item) => html`
- + + + `; } diff --git a/src/panels/config/dashboard/ha-config-dashboard.ts b/src/panels/config/dashboard/ha-config-dashboard.ts index f81527cce0..b7428354e4 100644 --- a/src/panels/config/dashboard/ha-config-dashboard.ts +++ b/src/panels/config/dashboard/ha-config-dashboard.ts @@ -7,7 +7,6 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import "../../../components/ha-card"; import "../../../components/ha-icon-next"; import "../../../components/ha-menu-button"; -import "../../../components/ha-svg-icon"; import { CloudStatus } from "../../../data/cloud"; import "../../../layouts/ha-app-layout"; import { haStyle } from "../../../resources/styles"; diff --git a/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts b/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts index 13f930437c..8ad148eef4 100644 --- a/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts +++ b/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts @@ -25,7 +25,7 @@ class DialogDeviceRegistryDetail extends LitElement { @state() private _params?: DeviceRegistryDetailDialogParams; - @state() private _areaId?: string | null; + @property() public _areaId?: string | null; @state() private _disabledBy!: string | null; diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 25206b1ca9..b130d34e91 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -1,3 +1,4 @@ +import { mdiPencil, mdiPlusCircle } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -9,6 +10,7 @@ import { computeStateName } from "../../../common/entity/compute_state_name"; import { stringCompare } from "../../../common/string/compare"; import { slugify } from "../../../common/string/slugify"; import "../../../components/entity/ha-battery-icon"; +import "../../../components/ha-icon-button"; import "../../../components/ha-icon-next"; import { AreaRegistryEntry } from "../../../data/area_registry"; import { @@ -184,8 +186,11 @@ export class HaConfigDevicePage extends LitElement { ` : "" @@ -216,8 +221,11 @@ export class HaConfigDevicePage extends LitElement { : ""} ` @@ -315,14 +323,14 @@ export class HaConfigDevicePage extends LitElement { ${this._related?.automation?.length @@ -387,20 +395,20 @@ export class HaConfigDevicePage extends LitElement { "ui.panel.config.devices.scene.scenes" )} - + ${ @@ -471,14 +479,14 @@ export class HaConfigDevicePage extends LitElement { ${this._related?.script?.length diff --git a/src/panels/config/devices/ha-config-devices-dashboard.ts b/src/panels/config/devices/ha-config-devices-dashboard.ts index 97502831d2..c8f12b685f 100644 --- a/src/panels/config/devices/ha-config-devices-dashboard.ts +++ b/src/panels/config/devices/ha-config-devices-dashboard.ts @@ -17,6 +17,7 @@ import { } from "../../../components/data-table/ha-data-table"; import "../../../components/entity/ha-battery-icon"; import "../../../components/ha-button-menu"; +import "../../../components/ha-icon-button"; import { AreaRegistryEntry } from "../../../data/area_registry"; import { ConfigEntry } from "../../../data/config_entries"; import { @@ -407,17 +408,13 @@ export class HaConfigDeviceDashboard extends LitElement { ` : html``} - - - + .path=${mdiFilterVariant} + > - - - - - - + + `; })} diff --git a/src/panels/config/energy/components/ha-energy-device-settings.ts b/src/panels/config/energy/components/ha-energy-device-settings.ts index eae9906b36..c805e92abf 100644 --- a/src/panels/config/energy/components/ha-energy-device-settings.ts +++ b/src/panels/config/energy/components/ha-energy-device-settings.ts @@ -6,6 +6,7 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { computeStateName } from "../../../../common/entity/compute_state_name"; import { stateIcon } from "../../../../common/entity/state_icon"; import "../../../../components/ha-card"; +import "../../../../components/ha-icon-button"; import { DeviceConsumptionEnergyPreference, EnergyPreferences, @@ -13,8 +14,8 @@ import { saveEnergyPreferences, } from "../../../../data/energy"; import { - showConfirmationDialog, showAlertDialog, + showConfirmationDialog, } from "../../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; @@ -84,9 +85,11 @@ export class EnergyDeviceSettings extends LitElement { ? computeStateName(entityState) : device.stat_consumption} - - - + `; })} diff --git a/src/panels/config/energy/components/ha-energy-gas-settings.ts b/src/panels/config/energy/components/ha-energy-gas-settings.ts index 13ff04c2a7..3f92d1a023 100644 --- a/src/panels/config/energy/components/ha-energy-gas-settings.ts +++ b/src/panels/config/energy/components/ha-energy-gas-settings.ts @@ -5,17 +5,18 @@ import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; import { computeStateName } from "../../../../common/entity/compute_state_name"; import "../../../../components/ha-card"; +import "../../../../components/ha-icon-button"; import { EnergyPreferences, - saveEnergyPreferences, - GasSourceTypeEnergyPreference, EnergyPreferencesValidation, EnergyValidationIssue, + GasSourceTypeEnergyPreference, getEnergyGasUnitCategory, + saveEnergyPreferences, } from "../../../../data/energy"; import { - showConfirmationDialog, showAlertDialog, + showConfirmationDialog, } from "../../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; @@ -92,12 +93,14 @@ export class EnergyGasSettings extends LitElement { ? computeStateName(entityState) : source.stat_energy_from} - - - - - - + + `; })} diff --git a/src/panels/config/energy/components/ha-energy-grid-settings.ts b/src/panels/config/energy/components/ha-energy-grid-settings.ts index 652a7e01f2..d0b3df4e76 100644 --- a/src/panels/config/energy/components/ha-energy-grid-settings.ts +++ b/src/panels/config/energy/components/ha-energy-grid-settings.ts @@ -11,6 +11,7 @@ import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; import { computeStateName } from "../../../../common/entity/compute_state_name"; import "../../../../components/ha-card"; +import "../../../../components/ha-icon-button"; import { ConfigEntry, deleteConfigEntry, @@ -130,12 +131,14 @@ export class EnergyGridSettings extends LitElement { ? computeStateName(entityState) : flow.stat_energy_from} - - - - - - + + `; })} @@ -167,12 +170,14 @@ export class EnergyGridSettings extends LitElement { ? computeStateName(entityState) : flow.stat_energy_to} - - - - - - + + `; })} @@ -202,13 +207,12 @@ export class EnergyGridSettings extends LitElement { /> ${entry.title} - - - + - - - + ` )} ${this._configEntries?.length === 0 diff --git a/src/panels/config/energy/components/ha-energy-solar-settings.ts b/src/panels/config/energy/components/ha-energy-solar-settings.ts index 9f1bbd3712..eca1055649 100644 --- a/src/panels/config/energy/components/ha-energy-solar-settings.ts +++ b/src/panels/config/energy/components/ha-energy-solar-settings.ts @@ -5,6 +5,7 @@ import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; import { computeStateName } from "../../../../common/entity/compute_state_name"; import "../../../../components/ha-card"; +import "../../../../components/ha-icon-button"; import { EnergyInfo, EnergyPreferences, @@ -102,14 +103,16 @@ export class EnergySolarSettings extends LitElement { > ${this.info ? html` - - - + ` : ""} - - - + `; })} diff --git a/src/panels/config/energy/components/styles.ts b/src/panels/config/energy/components/styles.ts index 91ef2109cd..5aab3c4dbc 100644 --- a/src/panels/config/energy/components/styles.ts +++ b/src/panels/config/energy/components/styles.ts @@ -31,7 +31,7 @@ export const energyCardStyles = css` .row .content { flex-grow: 1; } - mwc-icon-button { + ha-icon-button { color: var(--secondary-text-color); } `; diff --git a/src/panels/config/energy/ha-config-energy.ts b/src/panels/config/energy/ha-config-energy.ts index 83e1ef20e2..b93c93c749 100644 --- a/src/panels/config/energy/ha-config-energy.ts +++ b/src/panels/config/energy/ha-config-energy.ts @@ -1,6 +1,5 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; -import "../../../components/ha-svg-icon"; import { EnergyPreferencesValidation, getEnergyPreferenceValidation, diff --git a/src/panels/config/entities/dialog-entity-editor.ts b/src/panels/config/entities/dialog-entity-editor.ts index 706207f053..74bae4b7cb 100644 --- a/src/panels/config/entities/dialog-entity-editor.ts +++ b/src/panels/config/entities/dialog-entity-editor.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import "@material/mwc-tab"; import "@material/mwc-tab-bar"; import { mdiClose, mdiTune } from "@mdi/js"; @@ -11,8 +10,8 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { computeStateName } from "../../../common/entity/compute_state_name"; import "../../../components/ha-dialog"; import "../../../components/ha-header-bar"; +import "../../../components/ha-icon-button"; import "../../../components/ha-related-items"; -import "../../../components/ha-svg-icon"; import { EntityRegistryEntry, ExtEntityRegistryEntry, @@ -82,27 +81,25 @@ export class DialogEntityEditor extends LitElement { >
- - - + > ${stateObj ? computeStateName(stateObj) : entry?.name || entityId} ${stateObj ? html` - - - + > ` : ""} diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index 3c26266704..7dfe441b87 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -14,7 +14,7 @@ import "@polymer/paper-listbox/paper-listbox"; import "@polymer/paper-tooltip/paper-tooltip"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state, query } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import memoize from "memoize-one"; @@ -33,6 +33,7 @@ import type { SelectionChangedEvent, } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-button-menu"; +import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import { AreaRegistryEntry, @@ -540,32 +541,35 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { > ` : html` - + .path=${mdiUndo} + .label=${this.hass.localize("ui.common.enable")} + > ${this.hass.localize( "ui.panel.config.entities.picker.enable_selected.button" )} - + .path=${mdiCancel} + .label=${this.hass.localize("ui.common.disable")} + > ${this.hass.localize( "ui.panel.config.entities.picker.disable_selected.button" )} - + .path=${mdiDelete} + .label=${this.hass.localize("ui.common.remove")} + > ${this.hass.localize( "ui.panel.config.entities.picker.remove_selected.button" @@ -575,17 +579,13 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
` : html` - - - + .path=${mdiFilterVariant} + > mwc-button, - .header-btns > mwc-icon-button { + .header-btns > ha-icon-button { margin: 8px; } ha-button-menu { diff --git a/src/panels/config/helpers/forms/ha-input_select-form.ts b/src/panels/config/helpers/forms/ha-input_select-form.ts index 9664e14979..a269c3e938 100644 --- a/src/panels/config/helpers/forms/ha-input_select-form.ts +++ b/src/panels/config/helpers/forms/ha-input_select-form.ts @@ -1,10 +1,11 @@ import "@material/mwc-button/mwc-button"; +import { mdiDelete } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-item/paper-item-body"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state, query } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-icon-button"; import "../../../../components/ha-icon-input"; @@ -89,11 +90,11 @@ class HaInputSelectForm extends LitElement { ${option} ` diff --git a/src/panels/config/info/system-health-card.ts b/src/panels/config/info/system-health-card.ts index 28c139609a..5f825ac37a 100644 --- a/src/panels/config/info/system-health-card.ts +++ b/src/panels/config/info/system-health-card.ts @@ -1,5 +1,4 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-icon-button"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiContentCopy } from "@mdi/js"; @@ -12,7 +11,7 @@ import { copyToClipboard } from "../../../common/util/copy-clipboard"; import "../../../components/ha-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-circular-progress"; -import "../../../components/ha-svg-icon"; +import "../../../components/ha-icon-button"; import { domainToName } from "../../../data/integration"; import { subscribeSystemHealthInfo, @@ -150,9 +149,11 @@ class SystemHealthCard extends LitElement { slot="toolbar-icon" @action=${this._copyInfo} > - - - + ${this.hass.localize("ui.panel.config.info.copy_raw")} diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index 55e691d524..51ffe7e2f4 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import { ActionDetail } from "@material/mwc-list"; import "@material/mwc-list/mwc-list-item"; import { mdiFilterVariant, mdiPlus } from "@mdi/js"; @@ -25,6 +24,7 @@ import { nextRender } from "../../../common/util/render-status"; import "../../../components/ha-button-menu"; import "../../../components/ha-checkbox"; import "../../../components/ha-fab"; +import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { ConfigEntry, getConfigEntries } from "../../../data/config_entries"; @@ -290,13 +290,12 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { slot=${ifDefined(this.narrow ? "toolbar-icon" : undefined)} @action=${this._handleMenuAction} > - - - + ${this.hass.localize( @@ -326,6 +325,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { ? html`
` @@ -291,13 +298,11 @@ export class HaIntegrationCard extends LitElement { : ""} - - - + .label=${this.hass.localize("ui.common.menu")} + .path=${mdiDotsVertical} + > ${this.hass.localize( "ui.panel.config.integrations.config_entry.rename" diff --git a/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts b/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts index 255579d4ad..032ee83778 100644 --- a/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts +++ b/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-children.ts @@ -101,6 +101,7 @@ class DialogZHADeviceChildren extends LitElement { active >` : html` diff --git a/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts b/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts index de1a2781c5..d00e672d5f 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts @@ -1,3 +1,4 @@ +import { mdiHelpCircle } from "@mdi/js"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; @@ -72,7 +73,8 @@ export class ZHAClusterCommands extends LitElement { diff --git a/src/panels/config/integrations/integration-panels/zha/zha-clusters-data-table.ts b/src/panels/config/integrations/integration-panels/zha/zha-clusters-data-table.ts index e29bcbe10d..f4f0e5fdbf 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-clusters-data-table.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-clusters-data-table.ts @@ -76,6 +76,7 @@ export class ZHAClustersDataTable extends LitElement { protected render(): TemplateResult { return html` diff --git a/src/panels/config/integrations/integration-panels/zha/zha-device-binding.ts b/src/panels/config/integrations/integration-panels/zha/zha-device-binding.ts index cc5623422d..024e35db24 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-device-binding.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-device-binding.ts @@ -1,4 +1,5 @@ import "@material/mwc-button/mwc-button"; +import { mdiHelpCircle } from "@mdi/js"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-listbox/paper-listbox"; @@ -52,7 +53,8 @@ export class ZHADeviceBindingControl extends LitElement { diff --git a/src/panels/config/integrations/integration-panels/zha/zha-device-endpoint-data-table.ts b/src/panels/config/integrations/integration-panels/zha/zha-device-endpoint-data-table.ts index eb2237a716..bebc5826a8 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-device-endpoint-data-table.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-device-endpoint-data-table.ts @@ -137,6 +137,7 @@ export class ZHADeviceEndpointDataTable extends LitElement { protected render(): TemplateResult { return html` diff --git a/src/panels/config/integrations/integration-panels/zha/zha-group-page.ts b/src/panels/config/integrations/integration-panels/zha/zha-group-page.ts index af438db7f3..55909499ac 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-group-page.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-group-page.ts @@ -1,4 +1,5 @@ import "@material/mwc-button"; +import { mdiDelete } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; import { customElement, property, state, query } from "lit/decorators"; import { HASSDomEvent } from "../../../../../common/dom/fire_event"; @@ -101,8 +102,9 @@ export class ZHAGroupPage extends LitElement { >
diff --git a/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts b/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts index 737f504a2f..8403cac13b 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-network-visualization-page.ts @@ -14,7 +14,6 @@ import "../../../../../components/ha-button-menu"; import "../../../../../components/ha-checkbox"; import type { HaCheckbox } from "../../../../../components/ha-checkbox"; import "../../../../../components/ha-formfield"; -import "../../../../../components/ha-svg-icon"; import { DeviceRegistryEntry } from "../../../../../data/device_registry"; import { fetchDevices, @@ -142,6 +141,7 @@ export class ZHANetworkVisualizationPage extends LitElement { ? html`
${!this.narrow ? html`[[localize('ui.panel.config.zwave.node_management.header')]] - + + +
[[localize('ui.panel.config.zwave.node_management.introduction')]] diff --git a/src/panels/config/integrations/integration-panels/zwave/zwave-network.ts b/src/panels/config/integrations/integration-panels/zwave/zwave-network.ts index 9a346e7551..4e87e96b1b 100644 --- a/src/panels/config/integrations/integration-panels/zwave/zwave-network.ts +++ b/src/panels/config/integrations/integration-panels/zwave/zwave-network.ts @@ -1,3 +1,4 @@ +import { mdiHelpCircle } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -55,7 +56,8 @@ export class ZwaveNetwork extends LitElement {
diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts index e24de84726..dbd163508f 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-dashboard.ts @@ -1,10 +1,10 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiAlertCircle, mdiCheckCircle, mdiCircle, mdiRefresh } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import "../../../../../components/ha-card"; +import "../../../../../components/ha-icon-button"; import "../../../../../components/ha-icon-next"; import "../../../../../components/ha-svg-icon"; import { getSignedPath } from "../../../../../data/auth"; @@ -83,9 +83,12 @@ class ZWaveJSConfigDashboard extends LitElement { .route=${this.route} .tabs=${configTabs} > - - - +
${this.hass.localize("ui.panel.config.zwave_js.dashboard.header")} diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-logs.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-logs.ts index 8df84d6576..42f9c88675 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-logs.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-logs.ts @@ -1,9 +1,11 @@ +import { mdiDownload } from "@mdi/js"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; import "@polymer/paper-listbox/paper-listbox"; -import { mdiDownload } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultArray, html, LitElement } from "lit"; -import { customElement, property, state, query } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; +import { capitalizeFirstLetter } from "../../../../../common/string/capitalize-first-letter"; +import "../../../../../components/ha-icon-button"; import { fetchZWaveJSLogConfig, setZWaveJSLogLevel, @@ -16,7 +18,6 @@ import { haStyle } from "../../../../../resources/styles"; import { HomeAssistant, Route } from "../../../../../types"; import { fileDownload } from "../../../../../util/file_download"; import { configTabs } from "./zwave_js-config-router"; -import { capitalizeFirstLetter } from "../../../../../common/string/capitalize-first-letter"; @customElement("zwave_js-logs") class ZWaveJSLogs extends SubscribeMixin(LitElement) { @@ -99,14 +100,13 @@ class ZWaveJSLogs extends SubscribeMixin(LitElement) { ` : ""}
- - - + .path=${mdiDownload} + >
diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts index 993b3cc7a9..9b2e0a4bdf 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts @@ -1,5 +1,4 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiCheckCircle, mdiCircle, diff --git a/src/panels/config/logs/dialog-system-log-detail.ts b/src/panels/config/logs/dialog-system-log-detail.ts index 074a87eafb..783d7e4627 100644 --- a/src/panels/config/logs/dialog-system-log-detail.ts +++ b/src/panels/config/logs/dialog-system-log-detail.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiClose, mdiContentCopy, mdiPackageVariant } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; @@ -7,6 +6,7 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { copyToClipboard } from "../../../common/util/copy-clipboard"; import "../../../components/ha-dialog"; import "../../../components/ha-header-bar"; +import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import { domainToName, @@ -64,15 +64,18 @@ class DialogSystemLogDetail extends LitElement { const showDocumentation = this._manifest && (this._manifest.is_built_in || - // Custom components with our offical docs should not link to our docs + // Custom components with our official docs should not link to our docs !this._manifest.documentation.includes("://www.home-assistant.io")); return html` - - - + ${this.hass.localize( "ui.panel.config.logs.details", @@ -84,9 +87,13 @@ class DialogSystemLogDetail extends LitElement { >` )} - - - + ${this.isCustomIntegration ? html`
diff --git a/src/panels/config/logs/error-log-card.ts b/src/panels/config/logs/error-log-card.ts index b096fb93ad..bd9c7f9e7d 100644 --- a/src/panels/config/logs/error-log-card.ts +++ b/src/panels/config/logs/error-log-card.ts @@ -1,4 +1,5 @@ import "@material/mwc-button"; +import { mdiRefresh } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { property, state } from "lit/decorators"; import "../../../components/ha-icon-button"; @@ -17,8 +18,9 @@ class ErrorLogCard extends LitElement { ? html`
${this._errorHTML}
diff --git a/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts b/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts index cec992c52c..26b0551106 100644 --- a/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts +++ b/src/panels/config/lovelace/dashboards/ha-config-lovelace-dashboards.ts @@ -1,4 +1,4 @@ -import { mdiPlus } from "@mdi/js"; +import { mdiOpenInNew, mdiPlus } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -149,9 +149,12 @@ export class HaConfigLovelaceDashboards extends LitElement { narrow ? html` ` : html` diff --git a/src/panels/config/scene/ha-scene-dashboard.ts b/src/panels/config/scene/ha-scene-dashboard.ts index a3399fc85a..46d40bcaae 100644 --- a/src/panels/config/scene/ha-scene-dashboard.ts +++ b/src/panels/config/scene/ha-scene-dashboard.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import { mdiHelpCircle, mdiInformationOutline, @@ -19,6 +18,7 @@ import { DataTableColumnContainer } from "../../../components/data-table/ha-data import "../../../components/ha-button-related-filter-menu"; import "../../../components/ha-fab"; import "../../../components/ha-icon"; +import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import { forwardHaptic } from "../../../data/haptics"; import { activateScene, SceneEntity } from "../../../data/scene"; @@ -72,15 +72,14 @@ class HaSceneDashboard extends LitElement { type: "icon-button", template: (_toggle, scene) => html` - - - + > `, }, icon: { @@ -99,15 +98,14 @@ class HaSceneDashboard extends LitElement { title: "", type: "icon-button", template: (_info, scene) => html` - - - + .path=${mdiInformationOutline} + > `, }, edit: { @@ -121,16 +119,13 @@ class HaSceneDashboard extends LitElement { : undefined )} > - - - + .path=${scene.attributes.id ? mdiPencil : mdiPencilOff} + > ${!scene.attributes.id ? html` @@ -164,9 +159,12 @@ class HaSceneDashboard extends LitElement { @clear-filter=${this._clearFilter} hasFab > - - - + - - + .label=${this.hass.localize("ui.common.menu")} + .path=${mdiDotsVertical} + > ${device.name} - - + .label=${this.hass.localize("ui.common.menu")} + .path=${mdiDotsVertical} + > html` - - - + .path=${mdiPlay} + > `, }, icon: { @@ -128,13 +127,14 @@ class HaScriptPicker extends LitElement { title: "", type: "icon-button", template: (_info, script) => html` - - - + .label=${this.hass.localize( + "ui.panel.config.script.picker.show_info" + )} + .path=${mdiInformationOutline} + > `, }; columns.trace = { @@ -142,13 +142,12 @@ class HaScriptPicker extends LitElement { type: "icon-button", template: (_info, script: any) => html` - - - + .path=${mdiHistory} + > `, }; @@ -157,13 +156,12 @@ class HaScriptPicker extends LitElement { type: "icon-button", template: (_info, script: any) => html` - - - + .path=${mdiPencil} + > `, }; @@ -188,9 +186,12 @@ class HaScriptPicker extends LitElement { @clear-filter=${this._clearFilter} hasFab > - - - + - - - + - - + .path=${mdiDownload} + > `; return html` @@ -120,23 +122,24 @@ export class HaScriptTrace extends LitElement { class="linkButton" href="/config/script/edit/${this.scriptEntityId}" > - - - +
` : ""} ${this._traces && this._traces.length > 0 ? html`
- - - + .path=${mdiRayEndArrow} + > - - - + .path=${mdiRayStartArrow} + >
` : ""} diff --git a/src/panels/config/tags/ha-config-tags.ts b/src/panels/config/tags/ha-config-tags.ts index 09d5096d16..d0c6b780c0 100644 --- a/src/panels/config/tags/ha-config-tags.ts +++ b/src/panels/config/tags/ha-config-tags.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import { mdiCog, mdiContentDuplicate, @@ -12,6 +11,7 @@ import memoizeOne from "memoize-one"; import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-card"; import "../../../components/ha-fab"; +import "../../../components/ha-icon-button"; import "../../../components/ha-relative-time"; import { showAutomationEditor, TagTrigger } from "../../../data/automation"; import { @@ -107,36 +107,33 @@ export class HaConfigTags extends SubscribeMixin(LitElement) { columns.write = { title: "", type: "icon-button", - template: (_write, tag: any) => html` html` - - `, + .label=${this.hass.localize("ui.panel.config.tag.write")} + .path=${mdiContentDuplicate} + >`, }; } columns.automation = { title: "", type: "icon-button", - template: (_automation, tag: any) => html` html` - - `, + .label=${this.hass.localize("ui.panel.config.tag.create_automation")} + .path=${mdiRobot} + >`, }; columns.edit = { title: "", type: "icon-button", - template: (_settings, tag: any) => html` html` - - `, + .label=${this.hass.localize("ui.panel.config.tag.edit")} + .path=${mdiCog} + >`, }; return columns; } @@ -193,9 +190,12 @@ export class HaConfigTags extends SubscribeMixin(LitElement) { .noDataText=${this.hass.localize("ui.panel.config.tag.no_tags")} hasFab > - - - + `; + return html``; } const hass = this.hass; const listBox = @@ -151,15 +151,17 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { .entry=${entry} > - ${entry.name} + ${entry.name} ${!this.narrow ? html` - - - + .path=${mdiPencil} + .label=${hass.localize( + "ui.panel.config.zone.edit_zone" + )} + > ` : ""} @@ -181,7 +183,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { stateObject.entity_id}
- - - + .path=${stateObject.entity_id === "zone.home" && + this.narrow && + this._canEditCore + ? mdiPencil + : mdiPencilOff} + .label=${hass.localize( + "ui.panel.config.zone.edit_zone" + )} + > ${stateObject.entity_id === "zone.home" - ? this.hass.localize( + ? hass.localize( `ui.panel.config.zone.${ this.narrow ? "edit_home_zone_narrow" : "edit_home_zone" }` ) - : this.hass.localize( + : hass.localize( "ui.panel.config.zone.configured_in_yaml" )} @@ -488,10 +490,10 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { overflow: hidden; } ha-icon, - mwc-icon-button:not([disabled]) { + ha-icon-button:not([disabled]) { color: var(--secondary-text-color); } - mwc-icon-button { + ha-icon-button { --mdc-theme-text-disabled-on-light: var(--disabled-text-color); } .empty { @@ -520,6 +522,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { paper-icon-item { padding-top: 4px; padding-bottom: 4px; + cursor: pointer; } .overflow paper-icon-item:last-child { margin-bottom: 80px; diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index a560d70693..77b85734b9 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -14,6 +14,7 @@ import { HaProgressButton } from "../../../components/buttons/ha-progress-button import "../../../components/entity/ha-entity-picker"; import "../../../components/ha-card"; import "../../../components/ha-expansion-panel"; +import "../../../components/ha-icon-button"; import "../../../components/ha-service-control"; import "../../../components/ha-service-picker"; import "../../../components/ha-yaml-editor"; @@ -185,12 +186,11 @@ class HaPanelDevService extends LitElement { target="_blank" rel="noreferrer" > - - - + ` : ""}
` diff --git a/src/panels/developer-tools/state/developer-tools-state.js b/src/panels/developer-tools/state/developer-tools-state.js index 201619bb3b..4d4102227e 100644 --- a/src/panels/developer-tools/state/developer-tools-state.js +++ b/src/panels/developer-tools/state/developer-tools-state.js @@ -16,6 +16,7 @@ import { escapeRegExp } from "../../../common/string/escape_regexp"; import { copyToClipboard } from "../../../common/util/copy-clipboard"; import "../../../components/entity/ha-entity-picker"; import "../../../components/ha-code-editor"; +import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { EventsMixin } from "../../../mixins/events-mixin"; @@ -165,11 +166,11 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) { raised >[[localize('ui.panel.developer-tools.tabs.states.set_state')]] - + path="[[refreshIcon()]]" + >
diff --git a/src/panels/energy/ha-panel-energy.ts b/src/panels/energy/ha-panel-energy.ts index 5f825fede5..09673e961f 100644 --- a/src/panels/energy/ha-panel-energy.ts +++ b/src/panels/energy/ha-panel-energy.ts @@ -122,7 +122,7 @@ class PanelEnergy extends LitElement { return [ haStyle, css` - mwc-icon-button { + ha-icon-button { color: var(--text-primary-color); } app-toolbar { diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts index c1f7ae5fd6..aa6b043e64 100644 --- a/src/panels/history/ha-panel-history.ts +++ b/src/panels/history/ha-panel-history.ts @@ -18,6 +18,7 @@ import "../../components/entity/ha-entity-picker"; import "../../components/ha-circular-progress"; import "../../components/ha-date-range-picker"; import type { DateRangePickerRanges } from "../../components/ha-date-range-picker"; +import "../../components/ha-icon-button"; import "../../components/ha-menu-button"; import { computeHistory, fetchDate } from "../../data/history"; import "../../layouts/ha-app-layout"; @@ -65,12 +66,12 @@ class HaPanelHistory extends LitElement { .narrow=${this.narrow} >
${this.hass.localize("panel.history")}
- - - + .path=${mdiRefresh} + .label=${this.hass.localize("ui.common.refresh")} + > diff --git a/src/panels/logbook/ha-panel-logbook.ts b/src/panels/logbook/ha-panel-logbook.ts index 8b7987f8d1..8c8ff39e89 100644 --- a/src/panels/logbook/ha-panel-logbook.ts +++ b/src/panels/logbook/ha-panel-logbook.ts @@ -1,5 +1,4 @@ import { mdiRefresh } from "@mdi/js"; -import "@material/mwc-icon-button"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; import { css, html, LitElement, PropertyValues } from "lit"; @@ -20,6 +19,7 @@ import "../../components/entity/ha-entity-picker"; import "../../components/ha-circular-progress"; import "../../components/ha-date-range-picker"; import type { DateRangePickerRanges } from "../../components/ha-date-range-picker"; +import "../../components/ha-icon-button"; import "../../components/ha-menu-button"; import { clearLogbookCache, @@ -82,12 +82,12 @@ export class HaPanelLogbook extends LitElement { .narrow=${this.narrow} >
${this.hass.localize("panel.logbook")}
- - - + > diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index b1337abf0a..9baf03d160 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -1,3 +1,4 @@ +import { mdiDotsVertical } from "@mdi/js"; import "@thomasloven/round-slider"; import { HassEntity } from "home-assistant-js-websocket"; import { @@ -158,7 +159,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { return html` - - - + >
@@ -131,7 +133,6 @@ export class HuiLightCard extends LitElement implements LovelaceCard { "state-on": stateObj.state === "on", "state-unavailable": stateObj.state === UNAVAILABLE, })}" - .icon=${this._config.icon || stateIcon(stateObj)} .disabled=${UNAVAILABLE_STATES.includes(stateObj.state)} style=${styleMap({ filter: this._computeBrightness(stateObj), @@ -143,7 +144,11 @@ export class HuiLightCard extends LitElement implements LovelaceCard { hasDoubleClick: hasAction(this._config!.double_tap_action), })} tabindex="0" - > + > + +
diff --git a/src/panels/lovelace/cards/hui-map-card.ts b/src/panels/lovelace/cards/hui-map-card.ts index d660dae680..9efb669f41 100644 --- a/src/panels/lovelace/cards/hui-map-card.ts +++ b/src/panels/lovelace/cards/hui-map-card.ts @@ -137,13 +137,14 @@ class HuiMapCard extends LitElement implements LovelaceCard { .paths=${this._getHistoryPaths(this._config, this._history)} .darkMode=${this._config.dark_mode} > - - - + >
`; @@ -365,7 +366,7 @@ class HuiMapCard extends LitElement implements LovelaceCard { background: inherit; } - mwc-icon-button { + ha-icon-button { position: absolute; top: 75px; left: 3px; diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index 7a223f7bb0..7656cb8400 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -1,5 +1,4 @@ -import "@material/mwc-icon-button"; -import { mdiPlayBoxMultiple } from "@mdi/js"; +import { mdiDotsVertical, mdiPlayBoxMultiple } from "@mdi/js"; import "@polymer/paper-progress/paper-progress"; import type { PaperProgressElement } from "@polymer/paper-progress/paper-progress"; import { @@ -23,7 +22,6 @@ import { debounce } from "../../../common/util/debounce"; import "../../../components/ha-card"; import "../../../components/ha-icon"; import "../../../components/ha-icon-button"; -import "../../../components/ha-svg-icon"; import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog"; import { UNAVAILABLE_STATES } from "../../../data/entity"; import { @@ -237,7 +235,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
@@ -271,27 +269,26 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { ${controls!.map( (control) => html` + > + + ` )} ${supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA) ? html` - + > ` : ""}
@@ -692,7 +689,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { --mdc-icon-size: 40px; } - mwc-icon-button.browse-media { + ha-icon-button.browse-media { position: absolute; right: 4px; --mdc-icon-size: 24px; diff --git a/src/panels/lovelace/cards/hui-picture-glance-card.ts b/src/panels/lovelace/cards/hui-picture-glance-card.ts index 4a29f5679f..13b5e442ee 100644 --- a/src/panels/lovelace/cards/hui-picture-glance-card.ts +++ b/src/panels/lovelace/cards/hui-picture-glance-card.ts @@ -16,6 +16,7 @@ import { computeStateDisplay } from "../../../common/entity/compute_state_displa import { computeStateName } from "../../../common/entity/compute_state_name"; import { stateIcon } from "../../../common/entity/state_icon"; import "../../../components/ha-card"; +import "../../../components/ha-icon"; import "../../../components/ha-icon-button"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; @@ -252,13 +253,14 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard { class=${classMap({ "state-on": !STATES_OFF.has(stateObj.state), })} - .icon=${entityConf.icon || stateIcon(stateObj)} - title=${`${computeStateName(stateObj)} : ${computeStateDisplay( + .label=${`${computeStateName(stateObj)} : ${computeStateDisplay( this.hass!.localize, stateObj, this.hass!.locale )}`} - > + > + + ${this._config!.show_state !== true && entityConf.show_state !== true ? html`
` : html` diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index d2869a5a4b..dd1b8ae477 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -19,6 +19,7 @@ import { computeStateName } from "../../../common/entity/compute_state_name"; import { formatNumber } from "../../../common/number/format_number"; import "../../../components/ha-card"; import type { HaCard } from "../../../components/ha-card"; +import "../../../components/ha-icon"; import "../../../components/ha-icon-button"; import { ClimateEntity, @@ -233,14 +234,15 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { [mode]: true, })} > - - - + >
@@ -414,10 +416,11 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { + > + + `; } diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 63290da1de..aef797e278 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@material/mwc-icon-button"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiArrowDown, mdiArrowUp, mdiDotsVertical } from "@mdi/js"; @@ -14,6 +13,7 @@ import { import { customElement, property, queryAssignedNodes } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-button-menu"; +import "../../../components/ha-icon-button"; import { saveConfig } from "../../../data/lovelace"; import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../../../types"; @@ -60,36 +60,34 @@ export class HuiCardOptions extends LitElement { >
- - - - + + > - - - - + .path=${mdiDotsVertical} + > ${this.hass!.localize( "ui.panel.lovelace.editor.edit_card.move" @@ -137,11 +135,11 @@ export class HuiCardOptions extends LitElement { align-items: center; } - mwc-icon-button { + ha-icon-button { color: var(--primary-text-color); } - mwc-icon-button.move-arrow[disabled] { + ha-icon-button.move-arrow[disabled] { color: var(--disabled-text-color); } diff --git a/src/panels/lovelace/components/hui-energy-period-selector.ts b/src/panels/lovelace/components/hui-energy-period-selector.ts index 95bdb8a060..0ac5bab267 100644 --- a/src/panels/lovelace/components/hui-energy-period-selector.ts +++ b/src/panels/lovelace/components/hui-energy-period-selector.ts @@ -1,21 +1,22 @@ +import "@material/mwc-button/mwc-button"; import { mdiChevronLeft, mdiChevronRight } from "@mdi/js"; import { - endOfToday, addDays, - endOfDay, - startOfToday, - endOfWeek, - endOfMonth, - startOfDay, - startOfWeek, - startOfMonth, addMonths, addWeeks, - startOfYear, addYears, + differenceInDays, + endOfDay, + endOfMonth, + endOfToday, + endOfWeek, endOfYear, isWithinInterval, - differenceInDays, + startOfDay, + startOfMonth, + startOfToday, + startOfWeek, + startOfYear, } from "date-fns"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; @@ -26,14 +27,12 @@ import { formatDateShort, formatDateYear, } from "../../../common/datetime/format_date"; +import { toggleAttribute } from "../../../common/dom/toggle_attribute"; +import "../../../components/ha-button-toggle-group"; +import "../../../components/ha-icon-button"; import { EnergyData, getEnergyDataCollection } from "../../../data/energy"; import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import { HomeAssistant, ToggleButton } from "../../../types"; -import "@material/mwc-icon-button/mwc-icon-button"; -import "../../../components/ha-svg-icon"; -import "@material/mwc-button/mwc-button"; -import "../../../components/ha-button-toggle-group"; -import { toggleAttribute } from "../../../common/dom/toggle_attribute"; @customElement("hui-energy-period-selector") export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { @@ -108,22 +107,20 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { this._endDate || new Date(), this.hass.locale )}`} - - - - + - - + .path=${mdiChevronRight} + > ${this.hass.localize( "ui.panel.lovelace.components.energy_period_selector.today" @@ -264,7 +261,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { --mdc-button-disabled-ink-color: var(--disabled-text-color); --mdc-icon-button-ripple-opacity: 0.2; } - mwc-icon-button { + ha-icon-button { --mdc-icon-button-size: 28px; } ha-button-toggle-group { diff --git a/src/panels/lovelace/components/hui-input-list-editor.ts b/src/panels/lovelace/components/hui-input-list-editor.ts index 5cead88e75..fe53e72c11 100644 --- a/src/panels/lovelace/components/hui-input-list-editor.ts +++ b/src/panels/lovelace/components/hui-input-list-editor.ts @@ -1,3 +1,4 @@ +import { mdiClose } from "@mdi/js"; import "@polymer/paper-input/paper-input"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; @@ -33,9 +34,10 @@ export class HuiInputListEditor extends LitElement { >Clear diff --git a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts index 882cc7266b..a3c9f8ec85 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts @@ -98,6 +98,7 @@ export class HuiCardPicker extends LitElement { return html` - - - + ` : ""} diff --git a/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts b/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts index 3a5791e8e3..b08cdbc539 100644 --- a/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts +++ b/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts @@ -28,6 +28,7 @@ export class HuiEntityPickerTable extends LitElement { protected render(): TemplateResult { return html` - - - + > - - - + > - - - + >
${!this.config?.type ? html` - - - + > ` : html` - - - - + - - + > `}
`; @@ -118,7 +114,7 @@ export class HuiHeaderFooterEditor extends LitElement { align-items: center; } - mwc-icon-button, + ha-icon-button, .header-footer-icon { --mdc-icon-button-size: 36px; color: var(--secondary-text-color); diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index fe2e6fad39..961f20cd8e 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiHelpCircle } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -8,7 +7,7 @@ import { computeRTLDirection } from "../../../common/util/compute_rtl"; import "../../../components/ha-circular-progress"; import "../../../components/ha-dialog"; import "../../../components/ha-formfield"; -import "../../../components/ha-svg-icon"; +import "../../../components/ha-icon-button"; import "../../../components/ha-switch"; import "../../../components/ha-yaml-editor"; import type { LovelaceConfig } from "../../../data/lovelace"; @@ -67,9 +66,10 @@ export class HuiSaveConfig extends LitElement implements HassDialog { rel="noreferrer" dir=${computeRTLDirection(this.hass!)} > - - - + `} >
diff --git a/src/panels/lovelace/editor/hui-entities-card-row-editor.ts b/src/panels/lovelace/editor/hui-entities-card-row-editor.ts index 9095c6b1b1..5ea6589448 100644 --- a/src/panels/lovelace/editor/hui-entities-card-row-editor.ts +++ b/src/panels/lovelace/editor/hui-entities-card-row-editor.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import { mdiClose, mdiDrag, mdiPencil } from "@mdi/js"; import { css, @@ -18,6 +17,7 @@ import Sortable, { import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/entity/ha-entity-picker"; import type { HaEntityPicker } from "../../../components/entity/ha-entity-picker"; +import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import { sortableStyles } from "../../../resources/ha-sortable-style"; import { HomeAssistant } from "../../../types"; @@ -104,26 +104,24 @@ export class HuiEntitiesCardRowEditor extends LitElement { @value-changed=${this._valueChanged} > `} - - - - + - - + >
` ) diff --git a/src/panels/lovelace/editor/hui-sub-element-editor.ts b/src/panels/lovelace/editor/hui-sub-element-editor.ts index e243aee060..eeae816645 100644 --- a/src/panels/lovelace/editor/hui-sub-element-editor.ts +++ b/src/panels/lovelace/editor/hui-sub-element-editor.ts @@ -1,10 +1,9 @@ import "@material/mwc-button"; -import "@material/mwc-icon-button"; import { mdiArrowLeft } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state, query } from "lit/decorators"; import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; -import "../../../components/ha-svg-icon"; +import "../../../components/ha-icon-button"; import type { HomeAssistant } from "../../../types"; import type { LovelaceRowConfig } from "../entity-rows/types"; import type { LovelaceHeaderFooterConfig } from "../header-footer/types"; @@ -37,9 +36,11 @@ export class HuiSubElementEditor extends LitElement { return html`
- - - + ${this.hass.localize( `ui.panel.lovelace.editor.sub-element-editor.types.${this.config?.type}` diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index 4f11a0232b..1b99c687e0 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -1,3 +1,16 @@ +import { + mdiPause, + mdiPlay, + mdiPlayPause, + mdiPower, + mdiSkipNext, + mdiSkipPrevious, + mdiStop, + mdiVolumeHigh, + mdiVolumeMinus, + mdiVolumeOff, + mdiVolumePlus, +} from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { css, @@ -102,7 +115,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK) ? html` ` @@ -117,7 +130,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { supportsFeature(stateObj, SUPPORT_PAUSE))) ? html` ` @@ -126,7 +139,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { supportsFeature(stateObj, SUPPORT_NEXT_TRACK) ? html` ` @@ -148,7 +161,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { !UNAVAILABLE_STATES.includes(entityState) ? html` ` @@ -161,7 +174,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { !UNAVAILABLE_STATES.includes(entityState) ? html` ` @@ -177,9 +190,9 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { ${supportsFeature(stateObj, SUPPORT_VOLUME_MUTE) ? html` ` @@ -200,11 +213,11 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS) ? html` ` @@ -238,12 +251,12 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { private _computeControlIcon(stateObj: HassEntity): string { return stateObj.state === "on" - ? "hass:play-pause" + ? mdiPlayPause : stateObj.state !== "playing" - ? "hass:play" + ? mdiPlay : supportsFeature(stateObj, SUPPORT_PAUSE) - ? "hass:pause" - : "hass:stop"; + ? mdiPause + : mdiStop; } private _togglePower(): void { diff --git a/src/panels/lovelace/hui-editor.ts b/src/panels/lovelace/hui-editor.ts index c2c04b095d..235b32f176 100644 --- a/src/panels/lovelace/hui-editor.ts +++ b/src/panels/lovelace/hui-editor.ts @@ -1,5 +1,6 @@ import { undoDepth } from "@codemirror/history"; import "@material/mwc-button"; +import { mdiClose } from "@mdi/js"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; import { dump, load } from "js-yaml"; @@ -55,8 +56,9 @@ class LovelaceFullConfigEditor extends LitElement {
${this.hass!.localize( diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 5ab8afac4e..833938d199 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -47,6 +47,7 @@ import { debounce } from "../../common/util/debounce"; import { afterNextRender } from "../../common/util/render-status"; import "../../components/ha-button-menu"; import "../../components/ha-icon"; +import "../../components/ha-icon-button"; import "../../components/ha-icon-button-arrow-next"; import "../../components/ha-icon-button-arrow-prev"; import "../../components/ha-menu-button"; @@ -118,30 +119,24 @@ class HUIRoot extends LitElement { ${this._editMode ? html` - - - + >
${this.config.title || this.hass!.localize("ui.panel.lovelace.editor.header")} - - - + >
- - - + .path=${mdiHelpCircle} + > - - - + .path=${mdiDotsVertical} + > ${__DEMO__ /* No unused entities available in the demo */ ? "" : html` @@ -278,28 +268,23 @@ class HUIRoot extends LitElement { ${!this.narrow && this._conversation(this.hass.config.components) ? html` - - - + > ` : ""} - - - + .path=${mdiDotsVertical} + > ${this.narrow && this._conversation(this.hass.config.components) ? html` @@ -448,9 +433,6 @@ class HUIRoot extends LitElement { ? html` - - + .path=${mdiPlus} + > ` : ""} diff --git a/src/panels/lovelace/views/hui-sidebar-view.ts b/src/panels/lovelace/views/hui-sidebar-view.ts index f62acd7d7d..165bd8a159 100644 --- a/src/panels/lovelace/views/hui-sidebar-view.ts +++ b/src/panels/lovelace/views/hui-sidebar-view.ts @@ -156,7 +156,7 @@ export class SideBarView extends LitElement implements LovelaceViewElement { element.lovelace = this.lovelace; element.path = [this.index!, idx]; card.editMode = true; - const movePositionButton = document.createElement("mwc-icon-button"); + const movePositionButton = document.createElement("ha-icon-button"); movePositionButton.slot = "buttons"; const moveIcon = document.createElement("ha-svg-icon"); moveIcon.path = diff --git a/src/panels/mailbox/ha-dialog-show-audio-message.js b/src/panels/mailbox/ha-dialog-show-audio-message.js index 3314d8784f..3b999d8f49 100644 --- a/src/panels/mailbox/ha-dialog-show-audio-message.js +++ b/src/panels/mailbox/ha-dialog-show-audio-message.js @@ -4,6 +4,8 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; import "../../components/dialog/ha-paper-dialog"; import "../../components/ha-circular-progress"; +import "../../components/ha-icon"; +import "../../components/ha-icon-button"; import LocalizeMixin from "../../mixins/localize-mixin"; import "../../styles/polymer-ha-style-dialog"; @@ -56,11 +58,9 @@ class HaDialogShowAudioMessage extends LocalizeMixin(PolymerElement) { - + + +
diff --git a/src/panels/map/ha-panel-map.ts b/src/panels/map/ha-panel-map.ts index d391668c9d..89b9351473 100644 --- a/src/panels/map/ha-panel-map.ts +++ b/src/panels/map/ha-panel-map.ts @@ -1,16 +1,15 @@ import { mdiPencil } from "@mdi/js"; -import "@material/mwc-icon-button"; import "@polymer/app-layout/app-toolbar/app-toolbar"; import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; import { property } from "lit/decorators"; import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { navigate } from "../../common/navigate"; -import "../../components/ha-svg-icon"; import "../../components/ha-menu-button"; -import "../../layouts/ha-app-layout"; -import { HomeAssistant } from "../../types"; +import "../../components/ha-icon-button"; import "../../components/map/ha-map"; +import "../../layouts/ha-app-layout"; import { haStyle } from "../../resources/styles"; +import { HomeAssistant } from "../../types"; class HaPanelMap extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -30,9 +29,11 @@ class HaPanelMap extends LitElement { >
${this.hass.localize("panel.map")}
${!__DEMO__ && this.hass.user?.is_admin - ? html`` + ? html` ` : ""}
diff --git a/src/panels/media-browser/ha-panel-media-browser.ts b/src/panels/media-browser/ha-panel-media-browser.ts index ebf1bfe90c..5b1cc9b0dc 100644 --- a/src/panels/media-browser/ha-panel-media-browser.ts +++ b/src/panels/media-browser/ha-panel-media-browser.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; diff --git a/src/panels/profile/ha-long-lived-access-tokens-card.ts b/src/panels/profile/ha-long-lived-access-tokens-card.ts index dd331c6949..3fe4755b23 100644 --- a/src/panels/profile/ha-long-lived-access-tokens-card.ts +++ b/src/panels/profile/ha-long-lived-access-tokens-card.ts @@ -1,5 +1,4 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiDelete } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; @@ -8,7 +7,7 @@ import { relativeTime } from "../../common/datetime/relative_time"; import { fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-card"; import "../../components/ha-settings-row"; -import "../../components/ha-svg-icon"; +import "../../components/ha-icon-button"; import { RefreshToken } from "../../data/refresh_token"; import { showAlertDialog, @@ -72,14 +71,13 @@ class HaLongLivedTokens extends LitElement { relativeTime(new Date(token.created_at), this.hass.locale) )}
- - - + > ` )}
@@ -171,7 +169,7 @@ class HaLongLivedTokens extends LitElement { mwc-button { --mdc-theme-primary: var(--primary-color); } - mwc-icon-button { + ha-icon-button { color: var(--primary-text-color); } `, diff --git a/src/panels/profile/ha-refresh-tokens-card.ts b/src/panels/profile/ha-refresh-tokens-card.ts index 12f801978e..12f08d2bf0 100644 --- a/src/panels/profile/ha-refresh-tokens-card.ts +++ b/src/panels/profile/ha-refresh-tokens-card.ts @@ -1,4 +1,3 @@ -import "@material/mwc-icon-button/mwc-icon-button"; import { mdiDelete } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; @@ -8,7 +7,7 @@ import { relativeTime } from "../../common/datetime/relative_time"; import { fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-card"; import "../../components/ha-settings-row"; -import "../../components/ha-svg-icon"; +import "../../components/ha-icon-button"; import { RefreshToken } from "../../data/refresh_token"; import { showAlertDialog, @@ -93,14 +92,13 @@ class HaRefreshTokens extends LitElement { )} ` : ""} - - - + >
` ) @@ -144,7 +142,7 @@ class HaRefreshTokens extends LitElement { ha-settings-row { padding: 0; } - mwc-icon-button { + ha-icon-button { color: var(--primary-text-color); } `, diff --git a/src/panels/shopping-list/ha-panel-shopping-list.ts b/src/panels/shopping-list/ha-panel-shopping-list.ts index f46d52dcd2..a852182225 100644 --- a/src/panels/shopping-list/ha-panel-shopping-list.ts +++ b/src/panels/shopping-list/ha-panel-shopping-list.ts @@ -12,6 +12,7 @@ import { import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; +import "../../components/ha-icon-button"; import "../../components/ha-menu-button"; import { showVoiceCommandDialog } from "../../dialogs/voice-command-dialog/show-ha-voice-command-dialog"; import "../../layouts/ha-app-layout"; @@ -60,14 +61,13 @@ class PanelShoppingList extends LitElement {
${this.hass.localize("panel.shopping_list")}
${this._conversation(this.hass.config.components) ? html` - - - + > ` : ""} diff --git a/src/translations/en.json b/src/translations/en.json index 65c982211e..7b0af74478 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -282,6 +282,7 @@ "enable": "Enable", "disable": "Disable", "close": "Close", + "clear": "Clear", "leave": "Leave", "stay": "Stay", "next": "Next", @@ -294,7 +295,7 @@ "not_now": "Not now", "skip": "Skip", "menu": "Menu", - "overflow_menu": "Overflow menu", + "help": "Help", "successfully_saved": "Successfully saved", "successfully_deleted": "Successfully deleted", "error_required": "Required", @@ -341,6 +342,7 @@ "entity": { "entity-picker": { "entity": "Entity", + "edit": "Edit", "clear": "Clear", "no_match": "No matching entities found", "show_entities": "Show entities" @@ -351,8 +353,10 @@ } }, "target-picker": { + "expand": "Expand", "expand_area_id": "Expand this area into the separate devices and entities that it contains. After expanding, it will not update the devices and entities when the area changes.", "expand_device_id": "Expand this device into the separate entities that it contains. After expanding, it will not update the entities when the device changes.", + "remove": "Remove", "remove_area_id": "Remove area", "remove_device_id": "Remove device", "remove_entity_id": "Remove entity", @@ -895,7 +899,9 @@ "sidebar": { "external_app_configuration": "App Configuration", "sidebar_toggle": "Sidebar Toggle", - "done": "Done" + "done": "Done", + "hide_panel": "Hide panel", + "show_panel": "Show panel" }, "panel": { "my": { @@ -922,6 +928,7 @@ "areas": { "caption": "Areas", "description": "Group devices and entities into areas", + "edit_settings": "Area settings", "data_table": { "area": "Area", "devices": "Devices", @@ -1209,6 +1216,7 @@ }, "info": { "caption": "Info", + "copy_menu": "Copy menu", "copy_raw": "Raw Text", "copy_github": "For GitHub", "description": "Version, system health and links to documentation", @@ -1243,6 +1251,7 @@ "no_issues": "There are no new issues!", "clear": "Clear", "refresh": "Refresh", + "copy": "Copy log entry", "multiple_messages": "message first occurred at {time} and shows up {counter} times", "level": { "critical": "CRITICAL", @@ -1771,6 +1780,13 @@ "ambiguous_entities": "One or more devices have more than one matching entity, please pick the one you want to use.", "unknown_placeholder": "Unknown placeholder" } + }, + "trace": { + "refresh": "[%key:ui::common::refresh%]", + "download_trace": "Download trace", + "edit_automation": "Edit automation", + "older_trace": "Older trace", + "newer_trace": "Newer trace" } }, "blueprint": { @@ -2101,6 +2117,7 @@ "caption": "Devices", "description": "Manage configured devices", "device_info": "Device info", + "edit_settings": "Edit settings", "unnamed_device": "Unnamed device", "unknown_error": "Unknown error", "name": "Name", @@ -2276,6 +2293,7 @@ "no_zones_created_yet": "Looks like you have not created any zones yet.", "create_zone": "Create Zone", "add_zone": "Add Zone", + "edit_zone": "Edit Zone", "confirm_delete": "Are you sure you want to delete this zone?", "configured_in_yaml": "Zones configured via configuration.yaml cannot be edited via the UI.", "edit_home_zone": "The radius of the Home zone can't be edited from the frontend yet. Drag the marker on the map to move the home zone.", @@ -2656,7 +2674,8 @@ "group_name_placeholder": "Group Name", "create_group": "Zigbee Home Automation - Create Group", "create": "Create Group", - "creating_group": "Creating Group" + "creating_group": "Creating Group", + "delete": "Delete Group" }, "visualization": { "header": "Network Visualization", @@ -2925,6 +2944,7 @@ "lovelace": { "cards": { "confirm_delete": "Are you sure you want to delete this card?", + "show_more_info": "Show more information", "actions": { "action_confirmation": "Are you sure you want to run action ''{action}''?", "no_entity_more_info": "No entity provided for more info dialog", @@ -2964,6 +2984,9 @@ "starting": { "description": "Home Assistant is starting, please wait…" }, + "map": { + "reset_focus": "Reset focus" + }, "energy": { "loading": "Loading...", "no_data": "There is no data to show. It can take up to 2 hours for new data to arrive after you configure your energy dashboard.", @@ -3131,6 +3154,8 @@ "delete": "Delete card", "duplicate": "Duplicate card", "move": "Move to view", + "move_up": "Move card up", + "move_down": "Move card down", "move_before": "Move card before", "move_after": "Move card after", "options": "More options", @@ -3471,6 +3496,9 @@ "delete_prompt": "Delete this message?", "delete_button": "Delete" }, + "map": { + "edit_zones": "Edit Zones" + }, "profile": { "current_user": "You are currently logged in as {fullName}.", "is_owner": "You are an owner.", @@ -4119,6 +4147,7 @@ "running_version": "You are currently running version {version}", "save": "[%key:ui::common::save%]", "close": "[%key:ui::common::close%]", + "menu": "[%key:ui::common::menu%]", "show_more": "Show more information about this", "update_available": "{count, plural,\n one {Update}\n other {{count} updates}\n} pending", "update": "Update", From 7fc00ce1cbc45aebd2df0f52ceb5da7c55bb1787 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Thu, 14 Oct 2021 17:00:31 +0200 Subject: [PATCH 029/115] Fix sizing / positioning error for trace graph node with subsequent branches (#10049) --- src/components/trace/hat-graph-node.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/trace/hat-graph-node.ts b/src/components/trace/hat-graph-node.ts index 5b623eb61e..203419657b 100644 --- a/src/components/trace/hat-graph-node.ts +++ b/src/components/trace/hat-graph-node.ts @@ -40,6 +40,8 @@ export class HatGraphNode extends LitElement { const width = SPACING + NODE_SIZE; return html` Date: Thu, 14 Oct 2021 09:56:51 -0700 Subject: [PATCH 030/115] Initial support for entity category (#10266) --- gallery/src/demos/demo-integration-card.ts | 1 + src/data/entity_registry.ts | 1 + .../device-detail/ha-device-entities-card.ts | 8 ++-- .../config/devices/ha-config-device-page.ts | 37 ++++++++++++++++--- .../config/entities/ha-config-entities.ts | 1 + .../common/generate-lovelace-config.ts | 5 ++- src/translations/en.json | 3 ++ 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index 0b08a0aa3e..ecfcd9671c 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -187,6 +187,7 @@ const createEntityRegistryEntries = ( device_id: "mock-device-id", area_id: null, disabled_by: null, + entity_category: null, entity_id: "binary_sensor.updater", name: null, icon: null, diff --git a/src/data/entity_registry.ts b/src/data/entity_registry.ts index 28f389922e..7072c44227 100644 --- a/src/data/entity_registry.ts +++ b/src/data/entity_registry.ts @@ -13,6 +13,7 @@ export interface EntityRegistryEntry { device_id: string | null; area_id: string | null; disabled_by: string | null; + entity_category: "config" | "diagnostic" | null; } export interface ExtEntityRegistryEntry extends EntityRegistryEntry { diff --git a/src/panels/config/devices/device-detail/ha-device-entities-card.ts b/src/panels/config/devices/device-detail/ha-device-entities-card.ts index 5bb169256b..1cd5ee4051 100644 --- a/src/panels/config/devices/device-detail/ha-device-entities-card.ts +++ b/src/panels/config/devices/device-detail/ha-device-entities-card.ts @@ -25,6 +25,8 @@ import { EntityRegistryStateEntry } from "../ha-config-device-page"; @customElement("ha-device-entities-card") export class HaDeviceEntitiesCard extends LitElement { + @property() public header!: string; + @property({ attribute: false }) public hass!: HomeAssistant; @property() public entities!: EntityRegistryStateEntry[]; @@ -47,11 +49,7 @@ export class HaDeviceEntitiesCard extends LitElement { const disabledEntities: EntityRegistryStateEntry[] = []; this._entityRows = []; return html` - + ${this.entities.length ? html`
diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index b130d34e91..ebca2ef39e 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -8,6 +8,7 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { stringCompare } from "../../../common/string/compare"; +import { groupBy } from "../../../common/util/group-by"; import { slugify } from "../../../common/string/slugify"; import "../../../components/entity/ha-battery-icon"; import "../../../components/ha-icon-button"; @@ -112,6 +113,25 @@ export class HaConfigDevicePage extends LitElement { ) ); + private _entitiesByCategory = memoizeOne( + (entities: EntityRegistryEntry[]) => { + const result = groupBy( + entities, + (entry) => entry.entity_category || "state" + ) as Record< + "state" | NonNullable, + EntityRegistryStateEntry[] + >; + for (const key of ["state", "diagnostic", "config"]) { + if (!(key in result)) { + result[key] = []; + } + } + + return result; + } + ); + private _computeArea = memoizeOne( (areas, device): AreaRegistryEntry | undefined => { if (!areas || !device || !device.area_id) { @@ -159,6 +179,7 @@ export class HaConfigDevicePage extends LitElement { const integrations = this._integrations(device, this.entries); const entities = this._entities(this.deviceId, this.entities); + const entitiesByCategory = this._entitiesByCategory(entities); const batteryEntity = this._batteryEntity(entities); const batteryChargingEntity = this._batteryChargingEntity(entities); const batteryState = batteryEntity @@ -298,18 +319,22 @@ export class HaConfigDevicePage extends LitElement { ${this._renderIntegrationInfo(device, integrations)} - ${ - entities.length - ? html` + ${["state", "config", "diagnostic"].map((category) => + !entitiesByCategory[category].length + ? "" + : html` ` - : html`` - } + )} +
${ diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index 7dfe441b87..4b22362764 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -679,6 +679,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { icon: null, readonly: true, selectable: false, + entity_category: null, }); } if (changed) { diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index 7ed2709528..5edc9e313e 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -189,6 +189,7 @@ const adjustName = (name: string): string => hasUpperCase(name.substr(0, name.indexOf(" "))) ? name : name[0].toUpperCase() + name.slice(1); + const computeDefaultViewStates = ( entities: HassEntities, entityEntries: EntityRegistryEntry[] @@ -196,7 +197,9 @@ const computeDefaultViewStates = ( const states = {}; const hiddenEntities = new Set( entityEntries - .filter((entry) => HIDE_PLATFORM.has(entry.platform)) + .filter( + (entry) => entry.entity_category || HIDE_PLATFORM.has(entry.platform) + ) .map((entry) => entry.entity_id) ); diff --git a/src/translations/en.json b/src/translations/en.json index 7b0af74478..fddb6988d7 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2170,6 +2170,9 @@ "device_not_found": "Device not found.", "entities": { "entities": "Entities", + "state": "State", + "diagnostic": "Diagnostic", + "config": "Config", "add_entities_lovelace": "Add to Lovelace", "none": "This device has no entities", "hide_disabled": "Hide disabled", From 33e1d34cb1453b935b1c73ce1404173a45ac1d36 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 14 Oct 2021 11:17:44 -0700 Subject: [PATCH 031/115] Add support for device configuration URL (#10251) * Add support for device configuration URL * Lint * Tweak text --- gallery/src/demos/demo-integration-card.ts | 1 + src/data/device_registry.ts | 1 + .../config/devices/ha-config-device-page.ts | 32 ++++++++++++++++++- src/translations/en.json | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts index ecfcd9671c..4da42f1279 100644 --- a/gallery/src/demos/demo-integration-card.ts +++ b/gallery/src/demos/demo-integration-card.ts @@ -212,6 +212,7 @@ const createDeviceRegistryEntries = ( area_id: null, name_by_user: null, disabled_by: null, + configuration_url: null, }, ]; diff --git a/src/data/device_registry.ts b/src/data/device_registry.ts index 8e074b5e2c..5c039437e4 100644 --- a/src/data/device_registry.ts +++ b/src/data/device_registry.ts @@ -18,6 +18,7 @@ export interface DeviceRegistryEntry { name_by_user: string | null; entry_type: "service" | null; disabled_by: string | null; + configuration_url: string | null; } export interface DeviceEntityLookup { diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index ebca2ef39e..39c9ab79e9 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -1,4 +1,4 @@ -import { mdiPencil, mdiPlusCircle } from "@mdi/js"; +import { mdiPencil, mdiPlusCircle, mdiOpenInNew } from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -13,6 +13,7 @@ import { slugify } from "../../../common/string/slugify"; import "../../../components/entity/ha-battery-icon"; import "../../../components/ha-icon-button"; import "../../../components/ha-icon-next"; +import "../../../components/ha-svg-icon"; import { AreaRegistryEntry } from "../../../data/area_registry"; import { ConfigEntry, @@ -316,6 +317,31 @@ export class HaConfigDevicePage extends LitElement { ` : html`` } + ${ + device.configuration_url + ? html` + + ` + : "" + } ${this._renderIntegrationInfo(device, integrations)} @@ -944,6 +970,10 @@ export class HaConfigDevicePage extends LitElement { ha-card a { color: var(--primary-text-color); } + + ha-svg-icon[slot="trailingIcon"] { + display: block; + } `, ]; } diff --git a/src/translations/en.json b/src/translations/en.json index fddb6988d7..a31e5636ab 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2131,6 +2131,8 @@ "config_entry": "Config entry" }, "enabled_description": "Disabled devices will not be shown and entities belonging to the device will be disabled and not added to Home Assistant.", + "open_configuration_url_device": "Visit device", + "open_configuration_url_service": "Visit service", "automation": { "automations": "Automations", "no_automations": "No automations", From 6e8e9824f93668f37f6fcafea609f93bdf9aeaff Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 14 Oct 2021 20:18:32 +0200 Subject: [PATCH 032/115] Bump mdc/mwc to 0.25.2 (#10271) --- package.json | 42 +- yarn.lock | 1282 +++++++++++++++++++++++++------------------------- 2 files changed, 653 insertions(+), 671 deletions(-) diff --git a/package.json b/package.json index fcd9afa372..09f72733ae 100644 --- a/package.json +++ b/package.json @@ -46,27 +46,27 @@ "@fullcalendar/interaction": "5.9.0", "@fullcalendar/list": "5.9.0", "@lit-labs/virtualizer": "patch:@lit-labs/virtualizer@0.6.0#./.yarn/patches/@lit-labs/virtualizer/0.7.0.patch", - "@material/chips": "13.0.0-canary.65125b3a6.0", - "@material/data-table": "13.0.0-canary.65125b3a6.0", - "@material/mwc-button": "0.25.1", - "@material/mwc-checkbox": "0.25.1", - "@material/mwc-circular-progress": "0.25.1", - "@material/mwc-dialog": "0.25.1", - "@material/mwc-fab": "0.25.1", - "@material/mwc-formfield": "0.25.1", - "@material/mwc-icon-button": "0.25.1", - "@material/mwc-linear-progress": "0.25.1", - "@material/mwc-list": "0.25.1", - "@material/mwc-menu": "0.25.1", - "@material/mwc-radio": "0.25.1", - "@material/mwc-ripple": "0.25.1", - "@material/mwc-select": "^0.25.1", - "@material/mwc-slider": "^0.25.1", - "@material/mwc-switch": "0.25.1", - "@material/mwc-tab": "0.25.1", - "@material/mwc-tab-bar": "0.25.1", - "@material/mwc-textfield": "^0.25.1", - "@material/top-app-bar": "13.0.0-canary.65125b3a6.0", + "@material/chips": "14.0.0-canary.353ca7e9f.0", + "@material/data-table": "14.0.0-canary.353ca7e9f.0", + "@material/mwc-button": "0.25.2", + "@material/mwc-checkbox": "0.25.2", + "@material/mwc-circular-progress": "0.25.2", + "@material/mwc-dialog": "0.25.2", + "@material/mwc-fab": "0.25.2", + "@material/mwc-formfield": "0.25.2", + "@material/mwc-icon-button": "0.25.2", + "@material/mwc-linear-progress": "0.25.2", + "@material/mwc-list": "0.25.2", + "@material/mwc-menu": "0.25.2", + "@material/mwc-radio": "0.25.2", + "@material/mwc-ripple": "0.25.2", + "@material/mwc-select": "0.25.2", + "@material/mwc-slider": "0.25.2", + "@material/mwc-switch": "0.25.2", + "@material/mwc-tab": "0.25.2", + "@material/mwc-tab-bar": "0.25.2", + "@material/mwc-textfield": "0.25.2", + "@material/top-app-bar": "14.0.0-canary.353ca7e9f.0", "@mdi/js": "6.2.95", "@mdi/svg": "6.2.95", "@polymer/app-layout": "^3.1.0", diff --git a/yarn.lock b/yarn.lock index 597e15e935..4ec7ec8975 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1965,954 +1965,936 @@ __metadata: languageName: node linkType: hard -"@material/animation@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/animation@npm:13.0.0-canary.65125b3a6.0" +"@material/animation@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/animation@npm:14.0.0-canary.353ca7e9f.0" dependencies: tslib: ^2.1.0 - checksum: ea7f87727ec49bea2481652205fb160f74f0b8d780d788a60319cac0fdd543937c2a74484a98e944c650d6edf7f5d8804bbab2ab3033c73a83c4d5a9dbf1cafd + checksum: 3aa1377945b71872cf2953bd1718652e4576fa3e06b91eff251e71298e8ae03f9c10130db06d641ba5e988f26112556c38ca97d8ea4f09aa268beb10c3d5a297 languageName: node linkType: hard -"@material/base@npm:13.0.0-canary.65125b3a6.0, @material/base@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/base@npm:13.0.0-canary.65125b3a6.0" +"@material/base@npm:14.0.0-canary.353ca7e9f.0, @material/base@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/base@npm:14.0.0-canary.353ca7e9f.0" dependencies: tslib: ^2.1.0 - checksum: 875f2c6ec85a9e34c741bae6806a375e68d74c271ede4e664d5e7ea4847cbd35e0a9cb244296cfc474f87904bd6af21e4ef2d8e4d67fd5f116d8fc4c651808d0 + checksum: df65c8152859aa260df73a46c83a3b215eb4861ded12eb30f30ce45370e6595bc99d3cce3be82574e59ef5734f1a737b05743b5a5ec7f6c1eaba027222e0a55f languageName: node linkType: hard -"@material/button@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/button@npm:13.0.0-canary.65125b3a6.0" +"@material/button@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/button@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/tokens": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/tokens": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 84e6e3a4eaf0eb0a8615ff4a5d30a20dfb9be2adbaf86badb3712f6a6a6bc948c771e46b6a3bd617625ad338e813b3b47408e567577c24c523f4f3800c09893d + checksum: 500c798faab9bfd04593e5bb81c1eb35de1bd9253759ded43ffcbaa608eb952946aada6086767417398d8ddb07fc355b235d953be414322fb7f858f4863e249a languageName: node linkType: hard -"@material/checkbox@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/checkbox@npm:13.0.0-canary.65125b3a6.0" +"@material/checkbox@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/checkbox@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: d8b345663037a4d5e046d7468493678026dd22c3ed133ec91c9f1ace030380fb5de70e7b3fb0b77d4dbbe3fe2e1dcf74cbb8e033dcdbf5afbe7d088600129259 + checksum: df3ff5b5695bf7f02eb45bbf4251894f3f6c9bda52bcd97b9172a80990db845bbe50af8364d61954603acf9c6bcabae350f4246da66826f2ebb695ebdc3a948f languageName: node linkType: hard -"@material/chips@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/chips@npm:13.0.0-canary.65125b3a6.0" +"@material/chips@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/chips@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/checkbox": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/tokens": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/checkbox": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/tokens": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: e1e6137452d142328580cffcc21a96a7622dbd52a2dc2dacefd852c83dd7fbe014c21b79fb47c9a569f53a5617cccc9473f88f8917053812e59c9c04164cfa50 + checksum: 11341b0350ef9e2fd8e9db89a2bba70cda43fa6d0efa713ecd7f701edabf0ca80958d7bcd4a9670c4fb6a807141059799cbb0524078bb0c6460ad0c732336053 languageName: node linkType: hard -"@material/circular-progress@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/circular-progress@npm:13.0.0-canary.65125b3a6.0" +"@material/circular-progress@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/circular-progress@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/progress-indicator": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/progress-indicator": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 09150563340bf258a28699969e9d1690f6b669e2c3b1bbc58ee0fefc11aa90414eeb00e2ca8c7d7ffc78a51751532599f65f31bbf9c50e7863d16f60bd61d91c + checksum: 3376d6056acfc00cc5d6c165b0a17c69b90420bb5405223d5781b64987e5504018c529a4c45fa256de08f3c47589543315368c57a3b4d444af2a29f8833d6f58 languageName: node linkType: hard -"@material/data-table@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/data-table@npm:13.0.0-canary.65125b3a6.0" +"@material/data-table@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/data-table@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/checkbox": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/icon-button": 13.0.0-canary.65125b3a6.0 - "@material/linear-progress": 13.0.0-canary.65125b3a6.0 - "@material/list": 13.0.0-canary.65125b3a6.0 - "@material/menu": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/select": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/checkbox": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/icon-button": 14.0.0-canary.353ca7e9f.0 + "@material/linear-progress": 14.0.0-canary.353ca7e9f.0 + "@material/list": 14.0.0-canary.353ca7e9f.0 + "@material/menu": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/select": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: e705de99d0c0789ed785c691429409e679dbfcd9584ba10eb1b8332e913ceee5a002d0cf1dce8862badbb9b1e89c712b5970748ae0126f2b2dd1a63e6df5cd8d + checksum: 53222f03d0d020fb33f23f3694d78258109432ea478cc9314af801742383f3a67c7f31bd5a620e2897365e1f4e638de3abdd4fbf3bc03777292666eebff43967 languageName: node linkType: hard -"@material/density@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/density@npm:13.0.0-canary.65125b3a6.0" +"@material/density@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/density@npm:14.0.0-canary.353ca7e9f.0" dependencies: tslib: ^2.1.0 - checksum: 570bd2e54d22fc80c21277b92c92503b1a8d081ad2c339f786a3392d3e8059e062a96c0ba466d8dad5ae73dece846366c3e4711cb164fcd30bde6d56afcbfc4c + checksum: e78f70891c2b552e2153a23adbe0de78e79a1cd74b16d3bdc2507e8112befca3a0a5ecc4ba8ae29cecf8541dcbff8c62cb0c48bbe2356b36796bb81fe78b68c1 languageName: node linkType: hard -"@material/dialog@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/dialog@npm:13.0.0-canary.65125b3a6.0" +"@material/dialog@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/dialog@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/button": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/icon-button": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/tokens": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/button": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/icon-button": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/tokens": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 8ea9fbb97f84543eddf694de9ea87f0966eba603bf359ccc24f45746c6450c37f5f6dea5eb3484842c814ace1e1358af8c9eb2cdd1f4b0f029f8f047c0025075 + checksum: 0f5648975c68f8469ba0327250e6da61d057529e87337396d0887164368b116ced11fc68e4d2a6ea814eee1c890b4d50d3df58c96d0e3f5b42a21a2452fa59f7 languageName: node linkType: hard -"@material/dom@npm:13.0.0-canary.65125b3a6.0, @material/dom@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/dom@npm:13.0.0-canary.65125b3a6.0" +"@material/dom@npm:14.0.0-canary.353ca7e9f.0, @material/dom@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/dom@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 2a43ce2c5a413e58d0bf2c4fb119d09d4fd9ef45418da829ef7668e006dc5c9a22ab51a1653432e3df04d205f81044c5d49f20a55fb5fb5e2f900fd72ba350ae + checksum: 0579dde093ebcb8c9bc786ead6e47bd7777e027235f33f064c5ea4b5f22a5ed44f7b468992a722e5b95243c19041d5fc47a57b715108be90e62417813d27c266 languageName: node linkType: hard -"@material/elevation@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/elevation@npm:13.0.0-canary.65125b3a6.0" +"@material/elevation@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/elevation@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 4896996624e042b2da0b5c3e87af58b24db2cef6be91a4ca99addb47a05a0ddecc9259a6cdaa2b16d7c1732e38bc30de078d1edc05485fe82f2487440f09f9d9 + checksum: 897aa811f0835c00ef6b7e03f58b314d31d1eb5a42b4d656e3fd457b2a53b6c767eb692c20ee65cb595bd85d5311fb3fd1c7c1b9b2fc6aee2fad1b807f2520ad languageName: node linkType: hard -"@material/feature-targeting@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/feature-targeting@npm:13.0.0-canary.65125b3a6.0" +"@material/feature-targeting@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/feature-targeting@npm:14.0.0-canary.353ca7e9f.0" dependencies: tslib: ^2.1.0 - checksum: 155fe087e08ba82e590567853433a4675bf0fe7f8f8d8ca46d0fff2295497cea27c93d8c8fd747aa8773101a07747cac3f74c76394cf87f36bc62ec4ef7b3df8 + checksum: 1d7d1614fa70afa9eff1e94f313dd2dbcee0f133523505a80732b7660a1d0de3b5a2fb5cf14285b684ebd1dca91af3a61ea3c3ca7f23269e6fe959905307401b languageName: node linkType: hard -"@material/floating-label@npm:13.0.0-canary.65125b3a6.0, @material/floating-label@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/floating-label@npm:13.0.0-canary.65125b3a6.0" +"@material/floating-label@npm:14.0.0-canary.353ca7e9f.0, @material/floating-label@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/floating-label@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 6e050517c0a847d6e40056714cb39bf25379b6fdbd11e64010db50fbed1141df201bbcf57665adbb9e26597818d88d0ad1349cc278832babf836254c2b846792 + checksum: caa5357495b1760de16ebf57b4007363ce81c9f61d9d4366109ba09796caee6717c289bb81e8eb3ada3a1f08b65f12a85cc34137b1ab1f85b73416f2225be5d4 languageName: node linkType: hard -"@material/form-field@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/form-field@npm:13.0.0-canary.65125b3a6.0" +"@material/form-field@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/form-field@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 711855e4de4a68a00e8f0ef86260e71a94a141b370f997ae50097771f09fcb9f5e124ae5119e6fa511204b6632ad866ea1e1c3e6546035517aa49ae8c671d600 + checksum: 7ba43ea322b568ef4d637714a1fb64e294f4066fc54cade8d7c3212e77ede99ec3ed1f0210c3f31c43bdfe1f69ea79627bcdc447f57bac2a7c5930f7b08a7489 languageName: node linkType: hard -"@material/icon-button@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/icon-button@npm:13.0.0-canary.65125b3a6.0" +"@material/icon-button@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/icon-button@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: d6600d7284b01370231305028b92397cde74efea000a06b2b4e4b226ac5b8177f965aef19e7238307faaa21ba793c4cf75f81f6f0ff13e95fd92624ba9ec95a3 + checksum: 38fcb29d1aa1ae79e62bcf1ebc0e43f87c7b92e18290571199f15b693755410c22048cad610c8292edefaaa26d1afc18831195940256f0985966373287388100 languageName: node linkType: hard -"@material/line-ripple@npm:13.0.0-canary.65125b3a6.0, @material/line-ripple@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/line-ripple@npm:13.0.0-canary.65125b3a6.0" +"@material/line-ripple@npm:14.0.0-canary.353ca7e9f.0, @material/line-ripple@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/line-ripple@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: fe7903d734ad7af4629e269dda0059716feda2bc7b42de4916abf650fd6f8989066b399fe740d23f4ae856ff78a5ef06479306ed41d035f97ea9f285480bd6bf + checksum: ffb13a75c0e58036c15c0baee9dd74bd84eb7ebba2f81d4bcca24cf7cb272188c7ef28d7a37089ebe91457a86ad1cc246895e36e24b64e9a97670371d41e8076 languageName: node linkType: hard -"@material/linear-progress@npm:13.0.0-canary.65125b3a6.0, @material/linear-progress@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/linear-progress@npm:13.0.0-canary.65125b3a6.0" +"@material/linear-progress@npm:14.0.0-canary.353ca7e9f.0, @material/linear-progress@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/linear-progress@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/progress-indicator": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/progress-indicator": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: d8300a7e10afcd280c9bb2e8390773255f7e405c83180e53765053ebd785445046073b106ee2df4b852d1dcda23366fdbda5de4235c0807cd19c5f96348961cb + checksum: 7b2f168dfeb8ecf371f682ba640e371c3c6261796dd43670b99815ec8a102d7d0f3093a3f8753c801687238a52d42ad6ef1787acc5c778eb11be0ca0d223b623 languageName: node linkType: hard -"@material/list@npm:13.0.0-canary.65125b3a6.0, @material/list@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/list@npm:13.0.0-canary.65125b3a6.0" +"@material/list@npm:14.0.0-canary.353ca7e9f.0, @material/list@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/list@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 76cd28693d4eb5268a7efc07e46c3a035e530115485809650ddb13d32d66caebdb8b01164e5d16169475b726491cafc673e7f23e725ec53074921c2bb52c610b + checksum: 28bfa9b1a30c92813b5df3b0762311636bc41c4f546f744ab2892476c77ce8c7aa1b132de6801ebdbfa04b97330278b324c9a9e72677680799c411b2597a77cc languageName: node linkType: hard -"@material/menu-surface@npm:13.0.0-canary.65125b3a6.0, @material/menu-surface@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/menu-surface@npm:13.0.0-canary.65125b3a6.0" +"@material/menu-surface@npm:14.0.0-canary.353ca7e9f.0, @material/menu-surface@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/menu-surface@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: ce120a9f6d39825cf547aef6fca868e463f3f945f16402ebe42aed74322a73d152c906ad869777ff33ad780f9661b6370e9f3554bbec72f7e551a0c3e1b3914a + checksum: 9985f95a026889ac44e7201fbd919bcfb12bf9a49423ea092bfba65af8c0bb809059837049c8802c707677b0728746f34cc6a0c0567e0d5377923e051eccc0fd languageName: node linkType: hard -"@material/menu@npm:13.0.0-canary.65125b3a6.0, @material/menu@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/menu@npm:13.0.0-canary.65125b3a6.0" +"@material/menu@npm:14.0.0-canary.353ca7e9f.0, @material/menu@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/menu@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/list": 13.0.0-canary.65125b3a6.0 - "@material/menu-surface": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/list": 14.0.0-canary.353ca7e9f.0 + "@material/menu-surface": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 5e7796575f848592ab7326df5ffd27726a5f5632823e8f3126ac50da67b44504bb4afc713783295a114a5d21e0b5278a44378f2908528254910e9da68582fb85 + checksum: 8fd255f87b8442bcc103b7df21ac1145c876252085a702ab7982426bb707c4a9a30d3b565f1a7d61a4a4532e9a9e0244734f6429d346cc83b8d7ac81c302f26c languageName: node linkType: hard -"@material/mwc-base@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-base@npm:0.25.1" +"@material/mwc-base@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-base@npm:0.25.2" dependencies: "@lit/reactive-element": 1.0.0-rc.4 - "@material/base": =13.0.0-canary.65125b3a6.0 - "@material/dom": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 + "@material/base": =14.0.0-canary.353ca7e9f.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 69206ecad24cda0d290e008bb67f16ba22519f9b21c5a03831015980a62bf5e326d5ba238903e8e29a0abd25ac743c0432e55842be1ccd90fa90bde1832176d4 + checksum: a37b5389b7361a0bb2090f28c84947ff1e9e6c9e0779ee8591798db641fd5124b309df3ba5d8905262edd291a03dfa227932da909baf42c3f42786f9904400ae languageName: node linkType: hard -"@material/mwc-button@npm:0.25.1, @material/mwc-button@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-button@npm:0.25.1" +"@material/mwc-button@npm:0.25.2, @material/mwc-button@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-button@npm:0.25.2" dependencies: - "@material/mwc-icon": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/mwc-icon": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 5634ea9ad9d88603646a9a7598cf0dba8393a3b4a095dc93afd859fab0ae4a3e7bf5168577f3f40c690932d01c0de6e4c80160760df89d56036b3c1becbbcd00 + checksum: 37be1e20bed921f018443cd6283536d5463244b689d1bcb1ee7a44244e6a3b9356f551fb523db8d5cfc8265afc0d0728dfb761a3bfa7be7ab9decc4d16990a5d languageName: node linkType: hard -"@material/mwc-checkbox@npm:0.25.1, @material/mwc-checkbox@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-checkbox@npm:0.25.1" +"@material/mwc-checkbox@npm:0.25.2, @material/mwc-checkbox@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-checkbox@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: ae1d193ee58ce15fa8b58619ebfc8f087d96dd83f128c933fe9712a3e466e43068cbf54a93558b2e02715d13580e0f33c9dedf1b943c4e5b60cc6c08f2d12fd6 + checksum: 473fe4fa8c4c368b6540508b13d22d654dd23a9fe287e10659aa7d6d041434a118aec96d9b753013681a4276ff78470639873c666d57cb91a5618278f180a67f languageName: node linkType: hard -"@material/mwc-circular-progress@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-circular-progress@npm:0.25.1" +"@material/mwc-circular-progress@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-circular-progress@npm:0.25.2" dependencies: - "@material/circular-progress": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/theme": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/circular-progress": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/theme": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: ccce826f66ca74fd315d55f7318958fc9a5b2f477808d0c82e164c11c1ab1fa983c0c2ad1298678a9780d885b1c6d85cadfbca7fc889873fdaa84575861791da + checksum: c3eee68eb0444404def502166ccef7f1af13201ecf7dbe7ead3b971e85a6fe0e968b6ef7ee9cb3d79a8eae3b76efceea7ddc2af58d705d2671ecb2516946c7f9 languageName: node linkType: hard -"@material/mwc-dialog@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-dialog@npm:0.25.1" +"@material/mwc-dialog@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-dialog@npm:0.25.2" dependencies: - "@material/dialog": =13.0.0-canary.65125b3a6.0 - "@material/dom": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/mwc-button": ^0.25.1 + "@material/dialog": =14.0.0-canary.353ca7e9f.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-button": ^0.25.2 blocking-elements: ^0.1.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + lit: ^2.0.0 tslib: ^2.0.1 wicg-inert: ^3.0.0 - checksum: e9086a7df20017a2961792213ba7b5f190110da55f122f05ea3ad7448c43edbe65c3903e197cd887745c0d5c6ea0c63759d1c98c658f474fc69d3841ce93dd2f + checksum: f2e9733ba5fac758f78ac0356de4570ae24cf229f7a07118eeb307fabb871541d1a027a43088c9dae2682390c613fec0dc24a5c71f0d9884a98ffcec9ded83a1 languageName: node linkType: hard -"@material/mwc-fab@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-fab@npm:0.25.1" +"@material/mwc-fab@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-fab@npm:0.25.2" dependencies: - "@material/mwc-ripple": ^0.25.1 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/mwc-ripple": ^0.25.2 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 848992aa49e5a85efcb8e5026a4abb155539633439977b45877519a653242953a9464a881e765e5153e9d9f44c5749c20fc9c5b27b1d1172b06c43f06781ea58 + checksum: 8ad9bc73cd02e7c1cf3d662e75ab97ce2786169105127af203b7e17c59ef8ed5ae68de01fc4a753816a9982b4eb3dbbaafc9aa5a76fea7eafa364a9217868b1a languageName: node linkType: hard -"@material/mwc-floating-label@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-floating-label@npm:0.25.1" +"@material/mwc-floating-label@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-floating-label@npm:0.25.2" dependencies: - "@material/floating-label": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/floating-label": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 22d91998c1d01115e8ac59b71b5fe35cb8dc7c781bedb191377659536c0f190d99d5965cab41e67fe3bfc5100fdcdb0659c3f52b3712e89e4ae3994f5dc8319e + checksum: 27825073ea033675147dc505f4259313c53d71cbe25949f832e848c8767f5501afd6fc1e7bef6ae79607d04a522141c6b4cc06a6eaa79778a9807549902ab872 languageName: node linkType: hard -"@material/mwc-formfield@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-formfield@npm:0.25.1" +"@material/mwc-formfield@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-formfield@npm:0.25.2" dependencies: - "@material/form-field": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/form-field": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 3d87db5281b672e5df6d5f88014182fbef86c113e6991e1a37c04f3a609267742f12f86bcc3ec57960e2584a578cf032944bd5a5d6e4725127f7b2fdc5d69f38 + checksum: 354365f89ac83c5918cf8eca0ea1091e5e0d696b2076dd22e6311fdcf76c0c21b54a23c95dc3b3d940b95f9a5377e5c1061cec5d760d47a6b8bf75b8a3f4d1b7 languageName: node linkType: hard -"@material/mwc-icon-button@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-icon-button@npm:0.25.1" +"@material/mwc-icon-button@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-icon-button@npm:0.25.2" dependencies: - "@material/mwc-ripple": ^0.25.1 - lit-element: ^3.0.0 + "@material/mwc-ripple": ^0.25.2 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 72751ff7a3f379b6d8097be9fb6619f18634db03e916eafed8045857cdf74a43d7b1de03ecf6f455613d738a6ed318496615f2eade693f7b171b09b76923e92a + checksum: a3403989670df57f9bc656d29f5e5c3cdecfdaee9b4107bb0a1d6640b5abc3c2bcc72afc19b622d1a3af65935b37d201408af2f29913c9f6e0a37f2aa5a488a7 languageName: node linkType: hard -"@material/mwc-icon@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-icon@npm:0.25.1" +"@material/mwc-icon@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-icon@npm:0.25.2" dependencies: - lit-element: ^3.0.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 3b0f730d046bc4c655fae86092e7356976fea1fd1d8866eb5e0e03ba7e2f182fb4d5b28c2af4dbf570c594494b40a8b19c7c6857a935507e4d7554575ff60f4e + checksum: 1ccb0d63ecf57387f160e7f756e710f9f07a1936ef4ba36c9d09345c7e0d9b96800fdc85f8c4476619c32f86f3424c20152c5086c675e46a9f2e88ea807b6ac7 languageName: node linkType: hard -"@material/mwc-line-ripple@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-line-ripple@npm:0.25.1" +"@material/mwc-line-ripple@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-line-ripple@npm:0.25.2" dependencies: - "@material/line-ripple": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/line-ripple": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 5897f55cd11e134a2adea03b4cffaa46bf5d8fb71dff2c0601a53960f4ff35a4ba82ea443bdbe72daca801d3abc1b7a459bd980dbeab59dbd7b216b5e10fc1f2 + checksum: 03c9cafcf004c80c855625b424ead232c6e73ff6f0c4f71cb94a2c4041df24053069f51fc3f1d935a6bd0d8104e51e647b755ec224cdbaf5c95f4a9f78d257d8 languageName: node linkType: hard -"@material/mwc-linear-progress@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-linear-progress@npm:0.25.1" +"@material/mwc-linear-progress@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-linear-progress@npm:0.25.2" dependencies: - "@material/linear-progress": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/theme": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/linear-progress": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/theme": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: c3cb4667ee1b314a9ab4235608af473232a79a2661c568404d9cce31d1f277bed382f98147234bfa1bac772ef574c98d1499961a13ae0a5d28aead2cac228065 + checksum: d70af0d476e7c50ccf2d4bcb20b0b0561dd756a1170bc6a6e571eeb4b7779307b56ba29cbddbcbca0f4fe5df4f4414aa41ade3df7d323ecc453518ada79cd71f languageName: node linkType: hard -"@material/mwc-list@npm:0.25.1, @material/mwc-list@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-list@npm:0.25.1" +"@material/mwc-list@npm:0.25.2, @material/mwc-list@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-list@npm:0.25.2" dependencies: - "@material/base": =13.0.0-canary.65125b3a6.0 - "@material/dom": =13.0.0-canary.65125b3a6.0 - "@material/list": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/mwc-checkbox": ^0.25.1 - "@material/mwc-radio": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/base": =14.0.0-canary.353ca7e9f.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + "@material/list": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-checkbox": ^0.25.2 + "@material/mwc-radio": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 23ff641235ce9374376184cfa1c341f2e62cc5ac1e721c0330c2e2a96992e4df4d055d05a9905e2ce6ee244badb848012ea53f38b1322310b52e2b5a68ec0b18 + checksum: 2e661b61b0b66ba04a1adc870105e6c73f0772c8ebc3252698c353770a474b87e3340efa5fbe022f8b4d344319040264bc72d83d0f094b8255f9955c949eb77c languageName: node linkType: hard -"@material/mwc-menu@npm:0.25.1, @material/mwc-menu@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-menu@npm:0.25.1" +"@material/mwc-menu@npm:0.25.2, @material/mwc-menu@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-menu@npm:0.25.2" dependencies: - "@material/menu": =13.0.0-canary.65125b3a6.0 - "@material/menu-surface": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/mwc-list": ^0.25.1 - "@material/shape": =13.0.0-canary.65125b3a6.0 - "@material/theme": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/menu": =14.0.0-canary.353ca7e9f.0 + "@material/menu-surface": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-list": ^0.25.2 + "@material/shape": =14.0.0-canary.353ca7e9f.0 + "@material/theme": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 44abdb4ff4e47e558ba1fc5d9f96900ca8ef3f0728873b36e11892e4d0c912a5c6694a86f0e1c633b5a4706e5e1515b4dba8d927b99c709492d1b7af4d559623 + checksum: 5ca6a961e3f548c8f2e6301405f660684f1b3701142efe94c7e84b6644c757e8b06b22ab6febefe854b761ccd610c9b37660873ae41c7420fad01db8d9161899 languageName: node linkType: hard -"@material/mwc-notched-outline@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-notched-outline@npm:0.25.1" +"@material/mwc-notched-outline@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-notched-outline@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/notched-outline": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/mwc-base": ^0.25.2 + "@material/notched-outline": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: e86709d2f0b6b118a8ba606055c1e8a633919a834e05b4bf897d472206a6031e9ec20b20cdcccbc1d364939ea948e60aea4132eb17c4225938cc059ab370f301 + checksum: 6e615e10ac1c97fe9e648b150a6e2e9494baf2042d415a7f7932c740b5b4f8f889531f99dc1312e5f4d1932ef8978d51a0841bfea3a33878d82ef7b5b1f4cfa6 languageName: node linkType: hard -"@material/mwc-radio@npm:0.25.1, @material/mwc-radio@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-radio@npm:0.25.1" +"@material/mwc-radio@npm:0.25.2, @material/mwc-radio@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-radio@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - "@material/radio": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + "@material/radio": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 888e75a2a6804964b8939f4118e95ba28c637f04680b9df1d72d63463ecb198f8f2fa9f1130824b5748a96a70bb1d10baf57dd957d5f1fa1ed9955353e61157a + checksum: 22fcacf51d4324f6d8890ab7391f1fd45a6fedb60d454d40f70d999b0626766e7adb172928fe0158015f55e7665ae43acb226c3378c89dcb7e58d67b1e82ea63 languageName: node linkType: hard -"@material/mwc-ripple@npm:0.25.1, @material/mwc-ripple@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-ripple@npm:0.25.1" +"@material/mwc-ripple@npm:0.25.2, @material/mwc-ripple@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-ripple@npm:0.25.2" dependencies: - "@material/dom": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/ripple": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/ripple": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 9c09cdc655191d33ccee4437ca4214b5a71acbc393c248612d803b4d623d61ff542cbe6cb089318a114020d872acaf6dd305c33f990fab80db36aec4f5ad6408 + checksum: 99557d87e5f3240f7184339f34de26d933cc3e20d43cd30549178dba2b0b791835a801256244c0a0c53994b728863e627efa2fc0f29279f8799af2d8510434c4 languageName: node linkType: hard -"@material/mwc-select@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-select@npm:0.25.1" +"@material/mwc-select@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-select@npm:0.25.2" dependencies: - "@material/dom": =13.0.0-canary.65125b3a6.0 - "@material/floating-label": =13.0.0-canary.65125b3a6.0 - "@material/line-ripple": =13.0.0-canary.65125b3a6.0 - "@material/list": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/mwc-floating-label": ^0.25.1 - "@material/mwc-icon": ^0.25.1 - "@material/mwc-line-ripple": ^0.25.1 - "@material/mwc-list": ^0.25.1 - "@material/mwc-menu": ^0.25.1 - "@material/mwc-notched-outline": ^0.25.1 - "@material/select": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + "@material/floating-label": =14.0.0-canary.353ca7e9f.0 + "@material/line-ripple": =14.0.0-canary.353ca7e9f.0 + "@material/list": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-floating-label": ^0.25.2 + "@material/mwc-icon": ^0.25.2 + "@material/mwc-line-ripple": ^0.25.2 + "@material/mwc-list": ^0.25.2 + "@material/mwc-menu": ^0.25.2 + "@material/mwc-notched-outline": ^0.25.2 + "@material/select": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 542c24e93e16d0a9f101765679c14e823a0c6fd3932b6f33e6a0bd440e436265c2571505db850be3dcff09e0a05d79ffecdc55e0e1340ba8722e181ed3667529 + checksum: d41344b0286396d562e607e22ee630fd1013453e0ec9bad3b1dfa7b4548c03dde677cc80b59fed69580b391d9ec917259f0ad603d089bc2939d72ed3f47abd91 languageName: node linkType: hard -"@material/mwc-slider@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-slider@npm:0.25.1" +"@material/mwc-slider@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-slider@npm:0.25.2" dependencies: - "@material/dom": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - "@material/slider": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + "@material/slider": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 964ba94e12b2aee8e67b19e0d4fc7b8a8a4945be8bef82aa3a305247b2e318709d1d3ffd9761f87a920f85538a863aca59c2746f8bd85e82125c1d15f98c8768 + checksum: e87637e0a998b85cc7d49e935f80f7234b8cf13cc982efdf583614241c420954e33f4a6156cd6ca85ae58e27554575ff36ccab5a3ef6ba2d3c0a6b8b95a8153a languageName: node linkType: hard -"@material/mwc-switch@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-switch@npm:0.25.1" +"@material/mwc-switch@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-switch@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - "@material/switch": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + "@material/switch": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: df6dd30d7bc1ddfa318d04f8e68044f6e3e45731d0c56499e3be7eddc13c8c049b8ac5d1872fefbb859ad18e1e4bb0e7be19c81db486d0366a1f576793cd95f7 + checksum: 7fe6454d6c0655321ac0220cd9ac146808d301f7d3fec5153c3235483082c5c72218230af3608c492ab99517e658c800feb0bdce0a26bd384abbaa6feb48c7ce languageName: node linkType: hard -"@material/mwc-tab-bar@npm:0.25.1": - version: 0.25.1 - resolution: "@material/mwc-tab-bar@npm:0.25.1" +"@material/mwc-tab-bar@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-tab-bar@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/mwc-tab": ^0.25.1 - "@material/mwc-tab-scroller": ^0.25.1 - "@material/tab": =13.0.0-canary.65125b3a6.0 - "@material/tab-bar": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-tab": ^0.25.2 + "@material/mwc-tab-scroller": ^0.25.2 + "@material/tab": =14.0.0-canary.353ca7e9f.0 + "@material/tab-bar": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: a65dab8e24241a6d9a3ddb6e2321c6f70b71b24c388625c276c2f05d670b533bb3aeb6656bff4e858d3ff6d2fb5dd5ebfac86c889f962e9d54d507fd80eb00ac + checksum: 44084ca9cf79c24153faaf088239c3d409d503ec71a0919426f9aaeab0ab6f3d687b088474950adf5e28ce22887ef93244e26e8257166fe451807aecea0da4e1 languageName: node linkType: hard -"@material/mwc-tab-indicator@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-tab-indicator@npm:0.25.1" +"@material/mwc-tab-indicator@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-tab-indicator@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/tab-indicator": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/mwc-base": ^0.25.2 + "@material/tab-indicator": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 551148a247ceea1ad1d3bf7428e9e712e093b910a96161b0264ffba6d3a187ecc430eadeb6679014368f55959728c8ac2696e1a291b90426544c9401f405eb82 + checksum: a4d4a1ab1e4c6fd64314d040579cdd9e3ea0c19bc17f6183220c27ea9d54ed3d765d6773469a2286b65aca940f8c850dcb65b11af32670b40ca485d92406bf0e languageName: node linkType: hard -"@material/mwc-tab-scroller@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-tab-scroller@npm:0.25.1" +"@material/mwc-tab-scroller@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-tab-scroller@npm:0.25.2" dependencies: - "@material/dom": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/tab-scroller": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 + "@material/dom": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/tab-scroller": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 2f832b4f6f75acb59e4de61962f9fa15a888c9dc08e5b5146ac0f04f11c1429c70ad06eab6f73886037021491edd1deb71f9160aea79f59e6a2d6b8028e22bd6 + checksum: f67cdbaea7046326e123192cb7e261c2455c2b61c5e9687ea22b512eacb7efe970bc91188291f93aba55b9f9daae992abfa0ce5f81d3f03510e698d8a60e5fb0 languageName: node linkType: hard -"@material/mwc-tab@npm:0.25.1, @material/mwc-tab@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-tab@npm:0.25.1" +"@material/mwc-tab@npm:0.25.2, @material/mwc-tab@npm:^0.25.2": + version: 0.25.2 + resolution: "@material/mwc-tab@npm:0.25.2" dependencies: - "@material/mwc-base": ^0.25.1 - "@material/mwc-ripple": ^0.25.1 - "@material/mwc-tab-indicator": ^0.25.1 - "@material/tab": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-ripple": ^0.25.2 + "@material/mwc-tab-indicator": ^0.25.2 + "@material/tab": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 0aeeb862088695c90f572dee8f56ddacb43dcd656dfb3c2c5efe87f15008a2511a6303cd157735e3b0070f05b783b6afe2d6f4527cb3fd3c8d1d1835f21394a0 + checksum: 899ea855bcf4dc6229d02b018f93df2c4315e966674f82b456148016df41728cb88f0b390053013f9dcc5347ec8cf458b4643a606e18a6309c7031cd33122019 languageName: node linkType: hard -"@material/mwc-textfield@npm:^0.25.1": - version: 0.25.1 - resolution: "@material/mwc-textfield@npm:0.25.1" +"@material/mwc-textfield@npm:0.25.2": + version: 0.25.2 + resolution: "@material/mwc-textfield@npm:0.25.2" dependencies: - "@material/floating-label": =13.0.0-canary.65125b3a6.0 - "@material/line-ripple": =13.0.0-canary.65125b3a6.0 - "@material/mwc-base": ^0.25.1 - "@material/mwc-floating-label": ^0.25.1 - "@material/mwc-line-ripple": ^0.25.1 - "@material/mwc-notched-outline": ^0.25.1 - "@material/textfield": =13.0.0-canary.65125b3a6.0 - lit-element: ^3.0.0 - lit-html: ^2.0.0 + "@material/floating-label": =14.0.0-canary.353ca7e9f.0 + "@material/line-ripple": =14.0.0-canary.353ca7e9f.0 + "@material/mwc-base": ^0.25.2 + "@material/mwc-floating-label": ^0.25.2 + "@material/mwc-line-ripple": ^0.25.2 + "@material/mwc-notched-outline": ^0.25.2 + "@material/textfield": =14.0.0-canary.353ca7e9f.0 + lit: ^2.0.0 tslib: ^2.0.1 - checksum: 31a0235c4b50dcbff28d913c90be114b2972edceb753b17eb84f47cdb46459716a70ee939e9853b8e9ce86af0105e48fea31700e8bac5c30dfadba0f1d5b2235 + checksum: 9ee773c53e4ce748b8cc690d68ca27c7be3f93562124dec799cd0f069152d33dd12957c465091cf40c9c7d027af7659078628fa0f04ee6b2f83e643c0a4988b4 languageName: node linkType: hard -"@material/notched-outline@npm:13.0.0-canary.65125b3a6.0, @material/notched-outline@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/notched-outline@npm:13.0.0-canary.65125b3a6.0" +"@material/notched-outline@npm:14.0.0-canary.353ca7e9f.0, @material/notched-outline@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/notched-outline@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/floating-label": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/floating-label": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 00e0c65d9672d8514f5984d7c2b74b844ed3c9a808a7a12fd30a1555f343796a2b340053abb36d6f8320a0571a3dd496c5d53d646ac14753a1c81daa81189058 + checksum: 6c1868591bcda0eb4695ed9d281940c55ad849bb7cb6f99d08804ebc266521644e5c87b3891247ec383dca86247b794ac4d17f8aef752146d5de142cff1635ff languageName: node linkType: hard -"@material/progress-indicator@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/progress-indicator@npm:13.0.0-canary.65125b3a6.0" +"@material/progress-indicator@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/progress-indicator@npm:14.0.0-canary.353ca7e9f.0" dependencies: tslib: ^2.1.0 - checksum: 1e71b5fd7dab40fa0f4f2f89950ed4b0e5abc36d9bf0832bd665ad66c7772b01b10519ec12bb9c13661e55f49dba7a04f6fde53ff1eb1baf45e3143cf2c5c34a + checksum: a92f2c5f16f94ca4d1c5bf8261e586dd13d8a55c193bd42457bed6632d65cde09daf1b775d626c934da8bea239042ea7a4e31719e446afb8f6fba4e7dfa6791f languageName: node linkType: hard -"@material/radio@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/radio@npm:13.0.0-canary.65125b3a6.0" +"@material/radio@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/radio@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/touch-target": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/touch-target": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 2cc58915687eeda39cc00dd2bbe49ac9913cf64f8eb605f421a88da4642ecaa03b996b6bd19863f55174eee6cf758d91cfe3eb40d12d04fc98c7ae592db9c925 + checksum: 6ef8c78cce0641533c1bcfdea76dc36845bb3523d5b23460b4a6a36eb11b272e6d6d8c48da69ebc6fd5f98dbf6f6dc7795aaa40e287df6e996470ec5a866738d languageName: node linkType: hard -"@material/ripple@npm:13.0.0-canary.65125b3a6.0, @material/ripple@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/ripple@npm:13.0.0-canary.65125b3a6.0" +"@material/ripple@npm:14.0.0-canary.353ca7e9f.0, @material/ripple@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/ripple@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: e439a7865c743f0c836e5e35d2c490c2542496d30f465c8738e733d5a384d929adcb7b13bdba9c0e22c398c4e867339aac18368f7a8c979e4d2a06b9111a479e + checksum: 0af903097a71793ad9f366a791382bc2b68b1fed16d0ca1618e221a506aec723a4dbb7994457dc6a1a414a1e432ae7f1a093323307e2867a25181ee018a594ea languageName: node linkType: hard -"@material/rtl@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/rtl@npm:13.0.0-canary.65125b3a6.0" +"@material/rtl@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/rtl@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: bbf332ce1f37d0c806ee77652840c73c2dc8500b4861a117b98f2dcb8aa40cbbf9e753cab1e7844b5c6b07c51f5e26ca96113512e601542c92966a496676e245 + checksum: 6ccb7d92613ef7241cd2dd4368fb636e2ee5b6ea780cf376210e07b3e8e5fa950d3c3e597c80cd8e55cdb4e3f7f7f3def7246e78cabec19a86d5076ab38d50d4 languageName: node linkType: hard -"@material/select@npm:13.0.0-canary.65125b3a6.0, @material/select@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/select@npm:13.0.0-canary.65125b3a6.0" +"@material/select@npm:14.0.0-canary.353ca7e9f.0, @material/select@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/select@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/floating-label": 13.0.0-canary.65125b3a6.0 - "@material/line-ripple": 13.0.0-canary.65125b3a6.0 - "@material/list": 13.0.0-canary.65125b3a6.0 - "@material/menu": 13.0.0-canary.65125b3a6.0 - "@material/menu-surface": 13.0.0-canary.65125b3a6.0 - "@material/notched-outline": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/floating-label": 14.0.0-canary.353ca7e9f.0 + "@material/line-ripple": 14.0.0-canary.353ca7e9f.0 + "@material/list": 14.0.0-canary.353ca7e9f.0 + "@material/menu": 14.0.0-canary.353ca7e9f.0 + "@material/menu-surface": 14.0.0-canary.353ca7e9f.0 + "@material/notched-outline": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 078a4689164745a2f2ac750055bacf054d710145c916ebdb39ab4ef124232f1cb201fd03e1e23339e2c6ae8c01d4f8abd43a2101f3bf067929d45683830c0cae + checksum: 92608ccdbe512ea8e9f8492232a9229489fdc496e814c181a7d2bdc5711233d9de08d6c883bf652720031ac49d504b92fa6b5a95b942ab6bce6c04136315268d languageName: node linkType: hard -"@material/shape@npm:13.0.0-canary.65125b3a6.0, @material/shape@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/shape@npm:13.0.0-canary.65125b3a6.0" +"@material/shape@npm:14.0.0-canary.353ca7e9f.0, @material/shape@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/shape@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 03d9c5cab16dfdf867f1663ebd77e0ea74a346df570dd9fccc61a7588ccde8dafc73803f5501e2900dc7b50469e2fe068ba3cb92567abbeda689641e11eeea3b + checksum: 840a4eea7bb4ec2a377fa2d33a35d2c9b121bd59f20fa7ed2f099048ec27ae519001ca889869da31cc6487d9fd08585965022dcb87c552c0c5e8af810ae0bf7b languageName: node linkType: hard -"@material/slider@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/slider@npm:13.0.0-canary.65125b3a6.0" +"@material/slider@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/slider@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 26f6de62b296296b196cfa31193e137f91da8a4eb6c1e8c7209a73eac3c2d4bbbb412e020b715942ab861632701a6c9931e8b845a4f7cc92b6700f43b811c50c + checksum: 074c220ea435724e44912cff9fd057fb0f4c93282f882d96b5ed9b96f578b3ea20b6bb736f74196c4f1a13a6916b376e219051008abf4ca63fd122c2181a1828 languageName: node linkType: hard -"@material/switch@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/switch@npm:13.0.0-canary.65125b3a6.0" +"@material/switch@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/switch@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/tokens": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/tokens": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: bf0a79339fce551c284d2919717599c67c187944bd6c377df2d7cecad27451bc567ac9206b71798f436175c77ceb045df02b0864a721be8ccbb3afa844adb0b3 + checksum: bb0c67a116f0eb1c6eebc260e83de924dbd303cc02e805bf53d04a25b2fa7d3bcd874f6247097f7ab9925ba3968b12c2a144d23286d5a8e7a1d1c4d57416cd71 languageName: node linkType: hard -"@material/tab-bar@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/tab-bar@npm:13.0.0-canary.65125b3a6.0" +"@material/tab-bar@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/tab-bar@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/tab": 13.0.0-canary.65125b3a6.0 - "@material/tab-indicator": 13.0.0-canary.65125b3a6.0 - "@material/tab-scroller": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/tab": 14.0.0-canary.353ca7e9f.0 + "@material/tab-indicator": 14.0.0-canary.353ca7e9f.0 + "@material/tab-scroller": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 351f8cbaaf6ddba94c67240ea58ed15972b17824a8bbf8a6b70ef6e16dfa100ff392fac120c9014afc856248b1d1cc8e419df45c76c3322e52fa39c73fc0ae54 + checksum: fcb22a70f401873829d7dda72c847355957b5a7330a20f8437333f2793611a0b3ad6ce5520fe0905afaec37e58e8d2f9872f158bb62afa77f0562069fc529a18 languageName: node linkType: hard -"@material/tab-indicator@npm:13.0.0-canary.65125b3a6.0, @material/tab-indicator@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/tab-indicator@npm:13.0.0-canary.65125b3a6.0" +"@material/tab-indicator@npm:14.0.0-canary.353ca7e9f.0, @material/tab-indicator@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/tab-indicator@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 15ce88420c7f6f397c476df6a62db35608bbb8f355ff978b7afb3c9457704299a8c597a1800b21e8011f282b281fc33bbac73fd0fe508375c479ecd5a76723c1 + checksum: f65e0e431ee1f56207eb536c963faf124c909cfd2dbabbf4d6f47c1f5fb41e0c50f61672af1cd2843d8a67eead9d3fffb0dc1992986201a8d8ee8da2d5c4a22f languageName: node linkType: hard -"@material/tab-scroller@npm:13.0.0-canary.65125b3a6.0, @material/tab-scroller@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/tab-scroller@npm:13.0.0-canary.65125b3a6.0" +"@material/tab-scroller@npm:14.0.0-canary.353ca7e9f.0, @material/tab-scroller@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/tab-scroller@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/tab": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/tab": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 5478ee4905e780e8d0503681d9d579ea0d8ac31507ed1c7f6a887bb8e6fca00e51f10dfeee21d49154586c185156150ea8930c8d4c4f4eaffb204076e83537ef + checksum: dee4b149f715726c08fd185ac22cec54eb946ae9ee2fc1a89729f3e30a6cbbc40e278774a485729cb562b885a9c7163bfd1033bd295a643a1da1f4afcbd81c09 languageName: node linkType: hard -"@material/tab@npm:13.0.0-canary.65125b3a6.0, @material/tab@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/tab@npm:13.0.0-canary.65125b3a6.0" +"@material/tab@npm:14.0.0-canary.353ca7e9f.0, @material/tab@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/tab@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/tab-indicator": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/tab-indicator": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 6f48ab2361d80025ccc3422c7b785c80efeccfcf96d64aae60eb6988a094def547edc7d006a3a8f00229ca391e19897d4a8737159911d813e714b66732b698dc + checksum: e70fc8fb890c97de340a7b0f99be0a1b11490375e82167dba11d650ca1ed8679f9764b12e7a60d81a534de2d4821f74fb08cfd080480516e791c458b9f0de24f languageName: node linkType: hard -"@material/textfield@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/textfield@npm:13.0.0-canary.65125b3a6.0" +"@material/textfield@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/textfield@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/density": 13.0.0-canary.65125b3a6.0 - "@material/dom": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/floating-label": 13.0.0-canary.65125b3a6.0 - "@material/line-ripple": 13.0.0-canary.65125b3a6.0 - "@material/notched-outline": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/density": 14.0.0-canary.353ca7e9f.0 + "@material/dom": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/floating-label": 14.0.0-canary.353ca7e9f.0 + "@material/line-ripple": 14.0.0-canary.353ca7e9f.0 + "@material/notched-outline": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 1be6d8c1941729a580cb56fd9079049e9cb0dc9c648708af19683a11bd2f14b21b212cc8cf41f77c8cac9441438fe1f17696b70264daf8e0ff72f22baec7136a + checksum: def6b30da404dc3e87a8c629ad38d4098c3e5bf1b1b8b9ad3575da52c2e26d03effd709073d16e1b2e7df17f009f133737fe150af036324afeba0c5b0071a9a8 languageName: node linkType: hard -"@material/theme@npm:13.0.0-canary.65125b3a6.0, @material/theme@npm:=13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/theme@npm:13.0.0-canary.65125b3a6.0" +"@material/theme@npm:14.0.0-canary.353ca7e9f.0, @material/theme@npm:=14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/theme@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 06d659e072fbc2a57a20e097229323e98ec66a71d27f7a789574d534d8fcf8fde97260aac7bd550dbd1946530264ae9ffb74afcef8ebbf812f56fc1e05200ee8 + checksum: cb56e2e2f4d73904ce1efd86371988f77d99f5169af2f73f78258ff15d6c4e52ce8a516d2dd87841deb1b500feebd09ce05bc33f4e075078daf9f481deba9c02 languageName: node linkType: hard -"@material/tokens@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/tokens@npm:13.0.0-canary.65125b3a6.0" +"@material/tokens@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/tokens@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/elevation": 13.0.0-canary.65125b3a6.0 - checksum: e90adbee3e32d518c84927e220f6db7b90f276454abbe301bd76eb46533b341472e079cc264ae3180d197a6b7a516e33a5a1aedb61137f3269d8baf9afc95166 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + checksum: 436874c6579c0f2041900c4876b021c6c9041f41d8ef8b37d79bbc091fc12ad34d2b999c83f9f2763e39cf01caab3635e6da995f622504b393222fb4d2eed823 languageName: node linkType: hard -"@material/top-app-bar@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/top-app-bar@npm:13.0.0-canary.65125b3a6.0" +"@material/top-app-bar@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/top-app-bar@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/animation": 13.0.0-canary.65125b3a6.0 - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/elevation": 13.0.0-canary.65125b3a6.0 - "@material/ripple": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 - "@material/shape": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 - "@material/typography": 13.0.0-canary.65125b3a6.0 + "@material/animation": 14.0.0-canary.353ca7e9f.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/elevation": 14.0.0-canary.353ca7e9f.0 + "@material/ripple": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 + "@material/shape": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 + "@material/typography": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: ae0e571f216441f66627aaea7cb58b47391887dabc646a6cf7faf26aea5a130c82ac2147dcef37a32902bcdcc2f0e35178b61fbacb8743d732c3f2c9efbf0e5b + checksum: e1dc360d3271cc95c9ed0f71e9982e2b9f382b0b7b6e48ec794716ef71284ec00d7d63fd297fc77b99c1bb203fa818cc6b10d7d74c46ea4bcc18b2b43e5032a2 languageName: node linkType: hard -"@material/touch-target@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/touch-target@npm:13.0.0-canary.65125b3a6.0" +"@material/touch-target@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/touch-target@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/base": 13.0.0-canary.65125b3a6.0 - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/rtl": 13.0.0-canary.65125b3a6.0 + "@material/base": 14.0.0-canary.353ca7e9f.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/rtl": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 6e2aaf235c7de61d5132b4a72cdd5e00cfdc29b644ca815b892428963b635c40ca2adbbf780ca8732e24e0f99c07053f5e2982fdbdd3921172f0c71aba6a3a90 + checksum: 8ea70816bda4a75d3a46c03d4881812cdce0c0b6a5d1baa64d35304e5d37163cf2c391816b3e5f2eac2a1969457c8855b58c2520e55f487f584449cf07926288 languageName: node linkType: hard -"@material/typography@npm:13.0.0-canary.65125b3a6.0": - version: 13.0.0-canary.65125b3a6.0 - resolution: "@material/typography@npm:13.0.0-canary.65125b3a6.0" +"@material/typography@npm:14.0.0-canary.353ca7e9f.0": + version: 14.0.0-canary.353ca7e9f.0 + resolution: "@material/typography@npm:14.0.0-canary.353ca7e9f.0" dependencies: - "@material/feature-targeting": 13.0.0-canary.65125b3a6.0 - "@material/theme": 13.0.0-canary.65125b3a6.0 + "@material/feature-targeting": 14.0.0-canary.353ca7e9f.0 + "@material/theme": 14.0.0-canary.353ca7e9f.0 tslib: ^2.1.0 - checksum: 8b7683f2c864f8fb79fd003820b2d3d3cc0eb47f15ed3a19313cdecda7c825e81adcb5268bfba89161048f7edaa637db1ccfc7e06d764827b613932a1933802d + checksum: b54562b3fd2fcdba7d63982040a0c877dde27aa7b4e1d5ffbcaec9f61670798db882a11066521680d584344f63d54ad43adb69eba51926992823f3d7eefc7ac8 languageName: node linkType: hard @@ -9097,27 +9079,27 @@ fsevents@^1.2.7: "@fullcalendar/list": 5.9.0 "@koa/cors": ^3.1.0 "@lit-labs/virtualizer": "patch:@lit-labs/virtualizer@0.6.0#./.yarn/patches/@lit-labs/virtualizer/0.7.0.patch" - "@material/chips": 13.0.0-canary.65125b3a6.0 - "@material/data-table": 13.0.0-canary.65125b3a6.0 - "@material/mwc-button": 0.25.1 - "@material/mwc-checkbox": 0.25.1 - "@material/mwc-circular-progress": 0.25.1 - "@material/mwc-dialog": 0.25.1 - "@material/mwc-fab": 0.25.1 - "@material/mwc-formfield": 0.25.1 - "@material/mwc-icon-button": 0.25.1 - "@material/mwc-linear-progress": 0.25.1 - "@material/mwc-list": 0.25.1 - "@material/mwc-menu": 0.25.1 - "@material/mwc-radio": 0.25.1 - "@material/mwc-ripple": 0.25.1 - "@material/mwc-select": ^0.25.1 - "@material/mwc-slider": ^0.25.1 - "@material/mwc-switch": 0.25.1 - "@material/mwc-tab": 0.25.1 - "@material/mwc-tab-bar": 0.25.1 - "@material/mwc-textfield": ^0.25.1 - "@material/top-app-bar": 13.0.0-canary.65125b3a6.0 + "@material/chips": 14.0.0-canary.353ca7e9f.0 + "@material/data-table": 14.0.0-canary.353ca7e9f.0 + "@material/mwc-button": 0.25.2 + "@material/mwc-checkbox": 0.25.2 + "@material/mwc-circular-progress": 0.25.2 + "@material/mwc-dialog": 0.25.2 + "@material/mwc-fab": 0.25.2 + "@material/mwc-formfield": 0.25.2 + "@material/mwc-icon-button": 0.25.2 + "@material/mwc-linear-progress": 0.25.2 + "@material/mwc-list": 0.25.2 + "@material/mwc-menu": 0.25.2 + "@material/mwc-radio": 0.25.2 + "@material/mwc-ripple": 0.25.2 + "@material/mwc-select": 0.25.2 + "@material/mwc-slider": 0.25.2 + "@material/mwc-switch": 0.25.2 + "@material/mwc-tab": 0.25.2 + "@material/mwc-tab-bar": 0.25.2 + "@material/mwc-textfield": 0.25.2 + "@material/top-app-bar": 14.0.0-canary.353ca7e9f.0 "@mdi/js": 6.2.95 "@mdi/svg": 6.2.95 "@open-wc/dev-server-hmr": ^0.0.2 From 3f2cce936cb834038cc257ffaa3f8db9b0706a73 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 14 Oct 2021 13:06:18 -0700 Subject: [PATCH 033/115] Bumped version to 20211014.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 589990ec84..fcf5b86a56 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20211007.0", + version="20211014.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/frontend", author="The Home Assistant Authors", From 4b77910e4f31b048d30d09663e03cf18f0a0e762 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 15 Oct 2021 00:03:51 -0700 Subject: [PATCH 034/115] Warn if iframe won't be able to load the website (#10217) --- src/panels/lovelace/cards/hui-iframe-card.ts | 26 +++++++++++++++++--- src/translations/en.json | 3 +++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/panels/lovelace/cards/hui-iframe-card.ts b/src/panels/lovelace/cards/hui-iframe-card.ts index 84658915da..f791c08ce6 100644 --- a/src/panels/lovelace/cards/hui-iframe-card.ts +++ b/src/panels/lovelace/cards/hui-iframe-card.ts @@ -1,10 +1,12 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import parseAspectRatio from "../../../common/util/parse-aspect-ratio"; import "../../../components/ha-card"; +import "../../../components/ha-alert"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { IframeCardConfig } from "./types"; +import type { HomeAssistant } from "../../../types"; @customElement("hui-iframe-card") export class HuiIframeCard extends LitElement implements LovelaceCard { @@ -24,7 +26,9 @@ export class HuiIframeCard extends LitElement implements LovelaceCard { @property({ type: Boolean, reflect: true }) public isPanel = false; - @property() protected _config?: IframeCardConfig; + @property() public hass?: HomeAssistant; + + @state() protected _config?: IframeCardConfig; public getCardSize(): number { if (!this._config) { @@ -45,7 +49,7 @@ export class HuiIframeCard extends LitElement implements LovelaceCard { } protected render(): TemplateResult { - if (!this._config) { + if (!this._config || !this.hass) { return html``; } @@ -59,6 +63,22 @@ export class HuiIframeCard extends LitElement implements LovelaceCard { padding = "50%"; } + const target_protocol = new URL(this._config.url, location.toString()) + .protocol; + if (location.protocol === "https:" && target_protocol !== "https:") { + return html` + + ${this.hass!.localize( + "ui.panel.lovelace.cards.iframe.error_secure_context", + { + target_protocol, + context_protocol: location.protocol, + } + )} + + `; + } + return html`
Date: Sat, 16 Oct 2021 05:37:48 -0700 Subject: [PATCH 035/115] Disable ha-form while submitting entry flow (#10290) --- src/dialogs/config-flow/step-flow-form.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dialogs/config-flow/step-flow-form.ts b/src/dialogs/config-flow/step-flow-form.ts index 1b7865bd4b..a1969dc460 100644 --- a/src/dialogs/config-flow/step-flow-form.ts +++ b/src/dialogs/config-flow/step-flow-form.ts @@ -48,6 +48,7 @@ class StepFlowForm extends LitElement { : ""} Date: Sat, 16 Oct 2021 05:38:58 -0700 Subject: [PATCH 036/115] Convert all warning classes to ha-alert (#10289) --- .../src/addon-view/info/hassio-addon-info.ts | 29 +++++++++---------- .../action/ha-automation-action-row.ts | 15 ++++++---- .../trigger/ha-automation-trigger-row.ts | 12 +++++--- .../config/devices/ha-config-device-page.ts | 21 +++++++------- .../lovelace/editor/hui-element-editor.ts | 12 +++++--- src/translations/en.json | 2 +- 6 files changed, 50 insertions(+), 41 deletions(-) diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index f37fde8eaf..8d54e25563 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -180,24 +180,21 @@ class HassioAddonInfo extends LitElement { : ""} ${!this.addon.protected ? html` - -

${this.supervisor.localize( - "addon.dashboard.protection_mode.title" - )} -

-
- ${this.supervisor.localize("addon.dashboard.protection_mode.content")} -
-
- - ${this.supervisor.localize( + -
-
-
- ` + @alert-action-clicked=${this._protectionToggled} + > + ${this.supervisor.localize( + "addon.dashboard.protection_mode.content" + )} + + ` : ""} diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts index 7685926e49..6e1f316a82 100644 --- a/src/panels/config/automation/action/ha-automation-action-row.ts +++ b/src/panels/config/automation/action/ha-automation-action-row.ts @@ -12,6 +12,7 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { handleStructError } from "../../../../common/structs/handle-errors"; import "../../../../components/ha-button-menu"; import "../../../../components/ha-card"; +import "../../../../components/ha-alert"; import "../../../../components/ha-icon-button"; import type { HaYamlEditor } from "../../../../components/ha-yaml-editor"; import type { Action } from "../../../../data/script"; @@ -42,7 +43,8 @@ const OPTIONS = [ "device_id", ]; -const getType = (action: Action) => OPTIONS.find((option) => option in action); +const getType = (action: Action | undefined) => + action ? OPTIONS.find((option) => option in action) : undefined; declare global { // for fire event @@ -171,9 +173,12 @@ export default class HaAutomationActionRow extends LitElement {
${this._warnings - ? html`
- ${this.hass.localize("ui.errors.config.editor_not_supported")}: -
+ ? html` ${this._warnings!.length > 0 && this._warnings![0] !== undefined ? html`
    ${this._warnings!.map( @@ -182,7 +187,7 @@ export default class HaAutomationActionRow extends LitElement {
` : ""} ${this.hass.localize("ui.errors.config.edit_in_yaml_supported")} -
` + ` : ""} ${yamlMode ? html` diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index 3d72c5f404..f5d9125699 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -12,6 +12,7 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { handleStructError } from "../../../../common/structs/handle-errors"; import "../../../../components/ha-button-menu"; import "../../../../components/ha-card"; +import "../../../../components/ha-alert"; import "../../../../components/ha-icon-button"; import type { Trigger } from "../../../../data/automation"; import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box"; @@ -121,9 +122,12 @@ export default class HaAutomationTriggerRow extends LitElement {
${this._warnings - ? html`
- ${this.hass.localize("ui.errors.config.editor_not_supported")}: -
+ ? html` ${this._warnings.length && this._warnings[0] !== undefined ? html`
    ${this._warnings.map( @@ -132,7 +136,7 @@ export default class HaAutomationTriggerRow extends LitElement {
` : ""} ${this.hass.localize("ui.errors.config.edit_in_yaml_supported")} -
` + ` : ""} ${yamlMode ? html` diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 39c9ab79e9..9be745ae4e 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -13,6 +13,7 @@ import { slugify } from "../../../common/string/slugify"; import "../../../components/entity/ha-battery-icon"; import "../../../components/ha-icon-button"; import "../../../components/ha-icon-next"; +import "../../../components/ha-alert"; import "../../../components/ha-svg-icon"; import { AreaRegistryEntry } from "../../../data/area_registry"; import { @@ -296,17 +297,15 @@ export class HaConfigDevicePage extends LitElement { ${ device.disabled_by ? html` -
-

- ${this.hass.localize( - "ui.panel.config.devices.enabled_cause", - "cause", - this.hass.localize( - `ui.panel.config.devices.disabled_by.${device.disabled_by}` - ) - )} -

-
+ + ${this.hass.localize( + "ui.panel.config.devices.enabled_cause", + "cause", + this.hass.localize( + `ui.panel.config.devices.disabled_by.${device.disabled_by}` + ) + )} + ${device.disabled_by === "user" ? html`
diff --git a/src/panels/lovelace/editor/hui-element-editor.ts b/src/panels/lovelace/editor/hui-element-editor.ts index 68e0d1875c..3fa6aa3d87 100644 --- a/src/panels/lovelace/editor/hui-element-editor.ts +++ b/src/panels/lovelace/editor/hui-element-editor.ts @@ -15,6 +15,7 @@ import { computeRTL } from "../../../common/util/compute_rtl"; import { deepEqual } from "../../../common/util/deep-equal"; import "../../../components/ha-circular-progress"; import "../../../components/ha-code-editor"; +import "../../../components/ha-alert"; import type { HaCodeEditor } from "../../../components/ha-code-editor"; import type { LovelaceCardConfig, @@ -229,9 +230,12 @@ export abstract class HuiElementEditor extends LitElement { : ""} ${this.hasWarning ? html` -
- ${this.hass.localize("ui.errors.config.editor_not_supported")}: -
+ ${this._warnings!.length > 0 && this._warnings![0] !== undefined ? html`
    ${this._warnings!.map( @@ -240,7 +244,7 @@ export abstract class HuiElementEditor extends LitElement {
` : ""} ${this.hass.localize("ui.errors.config.edit_in_yaml_supported")} -
+ ` : ""}
diff --git a/src/translations/en.json b/src/translations/en.json index 5b18237bc1..30caecee09 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4026,7 +4026,7 @@ "protection_mode": { "title": "Warning: Protection mode is disabled!", "content": "Protection mode on this add-on is disabled! This gives the add-on full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this add-on.", - "enable": "Enable Protection mode" + "enable": "[%key:ui::common::enable%]" }, "capability": { "stage": { From a690a1d7bfd84ec98ed17587616a1d688c7603b1 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 16 Oct 2021 05:41:23 -0700 Subject: [PATCH 037/115] ABC automation types + use MWC (#10287) --- .../action/ha-automation-action-row.ts | 53 ++++++++++--------- .../types/ha-automation-action-delay.ts | 3 ++ .../ha-automation-condition-editor.ts | 53 ++++++++++--------- .../trigger/ha-automation-trigger-row.ts | 53 ++++++++++--------- 4 files changed, 90 insertions(+), 72 deletions(-) diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts index 6e1f316a82..23313c87aa 100644 --- a/src/panels/config/automation/action/ha-automation-action-row.ts +++ b/src/panels/config/automation/action/ha-automation-action-row.ts @@ -1,15 +1,16 @@ import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiArrowDown, mdiArrowUp, mdiDotsVertical } from "@mdi/js"; -import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-listbox/paper-listbox"; -import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox"; +import "@material/mwc-select"; +import type { Select } from "@material/mwc-select"; import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; import { customElement, property, query, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../common/dom/fire_event"; +import { stringCompare } from "../../../../common/string/compare"; import { handleStructError } from "../../../../common/structs/handle-errors"; +import { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-button-menu"; import "../../../../components/ha-card"; import "../../../../components/ha-alert"; @@ -99,6 +100,19 @@ export default class HaAutomationActionRow extends LitElement { @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; + private _processedTypes = memoizeOne( + (localize: LocalizeFunc): [string, string][] => + OPTIONS.map( + (action) => + [ + action, + localize( + `ui.panel.config.automation.editor.actions.type.${action}.label` + ), + ] as [string, string] + ).sort((a, b) => stringCompare(a[1], b[1])) + ); + protected updated(changedProperties: PropertyValues) { if (!changedProperties.has("action")) { return; @@ -211,28 +225,20 @@ export default class HaAutomationActionRow extends LitElement { > ` : html` - - - ${OPTIONS.map( - (opt) => html` - - ${this.hass.localize( - `ui.panel.config.automation.editor.actions.type.${opt}.label` - )} - - ` - )} - - + ${this._processedTypes(this.hass.localize).map( + ([opt, label]) => html` + ${label} + ` + )} + +
${dynamicElement(`ha-automation-action-${type}`, { hass: this.hass, @@ -292,8 +298,7 @@ export default class HaAutomationActionRow extends LitElement { } private _typeChanged(ev: CustomEvent) { - const type = ((ev.target as PaperListboxElement)?.selectedItem as any) - ?.action; + const type = (ev.target as Select).value; if (!type) { return; diff --git a/src/panels/config/automation/action/types/ha-automation-action-delay.ts b/src/panels/config/automation/action/types/ha-automation-action-delay.ts index e03a533be6..488494e65e 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-delay.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-delay.ts @@ -40,6 +40,9 @@ export class HaDelayAction extends LitElement implements ActionElement { protected render() { return html` + OPTIONS.map( + (condition) => + [ + condition, + localize( + `ui.panel.config.automation.editor.conditions.type.${condition}.label` + ), + ] as [string, string] + ).sort((a, b) => stringCompare(a[1], b[1])) + ); + protected render() { const selected = OPTIONS.indexOf(this.condition.condition); const yamlMode = this.yamlMode || selected === -1; @@ -71,28 +85,20 @@ export default class HaAutomationConditionEditor extends LitElement { > ` : html` - - - ${OPTIONS.map( - (opt) => html` - - ${this.hass.localize( - `ui.panel.config.automation.editor.conditions.type.${opt}.label` - )} - - ` - )} - - + ${this._processedTypes(this.hass.localize).map( + ([opt, label]) => html` + ${label} + ` + )} + +
${dynamicElement( `ha-automation-condition-${this.condition.condition}`, @@ -104,8 +110,7 @@ export default class HaAutomationConditionEditor extends LitElement { } private _typeChanged(ev: CustomEvent) { - const type = ((ev.target as PaperListboxElement)?.selectedItem as any) - ?.condition; + const type = (ev.target as Select).value; if (!type) { return; diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index f5d9125699..51487ee054 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -1,15 +1,16 @@ import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiDotsVertical } from "@mdi/js"; -import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-listbox/paper-listbox"; -import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox"; +import "@material/mwc-select"; +import type { Select } from "@material/mwc-select"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../common/dom/fire_event"; +import { stringCompare } from "../../../../common/string/compare"; import { handleStructError } from "../../../../common/structs/handle-errors"; +import { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-button-menu"; import "../../../../components/ha-card"; import "../../../../components/ha-alert"; @@ -86,6 +87,19 @@ export default class HaAutomationTriggerRow extends LitElement { @state() private _yamlMode = false; + private _processedTypes = memoizeOne( + (localize: LocalizeFunc): [string, string][] => + OPTIONS.map( + (action) => + [ + action, + localize( + `ui.panel.config.automation.editor.triggers.type.${action}.label` + ), + ] as [string, string] + ).sort((a, b) => stringCompare(a[1], b[1])) + ); + protected render() { const selected = OPTIONS.indexOf(this.trigger.platform); const yamlMode = this._yamlMode || selected === -1; @@ -160,28 +174,20 @@ export default class HaAutomationTriggerRow extends LitElement { > ` : html` - - - ${OPTIONS.map( - (opt) => html` - - ${this.hass.localize( - `ui.panel.config.automation.editor.triggers.type.${opt}.label` - )} - - ` - )} - - + ${this._processedTypes(this.hass.localize).map( + ([opt, label]) => html` + ${label} + ` + )} + + Date: Sat, 16 Oct 2021 14:43:03 +0200 Subject: [PATCH 038/115] Add "capitalize" option to `hui-timestamp-display` (#10280) --- src/components/entity/state-info.ts | 2 ++ src/panels/lovelace/cards/hui-glance-card.ts | 1 + src/panels/lovelace/components/hui-timestamp-display.ts | 7 +++++++ src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts | 1 + src/panels/lovelace/special-rows/hui-attribute-row.ts | 1 + src/state-summary/state-card-display.ts | 1 + 6 files changed, 13 insertions(+) diff --git a/src/components/entity/state-info.ts b/src/components/entity/state-info.ts index cbc7b1c0f9..01f95f88bb 100644 --- a/src/components/entity/state-info.ts +++ b/src/components/entity/state-info.ts @@ -53,6 +53,7 @@ class StateInfo extends LitElement {
@@ -64,6 +65,7 @@ class StateInfo extends LitElement {
diff --git a/src/panels/lovelace/cards/hui-glance-card.ts b/src/panels/lovelace/cards/hui-glance-card.ts index fd1528c329..445bd5ff7a 100644 --- a/src/panels/lovelace/cards/hui-glance-card.ts +++ b/src/panels/lovelace/cards/hui-glance-card.ts @@ -321,6 +321,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard { .hass=${this.hass} .ts=${new Date(stateObj.state)} .format=${entityConf.format} + capitalize > ` : entityConf.show_last_changed diff --git a/src/panels/lovelace/components/hui-timestamp-display.ts b/src/panels/lovelace/components/hui-timestamp-display.ts index 211ff97268..2ffbba65ce 100644 --- a/src/panels/lovelace/components/hui-timestamp-display.ts +++ b/src/panels/lovelace/components/hui-timestamp-display.ts @@ -4,6 +4,7 @@ import { formatDate } from "../../../common/datetime/format_date"; import { formatDateTime } from "../../../common/datetime/format_date_time"; import { formatTime } from "../../../common/datetime/format_time"; import { relativeTime } from "../../../common/datetime/relative_time"; +import { capitalizeFirstLetter } from "../../../common/string/capitalize-first-letter"; import { FrontendLocaleData } from "../../../data/translation"; import { HomeAssistant } from "../../../types"; import { TimestampRenderingFormat } from "./types"; @@ -25,6 +26,8 @@ class HuiTimestampDisplay extends LitElement { @property() public format?: TimestampRenderingFormat; + @property({ type: Boolean }) public capitalize = false; + @state() private _relative?: string; private _connected?: boolean; @@ -105,6 +108,10 @@ class HuiTimestampDisplay extends LitElement { this._format === "relative" ? relativeTime(this.ts, this.hass!.locale) : relativeTime(new Date(), this.hass!.locale, this.ts, false); + + this._relative = this.capitalize + ? capitalizeFirstLetter(this._relative) + : this._relative; } } } diff --git a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts index cf599ba375..ff0a6f6584 100644 --- a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts @@ -77,6 +77,7 @@ class HuiSensorEntityRow extends LitElement implements LovelaceRow { .hass=${this.hass} .ts=${new Date(stateObj.state)} .format=${this._config.format} + capitalize > ` : computeStateDisplay( diff --git a/src/panels/lovelace/special-rows/hui-attribute-row.ts b/src/panels/lovelace/special-rows/hui-attribute-row.ts index 540c7bf1ef..99e4a57907 100644 --- a/src/panels/lovelace/special-rows/hui-attribute-row.ts +++ b/src/panels/lovelace/special-rows/hui-attribute-row.ts @@ -70,6 +70,7 @@ class HuiAttributeRow extends LitElement implements LovelaceRow { .hass=${this.hass} .ts=${date} .format=${this._config.format} + capitalize >` : typeof attribute === "number" ? formatNumber(attribute, this.hass.locale) diff --git a/src/state-summary/state-card-display.ts b/src/state-summary/state-card-display.ts index 7bd0e49c6c..1e8a856975 100755 --- a/src/state-summary/state-card-display.ts +++ b/src/state-summary/state-card-display.ts @@ -47,6 +47,7 @@ export class StateCardDisplay extends LitElement { .hass=${this.hass} .ts=${new Date(this.stateObj.state)} format="datetime" + capitalize >` : computeStateDisplay( this.hass!.localize, From 588f5bd6b7ed658232cac4f110b1a1400195b8fb Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Sat, 16 Oct 2021 14:49:57 +0200 Subject: [PATCH 039/115] Add additional binary device classes to inversion list (#10152) --- .../chart/state-history-chart-timeline.ts | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/components/chart/state-history-chart-timeline.ts b/src/components/chart/state-history-chart-timeline.ts index 4dd857bcfe..85de3ea9f7 100644 --- a/src/components/chart/state-history-chart-timeline.ts +++ b/src/components/chart/state-history-chart-timeline.ts @@ -12,22 +12,19 @@ import { HomeAssistant } from "../../types"; import "./ha-chart-base"; import type { TimeLineData } from "./timeline-chart/const"; -/** Binary sensor device classes for which the static colors for on/off need to be inverted. - * List the ones were "off" = good or normal state = should be rendered "green". +/** Binary sensor device classes for which the static colors for on/off are NOT inverted. + * List the ones were "on" = good or normal state => should be rendered "green". + * Note: It is now a "not inverted" list (compared to the past) since we now have more inverted ones. */ -const BINARY_SENSOR_DEVICE_CLASS_COLOR_INVERTED = new Set([ - "battery", - "door", - "garage_door", - "gas", - "lock", - "motion", - "opening", - "problem", - "safety", - "smoke", - "tamper", - "window", +const BINARY_SENSOR_DEVICE_CLASS_COLOR_NOT_INVERTED = new Set([ + "battery_charging", + "connectivity", + "light", + "moving", + "plug", + "power", + "presence", + "update", ]); const STATIC_STATE_COLORS = new Set([ @@ -48,7 +45,7 @@ const invertOnOff = (entityState?: HassEntity) => entityState && computeDomain(entityState.entity_id) === "binary_sensor" && "device_class" in entityState.attributes && - BINARY_SENSOR_DEVICE_CLASS_COLOR_INVERTED.has( + !BINARY_SENSOR_DEVICE_CLASS_COLOR_NOT_INVERTED.has( entityState.attributes.device_class! ); From 816d5ee594b9c1b8680d7cc86ff75888907e447a Mon Sep 17 00:00:00 2001 From: Kyle Niewiada Date: Sat, 16 Oct 2021 11:09:00 -0400 Subject: [PATCH 040/115] Fix energy onboarding `add_solar_production` button (#10275) (#10286) --- .../energy/cards/energy-setup-wizard-card.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/panels/energy/cards/energy-setup-wizard-card.ts b/src/panels/energy/cards/energy-setup-wizard-card.ts index 248a80c10d..57a1ee52e7 100644 --- a/src/panels/energy/cards/energy-setup-wizard-card.ts +++ b/src/panels/energy/cards/energy-setup-wizard-card.ts @@ -1,7 +1,12 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; -import { EnergyPreferences, saveEnergyPreferences } from "../../../data/energy"; +import { + EnergyInfo, + EnergyPreferences, + getEnergyInfo, + saveEnergyPreferences, +} from "../../../data/energy"; import { LovelaceCardConfig } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { LovelaceCard, Lovelace } from "../../lovelace/types"; @@ -20,6 +25,8 @@ export class EnergySetupWizard extends LitElement implements LovelaceCard { @property({ attribute: false }) public lovelace?: Lovelace; + @state() private _info?: EnergyInfo; + @state() private _step = 0; @state() private _preferences: EnergyPreferences = { @@ -39,6 +46,7 @@ export class EnergySetupWizard extends LitElement implements LovelaceCard { protected firstUpdated() { this.hass.loadFragmentTranslation("config"); + this._fetchconfig(); } protected render(): TemplateResult { @@ -54,6 +62,7 @@ export class EnergySetupWizard extends LitElement implements LovelaceCard { ? html`` : this._step === 2 @@ -90,6 +99,10 @@ export class EnergySetupWizard extends LitElement implements LovelaceCard { `; } + private async _fetchconfig() { + this._info = await getEnergyInfo(this.hass); + } + private _prefsChanged(ev: CustomEvent) { this._preferences = ev.detail.value; } From ec47e320d2aecdb604e5eeff1c6f2c2c65da8522 Mon Sep 17 00:00:00 2001 From: MartinT <44962077+MartinTuroci@users.noreply.github.com> Date: Sat, 16 Oct 2021 17:30:48 +0200 Subject: [PATCH 041/115] Unify default dashboard name (#10254) Co-authored-by: Bram Kragten --- src/panels/profile/ha-pick-dashboard-row.ts | 6 +++++- src/translations/en.json | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/panels/profile/ha-pick-dashboard-row.ts b/src/panels/profile/ha-pick-dashboard-row.ts index 482ce1969b..544c7296cc 100644 --- a/src/panels/profile/ha-pick-dashboard-row.ts +++ b/src/panels/profile/ha-pick-dashboard-row.ts @@ -43,7 +43,11 @@ class HaPickDashboardRow extends LitElement { @iron-select=${this._dashboardChanged} attr-for-selected="url-path" > - default + ${this.hass.localize( + "ui.panel.profile.dashboard.default_dashboard_label" + )} ${this._dashboards.map((dashboard) => { if (!this.hass.user!.is_admin && dashboard.require_admin) { return ""; diff --git a/src/translations/en.json b/src/translations/en.json index 30caecee09..079233c5c5 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1288,7 +1288,7 @@ "confirm_delete_title": "Delete {dashboard_title}?", "confirm_delete_text": "Your dashboard will be permanently deleted.", "cant_edit_yaml": "Dashboards defined in YAML cannot be edited from the UI. Change them in configuration.yaml.", - "cant_edit_default": "The standard Lovelace dashboard cannot be edited from the UI. You can hide it by setting another dashboard as default.", + "cant_edit_default": "The default Lovelace dashboard, Overview, cannot be edited from the UI. You can hide it by setting another dashboard as default.", "detail": { "edit_dashboard": "Edit dashboard", "new_dashboard": "Add new dashboard", @@ -3592,7 +3592,8 @@ "dashboard": { "header": "Dashboard", "description": "Pick a default dashboard for this device.", - "dropdown_label": "Dashboard" + "dropdown_label": "Dashboard", + "default_dashboard_label": "Overview (default)" }, "change_password": { "header": "Change Password", From 93f64de8750d0765f5c43d5a27733aa28815ea0b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sat, 16 Oct 2021 23:03:26 +0200 Subject: [PATCH 042/115] Fix icon buttons in Safari (#10293) --- src/components/ha-icon-button.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/ha-icon-button.ts b/src/components/ha-icon-button.ts index 98a0b68e62..d4f9ce8ba7 100644 --- a/src/components/ha-icon-button.ts +++ b/src/components/ha-icon-button.ts @@ -28,8 +28,9 @@ export class HaIconButton extends LitElement { .title=${this.hideTitle ? "" : this.label} .disabled=${this.disabled} > - ${this.path ? html`` : ""} - + ${this.path + ? html`` + : html``} `; } @@ -47,9 +48,6 @@ export class HaIconButton extends LitElement { --mdc-theme-on-primary: currentColor; --mdc-theme-text-disabled-on-light: var(--disabled-text-color); } - ha-icon { - --ha-icon-display: inline; - } `; } } From f0062b1e670407deb22fb5daf2f31be5e8066e1c Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 18 Oct 2021 01:39:13 +0200 Subject: [PATCH 043/115] Only render badge value if there is no icon and no image (#10310) --- src/components/entity/ha-state-label-badge.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/entity/ha-state-label-badge.ts b/src/components/entity/ha-state-label-badge.ts index fa84be3fc2..8196d2bdd5 100644 --- a/src/components/entity/ha-state-label-badge.ts +++ b/src/components/entity/ha-state-label-badge.ts @@ -69,9 +69,13 @@ export class HaStateLabelBadge extends LitElement { `; } + // Rendering priority inside badge: + // 1. Icon directly defined in badge config + // 2. Image directly defined in badge config + // 3. Image taken from entity picture + // 4. Icon determined via entity state + // 5. Value string as fallback const domain = computeStateDomain(entityState); - - const value = this._computeValue(domain, entityState); const icon = this.icon ? this.icon : this._computeIcon(domain, entityState); const image = this.icon ? "" @@ -79,6 +83,8 @@ export class HaStateLabelBadge extends LitElement { ? this.image : entityState.attributes.entity_picture_local || entityState.attributes.entity_picture; + const value = + !image && !icon ? this._computeValue(domain, entityState) : undefined; return html` ${!image && icon ? html`` : ""} - ${value && (this.icon || !this.image) + ${value && !icon && !image ? html` 4 ? "big" : ""} >${value}` From a8ff98b80897cfdc3ada93d838ef7f0dbe23a97e Mon Sep 17 00:00:00 2001 From: Michael Irigoyen Date: Mon, 18 Oct 2021 05:41:31 -0500 Subject: [PATCH 044/115] Update MDI to v6.3.95 (#10313) --- package.json | 4 ++-- yarn.lock | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 09f72733ae..5711fd6bf8 100644 --- a/package.json +++ b/package.json @@ -67,8 +67,8 @@ "@material/mwc-tab-bar": "0.25.2", "@material/mwc-textfield": "0.25.2", "@material/top-app-bar": "14.0.0-canary.353ca7e9f.0", - "@mdi/js": "6.2.95", - "@mdi/svg": "6.2.95", + "@mdi/js": "6.3.95", + "@mdi/svg": "6.3.95", "@polymer/app-layout": "^3.1.0", "@polymer/iron-flex-layout": "^3.0.1", "@polymer/iron-icon": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index 4ec7ec8975..2ce6416c9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2898,17 +2898,17 @@ __metadata: languageName: node linkType: hard -"@mdi/js@npm:6.2.95": - version: 6.2.95 - resolution: "@mdi/js@npm:6.2.95" - checksum: 85f33d0bbb0665ef048dbcae8759eb7b17db35594f1e471c71946fb36ea8416d3c21b3a1013bb587c7293f2c84d97af6ed791a6904625abdae7ec96a75569e5e +"@mdi/js@npm:6.3.95": + version: 6.3.95 + resolution: "@mdi/js@npm:6.3.95" + checksum: e0ecdf2a2b1b46ead42266cc9dcc29c08495c8d3af53314bf28e0c2b637d528e9e1d16e523c1ab678b78c8930a7d29ee91a43f35f15a4ae5aa00244bc836da54 languageName: node linkType: hard -"@mdi/svg@npm:6.2.95": - version: 6.2.95 - resolution: "@mdi/svg@npm:6.2.95" - checksum: c2f14e8b62ae4c31da84af44d13f02b050c9a7759e20f08c9088996b2cafea5ff372c89795d57e976d8a693034964dad8f65bc75eea02834d1d8784e2e22627e +"@mdi/svg@npm:6.3.95": + version: 6.3.95 + resolution: "@mdi/svg@npm:6.3.95" + checksum: ed8d8042fbac21ca2011c799ba57767502cce820c15cd99d5dbacd89275d0350bd9c89557c7301e42986c85e80975c6a72d96f92c4efdf667ddb3d730904225b languageName: node linkType: hard @@ -9100,8 +9100,8 @@ fsevents@^1.2.7: "@material/mwc-tab-bar": 0.25.2 "@material/mwc-textfield": 0.25.2 "@material/top-app-bar": 14.0.0-canary.353ca7e9f.0 - "@mdi/js": 6.2.95 - "@mdi/svg": 6.2.95 + "@mdi/js": 6.3.95 + "@mdi/svg": 6.3.95 "@open-wc/dev-server-hmr": ^0.0.2 "@polymer/app-layout": ^3.1.0 "@polymer/iron-flex-layout": ^3.0.1 From 84533b88432104ec149bd256e1872a7bccbe5363 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 18 Oct 2021 03:42:34 -0700 Subject: [PATCH 045/115] Rename `stream_type` to `frontend_stream_type` (#10298) --- src/components/ha-camera-stream.ts | 8 ++++---- src/data/camera.ts | 2 +- src/dialogs/more-info/controls/more-info-camera.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/ha-camera-stream.ts b/src/components/ha-camera-stream.ts index c19ee6d71f..1a73c3c673 100644 --- a/src/components/ha-camera-stream.ts +++ b/src/components/ha-camera-stream.ts @@ -52,7 +52,7 @@ class HaCameraStream extends LitElement { this.stateObj && (changedProps.get("stateObj") as CameraEntity | undefined)?.entity_id !== this.stateObj.entity_id && - this.stateObj!.attributes.stream_type === STREAM_TYPE_HLS + this.stateObj!.attributes.frontend_stream_type === STREAM_TYPE_HLS ) { this._forceMJPEG = undefined; this._url = undefined; @@ -84,7 +84,7 @@ class HaCameraStream extends LitElement { .alt=${`Preview of the ${computeStateName(this.stateObj)} camera.`} />`; } - if (this.stateObj.attributes.stream_type === STREAM_TYPE_HLS && true) { + if (this.stateObj.attributes.frontend_stream_type === STREAM_TYPE_HLS) { return this._url ? html` ` : html``; } - if (this.stateObj.attributes.stream_type === STREAM_TYPE_WEB_RTC) { + if (this.stateObj.attributes.frontend_stream_type === STREAM_TYPE_WEB_RTC) { return html` Date: Mon, 18 Oct 2021 14:11:41 +0200 Subject: [PATCH 046/115] Fix translation key energy distribution solar (#10316) --- .../lovelace/cards/energy/hui-energy-distribution-card.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts index 83835855b6..7c2cf2c2d2 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts @@ -296,7 +296,7 @@ class HuiEnergyDistrubutionCard ? html`
${this.hass.localize( - "ui.panel.lovelace.cards.energy.distribution.solar" + "ui.panel.lovelace.cards.energy.energy_distribution.solar" )}
From bb2fe650ace4692a984dad1f3a30044d6a5796a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 18 Oct 2021 22:04:50 +0200 Subject: [PATCH 047/115] Prevent mwc-list-item from opening up quick-bar (#10317) --- src/state/quick-bar-mixin.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/state/quick-bar-mixin.ts b/src/state/quick-bar-mixin.ts index 445a9e3ee5..a0e98b327c 100644 --- a/src/state/quick-bar-mixin.ts +++ b/src/state/quick-bar-mixin.ts @@ -58,6 +58,10 @@ export default >(superClass: T) => return false; } + if (el.parentElement.tagName === "MWC-SELECT") { + return false; + } + if (el.tagName !== "INPUT") { return true; } From d5b98d306d7690784c4909ac1725c56965379718 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 18 Oct 2021 13:05:38 -0700 Subject: [PATCH 048/115] Remove element resize hook (#10300) --- src/components/ha-hls-player.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/components/ha-hls-player.ts b/src/components/ha-hls-player.ts index d621e79d80..7f10361583 100644 --- a/src/components/ha-hls-player.ts +++ b/src/components/ha-hls-player.ts @@ -8,7 +8,6 @@ import { TemplateResult, } from "lit"; import { customElement, property, query } from "lit/decorators"; -import { fireEvent } from "../common/dom/fire_event"; import { nextRender } from "../common/util/render-status"; import { getExternalConfig } from "../external_app/external_config"; import type { HomeAssistant } from "../types"; @@ -65,7 +64,6 @@ class HaHLSPlayer extends LitElement { .muted=${this.muted} ?playsinline=${this.playsInline} ?controls=${this.controls} - @loadeddata=${this._elementResized} > `; } @@ -206,10 +204,6 @@ class HaHLSPlayer extends LitElement { }); } - private _elementResized() { - fireEvent(this, "iron-resize"); - } - private _cleanUp() { if (this._hlsPolyfillInstance) { this._hlsPolyfillInstance.destroy(); From a8486eda9f7bfd90c21c372dc9b3feb3836bbba5 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 18 Oct 2021 13:06:42 -0700 Subject: [PATCH 049/115] Improve WebRTC stream error handling and cleanup (#10302) --- src/components/ha-web-rtc-player.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/components/ha-web-rtc-player.ts b/src/components/ha-web-rtc-player.ts index 99faf1953f..b31b2c0a7d 100644 --- a/src/components/ha-web-rtc-player.ts +++ b/src/components/ha-web-rtc-player.ts @@ -39,6 +39,10 @@ class HaWebRtcPlayer extends LitElement { // don't cache this, as we remove it on disconnects @query("#remote-stream") private _videoEl!: HTMLVideoElement; + private _peerConnection?: RTCPeerConnection; + + private _remoteStream?: MediaStream; + protected render(): TemplateResult { if (this._error) { return html`${this._error}`; @@ -71,6 +75,7 @@ class HaWebRtcPlayer extends LitElement { private async _startWebRtc(): Promise { this._error = undefined; + const peerConnection = new RTCPeerConnection(); // Some cameras (such as nest) require a data channel to establish a stream // however, not used by any integrations. @@ -93,6 +98,7 @@ class HaWebRtcPlayer extends LitElement { ); } catch (err: any) { this._error = "Failed to start WebRTC stream: " + err.message; + peerConnection.close(); return; } @@ -102,21 +108,39 @@ class HaWebRtcPlayer extends LitElement { remoteStream.addTrack(event.track); this._videoEl.srcObject = remoteStream; }); + this._remoteStream = remoteStream; // Initiate the stream with the remote device const remoteDesc = new RTCSessionDescription({ type: "answer", sdp: webRtcAnswer.answer, }); - await peerConnection.setRemoteDescription(remoteDesc); + try { + await peerConnection.setRemoteDescription(remoteDesc); + } catch (err: any) { + this._error = "Failed to connect WebRTC stream: " + err.message; + peerConnection.close(); + return; + } + this._peerConnection = peerConnection; } private _cleanUp() { + if (this._remoteStream) { + this._remoteStream.getTracks().forEach((track) => { + track.stop(); + }); + this._remoteStream = undefined; + } if (this._videoEl) { const videoEl = this._videoEl; videoEl.removeAttribute("src"); videoEl.load(); } + if (this._peerConnection) { + this._peerConnection.close(); + this._peerConnection = undefined; + } } static get styles(): CSSResultGroup { From f1cb21e7fcc22ce680e147c61579be33903745fc Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 18 Oct 2021 22:07:16 +0200 Subject: [PATCH 050/115] Fix formatting of weather extrema temperatures (#10306) --- src/data/weather.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/data/weather.ts b/src/data/weather.ts index d37175d727..f3a6ef5346 100644 --- a/src/data/weather.ts +++ b/src/data/weather.ts @@ -245,17 +245,9 @@ const getWeatherExtrema = ( const unit = getWeatherUnit(hass!, "temperature"); return html` - ${tempHigh - ? ` - ${tempHigh} ${unit} - ` - : ""} + ${tempHigh ? `${formatNumber(tempHigh, hass.locale)} ${unit}` : ""} ${tempLow && tempHigh ? " / " : ""} - ${tempLow - ? ` - ${tempLow} ${unit} - ` - : ""} + ${tempLow ? `${formatNumber(tempLow, hass.locale)} ${unit}` : ""} `; }; From bdb3c04037c0403997acbf37362ed9d19b9583a7 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 18 Oct 2021 22:09:21 +0200 Subject: [PATCH 051/115] Ensure current active dark modes gets used for manually set themes (#10307) --- hassio/src/hassio-main.ts | 6 -- src/common/dom/apply_themes_on_element.ts | 99 ++++++++++++----------- src/layouts/supervisor-error-screen.ts | 6 -- 3 files changed, 53 insertions(+), 58 deletions(-) diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index 93181aa106..8ded32bbf0 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -113,12 +113,6 @@ export class HassioMain extends SupervisorBaseElement { : this.hass.themes.default_theme); themeSettings = this.hass.selectedTheme; - if (themeSettings?.dark === undefined) { - themeSettings = { - ...this.hass.selectedTheme, - dark: this.hass.themes.darkMode, - }; - } } else { themeName = (this.hass.selectedTheme as unknown as string) || diff --git a/src/common/dom/apply_themes_on_element.ts b/src/common/dom/apply_themes_on_element.ts index 721863e7f3..fca6e2262a 100644 --- a/src/common/dom/apply_themes_on_element.ts +++ b/src/common/dom/apply_themes_on_element.ts @@ -36,55 +36,62 @@ export const applyThemesOnElement = ( let cacheKey = selectedTheme; let themeRules: Partial = {}; - if (themeSettings) { - if (themeSettings.dark) { - cacheKey = `${cacheKey}__dark`; - themeRules = { ...darkStyles }; + // If there is no explicitly desired dark mode provided, we automatically + // use the active one from hass.themes. + if (!themeSettings || themeSettings?.dark === undefined) { + themeSettings = { + ...themeSettings, + dark: themes.darkMode, + }; + } + + if (themeSettings.dark) { + cacheKey = `${cacheKey}__dark`; + themeRules = { ...darkStyles }; + } + + if (selectedTheme === "default") { + // Determine the primary and accent colors from the current settings. + // Fallbacks are implicitly the HA default blue and orange or the + // derived "darkStyles" values, depending on the light vs dark mode. + const primaryColor = themeSettings.primaryColor; + const accentColor = themeSettings.accentColor; + + if (themeSettings.dark && primaryColor) { + themeRules["app-header-background-color"] = hexBlend( + primaryColor, + "#121212", + 8 + ); } - if (selectedTheme === "default") { - // Determine the primary and accent colors from the current settings. - // Fallbacks are implicitly the HA default blue and orange or the - // derived "darkStyles" values, depending on the light vs dark mode. - const primaryColor = themeSettings.primaryColor; - const accentColor = themeSettings.accentColor; + if (primaryColor) { + cacheKey = `${cacheKey}__primary_${primaryColor}`; + const rgbPrimaryColor = hex2rgb(primaryColor); + const labPrimaryColor = rgb2lab(rgbPrimaryColor); + themeRules["primary-color"] = primaryColor; + const rgbLightPrimaryColor = lab2rgb(labBrighten(labPrimaryColor)); + themeRules["light-primary-color"] = rgb2hex(rgbLightPrimaryColor); + themeRules["dark-primary-color"] = lab2hex(labDarken(labPrimaryColor)); + themeRules["text-primary-color"] = + rgbContrast(rgbPrimaryColor, [33, 33, 33]) < 6 ? "#fff" : "#212121"; + themeRules["text-light-primary-color"] = + rgbContrast(rgbLightPrimaryColor, [33, 33, 33]) < 6 + ? "#fff" + : "#212121"; + themeRules["state-icon-color"] = themeRules["dark-primary-color"]; + } + if (accentColor) { + cacheKey = `${cacheKey}__accent_${accentColor}`; + themeRules["accent-color"] = accentColor; + const rgbAccentColor = hex2rgb(accentColor); + themeRules["text-accent-color"] = + rgbContrast(rgbAccentColor, [33, 33, 33]) < 6 ? "#fff" : "#212121"; + } - if (themeSettings.dark && primaryColor) { - themeRules["app-header-background-color"] = hexBlend( - primaryColor, - "#121212", - 8 - ); - } - - if (primaryColor) { - cacheKey = `${cacheKey}__primary_${primaryColor}`; - const rgbPrimaryColor = hex2rgb(primaryColor); - const labPrimaryColor = rgb2lab(rgbPrimaryColor); - themeRules["primary-color"] = primaryColor; - const rgbLightPrimaryColor = lab2rgb(labBrighten(labPrimaryColor)); - themeRules["light-primary-color"] = rgb2hex(rgbLightPrimaryColor); - themeRules["dark-primary-color"] = lab2hex(labDarken(labPrimaryColor)); - themeRules["text-primary-color"] = - rgbContrast(rgbPrimaryColor, [33, 33, 33]) < 6 ? "#fff" : "#212121"; - themeRules["text-light-primary-color"] = - rgbContrast(rgbLightPrimaryColor, [33, 33, 33]) < 6 - ? "#fff" - : "#212121"; - themeRules["state-icon-color"] = themeRules["dark-primary-color"]; - } - if (accentColor) { - cacheKey = `${cacheKey}__accent_${accentColor}`; - themeRules["accent-color"] = accentColor; - const rgbAccentColor = hex2rgb(accentColor); - themeRules["text-accent-color"] = - rgbContrast(rgbAccentColor, [33, 33, 33]) < 6 ? "#fff" : "#212121"; - } - - // Nothing was changed - if (element._themes?.cacheKey === cacheKey) { - return; - } + // Nothing was changed + if (element._themes?.cacheKey === cacheKey) { + return; } } diff --git a/src/layouts/supervisor-error-screen.ts b/src/layouts/supervisor-error-screen.ts index f59ae95538..cc9a9be2ad 100644 --- a/src/layouts/supervisor-error-screen.ts +++ b/src/layouts/supervisor-error-screen.ts @@ -91,12 +91,6 @@ class SupervisorErrorScreen extends LitElement { : this.hass.themes.default_theme); themeSettings = this.hass.selectedTheme; - if (themeName === "default" && themeSettings?.dark === undefined) { - themeSettings = { - ...this.hass.selectedTheme, - dark: this.hass.themes.darkMode, - }; - } } else { themeName = (this.hass.selectedTheme as unknown as string) || From 403c0422352e0af452850ba467b74c9c276a3e1d Mon Sep 17 00:00:00 2001 From: MartinT <44962077+MartinTuroci@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:27:00 +0200 Subject: [PATCH 052/115] Add views dropdown and footer actions to the "move to view" dialog (#10172) Co-authored-by: Bram Kragten --- .../lovelace/components/hui-views-list.ts | 93 ------------------- .../select-view/hui-dialog-select-view.ts | 67 +++++++++++-- src/translations/en.json | 4 +- 3 files changed, 60 insertions(+), 104 deletions(-) delete mode 100644 src/panels/lovelace/components/hui-views-list.ts diff --git a/src/panels/lovelace/components/hui-views-list.ts b/src/panels/lovelace/components/hui-views-list.ts deleted file mode 100644 index a04e3f0cba..0000000000 --- a/src/panels/lovelace/components/hui-views-list.ts +++ /dev/null @@ -1,93 +0,0 @@ -import "@polymer/paper-item/paper-icon-item"; -import "@polymer/paper-listbox/paper-listbox"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators"; -import { fireEvent } from "../../../common/dom/fire_event"; -import { toggleAttribute } from "../../../common/dom/toggle_attribute"; -import "../../../components/ha-icon"; -import { LovelaceConfig } from "../../../data/lovelace"; - -declare global { - interface HASSDomEvents { - "view-selected": { - view: number; - }; - } -} - -@customElement("hui-views-list") -class HuiViewsList extends LitElement { - @state() private lovelaceConfig?: LovelaceConfig | undefined; - - @state() private selected?: number | undefined; - - protected render(): TemplateResult { - if (!this.lovelaceConfig) { - return html``; - } - - return html` - - ${this.lovelaceConfig.views.map( - (view, index) => html` - - ${view.icon - ? html` - - ` - : ""} - ${view.title || view.path || "Unnamed view"} - - ` - )} - - `; - } - - protected updated(changedProps) { - super.updated(changedProps); - toggleAttribute( - this, - "hide-icons", - this.lovelaceConfig - ? !this.lovelaceConfig.views.some((view) => view.icon) - : true - ); - } - - private async _handlePickView(ev: Event) { - const view = Number((ev.currentTarget as any).getAttribute("data-index")); - fireEvent(this, "view-selected", { view }); - } - - static get styles(): CSSResultGroup { - return css` - paper-listbox { - padding-top: 0; - } - - paper-listbox ha-icon { - padding: 12px; - color: var(--secondary-text-color); - } - - paper-icon-item { - cursor: pointer; - } - - paper-icon-item[disabled] { - cursor: initial; - } - - :host([hide-icons]) paper-icon-item { - --paper-item-icon-width: 0px; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "hui-views-list": HuiViewsList; - } -} diff --git a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts index 2ea6f32c6b..b29222a70e 100644 --- a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts +++ b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts @@ -1,9 +1,13 @@ +import "@material/mwc-list/mwc-list"; +import "@material/mwc-list/mwc-radio-list-item"; import "@polymer/paper-item/paper-item"; +import "@polymer/paper-listbox/paper-listbox"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/dialog/ha-paper-dialog"; import { createCloseHeading } from "../../../../components/ha-dialog"; +import "../../../../components/ha-icon"; import "../../../../components/ha-paper-dropdown-menu"; import { fetchConfig, @@ -13,9 +17,16 @@ import { } from "../../../../data/lovelace"; import { haStyleDialog } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; -import "../../components/hui-views-list"; import type { SelectViewDialogParams } from "./show-select-view-dialog"; +declare global { + interface HASSDomEvents { + "view-selected": { + view: number; + }; + } +} + @customElement("hui-dialog-select-view") export class HuiDialogSelectView extends LitElement { public hass!: HomeAssistant; @@ -28,6 +39,8 @@ export class HuiDialogSelectView extends LitElement { @state() private _config?: LovelaceConfig; + @state() private _selectedViewIdx = 0; + public showDialog(params: SelectViewDialogParams): void { this._config = params.lovelaceConfig; this._urlPath = params.urlPath; @@ -50,7 +63,6 @@ export class HuiDialogSelectView extends LitElement { ` : ""} ${this._config - ? html` - ` + ? this._config.views.length > 1 + ? html` + + ${this._config.views.map( + (view, idx) => html` + icon) + ? "icon" + : null} + @click=${this._viewChanged} + .value=${idx.toString()} + .selected=${this._selectedViewIdx === idx} + > + ${view.title} + + + ` + )} + + ` + : "" : html`
No config found.
`} + + ${this.hass!.localize("ui.common.cancel")} + + + ${this.hass!.localize("ui.common.move")} +
`; } @@ -118,6 +152,7 @@ export class HuiDialogSelectView extends LitElement { urlPath = null; } this._urlPath = urlPath; + this._selectedViewIdx = 0; try { this._config = await fetchConfig(this.hass.connection, urlPath, false); } catch (err: any) { @@ -125,9 +160,21 @@ export class HuiDialogSelectView extends LitElement { } } - private _selectView(e: CustomEvent): void { - const view: number = e.detail.view; - this._params!.viewSelectedCallback(this._urlPath!, this._config!, view); + private _viewChanged(e) { + const view = Number(e.target.value); + + if (!isNaN(view)) { + this._selectedViewIdx = view; + } + } + + private _selectView(): void { + fireEvent(this, "view-selected", { view: this._selectedViewIdx }); + this._params!.viewSelectedCallback( + this._urlPath!, + this._config!, + this._selectedViewIdx + ); this.closeDialog(); } diff --git a/src/translations/en.json b/src/translations/en.json index 079233c5c5..70335e9823 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -288,6 +288,7 @@ "next": "Next", "back": "Back", "undo": "Undo", + "move": "Move", "save": "Save", "rename": "Rename", "yes": "Yes", @@ -3174,7 +3175,8 @@ }, "select_view": { "header": "Choose a view", - "dashboard_label": "Dashboard" + "dashboard_label": "Dashboard", + "views_label": "View" }, "suggest_card": { "header": "We created a suggestion for you", From 2770d1f36b94c8e5023add1af436f465627f8d2c Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 18 Oct 2021 22:45:21 +0200 Subject: [PATCH 053/115] Icon Picker (#10161) --- build-scripts/gulp/gen-icons-json.js | 37 ++++- src/components/ha-icon-picker.ts | 142 ++++++++++++++++++ .../entities/entity-registry-settings.ts | 9 +- .../config/helpers/forms/ha-counter-form.ts | 6 +- .../helpers/forms/ha-input_boolean-form.ts | 6 +- .../helpers/forms/ha-input_datetime-form.ts | 6 +- .../helpers/forms/ha-input_number-form.ts | 6 +- .../helpers/forms/ha-input_select-form.ts | 6 +- .../helpers/forms/ha-input_text-form.ts | 6 +- .../config/helpers/forms/ha-timer-form.ts | 6 +- .../dialog-lovelace-dashboard-detail.ts | 6 +- src/panels/config/scene/ha-scene-editor.ts | 6 +- src/panels/config/script/ha-script-editor.ts | 6 +- .../config-elements/hui-button-card-editor.ts | 6 +- .../config-elements/hui-entity-card-editor.ts | 6 +- .../hui-generic-entity-row-editor.ts | 6 +- .../config-elements/hui-light-card-editor.ts | 6 +- .../config-elements/hui-sensor-card-editor.ts | 6 +- .../editor/view-editor/hui-view-editor.ts | 6 +- 19 files changed, 226 insertions(+), 58 deletions(-) create mode 100644 src/components/ha-icon-picker.ts diff --git a/build-scripts/gulp/gen-icons-json.js b/build-scripts/gulp/gen-icons-json.js index 58bb4faaaa..42563d15af 100644 --- a/build-scripts/gulp/gen-icons-json.js +++ b/build-scripts/gulp/gen-icons-json.js @@ -22,17 +22,38 @@ const getMeta = () => { const svg = fs.readFileSync(`${ICON_PATH}/${icon.name}.svg`, { encoding, }); - return { path: svg.match(/ d="([^"]+)"/)[1], name: icon.name }; + return { + path: svg.match(/ d="([^"]+)"/)[1], + name: icon.name, + tags: icon.tags, + }; }); }; const addRemovedMeta = (meta) => { const file = fs.readFileSync(REMOVED_ICONS_PATH, { encoding }); const removed = JSON.parse(file); - const combinedMeta = [...meta, ...removed]; + const removedMeta = removed.map((removeIcon) => ({ + path: removeIcon.path, + name: removeIcon.name, + tags: [], + })); + const combinedMeta = [...meta, ...removedMeta]; return combinedMeta.sort((a, b) => a.name.localeCompare(b.name)); }; +const homeAutomationTag = "Home Automation"; + +const orderMeta = (meta) => { + const homeAutomationMeta = meta.filter((icon) => + icon.tags.includes(homeAutomationTag) + ); + const otherMeta = meta.filter( + (icon) => !icon.tags.includes(homeAutomationTag) + ); + return [...homeAutomationMeta, ...otherMeta]; +}; + const splitBySize = (meta) => { const chunks = []; const CHUNK_SIZE = 50000; @@ -77,8 +98,9 @@ const findDifferentiator = (curString, prevString) => { }; gulp.task("gen-icons-json", (done) => { - const meta = addRemovedMeta(getMeta()); - const split = splitBySize(meta); + const meta = getMeta(); + const metaAndRemoved = addRemovedMeta(meta); + const split = splitBySize(metaAndRemoved); if (!fs.existsSync(OUTPUT_DIR)) { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); @@ -116,5 +138,12 @@ gulp.task("gen-icons-json", (done) => { JSON.stringify({ version: package.version, parts }) ); + const orderedMeta = orderMeta(meta); + + fs.writeFileSync( + path.resolve(OUTPUT_DIR, "iconList.json"), + JSON.stringify(orderedMeta.map((icon) => icon.name)) + ); + done(); }); diff --git a/src/components/ha-icon-picker.ts b/src/components/ha-icon-picker.ts new file mode 100644 index 0000000000..added27c6e --- /dev/null +++ b/src/components/ha-icon-picker.ts @@ -0,0 +1,142 @@ +import "@polymer/paper-input/paper-input"; +import { mdiCheck } from "@mdi/js"; +import { css, html, LitElement, TemplateResult } from "lit"; +import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers"; +import { customElement, property, query } from "lit/decorators"; +import { fireEvent } from "../common/dom/fire_event"; +import { PolymerChangedEvent } from "../polymer-types"; +import "./ha-icon"; +import iconList from "../../build/mdi/iconList.json"; + +const mdiIconList = iconList.map((icon) => `mdi:${icon}`); + +// eslint-disable-next-line lit/prefer-static-styles +const rowRenderer: ComboBoxLitRenderer = (item) => html` + + + + + ${item} + `; + +@customElement("ha-icon-picker") +export class HaIconPicker extends LitElement { + @property() public value?: string; + + @property() public label?: string; + + @property() public placeholder?: string; + + @property({ attribute: "error-message" }) public errorMessage?: string; + + @property({ type: Boolean }) public disabled = false; + + @query("vaadin-combo-box-light", true) private comboBox!: HTMLElement; + + @property({ type: Boolean }) private _opened = false; + + protected render(): TemplateResult { + return html` + + + ${!this._opened && (this._value || this.placeholder) + ? html` + + + ` + : ""} + + + `; + } + + private _openedChanged(ev: PolymerChangedEvent) { + this._opened = ev.detail.value; + } + + private _valueChanged(ev: PolymerChangedEvent) { + this._setValue(ev.detail.value); + } + + private _setValue(value: string) { + this.value = value; + fireEvent( + this, + "value-changed", + { value }, + { + bubbles: false, + composed: false, + } + ); + } + + private _filterChanged(ev: CustomEvent): void { + const filterString = ev.detail.value.toLowerCase(); + const characterCount = filterString.length; + if (characterCount >= 2) { + const filteredItems = mdiIconList.filter((icon) => + icon.toLowerCase().includes(filterString) + ); + if (filteredItems.length > 0) { + (this.comboBox as any).filteredItems = filteredItems; + } else { + (this.comboBox as any).filteredItems = [filterString]; + } + } else { + (this.comboBox as any).filteredItems = []; + } + } + + private get _value() { + return this.value || ""; + } + + static get styles() { + return css` + ha-icon { + position: absolute; + bottom: 2px; + right: 0; + } + `; + } +} diff --git a/src/panels/config/entities/entity-registry-settings.ts b/src/panels/config/entities/entity-registry-settings.ts index b7936933e6..15dacde33d 100644 --- a/src/panels/config/entities/entity-registry-settings.ts +++ b/src/panels/config/entities/entity-registry-settings.ts @@ -15,7 +15,7 @@ import { computeDomain } from "../../../common/entity/compute_domain"; import { domainIcon } from "../../../common/entity/domain_icon"; import "../../../components/ha-area-picker"; import "../../../components/ha-expansion-panel"; -import "../../../components/ha-icon-input"; +import "../../../components/ha-icon-picker"; import "../../../components/ha-switch"; import type { HaSwitch } from "../../../components/ha-switch"; import { @@ -133,7 +133,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { .placeholder=${this.entry.original_name} .disabled=${this._submitting} > - + > - + > - + >
`; } diff --git a/src/panels/config/helpers/forms/ha-input_datetime-form.ts b/src/panels/config/helpers/forms/ha-input_datetime-form.ts index d28277078c..87c6931c8d 100644 --- a/src/panels/config/helpers/forms/ha-input_datetime-form.ts +++ b/src/panels/config/helpers/forms/ha-input_datetime-form.ts @@ -4,7 +4,7 @@ import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/ha-icon-input"; +import "../../../../components/ha-icon-picker"; import { InputDateTime } from "../../../../data/input_datetime"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; @@ -70,14 +70,14 @@ class HaInputDateTimeForm extends LitElement { .invalid=${nameInvalid} dialogInitialFocus > - + >
${this.hass.localize("ui.dialogs.helper_settings.input_datetime.mode")}:
diff --git a/src/panels/config/helpers/forms/ha-input_number-form.ts b/src/panels/config/helpers/forms/ha-input_number-form.ts index a87ea0cde0..b65e5d1ed8 100644 --- a/src/panels/config/helpers/forms/ha-input_number-form.ts +++ b/src/panels/config/helpers/forms/ha-input_number-form.ts @@ -4,7 +4,7 @@ import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/ha-icon-input"; +import "../../../../components/ha-icon-picker"; import { InputNumber } from "../../../../data/input_number"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; @@ -85,14 +85,14 @@ class HaInputNumberForm extends LitElement { .invalid=${nameInvalid} dialogInitialFocus > - + > - + > ${this.hass!.localize( "ui.dialogs.helper_settings.input_select.options" )}: diff --git a/src/panels/config/helpers/forms/ha-input_text-form.ts b/src/panels/config/helpers/forms/ha-input_text-form.ts index 3c951bc8f3..6262913d46 100644 --- a/src/panels/config/helpers/forms/ha-input_text-form.ts +++ b/src/panels/config/helpers/forms/ha-input_text-form.ts @@ -4,7 +4,7 @@ import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/ha-icon-input"; +import "../../../../components/ha-icon-picker"; import { InputText } from "../../../../data/input_text"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; @@ -76,14 +76,14 @@ class HaInputTextForm extends LitElement { .invalid=${nameInvalid} dialogInitialFocus > - + > ${this.hass.userData?.showAdvanced ? html` - + > - + > ${!this._params.dashboard && this.hass.userData?.showAdvanced ? html` - - +
diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 6e7e15d3a2..e6d617990e 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -30,7 +30,7 @@ import "../../../components/ha-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-fab"; import "../../../components/ha-icon-button"; -import "../../../components/ha-icon-input"; +import "../../../components/ha-icon-picker"; import "../../../components/ha-svg-icon"; import "../../../components/ha-yaml-editor"; import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; @@ -213,7 +213,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @change=${this._aliasChanged} > - - + ${!this.scriptEntityId ? html` - + >
diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts index af18dd6edd..51796a5546 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts @@ -5,7 +5,7 @@ import { assert, assign, boolean, object, optional, string } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; import { stateIcon } from "../../../../common/entity/state_icon"; import "../../../../components/entity/ha-entity-attribute-picker"; -import "../../../../components/ha-icon-input"; +import "../../../../components/ha-icon-picker"; import { HomeAssistant } from "../../../../types"; import { EntityCardConfig } from "../../cards/types"; import "../../components/hui-action-editor"; @@ -103,7 +103,7 @@ export class HuiEntityCardEditor .configValue=${"name"} @value-changed=${this._valueChanged} > - + >
- + >
- + >
- + > - + > Date: Tue, 19 Oct 2021 16:38:57 +0800 Subject: [PATCH 054/115] Use maxLiveSyncPlaybackRate in ha-hls-player (#10323) --- src/components/ha-hls-player.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ha-hls-player.ts b/src/components/ha-hls-player.ts index 7f10361583..1db14c07ee 100644 --- a/src/components/ha-hls-player.ts +++ b/src/components/ha-hls-player.ts @@ -189,6 +189,7 @@ class HaHLSPlayer extends LitElement { fragLoadingTimeOut: 30000, manifestLoadingTimeOut: 30000, levelLoadingTimeOut: 30000, + maxLiveSyncPlaybackRate: 2, }); this._hlsPolyfillInstance = hls; hls.attachMedia(videoEl); From 04f586721ffd35235a8109e69f3c3fc68ba71ec6 Mon Sep 17 00:00:00 2001 From: Will Adler Date: Tue, 19 Oct 2021 07:48:59 -0400 Subject: [PATCH 055/115] Revise grid neutrality energy dashboard card, modify energy dashboard presentation to match (#10054) Co-authored-by: Bram Kragten --- .../cards/energy/hui-energy-grid-neutrality-gauge-card.ts | 6 ++---- .../lovelace/cards/energy/hui-energy-usage-graph-card.ts | 7 +------ src/resources/ha-style.ts | 4 ++-- src/resources/styles.ts | 2 +- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts b/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts index 2a900769a9..a033f35548 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts @@ -18,12 +18,10 @@ import { SubscribeMixin } from "../../../../mixins/subscribe-mixin"; import type { HomeAssistant } from "../../../../types"; import type { LovelaceCard } from "../../types"; import type { EnergyGridGaugeCardConfig } from "../types"; -import { severityMap } from "../hui-gauge-card"; const LEVELS: LevelDefinition[] = [ - { level: -1, stroke: severityMap.red }, - { level: -0.2, stroke: severityMap.yellow }, - { level: 0, stroke: severityMap.green }, + { level: -1, stroke: "var(--energy-grid-consumption-color)" }, + { level: 0, stroke: "var(--energy-grid-return-color)" }, ]; @customElement("hui-energy-grid-neutrality-gauge-card") diff --git a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts index 7333762958..cbfb66296d 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts @@ -17,7 +17,6 @@ import { rgb2hex, rgb2lab, } from "../../../../common/color/convert-color"; -import { hexBlend } from "../../../../common/color/hex"; import { labDarken } from "../../../../common/color/lab"; import { formatTime } from "../../../../common/datetime/format_time"; import { computeStateName } from "../../../../common/entity/compute_state_name"; @@ -357,10 +356,6 @@ export class HuiEnergyUsageGraphCard ), }; - const backgroundColor = computedStyles - .getPropertyValue("--card-background-color") - .trim(); - Object.entries(statistics).forEach(([key, statIds]) => { const sum = [ "solar", @@ -515,7 +510,7 @@ export class HuiEnergyUsageGraphCard ? Object.keys(combinedData).length : idx + 1, borderColor, - backgroundColor: hexBlend(borderColor, backgroundColor, 50), + backgroundColor: borderColor + "7F", stack: "stack", data: [], }); diff --git a/src/resources/ha-style.ts b/src/resources/ha-style.ts index 053efc7991..db0f0c9a0c 100644 --- a/src/resources/ha-style.ts +++ b/src/resources/ha-style.ts @@ -84,8 +84,8 @@ documentContainer.innerHTML = ` --state-climate-idle-color: #8a8a8a; /* energy */ - --energy-grid-consumption-color: #126a9a; - --energy-grid-return-color: #673ab7; + --energy-grid-consumption-color: #488fc2; + --energy-grid-return-color: #8353d1; --energy-solar-color: #ff9800; --energy-non-fossil-color: #0f9d58; --energy-battery-out-color: #4db6ac; diff --git a/src/resources/styles.ts b/src/resources/styles.ts index 19d0e34433..bd1918bb4f 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -45,7 +45,7 @@ export const darkStyles = { "codemirror-property": "#C792EA", "codemirror-qualifier": "#DECB6B", "codemirror-type": "#DECB6B", - "energy-grid-return-color": "#b39bdb", + "energy-grid-return-color": "#a280db", }; export const derivedStyles = { From b3f8daa75835972619d62214298c3b36378cc69c Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Tue, 19 Oct 2021 18:24:11 +0200 Subject: [PATCH 056/115] Fix `ha-icon-button` in `ha-file-upload` (#10328) --- src/components/ha-file-upload.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/components/ha-file-upload.ts b/src/components/ha-file-upload.ts index e43b69a859..611ff357d5 100644 --- a/src/components/ha-file-upload.ts +++ b/src/components/ha-file-upload.ts @@ -84,15 +84,20 @@ export class HaFileUpload extends LitElement { ${this.value} ${this.value - ? html`` - : html` - .path=${this.icon} >`} + ? html` + + ` + : html` + + `} `} From 21e1fef0fb7f3cf58ad100af47360e4ba79eb893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 19 Oct 2021 18:37:22 +0200 Subject: [PATCH 057/115] Use error for protection mode alert (#10315) --- hassio/src/addon-view/info/hassio-addon-info.ts | 2 +- src/translations/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index 8d54e25563..d6057e3169 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -181,7 +181,7 @@ class HassioAddonInfo extends LitElement { ${!this.addon.protected ? html` Date: Tue, 19 Oct 2021 18:37:38 +0200 Subject: [PATCH 058/115] Change unsupported reason container to software (#10325) --- hassio/src/system/hassio-supervisor-info.ts | 76 ++++++++------------- src/translations/en.json | 2 +- 2 files changed, 28 insertions(+), 50 deletions(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 7282cced77..2a2ef93de9 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -31,29 +31,9 @@ import { documentationUrl } from "../../../src/util/documentation-url"; import "../components/supervisor-metric"; import { hassioStyle } from "../resources/hassio-style"; -const UNSUPPORTED_REASON_URL = { - apparmor: "/more-info/unsupported/apparmor", - container: "/more-info/unsupported/container", - content_trust: "/more-info/unsupported/content_trust", - dbus: "/more-info/unsupported/dbus", - docker_configuration: "/more-info/unsupported/docker_configuration", - docker_version: "/more-info/unsupported/docker_version", - job_conditions: "/more-info/unsupported/job_conditions", - lxc: "/more-info/unsupported/lxc", - network_manager: "/more-info/unsupported/network_manager", - os_agent: "/more-info/unsupported/os_agent", - os: "/more-info/unsupported/os", - privileged: "/more-info/unsupported/privileged", - source_mods: "/more-info/unsupported/source_mods", - systemd: "/more-info/unsupported/systemd", -}; - +const UNSUPPORTED_REASON_URL = {}; const UNHEALTHY_REASON_URL = { privileged: "/more-info/unsupported/privileged", - supervisor: "/more-info/unhealthy/supervisor", - setup: "/more-info/unhealthy/setup", - docker: "/more-info/unhealthy/docker", - untrusted: "/more-info/unhealthy/untrusted", }; @customElement("hassio-supervisor-info") @@ -425,20 +405,19 @@ class HassioSupervisorInfo extends LitElement { ${this.supervisor.resolution.unsupported.map( (reason) => html`
  • - ${UNSUPPORTED_REASON_URL[reason] - ? html` - ${this.supervisor.localize( - `system.supervisor.unsupported_reason.${reason}` - ) || reason} - ` - : reason} + + ${this.supervisor.localize( + `system.supervisor.unsupported_reason.${reason}` + ) || reason} +
  • ` )} @@ -456,20 +435,19 @@ class HassioSupervisorInfo extends LitElement { ${this.supervisor.resolution.unhealthy.map( (reason) => html`
  • - ${UNHEALTHY_REASON_URL[reason] - ? html` - ${this.supervisor.localize( - `system.supervisor.unhealthy_reason.${reason}` - ) || reason} - ` - : reason} + + ${this.supervisor.localize( + `system.supervisor.unhealthy_reason.${reason}` + ) || reason} +
  • ` )} diff --git a/src/translations/en.json b/src/translations/en.json index d938f29204..764815d077 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4244,7 +4244,6 @@ "share_diagonstics_description": "Would you want to automatically share crash reports and diagnostic information when the Supervisor encounters unexpected errors? {line_break} This will allow us to fix the problems, the information is only accessible to the Home Assistant Core team and will not be shared with others.{line_break} The data does not include any private/sensitive information and you can disable this in settings at any time you want.", "unsupported_reason": { "apparmor": "AppArmor is not enabled on the host", - "container": "Containers known to cause issues", "content_trust": "Content-trust validation is disabled", "dbus": "DBUS", "docker_configuration": "Docker Configuration", @@ -4255,6 +4254,7 @@ "os": "Operating System", "os_agent": "OS Agent", "privileged": "Supervisor is not privileged", + "software": "Unsupported software detected", "source_mods": "Source modifications", "systemd": "Systemd" }, From e47a5effe6252c2e6cd7a8674e60e5dfa57eec89 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 19 Oct 2021 22:31:24 +0200 Subject: [PATCH 059/115] Migrate all paper checkbox elements to mwc (#10329) --- package.json | 1 - src/components/ha-form/ha-form-boolean.ts | 2 +- .../more-info/controls/more-info-camera.ts | 29 ++++++++++++------- .../customize/types/ha-customize-boolean.js | 18 +++++++++--- .../config/entities/ha-config-entities.ts | 1 - .../zwave/ha-config-zwave.js | 19 ++++++++---- .../state/developer-tools-state.js | 21 ++++++++++---- .../lovelace/cards/hui-shopping-list-card.ts | 24 +++++++-------- yarn.lock | 15 ---------- 9 files changed, 73 insertions(+), 57 deletions(-) diff --git a/package.json b/package.json index 5711fd6bf8..2329f6e87f 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,6 @@ "@polymer/iron-input": "^3.0.1", "@polymer/iron-overlay-behavior": "^3.0.3", "@polymer/iron-resizable-behavior": "^3.0.1", - "@polymer/paper-checkbox": "^3.1.0", "@polymer/paper-dialog": "^3.0.1", "@polymer/paper-dialog-behavior": "^3.0.1", "@polymer/paper-dialog-scrollable": "^3.0.1", diff --git a/src/components/ha-form/ha-form-boolean.ts b/src/components/ha-form/ha-form-boolean.ts index d55876859d..1e62d3fd13 100644 --- a/src/components/ha-form/ha-form-boolean.ts +++ b/src/components/ha-form/ha-form-boolean.ts @@ -20,7 +20,7 @@ export class HaFormBoolean extends LitElement implements HaFormElement { @property({ type: Boolean }) public disabled = false; - @query("paper-checkbox", true) private _input?: HTMLElement; + @query("ha-checkbox", true) private _input?: HTMLElement; public focus() { if (this._input) { diff --git a/src/dialogs/more-info/controls/more-info-camera.ts b/src/dialogs/more-info/controls/more-info-camera.ts index a573fdcf64..6d265e5b8d 100644 --- a/src/dialogs/more-info/controls/more-info-camera.ts +++ b/src/dialogs/more-info/controls/more-info-camera.ts @@ -1,5 +1,3 @@ -import "@polymer/paper-checkbox/paper-checkbox"; -import type { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox"; import { css, CSSResultGroup, @@ -12,6 +10,7 @@ import { property, state } from "lit/decorators"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-camera-stream"; +import { HaCheckbox } from "../../../components/ha-checkbox"; import { CameraEntity, CameraPreferences, @@ -25,7 +24,7 @@ import type { HomeAssistant } from "../../../types"; class MoreInfoCamera extends LitElement { @property({ attribute: false }) public hass?: HomeAssistant; - @property() public stateObj?: CameraEntity; + @property({ attribute: false }) public stateObj?: CameraEntity; @state() private _cameraPrefs?: CameraPreferences; @@ -55,12 +54,14 @@ class MoreInfoCamera extends LitElement { > ${this._cameraPrefs ? html` - - Preload stream - + + + Preload stream + + ` : undefined} `; @@ -101,7 +102,7 @@ class MoreInfoCamera extends LitElement { } private async _handleCheckboxChanged(ev) { - const checkbox = ev.currentTarget as PaperCheckboxElement; + const checkbox = ev.currentTarget as HaCheckbox; try { this._cameraPrefs = await updateCameraPrefs( this.hass!, @@ -122,7 +123,7 @@ class MoreInfoCamera extends LitElement { display: block; position: relative; } - paper-checkbox { + ha-checkbox { position: absolute; top: 0; right: 0; @@ -135,3 +136,9 @@ class MoreInfoCamera extends LitElement { } customElements.define("more-info-camera", MoreInfoCamera); + +declare global { + interface HTMLElementTagNameMap { + "more-info-camera": MoreInfoCamera; + } +} diff --git a/src/panels/config/customize/types/ha-customize-boolean.js b/src/panels/config/customize/types/ha-customize-boolean.js index bf6aa5c7db..803e6d8d21 100644 --- a/src/panels/config/customize/types/ha-customize-boolean.js +++ b/src/panels/config/customize/types/ha-customize-boolean.js @@ -1,14 +1,20 @@ -import "@polymer/paper-checkbox/paper-checkbox"; import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ import { PolymerElement } from "@polymer/polymer/polymer-element"; +import "../../../../components/ha-checkbox"; +import "../../../../components/ha-formfield"; class HaCustomizeBoolean extends PolymerElement { static get template() { return html` - - [[item.description]] - + + + `; } @@ -20,5 +26,9 @@ class HaCustomizeBoolean extends PolymerElement { }, }; } + + checkedChanged(ev) { + this.item.value = ev.target.checked; + } } customElements.define("ha-customize-boolean", HaCustomizeBoolean); diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index 4b22362764..b62f504f5d 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -7,7 +7,6 @@ import { mdiPlus, mdiUndo, } from "@mdi/js"; -import "@polymer/paper-checkbox/paper-checkbox"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-listbox/paper-listbox"; diff --git a/src/panels/config/integrations/integration-panels/zwave/ha-config-zwave.js b/src/panels/config/integrations/integration-panels/zwave/ha-config-zwave.js index 55bddd903a..f9dc04ddf5 100644 --- a/src/panels/config/integrations/integration-panels/zwave/ha-config-zwave.js +++ b/src/panels/config/integrations/integration-panels/zwave/ha-config-zwave.js @@ -3,7 +3,6 @@ import "@polymer/app-layout/app-toolbar/app-toolbar"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; -import "@polymer/paper-checkbox/paper-checkbox"; import "@polymer/paper-listbox/paper-listbox"; import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ @@ -308,12 +307,16 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) { >
    - - [[localize('ui.panel.config.zwave.node_management.exclude_entity')]] - + + + [[localize('ui.panel.developer-tools.tabs.states.entity')]] [[localize('ui.panel.developer-tools.tabs.states.state')]] - + [[localize('ui.panel.developer-tools.tabs.states.attributes')]] - + reducedTouchTarget + > @@ -545,6 +555,7 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) { } saveAttributeCheckboxState(ev) { + this._showAttributes = ev.target.checked; try { localStorage.setItem("devToolsShowAttributes", ev.target.checked); } catch (e) { diff --git a/src/panels/lovelace/cards/hui-shopping-list-card.ts b/src/panels/lovelace/cards/hui-shopping-list-card.ts index 25ed95dd0e..491ce3e245 100644 --- a/src/panels/lovelace/cards/hui-shopping-list-card.ts +++ b/src/panels/lovelace/cards/hui-shopping-list-card.ts @@ -1,5 +1,4 @@ import { mdiDrag, mdiNotificationClearAll, mdiPlus, mdiSort } from "@mdi/js"; -import "@polymer/paper-checkbox/paper-checkbox"; import { PaperInputElement } from "@polymer/paper-input/paper-input"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { @@ -17,6 +16,7 @@ import { repeat } from "lit/directives/repeat"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import "../../../components/ha-card"; import "../../../components/ha-icon"; +import "../../../components/ha-checkbox"; import { addItem, clearItems, @@ -178,12 +178,12 @@ class HuiShoppingListCard (item) => html`
    - + @change=${this._completeItem} + > html`
    - + @change=${this._completeItem} + > Date: Tue, 19 Oct 2021 22:42:30 +0200 Subject: [PATCH 060/115] Migrate all paper-radio elements to mwc-radio (#10327) --- package.json | 2 - src/onboarding/onboarding-core-config.ts | 78 ++++++++----- .../types/ha-automation-condition-sun.ts | 104 +++++++++++------- .../ha-automation-trigger-geo_location.ts | 53 +++++---- .../ha-automation-trigger-homeassistant.ts | 53 +++++---- .../types/ha-automation-trigger-sun.ts | 61 ++++++---- .../types/ha-automation-trigger-zone.ts | 54 +++++---- src/panels/config/core/ha-config-core-form.ts | 77 ++++++++----- src/panels/config/core/ha-config-name-form.ts | 2 - .../helpers/forms/ha-input_datetime-form.ts | 62 +++++++---- .../helpers/forms/ha-input_number-form.ts | 44 +++++--- .../helpers/forms/ha-input_text-form.ts | 44 +++++--- yarn.lock | 27 ----- 13 files changed, 398 insertions(+), 263 deletions(-) diff --git a/package.json b/package.json index 2329f6e87f..16c2a47c0f 100644 --- a/package.json +++ b/package.json @@ -84,8 +84,6 @@ "@polymer/paper-listbox": "^3.0.1", "@polymer/paper-menu-button": "^3.1.0", "@polymer/paper-progress": "^3.0.1", - "@polymer/paper-radio-button": "^3.0.1", - "@polymer/paper-radio-group": "^3.0.1", "@polymer/paper-ripple": "^3.0.2", "@polymer/paper-slider": "^3.0.1", "@polymer/paper-styles": "^3.0.1", diff --git a/src/onboarding/onboarding-core-config.ts b/src/onboarding/onboarding-core-config.ts index 83a1e06281..d0f61cfbbc 100644 --- a/src/onboarding/onboarding-core-config.ts +++ b/src/onboarding/onboarding-core-config.ts @@ -1,8 +1,6 @@ import "@material/mwc-button/mwc-button"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; @@ -21,6 +19,9 @@ import { SYMBOL_TO_ISO } from "../data/currency"; import { onboardCoreConfigStep } from "../data/onboarding"; import type { PolymerChangedEvent } from "../polymer-types"; import type { HomeAssistant } from "../types"; +import "../components/ha-radio"; +import "../components/ha-formfield"; +import type { HaRadio } from "../components/ha-radio"; const amsterdam: [number, number] = [52.3731339, 4.8903147]; const mql = matchMedia("(prefers-color-scheme: dark)"); @@ -135,32 +136,44 @@ class OnboardingCoreConfig extends LitElement { "ui.panel.config.core.section.core.core_config.unit_system" )}
    - - - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.unit_system_metric" - )} -
    - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.metric_example" +
    + - - - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.unit_system_imperial" - )} -
    - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.imperial_example" +
    + ${this.hass.localize( + "ui.panel.config.core.section.core.core_config.metric_example" + )} +
    `} + > + + + - - +
    + ${this.hass.localize( + "ui.panel.config.core.section.core.core_config.imperial_example" + )} +
    `} + > + +
    +
    @@ -281,10 +294,8 @@ class OnboardingCoreConfig extends LitElement { this._location = ev.detail.location; } - private _unitSystemChanged( - ev: PolymerChangedEvent - ) { - this._unitSystem = ev.detail.value; + private _unitSystemChanged(ev: CustomEvent) { + this._unitSystem = (ev.target as HaRadio).value as "metric" | "imperial"; } private async _detect() { @@ -363,6 +374,13 @@ class OnboardingCoreConfig extends LitElement { .row > * { margin: 0 8px; } + + .radio-group { + display: flex; + flex-direction: column; + flex: 1; + } + .footer { margin-top: 16px; text-align: right; diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-sun.ts b/src/panels/config/automation/condition/types/ha-automation-condition-sun.ts index bda9399539..0cbf5a339a 100644 --- a/src/panels/config/automation/condition/types/ha-automation-condition-sun.ts +++ b/src/panels/config/automation/condition/types/ha-automation-condition-sun.ts @@ -1,8 +1,5 @@ import "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; -import type { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-group"; -import { html, LitElement } from "lit"; +import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../../../common/dom/fire_event"; import type { SunCondition } from "../../../../../data/automation"; @@ -11,12 +8,15 @@ import { ConditionElement, handleChangeEvent, } from "../ha-automation-condition-row"; +import "../../../../../components/ha-radio"; +import "../../../../../components/ha-formfield"; +import type { HaRadio } from "../../../../../components/ha-radio"; @customElement("ha-automation-condition-sun") export class HaSunCondition extends LitElement implements ConditionElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public condition!: SunCondition; + @property({ attribute: false }) public condition!: SunCondition; public static get defaultConfig() { return {}; @@ -25,28 +25,35 @@ export class HaSunCondition extends LitElement implements ConditionElement { protected render() { const { after, after_offset, before, before_offset } = this.condition; return html` - - - `; } @@ -87,10 +93,17 @@ export default class HaGeolocationTrigger extends LitElement { fireEvent(this, "value-changed", { value: { ...this.trigger, - event: (ev.target as PaperRadioGroupElement).selected, + event: (ev.target as HaRadio).value, }, }); } + + static styles = css` + label { + display: flex; + align-items: center; + } + `; } declare global { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts index f4464a4b36..5e64f7fd47 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts @@ -1,17 +1,17 @@ -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; -import type { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-group"; -import { html, LitElement } from "lit"; +import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../../../common/dom/fire_event"; +import type { HaRadio } from "../../../../../components/ha-radio"; import type { HassTrigger } from "../../../../../data/automation"; import type { HomeAssistant } from "../../../../../types"; +import "../../../../../components/ha-formfield"; +import "../../../../../components/ha-radio"; @customElement("ha-automation-trigger-homeassistant") export default class HaHassTrigger extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public trigger!: HassTrigger; + @property({ attribute: false }) public trigger!: HassTrigger; public static get defaultConfig() { return { @@ -26,23 +26,31 @@ export default class HaHassTrigger extends LitElement { ${this.hass.localize( "ui.panel.config.automation.editor.triggers.type.homeassistant.event" )} - - - - ${this.hass.localize( + - - ${this.hass.localize( + > + + + - + > + + + `; } @@ -51,10 +59,17 @@ export default class HaHassTrigger extends LitElement { fireEvent(this, "value-changed", { value: { ...this.trigger, - event: (ev.target as PaperRadioGroupElement).selected, + event: (ev.target as HaRadio).value, }, }); } + + static styles = css` + label { + display: flex; + align-items: center; + } + `; } declare global { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts index d940a3e1cc..0d6bf97980 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts @@ -1,10 +1,10 @@ import "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; -import type { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-group"; -import { html, LitElement } from "lit"; +import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../../../common/dom/fire_event"; +import "../../../../../components/ha-radio"; +import "../../../../../components/ha-formfield"; +import type { HaRadio } from "../../../../../components/ha-radio"; import type { SunTrigger } from "../../../../../data/automation"; import type { HomeAssistant } from "../../../../../types"; import { @@ -16,7 +16,7 @@ import { export class HaSunTrigger extends LitElement implements TriggerElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public trigger!: SunTrigger; + @property({ attribute: false }) public trigger!: SunTrigger; public static get defaultConfig() { return { @@ -27,27 +27,35 @@ export class HaSunTrigger extends LitElement implements TriggerElement { protected render() { const { offset, event } = this.trigger; return html` - - `; } @@ -97,10 +106,17 @@ export class HaZoneTrigger extends LitElement { fireEvent(this, "value-changed", { value: { ...this.trigger, - event: (ev.target as PaperRadioGroupElement).selected, + event: (ev.target as HaRadio).value, }, }); } + + static styles = css` + label { + display: flex; + align-items: center; + } + `; } declare global { diff --git a/src/panels/config/core/ha-config-core-form.ts b/src/panels/config/core/ha-config-core-form.ts index 4e48098672..495b963121 100644 --- a/src/panels/config/core/ha-config-core-form.ts +++ b/src/panels/config/core/ha-config-core-form.ts @@ -1,8 +1,6 @@ import "@material/mwc-button/mwc-button"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; @@ -16,6 +14,9 @@ import { ConfigUpdateValues, saveCoreConfig } from "../../../data/core"; import { SYMBOL_TO_ISO } from "../../../data/currency"; import type { PolymerChangedEvent } from "../../../polymer-types"; import type { HomeAssistant } from "../../../types"; +import "../../../components/ha-formfield"; +import "../../../components/ha-radio"; +import type { HaRadio } from "../../../components/ha-radio"; @customElement("ha-config-core-form") class ConfigCoreForm extends LitElement { @@ -120,32 +121,44 @@ class ConfigCoreForm extends LitElement { "ui.panel.config.core.section.core.core_config.unit_system" )}
    - - - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.unit_system_metric" - )} -
    - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.metric_example" +
    + - - - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.unit_system_imperial" - )} -
    - ${this.hass.localize( - "ui.panel.config.core.section.core.core_config.imperial_example" +
    + ${this.hass.localize( + "ui.panel.config.core.section.core.core_config.metric_example" + )} +
    `} + > + + + - - +
    + ${this.hass.localize( + "ui.panel.config.core.section.core.core_config.imperial_example" + )} +
    `} + > + +
    +
    @@ -258,10 +271,8 @@ class ConfigCoreForm extends LitElement { this._location = ev.detail.location; } - private _unitSystemChanged( - ev: PolymerChangedEvent - ) { - this._unitSystem = ev.detail.value; + private _unitSystemChanged(ev: CustomEvent) { + this._unitSystem = (ev.target as HaRadio).value as "metric" | "imperial"; } private async _save() { @@ -307,6 +318,12 @@ class ConfigCoreForm extends LitElement { margin: 0 8px; } + .radio-group { + display: flex; + flex-direction: column; + flex: 1; + } + .card-actions { text-align: right; } diff --git a/src/panels/config/core/ha-config-name-form.ts b/src/panels/config/core/ha-config-name-form.ts index 3edc3be6d8..7dc7752720 100644 --- a/src/panels/config/core/ha-config-name-form.ts +++ b/src/panels/config/core/ha-config-name-form.ts @@ -1,8 +1,6 @@ import "@material/mwc-button/mwc-button"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; import { css, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import "../../../components/ha-card"; diff --git a/src/panels/config/helpers/forms/ha-input_datetime-form.ts b/src/panels/config/helpers/forms/ha-input_datetime-form.ts index 87c6931c8d..8f9f89c084 100644 --- a/src/panels/config/helpers/forms/ha-input_datetime-form.ts +++ b/src/panels/config/helpers/forms/ha-input_datetime-form.ts @@ -1,6 +1,4 @@ import "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; @@ -8,6 +6,9 @@ import "../../../../components/ha-icon-picker"; import { InputDateTime } from "../../../../data/input_datetime"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; +import "../../../../components/ha-formfield"; +import "../../../../components/ha-radio"; +import type { HaRadio } from "../../../../components/ha-radio"; @customElement("ha-input_datetime-form") class HaInputDateTimeForm extends LitElement { @@ -81,32 +82,49 @@ class HaInputDateTimeForm extends LitElement {
    ${this.hass.localize("ui.dialogs.helper_settings.input_datetime.mode")}:
    - - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_datetime.date" - )} - - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_datetime.time" - )} - - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_datetime.datetime" - )} - - + + + + + + + +
    `; } private _modeChanged(ev: CustomEvent) { - const mode = ev.detail.value; + const mode = (ev.target as HaRadio).value; fireEvent(this, "value-changed", { value: { ...this._item, diff --git a/src/panels/config/helpers/forms/ha-input_number-form.ts b/src/panels/config/helpers/forms/ha-input_number-form.ts index b65e5d1ed8..9d6960062a 100644 --- a/src/panels/config/helpers/forms/ha-input_number-form.ts +++ b/src/panels/config/helpers/forms/ha-input_number-form.ts @@ -1,6 +1,4 @@ import "@polymer/paper-input/paper-input"; -import "@polymer/paper-radio-button/paper-radio-button"; -import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; @@ -8,6 +6,9 @@ import "../../../../components/ha-icon-picker"; import { InputNumber } from "../../../../data/input_number"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; +import "../../../../components/ha-formfield"; +import "../../../../components/ha-radio"; +import type { HaRadio } from "../../../../components/ha-radio"; @customElement("ha-input_number-form") class HaInputNumberForm extends LitElement { @@ -117,21 +118,30 @@ class HaInputNumberForm extends LitElement { ${this.hass.localize( "ui.dialogs.helper_settings.input_number.mode" )} - - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_number.slider" - )} - - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_number.box" - )} - - + + + + +
    - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_text.text" - )} - - - ${this.hass.localize( - "ui.dialogs.helper_settings.input_text.password" - )} - - + + + + +
    Date: Tue, 19 Oct 2021 16:53:06 -0400 Subject: [PATCH 061/115] Correct grid neutrality card tooltip, make consistent with new colors (#10326) --- .../cards/energy/hui-energy-grid-neutrality-gauge-card.ts | 2 +- src/translations/en.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts b/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts index a033f35548..cc26d82a0d 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-grid-neutrality-gauge-card.ts @@ -107,7 +107,7 @@ class HuiEnergyGridGaugeCard )}

    ${this.hass.localize( - "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.red_green_color_explain" + "ui.panel.lovelace.cards.energy.grid_neutrality_gauge.color_explain" )} diff --git a/src/translations/en.json b/src/translations/en.json index 764815d077..b842ec456e 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3027,8 +3027,8 @@ "self_consumed_solar_could_not_calc": "Self-consumed solar energy couldn't be calculated" }, "grid_neutrality_gauge": { - "energy_dependency": "This card represents your energy dependency.", - "red_green_color_explain": "If it's green, it means you produced more energy than that you consumed from the grid. If it's in the red, it means that you relied on the grid for part of your home's energy consumption.", + "energy_dependency": "This card indicates your net energy usage.", + "color_explain": "If the needle is in the purple, you returned more energy to the grid than you consumed from it. If it's in the blue, you consumed more energy from the grid than you returned.", "net_returned_grid": "Net returned to the grid", "net_consumed_grid": "Net consumed from the grid", "grid_neutrality_not_calculated": "Grid neutrality could not be calculated" From b1e6935df9d2ae03a5249630e243ff8a008d1d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 19 Oct 2021 22:54:07 +0200 Subject: [PATCH 062/115] Fix select options for add-on config (#10330) --- .../addon-view/config/hassio-addon-config.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/hassio/src/addon-view/config/hassio-addon-config.ts b/hassio/src/addon-view/config/hassio-addon-config.ts index b3605d3cca..7c53563ad2 100644 --- a/hassio/src/addon-view/config/hassio-addon-config.ts +++ b/hassio/src/addon-view/config/hassio-addon-config.ts @@ -78,6 +78,18 @@ class HassioAddonConfig extends LitElement { this.addon.translations.en?.configuration?.[entry.name].name || entry.name; + private _schema = memoizeOne((schema: HaFormSchema[]): HaFormSchema[] => + // @ts-expect-error supervisor does not implement [string, string] for select.options[] + schema.map((entry) => + entry.type === "select" + ? { + ...entry, + options: entry.options.map((option) => [option, option]), + } + : entry + ) + ); + private _filteredShchema = memoizeOne( (options: Record, schema: HaFormSchema[]) => schema.filter((entry) => entry.name in options || entry.required) @@ -128,12 +140,14 @@ class HassioAddonConfig extends LitElement { .data=${this._options!} @value-changed=${this._configChanged} .computeLabel=${this.computeLabel} - .schema=${this._showOptional - ? this.addon.schema! - : this._filteredShchema( - this.addon.options, - this.addon.schema! - )} + .schema=${this._schema( + this._showOptional + ? this.addon.schema! + : this._filteredShchema( + this.addon.options, + this.addon.schema! + ) + )} >` : html` Date: Tue, 19 Oct 2021 22:56:49 +0200 Subject: [PATCH 063/115] Migrate all paper dialogs to mwc (#10333) --- .../markdown/dialog-hassio-markdown.ts | 18 --- package.json | 3 - .../dialog/ha-iron-focusables-helper.js | 89 ----------- src/components/dialog/ha-paper-dialog.ts | 31 ---- src/components/ha-dialog.ts | 8 +- .../config-flow/dialog-data-entry-flow.ts | 1 - .../ha-voice-command-dialog.ts | 149 ++++++------------ src/mixins/dialog-mixin.js | 25 --- .../areas/dialog-area-registry-detail.ts | 1 - .../automation/thingtalk/dialog-thingtalk.ts | 71 ++++----- .../thingtalk/ha-thingtalk-placeholders.ts | 54 +++---- .../blueprint/dialog-import-blueprint.ts | 1 - .../dialog-cloud-certificate.ts | 51 +++--- .../dialog-manage-cloudhook.ts | 75 ++++----- .../zha/zha-add-group-page.ts | 6 +- .../integration-panels/zha/zha-group-page.ts | 8 +- .../zwave/zwave-log-dialog.js | 31 ++-- .../card-editor/hui-dialog-delete-card.ts | 2 - .../card-editor/hui-dialog-suggest-card.ts | 2 - .../lovelace/editor/hui-dialog-save-config.ts | 15 -- .../hui-dialog-edit-lovelace.ts | 103 ++++-------- .../select-view/hui-dialog-select-view.ts | 1 - .../mailbox/ha-dialog-show-audio-message.js | 67 +++----- src/panels/profile/ha-change-password-card.ts | 1 - src/resources/ha-style.ts | 19 --- src/resources/styles.ts | 51 ------ yarn.lock | 38 ----- 27 files changed, 230 insertions(+), 691 deletions(-) delete mode 100644 src/components/dialog/ha-iron-focusables-helper.js delete mode 100644 src/components/dialog/ha-paper-dialog.ts delete mode 100644 src/mixins/dialog-mixin.js diff --git a/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts b/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts index b936a70f97..1a1c5dfe13 100644 --- a/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts +++ b/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts @@ -47,11 +47,6 @@ class HassioMarkdownDialog extends LitElement { haStyleDialog, hassioStyle, css` - ha-paper-dialog { - min-width: 350px; - font-size: 14px; - border-radius: 2px; - } app-toolbar { margin: 0; padding: 0 16px; @@ -62,19 +57,6 @@ class HassioMarkdownDialog extends LitElement { margin-left: 16px; } @media all and (max-width: 450px), all and (max-height: 500px) { - ha-paper-dialog { - max-height: 100%; - } - ha-paper-dialog::before { - content: ""; - position: fixed; - z-index: -1; - top: 0px; - left: 0px; - right: 0px; - bottom: 0px; - background-color: inherit; - } app-toolbar { color: var(--text-primary-color); background-color: var(--primary-color); diff --git a/package.json b/package.json index 16c2a47c0f..ee71475cdb 100644 --- a/package.json +++ b/package.json @@ -75,9 +75,6 @@ "@polymer/iron-input": "^3.0.1", "@polymer/iron-overlay-behavior": "^3.0.3", "@polymer/iron-resizable-behavior": "^3.0.1", - "@polymer/paper-dialog": "^3.0.1", - "@polymer/paper-dialog-behavior": "^3.0.1", - "@polymer/paper-dialog-scrollable": "^3.0.1", "@polymer/paper-dropdown-menu": "^3.2.0", "@polymer/paper-input": "^3.2.1", "@polymer/paper-item": "^3.0.1", diff --git a/src/components/dialog/ha-iron-focusables-helper.js b/src/components/dialog/ha-iron-focusables-helper.js deleted file mode 100644 index 1f75e82c52..0000000000 --- a/src/components/dialog/ha-iron-focusables-helper.js +++ /dev/null @@ -1,89 +0,0 @@ -/** -@license -Copyright (c) 2016 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at -http://polymer.github.io/LICENSE.txt The complete set of authors may be found at -http://polymer.github.io/AUTHORS.txt The complete set of contributors may be -found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as -part of the polymer project is also subject to an additional IP rights grant -found at http://polymer.github.io/PATENTS.txt -*/ -/* - Fixes issue with not using shadow dom properly in iron-overlay-behavior/icon-focusables-helper.js -*/ -import { IronFocusablesHelper } from "@polymer/iron-overlay-behavior/iron-focusables-helper"; -import { dom } from "@polymer/polymer/lib/legacy/polymer.dom"; - -export const HaIronFocusablesHelper = { - /** - * Returns a sorted array of tabbable nodes, including the root node. - * It searches the tabbable nodes in the light and shadow dom of the chidren, - * sorting the result by tabindex. - * @param {!Node} node - * @return {!Array} - */ - getTabbableNodes: function (node) { - const result = []; - // If there is at least one element with tabindex > 0, we need to sort - // the final array by tabindex. - const needsSortByTabIndex = this._collectTabbableNodes(node, result); - if (needsSortByTabIndex) { - return IronFocusablesHelper._sortByTabIndex(result); - } - return result; - }, - - /** - * Searches for nodes that are tabbable and adds them to the `result` array. - * Returns if the `result` array needs to be sorted by tabindex. - * @param {!Node} node The starting point for the search; added to `result` - * if tabbable. - * @param {!Array} result - * @return {boolean} - * @private - */ - _collectTabbableNodes: function (node, result) { - // If not an element or not visible, no need to explore children. - if ( - node.nodeType !== Node.ELEMENT_NODE || - !IronFocusablesHelper._isVisible(node) - ) { - return false; - } - const element = /** @type {!HTMLElement} */ (node); - const tabIndex = IronFocusablesHelper._normalizedTabIndex(element); - let needsSort = tabIndex > 0; - if (tabIndex >= 0) { - result.push(element); - } - - // In ShadowDOM v1, tab order is affected by the order of distrubution. - // E.g. getTabbableNodes(#root) in ShadowDOM v1 should return [#A, #B]; - // in ShadowDOM v0 tab order is not affected by the distrubution order, - // in fact getTabbableNodes(#root) returns [#B, #A]. - //
    - // - // - // - // - // - // - //
    - // TODO(valdrin) support ShadowDOM v1 when upgrading to Polymer v2.0. - let children; - if (element.localName === "content" || element.localName === "slot") { - children = dom(element).getDistributedNodes(); - } else { - // ///////////////////////// - // Use shadow root if possible, will check for distributed nodes. - // THIS IS THE CHANGED LINE - children = dom(element.shadowRoot || element.root || element).children; - // ///////////////////////// - } - for (let i = 0; i < children.length; i++) { - // Ensure method is always invoked to collect tabbable children. - needsSort = this._collectTabbableNodes(children[i], result) || needsSort; - } - return needsSort; - }, -}; diff --git a/src/components/dialog/ha-paper-dialog.ts b/src/components/dialog/ha-paper-dialog.ts deleted file mode 100644 index edaeff9315..0000000000 --- a/src/components/dialog/ha-paper-dialog.ts +++ /dev/null @@ -1,31 +0,0 @@ -import "@polymer/paper-dialog/paper-dialog"; -import type { PaperDialogElement } from "@polymer/paper-dialog/paper-dialog"; -import { mixinBehaviors } from "@polymer/polymer/lib/legacy/class"; -import type { Constructor } from "../../types"; -import { HaIronFocusablesHelper } from "./ha-iron-focusables-helper"; - -const paperDialogClass = customElements.get( - "paper-dialog" -) as Constructor; - -// behavior that will override existing iron-overlay-behavior and call the fixed implementation -const haTabFixBehaviorImpl = { - get _focusableNodes() { - return HaIronFocusablesHelper.getTabbableNodes(this); - }, -}; - -// paper-dialog that uses the haTabFixBehaviorImpl behavior -// export class HaPaperDialog extends paperDialogClass {} -// @ts-ignore -export class HaPaperDialog - extends mixinBehaviors([haTabFixBehaviorImpl], paperDialogClass) - implements PaperDialogElement {} - -declare global { - interface HTMLElementTagNameMap { - "ha-paper-dialog": HaPaperDialog; - } -} -// @ts-ignore -customElements.define("ha-paper-dialog", HaPaperDialog); diff --git a/src/components/ha-dialog.ts b/src/components/ha-dialog.ts index d5f9abcc67..0b1633845d 100644 --- a/src/components/ha-dialog.ts +++ b/src/components/ha-dialog.ts @@ -24,7 +24,7 @@ export const createCloseHeading = ( // @ts-expect-error export class HaDialog extends Dialog { public scrollToPos(x: number, y: number) { - this.contentElement.scrollTo(x, y); + this.contentElement?.scrollTo(x, y); } protected renderHeading() { @@ -44,6 +44,12 @@ export class HaDialog extends Dialog { justify-content: var(--justify-action-buttons, flex-end); padding-bottom: max(env(safe-area-inset-bottom), 8px); } + .mdc-dialog__actions span:nth-child(1) { + flex: var(--secondary-action-button-flex, unset); + } + .mdc-dialog__actions span:nth-child(2) { + flex: var(--primary-action-button-flex, unset); + } .mdc-dialog__container { align-items: var(--vertial-align-dialog, center); } diff --git a/src/dialogs/config-flow/dialog-data-entry-flow.ts b/src/dialogs/config-flow/dialog-data-entry-flow.ts index b31095e2c1..e7fcb1572b 100644 --- a/src/dialogs/config-flow/dialog-data-entry-flow.ts +++ b/src/dialogs/config-flow/dialog-data-entry-flow.ts @@ -1,6 +1,5 @@ import "@material/mwc-button"; import { mdiClose } from "@mdi/js"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import type { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, diff --git a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts index 7f6cb5e486..4c8fa20780 100644 --- a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts +++ b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts @@ -1,7 +1,5 @@ /* eslint-disable lit/prefer-static-styles */ import { mdiMicrophone } from "@mdi/js"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import type { PaperDialogScrollableElement } from "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; import { @@ -17,7 +15,6 @@ import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../common/dom/fire_event"; import { SpeechRecognition } from "../../common/dom/speech-recognition"; import { uid } from "../../common/util/uid"; -import "../../components/dialog/ha-paper-dialog"; import "../../components/ha-icon-button"; import { AgentInfo, @@ -27,6 +24,9 @@ import { } from "../../data/conversation"; import { haStyleDialog } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; +import "../../components/ha-dialog"; +import type { HaDialog } from "../../components/ha-dialog"; +import "@material/mwc-button/mwc-button"; interface Message { who: string; @@ -56,7 +56,7 @@ export class HaVoiceCommandDialog extends LitElement { @state() private _agentInfo?: AgentInfo; - @query("#messages", true) private messages!: PaperDialogScrollableElement; + @query("ha-dialog", true) private _dialog!: HaDialog; private recognition!: SpeechRecognition; @@ -70,74 +70,42 @@ export class HaVoiceCommandDialog extends LitElement { this._agentInfo = await getAgentInfo(this.hass); } + public async closeDialog(): Promise { + this._opened = false; + if (this.recognition) { + this.recognition.abort(); + } + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + protected render(): TemplateResult { - // CSS custom property mixins only work in render https://github.com/Polymer/lit-element/issues/633 + if (!this._opened) { + return html``; + } return html` - - - ${this._agentInfo && this._agentInfo.onboarding - ? html` -
    - ${this._agentInfo.onboarding.text} -
    - ${this.hass.localize("ui.common.yes")}! - ${this.hass.localize("ui.common.no")} + +
    + ${this._agentInfo && this._agentInfo.onboarding + ? html` +
    + ${this._agentInfo.onboarding.text} +
    + ${this.hass.localize("ui.common.yes")}! + ${this.hass.localize("ui.common.no")} +
    -
    - ` - : ""} - + ` + : ""} ${this._conversation.map( (message) => html`
    @@ -157,8 +125,8 @@ export class HaVoiceCommandDialog extends LitElement {
    ` : ""} -
    -
    +
    +
    - + `; } @@ -346,18 +314,7 @@ export class HaVoiceCommandDialog extends LitElement { } private _scrollMessagesBottom() { - this.messages.scrollTarget.scrollTop = - this.messages.scrollTarget.scrollHeight; - if (this.messages.scrollTarget.scrollTop === 0) { - fireEvent(this.messages, "iron-resize"); - } - } - - private _openedChanged(ev: CustomEvent) { - this._opened = ev.detail.value; - if (!this._opened && this.recognition) { - this.recognition.abort(); - } + this._dialog.scrollToPos(0, 99999); } private _computeMessageClasses(message: Message) { @@ -368,10 +325,6 @@ export class HaVoiceCommandDialog extends LitElement { return [ haStyleDialog, css` - :host { - z-index: 103; - } - ha-icon-button { color: var(--secondary-text-color); } @@ -380,13 +333,12 @@ export class HaVoiceCommandDialog extends LitElement { color: var(--primary-color); } - .input { - margin: 0 0 16px 0; + ha-dialog { + --primary-action-button-flex: 1; + --secondary-action-button-flex: 0; + --mdc-dialog-max-width: 450px; } - ha-paper-dialog { - width: 450px; - } a.button { text-decoration: none; } @@ -394,16 +346,7 @@ export class HaVoiceCommandDialog extends LitElement { width: 100%; } .onboarding { - padding: 0 24px; - } - paper-dialog-scrollable.top-border::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 1px; - background: var(--divider-color); + border-bottom: 1px solid var(--divider-color); } .side-by-side { display: flex; diff --git a/src/mixins/dialog-mixin.js b/src/mixins/dialog-mixin.js deleted file mode 100644 index cc8103935a..0000000000 --- a/src/mixins/dialog-mixin.js +++ /dev/null @@ -1,25 +0,0 @@ -import { PaperDialogBehavior } from "@polymer/paper-dialog-behavior/paper-dialog-behavior"; -import { mixinBehaviors } from "@polymer/polymer/lib/legacy/class"; -import { dedupingMixin } from "@polymer/polymer/lib/utils/mixin"; -import { EventsMixin } from "./events-mixin"; -/** - * @polymerMixin - * @appliesMixin EventsMixin - * @appliesMixin PaperDialogBehavior - */ -export default dedupingMixin( - (superClass) => - class extends mixinBehaviors( - [EventsMixin, PaperDialogBehavior], - superClass - ) { - static get properties() { - return { - withBackdrop: { - type: Boolean, - value: true, - }, - }; - } - } -); diff --git a/src/panels/config/areas/dialog-area-registry-detail.ts b/src/panels/config/areas/dialog-area-registry-detail.ts index 5daf53b5e0..217a330d49 100644 --- a/src/panels/config/areas/dialog-area-registry-detail.ts +++ b/src/panels/config/areas/dialog-area-registry-detail.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import "@polymer/paper-input/paper-input"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { property, state } from "lit/decorators"; diff --git a/src/panels/config/automation/thingtalk/dialog-thingtalk.ts b/src/panels/config/automation/thingtalk/dialog-thingtalk.ts index 3c6752ad46..a19ccbed10 100644 --- a/src/panels/config/automation/thingtalk/dialog-thingtalk.ts +++ b/src/panels/config/automation/thingtalk/dialog-thingtalk.ts @@ -1,20 +1,18 @@ import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state, query } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/dialog/ha-paper-dialog"; import "../../../../components/ha-circular-progress"; import type { AutomationConfig } from "../../../../data/automation"; import { convertThingTalk } from "../../../../data/cloud"; -import type { PolymerChangedEvent } from "../../../../polymer-types"; import { haStyle, haStyleDialog } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; import "./ha-thingtalk-placeholders"; import type { PlaceholderValues } from "./ha-thingtalk-placeholders"; import type { ThingtalkDialogParams } from "./show-dialog-thingtalk"; +import "../../../../components/ha-dialog"; export interface Placeholder { name: string; @@ -38,8 +36,6 @@ class DialogThingtalk extends LitElement { @state() private _submitting = false; - @state() private _opened = false; - @state() private _placeholders?: PlaceholderContainer; @query("#input") private _input?: PaperInputElement; @@ -51,7 +47,6 @@ class DialogThingtalk extends LitElement { public async showDialog(params: ThingtalkDialogParams): Promise { this._params = params; this._error = undefined; - this._opened = true; if (params.input) { this._value = params.input; await this.updateComplete; @@ -61,10 +56,10 @@ class DialogThingtalk extends LitElement { public closeDialog() { this._placeholders = undefined; + this._params = undefined; if (this._input) { this._input.value = null; } - this._opened = false; fireEvent(this, "dialog-closed", { dialog: this.localName }); } @@ -77,26 +72,22 @@ class DialogThingtalk extends LitElement { `; } return html` - -

    - ${this.hass.localize( - `ui.panel.config.automation.thingtalk.task_selection.header` - )} -

    - +
    ${this._error ? html`
    ${this._error}
    ` : ""} ${this.hass.localize( `ui.panel.config.automation.thingtalk.task_selection.introduction` @@ -143,23 +134,25 @@ class DialogThingtalk extends LitElement { class="attribution" >Powered by Almond - -
    - - ${this.hass.localize(`ui.common.skip`)} - - - ${this._submitting - ? html`` - : ""} - ${this.hass.localize(`ui.panel.config.automation.thingtalk.create`)} -
    - + + ${this.hass.localize(`ui.common.skip`)} + + + ${this._submitting + ? html`` + : ""} + ${this.hass.localize(`ui.panel.config.automation.thingtalk.create`)} + + `; } @@ -234,12 +227,6 @@ class DialogThingtalk extends LitElement { this.closeDialog(); }; - private _openedChanged(ev: PolymerChangedEvent): void { - if (!ev.detail.value) { - this.closeDialog(); - } - } - private _handleKeyUp(ev: KeyboardEvent) { if (ev.keyCode === 13) { this._generate(); @@ -255,7 +242,7 @@ class DialogThingtalk extends LitElement { haStyle, haStyleDialog, css` - ha-paper-dialog { + ha-dialog { max-width: 500px; } mwc-button.left { diff --git a/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts b/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts index 0f62bb0f39..9731a96394 100644 --- a/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts +++ b/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts @@ -25,7 +25,6 @@ import { import { subscribeEntityRegistry } from "../../../../data/entity_registry"; import { domainToName } from "../../../../data/integration"; import { SubscribeMixin } from "../../../../mixins/subscribe-mixin"; -import { PolymerChangedEvent } from "../../../../polymer-types"; import { haStyleDialog } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; import { Placeholder, PlaceholderContainer } from "./dialog-thingtalk"; @@ -124,18 +123,14 @@ export class ThingTalkPlaceholders extends SubscribeMixin(LitElement) { protected render(): TemplateResult { return html` - -

    - ${this.hass.localize( - `ui.panel.config.automation.thingtalk.link_devices.header` - )} -

    - +
    ${this._error ? html`
    ${this._error}
    ` : ""} ${Object.entries(this.placeholders).map( ([type, placeholders]) => @@ -243,16 +238,18 @@ export class ThingTalkPlaceholders extends SubscribeMixin(LitElement) { })} ` )} - -
    - - ${this.hass.localize(`ui.common.skip`)} - - - ${this.hass.localize(`ui.panel.config.automation.thingtalk.create`)} -
    - + + ${this.hass.localize(`ui.common.skip`)} + + + ${this.hass.localize(`ui.panel.config.automation.thingtalk.create`)} + + `; } @@ -440,11 +437,6 @@ export class ThingTalkPlaceholders extends SubscribeMixin(LitElement) { this.requestUpdate("_placeholderValues"); } }); - - fireEvent( - this.shadowRoot!.querySelector("ha-paper-dialog")! as HTMLElement, - "iron-resize" - ); } private _entityPicked(ev: Event): void { @@ -465,24 +457,16 @@ export class ThingTalkPlaceholders extends SubscribeMixin(LitElement) { fireEvent(this, "placeholders-filled", { value: this._placeholderValues }); } - private _openedChanged(ev: PolymerChangedEvent): void { - // The opened-changed event doesn't leave the shadowdom so we re-dispatch it - this.dispatchEvent(new CustomEvent(ev.type, ev)); - } - static get styles(): CSSResultGroup { return [ haStyleDialog, css` - ha-paper-dialog { + ha-dialog { max-width: 500px; } mwc-button.left { margin-right: auto; } - paper-dialog-scrollable { - margin-top: 10px; - } h3 { margin: 10px 0 0 0; font-weight: 500; diff --git a/src/panels/config/blueprint/dialog-import-blueprint.ts b/src/panels/config/blueprint/dialog-import-blueprint.ts index e9d9a4f0ea..ad2cb1eb6c 100644 --- a/src/panels/config/blueprint/dialog-import-blueprint.ts +++ b/src/panels/config/blueprint/dialog-import-blueprint.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; import { CSSResultGroup, html, LitElement, TemplateResult } from "lit"; diff --git a/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts b/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts index a91261914e..0616c0edd9 100644 --- a/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts +++ b/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts @@ -2,8 +2,7 @@ import "@material/mwc-button"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { formatDateTime } from "../../../../common/datetime/format_date_time"; -import "../../../../components/dialog/ha-paper-dialog"; -import type { HaPaperDialog } from "../../../../components/dialog/ha-paper-dialog"; +import { fireEvent } from "../../../../common/dom/fire_event"; import { haStyle } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; import type { CloudCertificateParams as CloudCertificateDialogParams } from "./show-dialog-cloud-certificate"; @@ -15,11 +14,13 @@ class DialogCloudCertificate extends LitElement { @property() private _params?: CloudCertificateDialogParams; - public async showDialog(params: CloudCertificateDialogParams) { + public showDialog(params: CloudCertificateDialogParams) { this._params = params; - // Wait till dialog is rendered. - await this.updateComplete; - this._dialog.open(); + } + + public closeDialog() { + this._params = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); } protected render() { @@ -29,12 +30,12 @@ class DialogCloudCertificate extends LitElement { const { certificateInfo } = this._params; return html` - -

    - ${this.hass!.localize( - "ui.panel.config.cloud.dialog_certificate.certificate_information" - )} -

    +

    ${this.hass!.localize( @@ -56,31 +57,21 @@ class DialogCloudCertificate extends LitElement {

    -
    - ${this.hass!.localize( - "ui.panel.config.cloud.dialog_certificate.close" - )} -
    -
    + + ${this.hass!.localize( + "ui.panel.config.cloud.dialog_certificate.close" + )} + + `; } - private get _dialog(): HaPaperDialog { - return this.shadowRoot!.querySelector("ha-paper-dialog")!; - } - - private _closeDialog() { - this._dialog.close(); - } - static get styles(): CSSResultGroup { return [ haStyle, css` - ha-paper-dialog { - width: 535px; + ha-dialog { + --mdc-dialog-max-width: 535px; } .break-word { overflow-wrap: break-word; diff --git a/src/panels/config/cloud/dialog-manage-cloudhook/dialog-manage-cloudhook.ts b/src/panels/config/cloud/dialog-manage-cloudhook/dialog-manage-cloudhook.ts index ce44207e7c..b018af2959 100644 --- a/src/panels/config/cloud/dialog-manage-cloudhook/dialog-manage-cloudhook.ts +++ b/src/panels/config/cloud/dialog-manage-cloudhook/dialog-manage-cloudhook.ts @@ -1,11 +1,9 @@ import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import "@polymer/paper-input/paper-input"; import type { PaperInputElement } from "@polymer/paper-input/paper-input"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { state } from "lit/decorators"; -import "../../../../components/dialog/ha-paper-dialog"; -import type { HaPaperDialog } from "../../../../components/dialog/ha-paper-dialog"; +import { fireEvent } from "../../../../common/dom/fire_event"; import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; @@ -19,11 +17,13 @@ export class DialogManageCloudhook extends LitElement { @state() private _params?: WebhookDialogParams; - public async showDialog(params: WebhookDialogParams) { + public showDialog(params: WebhookDialogParams) { this._params = params; - // Wait till dialog is rendered. - await this.updateComplete; - this._dialog.open(); + } + + public closeDialog() { + this._params = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); } protected render() { @@ -39,14 +39,14 @@ export class DialogManageCloudhook extends LitElement { ) : documentationUrl(this.hass!, `/integrations/${webhook.domain}/`); return html` - -

    - ${this.hass!.localize( - "ui.panel.config.cloud.dialog_cloudhook.webhook_for", - "name", - webhook.name - )} -

    +

    ${this.hass!.localize( @@ -79,36 +79,29 @@ export class DialogManageCloudhook extends LitElement {

    -
    - - ${this.hass!.localize( - "ui.panel.config.cloud.dialog_cloudhook.view_documentation" - )} - - ${this.hass!.localize( - "ui.panel.config.cloud.dialog_cloudhook.close" - )} -
    -
    + + + ${this.hass!.localize( + "ui.panel.config.cloud.dialog_cloudhook.view_documentation" + )} + + + + ${this.hass!.localize("ui.panel.config.cloud.dialog_cloudhook.close")} + + `; } - private get _dialog(): HaPaperDialog { - return this.shadowRoot!.querySelector("ha-paper-dialog")!; - } - private get _paperInput(): PaperInputElement { return this.shadowRoot!.querySelector("paper-input")!; } - private _closeDialog() { - this._dialog.close(); - } - private async _disableWebhook() { showConfirmationDialog(this, { text: this.hass!.localize( @@ -118,7 +111,7 @@ export class DialogManageCloudhook extends LitElement { confirmText: this.hass!.localize("ui.common.disable"), confirm: () => { this._params!.disableHook(); - this._closeDialog(); + this.closeDialog(); }, }); } @@ -147,7 +140,7 @@ export class DialogManageCloudhook extends LitElement { return [ haStyle, css` - ha-paper-dialog { + ha-dialog { width: 650px; } paper-input { @@ -156,7 +149,7 @@ export class DialogManageCloudhook extends LitElement { button.link { color: var(--primary-color); } - .paper-dialog-buttons a { + a { text-decoration: none; } `, diff --git a/src/panels/config/integrations/integration-panels/zha/zha-add-group-page.ts b/src/panels/config/integrations/integration-panels/zha/zha-add-group-page.ts index 067648de05..4c18a4e2b9 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-add-group-page.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-add-group-page.ts @@ -90,7 +90,7 @@ export class ZHAAddGroupPage extends LitElement { > -
    +
    -
    +
    -
    +
    - -

    OpenZwave internal logfile

    - + +
    [[_ozwLog]]
    - - +
    + `; } @@ -56,7 +54,6 @@ class ZwaveLogDialog extends EventsMixin(PolymerElement) { this._opened = true; this._dialogClosedCallback = dialogClosedCallback; this._numLogLines = _numLogLines; - setTimeout(() => this.$.pwaDialog.center(), 0); if (_tail) { this.setProperties({ _intervalId: setInterval(() => { @@ -66,6 +63,14 @@ class ZwaveLogDialog extends EventsMixin(PolymerElement) { } } + closeDialog() { + clearInterval(this._intervalId); + this._opened = false; + const closedEvent = true; + this._dialogClosedCallback({ closedEvent }); + this._dialogClosedCallback = null; + } + async _refreshLog() { const info = await this.hass.callApi( "GET", @@ -73,16 +78,6 @@ class ZwaveLogDialog extends EventsMixin(PolymerElement) { ); this.setProperties({ _ozwLog: info }); } - - _dialogClosed(ev) { - if (ev.target.nodeName === "ZWAVE-LOG-DIALOG") { - clearInterval(this._intervalId); - this._opened = false; - const closedEvent = true; - this._dialogClosedCallback({ closedEvent }); - this._dialogClosedCallback = null; - } - } } customElements.define("zwave-log-dialog", ZwaveLogDialog); diff --git a/src/panels/lovelace/editor/card-editor/hui-dialog-delete-card.ts b/src/panels/lovelace/editor/card-editor/hui-dialog-delete-card.ts index af540b58d5..724b04a3d7 100644 --- a/src/panels/lovelace/editor/card-editor/hui-dialog-delete-card.ts +++ b/src/panels/lovelace/editor/card-editor/hui-dialog-delete-card.ts @@ -1,9 +1,7 @@ -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import deepFreeze from "deep-freeze"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/dialog/ha-paper-dialog"; import type { LovelaceCardConfig } from "../../../../data/lovelace"; import { haStyleDialog } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; diff --git a/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts b/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts index 7116d09d05..3ba941d61e 100755 --- a/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts +++ b/src/panels/lovelace/editor/card-editor/hui-dialog-suggest-card.ts @@ -1,9 +1,7 @@ -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; import deepFreeze from "deep-freeze"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/dialog/ha-paper-dialog"; import "../../../../components/ha-yaml-editor"; import type { HaYamlEditor } from "../../../../components/ha-yaml-editor"; import { LovelaceCardConfig } from "../../../../data/lovelace"; diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index 961f20cd8e..5b2a00fc09 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -197,21 +197,6 @@ export class HuiSaveConfig extends LitElement implements HassDialog { return [ haStyleDialog, css` - @media all and (max-width: 450px), all and (max-height: 500px) { - /* overrule the ha-style-dialog max-height on small screens */ - ha-paper-dialog { - max-height: 100%; - height: 100%; - } - } - @media all and (min-width: 660px) { - ha-paper-dialog { - width: 650px; - } - } - ha-paper-dialog { - max-width: 650px; - } ha-switch { padding-bottom: 16px; } diff --git a/src/panels/lovelace/editor/lovelace-editor/hui-dialog-edit-lovelace.ts b/src/panels/lovelace/editor/lovelace-editor/hui-dialog-edit-lovelace.ts index 7465d3d757..606d822967 100644 --- a/src/panels/lovelace/editor/lovelace-editor/hui-dialog-edit-lovelace.ts +++ b/src/panels/lovelace/editor/lovelace-editor/hui-dialog-edit-lovelace.ts @@ -1,16 +1,14 @@ import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/dialog/ha-paper-dialog"; -import type { HaPaperDialog } from "../../../../components/dialog/ha-paper-dialog"; import "../../../../components/ha-circular-progress"; import type { LovelaceConfig } from "../../../../data/lovelace"; import { haStyleDialog } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; import type { Lovelace } from "../../types"; import "./hui-lovelace-editor"; +import "../../../../components/ha-dialog"; @customElement("hui-dialog-edit-lovelace") export class HuiDialogEditLovelace extends LitElement { @@ -20,44 +18,31 @@ export class HuiDialogEditLovelace extends LitElement { private _config?: LovelaceConfig; - private _saving: boolean; + private _saving = false; - public constructor() { - super(); - this._saving = false; - } - - public async showDialog(lovelace: Lovelace): Promise { + public showDialog(lovelace: Lovelace): void { this._lovelace = lovelace; - if (this._dialog == null) { - await this.updateComplete; - } - const { views, ...lovelaceConfig } = this._lovelace!.config; this._config = lovelaceConfig as LovelaceConfig; - - this._dialog.open(); } public closeDialog(): void { this._config = undefined; - this._dialog.close(); fireEvent(this, "dialog-closed", { dialog: this.localName }); } - private get _dialog(): HaPaperDialog { - return this.shadowRoot!.querySelector("ha-paper-dialog")!; - } - protected render(): TemplateResult { + if (!this._config) { + return html``; + } return html` - -

    - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_lovelace.header" - )} -

    - + +
    ${this.hass!.localize( "ui.panel.lovelace.editor.edit_lovelace.explanation" )} @@ -65,27 +50,26 @@ export class HuiDialogEditLovelace extends LitElement { .hass=${this.hass} .config=${this._config} @lovelace-config-changed=${this._ConfigChanged} - > -
    - ${this.hass!.localize("ui.common.cancel")} - - ${this._saving - ? html`` - : ""} - ${this.hass!.localize("ui.common.save")} + >
    - + + ${this.hass!.localize("ui.common.cancel")} + + + ${this._saving + ? html`` + : ""} + ${this.hass!.localize("ui.common.save")} + `; } @@ -128,26 +112,7 @@ export class HuiDialogEditLovelace extends LitElement { } static get styles(): CSSResultGroup { - return [ - haStyleDialog, - css` - @media all and (max-width: 450px), all and (max-height: 500px) { - /* overrule the ha-style-dialog max-height on small screens */ - ha-paper-dialog { - max-height: 100%; - height: 100%; - } - } - @media all and (min-width: 660px) { - ha-paper-dialog { - width: 650px; - } - } - ha-paper-dialog { - max-width: 650px; - } - `, - ]; + return haStyleDialog; } } diff --git a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts index b29222a70e..c6ede3156c 100644 --- a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts +++ b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts @@ -5,7 +5,6 @@ import "@polymer/paper-listbox/paper-listbox"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/dialog/ha-paper-dialog"; import { createCloseHeading } from "../../../../components/ha-dialog"; import "../../../../components/ha-icon"; import "../../../../components/ha-paper-dropdown-menu"; diff --git a/src/panels/mailbox/ha-dialog-show-audio-message.js b/src/panels/mailbox/ha-dialog-show-audio-message.js index 3b999d8f49..83d3d5bdf0 100644 --- a/src/panels/mailbox/ha-dialog-show-audio-message.js +++ b/src/panels/mailbox/ha-dialog-show-audio-message.js @@ -2,7 +2,7 @@ import "@material/mwc-button"; import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ import { PolymerElement } from "@polymer/polymer/polymer-element"; -import "../../components/dialog/ha-paper-dialog"; +import "../../components/ha-dialog"; import "../../components/ha-circular-progress"; import "../../components/ha-icon"; import "../../components/ha-icon-button"; @@ -19,41 +19,19 @@ class HaDialogShowAudioMessage extends LocalizeMixin(PolymerElement) { .error { color: red; } - @media all and (max-width: 500px) { - ha-paper-dialog { - margin: 0; - width: 100%; - max-height: calc(100% - var(--header-height)); - - position: fixed !important; - bottom: 0px; - left: 0px; - right: 0px; - overflow: scroll; - border-bottom-left-radius: 0px; - border-bottom-right-radius: 0px; - } - } - - ha-paper-dialog { - border-radius: 2px; - } - ha-paper-dialog p { + p { color: var(--secondary-text-color); } - .icon { - float: right; + text-align: right; } - -

    - [[localize('ui.panel.mailbox.playback_title')]] +