@@ -12,14 +12,23 @@ assistive technologies used by persons with disabilities.
1212
1313##Including ngAria
1414
15- Using ngAria is as simple as requiring the ngAria module in your application. ngAria hooks into
15+ Using {@link ngAria ngAria} is as simple as requiring the ngAria module in your application. ngAria hooks into
1616standard AngularJS directives and quietly injects accessibility support into your application
1717at runtime.
1818
1919```js
2020angular.module('myApp', ['ngAria'])...
2121```
2222
23+ ###Using ngAria
24+ Most of what ngAria does is only visible "under the hood". To see the module in action, once you've
25+ added it as a dependency, you can test a few things:
26+ * Using your favorite element inspector, look for ngAria attributes in your own code.
27+ * Test using your keyboard to ensure `tabindex` is used correctly.
28+ * Fire up a screen reader such as VoiceOver to listen for ARIA support.
29+ [Helpful screen reader tips.](http://webaim.org/articles/screenreader_testing/)
30+
31+ ##Supported directives
2332Currently, ngAria interfaces with the following directives:
2433
2534 * <a href="#ngmodel">ngModel</a>
@@ -31,7 +40,7 @@ Currently, ngAria interfaces with the following directives:
3140
3241<h2 id="ngmodel">ngModel</h2>
3342
34- Most of ngAria's heavy lifting happens in the [ ngModel](https://docs.angularjs.org/api/ng/directive/ ngModel)
43+ Most of ngAria's heavy lifting happens in the {@link ngModel ngModel}
3544directive. For elements using ngModel, special attention is paid by ngAria if that element also
3645has a a role or type of `checkbox`, `radio`, `range` or `textbox`.
3746
@@ -47,15 +56,41 @@ attributes (if they have not been explicitly specified by the developer):
4756
4857###Example
4958
50- ```html
51- <md-checkbox ng-model="val" required>
52- ```
53-
54- Becomes:
55-
56- ```html
57- <md-checkbox ng-model="val" required aria-required="true" tabIndex="0">
58- ```
59+ <example module="ngAria_ngModelExample" deps="angular-aria.js">
60+ <file name="index.html">
61+ <style>
62+ some-checkbox {
63+ background-color: black;
64+ color: white;
65+ }
66+ </style>
67+ <div print-markup>
68+ <form>
69+ <some-checkbox ng-model="user.subscribe" required>
70+ Fake Checkbox
71+ </some-checkbox>
72+ </form>
73+ </div>
74+ <script>
75+ var app = angular.module('ngAria_ngModelExample', ['ngAria']);
76+
77+ app.directive('printMarkup', function() {
78+ return {
79+ restrict: 'A',
80+ link: function($scope, $el, $attrs) {
81+ var el = $el[0].querySelector('form');
82+ var newEl = document.createElement('div');
83+ var output = 'Becomes: <pre><code>' +
84+ el.innerHTML.replace(/&/g, '&').replace(/</g, '<') +
85+ '</code></pre>';
86+ newEl.innerHTML = output;
87+ el.parentNode.insertBefore(newEl, el.nextSibling);
88+ }
89+ }
90+ });
91+ </script>
92+ </file>
93+ </example>
5994
6095ngAria will also add `tabIndex`, ensuring custom elements with these roles will be reachable from
6196the keyboard. It is still up to **you** as a developer to **ensure custom controls will be
@@ -106,6 +141,24 @@ screen reader users won't accidentally focus on "mystery elements". Managing tab
106141child control can be complex and affect performance, so it’s best to just stick with the default
107142`display: none` CSS. See the [fourth rule of ARIA use](http://www.w3.org/TR/aria-in-html/#fourth-rule-of-aria-use).
108143
144+ ###Example
145+ ```css
146+ .ng-hide {
147+ display: block;
148+ opacity: 0;
149+ }
150+ ```
151+ ```html
152+ <div ng-show="false" class="ng-hide" aria-hidden="true"></div>
153+ ```
154+
155+ Becomes:
156+
157+ ```html
158+ <div ng-show="true" aria-hidden="false"></div>
159+ ```
160+ *Note: Child links, buttons or other interactive controls must also be removed from the tab order.*
161+
109162<h2 id="nghide">ngHide</h2>
110163
111164>The [ngHide](https://docs.angularjs.org/api/ng/directive/ngHide) directive shows or hides the
@@ -116,33 +169,86 @@ The default CSS for `ngHide`, the inverse method to `ngShow`, makes ngAria redun
116169`aria-hidden` on the directive when it is hidden or shown, but the content is already hidden with
117170`display: none`. See explanation for <a href="#ngshow">ngShow</a> when overriding the default CSS.
118171
119- <h2 id="ngclick">ngClick and ngDblClick</h2>
120- If `ngClick` or `ngDblClick` is encountered, ngAria will add `tabIndex` if it isn't there already.
121- Even with this, you must currently still add `ng-keypress` to non-interactive elements such as
122- `<div>` or `<taco-button>` to enable keyboard access. Conversation is
123- [currently ongoing](https://github.com/angular/angular.js/issues/9254) about whether ngAria
124- should also bind `ng-keypress` to be more useful.
172+ <h2 id="ngclick">ngClick and ngDblclick</h2>
173+ If `ng-click` or `ng-dblclick` is encountered, ngAria will add `tabindex` if it isn't there already.
174+ Even with this, you must currently still add `ng-keypress` to non-interactive elements such as `div`
175+ or `taco-button` to enable keyboard access. Conversation is currently ongoing about whether ngAria
176+ should also bind `ng-keypress`.
177+
178+ ###Example
179+ ```html
180+ <div ng-click="toggleMenu()"></div>
181+ ```
182+
183+ Becomes:
184+ ```html
185+ <div ng-click="toggleMenu()" tabindex="0"></div>
186+ ```
187+ *Note: ngAria still requires `ng-keypress` to be added manually to non-native controls like divs.*
125188
126189<h2 id="ngmessages">ngMessages</h2>
127190
128191The new ngMessages module makes it easy to display form validation or other messages with priority
129192sequencing and animation. To expose these visual messages to screen readers,
130193ngAria injects `aria-live="polite"`, causing them to be read aloud any time a message is shown,
131194regardless of the user's focus location.
195+ ###Example
132196
133- * * *
197+ ```html
198+ <div ng-messages="myForm.myName.$error">
199+ <div ng-message="required">You did not enter a field</div>
200+ <div ng-message="maxlength">Your field is too long</div>
201+ </div>
202+ ```
134203
135- ##Disabling attributes
136- The attribute magic of ngAria may not work for every scenario. To disable individual attributes,
137- you can use the {@link ngAria.$ariaProvider#config config} method:
204+ Becomes:
138205
206+ ```html
207+ <div ng-messages="myForm.myName.$error" aria-live="polite">
208+ <div ng-message="required">You did not enter a field</div>
209+ <div ng-message="maxlength">Your field is too long</div>
210+ </div>
139211```
140- angular.module('myApp', ['ngAria'], function config($ariaProvider) {
141- $ariaProvider.config({
142- tabindex: false
212+
213+ ##Disabling attributes
214+ The attribute magic of ngAria may not work for every scenario. To disable individual attributes,
215+ you can use the {@link ngAria.$ariaProvider#config config} method. Just keep in mind this will
216+ tell ngAria to ignore the attribute globally.
217+
218+ <example module="ngAria_ngDisabledExample" deps="angular-aria.js">
219+ <file name="index.html">
220+ <form>
221+ <div ng-model="someModel" show-attrs>
222+ Div with ngModel, aria-invalid and tabindex disabled
223+ </div>
224+ </form>
225+ <script>
226+ angular.module('ngAria_ngDisabledExample', ['ngAria'], function config($ariaProvider) {
227+ $ariaProvider.config({
228+ ariaInvalid: false,
229+ tabindex: false
230+ });
231+ })
232+ .directive('showAttrs', function() {
233+ return function(scope, el, attrs) {
234+ var pre = document.createElement('pre');
235+ el.after(pre);
236+ scope.$watch(function() {
237+ var attrs = {};
238+ Array.prototype.slice.call(el[0].attributes, 0).forEach(function(item) {
239+ if (item.name !== 'show-attrs') {
240+ attrs[item.name] = item.value;
241+ }
242+ });
243+ return attrs;
244+ }, function(newAttrs, oldAttrs) {
245+ pre.innerText = JSON.stringify(newAttrs, null, 2);
246+ }, true);
247+ }
143248 });
144- });
145- ```
249+ </script>
250+ </file>
251+ </example>
146252
147253##Common Accessibility Patterns
148254
@@ -171,6 +277,7 @@ Accessibility best practices that apply to web apps in general also apply to Ang
171277
172278 * [Using ARIA in HTML](http://www.w3.org/TR/aria-in-html/)
173279 * [AngularJS Accessibility at ngEurope](https://www.youtube.com/watch?v=dmYDggEgU-s&list=UUEGUP3TJJfMsEM_1y8iviSQ)
280+ * [Testing with Screen Readers](http://webaim.org/articles/screenreader_testing/)
174281 * [Chrome Accessibility Developer Tools](https://chrome.google.com/webstore/detail/accessibility-developer-t/fpkknkljclfencbdbgkenhalefipecmb?hl=en)
175282 * [W3C Accessibility Testing](http://www.w3.org/wiki/Accessibility_testing)
176283 * [WebAIM](http://webaim.org)
0 commit comments