@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.
Files changed (42) hide show
  1. package/dist/cjs/createField.d.ts +27 -0
  2. package/dist/cjs/createForm.d.ts +21 -0
  3. package/dist/cjs/createFormFactory.d.ts +8 -0
  4. package/dist/cjs/formContext.d.ts +11 -0
  5. package/{build → dist/cjs}/index.cjs +17 -23
  6. package/dist/cjs/index.cjs.map +1 -0
  7. package/dist/cjs/index.d.cts +7 -0
  8. package/dist/cjs/index.d.ts +7 -0
  9. package/{build/dev.cjs → dist/cjs/index.js} +17 -23
  10. package/dist/cjs/tests/createField.test-d.d.ts +2 -0
  11. package/dist/cjs/tests/createField.test.d.ts +1 -0
  12. package/dist/cjs/tests/createForm.test.d.ts +1 -0
  13. package/dist/cjs/tests/createFormFactory.test.d.ts +1 -0
  14. package/dist/cjs/tests/utils.d.ts +1 -0
  15. package/dist/cjs/types.d.ts +4 -0
  16. package/dist/mjs/createField.d.ts +27 -0
  17. package/dist/mjs/createForm.d.ts +21 -0
  18. package/dist/mjs/createFormFactory.d.ts +8 -0
  19. package/dist/mjs/formContext.d.ts +11 -0
  20. package/dist/mjs/index.d.mts +7 -0
  21. package/dist/mjs/index.d.ts +7 -0
  22. package/{build → dist/mjs}/index.js +19 -17
  23. package/{build/dev.js → dist/mjs/index.mjs} +19 -17
  24. package/dist/mjs/index.mjs.map +1 -0
  25. package/dist/mjs/tests/createField.test-d.d.ts +2 -0
  26. package/dist/mjs/tests/createField.test.d.ts +1 -0
  27. package/dist/mjs/tests/createForm.test.d.ts +1 -0
  28. package/dist/mjs/tests/createFormFactory.test.d.ts +1 -0
  29. package/dist/mjs/tests/utils.d.ts +1 -0
  30. package/dist/mjs/types.d.ts +4 -0
  31. package/package.json +19 -32
  32. package/src/createField.tsx +62 -43
  33. package/src/createForm.tsx +18 -11
  34. package/src/createFormFactory.ts +15 -9
  35. package/src/formContext.ts +2 -2
  36. package/src/tests/createField.test-d.tsx +15 -8
  37. package/src/tests/createField.test.tsx +45 -34
  38. package/src/tests/createForm.test.tsx +54 -39
  39. package/src/tests/createFormFactory.test.tsx +2 -1
  40. package/src/types.ts +13 -4
  41. package/build/index.d.cts +0 -56
  42. 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.10.3",
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
- "build",
15
+ "dist",
16
16
  "src"
17
17
  ],
18
18
  "type": "module",
19
- "main": "./build/index.cjs",
20
- "module": "./build/index.js",
21
- "types": "./build/index.d.ts",
19
+ "types": "dist/mjs/index.d.mts",
20
+ "main": "dist/cjs/index.cjs",
21
+ "module": "dist/mjs/index.mjs",
22
22
  "exports": {
23
- "development": {
23
+ ".": {
24
24
  "import": {
25
- "types": "./build/index.d.ts",
26
- "default": "./build/dev.js"
25
+ "types": "./dist/mjs/index.d.mts",
26
+ "default": "./dist/mjs/index.mjs"
27
27
  },
28
28
  "require": {
29
- "types": "./build/index.d.cts",
30
- "default": "./build/dev.cjs"
29
+ "types": "./dist/cjs/index.d.cts",
30
+ "default": "./dist/cjs/index.cjs"
31
31
  }
32
32
  },
33
- "import": {
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.10.3"
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 ./build && rimraf ./coverage",
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": "tsup"
57
+ "build": "vite build"
71
58
  }
72
59
  }
@@ -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
- ValidatorType,
22
- FormValidator,
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<TData, FormValidator>
29
+ Field: FieldComponent<TParentData, TFormValidator>
26
30
  }
27
31
  }
28
32
 
29
33
  export type CreateField<TParentData> = <
30
34
  TName extends DeepKeys<TParentData>,
31
- ValidatorType,
32
- FormValidator,
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
- ValidatorType,
38
- FormValidator
45
+ TFieldValidator,
46
+ TFormValidator
39
47
  >,
40
48
  ) => () => FieldApi<
41
49
  TParentData,
42
50
  TName,
43
- ValidatorType,
44
- FormValidator,
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
- ValidatorType,
63
- FormValidator,
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
- ValidatorType,
69
- FormValidator
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
- ValidatorType,
117
- FormValidator,
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
- ValidatorType,
125
- FormValidator,
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, ValidatorType, FormValidator>,
147
+ CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
140
148
  'name' | 'index'
141
149
  >
142
150
 
143
- export type FieldComponent<TParentData, FormValidator> = <
151
+ export type FieldComponent<
152
+ TParentData,
153
+ TFormValidator extends
154
+ | Validator<TParentData, unknown>
155
+ | undefined = undefined,
156
+ > = <
144
157
  TName extends DeepKeys<TParentData>,
145
- ValidatorType,
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
- ValidatorType,
154
- FormValidator,
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
- ValidatorType,
162
- FormValidator,
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
- ValidatorType,
170
- FormValidator
188
+ TFieldValidator,
189
+ TFormValidator
171
190
  >,
172
191
  ) => JSXElement
173
- } & CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>,
192
+ } & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
174
193
  ) {
175
194
  const fieldApi = createField<
176
195
  TParentData,
177
196
  TName,
178
- ValidatorType,
179
- FormValidator
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
  >
@@ -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, ValidatorType> {
18
- Provider: (props: { children: any }) => any
19
- Field: FieldComponent<TFormData, ValidatorType>
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
- }) => any
27
+ }) => JSXElement
28
28
  }
29
29
  }
30
30
 
31
- export function createForm<TData, FormValidator>(
32
- opts?: () => FormOptions<TData, FormValidator>,
33
- ): FormApi<TData, FormValidator> {
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<TData, FormValidator>(options)
40
+ const formApi = new FormApi<TParentData, TFormValidator>(options)
36
41
 
37
42
  formApi.Provider = function Provider(props) {
38
43
  onMount(formApi.mount)
39
- return <formContext.Provider {...props} value={{ formApi: formApi }} />
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<TData>
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))
@@ -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<TFormData, FormValidator> = {
12
+ export type FormFactory<
13
+ TFormData,
14
+ TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
15
+ > = {
13
16
  createForm: (
14
- opts?: () => FormOptions<TFormData, FormValidator>,
15
- ) => FormApi<TFormData, FormValidator>
17
+ opts?: () => FormOptions<TFormData, TFormValidator>,
18
+ ) => FormApi<TFormData, TFormValidator>
16
19
  createField: CreateField<TFormData>
17
- Field: FieldComponent<TFormData, FormValidator>
20
+ Field: FieldComponent<TFormData, TFormValidator>
18
21
  }
19
22
 
20
- export function createFormFactory<TFormData, FormValidator>(
21
- defaultOpts?: () => FormOptions<TFormData, FormValidator>,
22
- ): FormFactory<TFormData, FormValidator> {
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, FormValidator>(() =>
31
+ createForm<TFormData, TFormValidator>(() =>
26
32
  mergeProps(defaultOpts?.() ?? {}, opts?.() ?? {}),
27
33
  ),
28
34
  createField,
@@ -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
- onChange={(val) => {
52
- assertType<'test'>(val)
53
- return null
54
+ validators={{
55
+ onChange: ({ value }) => {
56
+ assertType<'test'>(value)
57
+ return null
58
+ },
54
59
  }}
55
- children={(field) => null}
60
+ children={() => null}
56
61
  />
57
62
  <form.Field
58
63
  name="age"
59
- onChange={(val) => {
60
- assertType<84>(val)
61
- return null
64
+ validators={{
65
+ onChange: ({ value }) => {
66
+ assertType<84>(value)
67
+ return null
68
+ },
62
69
  }}
63
- children={(field) => null}
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, unknown>()
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, unknown>()
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, unknown>()
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
- onChange={(value) => (value.includes('other') ? error : undefined)}
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, unknown>()
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
- onChange={(value) => (value.includes('other') ? error : undefined)}
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, unknown>()
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
- onChange={(value) =>
190
- value.includes('other') ? onChangeError : undefined
191
- }
192
- onBlur={(value) =>
193
- value.includes('other') ? onBlurError : undefined
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, unknown>()
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
- onChangeAsync={async () => {
242
- await sleep(10)
243
- return error
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, unknown>()
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
- onChangeAsync={async () => {
289
- await sleep(10)
290
- return onChangeError
291
- }}
292
- onBlurAsync={async () => {
293
- await sleep(10)
294
- return onBlurError
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, unknown>()
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
- onChangeAsyncDebounceMs={100}
346
- onChangeAsync={async () => {
347
- mockFn()
348
- await sleep(10)
349
- return error
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>