Skip to content
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

feat(sidenav): close via escape key and restore focus to trigger element #1990

Merged
merged 11 commits into from
Dec 9, 2016

Conversation

crisbeto
Copy link
Member

  • Adds the ability to close a sidenav by pressing escape.
  • Restores focus to the trigger element after a sidenav is closed.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Nov 26, 2016
@jelbourn
Copy link
Member

R: @mmalerba

@@ -38,6 +38,7 @@ export class MdDuplicatedSidenavError extends MdError {
template: '<ng-content></ng-content>',
host: {
'(transitionend)': '_onTransitionEnd($event)',
'(keydown.escape)': 'handleEscapeKey()',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately we can't use this fancy syntax, since not all of the browsers we target support the key property of KeyboardEvent. We have a file of keycodes here: https://github.com/angular/material2/blob/master/src/lib/core/keyboard/keycodes.ts

Copy link
Member Author

@crisbeto crisbeto Dec 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know, I saw that the dialog was using it so I went with it. I'll switch it back to use the keyCode.

Regarding the reasoning in the keycodes.ts, I don't know if this is still an issue since there's an e2e test on the dialog that uses the escape key.

constructor(private _elementRef: ElementRef) {}
constructor(private _elementRef: ElementRef) {
this.onOpen.subscribe(() => {
this._elementFocusedBeforeSidenavWasOpened = document.activeElement as HTMLElement;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document.activeElement

what about universal?

Copy link
Member Author

@crisbeto crisbeto Dec 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think Angular has a way of getting this, at the moment. There are other components that use document.activeElement as well.

AFAIK when we start supporting Universal, we can check if the renderer is a browser with this and take the appropriate action:

import { isBrowser, isNode } from 'angular2-universal'

Copy link

@DzmitryShylovich DzmitryShylovich Dec 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for things such as

this._elementRef.nativeElement.focus();

you can use renderer

this.renderer.invokeElementMethod(this._elementRef.nativeElement, 'focus');

Core already have different renderer implementations for browser and server envs.

But Renderer doesn't have methods to retrieve dom elements and afaik the recommended approach is to use DomAdapter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm good point about the renderer methods, I was under the impression that I used it already, but I probably forgot to switch it over after I was done testing. I'll move those. I'll have to look into using the adapter for querying.

@crisbeto
Copy link
Member Author

crisbeto commented Dec 2, 2016

Addressed the feedback and rebased @mmalerba.

*/
handleKeydown(event: KeyboardEvent) {
if (event.keyCode === ESCAPE) {
this.close();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably want to stop propagation (if we have a dialog with a sidenav, esc should close the sidenav but not the dialog)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@crisbeto crisbeto force-pushed the sidenav-escape-to-close branch 2 times, most recently from b1d8b16 to 8b73513 Compare December 6, 2016 20:34
@mmalerba
Copy link
Contributor

mmalerba commented Dec 7, 2016

It seems the tests are failing after the sidenav focus trap stuff in #1695 was merged

@crisbeto
Copy link
Member Author

crisbeto commented Dec 7, 2016

Weird that it's only in Mobile Safari. I'll re-run the build and take a look.

@crisbeto
Copy link
Member Author

crisbeto commented Dec 8, 2016

I sorted it out @mmalerba. It was conflicting with the focus trapping.

@mmalerba mmalerba added the action: merge The PR is ready for merge by the caretaker label Dec 8, 2016
@mmalerba mmalerba merged commit a1331ec into angular:master Dec 9, 2016
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants