Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit bb36507

Browse files
Marcy Suttonpetebacondarwin
Marcy Sutton
authored andcommitted
feat(ngAria): add button role to ngClick
Closes #9254 Closes #10318
1 parent 0f50b01 commit bb36507

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

docs/content/guide/accessibility.ngdoc

+6-4
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
213213
If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex="0"` if it isn't there
214214
already.
215215

216-
For `ng-click`, keypress will also be bound to `div` and `li` elements. You can turn this
217-
functionality on or off with the `bindKeypress` configuration option.
216+
To fix widespread accessibility problems with `ng-click` on div elements, ngAria will dynamically
217+
bind keypress by default as long as the element isn't an anchor, button, input or textarea.
218+
You can turn this functionality on or off with the `bindKeypress` configuration option. ngAria
219+
will also add the `button` role to communicate to users of assistive technologies.
218220

219-
For `ng-dblclick`, you must manually add `ng-keypress` to non-interactive elements such as `div`
220-
or `taco-button` to enable keyboard access.
221+
For `ng-dblclick`, you must still manually add `ng-keypress` and role to non-interactive elements such
222+
as `div` or `taco-button` to enable keyboard access.
221223

222224
<h3>Example</h3>
223225
```html

src/ngAria/aria.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
*
2323
* | Directive | Supported Attributes |
2424
* |---------------------------------------------|----------------------------------------------------------------------------------------|
25-
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required |
2625
* | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
2726
* | {@link ng.directive:ngShow ngShow} | aria-hidden |
2827
* | {@link ng.directive:ngHide ngHide} | aria-hidden |
29-
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event |
3028
* | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
3129
* | {@link module:ngMessages ngMessages} | aria-live |
30+
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
31+
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
3232
*
3333
* Find out more information about each directive by reading the
3434
* {@link guide/accessibility ngAria Developer Guide}.
@@ -317,17 +317,22 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
317317
var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
318318
return function(scope, elem, attr) {
319319

320+
var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA'];
321+
320322
function isNodeOneOf(elem, nodeTypeArray) {
321323
if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
322324
return true;
323325
}
324326
}
327+
if (!elem.attr('role') && !isNodeOneOf(elem, nodeBlackList)) {
328+
elem.attr('role', 'button');
329+
}
325330

326331
if ($aria.config('tabindex') && !elem.attr('tabindex')) {
327332
elem.attr('tabindex', 0);
328333
}
329334

330-
if ($aria.config('bindKeypress') && !attr.ngKeypress && isNodeOneOf(elem, ['DIV', 'LI'])) {
335+
if ($aria.config('bindKeypress') && !attr.ngKeypress && !isNodeOneOf(elem, nodeBlackList)) {
331336
elem.on('keypress', function(event) {
332337
if (event.keyCode === 32 || event.keyCode === 13) {
333338
scope.$apply(callback);

test/ngAria/ariaSpec.js

+10
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ describe('$aria', function() {
195195
describe('roles for custom inputs', function() {
196196
beforeEach(injectScopeAndCompiler);
197197

198+
it('should add missing role="button" to custom input', function() {
199+
compileElement('<div ng-click="someFunction()"></div>');
200+
expect(element.attr('role')).toBe('button');
201+
});
202+
203+
it('should not add role="button" to anchor', function() {
204+
compileElement('<a ng-click="someFunction()"></a>');
205+
expect(element.attr('role')).not.toBe('button');
206+
});
207+
198208
it('should add missing role="checkbox" to custom input', function() {
199209
compileElement('<div type="checkbox" ng-model="val"></div>');
200210
expect(element.attr('role')).toBe('checkbox');

0 commit comments

Comments
 (0)