UNPKG

@volverjs/form-vue

Version:

Vue 3 Forms with @volverjs/ui-vue

186 lines (173 loc) 5.88 kB
import type { App, InjectionKey, Plugin } from 'vue' import { getCurrentInstance, inject } from 'vue' import { defineForm } from './VvForm' import { defineFormField } from './VvFormField' import { defineFormFieldsGroup } from './VvFormFieldsGroup' import { defineFormWrapper } from './VvFormWrapper' import { defineFormTemplate } from './VvFormTemplate' import type { InjectedFormData, InjectedFormWrapperData, InjectedFormFieldData, InjectedFormFieldsGroupData, FormComposableOptions, FormPluginOptions, FormTemplateItem, Path, PathValue, FormSchema, FormTemplate, } from './types' function _formType<Schema extends FormSchema, Type>(schema: Schema, options: FormComposableOptions<Schema, Type> = {}) { // create injection keys const formInjectionKey = Symbol('formInjectionKey') as InjectionKey<InjectedFormData<Schema, Type>> const formWrapperInjectionKey = Symbol('formWrapperInjectionKey') as InjectionKey< InjectedFormWrapperData<Schema> > const formFieldInjectionKey = Symbol('formFieldInjectionKey') as InjectionKey< InjectedFormFieldData<Schema> > const formFieldsGroupInjectionKey = Symbol('formFieldsGroupInjectionKey') as InjectionKey< InjectedFormFieldsGroupData<Schema> > // create components const VvFormWrapper = defineFormWrapper<Schema, Type>( formInjectionKey, formWrapperInjectionKey, ) const VvFormField = defineFormField<Schema, Type>( formInjectionKey, formWrapperInjectionKey, formFieldInjectionKey, options, ) const VvFormFieldsGroup = defineFormFieldsGroup<Schema, Type>( formInjectionKey, formWrapperInjectionKey, formFieldsGroupInjectionKey, ) const VvFormTemplate = defineFormTemplate<Schema, Type>(formInjectionKey, VvFormField) const wrappers = new Map<string, InjectedFormWrapperData<Schema>>() const { clear, errors, formData, ignoreUpdates, invalid, readonly, reset, status, stopUpdatesWatch, submit, validate, VvForm, } = defineForm(schema, formInjectionKey, options, VvFormTemplate, wrappers) return { clear, errors, formData, formFieldInjectionKey, formInjectionKey, formWrapperInjectionKey, ignoreUpdates, invalid, readonly, reset, status, stopUpdatesWatch, submit, validate, wrappers, VvForm, VvFormField, VvFormFieldsGroup, VvFormTemplate, VvFormWrapper, } } export const pluginInjectionKey = Symbol('pluginInjectionKey') as InjectionKey<FormPluginOptions> export function createForm(options: FormPluginOptions): Plugin & Partial<ReturnType<typeof useForm>> { let toReturn: Partial<ReturnType<typeof useForm>> = {} if (options.schema) { // @ts-expect-error - options.schema is always defined toReturn = _formType(options.schema, 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?.VvFormFieldsGroup) { app.component('VvFormFieldsGroup', toReturn.VvFormFieldsGroup) } if (toReturn?.VvFormTemplate) { app.component('VvFormTemplate', toReturn.VvFormTemplate) } } }, } } const formInstances: Map<string, ReturnType<typeof _formType>> = new Map() export function useForm<Schema extends FormSchema, Type>(schema: Schema, options: FormComposableOptions<Schema, Type> = {}): ReturnType <typeof _formType<Schema, Type>> { if (options.scope && formInstances.has(options.scope)) { return formInstances.get(options.scope) } if (!getCurrentInstance()) { const toReturn = _formType(schema, options) if (options.scope) { formInstances.set(options.scope, toReturn) } return toReturn } const toReturn = _formType( schema, { ...inject(pluginInjectionKey, {}), ...options, } as FormComposableOptions<Schema, Type>, ) if (options.scope) { formInstances.set(options.scope, toReturn) } return toReturn } export { FormFieldType } from './enums' export { defaultObjectBySchema } from './utils' type FormComponent = ReturnType<typeof defineForm> type FormWrapperComponent = ReturnType<typeof defineFormWrapper> type FormFieldComponent = ReturnType<typeof defineFormField> type FormFieldsGroupComponent = ReturnType<typeof defineFormFieldsGroup> type FormTemplateComponent = ReturnType<typeof defineFormFieldsGroup> export type { FormComponent, FormComposableOptions, FormFieldComponent, FormFieldsGroupComponent, FormPluginOptions, FormSchema, FormTemplate, FormTemplateComponent, FormTemplateItem, FormWrapperComponent, InjectedFormData, InjectedFormFieldData, InjectedFormWrapperData, Path, PathValue, } /** * @deprecated Use `useForm()` instead */ export function formType<Schema extends FormSchema, Type>(schema: Schema, options: FormComposableOptions<Schema, Type> = {}) { return _formType(schema, options) }