Skip to content

Commit

Permalink
feat(v-radio-group): integrate vee-validate validation
Browse files Browse the repository at this point in the history
  • Loading branch information
gravitano committed Jun 27, 2022
1 parent 2e84b4b commit 59cb499
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 18 deletions.
49 changes: 48 additions & 1 deletion packages/forms/src/radio/VRadioGroup.stories.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import {Meta, Story} from '@storybook/vue3';
import {useForm} from 'vee-validate';
import {object, number} from 'yup';
import VRadioGroup from './VRadioGroup.vue';
import VBtn from '@gits-id/button';

const items = [...Array(5)].map((v, k) => ({
text: `Item ${k + 1}`,
value: k + 1,
}));

export default {
title: 'Forms/RadioGroup',
Expand All @@ -8,7 +16,7 @@ export default {
args: {
modelValue: '',
value: '',
items: [...Array(5)].map((v, k) => ({text: `Item ${k + 1}`, value: k + 1})),
items,
itemText: 'text',
itemValue: 'value',
disabled: false,
Expand Down Expand Up @@ -86,3 +94,42 @@ NoLabel.parameters = {
},
},
};

export const Validation: Story<{}> = () => ({
components: {VRadioGroup, VBtn},
setup() {
const schema = object({
choose: number().oneOf([1, 2]).required().label('Agreement'),
});

const {handleSubmit, resetForm, values, errors} = useForm({
validationSchema: schema,
initialValues: {
choose: 0,
},
});

const onSubmit = handleSubmit((values) => {
alert(JSON.stringify(values));
});

return {onSubmit, resetForm, values, errors, items};
},
template: `
<form @submit="onSubmit" class="border-none">
<div class="flex gap-4">
<v-radio-group
name="choose"
label="Choose"
:items="items"
/>
</div>
<div class="mt-4">
<v-btn type="submit">Submit</v-btn>
<v-btn type="button" text @click="resetForm">Reset</v-btn>
</div>
<div class="my-5">Debug:</div>
<pre>{{ {errors, values} }}</pre>
</form>
`,
});
49 changes: 32 additions & 17 deletions packages/forms/src/radio/VRadioGroup.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import {ref, computed, toRefs, watch, PropType} from 'vue';
import {ErrorMessage} from 'vee-validate';
import {ErrorMessage, useField} from 'vee-validate';
import {useTextSize} from '@gits-id/utils';
type Value = string | number | object | boolean | Record<string, any>;
Expand Down Expand Up @@ -60,10 +60,26 @@ const props = defineProps({
type: Boolean,
default: false,
},
hideError: {
type: Boolean,
default: false,
},
labelClass: {
type: String,
default: '',
},
errorClass: {
type: String,
default: 'text-error-600 text-sm mt-1',
},
rules: {
type: String,
default: '',
},
id: {
type: String,
default: '',
},
});
const {
Expand All @@ -77,6 +93,8 @@ const {
itemText,
size,
inline,
name,
rules,
} = toRefs(props);
const emit = defineEmits([
Expand All @@ -87,7 +105,9 @@ const emit = defineEmits([
'blur',
]);
const selected = ref(value.value || modelValue.value);
const {value: selected, errorMessage} = useField(name, rules, {
initialValue: modelValue.value || modelValue.value,
});
const onChange = (event: any) => {
emit('change', event);
Expand Down Expand Up @@ -120,21 +140,13 @@ const setInnerValue = (val: Value) => {
selected.value = val;
};
watch(
modelValue,
(val) => {
setInnerValue(val);
},
{immediate: true},
);
watch(modelValue, (val) => {
setInnerValue(val);
});
watch(
value,
(val) => {
setInnerValue(val);
},
{immediate: true},
);
watch(value, (val) => {
setInnerValue(val);
});
</script>

<template>
Expand All @@ -153,6 +165,7 @@ watch(
>
<label v-for="(item, index) in items" :key="index">
<input
:id="id || name"
v-model="selected"
:name="name"
type="radio"
Expand All @@ -175,6 +188,8 @@ watch(
</slot>
</label>
</div>
<ErrorMessage class="text-error-600 text-sm mt-2 block" :name="name" />
<div v-if="errorMessage && !hideError" :class="errorClass">
{{ errorMessage }}
</div>
</div>
</template>

0 comments on commit 59cb499

Please sign in to comment.