@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
@@ -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
|
}
|
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 };
|