From 5939b365c5a46aeddfcf0a1621cfe92f6f9ee186 Mon Sep 17 00:00:00 2001 From: Zach Arend Date: Fri, 11 Feb 2022 00:30:11 +0000 Subject: [PATCH] fix(material/datepicker): fix Voiceover losing focus on PageDown Fixes an issue where Voiceover loses focus when pressing PageDown/PageUp in the calendar to go to the next month/year (issue #24330). Adding a 20ms timeout seems to fix this. Note that this will not fully fix the issue until #24397 is merged. Address #24330. --- src/material/datepicker/calendar-body.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/material/datepicker/calendar-body.ts b/src/material/datepicker/calendar-body.ts index 3749c74bb0f6..ce6f6f480772 100644 --- a/src/material/datepicker/calendar-body.ts +++ b/src/material/datepicker/calendar-body.ts @@ -20,7 +20,7 @@ import { OnDestroy, AfterViewChecked, } from '@angular/core'; -import {take} from 'rxjs/operators'; +import {delay, take} from 'rxjs/operators'; /** Extra CSS classes that can be associated with a calendar cell. */ export type MatCalendarCellCssClasses = string | string[] | Set | {[key: string]: any}; @@ -31,6 +31,8 @@ export type MatCalendarCellClassFunction = ( view: 'month' | 'year' | 'multi-year', ) => MatCalendarCellCssClasses; +export const FOCUS_ACTIVE_CELL_DELAY = 20; + /** * An internal class that represents the data corresponding to a single calendar cell. * @docs-private @@ -216,10 +218,14 @@ export class MatCalendarBody implements OnChanges, OnDestroy, AfterViewChecked { return cellNumber == this.activeCell; } - /** Focuses the active cell after the microtask queue is empty. */ + /** + * Focuses the active cell after the microtask queue is empty. + * + * Adds a 20ms delay to fix Voiceover losing focus when pressing PageUp/PageDown (issue #24330). + */ _focusActiveCell(movePreview = true) { this._ngZone.runOutsideAngular(() => { - this._ngZone.onStable.pipe(take(1)).subscribe(() => { + this._ngZone.onStable.pipe(take(1), delay(FOCUS_ACTIVE_CELL_DELAY)).subscribe(() => { const activeCell: HTMLElement | null = this._elementRef.nativeElement.querySelector( '.mat-calendar-body-active', );