Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit f715d05

Browse files
committed
feat(dropdown): focus toggle element when opening or closing with Esc`
* Improve accessibility. Closes #1908.
1 parent d89bbd1 commit f715d05

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

src/dropdown/dropdown.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ angular.module('ui.bootstrap.dropdown', [])
3636

3737
var escapeKeyBind = function( evt ) {
3838
if ( evt.which === 27 ) {
39+
openScope.focusToggleElement();
3940
closeDropdown();
4041
}
4142
};
@@ -71,17 +72,24 @@ angular.module('ui.bootstrap.dropdown', [])
7172
return scope.isOpen;
7273
};
7374

74-
scope.$watch('isOpen', function( value ) {
75-
$animate[value ? 'addClass' : 'removeClass'](self.$element, openClass);
75+
scope.focusToggleElement = function() {
76+
if ( self.toggleElement ) {
77+
self.toggleElement[0].focus();
78+
}
79+
};
7680

77-
if ( value ) {
81+
scope.$watch('isOpen', function( isOpen ) {
82+
$animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass);
83+
84+
if ( isOpen ) {
85+
scope.focusToggleElement();
7886
dropdownService.open( scope );
7987
} else {
8088
dropdownService.close( scope );
8189
}
8290

83-
setIsOpen($scope, value);
84-
toggleInvoker($scope, { open: !!value });
91+
setIsOpen($scope, isOpen);
92+
toggleInvoker($scope, { open: !!isOpen });
8593
});
8694

8795
$scope.$on('$locationChangeSuccess', function() {
@@ -112,6 +120,8 @@ angular.module('ui.bootstrap.dropdown', [])
112120
return;
113121
}
114122

123+
dropdownCtrl.toggleElement = element;
124+
115125
var toggleDropdown = function(event) {
116126
event.preventDefault();
117127
event.stopPropagation();

src/dropdown/test/dropdown.spec.js

+22-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ describe('dropdownToggle', function() {
2020
element.trigger(e);
2121
};
2222

23+
var isFocused = function(elm) {
24+
return elm[0] === document.activeElement;
25+
};
26+
2327
describe('basic', function() {
2428
function dropdown() {
25-
return $compile('<li class="dropdown"><a dropdown-toggle></a><ul><li>Hello</li></ul></li>')($rootScope);
29+
return $compile('<li class="dropdown"><a href dropdown-toggle></a><ul><li>Hello</li></ul></li>')($rootScope);
2630
}
2731

2832
beforeEach(function() {
@@ -44,10 +48,13 @@ describe('dropdownToggle', function() {
4448
expect(element.hasClass('open')).toBe(false);
4549
});
4650

47-
it('should close on escape key', function() {
51+
it('should close on escape key & focus toggle element', function() {
52+
$document.find('body').append(element);
4853
clickDropdownToggle();
4954
triggerKeyDown($document, 27);
5055
expect(element.hasClass('open')).toBe(false);
56+
expect(isFocused(element.find('a'))).toBe(true);
57+
element.remove();
5158
});
5259

5360
it('should not close on backspace key', function() {
@@ -170,7 +177,7 @@ describe('dropdownToggle', function() {
170177
describe('`is-open`', function() {
171178
beforeEach(function() {
172179
$rootScope.isopen = true;
173-
element = $compile('<li class="dropdown" is-open="isopen"><a dropdown-toggle></a><ul><li>Hello</li></ul></li>')($rootScope);
180+
element = $compile('<li class="dropdown" is-open="isopen"><a href dropdown-toggle></a><ul><li>Hello</li></ul></li>')($rootScope);
174181
$rootScope.$digest();
175182
});
176183

@@ -188,6 +195,18 @@ describe('dropdownToggle', function() {
188195
$rootScope.$digest();
189196
expect(element.hasClass('open')).toBe(false);
190197
});
198+
199+
it('focus toggle element when opening', function() {
200+
$document.find('body').append(element);
201+
clickDropdownToggle();
202+
$rootScope.isopen = false;
203+
$rootScope.$digest();
204+
expect(isFocused(element.find('a'))).toBe(false);
205+
$rootScope.isopen = true;
206+
$rootScope.$digest();
207+
expect(isFocused(element.find('a'))).toBe(true);
208+
element.remove();
209+
});
191210
});
192211

193212
describe('`on-toggle`', function() {

0 commit comments

Comments
 (0)