UNPKG

@volverjs/form-vue

Version:

Vue 3 Forms with @volverjs/ui-vue

156 lines (143 loc) 3.66 kB
import { getCurrentInstance, type App, inject, type InjectionKey, type Plugin, } from 'vue' import { defineFormField } from './VvFormField' import { defineForm } from './VvForm' import { defineFormWrapper } from './VvFormWrapper' import { defineFormTemplate } from './VvFormTemplate' import type { InjectedFormData, InjectedFormWrapperData, InjectedFormFieldData, FormComposableOptions, FormPluginOptions, FormTemplateItem, Path, PathValue, FormSchema, FormTemplate, } from './types' import type { AnyZodObject } from 'zod' const _formFactory = <Schema extends FormSchema>( schema: Schema, options: FormComposableOptions<Schema> = {}, ) => { // create injection keys const formInjectionKey = Symbol() as InjectionKey<InjectedFormData<Schema>> const formWrapperInjectionKey = Symbol() as InjectionKey< InjectedFormWrapperData<Schema> > const formFieldInjectionKey = Symbol() as InjectionKey< InjectedFormFieldData<Schema> > // create components const VvFormWrapper = defineFormWrapper( formInjectionKey, formWrapperInjectionKey, ) const VvFormField = defineFormField( formInjectionKey, formWrapperInjectionKey, formFieldInjectionKey, options, ) const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField) const { VvForm, errors, status, formData } = defineForm( schema, formInjectionKey, options, VvFormTemplate, ) return { VvForm, VvFormWrapper, VvFormField, VvFormTemplate, formInjectionKey, formWrapperInjectionKey, formFieldInjectionKey, errors, status, formData, } } export const pluginInjectionKey = Symbol() as InjectionKey<FormPluginOptions> export const createForm = ( options: FormPluginOptions, ): Plugin & Partial<ReturnType<typeof useForm>> => { let toReturn: Partial<ReturnType<typeof useForm>> = {} if (options.schema) { toReturn = _formFactory(options.schema as AnyZodObject, options) } return { ...toReturn, install(app: App, { global = false } = {}) { app.provide(pluginInjectionKey, options) if (global) { app.config.globalProperties.$vvForm = options if (toReturn?.VvForm) { app.component('VvForm', toReturn.VvForm) } if (toReturn?.VvFormWrapper) { app.component('VvFormWrapper', toReturn.VvFormWrapper) } if (toReturn?.VvFormField) { app.component('VvFormField', toReturn.VvFormField) } if (toReturn?.VvFormTemplate) { app.component('VvFormTemplate', toReturn.VvFormTemplate) } } }, } } export const useForm = <Schema extends FormSchema>( schema: Schema, options: FormComposableOptions<Schema> = {}, ) => { if (!getCurrentInstance()) { return _formFactory(schema, options) } return _formFactory( schema as AnyZodObject, { ...inject(pluginInjectionKey, {}), ...options, } as FormComposableOptions<AnyZodObject>, ) } export { FormFieldType } from './enums' export { defaultObjectBySchema } from './utils' type FormComponent = ReturnType<typeof defineForm> type FormWrapperComponent = ReturnType<typeof defineFormWrapper> type FormFieldComponent = ReturnType<typeof defineFormField> type FormTemplateComponent = ReturnType<typeof defineFormTemplate> export type { InjectedFormData, InjectedFormWrapperData, InjectedFormFieldData, FormComposableOptions, FormSchema, FormPluginOptions, FormComponent, FormWrapperComponent, FormFieldComponent, FormTemplate, FormTemplateComponent, FormTemplateItem, Path, PathValue, } /** * @deprecated Use `useForm()` instead */ export const formFactory = <Schema extends FormSchema>( schema: Schema, options: FormComposableOptions<Schema> = {}, ) => { return _formFactory(schema, options) }