Skip to content

fix(sidenav): not restoring focus to SVG elements #18614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/material/sidenav/drawer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,28 @@ describe('MatDrawer', () => {
.toBe(openButton, 'Expected focus to be restored to the open button on close.');
}));

it('should restore focus to an SVG element', fakeAsync(() => {
const fixture = TestBed.createComponent(BasicTestApp);
fixture.detectChanges();

const drawer = fixture.debugElement.query(By.directive(MatDrawer))!.componentInstance;
const svg = fixture.componentInstance.svg.nativeElement;
const drawerButton = fixture.componentInstance.drawerButton.nativeElement;

svg.focus();
drawer.open();
fixture.detectChanges();
flush();
drawerButton.focus();

drawer.close();
fixture.detectChanges();
flush();

expect(document.activeElement)
.toBe(svg, 'Expected focus to be restored to the SVG element on close.');
}));

it('should not restore focus on close if focus is outside drawer', fakeAsync(() => {
let fixture = TestBed.createComponent(BasicTestApp);
let drawer: MatDrawer = fixture.debugElement
Expand Down Expand Up @@ -907,6 +929,14 @@ class DrawerContainerTwoDrawerTestApp {
</mat-drawer>
<button (click)="drawer.open()" class="open" #openButton></button>
<button (click)="drawer.close()" class="close" #closeButton></button>
<svg
viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
tabindex="0"
focusable="true"
#svg>
<circle cx="50" cy="50" r="50"/>
</svg>
</mat-drawer-container>`,
})
class BasicTestApp {
Expand All @@ -920,6 +950,7 @@ class BasicTestApp {
@ViewChild('drawer') drawer: MatDrawer;
@ViewChild('drawerButton') drawerButton: ElementRef<HTMLButtonElement>;
@ViewChild('openButton') openButton: ElementRef<HTMLButtonElement>;
@ViewChild('svg') svg: ElementRef<SVGElement>;
@ViewChild('closeButton') closeButton: ElementRef<HTMLButtonElement>;

open() {
Expand Down
3 changes: 2 additions & 1 deletion src/material/sidenav/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr
const activeEl = this._doc && this._doc.activeElement;

if (activeEl && this._elementRef.nativeElement.contains(activeEl)) {
if (this._elementFocusedBeforeDrawerWasOpened instanceof HTMLElement) {
// Note that we don't check via `instanceof HTMLElement` so that we can cover SVGs as well.
if (this._elementFocusedBeforeDrawerWasOpened) {
this._focusMonitor.focusVia(this._elementFocusedBeforeDrawerWasOpened, this._openedVia);
} else {
this._elementRef.nativeElement.blur();
Expand Down