From 9bf41a37b458adc46e5dd4b080837fa46ebc812f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 9 Oct 2021 03:41:36 -0700 Subject: [PATCH] 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, })} `; })}