All files / src/BaseInput BaseRadio.vue.js

95.45% Statements 21/22
90% Branches 9/10
100% Functions 7/7
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                          1x             4x 4x 4x 3x   4x               8x 8x 8x 4x 4x 3x                   1x                   4x 4x       10x 5x   10x       4x       5x 8x            
// @ts-check
 
import Vue from "vue";
import { forEach, indexOf } from "lodash";
 
import BaseToggle from "./BaseToggle.vue";
 
 
/**
 * @details Radio buttons act like a group
 * but no event is emitted when unchecked, keep track of radio buttons
 * @type {{ [name: string]: Instance[] }}
 */
const radioMap = {};
 
/**
 * @param {string} name
 * @param {any} elt
 */
function radioMapAdd(name, elt) {
  Iif (!name) { return; }
  let radios = radioMap[name];
  if (!radios) {
    radios = radioMap[name] = [];
  }
  radios.push(elt);
}
 
/**
 * @param {string} name
 * @param {any} elt
 */
function radioMapRemove(name, elt) {
  const radios = radioMap[name];
  const idx = indexOf(radios, elt);
  if (idx >= 0) {
    radios.splice(idx, 1);
    if (radios.length === 0) {
      delete radioMap[name];
    }
  }
}
 
/**
 * @typedef {V.Instance<typeof component> &
  *  V.Instance<typeof BaseToggle>} Instance
  * @typedef {{ input: HTMLInputElement }} Refs
  */
const component = /** @type {V.Constructor<any, Refs>} */(Vue).extend({
  name: "BaseRadio",
  extends: BaseToggle,
  props: {
    name: { type: String, required: true }
  },
  watch: {
    name: {
      immediate: true,
      handler: function(value, oldValue) {
        radioMapRemove(oldValue, this);
        radioMapAdd(value, this);
      }
    },
    editValue(value) {
      if (value) {
        this.setChecked();
      }
      this.$refs.input.checked = value;
    }
  },
  beforeDestroy() {
    radioMapRemove(this.name, this);
  },
  methods: {
    setChecked() {
      forEach(radioMap[this.name], (radio) => {
        radio.editValue = radio === this;
      });
    }
  }
});
export default component;