|
1 | 1 | <template> |
2 | 2 | <form> |
3 | | - <div :class="divClass" :key="getOptionValue(option)" v-for="(option, index) in options"> |
| 3 | + <div v-for="(option, index) in options" :key="getOptionValue(option)" :class="divClass"> |
4 | 4 | <input |
5 | | - :class="inputClass" |
6 | | - type="radio" |
7 | | - v-uni-id="getOptionId(option, index)" |
8 | | - :name="`${name}`" |
9 | | - :value="emitObjects ? option : getOptionValue(option)" |
10 | | - v-model="selected" |
11 | | - v-bind="$attrs" |
12 | | - :disabled="isReadOnly" |
13 | | - :aria-label="getOptionAriaLabel(option)" |
14 | | - > |
15 | | - <label :class="labelClass" v-uni-for="getOptionId(option, index)"> |
16 | | - {{getOptionContent(option)}} |
| 5 | + v-model="selected" |
| 6 | + v-uni-id="getOptionId(option, index)" |
| 7 | + :class="inputClass" |
| 8 | + type="radio" |
| 9 | + :name="`${name}`" |
| 10 | + :value="emitObjects ? option : getOptionValue(option)" |
| 11 | + v-bind="$attrs" |
| 12 | + :disabled="isReadOnly" |
| 13 | + :aria-label="getOptionAriaLabel(option)" |
| 14 | + /> |
| 15 | + <label v-uni-for="getOptionId(option, index)" :class="labelClass"> |
| 16 | + {{ getOptionContent(option) }} |
17 | 17 | </label> |
18 | 18 | </div> |
19 | 19 | </form> |
20 | 20 | </template> |
21 | 21 |
|
22 | 22 | <script> |
23 | | -import {createUniqIdsMixin} from 'vue-uniq-ids' |
24 | | -import ValidationMixin from '../mixins/validation' |
| 23 | +import { createUniqIdsMixin } from "vue-uniq-ids"; |
| 24 | +import ValidationMixin from "../mixins/validation"; |
25 | 25 |
|
26 | 26 | const uniqIdsMixin = createUniqIdsMixin(); |
27 | 27 |
|
28 | 28 | export default { |
29 | | - inheritAttrs: false, |
30 | 29 | mixins: [uniqIdsMixin, ValidationMixin], |
| 30 | + inheritAttrs: false, |
31 | 31 | props: [ |
32 | | - 'value', |
33 | | - 'optionValue', |
34 | | - 'optionContent', |
35 | | - 'options', |
36 | | - 'error', |
37 | | - 'helper', |
38 | | - 'name', |
39 | | - 'controlClass', |
40 | | - 'emitObjects', |
41 | | - 'emitArray', |
42 | | - 'optionAriaLabel' |
| 32 | + "value", |
| 33 | + "optionValue", |
| 34 | + "optionContent", |
| 35 | + "options", |
| 36 | + "optionsExtra", |
| 37 | + "error", |
| 38 | + "helper", |
| 39 | + "name", |
| 40 | + "controlClass", |
| 41 | + "emitObjects", |
| 42 | + "emitArray", |
| 43 | + "optionAriaLabel" |
43 | 44 | ], |
44 | 45 | data() { |
45 | 46 | return { |
46 | | - selected:[] |
47 | | - } |
48 | | - }, |
49 | | - mounted() { |
50 | | - this.selected = this.value; |
51 | | - }, |
52 | | - watch: { |
53 | | - value(val) { |
54 | | - this.selected = val; |
55 | | - }, |
56 | | - selected() { |
57 | | - this.$emit('input', this.selected); |
58 | | - } |
| 47 | + selected: [] |
| 48 | + }; |
59 | 49 | }, |
60 | 50 | computed: { |
61 | 51 | divClass() { |
62 | | - return this.toggle ? 'custom-control custom-radio' : 'form-check'; |
| 52 | + return this.toggle ? "custom-control custom-radio" : "form-check"; |
63 | 53 | }, |
64 | 54 | labelClass() { |
65 | | - return this.toggle ? 'custom-control-label' : 'form-check-label'; |
| 55 | + return this.toggle ? "custom-control-label" : "form-check-label"; |
66 | 56 | }, |
67 | 57 | inputClass() { |
68 | 58 | return [ |
69 | | - {[this.controlClass]: !!this.controlClass}, |
70 | | - {'is-invalid': (this.validator && this.validator.errorCount) || this.error}, |
71 | | - this.toggle ? 'custom-control-input' : 'form-check-input' |
| 59 | + { [this.controlClass]: !!this.controlClass }, |
| 60 | + { "is-invalid": (this.validator && this.validator.errorCount) || this.error }, |
| 61 | + this.toggle ? "custom-control-input" : "form-check-input" |
72 | 62 | ]; |
| 63 | + } |
| 64 | + }, |
| 65 | + watch: { |
| 66 | + value(val) { |
| 67 | + this.selected = val; |
73 | 68 | }, |
| 69 | + selected() { |
| 70 | + this.$emit("input", this.selected); |
| 71 | + } |
| 72 | + }, |
| 73 | + mounted() { |
| 74 | + this.selected = this.value; |
74 | 75 | }, |
75 | 76 | methods: { |
76 | 77 | getOptionValue(option) { |
77 | | - return option[this.optionValue || 'value']; |
| 78 | + return option[this.optionValue || "value"]; |
78 | 79 | }, |
79 | 80 | getOptionContent(option) { |
80 | | - return option[this.optionContent || 'content']; |
| 81 | + return option[this.optionContent || "content"]; |
81 | 82 | }, |
82 | 83 | getOptionAriaLabel(option) { |
83 | | - const ariaLabel = option[this.optionAriaLabel || "ariaLabel"]; |
84 | | - return (!ariaLabel || ariaLabel === "") ? this.getOptionContent(option) : ariaLabel; |
| 84 | + let ariaLabel = ""; |
| 85 | + if (this.optionsExtra?.length) { |
| 86 | + const optionExtra = this.optionsExtra.find( |
| 87 | + (extra) => extra.hasOwnProperty(this.optionValue) && extra[this.optionValue] === option[this.optionValue] |
| 88 | + ); |
| 89 | + if (optionExtra) { |
| 90 | + ariaLabel = optionExtra[this.optionAriaLabel || "ariaLabel"] ?? ""; |
| 91 | + } |
| 92 | + } else { |
| 93 | + ariaLabel = option[this.optionAriaLabel || "ariaLabel"] ?? ""; |
| 94 | + } |
| 95 | + return !ariaLabel || ariaLabel === "" ? this.getOptionContent(option) : ariaLabel; |
85 | 96 | }, |
86 | 97 | getOptionId(option, index) { |
87 | 98 | return `${this.name}-${this.getOptionValue(option)}-${index}`; |
88 | 99 | } |
89 | 100 | } |
90 | | -} |
| 101 | +}; |
91 | 102 | </script> |
0 commit comments