all files / addon/components/ radio-group.js

100% Statements 29/29
100% Branches 20/20
100% Functions 4/4
100% Lines 28/28
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84                                              27×                                                                  
import Component from '@ember/component';
import layout from '../templates/components/radio-group';
 
const KEYCODES = {
  'SPACE': 32,
  'LEFT': 37,
  'UP': 38,
  'RIGHT': 39,
  'DOWN': 40,
};
 
/**
 * Radio Group Component
 */
export default Component.extend({
  layout,
 
  groupOptions: null,
  checkedValue: null,
  checkedValueIndex: null,
  activeRadioElement: null,
 
  init() {
    this._super(...arguments);
 
    this.groupOptions.forEach((option, index) => {
      if (option.value === this.checkedValue) {
        this.set('checkedValueIndex', index);
      }
    })
  },
 
  keyDown(e) {
    if (e.keyCode === KEYCODES.UP || e.keyCode === KEYCODES.DOWN) {
      e.preventDefault();
    }
  },
 
  keyUp(e) {
    if (e.keyCode === KEYCODES.UP || e.keyCode === KEYCODES.LEFT) {
      // Check previous option on Up|Left
      if (this.checkedValueIndex <= 0) {
        // Wrap to start
        this.set('checkedValue', this.groupOptions[this.groupOptions.length - 1].value);
        this.set('checkedValueIndex', this.groupOptions.length - 1);
      } else {
        this.set('checkedValue', this.groupOptions[this.checkedValueIndex - 1].value);
        this.set('checkedValueIndex', this.checkedValueIndex - 1);
      }
 
    } else if (e.keyCode === KEYCODES.DOWN || e.keyCode === KEYCODES.RIGHT) {
      // Check next option on Down|Right
      if (this.checkedValueIndex >= this.groupOptions.length - 1) {
        // Wrap to start
        this.set('checkedValue', this.groupOptions[0].value);
        this.set('checkedValueIndex', 0);
      } else {
        this.set('checkedValue', this.groupOptions[this.checkedValueIndex + 1].value);
        this.set('checkedValueIndex', this.checkedValueIndex + 1);
      }
 
    }
 
    // Focus new Element
    const newElement = document.querySelector('[role="radio"][data-value-index="' + this.checkedValueIndex + '"]');
    newElement.focus();
    this.changed(this.groupOptions[this.checkedValueIndex].value);
    e.preventDefault();
  },
 
  click(e) {
    const target = e.target;
 
    if (target.className === "radiogroup__label") return;
 
    this.set('checkedValue', target.getAttribute('data-value'));
    this.set('checkedValueIndex', parseInt(target.getAttribute('data-value-index')));
 
    this.changed(target.getAttribute('data-value'));
  },
 
});