Skip to content

Commit 8f3b316

Browse files
crisbetojosephperrott
authored andcommitted
fix(focus-monitor): allow native focus options to be passed through focusVia (#11962)
1 parent 4ac64da commit 8f3b316

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

src/cdk/a11y/focus-monitor/focus-monitor.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,19 @@ describe('FocusMonitor', () => {
212212

213213
expect(buttonElement.classList.length).toBe(0, 'button should not have any focus classes');
214214
}));
215+
216+
it('should pass focus options to the native focus method', fakeAsync(() => {
217+
spyOn(buttonElement, 'focus');
218+
219+
focusMonitor.focusVia(buttonElement, 'program', {preventScroll: true});
220+
fixture.detectChanges();
221+
tick();
222+
223+
expect(buttonElement.focus).toHaveBeenCalledWith(jasmine.objectContaining({
224+
preventScroll: true
225+
}));
226+
}));
227+
215228
});
216229

217230

src/cdk/a11y/focus-monitor/focus-monitor.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ export const TOUCH_BUFFER_MS = 650;
2929
export type FocusOrigin = 'touch' | 'mouse' | 'keyboard' | 'program' | null;
3030

3131

32+
/**
33+
* Corresponds to the options that can be passed to the native `focus` event.
34+
* via https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
35+
*/
36+
export interface FocusOptions {
37+
/** Whether the browser should scroll to the element when it is focused. */
38+
preventScroll?: boolean;
39+
}
40+
41+
3242
type MonitoredElementInfo = {
3343
unlisten: Function,
3444
checkChildren: boolean,
@@ -135,15 +145,17 @@ export class FocusMonitor implements OnDestroy {
135145

136146
/**
137147
* Focuses the element via the specified focus origin.
138-
* @param element The element to focus.
139-
* @param origin The focus origin.
148+
* @param element Element to focus.
149+
* @param origin Focus origin.
150+
* @param focusOption Options that can be used to configure the focus behavior.
140151
*/
141-
focusVia(element: HTMLElement, origin: FocusOrigin): void {
152+
focusVia(element: HTMLElement, origin: FocusOrigin, options?: FocusOptions): void {
142153
this._setOriginForCurrentEventQueue(origin);
143154

144155
// `focus` isn't available on the server
145156
if (typeof element.focus === 'function') {
146-
element.focus();
157+
// Cast the element to `any`, because the TS typings don't have the `options` parameter yet.
158+
(element as any).focus(options);
147159
}
148160
}
149161

0 commit comments

Comments
 (0)