Skip to content

Commit

Permalink
feat(v-form-select): integrate vee-validate to v-form-select
Browse files Browse the repository at this point in the history
  • Loading branch information
gravitano committed Jun 27, 2022
1 parent 43a0a47 commit 637cf64
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 33 deletions.
95 changes: 94 additions & 1 deletion packages/forms/src/form-select/VFormSelect.stories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import {Story, Meta} from '@storybook/vue3';
import {sizes} from '@gits-id/utils/sizes';
import type {VFormSelectProps} from './types';
import type {VFormSelectItem as VFormSelectProps} from './types';
import VFormSelect from './VFormSelect.vue';
import { useForm } from 'vee-validate';
import { object, string } from 'yup';
import {ref} from 'vue'
import VBtn from '@gits-id/button'

const items = [...Array(5)].map((item, index) => ({
value: index,
Expand All @@ -27,6 +31,7 @@ export default {
name: '',
error: false,
errorMessages: [],
disabled: false
},
} as Meta;

Expand Down Expand Up @@ -74,3 +79,91 @@ Error.parameters = {
},
},
};

export const Label = Template.bind({});
Label.args = {
label: 'My Label'
};
Label.parameters = {
docs: {
source: {
code: `<v-form-select :items="items" label="My Label" />`,
},
},
};


export const Validation: Story<{}> = (args) => ({
components: {VBtn, VFormSelect},
setup() {
const schema = object({
genre: string().required().label('Genre'),
gender: string().required().label('Gender'),
});

const {handleSubmit, resetForm, values} = useForm({
validationSchema: schema,
});

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

const genders = ref([
{
text: 'Select Gender',
value: '',
disabled: true
},
{
text: 'Male',
value: 'male'
},
{
text: 'Female',
value: 'female'
}
])

const genres = ref([
{
text: 'Select Genre',
value: '',
disabled: true
},
{
text: 'Pop',
value: 'pop'
},
{
text: 'Rock',
value: 'rock'
}
])

return {onSubmit, resetForm, values, genders, genres};
},
template: `
<form @submit="onSubmit" class="border-none">
<v-form-select
wrapper-class="mb-4"
name="genre"
label="Genre"
placeholder="Select your genre"
:items="genres"
/>
<v-form-select
wrapper-class="mb-4"
name="gender"
label="Gender"
placeholder="Select your gender"
:items="genders"
/>
<div class="mt-4">
<v-btn type="submit">Submit</v-btn>
<v-btn type="button" text @click="resetForm">Reset</v-btn>
</div>
<pre>{{ {values} }}</pre>
</form>
`,
});
85 changes: 53 additions & 32 deletions packages/forms/src/form-select/VFormSelect.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import {ref, toRefs, PropType, watch, computed} from 'vue';
import {ErrorMessage} from 'vee-validate';
import {ErrorMessage, useField} from 'vee-validate';
import {useInputClasses, useTextSize} from '@gits-id/utils';
import type {VFormSelectItem} from './types';
Expand Down Expand Up @@ -45,22 +45,40 @@ const props = defineProps({
type: Boolean,
default: false,
},
errorClass: {
type: String,
default: 'text-error-600 mt-1 text-sm',
},
rules: {
type: String,
default: '',
},
label: {
type: String,
default: '',
},
labelClass: {
type: String,
default: 'block mb-1',
},
wrapperClass: {
type: String,
default: '',
},
});
const emit = defineEmits(['update:modelValue']);
const {
modelValue,
value,
itemText,
itemValue,
error,
errorMessages,
name,
disabled,
} = toRefs(props);
const {modelValue, value, itemText, itemValue, error, name, disabled, rules} =
toRefs(props);
const {value: inputValue, errorMessage} = useField(name, rules, {
initialValue: value.value || modelValue.value,
});
const inputValue = ref(modelValue.value);
const message = computed(() => {
return errorMessage.value || props.errorMessages[0];
});
const {class: sizeClass} = useTextSize(props.size);
const inputClass = computed(() => useInputClasses(error.value));
Expand Down Expand Up @@ -95,25 +113,28 @@ const getText = (option: string | Record<string, any>) => {
</script>

<template>
<select
v-model="inputValue"
class="w-full block transition duration-300"
:class="classes"
:disabled="disabled"
v-bind="$attrs"
>
<option
v-for="(option, index) in items"
:key="index"
v-bind="option"
:value="getValue(option)"
<div :class="wrapperClass">
<label v-if="label" :for="name" :class="labelClass">
{{ label }}
</label>
<select
v-model="inputValue"
class="w-full block transition duration-300"
:class="classes"
:disabled="disabled"
v-bind="$attrs"
>
{{ getText(option) }}
</option>
</select>
<ErrorMessage
v-if="errorMessages.length"
class="text-error text-sm"
:name="name"
/>
<option
v-for="(option, index) in items"
:key="index"
v-bind="option"
:value="getValue(option)"
>
{{ getText(option) }}
</option>
</select>
<div v-if="message" :class="errorClass">
{{ message }}
</div>
</div>
</template>

0 comments on commit 637cf64

Please sign in to comment.