fix(overlays): update keyboard focus management

This commit is contained in:
Adam Bradley
2016-03-05 20:32:21 -06:00
parent 4922fc6075
commit e639457654
5 changed files with 68 additions and 35 deletions

View File

@ -1,4 +1,4 @@
import {Component, Renderer, ElementRef} from 'angular2/core';
import {Component, Renderer, ElementRef, HostListener} from 'angular2/core';
import {NgFor, NgIf} from 'angular2/common';
import {Animation} from '../../animations/animation';
@ -188,19 +188,18 @@ export class ActionSheet extends ViewController {
})
class ActionSheetCmp {
private d: any;
private keyUp: EventListener;
constructor(
private _viewCtrl: ViewController,
private _config: Config,
elementRef: ElementRef,
private _elementRef: ElementRef,
params: NavParams,
renderer: Renderer
) {
this.d = params.data;
if (this.d.cssClass) {
renderer.setElementClass(elementRef.nativeElement, this.d.cssClass, true);
renderer.setElementClass(_elementRef.nativeElement, this.d.cssClass, true);
}
}
@ -234,16 +233,28 @@ class ActionSheetCmp {
});
this.d.buttons = buttons;
}
let self = this;
self.keyUp = function(ev: KeyboardEvent) {
onPageDidEnter() {
let activeElement: any = document.activeElement;
if (document.activeElement) {
activeElement.blur();
}
let focusableEle = this._elementRef.nativeElement.querySelector('button');
if (focusableEle) {
focusableEle.focus();
}
}
@HostListener('body:keyup', ['$event'])
private _keyUp(ev: KeyboardEvent) {
if (this._viewCtrl.isLast()) {
if (ev.keyCode === 27) {
console.debug('actionsheet escape');
self.bdClick();
this.bdClick();
}
};
document.addEventListener('keyup', this.keyUp);
}
}
click(button, dismissDelay?) {
@ -278,14 +289,6 @@ class ActionSheetCmp {
dismiss(role): Promise<any> {
return this._viewCtrl.dismiss(null, role);
}
onPageWillLeave() {
document.removeEventListener('keyup', this.keyUp);
}
ngOnDestroy() {
document.removeEventListener('keyup', this.keyUp);
}
}
export interface ActionSheetOptions {

View File

@ -345,14 +345,16 @@ class AlertCmp {
@HostListener('body:keyup', ['$event'])
private _keyUp(ev: KeyboardEvent) {
if (ev.keyCode === 13) {
console.debug('alert, enter button');
let button = this.d.buttons[this.d.buttons.length - 1];
this.btnClick(button);
if (this._viewCtrl.isLast()) {
if (ev.keyCode === 13) {
console.debug('alert, enter button');
let button = this.d.buttons[this.d.buttons.length - 1];
this.btnClick(button);
} else if (ev.keyCode === 27) {
console.debug('alert, escape button');
this.bdClick();
} else if (ev.keyCode === 27) {
console.debug('alert, escape button');
this.bdClick();
}
}
}
@ -362,11 +364,9 @@ class AlertCmp {
activeElement.blur();
}
if (this.d.inputs.length) {
let firstInput = this._elementRef.nativeElement.querySelector('input');
if (firstInput) {
firstInput.focus();
}
let focusableEle = this._elementRef.nativeElement.querySelector('input,button');
if (focusableEle) {
focusableEle.focus();
}
}

View File

@ -68,8 +68,8 @@ export class MenuToggle {
*/
get isHidden() {
if (this._inNavbar && this._viewCtrl) {
if (this._viewCtrl.isRoot()) {
// this is the root view, so it should always show
if (this._viewCtrl.isFirst()) {
// this is the first view, so it should always show
return false;
}

View File

@ -1077,21 +1077,35 @@ export function run() {
it('should get first()', () => {
expect(nav.first()).toBe(null);
let view1 = new ViewController(Page1);
view1.setNav(nav);
let view2 = new ViewController(Page2);
view2.setNav(nav);
nav._views = [view1];
expect(nav.first()).toBe(view1);
expect(view1.isFirst()).toBe(true);
nav._views = [view1, view2];
expect(nav.first()).toBe(view1);
expect(view1.isFirst()).toBe(true);
expect(view2.isFirst()).toBe(false);
});
it('should get last()', () => {
expect(nav.last()).toBe(null);
let view1 = new ViewController(Page1);
view1.setNav(nav);
let view2 = new ViewController(Page2);
view2.setNav(nav);
nav._views = [view1];
expect(nav.last()).toBe(view1);
expect(view1.isLast()).toBe(true);
nav._views = [view1, view2];
expect(nav.last()).toBe(view2);
expect(view1.isLast()).toBe(false);
expect(view2.isLast()).toBe(true);
});
it('should get indexOf()', () => {

View File

@ -189,10 +189,26 @@ export class ViewController {
}
/**
* @returns {boolean} Returns if this Page is the root page of the NavController.
* @private
*/
isRoot(): boolean {
return (this.index === 0);
private isRoot(): boolean {
// deprecated warning
console.warn('ViewController isRoot() has been renamed to isFirst()');
return this.isFirst();
}
/**
* @returns {boolean} Returns if this Page is the first in the stack of pages within its NavController.
*/
isFirst(): boolean {
return (this._nav ? this._nav.first() === this : false);
}
/**
* @returns {boolean} Returns if this Page is the last in the stack of pages within its NavController.
*/
isLast(): boolean {
return (this._nav ? this._nav.last() === this : false);
}
/**