Skip to content

Commit

Permalink
Make checkbox accessible (#1031)
Browse files Browse the repository at this point in the history
Added support for
- [x] aria-checked
- [x] aria-labelledby
- [x] aria-label
and the `role="checkbox"`

https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/checkbox_role
  • Loading branch information
mikoscz authored and miguelcobain committed Nov 28, 2018
1 parent 3b966cd commit 464bde6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
18 changes: 18 additions & 0 deletions addon/components/paper-checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { inject as service } from '@ember/service';

import { computed } from '@ember/object';
import { not, and } from '@ember/object/computed';
import Component from '@ember/component';
import { assert } from '@ember/debug';
Expand All @@ -25,6 +26,12 @@ export default Component.extend(FocusableMixin, RippleMixin, ColorMixin, Proxiab
tagName: 'md-checkbox',
classNames: ['md-checkbox', 'md-default-theme'],
classNameBindings: ['isChecked:md-checked', 'indeterminate:md-indeterminate'],
attributeBindings: [
'role:role',
'ariaLabel:aria-label',
'ariaChecked:aria-checked',
'labelId:aria-labelledby'
],

/* RippleMixin Overrides */
rippleContainerSelector: '.md-container',
Expand All @@ -38,9 +45,20 @@ export default Component.extend(FocusableMixin, RippleMixin, ColorMixin, Proxiab
constants: service(),

value: false,
role: 'checkbox',

notIndeterminate: not('indeterminate'),
isChecked: and('notIndeterminate', 'value'),
ariaChecked: computed('isChecked', 'indeterminate', function() {
if (this.get('indeterminate')) {
return 'mixed';
}

return this.get('isChecked') ? 'true' : 'false';
}),
labelId: computed('elementId', function() {
return `${this.elementId}-label`;
}),

init() {
this._super(...arguments);
Expand Down
4 changes: 2 additions & 2 deletions addon/templates/components/paper-checkbox.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
</div>
{{#if hasBlock}}
<div class="md-label">
<span>
<span id={{labelId}}>
{{yield}}
</span>
</div>
{{else}}
<div class="md-label">
<span>
<span id={{labelId}}>
{{label}}
</span>
</div>
Expand Down
50 changes: 49 additions & 1 deletion tests/integration/components/paper-checkbox-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, triggerKeyEvent } from '@ember/test-helpers';
import { render, click, triggerKeyEvent, find } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | paper checkbox', function(hooks) {
Expand Down Expand Up @@ -129,4 +129,52 @@ module('Integration | Component | paper checkbox', function(hooks) {
assert.dom('md-checkbox').doesNotHaveClass('md-checked');
assert.dom('md-checkbox').hasClass('md-indeterminate');
});

test('it correctly sets aria-checked attribute', async function(assert) {
assert.expect(3);

this.set('value', false);
this.set('indeterminate', false);

await render(hbs`{{paper-checkbox onChange=null value=value indeterminate=indeterminate}}`);
assert.dom('md-checkbox').hasAttribute('aria-checked', 'false');

this.set('value', true);
assert.dom('md-checkbox').hasAttribute('aria-checked', 'true');

this.set('indeterminate', true);
assert.dom('md-checkbox').hasAttribute('aria-checked', 'mixed');
});

test('it sets correct aria-labelledby for label passed as property', async function(assert) {
await render(hbs`{{paper-checkbox onChange=null value=true label="important label"}}`);

let labelId = find('md-checkbox').getAttribute('aria-labelledby');

assert.dom(`#${labelId}`).hasText('important label');
});

test('it sets correct aria-labelledby for yielded label', async function(assert) {
await render(hbs`
{{#paper-checkbox onChange=null value=true}}
yielded label
{{/paper-checkbox}}
`);

let labelId = find('md-checkbox').getAttribute('aria-labelledby');

assert.dom(`#${labelId}`).hasText('yielded label');
});

test('it has correct role', async function(assert) {
await render(hbs`{{paper-checkbox onChange=null value=true}}`);

assert.dom('md-checkbox').hasAttribute('role');
});

test('it sets aria-label when ariaLabel is passed', async function(assert) {
await render(hbs`{{paper-checkbox onChange=null value=true ariaLabel='checkbox aria label'}}`);

assert.dom('md-checkbox').hasAttribute('aria-label', 'checkbox aria label');
});
});

0 comments on commit 464bde6

Please # to comment.