diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs
index efed17792f..769dd58a12 100644
--- a/build-scripts/webpack.cjs
+++ b/build-scripts/webpack.cjs
@@ -165,6 +165,7 @@ const createWebpackConfig = ({
"lit/directives/guard$": "lit/directives/guard.js",
"lit/directives/cache$": "lit/directives/cache.js",
"lit/directives/repeat$": "lit/directives/repeat.js",
+ "lit/directives/live$": "lit/directives/live.js",
"lit/polyfill-support$": "lit/polyfill-support.js",
"@lit-labs/virtualizer/layouts/grid":
"@lit-labs/virtualizer/layouts/grid.js",
diff --git a/package.json b/package.json
index 473d3b7b27..361e74d119 100644
--- a/package.json
+++ b/package.json
@@ -62,6 +62,7 @@
"@material/mwc-dialog": "0.27.0",
"@material/mwc-drawer": "0.27.0",
"@material/mwc-fab": "0.27.0",
+ "@material/mwc-floating-label": "0.27.0",
"@material/mwc-formfield": "0.27.0",
"@material/mwc-icon-button": "0.27.0",
"@material/mwc-linear-progress": "0.27.0",
diff --git a/src/auth/ha-auth-flow.ts b/src/auth/ha-auth-flow.ts
index b64cd092dd..f8f00cc972 100644
--- a/src/auth/ha-auth-flow.ts
+++ b/src/auth/ha-auth-flow.ts
@@ -77,11 +77,11 @@ export class HaAuthFlow extends LitElement {
protected render() {
return html`
+ ha-auth-form .root > * {
+ display: block;
+ }
+ ha-auth-form .root > *:not([own-margin]):not(:last-child) {
+ margin-bottom: 24px;
+ }
+ ha-auth-form ha-alert[own-margin] {
+ margin-bottom: 4px;
+ }
+
+ ${super.render()}
+ `;
+ }
}
declare global {
diff --git a/src/auth/ha-auth-textfield.ts b/src/auth/ha-auth-textfield.ts
index 7c4bb2c6cc..123deef03f 100644
--- a/src/auth/ha-auth-textfield.ts
+++ b/src/auth/ha-auth-textfield.ts
@@ -1,11 +1,79 @@
+/* eslint-disable lit/value-after-constraints */
/* eslint-disable lit/prefer-static-styles */
-import { html } from "lit";
+import { floatingLabel } from "@material/mwc-floating-label/mwc-floating-label-directive";
+import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators";
+import { ifDefined } from "lit/directives/if-defined";
+import { live } from "lit/directives/live";
import { HaTextField } from "../components/ha-textfield";
-import "@material/mwc-textfield/mwc-textfield.css";
@customElement("ha-auth-textfield")
export class HaAuthTextField extends HaTextField {
+ protected renderLabel(): TemplateResult | string {
+ return !this.label
+ ? ""
+ : html`
+ ${this.label}
+ `;
+ }
+
+ protected renderInput(shouldRenderHelperText: boolean): TemplateResult {
+ const minOrUndef = this.minLength === -1 ? undefined : this.minLength;
+ const maxOrUndef = this.maxLength === -1 ? undefined : this.maxLength;
+ const autocapitalizeOrUndef = this.autocapitalize
+ ? (this.autocapitalize as
+ | "off"
+ | "none"
+ | "on"
+ | "sentences"
+ | "words"
+ | "characters")
+ : undefined;
+ const showValidationMessage = this.validationMessage && !this.isUiValid;
+ const ariaLabelledbyOrUndef = this.label ? this.name : undefined;
+ const ariaControlsOrUndef = shouldRenderHelperText
+ ? "helper-text"
+ : undefined;
+ const ariaDescribedbyOrUndef =
+ this.focused || this.helperPersistent || showValidationMessage
+ ? "helper-text"
+ : undefined;
+ // TODO: live() directive needs casting for lit-analyzer
+ // https://github.com/runem/lit-analyzer/pull/91/files
+ // TODO: lit-analyzer labels min/max as (number|string) instead of string
+ return html` `;
+ }
+
public render() {
return html`