mirror of
https://github.com/bitwarden/desktop.git
synced 2024-11-28 12:35:40 +01:00
[AccountSwitching]Make account switcher accessible (#1289)
* Make account switcher keyboard accessible * ScreenReader: Announce submenu and expansion * ScreenReader: Announc switch account button with account info * Fix tab focus on dropdown * Fix esc not changing state * Fix linting issues Co-authored-by: Hinton <oscar@oscarhinton.com>
This commit is contained in:
parent
3e8705d548
commit
2b58861296
@ -1,9 +1,12 @@
|
|||||||
<a
|
<button
|
||||||
class="account-switcher"
|
class="account-switcher"
|
||||||
(click)="toggle()"
|
(click)="toggle()"
|
||||||
cdkOverlayOrigin
|
cdkOverlayOrigin
|
||||||
#trigger="cdkOverlayOrigin"
|
#trigger="cdkOverlayOrigin"
|
||||||
[hidden]="!showSwitcher"
|
[hidden]="!showSwitcher"
|
||||||
|
aria-haspopup="menu"
|
||||||
|
aria-expanded="isOpen"
|
||||||
|
aria-controls="cdk-overlay-container"
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="activeAccountEmail != null; else noActiveAccount">
|
<ng-container *ngIf="activeAccountEmail != null; else noActiveAccount">
|
||||||
<app-avatar
|
<app-avatar
|
||||||
@ -13,6 +16,7 @@
|
|||||||
[fontSize]="14"
|
[fontSize]="14"
|
||||||
[dynamic]="true"
|
[dynamic]="true"
|
||||||
*ngIf="activeAccountEmail != null"
|
*ngIf="activeAccountEmail != null"
|
||||||
|
aria-hidden="true"
|
||||||
></app-avatar>
|
></app-avatar>
|
||||||
<span>{{ activeAccountEmail }}</span>
|
<span>{{ activeAccountEmail }}</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -24,26 +28,33 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
[ngClass]="{ 'bwi-angle-down': !isOpen, 'bwi-chevron-up': isOpen }"
|
[ngClass]="{ 'bwi-angle-down': !isOpen, 'bwi-chevron-up': isOpen }"
|
||||||
></i>
|
></i>
|
||||||
</a>
|
</button>
|
||||||
|
|
||||||
<ng-template
|
<ng-template
|
||||||
cdkConnectedOverlay
|
cdkConnectedOverlay
|
||||||
[cdkConnectedOverlayOrigin]="trigger"
|
[cdkConnectedOverlayOrigin]="trigger"
|
||||||
[cdkConnectedOverlayHasBackdrop]="true"
|
[cdkConnectedOverlayHasBackdrop]="true"
|
||||||
[cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop'"
|
[cdkConnectedOverlayBackdropClass]="'cdk-overlay-transparent-backdrop'"
|
||||||
(backdropClick)="toggle()"
|
(backdropClick)="close()"
|
||||||
|
(detach)="close()"
|
||||||
[cdkConnectedOverlayOpen]="showSwitcher && isOpen"
|
[cdkConnectedOverlayOpen]="showSwitcher && isOpen"
|
||||||
[cdkConnectedOverlayPositions]="overlayPostition"
|
[cdkConnectedOverlayPositions]="overlayPostition"
|
||||||
cdkConnectedOverlayMinWidth="250px"
|
cdkConnectedOverlayMinWidth="250px"
|
||||||
>
|
>
|
||||||
<div class="account-switcher-dropdown" [@transformPanel]="'open'">
|
<div
|
||||||
|
class="account-switcher-dropdown"
|
||||||
|
[@transformPanel]="'open'"
|
||||||
|
cdkTrapFocus
|
||||||
|
cdkTrapFocusAutoCapture
|
||||||
|
>
|
||||||
<div class="accounts" *ngIf="numberOfAccounts > 0">
|
<div class="accounts" *ngIf="numberOfAccounts > 0">
|
||||||
<a
|
<button
|
||||||
*ngFor="let a of accounts | keyvalue"
|
*ngFor="let a of accounts | keyvalue"
|
||||||
class="account"
|
class="account"
|
||||||
[ngClass]="{ active: a.value.profile.authenticationStatus == 'active' }"
|
[ngClass]="{ active: a.value.profile.authenticationStatus == 'active' }"
|
||||||
href="#"
|
(click)="switch(a.key)"
|
||||||
(mousedown)="switch(a.key)"
|
appA11yTitle="{{ 'loggedInAsOn' | i18n: a.value.profile.email:a.value.serverUrl }}"
|
||||||
|
attr.aria-label="{{ 'switchAccount' | i18n }}"
|
||||||
>
|
>
|
||||||
<app-avatar
|
<app-avatar
|
||||||
[data]="a.value.profile.email"
|
[data]="a.value.profile.email"
|
||||||
@ -52,30 +63,33 @@
|
|||||||
[fontSize]="14"
|
[fontSize]="14"
|
||||||
[dynamic]="true"
|
[dynamic]="true"
|
||||||
*ngIf="a.value.profile.email != null"
|
*ngIf="a.value.profile.email != null"
|
||||||
|
aria-hidden="true"
|
||||||
></app-avatar>
|
></app-avatar>
|
||||||
<div class="accountInfo">
|
<div class="accountInfo">
|
||||||
<span class="email">{{ a.value.profile.email }}</span>
|
<span class="email" aria-hidden="true">{{ a.value.profile.email }}</span>
|
||||||
<span class="server" *ngIf="a.value.serverUrl != 'bitwarden.com'">{{
|
<span class="server" aria-hidden="true" *ngIf="a.value.serverUrl != 'bitwarden.com'">{{
|
||||||
a.value.serverUrl
|
a.value.serverUrl
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="status">{{ a.value.profile.authenticationStatus }}</span>
|
<span class="status" aria-hidden="true">{{ a.value.profile.authenticationStatus }}</span>
|
||||||
</div>
|
</div>
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-unlock bwi-2x text-muted"
|
class="bwi bwi-unlock bwi-2x text-muted"
|
||||||
|
aria-hidden="true"
|
||||||
*ngIf="a.value.profile.authenticationStatus == 'unlocked'"
|
*ngIf="a.value.profile.authenticationStatus == 'unlocked'"
|
||||||
></i>
|
></i>
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-lock bwi-2x text-muted"
|
class="bwi bwi-lock bwi-2x text-muted"
|
||||||
|
aria-hidden="true"
|
||||||
*ngIf="a.value.profile.authenticationStatus == 'locked'"
|
*ngIf="a.value.profile.authenticationStatus == 'locked'"
|
||||||
></i>
|
></i>
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="activeAccountEmail != null">
|
<ng-container *ngIf="activeAccountEmail != null">
|
||||||
<div class="border" *ngIf="numberOfAccounts > 0"></div>
|
<div class="border" *ngIf="numberOfAccounts > 0"></div>
|
||||||
<ng-container *ngIf="numberOfAccounts < 4">
|
<ng-container *ngIf="numberOfAccounts < 4">
|
||||||
<a class="add" routerLink="/login" (click)="addAccount()">
|
<button class="add" routerLink="/login" (click)="addAccount()">
|
||||||
<i class="bwi bwi-plus" aria-hidden="true"></i> {{ "addAccount" | i18n }}
|
<i class="bwi bwi-plus" aria-hidden="true"></i> {{ "addAccount" | i18n }}
|
||||||
</a>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="numberOfAccounts == 4">
|
<ng-container *ngIf="numberOfAccounts == 4">
|
||||||
<span class="accountLimitReached">{{ "accountSwitcherLimitReached" | i18n }} </span>
|
<span class="accountLimitReached">{{ "accountSwitcherLimitReached" | i18n }} </span>
|
||||||
|
@ -107,14 +107,18 @@ export class AccountSwitcherComponent implements OnInit {
|
|||||||
this.isOpen = !this.isOpen;
|
this.isOpen = !this.isOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.isOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
async switch(userId: string) {
|
async switch(userId: string) {
|
||||||
this.toggle();
|
this.close();
|
||||||
|
|
||||||
this.messagingService.send("switchAccount", { userId: userId });
|
this.messagingService.send("switchAccount", { userId: userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async addAccount() {
|
async addAccount() {
|
||||||
this.toggle();
|
this.close();
|
||||||
await this.stateService.setActiveUser(null);
|
await this.stateService.setActiveUser(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
width: auto;
|
||||||
|
|
||||||
@include themify($themes) {
|
@include themify($themes) {
|
||||||
color: themed("accountSwitcherTextColor");
|
color: themed("accountSwitcherTextColor");
|
||||||
}
|
}
|
||||||
@ -114,9 +118,11 @@
|
|||||||
0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
|
|
||||||
a {
|
button {
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
width: 100%;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
display: block;
|
|
||||||
|
|
||||||
@include themify($themes) {
|
@include themify($themes) {
|
||||||
color: themed("textColor");
|
color: themed("textColor");
|
||||||
@ -141,6 +147,7 @@
|
|||||||
|
|
||||||
.accountInfo {
|
.accountInfo {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
.email {
|
.email {
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
@ -173,6 +180,7 @@
|
|||||||
|
|
||||||
.add {
|
.add {
|
||||||
margin: 4px 0;
|
margin: 4px 0;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accountLimitReached {
|
.accountLimitReached {
|
||||||
|
Loading…
Reference in New Issue
Block a user