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

feat(ngAria): New module to make a11y easier #8342

Closed
wants to merge 1 commit into from

Conversation

arbus
Copy link
Contributor

@arbus arbus commented Jul 25, 2014

Adds various aria attributes to the built in directives.
This module currently hooks into ng-show/hide, input, textarea
button as a basic level of support for a11y. I am using this as a
base for adding more tags into the mix for form direction flow,
making ng-repeat updates atomic but the tags here are the most
basic ones.

Closes #5486 and #1600

@mary-poppins
Copy link

Thanks for the PR! Please check the items below to help us merge this faster. See the contributing docs for more information.

  • Uses the issue template (#8342)

If you need to make changes to your pull request, you can update the commit with git commit --amend.
Then, update the pull request with git push -f.

Thanks again for your help!

@arbus arbus added cla: yes and removed cla: no labels Jul 25, 2014
@IgorMinar IgorMinar added this to the 1.3.0 milestone Jul 25, 2014
@IgorMinar
Copy link
Contributor

Interesting. The current implementation is not ideal because it requires on reading the DOM state during digest (which is super slow), so we can't merge this as is. In many cases we could instead use $attrs.$observe to intercept attribute changes instead of watching them (that won't work for class attribute though because we use classList if available).

@naomiblack can you or someone else review this for correctness from the a11y perspective?

@btford
Copy link
Contributor

btford commented Jul 25, 2014

I think we're better off having a separate repo/module for this so that ARIA support doesn't block the 1.3 release, and so that we can iterate on and release better ARIA support independently of Angular's release cycle. I do think this is important enough to be maintained by angular-core.

(from #5486 (comment) )

@IgorMinar is it alright if I start a new repo for this? Or do we want to get this into 1.3?

nvm just saw this was triaged

@arbus
Copy link
Contributor Author

arbus commented Jul 26, 2014

@IgorMinar Code is now changed to use $attrs.$observe where possible

*
* Currently, the following aria tags are implemented:
*
* + aria-hidded
Copy link
Contributor

Choose a reason for hiding this comment

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

s/hidded/hidden/

*
* + aria-hidden
* + aria-checked
* + aria-diabled
Copy link
Contributor

Choose a reason for hiding this comment

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

aria-disabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is an useful attribute where ng-disabled is used to disabled certain fields based on the state of the form like so:

<form name="myForm">
    ...
   <input type="submit" ng-disabled="!myForm.$valid">
</form>

More info on aria-disabled : http://www.w3.org/TR/wai-aria/states_and_properties#aria-disabled

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I was just pointing out a misspelling in the doc. Thanks for the great info though!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, sorry didn't realize that. Updated now, thanks!

@btford
Copy link
Contributor

btford commented Aug 27, 2014

@marcysutton do you think this is good to go?

@btford btford assigned btford and unassigned naomiblack Aug 27, 2014
* Requires the {@link ngAria `ngAria`} module to be installed.
*/
function $AriaProvider(){
var config = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there other ARIA states and properties that would make sense to add here? What about aria-expanded, aria-label, aria-controls and others? Should those be added on an as-needed-and-tested basis?

@marcysutton
Copy link
Contributor

@btford I have a few questions about the directive to try and understand the scope and intention. It definitely makes sense to add support for tried and tested patterns, such as ngShow, ngHide, and native form inputs. I want to make sure we aren't thinking too small for the likely use cases, including non-semantic and custom elements.


describe('aria-hidden', function(){
beforeEach(function(){
setupModule();
Copy link
Contributor

Choose a reason for hiding this comment

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

why not just beforeEach(module('ngAria')) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed!

@marcysutton
Copy link
Contributor

@arbus, tabs are definitely tricky to get right. I'd agree that omitting ARIA for tabs is a good idea at this point.

I also don't think live regions make sense to add across the board (but I could be proven otherwise). Whether polling updates would be useful to AT users really depends on the context. I'd also want to make sure there aren't any performance issues before introducing them to Angular core.

I am experimenting with demos to make sure the use cases check out. One edit we should consider making now, however, is to check whether an ARIA attribute already exists before injecting it. We're doing that on AngularJS Material to make sure we don't stomp on top of the work by folks who know what they're doing. Any thoughts on that?

@btford
Copy link
Contributor

btford commented Sep 5, 2014

I'd also want to make sure there aren't any performance issues before introducing them to Angular core.

+1; we should probably add a benchmark: https://github.com/angular/angular.js/tree/master/benchmarks

One edit we should consider making now, however, is to check whether an ARIA attribute already exists before injecting it. We're doing that on AngularJS Material to make sure we don't stomp on top of the work by folks who know what they're doing. Any thoughts on that?

+1; I think this makes sense.

});
});

describe('aria-requried', function(){
Copy link
Contributor

Choose a reason for hiding this comment

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

typo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed, thanks for pointing it out!

@marcysutton
Copy link
Contributor

Ok, cool. Some more comments in the module would help maintainability, as well.

@arbus
Copy link
Contributor Author

arbus commented Sep 6, 2014

@marcysutton existing aria tags won't be overwritten if they already exist now.

@btford I am looking at how to write benchmarks now. Is there any particular part of the code that you want to focus on?

@stevefaulkner
Copy link

It is great to see angular improving its accessibility for AT users. It's unclear, from my reading of the code, if the keyboard behaviours associated with the roles being added are also being built-in. For example, if a role=button is being used on a <div> it is imperative that the control is included in the focus order and can be activated using both the enter and space keys. If this is not the case then the addition of a role can degrade the user experience.

@marcysutton
Copy link
Contributor

@stevefaulkner that is such a good point! We definitely need to factor in tabIndex for the module to be useful. Thanks for the heads up.

@stevefaulkner
Copy link

The ARIA design patterns documents required role/state/properties and keyboard interaction for a heap of custom controls.

@marcysutton
Copy link
Contributor

@arbus this module should also handle tabIndex. There are some obvious places, such as role="button" and role="checkbox". The more challenging contexts will come from items like role="radio" where the tabIndex="0" is expected on the parent radiogroup role. How do you want to work this in?

@arbus
Copy link
Contributor Author

arbus commented Sep 11, 2014

@btford @ThomasBurleson All the digest calls have been changed to use $apply. Also, use of ng-init has been removed.

@marcysutton, I just added tabindex for role="checkbox", role="menuitemcheckbox" role="button" and ngClick. Do you think we should add tabindex to ngDblclick as well?

As for the radiogroup problem, it looks like we can just set a tabindex=0 on the selected element tabindex=-1 on the other elements. This is the same approach shown in http://oaa-accessibility.org/example/28/ as well.

Also, do you think we should consider adding in a role="application" on ng-app?

@stevefaulkner
Copy link

@arbus

Also, do you think we should consider adding in a role="application" on ng-app?

Suggest extreme caution with use of role=application

@arbus
Copy link
Contributor Author

arbus commented Sep 11, 2014

@stevefaulkner ah got it. Then we shouldn't add that as a default.

@marcysutton
Copy link
Contributor

@arbus DEFINITELY not on the role="application"; it would cause more harm than good. Thanks @stevefaulkner for your input.

For tabIndex, I think it does make sense to add for ngDblClick. Nice catch! Sounds good for radio buttons.

Adds various aria attributes to the built in directives.
This module currently hooks into ng-show/hide, input, textarea
button as a basic level of support for a11y. I am using this as a
base for adding more tags into the mix for form direction flow,
making ng-repeat updates atomic but the tags here are the most
basic ones.

Closes angular#5486 and angular#1600
@arbus
Copy link
Contributor Author

arbus commented Sep 11, 2014

@marcysutton tabindex has been added to ngDblClick now

@ThomasBurleson
Copy link

@arbus - ngAria is really great work!
@btford - angular-hint is very cool. Perhaps this should also be used in Angular Material ?

@marcysutton
Copy link
Contributor

@arbus @btford I thought of another thing that needs addressing: keyboard events on custom controls. For example, if an element has ng-click on it, we should probably fire ng-keypress unless the developer opts out. Does this make sense to go in the ngAria module?

@arbus
Copy link
Contributor Author

arbus commented Sep 17, 2014

@marcysutton So you mean if a person tabs into an item with ng-click on it, we should listen for say a space bar keypress and fire the ng-click?

@btford
Copy link
Contributor

btford commented Sep 18, 2014

@arbus @marcysutton I paired with @tbosch on this yesterday. Made some changes, but I think it's ready to land. I squashed my changes into @arbus's commit, and created a new PR at #9157. I'd be happy to keep iterating on it once it's in master, but we need to get this in soon for 1.3.

Going forward, we can add new features to this module, but keep them disabled by default so they aren't breaking.

@btford
Copy link
Contributor

btford commented Sep 18, 2014

I landed this as d1434c9 with some changes! 💃

@marcysutton @arbus @ThomasBurleson @stevefaulkner thanks so much for your input! If there are more things we should add, can we start threads in new issues to discuss building upon what we have here?

@btford btford closed this Sep 18, 2014
@david-driscoll
Copy link

Would this override something like ngTouch's touch supported ng-click?

@btford
Copy link
Contributor

btford commented Sep 18, 2014

@david-driscoll nope

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ng-aria binding
10 participants