diff --git a/gallery/src/pages/components/ha-selector.ts b/gallery/src/pages/components/ha-selector.ts index e2cd0425ec..ce015a3756 100644 --- a/gallery/src/pages/components/ha-selector.ts +++ b/gallery/src/pages/components/ha-selector.ts @@ -50,7 +50,11 @@ const SCHEMAS: { action: { name: "Action", selector: { action: {} } }, text: { name: "Text", - selector: { text: { multiline: false } }, + selector: { text: {} }, + }, + password: { + name: "Password", + selector: { text: { type: "password" } }, }, text_multiline: { name: "Text multiline", diff --git a/hassio/src/dialogs/registries/dialog-hassio-registries.ts b/hassio/src/dialogs/registries/dialog-hassio-registries.ts index 1eb0072a3f..5f7d1967ae 100644 --- a/hassio/src/dialogs/registries/dialog-hassio-registries.ts +++ b/hassio/src/dialogs/registries/dialog-hassio-registries.ts @@ -19,22 +19,21 @@ import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; import type { HomeAssistant } from "../../../../src/types"; import { RegistriesDialogParams } from "./show-dialog-registries"; -const SCHEMA = [ +const SCHEMA: HaFormSchema[] = [ { - type: "string", name: "registry", required: true, + selector: { text: {} }, }, { - type: "string", name: "username", required: true, + selector: { text: {} }, }, { - type: "string", name: "password", required: true, - format: "password", + selector: { text: { type: "password" } }, }, ]; diff --git a/src/components/ha-selector/ha-selector-text.ts b/src/components/ha-selector/ha-selector-text.ts index f0a093de79..d9a1f87bfc 100644 --- a/src/components/ha-selector/ha-selector-text.ts +++ b/src/components/ha-selector/ha-selector-text.ts @@ -1,10 +1,12 @@ +import "@material/mwc-textarea/mwc-textarea"; +import "@material/mwc-textfield/mwc-textfield"; +import { mdiEye, mdiEyeOff } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement } from "lit"; -import { customElement, property } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import { StringSelector } from "../../data/selector"; import { HomeAssistant } from "../../types"; -import "@material/mwc-textfield/mwc-textfield"; -import "@material/mwc-textarea/mwc-textarea"; +import "../ha-icon-button"; @customElement("ha-selector-text") export class HaTextSelector extends LitElement { @@ -20,6 +22,8 @@ export class HaTextSelector extends LitElement { @property({ type: Boolean }) public disabled = false; + @state() private _unmaskedPassword = false; + protected render() { if (this.selector.text?.multiline) { return html``; } return html``; + .value=${this.value || ""} + .placeholder=${this.placeholder || ""} + .disabled=${this.disabled} + .type=${this._unmaskedPassword ? "text" : this.selector.text?.type} + @input=${this._handleChange} + .label=${this.label || ""} + .suffix=${this.selector.text?.type === "password" + ? // reserve some space for the icon. + html`
` + : this.selector.text?.suffix} + required + > + ${this.selector.text?.type === "password" + ? html`` + : ""}`; + } + + private _toggleUnmaskedPassword(): void { + this._unmaskedPassword = !this._unmaskedPassword; } private _handleChange(ev) { @@ -54,10 +75,22 @@ export class HaTextSelector extends LitElement { static get styles(): CSSResultGroup { return css` + :host { + display: block; + position: relative; + } mwc-textfield, mwc-textarea { width: 100%; } + ha-icon-button { + position: absolute; + top: 16px; + right: 16px; + --mdc-icon-button-size: 24px; + --mdc-icon-size: 20px; + color: var(--secondary-text-color); + } `; } } diff --git a/src/data/selector.ts b/src/data/selector.ts index 3bb2999877..2ea7e0c2fe 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -95,7 +95,22 @@ export interface ActionSelector { export interface StringSelector { text: { - multiline: boolean; + multiline?: boolean; + type?: + | "number" + | "text" + | "search" + | "tel" + | "url" + | "email" + | "password" + | "date" + | "month" + | "week" + | "time" + | "datetime-local" + | "color"; + suffix?: string; }; } diff --git a/src/onboarding/onboarding-create-user.ts b/src/onboarding/onboarding-create-user.ts index c511d34a46..1855141a60 100644 --- a/src/onboarding/onboarding-create-user.ts +++ b/src/onboarding/onboarding-create-user.ts @@ -18,10 +18,18 @@ import { onboardUserStep } from "../data/onboarding"; import { PolymerChangedEvent } from "../polymer-types"; const CREATE_USER_SCHEMA: HaFormSchema[] = [ - { type: "string", name: "name", required: true }, - { type: "string", name: "username", required: true }, - { type: "string", name: "password", required: true }, - { type: "string", name: "password_confirm", required: true }, + { name: "name", required: true, selector: { text: {} } }, + { name: "username", required: true, selector: { text: {} } }, + { + name: "password", + required: true, + selector: { text: { type: "password" } }, + }, + { + name: "password_confirm", + required: true, + selector: { text: { type: "password" } }, + }, ]; @customElement("onboarding-create-user") diff --git a/src/panels/config/integrations/integration-panels/zha/zha-config-dashboard.ts b/src/panels/config/integrations/integration-panels/zha/zha-config-dashboard.ts index 8983508074..710328c269 100644 --- a/src/panels/config/integrations/integration-panels/zha/zha-config-dashboard.ts +++ b/src/panels/config/integrations/integration-panels/zha/zha-config-dashboard.ts @@ -106,7 +106,7 @@ class ZHAConfigDashboard extends LitElement { ${this._configuration ? Object.entries(this._configuration.schemas).map( - ([section, schema]) => html` html`` : this._step.type === "form" - ? html`