@tanstack/solid-form 0.10.3 → 0.12.0
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/cjs/createField.d.ts +27 -0
- package/dist/cjs/createForm.d.ts +21 -0
- package/dist/cjs/createFormFactory.d.ts +8 -0
- package/dist/cjs/formContext.d.ts +11 -0
- package/{build → dist/cjs}/index.cjs +17 -23
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +7 -0
- package/dist/cjs/index.d.ts +7 -0
- package/{build/dev.cjs → dist/cjs/index.js} +17 -23
- package/dist/cjs/tests/createField.test-d.d.ts +2 -0
- package/dist/cjs/tests/createField.test.d.ts +1 -0
- package/dist/cjs/tests/createForm.test.d.ts +1 -0
- package/dist/cjs/tests/createFormFactory.test.d.ts +1 -0
- package/dist/cjs/tests/utils.d.ts +1 -0
- package/dist/cjs/types.d.ts +4 -0
- package/dist/mjs/createField.d.ts +27 -0
- package/dist/mjs/createForm.d.ts +21 -0
- package/dist/mjs/createFormFactory.d.ts +8 -0
- package/dist/mjs/formContext.d.ts +11 -0
- package/dist/mjs/index.d.mts +7 -0
- package/dist/mjs/index.d.ts +7 -0
- package/{build → dist/mjs}/index.js +19 -17
- package/{build/dev.js → dist/mjs/index.mjs} +19 -17
- package/dist/mjs/index.mjs.map +1 -0
- package/dist/mjs/tests/createField.test-d.d.ts +2 -0
- package/dist/mjs/tests/createField.test.d.ts +1 -0
- package/dist/mjs/tests/createForm.test.d.ts +1 -0
- package/dist/mjs/tests/createFormFactory.test.d.ts +1 -0
- package/dist/mjs/tests/utils.d.ts +1 -0
- package/dist/mjs/types.d.ts +4 -0
- package/package.json +19 -32
- package/src/createField.tsx +62 -43
- package/src/createForm.tsx +18 -11
- package/src/createFormFactory.ts +15 -9
- package/src/formContext.ts +2 -2
- package/src/tests/createField.test-d.tsx +15 -8
- package/src/tests/createField.test.tsx +45 -34
- package/src/tests/createForm.test.tsx +54 -39
- package/src/tests/createFormFactory.test.tsx +2 -1
- package/src/types.ts +13 -4
- package/build/index.d.cts +0 -56
- package/build/index.d.ts +0 -56
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tanstack/solid-form",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.12.0",
|
4
4
|
"description": "Powerful, type-safe forms for Solid.",
|
5
5
|
"author": "tannerlinsley",
|
6
6
|
"license": "MIT",
|
@@ -12,61 +12,48 @@
|
|
12
12
|
},
|
13
13
|
"sideEffects": false,
|
14
14
|
"files": [
|
15
|
-
"
|
15
|
+
"dist",
|
16
16
|
"src"
|
17
17
|
],
|
18
18
|
"type": "module",
|
19
|
-
"
|
20
|
-
"
|
21
|
-
"
|
19
|
+
"types": "dist/mjs/index.d.mts",
|
20
|
+
"main": "dist/cjs/index.cjs",
|
21
|
+
"module": "dist/mjs/index.mjs",
|
22
22
|
"exports": {
|
23
|
-
"
|
23
|
+
".": {
|
24
24
|
"import": {
|
25
|
-
"types": "./
|
26
|
-
"default": "./
|
25
|
+
"types": "./dist/mjs/index.d.mts",
|
26
|
+
"default": "./dist/mjs/index.mjs"
|
27
27
|
},
|
28
28
|
"require": {
|
29
|
-
"types": "./
|
30
|
-
"default": "./
|
29
|
+
"types": "./dist/cjs/index.d.cts",
|
30
|
+
"default": "./dist/cjs/index.cjs"
|
31
31
|
}
|
32
32
|
},
|
33
|
-
"
|
34
|
-
"types": "./build/index.d.ts",
|
35
|
-
"default": "./build/index.js"
|
36
|
-
},
|
37
|
-
"require": {
|
38
|
-
"types": "./build/index.d.cts",
|
39
|
-
"default": "./build/index.cjs"
|
40
|
-
}
|
41
|
-
},
|
42
|
-
"nx": {
|
43
|
-
"targets": {
|
44
|
-
"test:build": {
|
45
|
-
"dependsOn": [
|
46
|
-
"build"
|
47
|
-
]
|
48
|
-
}
|
49
|
-
}
|
33
|
+
"./package.json": "./package.json"
|
50
34
|
},
|
51
35
|
"devDependencies": {
|
52
36
|
"solid-js": "^1.7.8",
|
53
|
-
"tsup-preset-solid": "^2.1.0",
|
54
37
|
"vite-plugin-solid": "^2.7.0"
|
55
38
|
},
|
56
39
|
"dependencies": {
|
57
40
|
"@tanstack/solid-store": "^0.2.1",
|
58
|
-
"@tanstack/form-core": "0.
|
41
|
+
"@tanstack/form-core": "0.12.0"
|
59
42
|
},
|
60
43
|
"peerDependencies": {
|
61
44
|
"solid-js": "^1.6.0"
|
62
45
|
},
|
63
46
|
"scripts": {
|
64
|
-
"clean": "rimraf ./
|
47
|
+
"clean": "rimraf ./dist && rimraf ./coverage",
|
65
48
|
"test:eslint": "eslint --ext .ts,.tsx ./src",
|
66
|
-
"test:types": "tsc --noEmit",
|
49
|
+
"test:types:versions49": "../../node_modules/typescript49/bin/tsc --noEmit",
|
50
|
+
"test:types:versions50": "../../node_modules/typescript50/bin/tsc --noEmit",
|
51
|
+
"test:types:versions51": "../../node_modules/typescript51/bin/tsc --noEmit",
|
52
|
+
"test:types:versions52": "tsc --noEmit",
|
53
|
+
"test:types": "pnpm run \"/^test:types:versions.*/\"",
|
67
54
|
"test:lib": "vitest run --coverage",
|
68
55
|
"test:lib:dev": "pnpm run test:lib --watch",
|
69
56
|
"test:build": "publint --strict",
|
70
|
-
"build": "
|
57
|
+
"build": "vite build"
|
71
58
|
}
|
72
59
|
}
|
package/src/createField.tsx
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { FieldApi } from '@tanstack/form-core'
|
1
|
+
import { FieldApi, type Validator } from '@tanstack/form-core'
|
2
2
|
import {
|
3
3
|
createComponent,
|
4
4
|
createComputed,
|
@@ -18,30 +18,38 @@ declare module '@tanstack/form-core' {
|
|
18
18
|
interface FieldApi<
|
19
19
|
TParentData,
|
20
20
|
TName extends DeepKeys<TParentData>,
|
21
|
-
|
22
|
-
|
21
|
+
TFieldValidator extends
|
22
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
23
|
+
| undefined = undefined,
|
24
|
+
TFormValidator extends
|
25
|
+
| Validator<TParentData, unknown>
|
26
|
+
| undefined = undefined,
|
23
27
|
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
24
28
|
> {
|
25
|
-
Field: FieldComponent<
|
29
|
+
Field: FieldComponent<TParentData, TFormValidator>
|
26
30
|
}
|
27
31
|
}
|
28
32
|
|
29
33
|
export type CreateField<TParentData> = <
|
30
34
|
TName extends DeepKeys<TParentData>,
|
31
|
-
|
32
|
-
|
35
|
+
TFieldValidator extends
|
36
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
37
|
+
| undefined = undefined,
|
38
|
+
TFormValidator extends
|
39
|
+
| Validator<TParentData, unknown>
|
40
|
+
| undefined = undefined,
|
33
41
|
>(
|
34
42
|
opts: () => { name: Narrow<TName> } & CreateFieldOptions<
|
35
43
|
TParentData,
|
36
44
|
TName,
|
37
|
-
|
38
|
-
|
45
|
+
TFieldValidator,
|
46
|
+
TFormValidator
|
39
47
|
>,
|
40
48
|
) => () => FieldApi<
|
41
49
|
TParentData,
|
42
50
|
TName,
|
43
|
-
|
44
|
-
|
51
|
+
TFieldValidator,
|
52
|
+
TFormValidator,
|
45
53
|
DeepValue<TParentData, TName>
|
46
54
|
>
|
47
55
|
|
@@ -59,24 +67,20 @@ function makeFieldReactive<FieldApiT extends FieldApi<any, any, any, any>>(
|
|
59
67
|
export function createField<
|
60
68
|
TParentData,
|
61
69
|
TName extends DeepKeys<TParentData>,
|
62
|
-
|
63
|
-
|
70
|
+
TFieldValidator extends
|
71
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
72
|
+
| undefined = undefined,
|
73
|
+
TFormValidator extends
|
74
|
+
| Validator<TParentData, unknown>
|
75
|
+
| undefined = undefined,
|
64
76
|
>(
|
65
77
|
opts: () => CreateFieldOptions<
|
66
78
|
TParentData,
|
67
79
|
TName,
|
68
|
-
|
69
|
-
|
80
|
+
TFieldValidator,
|
81
|
+
TFormValidator
|
70
82
|
>,
|
71
|
-
): () => FieldApi<
|
72
|
-
TParentData,
|
73
|
-
TName,
|
74
|
-
ValidatorType,
|
75
|
-
FormValidator
|
76
|
-
// Omit<typeof opts, 'onMount'> & {
|
77
|
-
// form: FormApi<TParentData>
|
78
|
-
// }
|
79
|
-
> {
|
83
|
+
): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {
|
80
84
|
// Get the form API either manually or from context
|
81
85
|
const { formApi, parentFieldName } = useFormContext()
|
82
86
|
|
@@ -92,7 +96,7 @@ export function createField<
|
|
92
96
|
const fieldApi = new FieldApi({
|
93
97
|
...options,
|
94
98
|
form: formApi,
|
95
|
-
name: name as typeof options.name,
|
99
|
+
name: name as typeof options.name as never,
|
96
100
|
})
|
97
101
|
fieldApi.Field = Field as never
|
98
102
|
|
@@ -102,27 +106,31 @@ export function createField<
|
|
102
106
|
*
|
103
107
|
* createComputed to make sure this effect runs before render effects
|
104
108
|
*/
|
105
|
-
createComputed(() => fieldApi.update({ ...opts(), form: formApi }))
|
109
|
+
createComputed(() => fieldApi.update({ ...opts(), form: formApi } as never))
|
106
110
|
|
107
111
|
// Instantiates field meta and removes it when unrendered
|
108
112
|
onMount(() => onCleanup(fieldApi.mount()))
|
109
113
|
|
110
|
-
return makeFieldReactive(fieldApi)
|
114
|
+
return makeFieldReactive(fieldApi) as never
|
111
115
|
}
|
112
116
|
|
113
117
|
type FieldComponentProps<
|
114
118
|
TParentData,
|
115
119
|
TName extends DeepKeys<TParentData>,
|
116
|
-
|
117
|
-
|
120
|
+
TFieldValidator extends
|
121
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
122
|
+
| undefined = undefined,
|
123
|
+
TFormValidator extends
|
124
|
+
| Validator<TParentData, unknown>
|
125
|
+
| undefined = undefined,
|
118
126
|
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
119
127
|
> = {
|
120
128
|
children: (
|
121
129
|
fieldApi: () => FieldApi<
|
122
130
|
TParentData,
|
123
131
|
TName,
|
124
|
-
|
125
|
-
|
132
|
+
TFieldValidator,
|
133
|
+
TFormValidator,
|
126
134
|
TData
|
127
135
|
>,
|
128
136
|
) => JSXElement
|
@@ -136,13 +144,20 @@ type FieldComponentProps<
|
|
136
144
|
index?: never
|
137
145
|
}) &
|
138
146
|
Omit<
|
139
|
-
CreateFieldOptions<TParentData, TName,
|
147
|
+
CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
|
140
148
|
'name' | 'index'
|
141
149
|
>
|
142
150
|
|
143
|
-
export type FieldComponent<
|
151
|
+
export type FieldComponent<
|
152
|
+
TParentData,
|
153
|
+
TFormValidator extends
|
154
|
+
| Validator<TParentData, unknown>
|
155
|
+
| undefined = undefined,
|
156
|
+
> = <
|
144
157
|
TName extends DeepKeys<TParentData>,
|
145
|
-
|
158
|
+
TFieldValidator extends
|
159
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
160
|
+
| undefined = undefined,
|
146
161
|
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
147
162
|
>({
|
148
163
|
children,
|
@@ -150,33 +165,37 @@ export type FieldComponent<TParentData, FormValidator> = <
|
|
150
165
|
}: FieldComponentProps<
|
151
166
|
TParentData,
|
152
167
|
TName,
|
153
|
-
|
154
|
-
|
168
|
+
TFieldValidator,
|
169
|
+
TFormValidator,
|
155
170
|
TData
|
156
171
|
>) => JSXElement
|
157
172
|
|
158
173
|
export function Field<
|
159
174
|
TParentData,
|
160
175
|
TName extends DeepKeys<TParentData>,
|
161
|
-
|
162
|
-
|
176
|
+
TFieldValidator extends
|
177
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
178
|
+
| undefined = undefined,
|
179
|
+
TFormValidator extends
|
180
|
+
| Validator<TParentData, unknown>
|
181
|
+
| undefined = undefined,
|
163
182
|
>(
|
164
183
|
props: {
|
165
184
|
children: (
|
166
185
|
fieldApi: () => FieldApi<
|
167
186
|
TParentData,
|
168
187
|
TName,
|
169
|
-
|
170
|
-
|
188
|
+
TFieldValidator,
|
189
|
+
TFormValidator
|
171
190
|
>,
|
172
191
|
) => JSXElement
|
173
|
-
} & CreateFieldOptions<TParentData, TName,
|
192
|
+
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
|
174
193
|
) {
|
175
194
|
const fieldApi = createField<
|
176
195
|
TParentData,
|
177
196
|
TName,
|
178
|
-
|
179
|
-
|
197
|
+
TFieldValidator,
|
198
|
+
TFormValidator
|
180
199
|
>(() => {
|
181
200
|
const { children, ...fieldOptions } = props
|
182
201
|
return fieldOptions
|
@@ -185,7 +204,7 @@ export function Field<
|
|
185
204
|
return (
|
186
205
|
<formContext.Provider
|
187
206
|
value={{
|
188
|
-
formApi: fieldApi().form,
|
207
|
+
formApi: fieldApi().form as never,
|
189
208
|
parentFieldName: String(fieldApi().name),
|
190
209
|
}}
|
191
210
|
>
|
package/src/createForm.tsx
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { FormOptions, FormState } from '@tanstack/form-core'
|
1
|
+
import type { FormOptions, FormState, Validator } from '@tanstack/form-core'
|
2
2
|
import { FormApi, functionalUpdate } from '@tanstack/form-core'
|
3
3
|
import { createComputed, onMount, type JSXElement } from 'solid-js'
|
4
4
|
import { useStore } from '@tanstack/solid-store'
|
@@ -14,9 +14,9 @@ type NoInfer<T> = [T][T extends any ? 0 : never]
|
|
14
14
|
|
15
15
|
declare module '@tanstack/form-core' {
|
16
16
|
// eslint-disable-next-line no-shadow
|
17
|
-
interface FormApi<TFormData,
|
18
|
-
Provider: (props: { children: any }) =>
|
19
|
-
Field: FieldComponent<TFormData,
|
17
|
+
interface FormApi<TFormData, TFormValidator> {
|
18
|
+
Provider: (props: { children: any }) => JSXElement
|
19
|
+
Field: FieldComponent<TFormData, TFormValidator>
|
20
20
|
createField: CreateField<TFormData>
|
21
21
|
useStore: <TSelected = NoInfer<FormState<TFormData>>>(
|
22
22
|
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
|
@@ -24,22 +24,29 @@ declare module '@tanstack/form-core' {
|
|
24
24
|
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
25
25
|
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
|
26
26
|
children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement
|
27
|
-
}) =>
|
27
|
+
}) => JSXElement
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
|
-
export function createForm<
|
32
|
-
|
33
|
-
|
31
|
+
export function createForm<
|
32
|
+
TParentData,
|
33
|
+
TFormValidator extends
|
34
|
+
| Validator<TParentData, unknown>
|
35
|
+
| undefined = undefined,
|
36
|
+
>(
|
37
|
+
opts?: () => FormOptions<TParentData, TFormValidator>,
|
38
|
+
): FormApi<TParentData, TFormValidator> {
|
34
39
|
const options = opts?.()
|
35
|
-
const formApi = new FormApi<
|
40
|
+
const formApi = new FormApi<TParentData, TFormValidator>(options)
|
36
41
|
|
37
42
|
formApi.Provider = function Provider(props) {
|
38
43
|
onMount(formApi.mount)
|
39
|
-
return
|
44
|
+
return (
|
45
|
+
<formContext.Provider {...props} value={{ formApi: formApi as never }} />
|
46
|
+
)
|
40
47
|
}
|
41
48
|
formApi.Field = Field as any
|
42
|
-
formApi.createField = createField as CreateField<
|
49
|
+
formApi.createField = createField as CreateField<TParentData>
|
43
50
|
formApi.useStore = (selector) => useStore(formApi.store, selector)
|
44
51
|
formApi.Subscribe = (props) =>
|
45
52
|
functionalUpdate(props.children, useStore(formApi.store, props.selector))
|
package/src/createFormFactory.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { FormApi, FormOptions } from '@tanstack/form-core'
|
1
|
+
import type { FormApi, FormOptions, Validator } from '@tanstack/form-core'
|
2
2
|
|
3
3
|
import {
|
4
4
|
type CreateField,
|
@@ -9,20 +9,26 @@ import {
|
|
9
9
|
import { createForm } from './createForm'
|
10
10
|
import { mergeProps } from 'solid-js'
|
11
11
|
|
12
|
-
export type FormFactory<
|
12
|
+
export type FormFactory<
|
13
|
+
TFormData,
|
14
|
+
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
15
|
+
> = {
|
13
16
|
createForm: (
|
14
|
-
opts?: () => FormOptions<TFormData,
|
15
|
-
) => FormApi<TFormData,
|
17
|
+
opts?: () => FormOptions<TFormData, TFormValidator>,
|
18
|
+
) => FormApi<TFormData, TFormValidator>
|
16
19
|
createField: CreateField<TFormData>
|
17
|
-
Field: FieldComponent<TFormData,
|
20
|
+
Field: FieldComponent<TFormData, TFormValidator>
|
18
21
|
}
|
19
22
|
|
20
|
-
export function createFormFactory<
|
21
|
-
|
22
|
-
|
23
|
+
export function createFormFactory<
|
24
|
+
TFormData,
|
25
|
+
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
26
|
+
>(
|
27
|
+
defaultOpts?: () => FormOptions<TFormData, TFormValidator>,
|
28
|
+
): FormFactory<TFormData, TFormValidator> {
|
23
29
|
return {
|
24
30
|
createForm: (opts) =>
|
25
|
-
createForm<TFormData,
|
31
|
+
createForm<TFormData, TFormValidator>(() =>
|
26
32
|
mergeProps(defaultOpts?.() ?? {}, opts?.() ?? {}),
|
27
33
|
),
|
28
34
|
createField,
|
package/src/formContext.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import { createContext, useContext } from 'solid-js'
|
2
|
-
import type { FormApi } from '@tanstack/form-core'
|
2
|
+
import type { FormApi, Validator } from '@tanstack/form-core'
|
3
3
|
|
4
4
|
type FormContextType =
|
5
5
|
| undefined
|
6
6
|
| {
|
7
|
-
formApi: FormApi<any, any>
|
7
|
+
formApi: FormApi<any, Validator<any, unknown> | undefined>
|
8
8
|
parentFieldName?: string
|
9
9
|
}
|
10
10
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/// <reference lib="dom" />
|
1
2
|
import { assertType } from 'vitest'
|
2
3
|
import { createForm } from '../createForm'
|
3
4
|
|
@@ -19,12 +20,14 @@ it('should type state.value properly', () => {
|
|
19
20
|
name="firstName"
|
20
21
|
children={(field) => {
|
21
22
|
assertType<'test'>(field().state.value)
|
23
|
+
return null
|
22
24
|
}}
|
23
25
|
/>
|
24
26
|
<form.Field
|
25
27
|
name="age"
|
26
28
|
children={(field) => {
|
27
29
|
assertType<84>(field().state.value)
|
30
|
+
return null
|
28
31
|
}}
|
29
32
|
/>
|
30
33
|
</form.Provider>
|
@@ -48,19 +51,23 @@ it('should type onChange properly', () => {
|
|
48
51
|
<form.Provider>
|
49
52
|
<form.Field
|
50
53
|
name="firstName"
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
+
validators={{
|
55
|
+
onChange: ({ value }) => {
|
56
|
+
assertType<'test'>(value)
|
57
|
+
return null
|
58
|
+
},
|
54
59
|
}}
|
55
|
-
children={(
|
60
|
+
children={() => null}
|
56
61
|
/>
|
57
62
|
<form.Field
|
58
63
|
name="age"
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
validators={{
|
65
|
+
onChange: ({ value }) => {
|
66
|
+
assertType<84>(value)
|
67
|
+
return null
|
68
|
+
},
|
62
69
|
}}
|
63
|
-
children={(
|
70
|
+
children={() => null}
|
64
71
|
/>
|
65
72
|
</form.Provider>
|
66
73
|
)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/// <reference lib="dom" />
|
1
2
|
import { render, waitFor } from '@solidjs/testing-library'
|
2
3
|
import userEvent from '@testing-library/user-event'
|
3
4
|
import '@testing-library/jest-dom'
|
@@ -13,7 +14,7 @@ describe('createField', () => {
|
|
13
14
|
lastName: string
|
14
15
|
}
|
15
16
|
|
16
|
-
const formFactory = createFormFactory<Person
|
17
|
+
const formFactory = createFormFactory<Person>()
|
17
18
|
|
18
19
|
function Comp() {
|
19
20
|
const form = formFactory.createForm()
|
@@ -49,7 +50,7 @@ describe('createField', () => {
|
|
49
50
|
lastName: string
|
50
51
|
}
|
51
52
|
|
52
|
-
const formFactory = createFormFactory<Person
|
53
|
+
const formFactory = createFormFactory<Person>()
|
53
54
|
|
54
55
|
function Comp() {
|
55
56
|
const form = formFactory.createForm(() => ({
|
@@ -79,7 +80,7 @@ describe('createField', () => {
|
|
79
80
|
)
|
80
81
|
}
|
81
82
|
|
82
|
-
const { getByTestId } = render(<Comp />)
|
83
|
+
const { getByTestId } = render(() => <Comp />)
|
83
84
|
const input = getByTestId('fieldinput')
|
84
85
|
expect(input).toHaveValue('otherName')
|
85
86
|
})
|
@@ -91,7 +92,7 @@ describe('createField', () => {
|
|
91
92
|
}
|
92
93
|
const error = 'Please enter a different value'
|
93
94
|
|
94
|
-
const formFactory = createFormFactory<Person
|
95
|
+
const formFactory = createFormFactory<Person>()
|
95
96
|
|
96
97
|
function Comp() {
|
97
98
|
const form = formFactory.createForm()
|
@@ -100,7 +101,10 @@ describe('createField', () => {
|
|
100
101
|
<form.Provider>
|
101
102
|
<form.Field
|
102
103
|
name="firstName"
|
103
|
-
|
104
|
+
validators={{
|
105
|
+
onChange: ({ value }) =>
|
106
|
+
value.includes('other') ? error : undefined,
|
107
|
+
}}
|
104
108
|
children={(field) => (
|
105
109
|
<div>
|
106
110
|
<input
|
@@ -131,7 +135,7 @@ describe('createField', () => {
|
|
131
135
|
}
|
132
136
|
const error = 'Please enter a different value'
|
133
137
|
|
134
|
-
const formFactory = createFormFactory<Person
|
138
|
+
const formFactory = createFormFactory<Person>()
|
135
139
|
|
136
140
|
function Comp() {
|
137
141
|
const form = formFactory.createForm()
|
@@ -141,7 +145,10 @@ describe('createField', () => {
|
|
141
145
|
<form.Field
|
142
146
|
name="firstName"
|
143
147
|
defaultMeta={{ isTouched: true }}
|
144
|
-
|
148
|
+
validators={{
|
149
|
+
onChange: ({ value }) =>
|
150
|
+
value.includes('other') ? error : undefined,
|
151
|
+
}}
|
145
152
|
children={(field) => {
|
146
153
|
return (
|
147
154
|
<div>
|
@@ -176,7 +183,7 @@ describe('createField', () => {
|
|
176
183
|
const onChangeError = 'Please enter a different value (onChangeError)'
|
177
184
|
const onBlurError = 'Please enter a different value (onBlurError)'
|
178
185
|
|
179
|
-
const formFactory = createFormFactory<Person
|
186
|
+
const formFactory = createFormFactory<Person>()
|
180
187
|
|
181
188
|
function Comp() {
|
182
189
|
const form = formFactory.createForm()
|
@@ -186,12 +193,12 @@ describe('createField', () => {
|
|
186
193
|
<form.Field
|
187
194
|
name="firstName"
|
188
195
|
defaultMeta={{ isTouched: true }}
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
}
|
196
|
+
validators={{
|
197
|
+
onChange: ({ value }) =>
|
198
|
+
value.includes('other') ? onChangeError : undefined,
|
199
|
+
onBlur: ({ value }) =>
|
200
|
+
value.includes('other') ? onBlurError : undefined,
|
201
|
+
}}
|
195
202
|
children={(field) => (
|
196
203
|
<div>
|
197
204
|
<input
|
@@ -216,7 +223,6 @@ describe('createField', () => {
|
|
216
223
|
expect(queryByText(onBlurError)).not.toBeInTheDocument()
|
217
224
|
await user.type(input, 'other')
|
218
225
|
expect(getByText(onChangeError)).toBeInTheDocument()
|
219
|
-
// @ts-expect-error unsure why the 'vitest/globals' in tsconfig doesnt work here
|
220
226
|
await user.click(document.body)
|
221
227
|
expect(queryByText(onBlurError)).toBeInTheDocument()
|
222
228
|
})
|
@@ -228,7 +234,7 @@ describe('createField', () => {
|
|
228
234
|
}
|
229
235
|
const error = 'Please enter a different value'
|
230
236
|
|
231
|
-
const formFactory = createFormFactory<Person
|
237
|
+
const formFactory = createFormFactory<Person>()
|
232
238
|
|
233
239
|
function Comp() {
|
234
240
|
const form = formFactory.createForm()
|
@@ -238,9 +244,11 @@ describe('createField', () => {
|
|
238
244
|
<form.Field
|
239
245
|
name="firstName"
|
240
246
|
defaultMeta={{ isTouched: true }}
|
241
|
-
|
242
|
-
|
243
|
-
|
247
|
+
validators={{
|
248
|
+
onChangeAsync: async () => {
|
249
|
+
await sleep(10)
|
250
|
+
return error
|
251
|
+
},
|
244
252
|
}}
|
245
253
|
children={(field) => (
|
246
254
|
<div>
|
@@ -275,7 +283,7 @@ describe('createField', () => {
|
|
275
283
|
const onChangeError = 'Please enter a different value (onChangeError)'
|
276
284
|
const onBlurError = 'Please enter a different value (onBlurError)'
|
277
285
|
|
278
|
-
const formFactory = createFormFactory<Person
|
286
|
+
const formFactory = createFormFactory<Person>()
|
279
287
|
|
280
288
|
function Comp() {
|
281
289
|
const form = formFactory.createForm()
|
@@ -285,13 +293,15 @@ describe('createField', () => {
|
|
285
293
|
<form.Field
|
286
294
|
name="firstName"
|
287
295
|
defaultMeta={{ isTouched: true }}
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
296
|
+
validators={{
|
297
|
+
onChangeAsync: async () => {
|
298
|
+
await sleep(10)
|
299
|
+
return onChangeError
|
300
|
+
},
|
301
|
+
onBlurAsync: async () => {
|
302
|
+
await sleep(10)
|
303
|
+
return onBlurError
|
304
|
+
},
|
295
305
|
}}
|
296
306
|
children={(field) => (
|
297
307
|
<div>
|
@@ -319,7 +329,6 @@ describe('createField', () => {
|
|
319
329
|
await user.type(input, 'other')
|
320
330
|
await waitFor(() => getByText(onChangeError))
|
321
331
|
expect(getByText(onChangeError)).toBeInTheDocument()
|
322
|
-
// @ts-expect-error unsure why the 'vitest/globals' in tsconfig doesnt work here
|
323
332
|
await user.click(document.body)
|
324
333
|
await waitFor(() => getByText(onBlurError))
|
325
334
|
expect(getByText(onBlurError)).toBeInTheDocument()
|
@@ -332,7 +341,7 @@ describe('createField', () => {
|
|
332
341
|
}
|
333
342
|
const mockFn = vi.fn()
|
334
343
|
const error = 'Please enter a different value'
|
335
|
-
const formFactory = createFormFactory<Person
|
344
|
+
const formFactory = createFormFactory<Person>()
|
336
345
|
|
337
346
|
function Comp() {
|
338
347
|
const form = formFactory.createForm()
|
@@ -342,11 +351,13 @@ describe('createField', () => {
|
|
342
351
|
<form.Field
|
343
352
|
name="firstName"
|
344
353
|
defaultMeta={{ isTouched: true }}
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
354
|
+
validators={{
|
355
|
+
onChangeAsyncDebounceMs: 100,
|
356
|
+
onChangeAsync: async () => {
|
357
|
+
mockFn()
|
358
|
+
await sleep(10)
|
359
|
+
return error
|
360
|
+
},
|
350
361
|
}}
|
351
362
|
children={(field) => (
|
352
363
|
<div>
|