Skip to content
Snippets Groups Projects
Commit 42a551b3 authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-6103 OZG-6631 Fix popup list focus' (#750) from...

Merge pull request 'OZG-6103 OZG-6631 Fix popup list focus' (#750) from OZG-6103-popup-focus into master

Reviewed-on: https://git.ozg-sh.de/ozgcloud-app/alfa/pulls/750


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents 26a8da9f 3335f642
Branches
Tags
No related merge requests found
import { getElementFromFixture } from '@alfa-client/test-utils'; import { getElementFromFixture } from '@alfa-client/test-utils';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
import { PopupComponent } from './popup.component'; import { PopupComponent } from './popup.component';
...@@ -40,6 +40,46 @@ describe('PopupComponent', () => { ...@@ -40,6 +40,46 @@ describe('PopupComponent', () => {
}); });
}); });
describe('handleButtonClick', () => {
beforeEach(() => {
component.togglePopup = jest.fn();
component.focusList = jest.fn();
});
it('should toggle popup', () => {
component.handleButtonClick();
expect(component.togglePopup).toHaveBeenCalled();
});
it('should focus list if popup is visible', () => {
component.isPopupOpen = true;
component.handleButtonClick();
expect(component.focusList).toHaveBeenCalled();
});
it('should not focus list if popup is hidden', () => {
component.handleButtonClick();
expect(component.focusList).not.toHaveBeenCalled();
});
});
describe('focusList', () => {
it('should focus popup list item', fakeAsync(() => {
component.isPopupOpen = true;
fixture.detectChanges();
component.popupListRef.nativeElement.focus = jest.fn();
component.focusList();
tick();
expect(component.popupListRef.nativeElement.focus).toHaveBeenCalled();
}));
});
describe('aria-expanded', () => { describe('aria-expanded', () => {
it('should be true if popup is open', () => { it('should be true if popup is open', () => {
component.isPopupOpen = true; component.isPopupOpen = true;
......
...@@ -10,7 +10,7 @@ import { twMerge } from 'tailwind-merge'; ...@@ -10,7 +10,7 @@ import { twMerge } from 'tailwind-merge';
template: `<div class="relative w-fit"> template: `<div class="relative w-fit">
<button <button
[ngClass]="[twMerge('w-fit outline-2 outline-offset-2 outline-focus', buttonClass)]" [ngClass]="[twMerge('w-fit outline-2 outline-offset-2 outline-focus', buttonClass)]"
(click)="togglePopup()" (click)="handleButtonClick()"
[attr.aria-expanded]="isPopupOpen" [attr.aria-expanded]="isPopupOpen"
aria-haspopup="true" aria-haspopup="true"
[attr.aria-label]="label" [attr.aria-label]="label"
...@@ -25,8 +25,9 @@ import { twMerge } from 'tailwind-merge'; ...@@ -25,8 +25,9 @@ import { twMerge } from 'tailwind-merge';
[ngClass]="alignTo === 'left' ? 'right-0' : 'left-0'" [ngClass]="alignTo === 'left' ? 'right-0' : 'left-0'"
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
tabIndex="-1"
cdkTrapFocus cdkTrapFocus
[cdkTrapFocusAutoCapture]="true" #popupList
> >
<ng-content /> <ng-content />
</ul> </ul>
...@@ -38,9 +39,10 @@ export class PopupComponent { ...@@ -38,9 +39,10 @@ export class PopupComponent {
@Input() buttonClass: string = ''; @Input() buttonClass: string = '';
isPopupOpen: boolean = false; isPopupOpen: boolean = false;
twMerge = twMerge; readonly twMerge = twMerge;
@ViewChild('button') buttonRef: ElementRef<HTMLButtonElement>; @ViewChild('button') buttonRef: ElementRef<HTMLButtonElement>;
@ViewChild('popupList') popupListRef: ElementRef<HTMLUListElement>;
@HostListener('document:keydown', ['$event']) @HostListener('document:keydown', ['$event'])
onKeydownHandler(e: KeyboardEvent): void { onKeydownHandler(e: KeyboardEvent): void {
...@@ -56,6 +58,15 @@ export class PopupComponent { ...@@ -56,6 +58,15 @@ export class PopupComponent {
} }
} }
handleButtonClick(): void {
this.togglePopup();
if (this.isPopupOpen) this.focusList();
}
focusList(): void {
setTimeout(() => this.popupListRef.nativeElement.focus());
}
togglePopup(): void { togglePopup(): void {
this.isPopupOpen = !this.isPopupOpen; this.isPopupOpen = !this.isPopupOpen;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment