Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wants to merge 1 commit into from
Closed

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

@mary-poppins mary-poppins commented Jul 25, 2014

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
Member

@IgorMinar IgorMinar commented Jul 25, 2014

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 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 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

This comment has been minimized.

@btford

btford Aug 11, 2014
Contributor

s/hidded/hidden/

@btford btford removed the gh: PR label Aug 20, 2014
@caitp caitp force-pushed the angular:master branch from 591bac5 to d713ad1 Aug 22, 2014
*
* + aria-hidden
* + aria-checked
* + aria-diabled

This comment has been minimized.

@marcysutton

marcysutton Aug 22, 2014
Contributor

aria-disabled?

This comment has been minimized.

@arbus

arbus Aug 23, 2014
Author Contributor

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

This comment has been minimized.

@marcysutton

marcysutton Aug 23, 2014
Contributor

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

This comment has been minimized.

@arbus

arbus Aug 23, 2014
Author Contributor

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

@arbus arbus force-pushed the arbus:ngAria branch from abf454f to fff6bd5 Aug 23, 2014
@btford
Copy link
Contributor

@btford 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 = {

This comment has been minimized.

@marcysutton

marcysutton Aug 27, 2014
Contributor

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?

return{
restrict: 'E',
link: function(scope, elem, attr){
if(attr.type === 'checkbox'){

This comment has been minimized.

@marcysutton

marcysutton Aug 27, 2014
Contributor

aria-checked could also apply to a radio button input and possibly other widgets, including custom ones with role="checkbox" or role="radio" http://www.w3.org/TR/wai-aria/states_and_properties#aria-checked

This comment has been minimized.

@arbus

arbus Aug 28, 2014
Author Contributor

I intended for the radio type to be included in aria-checked but there isn't any attribute or class that we can monitor to see if an element is checked. We would have to monitor the ng-models' value and compare that against the value/ng-value attribute to figure out which element is checked. So I skipped over that as something that can be added on later and focusing on the simplest cases first.

I'd be open to implementing any way you can suggest!

This comment has been minimized.

@btford

btford Aug 28, 2014
Contributor

You can add another ngModel directive that does this.

This comment has been minimized.

@arbus

arbus Aug 30, 2014
Author Contributor

The radio buttons now have aria-checked enabled on them!

@marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Aug 27, 2014

@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();

This comment has been minimized.

@btford

btford Aug 27, 2014
Contributor

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

This comment has been minimized.

@arbus

arbus Aug 28, 2014
Author Contributor

fixed!

function $AriaProvider(){
var config = {
ariaHidden : true,
ariaChecked: true,

This comment has been minimized.

@btford

btford Aug 27, 2014
Contributor

indentation seems inconsistent; make sure you're using only spaces (no tabs).

This comment has been minimized.

@arbus

arbus Aug 28, 2014
Author Contributor

Had a misconfigured editor, fixed now

@arbus arbus force-pushed the arbus:ngAria branch from fff6bd5 to 79820b2 Aug 28, 2014
@tbosch tbosch force-pushed the angular:master branch from 6c27b89 to 271572c Aug 30, 2014
@arbus arbus force-pushed the arbus:ngAria branch from d830f46 to 88e09ee Sep 5, 2014
@marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Sep 5, 2014

@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 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(){

This comment has been minimized.

@caitp

caitp Sep 5, 2014
Contributor

typo

This comment has been minimized.

@arbus

arbus Sep 6, 2014
Author Contributor

fixed, thanks for pointing it out!

@marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Sep 5, 2014

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

@arbus arbus force-pushed the arbus:ngAria branch from f9320d8 to 168cd18 Sep 6, 2014
@arbus
Copy link
Contributor Author

@arbus 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

@stevefaulkner stevefaulkner commented Sep 6, 2014

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

@marcysutton marcysutton commented Sep 6, 2014

@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

@stevefaulkner stevefaulkner commented Sep 6, 2014

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

@marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Sep 10, 2014

@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?

@tbosch tbosch force-pushed the angular:master branch from a3d7934 to 1418383 Sep 10, 2014
@arbus
Copy link
Contributor Author

@arbus 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?

@arbus arbus force-pushed the arbus:ngAria branch from 168cd18 to 0cc7ca8 Sep 11, 2014
@stevefaulkner
Copy link

@stevefaulkner stevefaulkner commented Sep 11, 2014

@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 arbus commented Sep 11, 2014

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

@marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Sep 11, 2014

@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 #5486 and #1600
@arbus arbus force-pushed the arbus:ngAria branch from 0cc7ca8 to 8d7535e Sep 11, 2014
@arbus
Copy link
Contributor Author

@arbus arbus commented Sep 11, 2014

@marcysutton tabindex has been added to ngDblClick now

@ThomasBurleson
Copy link

@ThomasBurleson ThomasBurleson commented Sep 11, 2014

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

@petebacondarwin petebacondarwin force-pushed the angular:master branch from 02dc2aa to fd2d6c0 Sep 16, 2014
@marcysutton
Copy link
Contributor

@marcysutton marcysutton commented Sep 16, 2014

@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 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 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 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

@david-driscoll david-driscoll commented Sep 18, 2014

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

@btford
Copy link
Contributor

@btford btford commented Sep 18, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

10 participants
You can’t perform that action at this time.