[AC-3023] Resolve the capitalization here (#11019)

* Resolve the capitalization here

* Resolve the returned issue on A11y

* Fix the storage bug
This commit is contained in:
cyprain-okeke 2024-09-16 10:14:46 +01:00 committed by GitHub
parent b713e18b1a
commit f816e80314
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 5 deletions

View File

@ -53,10 +53,19 @@
[class]="'tw-grid-cols-' + selectableProducts.length"
>
<div
*ngFor="let selectableProduct of selectableProducts; let i = index"
*ngFor="
let selectableProduct of selectableProducts;
trackBy: manageSelectableProduct;
let i = index
"
[ngClass]="getPlanCardContainerClasses(selectableProduct, i)"
(click)="selectPlan(selectableProduct)"
tabindex="0"
[attr.tabindex]="focusedIndex !== i || isCardDisabled(i) ? '-1' : '0'"
class="product-card"
(keyup)="onKeydown($event, i)"
(focus)="onFocus(i)"
[attr.aria-disabled]="isCardDisabled(i)"
[id]="i + 'a_plan_card'"
>
<div class="tw-relative">
<div

View File

@ -160,6 +160,9 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
showPayment: boolean = false;
totalOpened: boolean = false;
currentPlan: PlanResponse;
currentFocusIndex = 0;
isCardStateDisabled = false;
focusedIndex: number | null = null;
deprecateStripeSourcesAPI: boolean;
@ -255,6 +258,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
setInitialPlanSelection() {
this.focusedIndex = this.selectableProducts.length - 1;
this.selectPlan(this.getPlanByType(ProductTierType.Enterprise));
}
@ -307,15 +311,22 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
if (plan == this.currentPlan) {
cardState = PlanCardState.Disabled;
this.isCardStateDisabled = true;
this.focusedIndex = index;
} else if (plan == this.selectedPlan) {
cardState = PlanCardState.Selected;
this.isCardStateDisabled = false;
this.focusedIndex = index;
} else if (
this.selectedInterval === PlanInterval.Monthly &&
plan.productTier == ProductTierType.Families
) {
cardState = PlanCardState.Disabled;
this.isCardStateDisabled = true;
this.focusedIndex = this.selectableProducts.length - 1;
} else {
cardState = PlanCardState.NotSelected;
this.isCardStateDisabled = false;
}
switch (cardState) {
@ -466,7 +477,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
get storageGb() {
return this.sub?.maxStorageGb - 1;
return this.sub?.maxStorageGb ? this.sub?.maxStorageGb - 1 : 0;
}
passwordManagerSeatTotal(plan: PlanResponse): number {
@ -492,7 +503,8 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
return (
plan.PasswordManager.additionalStoragePricePerGb * Math.abs(this.sub?.maxStorageGb - 1 || 0)
plan.PasswordManager.additionalStoragePricePerGb *
Math.abs(this.sub?.maxStorageGb ? this.sub?.maxStorageGb - 1 : 0 || 0)
);
}
@ -861,4 +873,44 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
return this.i18nService.t("planNameTeams");
}
}
onKeydown(event: KeyboardEvent, index: number) {
const cardElements = Array.from(document.querySelectorAll(".product-card")) as HTMLElement[];
let newIndex = index;
const direction = event.key === "ArrowRight" || event.key === "ArrowDown" ? 1 : -1;
if (["ArrowRight", "ArrowDown", "ArrowLeft", "ArrowUp"].includes(event.key)) {
do {
newIndex = (newIndex + direction + cardElements.length) % cardElements.length;
} while (this.isCardDisabled(newIndex) && newIndex !== index);
event.preventDefault();
setTimeout(() => {
const card = cardElements[newIndex];
if (
!(
card.classList.contains("tw-bg-secondary-100") &&
card.classList.contains("tw-text-muted")
)
) {
card?.focus();
}
}, 0);
}
}
onFocus(index: number) {
this.focusedIndex = index;
this.selectPlan(this.selectableProducts[index]);
}
isCardDisabled(index: number): boolean {
const card = this.selectableProducts[index];
return card === (this.currentPlan || this.isCardStateDisabled);
}
manageSelectableProduct(index: number) {
return index;
}
}

View File

@ -9062,7 +9062,7 @@
"message": "Directory integration"
},
"passwordLessSso": {
"message": "PasswordLess SSO"
"message": "Passwordless SSO"
},
"accountRecovery": {
"message": "Account recovery"