diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts index 331e240434cf..5d443fb24610 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts @@ -212,6 +212,19 @@ describe('FocusMonitor', () => { expect(buttonElement.classList.length).toBe(0, 'button should not have any focus classes'); })); + + it('should pass focus options to the native focus method', fakeAsync(() => { + spyOn(buttonElement, 'focus'); + + focusMonitor.focusVia(buttonElement, 'program', {preventScroll: true}); + fixture.detectChanges(); + tick(); + + expect(buttonElement.focus).toHaveBeenCalledWith(jasmine.objectContaining({ + preventScroll: true + })); + })); + }); diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.ts b/src/cdk/a11y/focus-monitor/focus-monitor.ts index 5628a307be65..a2cb0c337197 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.ts @@ -29,6 +29,16 @@ export const TOUCH_BUFFER_MS = 650; export type FocusOrigin = 'touch' | 'mouse' | 'keyboard' | 'program' | null; +/** + * Corresponds to the options that can be passed to the native `focus` event. + * via https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus + */ +export interface FocusOptions { + /** Whether the browser should scroll to the element when it is focused. */ + preventScroll?: boolean; +} + + type MonitoredElementInfo = { unlisten: Function, checkChildren: boolean, @@ -135,15 +145,17 @@ export class FocusMonitor implements OnDestroy { /** * Focuses the element via the specified focus origin. - * @param element The element to focus. - * @param origin The focus origin. + * @param element Element to focus. + * @param origin Focus origin. + * @param focusOption Options that can be used to configure the focus behavior. */ - focusVia(element: HTMLElement, origin: FocusOrigin): void { + focusVia(element: HTMLElement, origin: FocusOrigin, options?: FocusOptions): void { this._setOriginForCurrentEventQueue(origin); // `focus` isn't available on the server if (typeof element.focus === 'function') { - element.focus(); + // Cast the element to `any`, because the TS typings don't have the `options` parameter yet. + (element as any).focus(options); } }