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

Commit

Permalink
feat(dropdown): focus toggle element when opening or closing with Esc`
Browse files Browse the repository at this point in the history
 * Improve accessibility.

Closes #1908.
  • Loading branch information
bekos committed Mar 8, 2014
1 parent d89bbd1 commit f715d05
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
20 changes: 15 additions & 5 deletions src/dropdown/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ angular.module('ui.bootstrap.dropdown', [])

var escapeKeyBind = function( evt ) {
if ( evt.which === 27 ) {
openScope.focusToggleElement();
closeDropdown();
}
};
Expand Down Expand Up @@ -71,17 +72,24 @@ angular.module('ui.bootstrap.dropdown', [])
return scope.isOpen;
};

scope.$watch('isOpen', function( value ) {
$animate[value ? 'addClass' : 'removeClass'](self.$element, openClass);
scope.focusToggleElement = function() {
if ( self.toggleElement ) {
self.toggleElement[0].focus();
}
};

if ( value ) {
scope.$watch('isOpen', function( isOpen ) {
$animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass);

if ( isOpen ) {
scope.focusToggleElement();
dropdownService.open( scope );
} else {
dropdownService.close( scope );
}

setIsOpen($scope, value);
toggleInvoker($scope, { open: !!value });
setIsOpen($scope, isOpen);
toggleInvoker($scope, { open: !!isOpen });
});

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

dropdownCtrl.toggleElement = element;

var toggleDropdown = function(event) {
event.preventDefault();
event.stopPropagation();
Expand Down
25 changes: 22 additions & 3 deletions src/dropdown/test/dropdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ describe('dropdownToggle', function() {
element.trigger(e);
};

var isFocused = function(elm) {
return elm[0] === document.activeElement;
};

describe('basic', function() {
function dropdown() {
return $compile('<li class="dropdown"><a dropdown-toggle></a><ul><li>Hello</li></ul></li>')($rootScope);
return $compile('<li class="dropdown"><a href dropdown-toggle></a><ul><li>Hello</li></ul></li>')($rootScope);
}

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

it('should close on escape key', function() {
it('should close on escape key & focus toggle element', function() {
$document.find('body').append(element);
clickDropdownToggle();
triggerKeyDown($document, 27);
expect(element.hasClass('open')).toBe(false);
expect(isFocused(element.find('a'))).toBe(true);
element.remove();
});

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

Expand All @@ -188,6 +195,18 @@ describe('dropdownToggle', function() {
$rootScope.$digest();
expect(element.hasClass('open')).toBe(false);
});

it('focus toggle element when opening', function() {
$document.find('body').append(element);
clickDropdownToggle();
$rootScope.isopen = false;
$rootScope.$digest();
expect(isFocused(element.find('a'))).toBe(false);
$rootScope.isopen = true;
$rootScope.$digest();
expect(isFocused(element.find('a'))).toBe(true);
element.remove();
});
});

describe('`on-toggle`', function() {
Expand Down

0 comments on commit f715d05

Please sign in to comment.