feat: support custom form state

This commit is contained in:
zernonia 2024-04-19 14:10:59 +08:00
parent 1c562463b2
commit b07b4d4d96
2 changed files with 37 additions and 12 deletions

View File

@ -1,12 +1,12 @@
<script setup lang="ts">
import * as z from 'zod'
import { h, reactive } from 'vue'
import { h, reactive, ref } from 'vue'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import { Button } from '@/lib/registry/new-york/ui/button'
import { toast } from '@/lib/registry/new-york/ui/toast'
import type { Config } from '@/lib/registry/new-york/ui/auto-form'
import { AutoForm, AutoFormField } from '@/lib/registry/new-york/ui/auto-form'
import { AutoForm as AutoFormComponent, AutoFormField } from '@/lib/registry/new-york/ui/auto-form'
const schema = z.object({
guestListName: z.string(),
@ -30,11 +30,21 @@ function onSubmit(values: Record<string, any>) {
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
})
}
const form = useForm({
keepValuesOnUnmount: true, // make sure the array/object field doesn't destroy the linked field
validationSchema: toTypedSchema(schema),
})
form.setValues({
guestListName: 'testing 123',
})
</script>
<template>
<AutoForm
<AutoFormComponent
class="w-2/3 space-y-6"
:form="form"
:schema="schema"
:field-config="{
guestListName: {
@ -57,5 +67,5 @@ function onSubmit(values: Record<string, any>) {
<Button type="submit">
Submit
</Button>
</AutoForm>
</AutoFormComponent>
</template>

View File

@ -1,8 +1,8 @@
<script setup lang="ts" generic="U extends ZodRawShape, T extends ZodObject<U>">
import { computed } from 'vue'
import { computed, ref } from 'vue'
import type { ZodAny, ZodObject, ZodRawShape, z } from 'zod'
import { toTypedSchema } from '@vee-validate/zod'
import type { GenericObject } from 'vee-validate'
import type { FormContext, GenericObject } from 'vee-validate'
import { getBaseType, getDefaultValueInZodStack } from './utils'
import type { Config, ConfigItem, Shape } from './interface'
import AutoFormField from './AutoFormField.vue'
@ -10,6 +10,7 @@ import { Form } from '@/lib/registry/new-york/ui/form'
const props = defineProps<{
schema: T
form?: FormContext<GenericObject>
fieldConfig?: Config<z.infer<T>>
}>()
@ -38,14 +39,28 @@ const shapes = computed(() => {
return val
})
const formSchema = computed(() => toTypedSchema(props.schema))
const formComponent = computed(() => props.form ? 'form' : Form)
const formComponentProps = computed(() => {
const formSchema = toTypedSchema(props.schema)
if (props.form) {
return {
onSubmit: props.form.handleSubmit(val => emits('submit', val)),
}
}
else {
return {
keepValues: true,
validationSchema: formSchema,
onSubmit: (val: GenericObject) => emits('submit', val),
}
}
})
</script>
<template>
<Form
:keep-values="true"
:validation-schema="formSchema"
@submit="emits('submit', $event)"
<component
:is="formComponent"
v-bind="formComponentProps"
>
<template v-for="(shape, key) of shapes" :key="key">
<slot
@ -62,5 +77,5 @@ const formSchema = computed(() => toTypedSchema(props.schema))
</template>
<slot :shapes="shapes" />
</Form>
</component>
</template>