@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
@@ -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, unknown>()
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, unknown>()
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: (data) => {
88
- submittedData = data
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
- onMount: () => {
129
- setFormMounted(true)
130
- return undefined
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, unknown>()
163
+ const formFactory = createFormFactory<Person>()
161
164
 
162
165
  function Comp() {
163
166
  const form = formFactory.createForm(() => ({
164
- onChange: (value) =>
165
- value.firstName.includes('other') ? error : undefined,
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>{form.useStore((s) => s.errors)}</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, unknown>()
209
+ const formFactory = createFormFactory<Person>()
203
210
 
204
211
  function Comp() {
205
212
  const form = formFactory.createForm(() => ({
206
- onChange: (value) =>
207
- value.firstName.includes('other') ? error : undefined,
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, unknown>()
261
+ const formFactory = createFormFactory<Person>()
253
262
 
254
263
  function Comp() {
255
264
  const form = formFactory.createForm(() => ({
256
- onChange: (value) =>
257
- value.firstName.includes('other') ? onChangeError : undefined,
258
- onBlur: (value) =>
259
- value.firstName.includes('other') ? onBlurError : undefined,
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, unknown>()
316
+ const formFactory = createFormFactory<Person>()
307
317
 
308
318
  function Comp() {
309
319
  const form = formFactory.createForm(() => ({
310
- onChangeAsync: async () => {
311
- await sleep(10)
312
- return error
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, unknown>()
369
+ const formFactory = createFormFactory<Person>()
358
370
 
359
371
  function Comp() {
360
372
  const form = formFactory.createForm(() => ({
361
- async onChangeAsync() {
362
- await sleep(10)
363
- return onChangeError
364
- },
365
- async onBlurAsync() {
366
- await sleep(10)
367
- return onBlurError
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, unknown>()
431
+ const formFactory = createFormFactory<Person>()
419
432
 
420
433
  function Comp() {
421
434
  const form = formFactory.createForm(() => ({
422
- onChangeAsyncDebounceMs: 100,
423
- onChangeAsync: async () => {
424
- mockFn()
425
- await sleep(10)
426
- return error
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, unknown>(() => ({
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 { FieldOptions, DeepKeys, DeepValue } from '@tanstack/form-core'
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
- ValidatorType,
7
- FormValidator,
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, ValidatorType, FormValidator, TData> & {
18
+ > = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
10
19
  mode?: 'value' | 'array'
11
20
  }
package/build/index.d.cts DELETED
@@ -1,56 +0,0 @@
1
- import { DeepKeys, DeepValue, FieldOptions, Narrow, FieldApi, FormState, FormOptions, FormApi } from '@tanstack/form-core';
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
- import { JSXElement } from 'solid-js';
4
-
5
- type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, ValidatorType, FormValidator, TData> & {
6
- mode?: 'value' | 'array';
7
- };
8
-
9
- declare module '@tanstack/form-core' {
10
- interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
11
- Field: FieldComponent<TData, FormValidator>;
12
- }
13
- }
14
- type CreateField<TParentData> = <TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts: () => {
15
- name: Narrow<TName>;
16
- } & CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>) => () => FieldApi<TParentData, TName, ValidatorType, FormValidator, DeepValue<TParentData, TName>>;
17
- declare function createField<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts: () => CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>): () => FieldApi<TParentData, TName, ValidatorType, FormValidator>;
18
- type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
19
- children: (fieldApi: () => FieldApi<TParentData, TName, ValidatorType, FormValidator, TData>) => JSXElement;
20
- } & (TParentData extends any[] ? {
21
- name?: TName;
22
- index: number;
23
- } : {
24
- name: TName;
25
- index?: never;
26
- }) & Omit<CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>, 'name' | 'index'>;
27
- type FieldComponent<TParentData, FormValidator> = <TName extends DeepKeys<TParentData>, ValidatorType, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, ValidatorType, FormValidator, TData>) => JSXElement;
28
- declare function Field<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(props: {
29
- children: (fieldApi: () => FieldApi<TParentData, TName, ValidatorType, FormValidator>) => JSXElement;
30
- } & CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>): any;
31
-
32
- type NoInfer<T> = [T][T extends any ? 0 : never];
33
- declare module '@tanstack/form-core' {
34
- interface FormApi<TFormData, ValidatorType> {
35
- Provider: (props: {
36
- children: any;
37
- }) => any;
38
- Field: FieldComponent<TFormData, ValidatorType>;
39
- createField: CreateField<TFormData>;
40
- useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => () => TSelected;
41
- Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
42
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
43
- children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement;
44
- }) => any;
45
- }
46
- }
47
- declare function createForm<TData, FormValidator>(opts?: () => FormOptions<TData, FormValidator>): FormApi<TData, FormValidator>;
48
-
49
- type FormFactory<TFormData, FormValidator> = {
50
- createForm: (opts?: () => FormOptions<TFormData, FormValidator>) => FormApi<TFormData, FormValidator>;
51
- createField: CreateField<TFormData>;
52
- Field: FieldComponent<TFormData, FormValidator>;
53
- };
54
- declare function createFormFactory<TFormData, FormValidator>(defaultOpts?: () => FormOptions<TFormData, FormValidator>): FormFactory<TFormData, FormValidator>;
55
-
56
- export { CreateField, Field, FieldComponent, FormFactory, createField, createForm, createFormFactory };
package/build/index.d.ts DELETED
@@ -1,56 +0,0 @@
1
- import { DeepKeys, DeepValue, FieldOptions, Narrow, FieldApi, FormState, FormOptions, FormApi } from '@tanstack/form-core';
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
- import { JSXElement } from 'solid-js';
4
-
5
- type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldOptions<TParentData, TName, ValidatorType, FormValidator, TData> & {
6
- mode?: 'value' | 'array';
7
- };
8
-
9
- declare module '@tanstack/form-core' {
10
- interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
11
- Field: FieldComponent<TData, FormValidator>;
12
- }
13
- }
14
- type CreateField<TParentData> = <TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts: () => {
15
- name: Narrow<TName>;
16
- } & CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>) => () => FieldApi<TParentData, TName, ValidatorType, FormValidator, DeepValue<TParentData, TName>>;
17
- declare function createField<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(opts: () => CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>): () => FieldApi<TParentData, TName, ValidatorType, FormValidator>;
18
- type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
19
- children: (fieldApi: () => FieldApi<TParentData, TName, ValidatorType, FormValidator, TData>) => JSXElement;
20
- } & (TParentData extends any[] ? {
21
- name?: TName;
22
- index: number;
23
- } : {
24
- name: TName;
25
- index?: never;
26
- }) & Omit<CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>, 'name' | 'index'>;
27
- type FieldComponent<TParentData, FormValidator> = <TName extends DeepKeys<TParentData>, ValidatorType, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: FieldComponentProps<TParentData, TName, ValidatorType, FormValidator, TData>) => JSXElement;
28
- declare function Field<TParentData, TName extends DeepKeys<TParentData>, ValidatorType, FormValidator>(props: {
29
- children: (fieldApi: () => FieldApi<TParentData, TName, ValidatorType, FormValidator>) => JSXElement;
30
- } & CreateFieldOptions<TParentData, TName, ValidatorType, FormValidator>): any;
31
-
32
- type NoInfer<T> = [T][T extends any ? 0 : never];
33
- declare module '@tanstack/form-core' {
34
- interface FormApi<TFormData, ValidatorType> {
35
- Provider: (props: {
36
- children: any;
37
- }) => any;
38
- Field: FieldComponent<TFormData, ValidatorType>;
39
- createField: CreateField<TFormData>;
40
- useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => () => TSelected;
41
- Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
42
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
43
- children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement;
44
- }) => any;
45
- }
46
- }
47
- declare function createForm<TData, FormValidator>(opts?: () => FormOptions<TData, FormValidator>): FormApi<TData, FormValidator>;
48
-
49
- type FormFactory<TFormData, FormValidator> = {
50
- createForm: (opts?: () => FormOptions<TFormData, FormValidator>) => FormApi<TFormData, FormValidator>;
51
- createField: CreateField<TFormData>;
52
- Field: FieldComponent<TFormData, FormValidator>;
53
- };
54
- declare function createFormFactory<TFormData, FormValidator>(defaultOpts?: () => FormOptions<TFormData, FormValidator>): FormFactory<TFormData, FormValidator>;
55
-
56
- export { CreateField, Field, FieldComponent, FormFactory, createField, createForm, createFormFactory };