diff --git a/libs/ui/epg/src/lib/epg-guide/epg-guide.component.spec.ts b/libs/ui/epg/src/lib/epg-guide/epg-guide.component.spec.ts index 3eab4e372..e00e6e91c 100644 --- a/libs/ui/epg/src/lib/epg-guide/epg-guide.component.spec.ts +++ b/libs/ui/epg/src/lib/epg-guide/epg-guide.component.spec.ts @@ -447,6 +447,28 @@ describe('EpgGuideComponent', () => { ]); }); + it('jumps to now on N without scrolling back to a focus left off-screen', async () => { + await settle(fixture); + const viewportEl: HTMLElement = fixture.debugElement.query( + By.css('cdk-virtual-scroll-viewport') + ).nativeElement; + const scrollTo = jest.fn(); + viewportEl.scrollTo = scrollTo as unknown as HTMLElement['scrollTo']; + // jsdom reports a zero-sized lane, so this programme counts as hidden. + component.focusCell(0, 0); + await settle(fixture); + scrollTo.mockClear(); + + component.onKeydown(keydown('n')); + + // One combined smooth scroll; a reveal after it would cancel it. + expect(scrollTo).toHaveBeenCalledTimes(1); + expect(scrollTo).toHaveBeenCalledWith( + expect.objectContaining({ top: 0, behavior: 'smooth' }) + ); + expect(component.focus()).toEqual({ row: 0, block: 0 }); + }); + it('moves the roving focus to a clicked programme card', async () => { await settle(fixture); const card = fixture.debugElement.query( diff --git a/libs/ui/epg/src/lib/epg-guide/epg-guide.component.ts b/libs/ui/epg/src/lib/epg-guide/epg-guide.component.ts index d1913221b..bf69caa5f 100644 --- a/libs/ui/epg/src/lib/epg-guide/epg-guide.component.ts +++ b/libs/ui/epg/src/lib/epg-guide/epg-guide.component.ts @@ -257,11 +257,16 @@ export class EpgGuideComponent implements OnDestroy { */ @HostListener('document:keydown', ['$event']) onKeydown(event: KeyboardEvent): void { + const focusBefore = this.focus(); if (!this.keyboard.handle(event)) { return; } event.preventDefault(); - this.viewportController.revealFocus(this.focus()); + // Only a key that moved the focus scrolls to it: N scrolls to now on + // its own, and a reveal of a focus left off-screen would cancel it. + if (this.focus() !== focusBefore) { + this.viewportController.revealFocus(this.focus()); + } afterNextRender(() => this.viewportController.focusRovingTarget(), { injector: this.injector, });