Skip to content

Commit

Permalink
feat(accessibility): improve TAB key navigation in mini basket by usi…
Browse files Browse the repository at this point in the history
…ng ngbDropdown (#1694)
  • Loading branch information
andreassteinmann committed Sep 6, 2024
1 parent f6984d0 commit bd0a6f7
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 33 deletions.
8 changes: 4 additions & 4 deletions src/app/shell/header/mini-basket/mini-basket.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
[ngClass]="{ 'd-none': view !== 'full', 'd-md-block': view !== 'small', 'mini-cart-active': !isCollapsed }"
ishClickOutside
(isClickedOutside)="collapse()"
ngbDropdown
#miniBasketDropdown="ngbDropdown"
>
<button
type="button"
class="btn btn-link"
(click)="toggleCollapse()"
ngbDropdownToggle
aria-haspopup="menu"
[attr.aria-expanded]="!isCollapsed"
[attr.aria-label]="'shopping_cart.ministatus.label' | translate : { '0': itemCount$ | async }"
aria-controls="mini_basket_content"
>
<fa-icon [icon]="['fas', 'shopping-cart']" class="header-icon" />
<span>{{ 'shopping_cart.ministatus.items.text' | translate : { '0': itemCount$ | async } }}</span>
Expand All @@ -20,7 +20,7 @@
</ng-container>
</button>

<div *ngIf="!isCollapsed" class="mini-cart" id="mini_basket_content">
<div ngbDropdownMenu class="mini-cart">
<ish-lazy-mini-basket-content />
</div>
</div>
Expand Down
34 changes: 19 additions & 15 deletions src/app/shell/header/mini-basket/mini-basket.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { MockComponent } from 'ng-mocks';
import { EMPTY, of } from 'rxjs';
Expand Down Expand Up @@ -34,7 +36,7 @@ describe('Mini Basket Component', () => {
MockComponent(LazyMiniBasketContentComponent),
PricePipe,
],
imports: [TranslateModule.forRoot()],
imports: [NgbDropdownModule, TranslateModule.forRoot()],
providers: [
{ provide: AccountFacade, useFactory: () => instance(accountFacade) },
{ provide: AppFacade, useFactory: () => instance(appFacade) },
Expand Down Expand Up @@ -86,21 +88,23 @@ describe('Mini Basket Component', () => {
expect(element.textContent.replace(/ /g, '')).toMatchInlineSnapshot(`"30items/$141,796.98"`);
});

it('should set isCollapsed to proper value if toggleCollapsed is called', () => {
component.isCollapsed = true;
component.toggleCollapse();
expect(component.isCollapsed).toBeFalsy();
component.toggleCollapse();
expect(component.isCollapsed).toBeTruthy();
});
it('should toggle dropdown menu when clicked', () => {
const toggleButton = fixture.debugElement.query(By.css('button[ngbDropdownToggle]')).nativeElement;
toggleButton.click();
fixture.detectChanges();

it('should set isCollapsed to true if collapse() is called', () => {
component.collapse();
expect(component.isCollapsed).toBeTruthy();
});
const dropdownMenu = fixture.debugElement.query(By.css('div[ngbDropdownMenu]'));
// menu should be present
expect(dropdownMenu).toBeTruthy();

it('should set isCollapsed to false if open() is called', () => {
component.open();
expect(component.isCollapsed).toBeFalsy();
// check if menu is shown
expect(dropdownMenu.nativeElement.classList).toContain('show');

// click again to close
toggleButton.click();
fixture.detectChanges();

// menu should be hidden
expect(dropdownMenu.nativeElement.classList).not.toContain('show');
});
});
13 changes: 6 additions & 7 deletions src/app/shell/header/mini-basket/mini-basket.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
DestroyRef,
Input,
OnInit,
ViewChild,
inject,
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
import { Observable, concat, of, timer } from 'rxjs';
import { filter, map, switchMap } from 'rxjs/operators';

Expand All @@ -24,6 +26,8 @@ import { whenTruthy } from 'ish-core/utils/operators';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MiniBasketComponent implements OnInit {
@ViewChild('miniBasketDropdown', { static: true }) miniBasketDropdown!: NgbDropdown;

basketAnimation$: Observable<string>;
itemTotal$: Observable<PriceItem>;
itemCount$: Observable<number>;
Expand Down Expand Up @@ -74,18 +78,12 @@ export class MiniBasketComponent implements OnInit {
});
}

/**
* Toggle the collapse state of the mini basket programmatically.
*/
toggleCollapse() {
this.isCollapsed = !this.isCollapsed;
}

/**
* Collapse the mini basket programmatically.
*/
collapse() {
this.isCollapsed = true;
this.miniBasketDropdown.close();
this.cdRef.markForCheck();
}

Expand All @@ -95,6 +93,7 @@ export class MiniBasketComponent implements OnInit {
// visible-for-testing
open() {
this.isCollapsed = false;
this.miniBasketDropdown.open();
this.cdRef.markForCheck();
}
}
4 changes: 4 additions & 0 deletions src/styles/components/header/header-sticky.scss
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@
}
}
}

.mini-cart {
top: -2px !important;
}
}
}

Expand Down
1 change: 0 additions & 1 deletion src/styles/components/header/language-switch.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
.dropdown-menu {
position: absolute;
min-width: 50px;
margin-top: 0;
}

.language-switch-button {
Expand Down
13 changes: 9 additions & 4 deletions src/styles/pages/checkout/quick-cart.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

.quick-cart-link {
position: relative;
padding: 0 $space-default;
padding: 0;
margin-left: $space-default;
background: $color-tertiary;

Expand All @@ -26,10 +26,14 @@
font-size: 17px;
color: $text-color-secondary;
}

&::after {
display: none;
}
}

> .btn-link {
padding: $space-default * 0.5;
padding: ($space-default * 0.5) $space-default;
white-space: nowrap;
}

Expand All @@ -49,7 +53,8 @@

.mini-cart {
position: absolute;
right: -1px;
top: -1px !important;
// left: 1px !important;
z-index: 9999;
width: 310px;
padding: $space-default;
Expand Down Expand Up @@ -91,7 +96,7 @@

@include clearfix();

padding: $space-default 0;
padding: $space-default 2px $space-default 0;

& ~ .product-row {
border-top: $border-width-default solid $border-color-light;
Expand Down
2 changes: 1 addition & 1 deletion src/styles/themes/b2b/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ $input-accent-color: $CORPORATE-DARK;
// Dropdown
// Dropdown menu container and contents.

$dropdown-border-color: rgb(0 0 0 / 0.15);
$dropdown-border-color: $color-inverse;

// Grid breakpoints
// Define the minimum dimensions at which your layout will change,
Expand Down
2 changes: 1 addition & 1 deletion src/styles/themes/b2c/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ $input-accent-color: $CORPORATE-DARK;
// Dropdown
// Dropdown menu container and contents.

$dropdown-border-color: rgb(0 0 0 / 0.15);
$dropdown-border-color: $color-inverse;

// Grid breakpoints
// Define the minimum dimensions at which your layout will change,
Expand Down

0 comments on commit bd0a6f7

Please sign in to comment.