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; |