@tanstack/solid-form 0.10.3 → 0.11.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/build/index.d.cts +23 -23
- package/build/index.d.ts +23 -23
- package/package.json +2 -2
- 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 +13 -6
- 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
CHANGED
@@ -1,56 +1,56 @@
|
|
1
|
-
import { DeepKeys, DeepValue, FieldOptions, Narrow, FieldApi, FormState, FormOptions, FormApi } from '@tanstack/form-core';
|
1
|
+
import { DeepKeys, Validator, DeepValue, FieldOptions, Narrow, FieldApi, FormState, FormOptions, FormApi } from '@tanstack/form-core';
|
2
2
|
export { DeepKeys, DeepValue, FieldApi, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormApi, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, functionalUpdate } from '@tanstack/form-core';
|
3
3
|
import { JSXElement } from 'solid-js';
|
4
4
|
|
5
|
-
type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>,
|
5
|
+
type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
|
6
6
|
mode?: 'value' | 'array';
|
7
7
|
};
|
8
8
|
|
9
9
|
declare module '@tanstack/form-core' {
|
10
|
-
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>,
|
11
|
-
Field: FieldComponent<
|
10
|
+
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
|
11
|
+
Field: FieldComponent<TParentData, TFormValidator>;
|
12
12
|
}
|
13
13
|
}
|
14
|
-
type CreateField<TParentData> = <TName extends DeepKeys<TParentData>,
|
14
|
+
type CreateField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: () => {
|
15
15
|
name: Narrow<TName>;
|
16
|
-
} & CreateFieldOptions<TParentData, TName,
|
17
|
-
declare function createField<TParentData, TName extends DeepKeys<TParentData>,
|
18
|
-
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>,
|
19
|
-
children: (fieldApi: () => FieldApi<TParentData, TName,
|
16
|
+
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
17
|
+
declare function createField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: () => CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
|
18
|
+
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
|
19
|
+
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
|
20
20
|
} & (TParentData extends any[] ? {
|
21
21
|
name?: TName;
|
22
22
|
index: number;
|
23
23
|
} : {
|
24
24
|
name: TName;
|
25
25
|
index?: never;
|
26
|
-
}) & Omit<CreateFieldOptions<TParentData, TName,
|
27
|
-
type FieldComponent<TParentData,
|
28
|
-
declare function Field<TParentData, TName extends DeepKeys<TParentData>,
|
29
|
-
children: (fieldApi: () => FieldApi<TParentData, TName,
|
30
|
-
} & CreateFieldOptions<TParentData, TName,
|
26
|
+
}) & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
|
27
|
+
type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
|
28
|
+
declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(props: {
|
29
|
+
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => JSXElement;
|
30
|
+
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): any;
|
31
31
|
|
32
32
|
type NoInfer<T> = [T][T extends any ? 0 : never];
|
33
33
|
declare module '@tanstack/form-core' {
|
34
|
-
interface FormApi<TFormData,
|
34
|
+
interface FormApi<TFormData, TFormValidator> {
|
35
35
|
Provider: (props: {
|
36
36
|
children: any;
|
37
|
-
}) =>
|
38
|
-
Field: FieldComponent<TFormData,
|
37
|
+
}) => JSXElement;
|
38
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
39
39
|
createField: CreateField<TFormData>;
|
40
40
|
useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => () => TSelected;
|
41
41
|
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
42
42
|
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
|
43
43
|
children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement;
|
44
|
-
}) =>
|
44
|
+
}) => JSXElement;
|
45
45
|
}
|
46
46
|
}
|
47
|
-
declare function createForm<
|
47
|
+
declare function createForm<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts?: () => FormOptions<TParentData, TFormValidator>): FormApi<TParentData, TFormValidator>;
|
48
48
|
|
49
|
-
type FormFactory<TFormData,
|
50
|
-
createForm: (opts?: () => FormOptions<TFormData,
|
49
|
+
type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
|
50
|
+
createForm: (opts?: () => FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
51
51
|
createField: CreateField<TFormData>;
|
52
|
-
Field: FieldComponent<TFormData,
|
52
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
53
53
|
};
|
54
|
-
declare function createFormFactory<TFormData,
|
54
|
+
declare function createFormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: () => FormOptions<TFormData, TFormValidator>): FormFactory<TFormData, TFormValidator>;
|
55
55
|
|
56
56
|
export { CreateField, Field, FieldComponent, FormFactory, createField, createForm, createFormFactory };
|
package/build/index.d.ts
CHANGED
@@ -1,56 +1,56 @@
|
|
1
|
-
import { DeepKeys, DeepValue, FieldOptions, Narrow, FieldApi, FormState, FormOptions, FormApi } from '@tanstack/form-core';
|
1
|
+
import { DeepKeys, Validator, DeepValue, FieldOptions, Narrow, FieldApi, FormState, FormOptions, FormApi } from '@tanstack/form-core';
|
2
2
|
export { DeepKeys, DeepValue, FieldApi, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormApi, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, functionalUpdate } from '@tanstack/form-core';
|
3
3
|
import { JSXElement } from 'solid-js';
|
4
4
|
|
5
|
-
type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>,
|
5
|
+
type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
|
6
6
|
mode?: 'value' | 'array';
|
7
7
|
};
|
8
8
|
|
9
9
|
declare module '@tanstack/form-core' {
|
10
|
-
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>,
|
11
|
-
Field: FieldComponent<
|
10
|
+
interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
|
11
|
+
Field: FieldComponent<TParentData, TFormValidator>;
|
12
12
|
}
|
13
13
|
}
|
14
|
-
type CreateField<TParentData> = <TName extends DeepKeys<TParentData>,
|
14
|
+
type CreateField<TParentData> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: () => {
|
15
15
|
name: Narrow<TName>;
|
16
|
-
} & CreateFieldOptions<TParentData, TName,
|
17
|
-
declare function createField<TParentData, TName extends DeepKeys<TParentData>,
|
18
|
-
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>,
|
19
|
-
children: (fieldApi: () => FieldApi<TParentData, TName,
|
16
|
+
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, DeepValue<TParentData, TName>>;
|
17
|
+
declare function createField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts: () => CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
|
18
|
+
type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
|
19
|
+
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
|
20
20
|
} & (TParentData extends any[] ? {
|
21
21
|
name?: TName;
|
22
22
|
index: number;
|
23
23
|
} : {
|
24
24
|
name: TName;
|
25
25
|
index?: never;
|
26
|
-
}) & Omit<CreateFieldOptions<TParentData, TName,
|
27
|
-
type FieldComponent<TParentData,
|
28
|
-
declare function Field<TParentData, TName extends DeepKeys<TParentData>,
|
29
|
-
children: (fieldApi: () => FieldApi<TParentData, TName,
|
30
|
-
} & CreateFieldOptions<TParentData, TName,
|
26
|
+
}) & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'name' | 'index'>;
|
27
|
+
type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
|
28
|
+
declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(props: {
|
29
|
+
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => JSXElement;
|
30
|
+
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): any;
|
31
31
|
|
32
32
|
type NoInfer<T> = [T][T extends any ? 0 : never];
|
33
33
|
declare module '@tanstack/form-core' {
|
34
|
-
interface FormApi<TFormData,
|
34
|
+
interface FormApi<TFormData, TFormValidator> {
|
35
35
|
Provider: (props: {
|
36
36
|
children: any;
|
37
|
-
}) =>
|
38
|
-
Field: FieldComponent<TFormData,
|
37
|
+
}) => JSXElement;
|
38
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
39
39
|
createField: CreateField<TFormData>;
|
40
40
|
useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => () => TSelected;
|
41
41
|
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
42
42
|
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
|
43
43
|
children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement;
|
44
|
-
}) =>
|
44
|
+
}) => JSXElement;
|
45
45
|
}
|
46
46
|
}
|
47
|
-
declare function createForm<
|
47
|
+
declare function createForm<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts?: () => FormOptions<TParentData, TFormValidator>): FormApi<TParentData, TFormValidator>;
|
48
48
|
|
49
|
-
type FormFactory<TFormData,
|
50
|
-
createForm: (opts?: () => FormOptions<TFormData,
|
49
|
+
type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
|
50
|
+
createForm: (opts?: () => FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
|
51
51
|
createField: CreateField<TFormData>;
|
52
|
-
Field: FieldComponent<TFormData,
|
52
|
+
Field: FieldComponent<TFormData, TFormValidator>;
|
53
53
|
};
|
54
|
-
declare function createFormFactory<TFormData,
|
54
|
+
declare function createFormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: () => FormOptions<TFormData, TFormValidator>): FormFactory<TFormData, TFormValidator>;
|
55
55
|
|
56
56
|
export { CreateField, Field, FieldComponent, FormFactory, createField, createForm, createFormFactory };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tanstack/solid-form",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.11.0",
|
4
4
|
"description": "Powerful, type-safe forms for Solid.",
|
5
5
|
"author": "tannerlinsley",
|
6
6
|
"license": "MIT",
|
@@ -55,7 +55,7 @@
|
|
55
55
|
},
|
56
56
|
"dependencies": {
|
57
57
|
"@tanstack/solid-store": "^0.2.1",
|
58
|
-
"@tanstack/form-core": "0.
|
58
|
+
"@tanstack/form-core": "0.11.0"
|
59
59
|
},
|
60
60
|
"peerDependencies": {
|
61
61
|
"solid-js": "^1.6.0"
|
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,17 +51,21 @@ 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
60
|
children={(field) => 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
70
|
children={(field) => null}
|
64
71
|
/>
|
@@ -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>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/// <reference lib="dom" />
|
1
2
|
import { render, screen, waitFor } from '@solidjs/testing-library'
|
2
3
|
import '@testing-library/jest-dom'
|
3
4
|
import userEvent from '@testing-library/user-event'
|
@@ -15,7 +16,7 @@ describe('createForm', () => {
|
|
15
16
|
lastName: string
|
16
17
|
}
|
17
18
|
|
18
|
-
const formFactory = createFormFactory<Person
|
19
|
+
const formFactory = createFormFactory<Person>()
|
19
20
|
|
20
21
|
function Comp() {
|
21
22
|
const form = formFactory.createForm()
|
@@ -50,7 +51,7 @@ describe('createForm', () => {
|
|
50
51
|
lastName: string
|
51
52
|
}
|
52
53
|
|
53
|
-
const formFactory = createFormFactory<Person
|
54
|
+
const formFactory = createFormFactory<Person>()
|
54
55
|
|
55
56
|
function Comp() {
|
56
57
|
const form = formFactory.createForm(() => ({
|
@@ -84,8 +85,8 @@ describe('createForm', () => {
|
|
84
85
|
defaultValues: {
|
85
86
|
firstName: 'FirstName',
|
86
87
|
},
|
87
|
-
onSubmit: (
|
88
|
-
submittedData =
|
88
|
+
onSubmit: ({ value }) => {
|
89
|
+
submittedData = value
|
89
90
|
},
|
90
91
|
}))
|
91
92
|
|
@@ -125,9 +126,11 @@ describe('createForm', () => {
|
|
125
126
|
defaultValues: {
|
126
127
|
firstName: 'FirstName',
|
127
128
|
},
|
128
|
-
|
129
|
-
|
130
|
-
|
129
|
+
validators: {
|
130
|
+
onMount: () => {
|
131
|
+
setFormMounted(true)
|
132
|
+
return undefined
|
133
|
+
},
|
131
134
|
},
|
132
135
|
}))
|
133
136
|
|
@@ -157,14 +160,18 @@ describe('createForm', () => {
|
|
157
160
|
}
|
158
161
|
const error = 'Please enter a different value'
|
159
162
|
|
160
|
-
const formFactory = createFormFactory<Person
|
163
|
+
const formFactory = createFormFactory<Person>()
|
161
164
|
|
162
165
|
function Comp() {
|
163
166
|
const form = formFactory.createForm(() => ({
|
164
|
-
|
165
|
-
|
167
|
+
validators: {
|
168
|
+
onChange: ({ value }) =>
|
169
|
+
value.firstName.includes('other') ? error : undefined,
|
170
|
+
},
|
166
171
|
}))
|
167
172
|
|
173
|
+
const errors = form.useStore((s) => s.errors)
|
174
|
+
|
168
175
|
return (
|
169
176
|
<form.Provider>
|
170
177
|
<form.Field
|
@@ -178,7 +185,7 @@ describe('createForm', () => {
|
|
178
185
|
onBlur={field().handleBlur}
|
179
186
|
onInput={(e) => field().setValue(e.currentTarget.value)}
|
180
187
|
/>
|
181
|
-
<p>{
|
188
|
+
<p>{errors().join(',')}</p>
|
182
189
|
</div>
|
183
190
|
)}
|
184
191
|
/>
|
@@ -199,12 +206,14 @@ describe('createForm', () => {
|
|
199
206
|
}
|
200
207
|
const error = 'Please enter a different value'
|
201
208
|
|
202
|
-
const formFactory = createFormFactory<Person
|
209
|
+
const formFactory = createFormFactory<Person>()
|
203
210
|
|
204
211
|
function Comp() {
|
205
212
|
const form = formFactory.createForm(() => ({
|
206
|
-
|
207
|
-
|
213
|
+
validators: {
|
214
|
+
onChange: ({ value }) =>
|
215
|
+
value.firstName.includes('other') ? error : undefined,
|
216
|
+
},
|
208
217
|
}))
|
209
218
|
|
210
219
|
const [errors, setErrors] = createSignal<ValidationErrorMap>()
|
@@ -249,14 +258,16 @@ describe('createForm', () => {
|
|
249
258
|
const onChangeError = 'Please enter a different value (onChangeError)'
|
250
259
|
const onBlurError = 'Please enter a different value (onBlurError)'
|
251
260
|
|
252
|
-
const formFactory = createFormFactory<Person
|
261
|
+
const formFactory = createFormFactory<Person>()
|
253
262
|
|
254
263
|
function Comp() {
|
255
264
|
const form = formFactory.createForm(() => ({
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
265
|
+
validators: {
|
266
|
+
onChange: ({ value }) =>
|
267
|
+
value.firstName.includes('other') ? onChangeError : undefined,
|
268
|
+
onBlur: ({ value }) =>
|
269
|
+
value.firstName.includes('other') ? onBlurError : undefined,
|
270
|
+
},
|
260
271
|
}))
|
261
272
|
|
262
273
|
const [errors, setErrors] = createSignal<ValidationErrorMap>()
|
@@ -291,7 +302,6 @@ describe('createForm', () => {
|
|
291
302
|
expect(queryByText(onBlurError)).not.toBeInTheDocument()
|
292
303
|
await user.type(input, 'other')
|
293
304
|
expect(getByText(onChangeError)).toBeInTheDocument()
|
294
|
-
// @ts-expect-error unsure why the 'vitest/globals' in tsconfig doesnt work here
|
295
305
|
await user.click(document.body)
|
296
306
|
expect(queryByText(onBlurError)).toBeInTheDocument()
|
297
307
|
})
|
@@ -303,13 +313,15 @@ describe('createForm', () => {
|
|
303
313
|
}
|
304
314
|
const error = 'Please enter a different value'
|
305
315
|
|
306
|
-
const formFactory = createFormFactory<Person
|
316
|
+
const formFactory = createFormFactory<Person>()
|
307
317
|
|
308
318
|
function Comp() {
|
309
319
|
const form = formFactory.createForm(() => ({
|
310
|
-
|
311
|
-
|
312
|
-
|
320
|
+
validators: {
|
321
|
+
onChangeAsync: async () => {
|
322
|
+
await sleep(10)
|
323
|
+
return error
|
324
|
+
},
|
313
325
|
},
|
314
326
|
}))
|
315
327
|
|
@@ -354,17 +366,19 @@ describe('createForm', () => {
|
|
354
366
|
const onChangeError = 'Please enter a different value (onChangeError)'
|
355
367
|
const onBlurError = 'Please enter a different value (onBlurError)'
|
356
368
|
|
357
|
-
const formFactory = createFormFactory<Person
|
369
|
+
const formFactory = createFormFactory<Person>()
|
358
370
|
|
359
371
|
function Comp() {
|
360
372
|
const form = formFactory.createForm(() => ({
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
373
|
+
validators: {
|
374
|
+
async onChangeAsync() {
|
375
|
+
await sleep(10)
|
376
|
+
return onChangeError
|
377
|
+
},
|
378
|
+
async onBlurAsync() {
|
379
|
+
await sleep(10)
|
380
|
+
return onBlurError
|
381
|
+
},
|
368
382
|
},
|
369
383
|
}))
|
370
384
|
|
@@ -402,7 +416,6 @@ describe('createForm', () => {
|
|
402
416
|
await user.type(input, 'other')
|
403
417
|
await waitFor(() => getByText(onChangeError))
|
404
418
|
expect(getByText(onChangeError)).toBeInTheDocument()
|
405
|
-
// @ts-expect-error unsure why the 'vitest/globals' in tsconfig doesnt work here
|
406
419
|
await user.click(document.body)
|
407
420
|
await waitFor(() => getByText(onBlurError))
|
408
421
|
expect(getByText(onBlurError)).toBeInTheDocument()
|
@@ -415,15 +428,17 @@ describe('createForm', () => {
|
|
415
428
|
}
|
416
429
|
const mockFn = vi.fn()
|
417
430
|
const error = 'Please enter a different value'
|
418
|
-
const formFactory = createFormFactory<Person
|
431
|
+
const formFactory = createFormFactory<Person>()
|
419
432
|
|
420
433
|
function Comp() {
|
421
434
|
const form = formFactory.createForm(() => ({
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
435
|
+
validators: {
|
436
|
+
onChangeAsyncDebounceMs: 100,
|
437
|
+
onChangeAsync: async () => {
|
438
|
+
mockFn()
|
439
|
+
await sleep(10)
|
440
|
+
return error
|
441
|
+
},
|
427
442
|
},
|
428
443
|
}))
|
429
444
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/// <reference lib="dom" />
|
1
2
|
import { render } from '@solidjs/testing-library'
|
2
3
|
import '@testing-library/jest-dom'
|
3
4
|
import { createFormFactory } from '..'
|
@@ -9,7 +10,7 @@ describe('createFormFactory', () => {
|
|
9
10
|
lastName: string
|
10
11
|
}
|
11
12
|
|
12
|
-
const formFactory = createFormFactory<Person
|
13
|
+
const formFactory = createFormFactory<Person>(() => ({
|
13
14
|
defaultValues: {
|
14
15
|
firstName: 'FirstName',
|
15
16
|
lastName: 'LastName',
|
package/src/types.ts
CHANGED
@@ -1,11 +1,20 @@
|
|
1
|
-
import type {
|
1
|
+
import type {
|
2
|
+
FieldOptions,
|
3
|
+
DeepKeys,
|
4
|
+
DeepValue,
|
5
|
+
Validator,
|
6
|
+
} from '@tanstack/form-core'
|
2
7
|
|
3
8
|
export type CreateFieldOptions<
|
4
9
|
TParentData,
|
5
10
|
TName extends DeepKeys<TParentData>,
|
6
|
-
|
7
|
-
|
11
|
+
TFieldValidator extends
|
12
|
+
| Validator<DeepValue<TParentData, TName>, unknown>
|
13
|
+
| undefined = undefined,
|
14
|
+
TFormValidator extends
|
15
|
+
| Validator<TParentData, unknown>
|
16
|
+
| undefined = undefined,
|
8
17
|
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
9
|
-
> = FieldOptions<TParentData, TName,
|
18
|
+
> = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
|
10
19
|
mode?: 'value' | 'array'
|
11
20
|
}
|