[PM-8924] Login component tab and keyboard navigation fixes (#9707)

* tab and keyboard navigation fixes

* PM-8924 - Improve login component keyboard and mouse navigation scenarios

Co-authored-by: Ike Kottlowski <ikottlowski@bitwarden.com>

---------

Co-authored-by: Jared Snider <jsnider@bitwarden.com>
This commit is contained in:
Ike 2024-06-20 14:20:54 -07:00 committed by GitHub
parent 82f8641926
commit d74435dba7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 17 deletions

View File

@ -7,13 +7,7 @@
<div class="tw-mb-3"> <div class="tw-mb-3">
<bit-form-field> <bit-form-field>
<bit-label>{{ "emailAddress" | i18n }}</bit-label> <bit-label>{{ "emailAddress" | i18n }}</bit-label>
<input <input bitInput type="email" formControlName="email" appAutofocus />
bitInput
type="email"
formControlName="email"
appAutofocus
(keyup.enter)="validateEmail()"
/>
</bit-form-field> </bit-form-field>
</div> </div>
@ -27,7 +21,7 @@
<div class="tw-mb-3"> <div class="tw-mb-3">
<button <button
bitButton bitButton
type="button" type="submit"
buttonType="primary" buttonType="primary"
class="tw-w-full" class="tw-w-full"
(click)="validateEmail()" (click)="validateEmail()"
@ -54,8 +48,19 @@
<p class="tw-m-0 tw-text-sm"> <p class="tw-m-0 tw-text-sm">
{{ "newAroundHere" | i18n }} {{ "newAroundHere" | i18n }}
<!--mousedown event is used over click because it prevents the validation from firing --> <!-- Two notes:
<a bitLink href="#" (mousedown)="goToRegister()">{{ "createAccount" | i18n }}</a> (1) We check the value and validity of email so we don't send an invalid email to autofill
on load of register for both enter and mouse based navigation
(2) We use mousedown to trigger navigation so that the onBlur form validation does not fire
and move the create account link down the page on click which causes the user to miss actually
clicking on the link. Mousedown fires before onBlur.
-->
<a
[routerLink]="registerRoute"
[queryParams]="emailFormControl.valid ? { email: emailFormControl.value } : {}"
(mousedown)="goToRegister()"
>{{ "createAccount" | i18n }}</a
>
</p> </p>
</ng-container> </ng-container>
@ -67,7 +72,7 @@
<button type="button" bitSuffix bitIconButton bitPasswordInputToggle></button> <button type="button" bitSuffix bitIconButton bitPasswordInputToggle></button>
</bit-form-field> </bit-form-field>
<a <a
class="-tw-mt-2" class="tw-mt-2"
routerLink="/hint" routerLink="/hint"
(mousedown)="goToHint()" (mousedown)="goToHint()"
(click)="setLoginEmailValues()" (click)="setLoginEmailValues()"

View File

@ -165,10 +165,10 @@ export class LoginComponent extends BaseLoginComponent implements OnInit {
} }
async goToRegister() { async goToRegister() {
const email = this.formGroup.value.email; if (this.emailFormControl.valid) {
await this.router.navigate([this.registerRoute], {
if (email) { queryParams: { email: this.emailFormControl.value },
await this.router.navigate([this.registerRoute], { queryParams: { email: email } }); });
return; return;
} }

View File

@ -47,6 +47,10 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
validatedEmail = false; validatedEmail = false;
paramEmailSet = false; paramEmailSet = false;
get emailFormControl() {
return this.formGroup.controls.email;
}
formGroup = this.formBuilder.group({ formGroup = this.formBuilder.group({
email: ["", [Validators.required, Validators.email]], email: ["", [Validators.required, Validators.email]],
masterPassword: [ masterPassword: [
@ -277,8 +281,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
async validateEmail() { async validateEmail() {
this.formGroup.controls.email.markAsTouched(); this.formGroup.controls.email.markAsTouched();
const emailInvalid = this.formGroup.get("email").invalid; const emailValid = this.formGroup.get("email").valid;
if (!emailInvalid) { if (emailValid) {
this.toggleValidateEmail(true); this.toggleValidateEmail(true);
await this.getLoginWithDevice(this.loggedEmail); await this.getLoginWithDevice(this.loggedEmail);
} }