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`