@volverjs/form-vue 0.0.14-beta.2 → 0.0.14-beta.4
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/index.d.ts +1 -988
- package/dist/index.es.js +335 -313
- package/dist/index.umd.js +1 -1
- package/dist/{VvForm.d.ts → src/VvForm.d.ts} +18 -3
- package/dist/src/VvFormTemplate.d.ts +131 -0
- package/dist/src/index.d.ts +1919 -0
- package/dist/{types.d.ts → src/types.d.ts} +14 -6
- package/dist/test-playwright/VvForm.spec.d.ts +1 -0
- package/dist/test-playwright/VvFormField.spec.d.ts +1 -0
- package/dist/test-playwright/VvFormWrapper.spec.d.ts +1 -0
- package/dist/test-vitest/defaultObjectBySchema.test.d.ts +1 -0
- package/dist/test-vitest/useForm.test.d.ts +1 -0
- package/package.json +18 -17
- package/src/VvForm.ts +39 -13
- package/src/VvFormTemplate.ts +109 -114
- package/src/index.ts +21 -13
- package/src/types.ts +28 -7
- package/dist/VvFormTemplate.d.ts +0 -21
- /package/dist/{VvFormField.d.ts → src/VvFormField.d.ts} +0 -0
- /package/dist/{VvFormWrapper.d.ts → src/VvFormWrapper.d.ts} +0 -0
- /package/dist/{enums.d.ts → src/enums.d.ts} +0 -0
- /package/dist/{utils.d.ts → src/utils.d.ts} +0 -0
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { z, AnyZodObject, ZodEffects } from 'zod';
|
|
1
|
+
import { type Component, type DeepReadonly, type Ref } from 'vue';
|
|
2
|
+
import type { z, AnyZodObject, ZodEffects, inferFormattedError } from 'zod';
|
|
3
3
|
import type { FormFieldType, FormStatus } from './enums';
|
|
4
4
|
export type FormSchema = AnyZodObject | ZodEffects<AnyZodObject> | ZodEffects<ZodEffects<AnyZodObject>>;
|
|
5
5
|
export type FormFieldComponentOptions = {
|
|
6
6
|
lazyLoad?: boolean;
|
|
7
7
|
sideEffects?: (type: `${FormFieldType}`) => Promise<void> | void;
|
|
8
8
|
};
|
|
9
|
-
export type FormComponentOptions = {
|
|
9
|
+
export type FormComponentOptions<Schema> = {
|
|
10
10
|
updateThrottle?: number;
|
|
11
11
|
continuosValidation?: boolean;
|
|
12
|
+
template?: Schema extends FormSchema ? FormTemplate<Schema> : never;
|
|
13
|
+
onUpdate?: Schema extends FormSchema ? (data: Partial<z.infer<Schema> | undefined>) => void : never;
|
|
14
|
+
onSubmit?: Schema extends FormSchema ? (data: z.infer<Schema>) => void : never;
|
|
15
|
+
onInvalid?: Schema extends FormSchema ? (error: inferFormattedError<Schema, string>) => void : never;
|
|
16
|
+
onValid?: Schema extends FormSchema ? (data: z.infer<Schema>) => void : never;
|
|
12
17
|
};
|
|
13
|
-
export type FormComposableOptions = FormFieldComponentOptions & FormComponentOptions
|
|
14
|
-
|
|
18
|
+
export type FormComposableOptions<Schema> = FormFieldComponentOptions & FormComponentOptions<Schema>;
|
|
19
|
+
type FormPluginOptionsSchema = {
|
|
15
20
|
schema?: FormSchema;
|
|
16
|
-
}
|
|
21
|
+
};
|
|
22
|
+
export type FormPluginOptions = FormPluginOptionsSchema & FormComposableOptions<FormPluginOptionsSchema['schema']>;
|
|
17
23
|
export type InjectedFormData<Schema extends FormSchema> = {
|
|
18
24
|
formData: Ref<Partial<z.infer<Schema>> | undefined>;
|
|
19
25
|
errors: Readonly<Ref<DeepReadonly<z.inferFormattedError<Schema>> | undefined>>;
|
|
@@ -52,7 +58,9 @@ export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<string, a
|
|
|
52
58
|
vvElseIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>;
|
|
53
59
|
vvType?: `${FormFieldType}`;
|
|
54
60
|
vvShowValid?: boolean;
|
|
61
|
+
vvContent?: string;
|
|
55
62
|
vvDefaultValue?: any;
|
|
56
63
|
};
|
|
57
64
|
export type FormTemplateItem<Schema extends FormSchema> = SimpleFormTemplateItem<Schema> | ((data?: InjectedFormData<Schema>) => SimpleFormTemplateItem<Schema>);
|
|
65
|
+
export type FormTemplate<Schema extends FormSchema> = FormTemplateItem<Schema>[] | ((data?: InjectedFormData<Schema>) => FormTemplateItem<Schema>[]);
|
|
58
66
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/volverjs/form-vue/issues"
|
|
21
21
|
},
|
|
22
|
-
"version": "0.0.14-beta.
|
|
22
|
+
"version": "0.0.14-beta.4",
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">= 16.x"
|
|
25
25
|
},
|
|
26
|
-
"packageManager": "pnpm@8.
|
|
26
|
+
"packageManager": "pnpm@8.7.5",
|
|
27
27
|
"type": "module",
|
|
28
28
|
"main": "./dist/index.js",
|
|
29
29
|
"module": "./dist/index.js",
|
|
@@ -35,34 +35,35 @@
|
|
|
35
35
|
"*.d.ts"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@volverjs/ui-vue": "
|
|
39
|
-
"@vueuse/core": "^10.
|
|
38
|
+
"@volverjs/ui-vue": "0.0.10-beta.3",
|
|
39
|
+
"@vueuse/core": "^10.4.1",
|
|
40
40
|
"ts-dot-prop": "^2.1.3",
|
|
41
41
|
"vue": "^3.3.4",
|
|
42
|
-
"zod": "^3.
|
|
42
|
+
"zod": "^3.22.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@playwright/experimental-ct-vue": "1.
|
|
45
|
+
"@playwright/experimental-ct-vue": "1.38.0",
|
|
46
46
|
"@testing-library/vue": "^7.0.0",
|
|
47
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
48
|
-
"@
|
|
49
|
-
"@vitejs/plugin-vue": "^4.2.3",
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
48
|
+
"@vitejs/plugin-vue": "^4.3.4",
|
|
50
49
|
"@volverjs/style": "^0.1.11",
|
|
51
50
|
"@vue/compiler-sfc": "^3.3.4",
|
|
51
|
+
"@vue/eslint-config-typescript": "^12.0.0",
|
|
52
52
|
"@vue/runtime-core": "^3.3.4",
|
|
53
53
|
"@vue/test-utils": "^2.4.1",
|
|
54
54
|
"copy": "^0.3.2",
|
|
55
|
-
"eslint": "^8.
|
|
55
|
+
"eslint": "^8.49.0",
|
|
56
56
|
"eslint-config-prettier": "^9.0.0",
|
|
57
57
|
"eslint-plugin-prettier": "^5.0.0",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
58
|
+
"eslint-plugin-vue": "^9.17.0",
|
|
59
|
+
"happy-dom": "^11.0.6",
|
|
60
|
+
"prettier": "^3.0.3",
|
|
61
|
+
"typescript": "^5.2.2",
|
|
61
62
|
"vite": "^4.4.9",
|
|
62
|
-
"vite-plugin-dts": "^3.5.
|
|
63
|
+
"vite-plugin-dts": "^3.5.3",
|
|
63
64
|
"vite-plugin-eslint": "^1.8.1",
|
|
64
65
|
"vite-plugin-externalize-deps": "^0.7.0",
|
|
65
|
-
"vitest": "^0.34.
|
|
66
|
+
"vitest": "^0.34.4"
|
|
66
67
|
},
|
|
67
68
|
"typesVersions": {
|
|
68
69
|
"*": {
|
|
@@ -83,9 +84,9 @@
|
|
|
83
84
|
"scripts": {
|
|
84
85
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
|
85
86
|
"type-check": "tsc --noEmit",
|
|
86
|
-
"build": "vite build",
|
|
87
87
|
"dev": "vite build --watch",
|
|
88
|
-
"
|
|
88
|
+
"build": "vite build",
|
|
89
|
+
"test": "pnpm run build && pnpm run test-vitest && pnpm run test-playwright",
|
|
89
90
|
"test-vitest": "vitest run",
|
|
90
91
|
"test-vitest-watch": "vitest",
|
|
91
92
|
"test-playwright": "playwright test -c playwright-ct.config.ts",
|
package/src/VvForm.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type Component,
|
|
2
3
|
type InjectionKey,
|
|
3
4
|
type DeepReadonly,
|
|
4
5
|
type Ref,
|
|
6
|
+
type PropType,
|
|
5
7
|
withModifiers,
|
|
6
8
|
defineComponent,
|
|
7
9
|
ref,
|
|
@@ -18,6 +20,7 @@ import type { z, ZodFormattedError, TypeOf } from 'zod'
|
|
|
18
20
|
import type {
|
|
19
21
|
FormComponentOptions,
|
|
20
22
|
FormSchema,
|
|
23
|
+
FormTemplate,
|
|
21
24
|
InjectedFormData,
|
|
22
25
|
} from './types'
|
|
23
26
|
import { FormStatus } from './enums'
|
|
@@ -26,7 +29,8 @@ import { defaultObjectBySchema } from './utils'
|
|
|
26
29
|
export const defineForm = <Schema extends FormSchema>(
|
|
27
30
|
schema: Schema,
|
|
28
31
|
provideKey: InjectionKey<InjectedFormData<Schema>>,
|
|
29
|
-
options?: FormComponentOptions
|
|
32
|
+
options?: FormComponentOptions<Schema>,
|
|
33
|
+
VvFormTemplate?: Component,
|
|
30
34
|
) => {
|
|
31
35
|
const errors = ref<z.inferFormattedError<Schema> | undefined>()
|
|
32
36
|
const status = ref<FormStatus | undefined>()
|
|
@@ -46,6 +50,10 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
46
50
|
type: Boolean,
|
|
47
51
|
default: false,
|
|
48
52
|
},
|
|
53
|
+
template: {
|
|
54
|
+
type: [Array, Function] as PropType<FormTemplate<Schema>>,
|
|
55
|
+
default: undefined,
|
|
56
|
+
},
|
|
49
57
|
},
|
|
50
58
|
emits: ['invalid', 'valid', 'submit', 'update:modelValue'],
|
|
51
59
|
expose: ['submit', 'validate', 'errors', 'status', 'valid', 'invalid'],
|
|
@@ -89,6 +97,7 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
89
97
|
JSON.stringify(props.modelValue)
|
|
90
98
|
) {
|
|
91
99
|
emit('update:modelValue', newValue)
|
|
100
|
+
options?.onUpdate?.(toRaw(newValue))
|
|
92
101
|
}
|
|
93
102
|
},
|
|
94
103
|
{
|
|
@@ -107,13 +116,16 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
107
116
|
>
|
|
108
117
|
status.value = FormStatus.invalid
|
|
109
118
|
emit('invalid', errors.value)
|
|
119
|
+
options?.onInvalid?.(toRaw(errors.value))
|
|
110
120
|
return false
|
|
111
121
|
}
|
|
112
122
|
errors.value = undefined
|
|
113
123
|
status.value = FormStatus.valid
|
|
114
124
|
formData.value = parseResult.data
|
|
115
125
|
emit('update:modelValue', formData.value)
|
|
126
|
+
options?.onUpdate?.(toRaw(formData.value))
|
|
116
127
|
emit('valid', parseResult.data)
|
|
128
|
+
options?.onValid?.(toRaw(formData.value))
|
|
117
129
|
return true
|
|
118
130
|
}
|
|
119
131
|
|
|
@@ -122,7 +134,8 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
122
134
|
if (!validate()) {
|
|
123
135
|
return false
|
|
124
136
|
}
|
|
125
|
-
emit('submit', formData.value)
|
|
137
|
+
emit('submit', formData.value as z.infer<Schema>)
|
|
138
|
+
options?.onSubmit?.(toRaw(formData.value) as z.infer<Schema>)
|
|
126
139
|
return true
|
|
127
140
|
}
|
|
128
141
|
|
|
@@ -148,22 +161,35 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
148
161
|
}
|
|
149
162
|
},
|
|
150
163
|
render() {
|
|
164
|
+
const defaultSlot = () =>
|
|
165
|
+
this.$slots?.default?.({
|
|
166
|
+
formData: this.formData,
|
|
167
|
+
submit: this.submit,
|
|
168
|
+
validate: this.validate,
|
|
169
|
+
errors: this.errors,
|
|
170
|
+
status: this.status,
|
|
171
|
+
invalid: this.invalid,
|
|
172
|
+
}) ?? this.$slots.default
|
|
151
173
|
return h(
|
|
152
174
|
'form',
|
|
153
175
|
{
|
|
154
176
|
onSubmit: withModifiers(this.submit, ['prevent']),
|
|
155
177
|
},
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
178
|
+
(this.template ?? options?.template) && VvFormTemplate
|
|
179
|
+
? [
|
|
180
|
+
h(
|
|
181
|
+
VvFormTemplate,
|
|
182
|
+
{
|
|
183
|
+
schema: this.template ?? options?.template,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
default: defaultSlot,
|
|
187
|
+
},
|
|
188
|
+
),
|
|
189
|
+
]
|
|
190
|
+
: {
|
|
191
|
+
default: defaultSlot,
|
|
192
|
+
},
|
|
167
193
|
)
|
|
168
194
|
},
|
|
169
195
|
})
|
package/src/VvFormTemplate.ts
CHANGED
|
@@ -12,146 +12,141 @@ import {
|
|
|
12
12
|
unref,
|
|
13
13
|
} from 'vue'
|
|
14
14
|
import type { TypeOf, z } from 'zod'
|
|
15
|
-
import type { FormSchema, InjectedFormData,
|
|
15
|
+
import type { FormSchema, InjectedFormData, FormTemplate } from './types'
|
|
16
16
|
import type { FormStatus } from './enums'
|
|
17
17
|
|
|
18
18
|
export const defineFormTemplate = <Schema extends FormSchema>(
|
|
19
19
|
formProvideKey: InjectionKey<InjectedFormData<Schema>>,
|
|
20
20
|
VvFormField: Component,
|
|
21
21
|
) => {
|
|
22
|
-
const VvFormTemplate
|
|
22
|
+
const VvFormTemplate = defineComponent({
|
|
23
23
|
props: {
|
|
24
24
|
schema: {
|
|
25
|
-
type: [Array, Function] as PropType<
|
|
26
|
-
| FormTemplateItem<Schema>[]
|
|
27
|
-
| ((
|
|
28
|
-
data?: InjectedFormData<Schema>,
|
|
29
|
-
) => FormTemplateItem<Schema>[])
|
|
30
|
-
>,
|
|
25
|
+
type: [Array, Function] as PropType<FormTemplate<Schema>>,
|
|
31
26
|
required: true,
|
|
32
27
|
},
|
|
33
28
|
},
|
|
34
29
|
setup(templateProps, { slots: templateSlots }) {
|
|
35
30
|
const injectedFormData = inject(formProvideKey)
|
|
36
31
|
if (!injectedFormData?.formData) return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
normalizedSchema.reduce<
|
|
44
|
-
(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
return () => {
|
|
33
|
+
const normalizedSchema =
|
|
34
|
+
typeof templateProps.schema === 'function'
|
|
35
|
+
? templateProps.schema(injectedFormData)
|
|
36
|
+
: templateProps.schema
|
|
37
|
+
let lastIf: boolean | undefined = undefined
|
|
38
|
+
const toReturn = normalizedSchema.reduce<
|
|
39
|
+
(VNode | VNode[] | undefined)[]
|
|
40
|
+
>((acc, field) => {
|
|
41
|
+
const normalizedField =
|
|
42
|
+
typeof field === 'function'
|
|
43
|
+
? field(injectedFormData)
|
|
44
|
+
: field
|
|
45
|
+
const {
|
|
46
|
+
vvIs,
|
|
47
|
+
vvName,
|
|
48
|
+
vvSlots,
|
|
49
|
+
vvChildren,
|
|
50
|
+
vvIf,
|
|
51
|
+
vvElseIf,
|
|
52
|
+
vvType,
|
|
53
|
+
vvDefaultValue,
|
|
54
|
+
vvShowValid,
|
|
55
|
+
vvContent,
|
|
56
|
+
...props
|
|
57
|
+
} = normalizedField
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
),
|
|
70
|
-
)
|
|
71
|
-
} else if (typeof vvIf === 'function') {
|
|
72
|
-
lastIf = unref(vvIf(injectedFormData))
|
|
73
|
-
} else {
|
|
74
|
-
lastIf = unref(vvIf)
|
|
75
|
-
}
|
|
76
|
-
if (!lastIf) {
|
|
77
|
-
return acc
|
|
78
|
-
}
|
|
79
|
-
} else if (
|
|
80
|
-
vvElseIf !== undefined &&
|
|
81
|
-
lastIf !== undefined
|
|
82
|
-
) {
|
|
83
|
-
if (lastIf) {
|
|
84
|
-
return acc
|
|
85
|
-
}
|
|
86
|
-
if (typeof vvElseIf === 'string') {
|
|
87
|
-
lastIf = Boolean(
|
|
88
|
-
get(
|
|
89
|
-
Object(injectedFormData.formData.value),
|
|
90
|
-
vvElseIf,
|
|
91
|
-
),
|
|
92
|
-
)
|
|
93
|
-
} else if (typeof vvElseIf === 'function') {
|
|
94
|
-
lastIf = unref(vvElseIf(injectedFormData))
|
|
95
|
-
} else {
|
|
96
|
-
lastIf = unref(vvElseIf)
|
|
97
|
-
}
|
|
98
|
-
if (!lastIf) {
|
|
99
|
-
return acc
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
lastIf = undefined
|
|
103
|
-
}
|
|
104
|
-
// children
|
|
105
|
-
const hChildren = vvChildren
|
|
106
|
-
? h(VvFormTemplate, {
|
|
107
|
-
schema: vvChildren,
|
|
108
|
-
})
|
|
109
|
-
: undefined
|
|
110
|
-
// render
|
|
111
|
-
if (vvName) {
|
|
112
|
-
acc.push(
|
|
113
|
-
h(
|
|
114
|
-
VvFormField,
|
|
115
|
-
{
|
|
116
|
-
name: vvName,
|
|
117
|
-
is: vvIs,
|
|
118
|
-
type: vvType,
|
|
119
|
-
defaultValue: vvDefaultValue,
|
|
120
|
-
showValid: vvShowValid,
|
|
121
|
-
props,
|
|
122
|
-
},
|
|
123
|
-
vvSlots ?? hChildren,
|
|
59
|
+
// conditions
|
|
60
|
+
if (vvIf !== undefined) {
|
|
61
|
+
if (typeof vvIf === 'string') {
|
|
62
|
+
lastIf = Boolean(
|
|
63
|
+
get(
|
|
64
|
+
Object(injectedFormData.formData.value),
|
|
65
|
+
vvIf,
|
|
124
66
|
),
|
|
125
67
|
)
|
|
68
|
+
} else if (typeof vvIf === 'function') {
|
|
69
|
+
lastIf = unref(vvIf(injectedFormData))
|
|
70
|
+
} else {
|
|
71
|
+
lastIf = unref(vvIf)
|
|
72
|
+
}
|
|
73
|
+
if (!lastIf) {
|
|
126
74
|
return acc
|
|
127
75
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
76
|
+
} else if (vvElseIf !== undefined && lastIf !== undefined) {
|
|
77
|
+
if (lastIf) {
|
|
78
|
+
return acc
|
|
79
|
+
}
|
|
80
|
+
if (typeof vvElseIf === 'string') {
|
|
81
|
+
lastIf = Boolean(
|
|
82
|
+
get(
|
|
83
|
+
Object(injectedFormData.formData.value),
|
|
84
|
+
vvElseIf,
|
|
134
85
|
),
|
|
135
86
|
)
|
|
136
|
-
|
|
87
|
+
} else if (typeof vvElseIf === 'function') {
|
|
88
|
+
lastIf = unref(vvElseIf(injectedFormData))
|
|
89
|
+
} else {
|
|
90
|
+
lastIf = unref(vvElseIf)
|
|
137
91
|
}
|
|
138
|
-
if (
|
|
139
|
-
acc.push(hChildren)
|
|
92
|
+
if (!lastIf) {
|
|
140
93
|
return acc
|
|
141
94
|
}
|
|
95
|
+
} else {
|
|
96
|
+
lastIf = undefined
|
|
97
|
+
}
|
|
98
|
+
// children
|
|
99
|
+
const hChildren = vvChildren
|
|
100
|
+
? h(VvFormTemplate, {
|
|
101
|
+
schema: vvChildren,
|
|
102
|
+
})
|
|
103
|
+
: undefined
|
|
104
|
+
// render
|
|
105
|
+
if (vvName) {
|
|
106
|
+
acc.push(
|
|
107
|
+
h(
|
|
108
|
+
VvFormField,
|
|
109
|
+
{
|
|
110
|
+
name: vvName,
|
|
111
|
+
is: vvIs,
|
|
112
|
+
type: vvType,
|
|
113
|
+
defaultValue: vvDefaultValue,
|
|
114
|
+
showValid: vvShowValid,
|
|
115
|
+
props,
|
|
116
|
+
},
|
|
117
|
+
vvSlots ?? hChildren ?? vvContent,
|
|
118
|
+
),
|
|
119
|
+
)
|
|
142
120
|
return acc
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
121
|
+
}
|
|
122
|
+
if (vvIs) {
|
|
123
|
+
acc.push(
|
|
124
|
+
h(
|
|
125
|
+
vvIs as Component,
|
|
126
|
+
props,
|
|
127
|
+
vvSlots ?? hChildren ?? vvContent,
|
|
128
|
+
),
|
|
129
|
+
)
|
|
130
|
+
return acc
|
|
131
|
+
}
|
|
132
|
+
if (vvChildren) {
|
|
133
|
+
acc.push(hChildren)
|
|
134
|
+
return acc
|
|
135
|
+
}
|
|
136
|
+
return acc
|
|
137
|
+
}, [])
|
|
138
|
+
toReturn.push(
|
|
139
|
+
templateSlots?.default?.({
|
|
140
|
+
formData: injectedFormData?.formData.value,
|
|
141
|
+
submit: injectedFormData?.submit,
|
|
142
|
+
validate: injectedFormData?.validate,
|
|
143
|
+
errors: injectedFormData?.errors.value,
|
|
144
|
+
status: injectedFormData?.status.value,
|
|
145
|
+
invalid: injectedFormData?.invalid.value,
|
|
146
|
+
}),
|
|
154
147
|
)
|
|
148
|
+
return toReturn
|
|
149
|
+
}
|
|
155
150
|
},
|
|
156
151
|
})
|
|
157
152
|
|
package/src/index.ts
CHANGED
|
@@ -19,11 +19,13 @@ import type {
|
|
|
19
19
|
Path,
|
|
20
20
|
PathValue,
|
|
21
21
|
FormSchema,
|
|
22
|
+
FormTemplate,
|
|
22
23
|
} from './types'
|
|
24
|
+
import type { AnyZodObject } from 'zod'
|
|
23
25
|
|
|
24
26
|
const _formFactory = <Schema extends FormSchema>(
|
|
25
27
|
schema: Schema,
|
|
26
|
-
options: FormComposableOptions = {},
|
|
28
|
+
options: FormComposableOptions<Schema> = {},
|
|
27
29
|
) => {
|
|
28
30
|
// create injection keys
|
|
29
31
|
const formInjectionKey = Symbol() as InjectionKey<InjectedFormData<Schema>>
|
|
@@ -35,11 +37,6 @@ const _formFactory = <Schema extends FormSchema>(
|
|
|
35
37
|
>
|
|
36
38
|
|
|
37
39
|
// create components
|
|
38
|
-
const { VvForm, errors, status, formData } = defineForm(
|
|
39
|
-
schema,
|
|
40
|
-
formInjectionKey,
|
|
41
|
-
options,
|
|
42
|
-
)
|
|
43
40
|
const VvFormWrapper = defineFormWrapper(
|
|
44
41
|
formInjectionKey,
|
|
45
42
|
formWrapperInjectionKey,
|
|
@@ -51,6 +48,12 @@ const _formFactory = <Schema extends FormSchema>(
|
|
|
51
48
|
options,
|
|
52
49
|
)
|
|
53
50
|
const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField)
|
|
51
|
+
const { VvForm, errors, status, formData } = defineForm(
|
|
52
|
+
schema,
|
|
53
|
+
formInjectionKey,
|
|
54
|
+
options,
|
|
55
|
+
VvFormTemplate,
|
|
56
|
+
)
|
|
54
57
|
|
|
55
58
|
return {
|
|
56
59
|
VvForm,
|
|
@@ -73,7 +76,7 @@ export const createForm = (
|
|
|
73
76
|
): Plugin & Partial<ReturnType<typeof useForm>> => {
|
|
74
77
|
let toReturn: Partial<ReturnType<typeof useForm>> = {}
|
|
75
78
|
if (options.schema) {
|
|
76
|
-
toReturn = _formFactory(options.schema, options)
|
|
79
|
+
toReturn = _formFactory(options.schema as AnyZodObject, options)
|
|
77
80
|
}
|
|
78
81
|
return {
|
|
79
82
|
...toReturn,
|
|
@@ -102,15 +105,18 @@ export const createForm = (
|
|
|
102
105
|
|
|
103
106
|
export const useForm = <Schema extends FormSchema>(
|
|
104
107
|
schema: Schema,
|
|
105
|
-
options: FormComposableOptions = {},
|
|
108
|
+
options: FormComposableOptions<Schema> = {},
|
|
106
109
|
) => {
|
|
107
110
|
if (!getCurrentInstance()) {
|
|
108
111
|
return _formFactory(schema, options)
|
|
109
112
|
}
|
|
110
|
-
return _formFactory(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
return _formFactory(
|
|
114
|
+
schema as AnyZodObject,
|
|
115
|
+
{
|
|
116
|
+
...inject(pluginInjectionKey, {}),
|
|
117
|
+
...options,
|
|
118
|
+
} as FormComposableOptions<AnyZodObject>,
|
|
119
|
+
)
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
export { FormFieldType } from './enums'
|
|
@@ -126,10 +132,12 @@ export type {
|
|
|
126
132
|
InjectedFormWrapperData,
|
|
127
133
|
InjectedFormFieldData,
|
|
128
134
|
FormComposableOptions,
|
|
135
|
+
FormSchema,
|
|
129
136
|
FormPluginOptions,
|
|
130
137
|
FormComponent,
|
|
131
138
|
FormWrapperComponent,
|
|
132
139
|
FormFieldComponent,
|
|
140
|
+
FormTemplate,
|
|
133
141
|
FormTemplateComponent,
|
|
134
142
|
FormTemplateItem,
|
|
135
143
|
Path,
|
|
@@ -141,7 +149,7 @@ export type {
|
|
|
141
149
|
*/
|
|
142
150
|
export const formFactory = <Schema extends FormSchema>(
|
|
143
151
|
schema: Schema,
|
|
144
|
-
options: FormComposableOptions = {},
|
|
152
|
+
options: FormComposableOptions<Schema> = {},
|
|
145
153
|
) => {
|
|
146
154
|
return _formFactory(schema, options)
|
|
147
155
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { z, AnyZodObject, ZodEffects } from 'zod'
|
|
1
|
+
import { type Component, type DeepReadonly, type Ref } from 'vue'
|
|
2
|
+
import type { z, AnyZodObject, ZodEffects, inferFormattedError } from 'zod'
|
|
3
3
|
import type { FormFieldType, FormStatus } from './enums'
|
|
4
4
|
|
|
5
5
|
export type FormSchema =
|
|
@@ -12,17 +12,33 @@ export type FormFieldComponentOptions = {
|
|
|
12
12
|
sideEffects?: (type: `${FormFieldType}`) => Promise<void> | void
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export type FormComponentOptions = {
|
|
15
|
+
export type FormComponentOptions<Schema> = {
|
|
16
16
|
updateThrottle?: number
|
|
17
17
|
continuosValidation?: boolean
|
|
18
|
+
template?: Schema extends FormSchema ? FormTemplate<Schema> : never
|
|
19
|
+
onUpdate?: Schema extends FormSchema
|
|
20
|
+
? (data: Partial<z.infer<Schema> | undefined>) => void
|
|
21
|
+
: never
|
|
22
|
+
onSubmit?: Schema extends FormSchema
|
|
23
|
+
? (data: z.infer<Schema>) => void
|
|
24
|
+
: never
|
|
25
|
+
onInvalid?: Schema extends FormSchema
|
|
26
|
+
? (error: inferFormattedError<Schema, string>) => void
|
|
27
|
+
: never
|
|
28
|
+
onValid?: Schema extends FormSchema
|
|
29
|
+
? (data: z.infer<Schema>) => void
|
|
30
|
+
: never
|
|
18
31
|
}
|
|
19
32
|
|
|
20
|
-
export type FormComposableOptions = FormFieldComponentOptions &
|
|
21
|
-
FormComponentOptions
|
|
33
|
+
export type FormComposableOptions<Schema> = FormFieldComponentOptions &
|
|
34
|
+
FormComponentOptions<Schema>
|
|
22
35
|
|
|
23
|
-
|
|
36
|
+
type FormPluginOptionsSchema = {
|
|
24
37
|
schema?: FormSchema
|
|
25
|
-
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type FormPluginOptions = FormPluginOptionsSchema &
|
|
41
|
+
FormComposableOptions<FormPluginOptionsSchema['schema']>
|
|
26
42
|
|
|
27
43
|
export type InjectedFormData<Schema extends FormSchema> = {
|
|
28
44
|
formData: Ref<Partial<z.infer<Schema>> | undefined>
|
|
@@ -125,6 +141,7 @@ export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<
|
|
|
125
141
|
vvElseIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>
|
|
126
142
|
vvType?: `${FormFieldType}`
|
|
127
143
|
vvShowValid?: boolean
|
|
144
|
+
vvContent?: string
|
|
128
145
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
129
146
|
vvDefaultValue?: any
|
|
130
147
|
}
|
|
@@ -132,3 +149,7 @@ export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<
|
|
|
132
149
|
export type FormTemplateItem<Schema extends FormSchema> =
|
|
133
150
|
| SimpleFormTemplateItem<Schema>
|
|
134
151
|
| ((data?: InjectedFormData<Schema>) => SimpleFormTemplateItem<Schema>)
|
|
152
|
+
|
|
153
|
+
export type FormTemplate<Schema extends FormSchema> =
|
|
154
|
+
| FormTemplateItem<Schema>[]
|
|
155
|
+
| ((data?: InjectedFormData<Schema>) => FormTemplateItem<Schema>[])
|