shadcn-vue
shadcn-vue copied to clipboard
[Feature]: Add a function for ComboBox to allow finding default form value in list of option objects
Describe the feature
Currently, when trying to use the ComboBox with a form, there is a missing use case. A form that wants to track a simple schema like so:
const formSchema = toTypedSchema(z.object({
language: z.string(),
}))
and has an initial state like so:
initialValues: {
language: 'es',
},
Should still allow for sending in options to a combobox like so:
const languages = [
{ label: 'English', value: 'en' },
{ label: 'French', value: 'fr' },
{ label: 'German', value: 'de' },
{ label: 'Spanish', value: 'es' },
{ label: 'Portuguese', value: 'pt' },
{ label: 'Russian', value: 'ru' },
{ label: 'Japanese', value: 'ja' },
{ label: 'Korean', value: 'ko' },
{ label: 'Chinese', value: 'zh' },
] as const
I know in the reka-ui combobox example it sets the modelValue to be languages[0] for example, and it works. That doesn't work with vee-validate, though. There appears to be no prop that I can find to say: hey, lookup my list of options and compare the modelValue to that.
Ie, something like doesn't work:
<FormField name="language" v-slot="{ componentField }">
<FormItem class="flex flex-col">
<FormLabel>Language</FormLabel>
<Combobox v-bind="componentField">
nor does
<FormField name="language" v-slot="{ componentField }">
<FormItem class="flex flex-col">
<FormLabel>Language</FormLabel>
<Combobox :default-value="languages[3]">
The request here is to have this work, as I think it would be a common use case to have the component work correctly with initial values when within a form.
Additional information
- [ ] I intend to submit a PR for this feature.
- [ ] I have already implemented and/or tested this feature.
As a workaround, I found this to work:
const model = defineModel({
get: () => {
if (values.language) {
return languages.find((lang) => lang.value === values.language)
}
}
})
And then set v-model="model" on the ComboBox. It just requires me to reach outside the Field component from vee-validate and use the useForm/useField composables.
Maybe someone could help getting this type of feature into an auto-form component as well? Right now the enum input only works with a list of strings, and not a list of objects that map to a single string value, like requested in this ticket.
Here is a gist of the field I created that works on its own, not through autoform yet though:
https://gist.github.com/marr/ffd1f51dfb4e9a3c5757e1842b383923
I tried the code example from the Combobox - Form documentation, and it works as expected with the initial value. However, I've encountered an issue where the ComboboxInput component does not display the actual value properly (case with initialValue).
Updated Code to check values used within form
<script setup lang="ts">
....
const { values, handleSubmit, setFieldValue } = useForm({ // add `values` here
validationSchema: formSchema,
initialValues: {
language: '',
},
})
....
</script>
<template>
<pre>values - {{ values }}</pre> <!-- to print `values` -->
</template>
Hi, I just solved this issue!
Like what you suggested but using computed, so we need to control modelValue used within combobox
Code Solution
<script setup lang="ts">
....
const { values, handleSubmit, setFieldValue } = useForm({ // add `values` here
validationSchema: formSchema,
initialValues: {
language: '',
},
})
const comboboxValue = computed(() => {
return languages.find(language => language.value === values.language)
})
....
</script>
<template>
...
<Combobox v-model="comboboxValue" by="label">
...
</template>
@Us3r-gitHub won't that be problematic when the combobox tries to write to the computed value?
Also, this may duplicate the feature request here https://github.com/unovue/shadcn-vue-extended/issues/9