diff --git a/web/src/elements/forms/FormElement.ts b/web/src/elements/forms/FormElement.ts index bb408af88..b28c3bd7d 100644 --- a/web/src/elements/forms/FormElement.ts +++ b/web/src/elements/forms/FormElement.ts @@ -6,19 +6,20 @@ import { customElement, property } from "lit/decorators.js"; import PFForm from "@patternfly/patternfly/components/Form/form.css"; import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css"; +import PFBase from "@patternfly/patternfly/patternfly-base.css"; import { ErrorDetail } from "@goauthentik/api"; /** * This is used in two places outside of Flow, and in both cases is used primarily to - * display content, not take input. It displays the TOPT QR code, and the static + * display content, not take input. It displays the TOTP QR code, and the static * recovery tokens. But it's used a lot in Flow. */ @customElement("ak-form-element") export class FormElement extends AKElement { static get styles(): CSSResult[] { - return [PFForm, PFFormControl]; + return [PFBase, PFForm, PFFormControl]; } @property() @@ -28,7 +29,16 @@ export class FormElement extends AKElement { required = false; @property({ attribute: false }) - errors?: ErrorDetail[]; + set errors(value: ErrorDetail[] | undefined) { + this._errors = value; + const hasError = (value || []).length > 0; + this.querySelectorAll("input").forEach((input) => { + input.setAttribute("aria-invalid", hasError.toString()); + }); + this.requestUpdate(); + } + + _errors?: ErrorDetail[]; updated(): void { this.querySelectorAll("input[autofocus]").forEach((input) => { @@ -45,8 +55,12 @@ export class FormElement extends AKElement { : html``} - ${(this.errors || []).map((error) => { - return html`

${error.string}

`; + ${(this._errors || []).map((error) => { + return html`

+ + ${error.string} +

`; })} `; } diff --git a/web/src/flow/stages/password/PasswordStage.ts b/web/src/flow/stages/password/PasswordStage.ts index 774a1f5b3..36e301749 100644 --- a/web/src/flow/stages/password/PasswordStage.ts +++ b/web/src/flow/stages/password/PasswordStage.ts @@ -28,6 +28,11 @@ export class PasswordStage extends BaseStage 0; + } + renderInput(): HTMLInputElement { this.input = document.createElement("input"); this.input.type = "password"; @@ -38,6 +43,7 @@ export class PasswordStage extends BaseStage {