-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
75a5edf
commit 495f8c7
Showing
13 changed files
with
333 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { mount } from '@vue/test-utils'; | ||
|
||
import CRadio from './CRadio'; | ||
|
||
describe('CRadio', () => { | ||
it('renders with config checked class', () => { | ||
const wrapper = mount(CRadio, { | ||
global: { | ||
provide: { | ||
$chusho: { | ||
options: { | ||
components: { | ||
radio: { | ||
class: ({ checked }) => { | ||
return { checked }; | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
props: { | ||
modelValue: 'foo', | ||
value: 'foo', | ||
}, | ||
}); | ||
|
||
expect(wrapper.classes()).toEqual(['checked']); | ||
}); | ||
|
||
it('renders with correct attributes by default', () => { | ||
const wrapper = mount(CRadio, { | ||
props: { | ||
value: true, | ||
}, | ||
}); | ||
|
||
expect(wrapper.html()).toEqual('<input type="radio" value="true">'); | ||
}); | ||
|
||
it('renders with extra attributes', () => { | ||
const wrapper = mount(CRadio, { | ||
props: { | ||
value: true, | ||
}, | ||
attrs: { | ||
id: 'radio', | ||
}, | ||
}); | ||
|
||
expect(wrapper.html()).toEqual( | ||
'<input id="radio" type="radio" value="true">' | ||
); | ||
}); | ||
|
||
it('keeps the modelValue synchronized with a single radio', async () => { | ||
const wrapper = mount({ | ||
components: { | ||
CRadio, | ||
}, | ||
data() { | ||
return { | ||
value: false, | ||
}; | ||
}, | ||
template: '<CRadio v-model="value" :value="true" />', | ||
}); | ||
const radio = wrapper.findComponent(CRadio); | ||
|
||
expect(radio.vm.modelValue).toBe(false); | ||
expect(radio.element.checked).toBe(false); | ||
|
||
await radio.setValue(true); | ||
expect(radio.vm.modelValue).toBe(true); | ||
expect(radio.element.checked).toBe(true); | ||
expect(radio.emitted('update:modelValue')).toEqual([[true]]); | ||
|
||
await wrapper.setData({ value: false }); | ||
expect(radio.vm.modelValue).toBe(false); | ||
expect(radio.element.checked).toBe(false); | ||
}); | ||
|
||
it('keeps the modelValue synchronized with multiple radios', async () => { | ||
const wrapper = mount({ | ||
components: { | ||
CRadio, | ||
}, | ||
data() { | ||
return { | ||
value: false, | ||
}; | ||
}, | ||
template: `<CRadio id="1" v-model="value" :value="true" /><CRadio id="2" v-model="value" :value="false" />`, | ||
}); | ||
const radios = wrapper.findAllComponents(CRadio); | ||
|
||
expect(radios[0].vm.modelValue).toBe(false); | ||
expect(radios[0].element.checked).toBe(false); | ||
expect(radios[1].vm.modelValue).toBe(false); | ||
expect(radios[1].element.checked).toBe(true); | ||
|
||
await radios[0].setValue(true); | ||
expect(radios[0].vm.modelValue).toBe(true); | ||
expect(radios[0].element.checked).toBe(true); | ||
expect(radios[0].emitted('update:modelValue')).toEqual([[true]]); | ||
expect(radios[1].vm.modelValue).toBe(true); | ||
expect(radios[1].element.checked).toBe(false); | ||
|
||
await wrapper.setData({ value: false }); | ||
expect(radios[0].vm.modelValue).toBe(false); | ||
expect(radios[0].element.checked).toBe(false); | ||
expect(radios[1].vm.modelValue).toBe(false); | ||
expect(radios[1].element.checked).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { defineComponent, h, inject, mergeProps } from 'vue'; | ||
import { DollarChusho } from '../../types'; | ||
import { ALL_TYPES, generateConfigClass } from '../../utils/components'; | ||
import componentMixin from '../mixins/componentMixin'; | ||
|
||
export default defineComponent({ | ||
name: 'CRadio', | ||
|
||
mixins: [componentMixin], | ||
|
||
inheritAttrs: false, | ||
|
||
props: { | ||
/** | ||
* Bind the Radio state with the parent component. | ||
* @type {any} | ||
*/ | ||
modelValue: { | ||
type: ALL_TYPES, | ||
default: null, | ||
}, | ||
/** | ||
* The value to be used when the Radio is checked. | ||
* @type {any} | ||
*/ | ||
value: { | ||
type: ALL_TYPES, | ||
required: true, | ||
}, | ||
}, | ||
|
||
emits: ['update:modelValue'], | ||
|
||
render() { | ||
const radioConfig = inject<DollarChusho | null>('$chusho', null)?.options | ||
?.components?.radio; | ||
const checked = this.modelValue === this.value; | ||
const attrs: Record<string, unknown> = { | ||
...generateConfigClass(radioConfig?.class, { | ||
...this.$props, | ||
checked, | ||
}), | ||
type: 'radio', | ||
value: this.$props.value, | ||
checked, | ||
onChange: () => this.$emit('update:modelValue', this.$props.value), | ||
}; | ||
|
||
return h('input', mergeProps(this.$attrs, attrs), this.$slots); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import CRadio from './CRadio'; | ||
|
||
export { CRadio }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
packages/chusho/src/components/examples/components/radio/Controlled.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<template> | ||
<div class="space-x-6"> | ||
<CLabel for="radio-1" variant="inline"> | ||
<CRadio | ||
id="radio-1" | ||
v-model="value" | ||
variant="inline" | ||
name="radio-group" | ||
type="radio" | ||
:value="true" | ||
/> | ||
True | ||
</CLabel> | ||
<CLabel for="radio-2" variant="inline"> | ||
<CRadio | ||
id="radio-2" | ||
v-model="value" | ||
variant="inline" | ||
name="radio-group" | ||
type="radio" | ||
:value="false" | ||
/> | ||
False | ||
</CLabel> | ||
<CLabel for="radio-3" variant="inline"> | ||
<CRadio | ||
id="radio-3" | ||
v-model="value" | ||
variant="inline" | ||
name="radio-group" | ||
type="radio" | ||
:value="null" | ||
/> | ||
Other | ||
</CLabel> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { ref } from 'vue'; | ||
const value = ref(false); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<template> | ||
<div class="space-x-6"> | ||
<CLabel variant="inline" for="radio-cats"> | ||
<CRadio v-model="value" variant="inline" id="radio-cats" value="cats" /> | ||
Cats | ||
</CLabel> | ||
<CLabel variant="inline" for="radio-dogs"> | ||
<CRadio v-model="value" variant="inline" id="radio-dogs" value="dogs" /> | ||
Dogs | ||
</CLabel> | ||
<CLabel variant="inline" for="radio-both"> | ||
<CRadio v-model="value" variant="inline" id="radio-both" value="both" /> | ||
Both | ||
</CLabel> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { ref } from 'vue'; | ||
const value = ref('both'); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Radio | ||
|
||
Augmented form field for choice input. | ||
|
||
<Showcase> | ||
<ExampleRadio /> | ||
</Showcase> | ||
|
||
## Config | ||
|
||
The options below are to be set in the [global configuration](/guide/config.html) at the following location: | ||
|
||
```js | ||
{ | ||
components: { | ||
radio: { ... }, | ||
}, | ||
} | ||
``` | ||
|
||
### class | ||
|
||
Classes applied to the input element, except when the prop `bare` is set to `true`. See [styling components](/guide/styling-components/). | ||
|
||
- **type:** `Array<String | Object> | Object | String | (props: Object) => {}` | ||
- **default:** `null` | ||
|
||
#### Example | ||
|
||
```js | ||
class({ checked }) { | ||
return ['radio', { | ||
'radio--checked': checked, | ||
}] | ||
} | ||
``` | ||
|
||
## API | ||
|
||
<Docgen :components="['CRadio']" /> | ||
|
||
## Examples | ||
|
||
### Controlled | ||
|
||
```vue | ||
<template> | ||
<CRadio v-model="value" value="A" /> | ||
<CRadio v-model="value" value="B" /> | ||
<CRadio v-model="value" value="C" /> | ||
</template> | ||
<script> | ||
export default { | ||
data() { | ||
return { | ||
value: null, // None by default | ||
}; | ||
}, | ||
}; | ||
</script> | ||
``` |