Now it is time for look into the component.js for the ember-aria-checkbox component. We will be starting with a bare component skeleton like this:

import Component from '@ember/component'; import { set, get, computed } from '@ember/object'; import layout from '../templates/components/aria-checkbox'; export default Component.extend({ layout, }); 1 2 3 4 5 6 7 8 import Component from '@ember/component' ; import { set , get , computed } from '@ember/object' ; import layout from '../templates/components/aria-checkbox' ; export default Component . extend ( { layout , } ) ;

Next , we will be adding the essential classnames and attributes for the component.

... export default Component.extend({ layout, classNameBindings: ['focus:focus'], attributeBindings: ['role', 'ariaChecked:aria-checked', 'tabindex'], role: 'checkbox', }); 1 2 3 4 5 6 7 8 . . . export default Component . extend ( { layout , classNameBindings : [ 'focus:focus' ] , attributeBindings : [ 'role' , 'ariaChecked:aria-checked' , 'tabindex' ] , role : 'checkbox' , } ) ;

Next we add a computed property ariaChecked to track the toggled state of the component from the checked property.

export default Component.extend({ ... ariaChecked: computed('checked', function() { return get(this, 'checked') ? 'true' : 'false'; }) ... }); 1 2 3 4 5 6 7 export default Component . extend ( { . . . ariaChecked : computed ( 'checked' , function ( ) { return get ( this , 'checked' ) ? 'true' : 'false' ; } ) . . . } ) ;

Then we will be adding the requisite properties for the component to track the toggled and focus states along with the tabindex

export default Component.extend({ ... focus: false, checked: false, tabindex: 0, ... }); 1 2 3 4 5 6 7 export default Component . extend ( { . . . focus : false , checked : false , tabindex : 0 , . . . } ) ;

Now we shift our focus to the event handling part of the component. First we look at the keyDown events like whenever a particular key is pressed, we will toggle the component state from checked to unchecked and vice-versa.

As per the WAI-ARIA recommendations, the SPACE key is used for this purpose as soon as the checkbox got the focus. For that first we need to define the keycode mappings and the handling function for the keyDownevent for the component.

const KEYCODES = { 'RETURN': 13, 'SPACE': 32 }; export default Component.extend({ ... keyDown(e) { let flag = false; switch(e.keyCode) { case KEYCODES.SPACE: this.toggleProperty('checked'); flag = true; break; default: break; } if(flag) { e.stopPropagation(); e.preventDefault(); } } ... }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const KEYCODES = { 'RETURN' : 13 , 'SPACE' : 32 } ; export default Component . extend ( { . . . keyDown ( e ) { let flag = false ; switch ( e . keyCode ) { case KEYCODES . SPACE : this . toggleProperty ( 'checked' ) ; flag = true ; break ; default : break ; } if ( flag ) { e . stopPropagation ( ) ; e . preventDefault ( ) ; } } . . . } ) ;

Next the main click handler for the component where we just toggle the component state checked

export default Component.extend({ ... click() { this.toggleProperty('checked'); } ... }); 1 2 3 4 5 6 7 export default Component . extend ( { . . . click ( ) { this . toggleProperty ( 'checked' ) ; } . . . } ) ;

Finally, to set the focus classnames for the component, we will be setting the respective property focus to true on focus and false on blur.