@volverjs/form-vue 0.0.9 → 0.0.10-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,21 +16,25 @@ import {
16
16
  toRefs,
17
17
  watch,
18
18
  defineComponent,
19
+ onBeforeUnmount,
19
20
  } from 'vue'
21
+ import type { z } from 'zod'
20
22
  import { FormFieldType } from './enums'
21
23
  import type {
22
24
  InjectedFormData,
23
25
  InjectedFormWrapperData,
24
26
  InjectedFormFieldData,
25
- FormComposableOptions,
27
+ FormFieldComponentOptions,
28
+ Path,
29
+ FormSchema,
26
30
  } from './types'
27
31
 
28
- export const defineFormField = (
29
- formProvideKey: InjectionKey<InjectedFormData>,
30
- wrapperProvideKey: InjectionKey<InjectedFormWrapperData>,
31
- formFieldInjectionKey: InjectionKey<InjectedFormFieldData>,
32
- options: FormComposableOptions = {},
33
- ): Component => {
32
+ export const defineFormField = <Schema extends FormSchema>(
33
+ formProvideKey: InjectionKey<InjectedFormData<Schema>>,
34
+ wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>,
35
+ formFieldInjectionKey: InjectionKey<InjectedFormFieldData<Schema>>,
36
+ options?: FormFieldComponentOptions,
37
+ ) => {
34
38
  // define component
35
39
  return defineComponent({
36
40
  name: 'FieldComponent',
@@ -47,15 +51,20 @@ export const defineFormField = (
47
51
  default: undefined,
48
52
  },
49
53
  name: {
50
- type: [String, Number, Boolean, Symbol],
54
+ type: [String, Number, Boolean, Symbol] as PropType<
55
+ Path<z.infer<Schema>>
56
+ >,
51
57
  required: true,
52
58
  },
53
59
  props: {
54
60
  type: [Object, Function] as PropType<
55
- | Record<string, unknown>
56
- | ((
57
- formData?: Ref<ObjectConstructor>,
58
- ) => Record<string, unknown>)
61
+ Partial<
62
+ | z.infer<Schema>
63
+ | undefined
64
+ | ((
65
+ formData?: Ref<ObjectConstructor>,
66
+ ) => Partial<z.infer<Schema>> | undefined)
67
+ >
59
68
  >,
60
69
  default: () => ({}),
61
70
  },
@@ -67,6 +76,10 @@ export const defineFormField = (
67
76
  type: [String, Number, Boolean, Array, Object],
68
77
  default: undefined,
69
78
  },
79
+ lazyLoad: {
80
+ type: Boolean,
81
+ default: false,
82
+ },
70
83
  },
71
84
  emits: ['invalid', 'valid', 'update:formData', 'update:modelValue'],
72
85
  expose: ['invalid', 'invalidLabel', 'errors'],
@@ -74,22 +87,22 @@ export const defineFormField = (
74
87
  // v-model
75
88
  const modelValue = computed({
76
89
  get() {
77
- if (!formProvided?.modelValue) return
90
+ if (!injectedFormData?.formData) return
78
91
  return get(
79
- Object(formProvided.modelValue.value),
92
+ Object(injectedFormData.formData.value),
80
93
  String(props.name),
81
94
  )
82
95
  },
83
96
  set(value) {
84
- if (!formProvided?.modelValue) return
97
+ if (!injectedFormData?.formData) return
85
98
  set(
86
- Object(formProvided.modelValue.value),
99
+ Object(injectedFormData.formData.value),
87
100
  String(props.name),
88
101
  value,
89
102
  )
90
103
  emit('update:modelValue', {
91
104
  newValue: modelValue.value,
92
- formData: formProvided?.modelValue,
105
+ formData: injectedFormData?.formData,
93
106
  })
94
107
  },
95
108
  })
@@ -102,21 +115,26 @@ export const defineFormField = (
102
115
  }
103
116
  })
104
117
 
118
+ onBeforeUnmount(() => {
119
+ unwatchInvalid()
120
+ unwatchInjectedFormData()
121
+ })
122
+
105
123
  // inject data from parent form wrapper
106
- const wrapperProvided = inject(wrapperProvideKey, undefined)
107
- if (wrapperProvided) {
108
- wrapperProvided.fields.value.add(props.name as string)
124
+ const injectedWrapperData = inject(wrapperProvideKey, undefined)
125
+ if (injectedWrapperData) {
126
+ injectedWrapperData.fields.value.add(props.name as string)
109
127
  }
110
128
 
111
129
  // inject data from parent form
112
- const formProvided = inject(formProvideKey)
130
+ const injectedFormData = inject(formProvideKey)
113
131
  const { props: fieldProps, name: fieldName } = toRefs(props)
114
132
 
115
133
  const errors = computed(() => {
116
- if (!formProvided?.errors.value) {
134
+ if (!injectedFormData?.errors.value) {
117
135
  return undefined
118
136
  }
119
- return get(formProvided.errors.value, String(props.name))
137
+ return get(injectedFormData.errors.value, String(props.name))
120
138
  })
121
139
  const invalidLabel = computed(() => {
122
140
  return errors.value?._errors
@@ -124,27 +142,30 @@ export const defineFormField = (
124
142
  const invalid = computed(() => {
125
143
  return errors.value !== undefined
126
144
  })
127
- watch(invalid, () => {
145
+ const unwatchInvalid = watch(invalid, () => {
128
146
  if (invalid.value) {
129
147
  emit('invalid', invalidLabel.value)
130
- if (wrapperProvided) {
131
- wrapperProvided.errors.value.set(props.name as string, {
132
- _errors: invalidLabel.value,
133
- })
148
+ if (injectedWrapperData) {
149
+ injectedWrapperData.errors.value.set(
150
+ props.name as string,
151
+ {
152
+ _errors: invalidLabel.value,
153
+ },
154
+ )
134
155
  }
135
156
  } else {
136
157
  emit('valid', modelValue.value)
137
- if (wrapperProvided) {
138
- wrapperProvided.errors.value.delete(
158
+ if (injectedWrapperData) {
159
+ injectedWrapperData.errors.value.delete(
139
160
  props.name as string,
140
161
  )
141
162
  }
142
163
  }
143
164
  })
144
- watch(
145
- () => formProvided?.modelValue,
165
+ const unwatchInjectedFormData = watch(
166
+ () => injectedFormData?.formData,
146
167
  () => {
147
- emit('update:formData', formProvided?.modelValue)
168
+ emit('update:formData', injectedFormData?.formData)
148
169
  },
149
170
  { deep: true },
150
171
  )
@@ -153,7 +174,7 @@ export const defineFormField = (
153
174
  }
154
175
  const hasFieldProps = computed(() => {
155
176
  if (typeof fieldProps.value === 'function') {
156
- return fieldProps.value(formProvided?.modelValue)
177
+ return fieldProps.value(injectedFormData?.formData)
157
178
  }
158
179
  return fieldProps.value
159
180
  })
@@ -188,7 +209,6 @@ export const defineFormField = (
188
209
  })(props.type as FormFieldType),
189
210
  invalidLabel: invalidLabel.value,
190
211
  modelValue: modelValue.value,
191
- errors: props.is ? errors.value : undefined,
192
212
  'onUpdate:modelValue': onUpdate,
193
213
  }))
194
214
 
@@ -207,15 +227,15 @@ export const defineFormField = (
207
227
  onUpdate,
208
228
  invalid: invalid.value,
209
229
  invalidLabel: invalidLabel.value,
210
- formData: formProvided?.modelValue.value,
211
- formErrors: formProvided?.errors.value,
230
+ formData: injectedFormData?.formData.value,
231
+ formErrors: injectedFormData?.errors.value,
212
232
  errors: errors.value,
213
233
  }) ?? slots.defalut
214
234
  )
215
235
  },
216
236
  }
217
237
  }
218
- if (!options.lazyLoad) {
238
+ if (!(options?.lazyLoad ?? props.lazyLoad)) {
219
239
  let component: string | ConcreteComponent
220
240
  switch (props.type) {
221
241
  case FormFieldType.select:
@@ -251,7 +271,7 @@ export const defineFormField = (
251
271
  }
252
272
  }
253
273
  return defineAsyncComponent(async () => {
254
- if (options.sideEffects) {
274
+ if (options?.sideEffects) {
255
275
  await Promise.resolve(options.sideEffects(props.type))
256
276
  }
257
277
  switch (props.type) {
@@ -0,0 +1,179 @@
1
+ import { get } from 'ts-dot-prop'
2
+ import {
3
+ type Component,
4
+ type PropType,
5
+ type InjectionKey,
6
+ type DeepReadonly,
7
+ type Ref,
8
+ type VNode,
9
+ defineComponent,
10
+ h,
11
+ inject,
12
+ unref,
13
+ } from 'vue'
14
+ import type { TypeOf, z } from 'zod'
15
+ import type { FormSchema, InjectedFormData, FormTemplateItem } from './types'
16
+ import type { FormStatus } from './enums'
17
+
18
+ export const defineFormTemplate = <Schema extends FormSchema>(
19
+ formProvideKey: InjectionKey<InjectedFormData<Schema>>,
20
+ VvFormField: Component,
21
+ ) => {
22
+ const VvFormTemplate: Component = defineComponent({
23
+ props: {
24
+ schema: {
25
+ type: [Array, Function] as PropType<
26
+ | FormTemplateItem<Schema>[]
27
+ | ((
28
+ data?: InjectedFormData<Schema>,
29
+ ) => FormTemplateItem<Schema>[])
30
+ >,
31
+ required: true,
32
+ },
33
+ },
34
+ setup(templateProps, { slots: templateSlots }) {
35
+ const injectedFormData = inject(formProvideKey)
36
+ if (!injectedFormData?.formData) return
37
+ const normalizedSchema =
38
+ typeof templateProps.schema === 'function'
39
+ ? templateProps.schema(injectedFormData)
40
+ : templateProps.schema
41
+ let lastIf: boolean | undefined = undefined
42
+ return () =>
43
+ normalizedSchema.reduce<(VNode | VNode[] | undefined)[]>(
44
+ (acc, field) => {
45
+ const normalizedField =
46
+ typeof field === 'function'
47
+ ? field(injectedFormData)
48
+ : field
49
+ const {
50
+ vvIs,
51
+ vvName,
52
+ vvSlots,
53
+ vvChildren,
54
+ vvIf,
55
+ vvElseIf,
56
+ vvType,
57
+ vvDefaultValue,
58
+ vvShowValid,
59
+ ...props
60
+ } = normalizedField
61
+ // conditions
62
+ if (vvIf !== undefined) {
63
+ if (typeof vvIf === 'string') {
64
+ lastIf = Boolean(
65
+ get(
66
+ Object(injectedFormData.formData.value),
67
+ vvIf,
68
+ ),
69
+ )
70
+ } else if (typeof vvIf === 'function') {
71
+ lastIf = unref(vvIf(injectedFormData))
72
+ } else {
73
+ lastIf = unref(vvIf)
74
+ }
75
+ if (!lastIf) {
76
+ return acc
77
+ }
78
+ } else if (
79
+ vvElseIf !== undefined &&
80
+ lastIf !== undefined
81
+ ) {
82
+ if (lastIf) {
83
+ return acc
84
+ }
85
+ if (typeof vvElseIf === 'string') {
86
+ lastIf = Boolean(
87
+ get(
88
+ Object(injectedFormData.formData.value),
89
+ vvElseIf,
90
+ ),
91
+ )
92
+ } else if (typeof vvElseIf === 'function') {
93
+ lastIf = unref(vvElseIf(injectedFormData))
94
+ } else {
95
+ lastIf = unref(vvElseIf)
96
+ }
97
+ if (!lastIf) {
98
+ return acc
99
+ }
100
+ } else {
101
+ lastIf = undefined
102
+ }
103
+ // children
104
+ const hChildren = vvChildren
105
+ ? h(VvFormTemplate, {
106
+ schema: vvChildren,
107
+ })
108
+ : undefined
109
+ // render
110
+ if (vvName) {
111
+ acc.push(
112
+ h(
113
+ VvFormField,
114
+ {
115
+ name: vvName,
116
+ is: vvIs,
117
+ type: vvType,
118
+ defaultValue: vvDefaultValue,
119
+ showValid: vvShowValid,
120
+ props,
121
+ },
122
+ vvSlots ?? hChildren,
123
+ ),
124
+ )
125
+ return acc
126
+ }
127
+ if (vvIs) {
128
+ acc.push(
129
+ h(
130
+ vvIs as Component,
131
+ props,
132
+ vvSlots ?? hChildren,
133
+ ),
134
+ )
135
+ return acc
136
+ }
137
+ if (vvChildren) {
138
+ acc.push(hChildren)
139
+ return acc
140
+ }
141
+ return acc
142
+ },
143
+ [
144
+ templateSlots?.default?.({
145
+ formData: injectedFormData?.formData.value,
146
+ submit: injectedFormData?.submit,
147
+ errors: injectedFormData?.errors.value,
148
+ status: injectedFormData?.status.value,
149
+ invalid: injectedFormData?.invalid.value,
150
+ }),
151
+ ],
152
+ )
153
+ },
154
+ })
155
+
156
+ /**
157
+ * An hack to add types to the default slot
158
+ */
159
+ return VvFormTemplate as typeof VvFormTemplate & {
160
+ new (): {
161
+ $slots: {
162
+ default: (_: {
163
+ formData: unknown extends
164
+ | Partial<TypeOf<Schema>>
165
+ | undefined
166
+ ? undefined
167
+ : Partial<TypeOf<Schema>> | undefined
168
+ submit: () => boolean
169
+ errors: Readonly<
170
+ Ref<DeepReadonly<z.inferFormattedError<Schema>>>
171
+ >
172
+ status: Ref<DeepReadonly<`${FormStatus}` | undefined>>
173
+ invalid: Ref<DeepReadonly<boolean>>
174
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
+ }) => any
176
+ }
177
+ }
178
+ }
179
+ }
@@ -10,14 +10,20 @@ import {
10
10
  toRefs,
11
11
  watch,
12
12
  h,
13
+ type DeepReadonly,
13
14
  } from 'vue'
14
- import type { InjectedFormData, InjectedFormWrapperData } from './types'
15
+ import type { TypeOf, z } from 'zod'
16
+ import type {
17
+ FormSchema,
18
+ InjectedFormData,
19
+ InjectedFormWrapperData,
20
+ } from './types'
15
21
 
16
- export const defineFormWrapper = (
17
- formProvideKey: InjectionKey<InjectedFormData>,
18
- wrapperProvideKey: InjectionKey<InjectedFormWrapperData>,
22
+ export const defineFormWrapper = <Schema extends FormSchema>(
23
+ formProvideKey: InjectionKey<InjectedFormData<Schema>>,
24
+ wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>,
19
25
  ) => {
20
- return defineComponent({
26
+ const VvFormWrapper = defineComponent({
21
27
  name: 'WrapperComponent',
22
28
  props: {
23
29
  name: {
@@ -32,10 +38,10 @@ export const defineFormWrapper = (
32
38
  emits: ['invalid', 'valid'],
33
39
  expose: ['fields', 'invalid'],
34
40
  setup(props, { emit }) {
35
- const formProvided = inject(formProvideKey)
41
+ const injectedFormData = inject(formProvideKey)
36
42
  const wrapperProvided = inject(wrapperProvideKey, undefined)
37
43
  const fields = ref(new Set<string>())
38
- const errors: Ref<
44
+ const fieldsErrors: Ref<
39
45
  Map<string, Record<string, { _errors: string[] }>>
40
46
  > = ref(new Map())
41
47
  const { name } = toRefs(props)
@@ -43,7 +49,7 @@ export const defineFormWrapper = (
43
49
  // provide data to child fields
44
50
  provide(wrapperProvideKey, {
45
51
  name: readonly(name),
46
- errors,
52
+ errors: fieldsErrors,
47
53
  fields,
48
54
  })
49
55
 
@@ -62,7 +68,7 @@ export const defineFormWrapper = (
62
68
 
63
69
  // add fields to parent wrapper
64
70
  watch(
65
- () => new Map(errors.value),
71
+ () => new Map(fieldsErrors.value),
66
72
  (newValue, oldValue) => {
67
73
  if (wrapperProvided?.errors) {
68
74
  Array.from(oldValue.keys()).forEach((key) => {
@@ -80,10 +86,10 @@ export const defineFormWrapper = (
80
86
  )
81
87
 
82
88
  const invalid = computed(() => {
83
- if (!formProvided?.errors.value) {
89
+ if (!injectedFormData?.invalid.value) {
84
90
  return false
85
91
  }
86
- return errors.value.size > 0
92
+ return fieldsErrors.value.size > 0
87
93
  })
88
94
 
89
95
  watch(invalid, () => {
@@ -94,29 +100,64 @@ export const defineFormWrapper = (
94
100
  }
95
101
  })
96
102
 
97
- return { formProvided, invalid, fields, errors }
103
+ return {
104
+ formData: injectedFormData?.formData,
105
+ errors: injectedFormData?.errors,
106
+ invalid,
107
+ fields,
108
+ fieldsErrors,
109
+ }
98
110
  },
99
111
  render() {
100
112
  if (this.tag) {
101
- return h(
102
- this.tag,
103
- null,
104
- this.$slots.default?.({
105
- invalid: this.invalid,
106
- formData: this.formProvided?.modelValue,
107
- errors: this.formProvided?.errors,
108
- fieldsErrors: this.errors,
109
- }) ?? this.$slots.defalut,
110
- )
113
+ return h(this.tag, null, {
114
+ default: () =>
115
+ this.$slots.default?.({
116
+ invalid: this.invalid,
117
+ formData: this.formData,
118
+ errors: this.errors,
119
+ fieldsErrors: this.fieldsErrors,
120
+ }) ?? this.$slots.defalut,
121
+ })
111
122
  }
112
123
  return (
113
124
  this.$slots.default?.({
114
125
  invalid: this.invalid,
115
- formData: this.formProvided?.modelValue,
116
- errors: this.formProvided?.errors,
117
- fieldsErrors: this.errors,
126
+ formData: this.formData,
127
+ errors: this.errors,
128
+ fieldsErrors: this.fieldsErrors,
118
129
  }) ?? this.$slots.defalut
119
130
  )
120
131
  },
121
132
  })
133
+ /**
134
+ * An hack to add types to the default slot
135
+ */
136
+ return VvFormWrapper as typeof VvFormWrapper & {
137
+ new (): {
138
+ $slots: {
139
+ default: (_: {
140
+ invalid: boolean
141
+ formData: unknown extends
142
+ | Partial<TypeOf<Schema>>
143
+ | undefined
144
+ ? undefined
145
+ : Partial<TypeOf<Schema>> | undefined
146
+ errors: Readonly<
147
+ Ref<DeepReadonly<z.inferFormattedError<Schema>>>
148
+ >
149
+ fieldsErrors: Map<
150
+ string,
151
+ Record<
152
+ string,
153
+ {
154
+ _errors: string[]
155
+ }
156
+ >
157
+ >
158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
+ }) => any
160
+ }
161
+ }
162
+ }
122
163
  }
package/src/enums.ts CHANGED
@@ -21,3 +21,8 @@ export enum FormFieldType {
21
21
  combobox = 'combobox',
22
22
  custom = 'custom',
23
23
  }
24
+
25
+ export enum FormStatus {
26
+ invalid = 'invalid',
27
+ valid = 'valid',
28
+ }
package/src/index.ts CHANGED
@@ -1,30 +1,45 @@
1
- import { type App, inject, type InjectionKey, type Plugin } from 'vue'
2
- import type { AnyZodObject, ZodEffects } from 'zod'
1
+ import {
2
+ getCurrentInstance,
3
+ type App,
4
+ inject,
5
+ type InjectionKey,
6
+ type Plugin,
7
+ } from 'vue'
3
8
  import { defineFormField } from './VvFormField'
4
9
  import { defineForm } from './VvForm'
5
10
  import { defineFormWrapper } from './VvFormWrapper'
11
+ import { defineFormTemplate } from './VvFormTemplate'
6
12
  import type {
7
13
  InjectedFormData,
8
14
  InjectedFormWrapperData,
9
15
  InjectedFormFieldData,
10
16
  FormComposableOptions,
11
17
  FormPluginOptions,
18
+ FormTemplateItem,
19
+ Path,
20
+ PathValue,
21
+ FormSchema,
12
22
  } from './types'
13
23
 
14
- export const formFactory = (
15
- schema: AnyZodObject | ZodEffects<AnyZodObject>,
24
+ const _formFactory = <Schema extends FormSchema>(
25
+ schema: Schema,
16
26
  options: FormComposableOptions = {},
17
27
  ) => {
18
- // create injection keys form provide/inject
19
- const formInjectionKey = Symbol() as InjectionKey<InjectedFormData>
20
- const formWrapperInjectionKey =
21
- Symbol() as InjectionKey<InjectedFormWrapperData>
22
-
23
- const formFieldInjectionKey =
24
- Symbol() as InjectionKey<InjectedFormFieldData>
28
+ // create injection keys
29
+ const formInjectionKey = Symbol() as InjectionKey<InjectedFormData<Schema>>
30
+ const formWrapperInjectionKey = Symbol() as InjectionKey<
31
+ InjectedFormWrapperData<Schema>
32
+ >
33
+ const formFieldInjectionKey = Symbol() as InjectionKey<
34
+ InjectedFormFieldData<Schema>
35
+ >
25
36
 
26
37
  // create components
27
- const VvForm = defineForm(schema, formInjectionKey, options)
38
+ const { VvForm, errors, status, formData } = defineForm(
39
+ schema,
40
+ formInjectionKey,
41
+ options,
42
+ )
28
43
  const VvFormWrapper = defineFormWrapper(
29
44
  formInjectionKey,
30
45
  formWrapperInjectionKey,
@@ -35,14 +50,19 @@ export const formFactory = (
35
50
  formFieldInjectionKey,
36
51
  options,
37
52
  )
53
+ const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField)
38
54
 
39
55
  return {
40
56
  VvForm,
41
57
  VvFormWrapper,
42
58
  VvFormField,
59
+ VvFormTemplate,
43
60
  formInjectionKey,
44
61
  formWrapperInjectionKey,
45
62
  formFieldInjectionKey,
63
+ errors,
64
+ status,
65
+ formData,
46
66
  }
47
67
  }
48
68
 
@@ -53,7 +73,7 @@ export const createForm = (
53
73
  ): Plugin & Partial<ReturnType<typeof useForm>> => {
54
74
  let toReturn: Partial<ReturnType<typeof useForm>> = {}
55
75
  if (options.schema) {
56
- toReturn = formFactory(options.schema, options)
76
+ toReturn = _formFactory(options.schema, options)
57
77
  }
58
78
  return {
59
79
  ...toReturn,
@@ -72,17 +92,25 @@ export const createForm = (
72
92
  if (toReturn?.VvFormField) {
73
93
  app.component('VvFormField', toReturn.VvFormField)
74
94
  }
95
+ if (toReturn?.VvFormTemplate) {
96
+ app.component('VvFormTemplate', toReturn.VvFormTemplate)
97
+ }
75
98
  }
76
99
  },
77
100
  }
78
101
  }
79
102
 
80
- export const useForm = (
81
- schema: AnyZodObject | ZodEffects<AnyZodObject>,
103
+ export const useForm = <Schema extends FormSchema>(
104
+ schema: Schema,
82
105
  options: FormComposableOptions = {},
83
106
  ) => {
84
- const hasOptions = { ...inject(pluginInjectionKey, {}), ...options }
85
- return formFactory(schema, hasOptions)
107
+ if (!getCurrentInstance()) {
108
+ return _formFactory(schema, options)
109
+ }
110
+ return _formFactory(schema, {
111
+ ...inject(pluginInjectionKey, {}),
112
+ ...options,
113
+ })
86
114
  }
87
115
 
88
116
  export { FormFieldType } from './enums'
@@ -91,6 +119,7 @@ export { defaultObjectBySchema } from './utils'
91
119
  type FormComponent = ReturnType<typeof defineForm>
92
120
  type FormWrapperComponent = ReturnType<typeof defineFormWrapper>
93
121
  type FormFieldComponent = ReturnType<typeof defineFormField>
122
+ type FormTemplateComponent = ReturnType<typeof defineFormTemplate>
94
123
 
95
124
  export type {
96
125
  InjectedFormData,
@@ -101,4 +130,18 @@ export type {
101
130
  FormComponent,
102
131
  FormWrapperComponent,
103
132
  FormFieldComponent,
133
+ FormTemplateComponent,
134
+ FormTemplateItem,
135
+ Path,
136
+ PathValue,
137
+ }
138
+
139
+ /**
140
+ * @deprecated Use `useForm()` instead
141
+ */
142
+ export const formFactory = <Schema extends FormSchema>(
143
+ schema: Schema,
144
+ options: FormComposableOptions = {},
145
+ ) => {
146
+ return _formFactory(schema, options)
104
147
  }