Skip to content
This repository was archived by the owner on Mar 17, 2021. It is now read-only.

Commit ee94262

Browse files
committed
Added radio and radio-group components
1 parent 70aa3a6 commit ee94262

File tree

8 files changed

+330
-0
lines changed

8 files changed

+330
-0
lines changed

docs/.vuepress/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ module.exports = {
2525
'components/badge',
2626
'components/button',
2727
'components/checkbox',
28+
'components/radio',
29+
'components/radio-group',
2830
'components/tabs',
2931
'components/textbox'
3032
]

docs/components/radio-group.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Radio Group
2+
Set of radio's components
3+
4+
## Example
5+
<div class="p-3 border rounded-2 my-3">
6+
<v-radio-group
7+
class="mb-3"
8+
label="Favorite color"
9+
name="group1"
10+
v-model="group1"
11+
:options="['White', 'Red', 'Blue']"
12+
/>
13+
14+
<v-radio-group
15+
label="Favorite color"
16+
name="group2"
17+
v-model="group2"
18+
:options="[
19+
{ id: 1, label: 'White', value: 'white', disabled: false },
20+
{ id: 2, label: 'Red', value: 'red', disabled: true },
21+
{ id: 3, label: 'Blue', value: 'blue', disabled: false },
22+
]"
23+
/>
24+
</div>
25+
26+
```html
27+
<!-- Array of strings -->
28+
<v-radio-group
29+
label="Favorite color"
30+
name="group1"
31+
v-model="group1"
32+
:options="['White', 'Red', 'Blue']"
33+
/>
34+
35+
<!-- Array of objects -->
36+
<v-radio-group
37+
label="Favorite color"
38+
name="group2"
39+
v-model="group2"
40+
:options="[
41+
{ id: 1, label: 'White', value: 'white', disabled: false },
42+
{ id: 2, label: 'Red', value: 'red', disabled: true },
43+
{ id: 3, label: 'Blue', value: 'blue', disabled: false },
44+
]"
45+
/>
46+
```
47+
48+
## Props
49+
Name | Type | Description | Default | Required
50+
---------- | -------- | ----------- | ------- | --------
51+
name | String | The name of the radio group. Applied as the `name` attribute on each input element in the radio group | false | true
52+
label | String | The radio group label | None | false
53+
value, v-model | [String, Number] | The model that the selected value in the radio group syncs to. Can be set initially for a default selection. If you are not using `v-model`, you should listen for the `input` event and update `value` | None | true
54+
options | Array | An array of options to show to the user as radio buttons. The array can either be of strings or objects (but not both). | None | true
55+
keys | Object | Allows for redefining the option keys. The id, class, checked, and disabled keys are optional. Pass an object with custom keys if your data does not match the default keys. Note that if you redefine one key, you have to define all the others as well.| `{id: 'id',label: 'label',value: 'value',checked: 'checked',disabled: 'disabled' }` | false
56+
tabindex | [String, Number] | The radio group tabindex | None | false
57+
disabled | Boolean | Whether or not the radio group is disabled | false | false
58+
59+
## Events
60+
Name | Description
61+
---------- | -----------
62+
@focus | Emitted when a radio button in the group is focused
63+
@blur | Emitted when a radio button in the group loses focus
64+
@input | Emitted when the radio group value is changed. The handler is called with the new value
65+
@change | Emitted when the value of the radio group is changed. The handler is called with the new value
66+
67+
## Methods
68+
Name | Description
69+
---------- | ----------
70+
reset() | Call this method to reset the radio group's `value` to its initial `value`.
71+
<script>
72+
export default {
73+
data() {
74+
return { group1: '', group2: '' };
75+
},
76+
};
77+
</script>

docs/components/radio.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Radio
2+
The custom radio and it's states.
3+
4+
## Example
5+
<div class="p-3 border rounded-2 my-3 flex">
6+
<v-radio :checked="true" id="radio1" label="Radio 1" name="radio-group1" v-model="radio1" true-value="radio1-value" />
7+
</div>
8+
9+
```html
10+
<v-radio
11+
id="radio1"
12+
label="Radio 1"
13+
name="radio-group1"
14+
v-model="radio1"
15+
true-value="radio1-value"
16+
/>
17+
```
18+
19+
20+
## Props
21+
Name | Type | Description | Default | Required
22+
---------- | ----------------- | ----------------- | ------- | --------
23+
id | [String, Number] | Unique identifier | None | true
24+
Name | [String, Number] | The name attribute of the radio input element | None | true
25+
Label | [String, Number] | The radio label | None | true
26+
27+
## Events
28+
29+
## Methods
30+
31+
<script>
32+
export default {
33+
data() {
34+
return { radio1: '' };
35+
},
36+
};
37+
</script>

src/components/Radio/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Radio from './main.vue';
2+
3+
// eslint-disable-next-line func-names
4+
Radio.install = function (Vue) {
5+
Vue.component('VRadio', Radio);
6+
};
7+
8+
export default Radio;

src/components/Radio/main.vue

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<template>
2+
<div class="radio">
3+
<input
4+
class="radio__input"
5+
type="radio"
6+
7+
:id="id"
8+
:checked="checked"
9+
:disabled="disabled"
10+
:name="name"
11+
:tabindex="tabindex"
12+
:value="trueValue"
13+
14+
@blur="onBlur"
15+
@change="onChange"
16+
@focus="onFocus"
17+
18+
>
19+
<label class="radio__label" :for="id">{{ label }}</label>
20+
</div>
21+
</template>
22+
23+
<script>
24+
export default {
25+
name: 'VRadio',
26+
props: {
27+
id: {
28+
type: [String, Number],
29+
required: true,
30+
},
31+
name: {
32+
type: String,
33+
required: true,
34+
},
35+
label: {
36+
type: String,
37+
required: true,
38+
},
39+
tabindex: {
40+
type: [String, Number],
41+
},
42+
value: {
43+
type: [Number, String],
44+
required: true,
45+
},
46+
trueValue: {
47+
type: [Number, String],
48+
required: true,
49+
},
50+
checked: {
51+
type: Boolean,
52+
default: false,
53+
},
54+
disabled: {
55+
type: Boolean,
56+
default: false,
57+
},
58+
},
59+
created() {
60+
if (this.checked) {
61+
this.$emit('input', this.trueValue);
62+
}
63+
},
64+
computed: {
65+
isChecked() {
66+
// eslint-disable-next-line eqeqeq
67+
return (String(this.value).length > 0) && (this.value == this.trueValue);
68+
},
69+
},
70+
methods: {
71+
onFocus(e) {
72+
this.isActive = true;
73+
this.$emit('focus', e);
74+
},
75+
onBlur(e) {
76+
this.isActive = false;
77+
this.$emit('blur', e);
78+
},
79+
onChange(e) {
80+
if (!this.disabled) {
81+
this.$emit('input', this.trueValue);
82+
}
83+
84+
this.$emit('change', this.isChecked, e);
85+
},
86+
focus() {
87+
this.$refs.input.focus();
88+
},
89+
},
90+
};
91+
</script>

src/components/RadioGroup/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import RadioGroup from './main.vue';
2+
3+
// eslint-disable-next-line func-names
4+
RadioGroup.install = function (Vue) {
5+
Vue.component('VRadio', RadioGroup);
6+
};
7+
8+
export default RadioGroup;

src/components/RadioGroup/main.vue

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<template>
2+
<div class="radio-group">
3+
<div class="radio-group__label">{{ label }}</div>
4+
5+
<div class="radio-group__list">
6+
<div
7+
class="radio-group__item"
8+
:key="option[keys.id] || `${name}-${i}`"
9+
v-for="(option, i) in options"
10+
>
11+
<VRadio
12+
:id="option[keys.id] || `${name}-${i}`"
13+
:label="option[keys.label] || option"
14+
:checked="isOptionCheckedByDefault(option)"
15+
:disabled="disabled || option[keys.disabled]"
16+
:key="option[keys.id]"
17+
:name="name"
18+
:tabindex="tabindex"
19+
:true-value="option[keys.value] || option"
20+
21+
@blur="onBlur"
22+
@focus="onFocus"
23+
24+
v-model="selectedOptionValue"
25+
/>
26+
</div>
27+
</div>
28+
</div>
29+
</template>
30+
31+
<script>
32+
import VRadio from '../Radio';
33+
34+
export default {
35+
name: 'VRadioGroup',
36+
props: {
37+
name: {
38+
type: String,
39+
required: true,
40+
},
41+
tabindex: {
42+
type: [String, Number],
43+
},
44+
label: {
45+
type: String,
46+
},
47+
options: {
48+
type: Array,
49+
required: true,
50+
},
51+
value: {
52+
type: [Number, String],
53+
required: true,
54+
},
55+
keys: {
56+
type: Object,
57+
default() {
58+
return {
59+
id: 'id',
60+
label: 'label',
61+
value: 'value',
62+
checked: 'checked',
63+
disabled: 'disabled',
64+
};
65+
},
66+
},
67+
disabled: {
68+
type: Boolean,
69+
default: false,
70+
},
71+
},
72+
data() {
73+
return {
74+
initialValue: this.value,
75+
selectedOptionValue: this.value,
76+
};
77+
},
78+
methods: {
79+
reset() {
80+
this.$emit('input', this.initialValue);
81+
},
82+
isOptionCheckedByDefault(option) {
83+
// eslint-disable-next-line eqeqeq
84+
return this.initialValue == option[this.keys.value] || this.initialValue == option
85+
|| option[this.keys.checked];
86+
},
87+
onFocus(e) {
88+
this.$emit('focus', e);
89+
},
90+
onBlur(e) {
91+
this.$emit('blur', e);
92+
},
93+
},
94+
watch: {
95+
selectedOptionValue() {
96+
this.$emit('input', this.selectedOptionValue);
97+
this.$emit('change', this.selectedOptionValue);
98+
},
99+
value() {
100+
this.selectedOptionValue = this.value;
101+
},
102+
},
103+
components: { VRadio },
104+
};
105+
</script>

src/components/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ export { default as VAvatar } from './Avatar';
33
export { default as VBadge } from './Badge';
44
export { default as VButton } from './Button';
55
export { default as VCheckbox } from './Checkbox';
6+
export { default as VRadio } from './Radio';
7+
export { default as VRadioGroup } from './RadioGroup';
68
export { default as VTab } from './Tab';
79
export { default as VTabs } from './Tabs';
810
export { default as VTextbox } from './Textbox';

0 commit comments

Comments
 (0)