@volverjs/form-vue 1.0.0-beta.25 → 1.0.0-beta.26
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.
- package/dist/VvForm.d.ts +13 -10
- package/dist/VvFormField.d.ts +5 -5
- package/dist/VvFormFieldsGroup.d.ts +5 -5
- package/dist/VvFormTemplate.d.ts +9 -9
- package/dist/VvFormWrapper.d.ts +10 -10
- package/dist/index.d.ts +683 -177
- package/dist/index.es.js +627 -587
- package/dist/index.umd.js +1 -1
- package/dist/types.d.ts +25 -20
- package/package.json +10 -10
- package/src/VvForm.ts +26 -15
- package/src/VvFormField.ts +14 -7
- package/src/VvFormFieldsGroup.ts +17 -6
- package/src/VvFormTemplate.ts +17 -19
- package/src/VvFormWrapper.ts +45 -14
- package/src/index.ts +24 -10
- package/src/types.ts +39 -34
package/src/VvFormWrapper.ts
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type Component,
|
|
2
3
|
type DeepReadonly,
|
|
3
4
|
type InjectionKey,
|
|
4
5
|
type Ref,
|
|
5
6
|
type SlotsType,
|
|
6
7
|
computed,
|
|
7
8
|
defineComponent,
|
|
9
|
+
getCurrentInstance,
|
|
8
10
|
h,
|
|
9
11
|
inject,
|
|
12
|
+
onBeforeUnmount,
|
|
13
|
+
onMounted,
|
|
10
14
|
provide,
|
|
11
15
|
readonly,
|
|
12
16
|
ref,
|
|
13
17
|
toRefs,
|
|
14
18
|
watch,
|
|
15
19
|
} from 'vue'
|
|
16
|
-
import type { inferFormattedError,
|
|
20
|
+
import type { inferFormattedError, z } from 'zod'
|
|
17
21
|
import type {
|
|
18
22
|
FormSchema,
|
|
19
23
|
InjectedFormData,
|
|
20
24
|
InjectedFormWrapperData,
|
|
21
25
|
} from './types'
|
|
22
26
|
|
|
23
|
-
export function defineFormWrapper<Schema extends FormSchema>(formProvideKey: InjectionKey<InjectedFormData<Schema>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>) {
|
|
27
|
+
export function defineFormWrapper<Schema extends FormSchema, Type>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>) {
|
|
24
28
|
return defineComponent({
|
|
25
29
|
name: 'VvFormWrapper',
|
|
26
30
|
props: {
|
|
@@ -50,21 +54,21 @@ export function defineFormWrapper<Schema extends FormSchema>(formProvideKey: Inj
|
|
|
50
54
|
slots: Object as SlotsType<{
|
|
51
55
|
default: {
|
|
52
56
|
errors?: DeepReadonly<z.inferFormattedError<Schema>>
|
|
53
|
-
formData?: Partial<
|
|
57
|
+
formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type
|
|
54
58
|
formErrors?: DeepReadonly<inferFormattedError<Schema, string>>
|
|
55
59
|
invalid: boolean
|
|
56
|
-
submit?: InjectedFormData<Schema>['submit']
|
|
57
|
-
validate?: InjectedFormData<Schema>['validate']
|
|
60
|
+
submit?: InjectedFormData<Schema, Type>['submit']
|
|
61
|
+
validate?: InjectedFormData<Schema, Type>['validate']
|
|
58
62
|
validateWrapper?: () => Promise<boolean>
|
|
59
63
|
fieldsErrors: Map<string, inferFormattedError<Schema, string>>
|
|
60
|
-
clear?: InjectedFormData<Schema>['clear']
|
|
61
|
-
reset?: InjectedFormData<Schema>['reset']
|
|
64
|
+
clear?: InjectedFormData<Schema, Type>['clear']
|
|
65
|
+
reset?: InjectedFormData<Schema, Type>['reset']
|
|
62
66
|
}
|
|
63
67
|
}>,
|
|
64
68
|
setup(props, { emit }) {
|
|
65
69
|
const injectedFormData = inject(formProvideKey)
|
|
66
70
|
const wrapperProvided = inject(wrapperProvideKey, undefined)
|
|
67
|
-
const fields = ref(new
|
|
71
|
+
const fields = ref(new Map<string, string>())
|
|
68
72
|
const fieldsErrors: Ref<
|
|
69
73
|
Map<string, z.inferFormattedError<Schema>>
|
|
70
74
|
> = ref(new Map())
|
|
@@ -80,19 +84,28 @@ export function defineFormWrapper<Schema extends FormSchema>(formProvideKey: Inj
|
|
|
80
84
|
// add fields to parent wrapper
|
|
81
85
|
watch(
|
|
82
86
|
fields,
|
|
83
|
-
(newValue) => {
|
|
87
|
+
(newValue, oldValue) => {
|
|
84
88
|
if (wrapperProvided?.fields) {
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
oldValue.entries().forEach(([id]) => {
|
|
90
|
+
if (!newValue.has(id)) {
|
|
91
|
+
wrapperProvided?.fields.value.delete(id)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
if (wrapperProvided?.fields) {
|
|
96
|
+
newValue.entries().forEach(([id, field]) => {
|
|
97
|
+
if (!wrapperProvided?.fields.value.has(id)) {
|
|
98
|
+
wrapperProvided?.fields.value.set(id, field)
|
|
99
|
+
}
|
|
87
100
|
})
|
|
88
101
|
}
|
|
89
102
|
},
|
|
90
103
|
{ deep: true },
|
|
91
104
|
)
|
|
92
105
|
|
|
93
|
-
// add fields to parent wrapper
|
|
106
|
+
// add fields errors to parent wrapper
|
|
94
107
|
watch(
|
|
95
|
-
|
|
108
|
+
fieldsErrors,
|
|
96
109
|
(newValue, oldValue) => {
|
|
97
110
|
if (wrapperProvided?.errors) {
|
|
98
111
|
Array.from(oldValue.keys()).forEach((key) => {
|
|
@@ -125,8 +138,26 @@ export function defineFormWrapper<Schema extends FormSchema>(formProvideKey: Inj
|
|
|
125
138
|
}
|
|
126
139
|
})
|
|
127
140
|
|
|
141
|
+
onMounted(() => {
|
|
142
|
+
const instance = getCurrentInstance()
|
|
143
|
+
if (!instance || !injectedFormData?.wrappers || !name.value) {
|
|
144
|
+
console.warn('[@volverjs/form-vue]: Invalid wrapper registration state')
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
if (injectedFormData.wrappers.has(name.value)) {
|
|
148
|
+
console.warn(`[@volverjs/form-vue]: wrapper name "${name.value}" is already used`)
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
injectedFormData.wrappers.set(name.value, instance as unknown as Component)
|
|
152
|
+
})
|
|
153
|
+
onBeforeUnmount(() => {
|
|
154
|
+
if (injectedFormData?.wrappers && name.value) {
|
|
155
|
+
injectedFormData.wrappers.delete(name.value)
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
128
159
|
const validateWrapper = () => {
|
|
129
|
-
return injectedFormData?.validate(undefined, fields.value) ?? Promise.resolve(true)
|
|
160
|
+
return injectedFormData?.validate(undefined, new Set(fields.value.values())) ?? Promise.resolve(true)
|
|
130
161
|
}
|
|
131
162
|
|
|
132
163
|
return {
|
package/src/index.ts
CHANGED
|
@@ -25,9 +25,9 @@ import type {
|
|
|
25
25
|
FormTemplate,
|
|
26
26
|
} from './types'
|
|
27
27
|
|
|
28
|
-
function
|
|
28
|
+
function _formType<Schema extends FormSchema, Type>(schema: Schema, options: FormComposableOptions<Schema, Type> = {}) {
|
|
29
29
|
// create injection keys
|
|
30
|
-
const formInjectionKey = Symbol('formInjectionKey') as InjectionKey<InjectedFormData<Schema>>
|
|
30
|
+
const formInjectionKey = Symbol('formInjectionKey') as InjectionKey<InjectedFormData<Schema, Type>>
|
|
31
31
|
const formWrapperInjectionKey = Symbol('formWrapperInjectionKey') as InjectionKey<
|
|
32
32
|
InjectedFormWrapperData<Schema>
|
|
33
33
|
>
|
|
@@ -55,6 +55,7 @@ function _formFactory<Schema extends FormSchema>(schema: Schema, options: FormCo
|
|
|
55
55
|
formFieldsGroupInjectionKey,
|
|
56
56
|
)
|
|
57
57
|
const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField)
|
|
58
|
+
const wrappers = new Map<string, typeof VvFormWrapper>()
|
|
58
59
|
const {
|
|
59
60
|
clear,
|
|
60
61
|
errors,
|
|
@@ -68,7 +69,7 @@ function _formFactory<Schema extends FormSchema>(schema: Schema, options: FormCo
|
|
|
68
69
|
submit,
|
|
69
70
|
validate,
|
|
70
71
|
VvForm,
|
|
71
|
-
} = defineForm(schema, formInjectionKey, options, VvFormTemplate)
|
|
72
|
+
} = defineForm(schema, formInjectionKey, options, VvFormTemplate, wrappers)
|
|
72
73
|
|
|
73
74
|
return {
|
|
74
75
|
clear,
|
|
@@ -85,6 +86,7 @@ function _formFactory<Schema extends FormSchema>(schema: Schema, options: FormCo
|
|
|
85
86
|
stopUpdatesWatch,
|
|
86
87
|
submit,
|
|
87
88
|
validate,
|
|
89
|
+
wrappers,
|
|
88
90
|
VvForm,
|
|
89
91
|
VvFormField,
|
|
90
92
|
VvFormFieldsGroup,
|
|
@@ -98,7 +100,7 @@ export const pluginInjectionKey = Symbol('pluginInjectionKey') as InjectionKey<F
|
|
|
98
100
|
export function createForm(options: FormPluginOptions): Plugin & Partial<ReturnType<typeof useForm>> {
|
|
99
101
|
let toReturn: Partial<ReturnType<typeof useForm>> = {}
|
|
100
102
|
if (options.schema) {
|
|
101
|
-
toReturn =
|
|
103
|
+
toReturn = _formType(options.schema as AnyZodObject, options)
|
|
102
104
|
}
|
|
103
105
|
return {
|
|
104
106
|
...toReturn,
|
|
@@ -128,17 +130,29 @@ export function createForm(options: FormPluginOptions): Plugin & Partial<ReturnT
|
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
|
|
133
|
+
const formInstances: Map<string, ReturnType<typeof _formType>> = new Map()
|
|
134
|
+
export function useForm<Schema extends FormSchema, Type>(schema: Schema, options: FormComposableOptions<Schema, Type> = {}) {
|
|
135
|
+
if (options.scope && formInstances.has(options.scope)) {
|
|
136
|
+
return formInstances.get(options.scope) as ReturnType<typeof _formType<Schema, Type>>
|
|
137
|
+
}
|
|
132
138
|
if (!getCurrentInstance()) {
|
|
133
|
-
|
|
139
|
+
const toReturn = _formType(schema, options)
|
|
140
|
+
if (options.scope) {
|
|
141
|
+
formInstances.set(options.scope, toReturn)
|
|
142
|
+
}
|
|
143
|
+
return toReturn
|
|
134
144
|
}
|
|
135
|
-
|
|
145
|
+
const toReturn = _formType(
|
|
136
146
|
schema as AnyZodObject,
|
|
137
147
|
{
|
|
138
148
|
...inject(pluginInjectionKey, {}),
|
|
139
149
|
...options,
|
|
140
|
-
} as FormComposableOptions<AnyZodObject>,
|
|
150
|
+
} as FormComposableOptions<AnyZodObject, Type>,
|
|
141
151
|
)
|
|
152
|
+
if (options.scope) {
|
|
153
|
+
formInstances.set(options.scope, toReturn)
|
|
154
|
+
}
|
|
155
|
+
return toReturn
|
|
142
156
|
}
|
|
143
157
|
|
|
144
158
|
export { FormFieldType } from './enums'
|
|
@@ -171,6 +185,6 @@ export type {
|
|
|
171
185
|
/**
|
|
172
186
|
* @deprecated Use `useForm()` instead
|
|
173
187
|
*/
|
|
174
|
-
export function
|
|
175
|
-
return
|
|
188
|
+
export function formType<Schema extends FormSchema, Type>(schema: Schema, options: FormComposableOptions<Schema, Type> = {}) {
|
|
189
|
+
return _formType(schema, options)
|
|
176
190
|
}
|
package/src/types.ts
CHANGED
|
@@ -19,43 +19,47 @@ export type FormFieldComponentOptions = {
|
|
|
19
19
|
sideEffects?: (type: `${FormFieldType}`) => Promise<void> | void
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export type FormComponentOptions<Schema> = {
|
|
22
|
+
export type FormComponentOptions<Schema, Type> = {
|
|
23
23
|
updateThrottle?: number
|
|
24
24
|
continuousValidation?: boolean
|
|
25
25
|
readonly?: boolean
|
|
26
|
-
template?: Schema extends FormSchema ? FormTemplate<Schema> : never
|
|
26
|
+
template?: Schema extends FormSchema ? FormTemplate<Schema, Type> : never
|
|
27
|
+
class?: Schema extends FormSchema ? new (data?: Partial<z.infer<Schema>>) => Type : never
|
|
27
28
|
onUpdate?: Schema extends FormSchema
|
|
28
|
-
? (data?: Partial<z.infer<Schema>>) => void
|
|
29
|
+
? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void
|
|
29
30
|
: never
|
|
30
31
|
onSubmit?: Schema extends FormSchema
|
|
31
|
-
? (data?: z.infer<Schema
|
|
32
|
+
? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void
|
|
32
33
|
: never
|
|
33
|
-
onReset?: Schema extends FormSchema ? (data?: z.infer<Schema
|
|
34
|
+
onReset?: Schema extends FormSchema ? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void : never
|
|
34
35
|
onInvalid?: Schema extends FormSchema
|
|
35
36
|
? (error?: z.inferFormattedError<Schema>) => void
|
|
36
37
|
: never
|
|
37
38
|
onValid?: Schema extends FormSchema
|
|
38
|
-
? (data?: z.infer<Schema
|
|
39
|
+
? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void
|
|
39
40
|
: never
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
export type FormComposableOptions<Schema> = FormFieldComponentOptions &
|
|
43
|
-
FormComponentOptions<Schema>
|
|
43
|
+
export type FormComposableOptions<Schema, Type> = FormFieldComponentOptions &
|
|
44
|
+
FormComponentOptions<Schema, Type> & {
|
|
45
|
+
scope?: string
|
|
46
|
+
}
|
|
44
47
|
|
|
45
|
-
type FormPluginOptionsSchema = {
|
|
48
|
+
type FormPluginOptionsSchema<T = Partial<z.infer<FormSchema>>> = {
|
|
46
49
|
schema?: FormSchema
|
|
50
|
+
factory?: (data?: Partial<z.infer<FormSchema>>) => T
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
export type FormPluginOptions = FormPluginOptionsSchema &
|
|
50
|
-
FormComposableOptions<FormPluginOptionsSchema['schema']>
|
|
54
|
+
FormComposableOptions<FormPluginOptionsSchema['schema'], FormPluginOptionsSchema['factory']>
|
|
51
55
|
|
|
52
|
-
export type InjectedFormData<Schema extends FormSchema> = {
|
|
53
|
-
formData: Ref<Partial<z.infer<Schema>> | undefined>
|
|
56
|
+
export type InjectedFormData<Schema extends FormSchema, Type> = {
|
|
57
|
+
formData: Ref<(undefined extends Type ? Partial<z.infer<Schema>> : Type) | undefined>
|
|
54
58
|
errors: Readonly<
|
|
55
59
|
Ref<DeepReadonly<z.inferFormattedError<Schema>> | undefined>
|
|
56
60
|
>
|
|
57
61
|
submit: () => Promise<boolean>
|
|
58
|
-
validate: (formData?: Partial<z.infer<Schema
|
|
62
|
+
validate: (formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type, fields?: Set<string>) => Promise<boolean>
|
|
59
63
|
clear: () => void
|
|
60
64
|
reset: () => void
|
|
61
65
|
ignoreUpdates: IgnoredUpdater
|
|
@@ -63,11 +67,12 @@ export type InjectedFormData<Schema extends FormSchema> = {
|
|
|
63
67
|
status: Readonly<Ref<FormStatus | undefined>>
|
|
64
68
|
invalid: Readonly<Ref<boolean>>
|
|
65
69
|
readonly: Ref<boolean>
|
|
70
|
+
wrappers: Map<string, Component>
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
export type InjectedFormWrapperData<Schema extends FormSchema> = {
|
|
69
74
|
name: Ref<string>
|
|
70
|
-
fields: Ref<
|
|
75
|
+
fields: Ref<Map<string, string>>
|
|
71
76
|
errors: Ref<Map<string, z.inferFormattedError<Schema>>>
|
|
72
77
|
}
|
|
73
78
|
|
|
@@ -133,12 +138,12 @@ export type PathValue<T, TPath extends Path<T> | Path<T>[]> = T extends any
|
|
|
133
138
|
: never
|
|
134
139
|
: never
|
|
135
140
|
|
|
136
|
-
export type AnyBoolean<Schema extends FormSchema> =
|
|
141
|
+
export type AnyBoolean<Schema extends FormSchema, Type> =
|
|
137
142
|
| boolean
|
|
138
143
|
| Ref<boolean>
|
|
139
|
-
| ((data?: InjectedFormData<Schema>) => boolean | Ref<boolean>)
|
|
144
|
+
| ((data?: InjectedFormData<Schema, Type>) => boolean | Ref<boolean>)
|
|
140
145
|
|
|
141
|
-
export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<
|
|
146
|
+
export type SimpleFormTemplateItem<Schema extends FormSchema, Type> = Record<
|
|
142
147
|
string,
|
|
143
148
|
any
|
|
144
149
|
> & {
|
|
@@ -147,42 +152,42 @@ export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<
|
|
|
147
152
|
vvSlots?: Record<string, any>
|
|
148
153
|
vvChildren?:
|
|
149
154
|
| Array<
|
|
150
|
-
| SimpleFormTemplateItem<Schema>
|
|
155
|
+
| SimpleFormTemplateItem<Schema, Type>
|
|
151
156
|
| ((
|
|
152
|
-
data?: InjectedFormData<Schema>,
|
|
157
|
+
data?: InjectedFormData<Schema, Type>,
|
|
153
158
|
scope?: Record<string, unknown>,
|
|
154
|
-
) => SimpleFormTemplateItem<Schema>)
|
|
159
|
+
) => SimpleFormTemplateItem<Schema, Type>)
|
|
155
160
|
>
|
|
156
161
|
| ((
|
|
157
|
-
data?: InjectedFormData<Schema>,
|
|
162
|
+
data?: InjectedFormData<Schema, Type>,
|
|
158
163
|
scope?: Record<string, unknown>,
|
|
159
164
|
) => Array<
|
|
160
|
-
| SimpleFormTemplateItem<Schema>
|
|
165
|
+
| SimpleFormTemplateItem<Schema, Type>
|
|
161
166
|
| ((
|
|
162
|
-
data?: InjectedFormData<Schema>,
|
|
167
|
+
data?: InjectedFormData<Schema, Type>,
|
|
163
168
|
scope?: Record<string, unknown>,
|
|
164
|
-
) => SimpleFormTemplateItem<Schema>)
|
|
169
|
+
) => SimpleFormTemplateItem<Schema, Type>)
|
|
165
170
|
>)
|
|
166
|
-
vvIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>
|
|
167
|
-
vvElseIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>
|
|
171
|
+
vvIf?: AnyBoolean<Schema, Type> | Path<z.infer<Schema>>
|
|
172
|
+
vvElseIf?: AnyBoolean<Schema, Type> | Path<z.infer<Schema>>
|
|
168
173
|
vvType?: `${FormFieldType}`
|
|
169
174
|
vvShowValid?: boolean
|
|
170
175
|
vvContent?: string
|
|
171
176
|
vvDefaultValue?: any
|
|
172
177
|
}
|
|
173
178
|
|
|
174
|
-
export type FormTemplateItem<Schema extends FormSchema> =
|
|
175
|
-
| SimpleFormTemplateItem<Schema>
|
|
179
|
+
export type FormTemplateItem<Schema extends FormSchema, Type> =
|
|
180
|
+
| SimpleFormTemplateItem<Schema, Type>
|
|
176
181
|
| ((
|
|
177
|
-
data?: InjectedFormData<Schema>,
|
|
182
|
+
data?: InjectedFormData<Schema, Type>,
|
|
178
183
|
scope?: Record<string, unknown>,
|
|
179
|
-
) => SimpleFormTemplateItem<Schema>)
|
|
184
|
+
) => SimpleFormTemplateItem<Schema, Type>)
|
|
180
185
|
|
|
181
|
-
export type FormTemplate<Schema extends FormSchema> =
|
|
182
|
-
| FormTemplateItem<Schema>[]
|
|
186
|
+
export type FormTemplate<Schema extends FormSchema, Type> =
|
|
187
|
+
| FormTemplateItem<Schema, Type>[]
|
|
183
188
|
| ((
|
|
184
|
-
data?: InjectedFormData<Schema>,
|
|
189
|
+
data?: InjectedFormData<Schema, Type>,
|
|
185
190
|
scope?: Record<string, unknown>,
|
|
186
|
-
) => FormTemplateItem<Schema>[])
|
|
191
|
+
) => FormTemplateItem<Schema, Type>[])
|
|
187
192
|
|
|
188
193
|
export type RenderFunctionOutput = VNode<RendererNode, RendererElement, { [key: string]: any }>
|