mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACA-3899] Viewer thumbnails cannot be accessed by keyboard (#6150)
* accessibility * add thumb focus * close thumbs list event * fix eventbus listener * rename parameter * track previous focused element * implement FocusKeyManager * fix getGlobalEventBus is deprecated * keyboard navigation * set tabindex * setActiveItem on list change * update test
This commit is contained in:
@@ -17,19 +17,27 @@
|
||||
|
||||
import {
|
||||
Component, Input, ContentChild, TemplateRef, HostListener, OnInit,
|
||||
AfterViewInit, ElementRef, OnDestroy, ViewEncapsulation
|
||||
AfterViewInit, ElementRef, OnDestroy, ViewEncapsulation, EventEmitter, Output, Inject, ViewChildren, QueryList
|
||||
} from '@angular/core';
|
||||
import { ESCAPE, UP_ARROW, DOWN_ARROW } from '@angular/cdk/keycodes';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { FocusKeyManager } from '@angular/cdk/a11y';
|
||||
import { PdfThumbComponent } from './pdf-viewer-thumb.component';
|
||||
import { delay } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-pdf-thumbnails',
|
||||
templateUrl: './pdf-viewer-thumbnails.component.html',
|
||||
styleUrls: ['./pdf-viewer-thumbnails.component.scss'],
|
||||
host: { 'class': 'adf-pdf-thumbnails' },
|
||||
host: { class: 'adf-pdf-thumbnails' },
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class PdfThumbListComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@Input() pdfViewer: any;
|
||||
|
||||
@Output()
|
||||
close: EventEmitter<any> = new EventEmitter<void>();
|
||||
|
||||
virtualHeight: number = 0;
|
||||
translateY: number = 0;
|
||||
renderItems = [];
|
||||
@@ -39,56 +47,96 @@ export class PdfThumbListComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
private items = [];
|
||||
private margin: number = 15;
|
||||
private itemHeight: number = 114 + this.margin;
|
||||
private previouslyFocusedElement: HTMLElement | null = null;
|
||||
private keyManager: FocusKeyManager<PdfThumbComponent>;
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
@ViewChildren(PdfThumbComponent)
|
||||
thumbsList: QueryList<PdfThumbComponent>;
|
||||
|
||||
@HostListener('keydown', ['$event'])
|
||||
onKeydown(event: KeyboardEvent): void {
|
||||
const keyCode = event.keyCode;
|
||||
|
||||
if (keyCode === UP_ARROW && this.canSelectPreviousItem()) {
|
||||
this.pdfViewer.currentPageNumber -= 1;
|
||||
}
|
||||
|
||||
if (keyCode === DOWN_ARROW && this.canSelectNextItem()) {
|
||||
this.pdfViewer.currentPageNumber += 1;
|
||||
}
|
||||
|
||||
if (keyCode === ESCAPE) {
|
||||
this.close.emit();
|
||||
}
|
||||
|
||||
this.keyManager.setFocusOrigin('keyboard');
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
@HostListener('window:resize')
|
||||
onResize() {
|
||||
this.calculateItems();
|
||||
}
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
constructor(private element: ElementRef, @Inject(DOCUMENT) private document: any) {
|
||||
this.calculateItems = this.calculateItems.bind(this);
|
||||
this.onPageChange = this.onPageChange.bind(this);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
/* cspell:disable-next-line */
|
||||
this.pdfViewer.eventBus.on('pagechange', this.onPageChange);
|
||||
this.pdfViewer.eventBus.on('pagechanging', this.onPageChange);
|
||||
this.element.nativeElement.addEventListener('scroll', this.calculateItems, true);
|
||||
|
||||
this.setHeight(this.pdfViewer.currentPageNumber);
|
||||
this.items = this.getPages();
|
||||
this.calculateItems();
|
||||
|
||||
this.previouslyFocusedElement = this.document.activeElement as HTMLElement;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => this.scrollInto(this.pdfViewer.currentPageNumber), 0);
|
||||
this.keyManager = new FocusKeyManager(this.thumbsList);
|
||||
|
||||
this.thumbsList.changes
|
||||
.pipe(delay(0))
|
||||
.subscribe(() => this.keyManager.setActiveItem(this.getPageIndex(this.pdfViewer.currentPageNumber)));
|
||||
|
||||
setTimeout(() => {
|
||||
this.scrollInto(this.pdfViewer.currentPageNumber);
|
||||
this.keyManager.setActiveItem(this.getPageIndex(this.pdfViewer.currentPageNumber));
|
||||
}, 0);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.element.nativeElement.removeEventListener('scroll', this.calculateItems, true);
|
||||
/* cspell:disable-next-line */
|
||||
this.pdfViewer.eventBus.off('pagechange', this.onPageChange);
|
||||
this.pdfViewer.eventBus.on('pagechanging', this.onPageChange);
|
||||
|
||||
if (this.previouslyFocusedElement) {
|
||||
this.previouslyFocusedElement.focus();
|
||||
this.previouslyFocusedElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
trackByFn(_: number, item: any): number {
|
||||
return item.id;
|
||||
}
|
||||
|
||||
isSelected(pageNum: number) {
|
||||
return this.pdfViewer.currentPageNumber === pageNum;
|
||||
isSelected(pageNumber: number) {
|
||||
return this.pdfViewer.currentPageNumber === pageNumber;
|
||||
}
|
||||
|
||||
goTo(pageNum: number) {
|
||||
this.pdfViewer.currentPageNumber = pageNum;
|
||||
goTo(pageNumber: number) {
|
||||
this.pdfViewer.currentPageNumber = pageNumber;
|
||||
}
|
||||
|
||||
scrollInto(item: any) {
|
||||
scrollInto(pageNumber: number) {
|
||||
if (this.items.length) {
|
||||
const index: number = this.items.findIndex((element) => element.id === item);
|
||||
const index: number = this.items.findIndex((element) => element.id === pageNumber);
|
||||
|
||||
if (index < 0 || index >= this.items.length) {
|
||||
return;
|
||||
@@ -164,5 +212,20 @@ export class PdfThumbListComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
if (index >= this.renderItems.length - 1) {
|
||||
this.element.nativeElement.scrollTop += this.itemHeight;
|
||||
}
|
||||
|
||||
this.keyManager.setActiveItem(this.getPageIndex(event.pageNumber));
|
||||
}
|
||||
|
||||
private getPageIndex(pageNumber: number): number {
|
||||
const thumbsListArray = this.thumbsList.toArray();
|
||||
return thumbsListArray.findIndex(el => el.page.id === pageNumber);
|
||||
}
|
||||
|
||||
private canSelectNextItem(): boolean {
|
||||
return this.pdfViewer.currentPageNumber !== this.pdfViewer.pagesCount;
|
||||
}
|
||||
|
||||
private canSelectPreviousItem(): boolean {
|
||||
return this.pdfViewer.currentPageNumber !== 1;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user