Skip to content
This repository was archived by the owner on Jan 9, 2022. It is now read-only.

Commit 82cce16

Browse files
committed
feat: add Radio components for demo
1 parent ca77261 commit 82cce16

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

src/components/UI/Radio/Radio.vue

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<template>
2+
<div>
3+
<label>
4+
<input
5+
type="radio"
6+
:name="computedName"
7+
:checked="selected"
8+
@change="onChange"
9+
>
10+
{{ label }}
11+
</label>
12+
</div>
13+
</template>
14+
15+
<script lang="ts">
16+
import { computed, inject } from 'vue'
17+
18+
import { useComponentId } from '@/composables/componentId'
19+
20+
import { RadioInjectionKey } from '@/components/UI/symbols'
21+
22+
export default {
23+
name: 'Radio',
24+
props: {
25+
value: {
26+
type: [String, Boolean],
27+
default: true,
28+
},
29+
30+
label: {
31+
type: String,
32+
default: '',
33+
},
34+
35+
/**
36+
* Sets component's name attribute
37+
*/
38+
name: {
39+
type: String,
40+
default: '',
41+
},
42+
},
43+
44+
emits: ['change'],
45+
46+
setup(props, { emit }) {
47+
const RadioGroup = inject(RadioInjectionKey)
48+
49+
const id = useComponentId()
50+
const computedName = computed(() => {
51+
if(props.name && !RadioGroup) {
52+
return props.name
53+
}
54+
55+
return RadioGroup?.name || `radio-${id}`
56+
})
57+
58+
const onChange = () => {
59+
emit('change')
60+
RadioGroup?.onChange(props.value)
61+
}
62+
63+
const selected = computed(() => RadioGroup?.modelValue.value === props.value)
64+
65+
return {
66+
computedName,
67+
onChange,
68+
selected,
69+
}
70+
},
71+
}
72+
</script>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div>
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<script lang="ts">
8+
import { provide, computed } from 'vue'
9+
10+
import { useComponentId } from '@/composables/componentId'
11+
12+
import { RadioInjectionKey } from '@/components/UI/symbols'
13+
14+
export default {
15+
name: 'RadioGroup',
16+
props: {
17+
name: {
18+
type: String,
19+
default: '',
20+
},
21+
22+
modelValue: {
23+
type: [Boolean, String],
24+
default: '',
25+
},
26+
},
27+
28+
emits: {
29+
'update:modelValue': (value: string | boolean) => true,
30+
},
31+
32+
setup(props, { emit }) {
33+
const id = useComponentId()
34+
const computedName = computed(() => props.name || `radio-group-${id}`)
35+
36+
const computedModelValue = computed(() => props.modelValue)
37+
38+
provide(RadioInjectionKey, {
39+
name: computedName,
40+
modelValue: computedModelValue,
41+
onChange(value) {
42+
emit('update:modelValue', value)
43+
},
44+
})
45+
46+
},
47+
}
48+
</script>

src/components/UI/symbols.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { InjectionKey } from 'vue'
2+
import { RadioInjection } from '@/components/UI/types'
3+
4+
export const RadioInjectionKey: InjectionKey<RadioInjection> = Symbol('GroupRadio')

src/components/UI/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Ref } from 'vue'
2+
3+
export interface RadioInjection {
4+
name: Ref<string>
5+
modelValue: Ref<string | boolean>
6+
onChange: (value: boolean | string) => void
7+
}

0 commit comments

Comments
 (0)