diff --git a/lib/content-services/src/lib/permission-manager/components/permission-list/permission-list.component.html b/lib/content-services/src/lib/permission-manager/components/permission-list/permission-list.component.html index f191d4cc53..78dc2b8464 100644 --- a/lib/content-services/src/lib/permission-manager/components/permission-list/permission-list.component.html +++ b/lib/content-services/src/lib/permission-manager/components/permission-list/permission-list.component.html @@ -44,7 +44,6 @@ data-automation-id="permission-info-button" [adf-pop-over]="inheritedPermission" [target]="target" - [autofocusedElementSelector]="'.adf-sortable'" #popOver="adfPopOver" *ngIf="model.node.permissions.isInheritanceEnabled"> {{ (popOver.open ? 'PERMISSION_MANAGER.LABELS.HIDE' : 'PERMISSION_MANAGER.LABELS.SHOW') | translate }} diff --git a/lib/content-services/src/lib/permission-manager/components/pop-over.directive.spec.ts b/lib/content-services/src/lib/permission-manager/components/pop-over.directive.spec.ts index 246d3408d2..3185dcfa7e 100644 --- a/lib/content-services/src/lib/permission-manager/components/pop-over.directive.spec.ts +++ b/lib/content-services/src/lib/permission-manager/components/pop-over.directive.spec.ts @@ -23,7 +23,7 @@ import { OverlayModule } from '@angular/cdk/overlay'; @Component({ template: ` -
+
@@ -80,4 +80,28 @@ describe('PopOverDirective', () => { })); expect(popOverTrigger).not.toEqual(document.activeElement); }); + + it('should open pop over on enter key press if pop over is not open', () => { + const popOverTrigger = fixture.debugElement.query(By.directive(PopOverDirective)).nativeElement; + fixture.detectChanges(); + popOverTrigger.dispatchEvent(new KeyboardEvent('keyup', { + key: 'Enter' + })); + fixture.detectChanges(); + const popOverPanel = document.querySelector('.adf-popover-test'); + expect(popOverPanel).toBeDefined(); + }); + + it('should close pop over on enter key press if pop over is open', () => { + const popOverTrigger = fixture.debugElement.query(By.directive(PopOverDirective)).nativeElement; + fixture.detectChanges(); + popOverTrigger.click(); + fixture.detectChanges(); + popOverTrigger.dispatchEvent(new KeyboardEvent('keyup', { + key: 'Enter' + })); + fixture.detectChanges(); + const popOverPanel = document.querySelector('.adf-popover-test'); + expect(popOverPanel).toBeNull(); + }); }); diff --git a/lib/content-services/src/lib/permission-manager/components/pop-over.directive.ts b/lib/content-services/src/lib/permission-manager/components/pop-over.directive.ts index bd2c322042..1dcff8fca6 100644 --- a/lib/content-services/src/lib/permission-manager/components/pop-over.directive.ts +++ b/lib/content-services/src/lib/permission-manager/components/pop-over.directive.ts @@ -30,6 +30,7 @@ import { ConnectionPositionPair, Overlay, OverlayRef } from '@angular/cdk/overla import { TemplatePortal } from '@angular/cdk/portal'; import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; +import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y'; @Directive({ selector: '[adf-pop-over]', @@ -50,10 +51,13 @@ export class PopOverDirective implements OnInit, OnDestroy, AfterViewInit { private destroy$ = new Subject(); private overlayRef!: OverlayRef; + private focusTrap: ConfigurableFocusTrap; + constructor( private element: ElementRef, private overlay: Overlay, - private vcr: ViewContainerRef + private vcr: ViewContainerRef, + private focusTrapFactory: ConfigurableFocusTrapFactory ) { } ngOnInit(): void { @@ -61,7 +65,7 @@ export class PopOverDirective implements OnInit, OnDestroy, AfterViewInit { } ngAfterViewInit(): void { - this.element.nativeElement.addEventListener('click', () => this.attachOverlay()); + this.element.nativeElement.addEventListener('click', () => this.toggleOverlay()); this.element.nativeElement.addEventListener('keydown', this.preventDefaultForEnter); } @@ -100,13 +104,27 @@ export class PopOverDirective implements OnInit, OnDestroy, AfterViewInit { } @HostListener('keyup.enter') + private toggleOverlay(): void { + if (!this.overlayRef.hasAttached()) { + this.attachOverlay(); + } else { + this.detachOverlay(); + } + } + private attachOverlay(): void { if (!this.overlayRef.hasAttached()) { const periodSelectorPortal = new TemplatePortal(this.popOver, this.vcr); this.overlayRef.attach(periodSelectorPortal); this._open = true; - this.overlayRef.overlayElement.querySelector(this.autofocusedElementSelector).focus(); + if (this.autofocusedElementSelector) { + this.overlayRef.overlayElement.querySelector(this.autofocusedElementSelector).focus(); + } + + if (this.popOver && !this.focusTrap) { + this.focusTrap = this.focusTrapFactory.create(this.overlayRef.overlayElement); + } } } @@ -115,6 +133,10 @@ export class PopOverDirective implements OnInit, OnDestroy, AfterViewInit { if (this.overlayRef.hasAttached()) { this.overlayRef.detach(); this._open = false; + + this.focusTrap.destroy(); + this.focusTrap = null; + this.element.nativeElement.focus(); } }