@tanstack/react-form 0.24.2 → 0.25.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/index.cjs +0 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +0 -1
- package/dist/cjs/{createServerValidate.cjs → nextjs/createServerValidate.cjs} +12 -4
- package/dist/cjs/nextjs/createServerValidate.cjs.map +1 -0
- package/dist/cjs/nextjs/createServerValidate.d.cts +13 -0
- package/dist/cjs/nextjs/error.cjs +11 -0
- package/dist/cjs/nextjs/error.cjs.map +1 -0
- package/dist/cjs/nextjs/error.d.cts +10 -0
- package/dist/cjs/{nextjs-index.cjs → nextjs/index.cjs} +3 -1
- package/dist/cjs/nextjs/index.cjs.map +1 -0
- package/dist/cjs/nextjs/index.d.cts +3 -0
- package/dist/cjs/nextjs/types.d.cts +3 -0
- package/dist/cjs/start/createServerValidate.cjs +39 -0
- package/dist/cjs/start/createServerValidate.cjs.map +1 -0
- package/dist/cjs/start/createServerValidate.d.cts +13 -0
- package/dist/cjs/start/error.cjs +12 -0
- package/dist/cjs/start/error.cjs.map +1 -0
- package/dist/cjs/start/error.d.cts +12 -0
- package/dist/cjs/start/getFormData.cjs +22 -0
- package/dist/cjs/start/getFormData.cjs.map +1 -0
- package/dist/cjs/start/getFormData.d.cts +14 -0
- package/dist/cjs/start/index.cjs +10 -0
- package/dist/cjs/start/index.cjs.map +1 -0
- package/dist/cjs/start/index.d.cts +3 -0
- package/dist/cjs/start/types.d.cts +3 -0
- package/dist/cjs/start/utils.cjs +6 -0
- package/dist/cjs/start/utils.cjs.map +1 -0
- package/dist/cjs/start/utils.d.cts +1 -0
- package/dist/cjs/useField.cjs +3 -2
- package/dist/cjs/useField.cjs.map +1 -1
- package/dist/cjs/useField.d.cts +4 -9
- package/dist/cjs/useForm.cjs +6 -5
- package/dist/cjs/useForm.cjs.map +1 -1
- package/dist/cjs/useForm.d.cts +34 -35
- package/dist/cjs/useIsomorphicLayoutEffect.cjs +1 -4
- package/dist/cjs/useIsomorphicLayoutEffect.cjs.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/nextjs/createServerValidate.d.ts +13 -0
- package/dist/esm/{createServerValidate.js → nextjs/createServerValidate.js} +12 -4
- package/dist/esm/nextjs/createServerValidate.js.map +1 -0
- package/dist/esm/nextjs/error.d.ts +10 -0
- package/dist/esm/nextjs/error.js +11 -0
- package/dist/esm/nextjs/error.js.map +1 -0
- package/dist/esm/nextjs/index.d.ts +3 -0
- package/dist/esm/{nextjs-index.js → nextjs/index.js} +3 -1
- package/dist/esm/nextjs/index.js.map +1 -0
- package/dist/esm/nextjs/types.d.ts +3 -0
- package/dist/esm/start/createServerValidate.d.ts +13 -0
- package/dist/esm/start/createServerValidate.js +39 -0
- package/dist/esm/start/createServerValidate.js.map +1 -0
- package/dist/esm/start/error.d.ts +12 -0
- package/dist/esm/start/error.js +12 -0
- package/dist/esm/start/error.js.map +1 -0
- package/dist/esm/start/getFormData.d.ts +14 -0
- package/dist/esm/start/getFormData.js +22 -0
- package/dist/esm/start/getFormData.js.map +1 -0
- package/dist/esm/start/index.d.ts +3 -0
- package/dist/esm/start/index.js +10 -0
- package/dist/esm/start/index.js.map +1 -0
- package/dist/esm/start/types.d.ts +3 -0
- package/dist/esm/start/utils.d.ts +1 -0
- package/dist/esm/start/utils.js +6 -0
- package/dist/esm/start/utils.js.map +1 -0
- package/dist/esm/useField.d.ts +4 -9
- package/dist/esm/useField.js +3 -2
- package/dist/esm/useField.js.map +1 -1
- package/dist/esm/useForm.d.ts +34 -35
- package/dist/esm/useForm.js +6 -5
- package/dist/esm/useForm.js.map +1 -1
- package/dist/esm/useIsomorphicLayoutEffect.js +1 -4
- package/dist/esm/useIsomorphicLayoutEffect.js.map +1 -1
- package/package.json +26 -8
- package/src/index.ts +0 -1
- package/src/nextjs/createServerValidate.ts +66 -0
- package/src/nextjs/error.ts +18 -0
- package/src/nextjs/index.ts +4 -0
- package/src/nextjs/types.ts +6 -0
- package/src/start/createServerValidate.tsx +73 -0
- package/src/start/error.ts +21 -0
- package/src/start/getFormData.tsx +20 -0
- package/src/start/index.ts +3 -0
- package/src/start/types.ts +6 -0
- package/src/start/utils.ts +3 -0
- package/src/useField.tsx +15 -23
- package/src/useForm.tsx +37 -42
- package/src/useIsomorphicLayoutEffect.ts +0 -1
- package/dist/cjs/createServerValidate.cjs.map +0 -1
- package/dist/cjs/createServerValidate.d.cts +0 -21
- package/dist/cjs/nextjs-index.cjs.map +0 -1
- package/dist/cjs/nextjs-index.d.cts +0 -2
- package/dist/esm/createServerValidate.d.ts +0 -21
- package/dist/esm/createServerValidate.js.map +0 -1
- package/dist/esm/nextjs-index.d.ts +0 -2
- package/dist/esm/nextjs-index.js.map +0 -1
- package/src/createServerValidate.ts +0 -77
- package/src/nextjs-index.ts +0 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { decode } from 'decode-formdata'
|
|
2
|
+
import { ServerValidateError } from './error'
|
|
3
|
+
import type {
|
|
4
|
+
FormOptions,
|
|
5
|
+
ValidationError,
|
|
6
|
+
Validator,
|
|
7
|
+
} from '@tanstack/form-core'
|
|
8
|
+
import type { ServerFormState } from './types'
|
|
9
|
+
|
|
10
|
+
type OnServerValidateFn<TFormData> = (props: {
|
|
11
|
+
value: TFormData
|
|
12
|
+
}) => ValidationError
|
|
13
|
+
|
|
14
|
+
interface CreateServerValidateOptions<
|
|
15
|
+
TFormData,
|
|
16
|
+
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
17
|
+
> extends FormOptions<TFormData, TFormValidator> {
|
|
18
|
+
onServerValidate: OnServerValidateFn<TFormData>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const createServerValidate =
|
|
22
|
+
<
|
|
23
|
+
TFormData,
|
|
24
|
+
TFormValidator extends
|
|
25
|
+
| Validator<TFormData, unknown>
|
|
26
|
+
| undefined = undefined,
|
|
27
|
+
>(
|
|
28
|
+
defaultOpts: CreateServerValidateOptions<TFormData, TFormValidator>,
|
|
29
|
+
) =>
|
|
30
|
+
async (formData: FormData, info?: Parameters<typeof decode>[1]) => {
|
|
31
|
+
const { validatorAdapter, onServerValidate } = defaultOpts
|
|
32
|
+
|
|
33
|
+
const runValidator = (propsValue: { value: TFormData }) => {
|
|
34
|
+
if (validatorAdapter && typeof onServerValidate !== 'function') {
|
|
35
|
+
return validatorAdapter().validate(propsValue, onServerValidate)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const values = decode(formData, info) as never as TFormData
|
|
42
|
+
|
|
43
|
+
const onServerError = runValidator({ value: values })
|
|
44
|
+
|
|
45
|
+
if (!onServerError) return
|
|
46
|
+
|
|
47
|
+
const formState: ServerFormState<TFormData> = {
|
|
48
|
+
errorMap: {
|
|
49
|
+
onServer: onServerError,
|
|
50
|
+
},
|
|
51
|
+
values,
|
|
52
|
+
errors: onServerError ? [onServerError] : [],
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
throw new ServerValidateError({
|
|
56
|
+
formState,
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const initialFormState: ServerFormState<any> = {
|
|
61
|
+
errorMap: {
|
|
62
|
+
onServer: undefined,
|
|
63
|
+
},
|
|
64
|
+
values: undefined,
|
|
65
|
+
errors: [],
|
|
66
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ServerFormState } from './types'
|
|
2
|
+
|
|
3
|
+
interface ServerValidateErrorState<TFormData> {
|
|
4
|
+
formState: ServerFormState<TFormData>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export class ServerValidateError<TFormData>
|
|
8
|
+
extends Error
|
|
9
|
+
implements ServerValidateErrorState<TFormData>
|
|
10
|
+
{
|
|
11
|
+
formState: ServerFormState<TFormData>
|
|
12
|
+
|
|
13
|
+
constructor(options: ServerValidateErrorState<TFormData>) {
|
|
14
|
+
super('Your form has errors. Please check the fields and try again.')
|
|
15
|
+
this.name = 'ServerValidateError'
|
|
16
|
+
this.formState = options.formState
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { decode } from 'decode-formdata'
|
|
2
|
+
import { _tanstackInternalsCookie } from './utils'
|
|
3
|
+
import { ServerValidateError } from './error'
|
|
4
|
+
import type {
|
|
5
|
+
FormOptions,
|
|
6
|
+
ValidationError,
|
|
7
|
+
Validator,
|
|
8
|
+
} from '@tanstack/form-core'
|
|
9
|
+
import type { FetchFn } from '@tanstack/start'
|
|
10
|
+
import type { ServerFormState } from './types'
|
|
11
|
+
|
|
12
|
+
type Ctx = Parameters<FetchFn<FormData, unknown>>[1]
|
|
13
|
+
|
|
14
|
+
type OnServerValidateFn<TFormData> = (props: {
|
|
15
|
+
value: TFormData
|
|
16
|
+
}) => ValidationError
|
|
17
|
+
|
|
18
|
+
interface CreateServerValidateOptions<
|
|
19
|
+
TFormData,
|
|
20
|
+
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
21
|
+
> extends FormOptions<TFormData, TFormValidator> {
|
|
22
|
+
onServerValidate: OnServerValidateFn<TFormData>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const createServerValidate =
|
|
26
|
+
<
|
|
27
|
+
TFormData,
|
|
28
|
+
TFormValidator extends
|
|
29
|
+
| Validator<TFormData, unknown>
|
|
30
|
+
| undefined = undefined,
|
|
31
|
+
>(
|
|
32
|
+
defaultOpts: CreateServerValidateOptions<TFormData, TFormValidator>,
|
|
33
|
+
) =>
|
|
34
|
+
async (ctx: Ctx, formData: FormData, info?: Parameters<typeof decode>[1]) => {
|
|
35
|
+
const { validatorAdapter, onServerValidate } = defaultOpts
|
|
36
|
+
|
|
37
|
+
const runValidator = (propsValue: { value: TFormData }) => {
|
|
38
|
+
if (validatorAdapter && typeof onServerValidate !== 'function') {
|
|
39
|
+
return validatorAdapter().validate(propsValue, onServerValidate)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const referer = ctx.request.headers.get('referer')!
|
|
46
|
+
|
|
47
|
+
const data = decode(formData, info) as never as TFormData
|
|
48
|
+
|
|
49
|
+
const onServerError = runValidator({ value: data })
|
|
50
|
+
|
|
51
|
+
if (!onServerError) return
|
|
52
|
+
|
|
53
|
+
const formState: ServerFormState<TFormData> = {
|
|
54
|
+
errorMap: {
|
|
55
|
+
onServer: onServerError,
|
|
56
|
+
},
|
|
57
|
+
values: data,
|
|
58
|
+
errors: onServerError ? [onServerError] : [],
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const cookie = await _tanstackInternalsCookie.serialize(formState)
|
|
62
|
+
|
|
63
|
+
throw new ServerValidateError({
|
|
64
|
+
response: new Response('ok', {
|
|
65
|
+
headers: {
|
|
66
|
+
Location: referer,
|
|
67
|
+
'Set-Cookie': cookie,
|
|
68
|
+
},
|
|
69
|
+
status: 302,
|
|
70
|
+
}),
|
|
71
|
+
formState: formState,
|
|
72
|
+
})
|
|
73
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ServerFormState } from './types'
|
|
2
|
+
|
|
3
|
+
interface ServerValidateErrorState<TFormData> {
|
|
4
|
+
formState: ServerFormState<TFormData>
|
|
5
|
+
response: Response
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class ServerValidateError<TFormData>
|
|
9
|
+
extends Error
|
|
10
|
+
implements ServerValidateErrorState<TFormData>
|
|
11
|
+
{
|
|
12
|
+
response: Response
|
|
13
|
+
formState: ServerFormState<TFormData>
|
|
14
|
+
|
|
15
|
+
constructor(options: ServerValidateErrorState<TFormData>) {
|
|
16
|
+
super('Your form has errors. Please check the fields and try again.')
|
|
17
|
+
this.name = 'ServerValidateError'
|
|
18
|
+
this.response = options.response
|
|
19
|
+
this.formState = options.formState
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createServerFn } from '@tanstack/start'
|
|
2
|
+
import { _tanstackInternalsCookie } from './utils'
|
|
3
|
+
import type { ServerFormState } from './types'
|
|
4
|
+
|
|
5
|
+
export const initialFormState = {
|
|
6
|
+
errorMap: {
|
|
7
|
+
onServer: undefined,
|
|
8
|
+
},
|
|
9
|
+
errors: [],
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const getFormData = createServerFn('GET', async (_, ctx) => {
|
|
13
|
+
const data = (await _tanstackInternalsCookie.parse(
|
|
14
|
+
ctx.request.headers.get('Cookie'),
|
|
15
|
+
)) as undefined | ServerFormState<any>
|
|
16
|
+
// Delete the cookie before it hits the client again¸
|
|
17
|
+
ctx.request.headers.delete('Cookie')
|
|
18
|
+
if (!data) return initialFormState
|
|
19
|
+
return data
|
|
20
|
+
})
|
package/src/useField.tsx
CHANGED
|
@@ -5,27 +5,16 @@ import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
|
|
|
5
5
|
import type { NodeType, UseFieldOptions } from './types'
|
|
6
6
|
import type { DeepKeys, DeepValue, Validator } from '@tanstack/form-core'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface ReactFieldApi<
|
|
9
|
+
TParentData,
|
|
10
|
+
TFormValidator extends
|
|
11
|
+
| Validator<TParentData, unknown>
|
|
12
|
+
| undefined = undefined,
|
|
13
|
+
> {
|
|
9
14
|
/**
|
|
10
|
-
*
|
|
15
|
+
* A pre-bound and type-safe sub-field component using this field as a root.
|
|
11
16
|
*/
|
|
12
|
-
|
|
13
|
-
interface FieldApi<
|
|
14
|
-
TParentData,
|
|
15
|
-
TName extends DeepKeys<TParentData>,
|
|
16
|
-
TFieldValidator extends
|
|
17
|
-
| Validator<DeepValue<TParentData, TName>, unknown>
|
|
18
|
-
| undefined = undefined,
|
|
19
|
-
TFormValidator extends
|
|
20
|
-
| Validator<TParentData, unknown>
|
|
21
|
-
| undefined = undefined,
|
|
22
|
-
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
|
23
|
-
> {
|
|
24
|
-
/**
|
|
25
|
-
* A pre-bound and type-safe sub-field component using this field as a root.
|
|
26
|
-
*/
|
|
27
|
-
Field: FieldComponent<TParentData, TFormValidator>
|
|
28
|
-
}
|
|
17
|
+
Field: FieldComponent<TParentData, TFormValidator>
|
|
29
18
|
}
|
|
30
19
|
|
|
31
20
|
/**
|
|
@@ -75,7 +64,7 @@ export function useField<
|
|
|
75
64
|
TFormValidator,
|
|
76
65
|
TData
|
|
77
66
|
>,
|
|
78
|
-
)
|
|
67
|
+
) {
|
|
79
68
|
const [fieldApi] = useState(() => {
|
|
80
69
|
const api = new FieldApi({
|
|
81
70
|
...opts,
|
|
@@ -83,9 +72,12 @@ export function useField<
|
|
|
83
72
|
name: opts.name,
|
|
84
73
|
})
|
|
85
74
|
|
|
86
|
-
api
|
|
75
|
+
const extendedApi: typeof api & ReactFieldApi<TParentData, TFormValidator> =
|
|
76
|
+
api as never
|
|
77
|
+
|
|
78
|
+
extendedApi.Field = Field as never
|
|
87
79
|
|
|
88
|
-
return
|
|
80
|
+
return extendedApi
|
|
89
81
|
})
|
|
90
82
|
|
|
91
83
|
useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])
|
|
@@ -107,7 +99,7 @@ export function useField<
|
|
|
107
99
|
: undefined,
|
|
108
100
|
)
|
|
109
101
|
|
|
110
|
-
return fieldApi
|
|
102
|
+
return fieldApi
|
|
111
103
|
}
|
|
112
104
|
|
|
113
105
|
/**
|
package/src/useForm.tsx
CHANGED
|
@@ -7,31 +7,32 @@ import type { NoInfer } from '@tanstack/react-store'
|
|
|
7
7
|
import type { FormOptions, FormState, Validator } from '@tanstack/form-core'
|
|
8
8
|
import type { NodeType } from './types'
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Fields that are added onto the `FormAPI` from `@tanstack/form-core` and returned from `useForm`
|
|
12
|
+
*/
|
|
13
|
+
interface ReactFormApi<
|
|
14
|
+
TFormData,
|
|
15
|
+
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
16
|
+
> {
|
|
11
17
|
/**
|
|
12
|
-
*
|
|
18
|
+
* A React component to render form fields. With this, you can render and manage individual form fields.
|
|
13
19
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
) => TSelected
|
|
20
|
+
Field: FieldComponent<TFormData, TFormValidator>
|
|
21
|
+
/**
|
|
22
|
+
* A custom React hook that provides functionalities related to individual form fields. It gives you access to field values, errors, and allows you to set or update field values.
|
|
23
|
+
*/
|
|
24
|
+
useField: UseField<TFormData, TFormValidator>
|
|
25
|
+
/**
|
|
26
|
+
* A `useStore` hook that connects to the internal store of the form. It can be used to access the form's current state or any other related state information. You can optionally pass in a selector function to cherry-pick specific parts of the state
|
|
27
|
+
*/
|
|
28
|
+
useStore: <TSelected = NoInfer<FormState<TFormData>>>(
|
|
29
|
+
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
|
|
30
|
+
) => TSelected
|
|
31
|
+
/**
|
|
32
|
+
* A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
|
|
33
|
+
*/
|
|
34
|
+
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
|
30
35
|
/**
|
|
31
|
-
* A `Subscribe` function that allows you to listen and react to changes in the form's state. It's especially useful when you need to execute side effects or render specific components in response to state updates.
|
|
32
|
-
*/
|
|
33
|
-
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
|
|
34
|
-
/**
|
|
35
36
|
TypeScript versions <=5.0.4 have a bug that prevents
|
|
36
37
|
the type of the `TSelected` generic from being inferred
|
|
37
38
|
from the return type of this method.
|
|
@@ -42,41 +43,35 @@ declare module '@tanstack/form-core' {
|
|
|
42
43
|
@see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
|
|
43
44
|
@see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
|
|
44
45
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
46
|
+
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
|
|
47
|
+
children: ((state: NoInfer<TSelected>) => NodeType) | NodeType
|
|
48
|
+
}) => NodeType
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
* A custom React Hook that returns an instance of the `FormApi` class.
|
|
52
|
+
* A custom React Hook that returns an extended instance of the `FormApi` class.
|
|
53
53
|
*
|
|
54
54
|
* This API encapsulates all the necessary functionalities related to the form. It allows you to manage form state, handle submissions, and interact with form fields
|
|
55
55
|
*/
|
|
56
56
|
export function useForm<
|
|
57
57
|
TFormData,
|
|
58
58
|
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
59
|
-
>(
|
|
60
|
-
opts?: FormOptions<TFormData, TFormValidator>,
|
|
61
|
-
): FormApi<TFormData, TFormValidator> {
|
|
59
|
+
>(opts?: FormOptions<TFormData, TFormValidator>) {
|
|
62
60
|
const [formApi] = useState(() => {
|
|
63
61
|
const api = new FormApi<TFormData, TFormValidator>(opts)
|
|
64
|
-
|
|
62
|
+
|
|
63
|
+
const extendedApi: typeof api & ReactFormApi<TFormData, TFormValidator> =
|
|
64
|
+
api as never
|
|
65
|
+
extendedApi.Field = function APIField(props) {
|
|
65
66
|
return (<Field {...props} form={api} />) as never
|
|
66
67
|
}
|
|
67
68
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
selector,
|
|
72
|
-
) => {
|
|
69
|
+
extendedApi.useField = (props) => useField({ ...props, form: api })
|
|
70
|
+
extendedApi.useStore = (selector) => {
|
|
73
71
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
74
72
|
return useStore(api.store as any, selector as any) as any
|
|
75
73
|
}
|
|
76
|
-
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
props,
|
|
79
|
-
) => {
|
|
74
|
+
extendedApi.Subscribe = (props) => {
|
|
80
75
|
return functionalUpdate(
|
|
81
76
|
props.children,
|
|
82
77
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -84,7 +79,7 @@ export function useForm<
|
|
|
84
79
|
) as any
|
|
85
80
|
}
|
|
86
81
|
|
|
87
|
-
return
|
|
82
|
+
return extendedApi
|
|
88
83
|
})
|
|
89
84
|
|
|
90
85
|
useIsomorphicLayoutEffect(formApi.mount, [])
|
|
@@ -99,5 +94,5 @@ export function useForm<
|
|
|
99
94
|
formApi.update(opts)
|
|
100
95
|
})
|
|
101
96
|
|
|
102
|
-
return formApi
|
|
97
|
+
return formApi
|
|
103
98
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createServerValidate.cjs","sources":["../../src/createServerValidate.ts"],"sourcesContent":["import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormOptions<\n TFormData,\n TFormValidator extends\n | Validator<TFormData, unknown>\n | undefined = undefined,\n > {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n }\n}\n\ntype ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const createServerValidate = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts || {}\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n\nexport const initialFormState = {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n}\n"],"names":["decode"],"mappings":";;;AAuCO,MAAM,uBAAuB,CAIlC,gBAEC,OACC,UACA,SACkE;AAClE,QAAM,EAAE,kBAAkB,qBAAqB,eAAe,CAAA;AAExD,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAOA,eAAAA,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AAEK,MAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ,CAAC;AACX;;;"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { decode } from 'decode-formdata';
|
|
2
|
-
import { FormApi, FormOptions, ValidationError, Validator } from '@tanstack/form-core';
|
|
3
|
-
|
|
4
|
-
type OnServerValidateFn<TFormData> = (props: {
|
|
5
|
-
value: TFormData;
|
|
6
|
-
}) => ValidationError;
|
|
7
|
-
type OnServerValidateOrFn<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = TFormValidator extends Validator<TFormData, infer FFN> ? FFN | OnServerValidateFn<TFormData> : OnServerValidateFn<TFormData>;
|
|
8
|
-
declare module '@tanstack/form-core' {
|
|
9
|
-
interface FormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
|
|
10
|
-
onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
|
|
14
|
-
export declare const createServerValidate: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
|
|
15
|
-
export declare const initialFormState: {
|
|
16
|
-
errorMap: {
|
|
17
|
-
onServer: undefined;
|
|
18
|
-
};
|
|
19
|
-
errors: never[];
|
|
20
|
-
};
|
|
21
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nextjs-index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { decode } from 'decode-formdata';
|
|
2
|
-
import { FormApi, FormOptions, ValidationError, Validator } from '@tanstack/form-core';
|
|
3
|
-
|
|
4
|
-
type OnServerValidateFn<TFormData> = (props: {
|
|
5
|
-
value: TFormData;
|
|
6
|
-
}) => ValidationError;
|
|
7
|
-
type OnServerValidateOrFn<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = TFormValidator extends Validator<TFormData, infer FFN> ? FFN | OnServerValidateFn<TFormData> : OnServerValidateFn<TFormData>;
|
|
8
|
-
declare module '@tanstack/form-core' {
|
|
9
|
-
interface FormOptions<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> {
|
|
10
|
-
onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
type ValidateFormData<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = (formData: FormData, info?: Parameters<typeof decode>[1]) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>;
|
|
14
|
-
export declare const createServerValidate: <TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: FormOptions<TFormData, TFormValidator>) => ValidateFormData<TFormData, TFormValidator>;
|
|
15
|
-
export declare const initialFormState: {
|
|
16
|
-
errorMap: {
|
|
17
|
-
onServer: undefined;
|
|
18
|
-
};
|
|
19
|
-
errors: never[];
|
|
20
|
-
};
|
|
21
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createServerValidate.js","sources":["../../src/createServerValidate.ts"],"sourcesContent":["import { decode } from 'decode-formdata'\nimport type {\n FormApi,\n FormOptions,\n ValidationError,\n Validator,\n} from '@tanstack/form-core'\n\ntype OnServerValidateFn<TFormData> = (props: {\n value: TFormData\n}) => ValidationError\n\ntype OnServerValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | OnServerValidateFn<TFormData>\n : OnServerValidateFn<TFormData>\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormOptions<\n TFormData,\n TFormValidator extends\n | Validator<TFormData, unknown>\n | undefined = undefined,\n > {\n onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>\n }\n}\n\ntype ValidateFormData<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>\n\nexport const createServerValidate = <\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: FormOptions<TFormData, TFormValidator>,\n) =>\n (async (\n formData: FormData,\n info?: Parameters<typeof decode>[1],\n ): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {\n const { validatorAdapter, onServerValidate } = defaultOpts || {}\n\n const runValidator = (propsValue: { value: TFormData }) => {\n if (validatorAdapter && typeof onServerValidate !== 'function') {\n return validatorAdapter().validate(propsValue, onServerValidate)\n }\n\n return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)\n }\n\n const data = decode(formData, info) as never as TFormData\n\n const onServerError = runValidator({ value: data })\n\n return {\n errorMap: {\n onServer: onServerError,\n },\n errors: onServerError ? [onServerError] : [],\n }\n }) as ValidateFormData<TFormData, TFormValidator>\n\nexport const initialFormState = {\n errorMap: {\n onServer: undefined,\n },\n errors: [],\n}\n"],"names":[],"mappings":";AAuCO,MAAM,uBAAuB,CAIlC,gBAEC,OACC,UACA,SACkE;AAClE,QAAM,EAAE,kBAAkB,qBAAqB,eAAe,CAAA;AAExD,QAAA,eAAe,CAAC,eAAqC;AACrD,QAAA,oBAAoB,OAAO,qBAAqB,YAAY;AAC9D,aAAO,iBAAiB,EAAE,SAAS,YAAY,gBAAgB;AAAA,IACjE;AAEA,WAAQ,iBAAmD,UAAU;AAAA,EAAA;AAGjE,QAAA,OAAO,OAAO,UAAU,IAAI;AAElC,QAAM,gBAAgB,aAAa,EAAE,OAAO,KAAM,CAAA;AAE3C,SAAA;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,EAAA;AAE/C;AAEK,MAAM,mBAAmB;AAAA,EAC9B,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ,CAAC;AACX;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nextjs-index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { decode } from 'decode-formdata'
|
|
2
|
-
import type {
|
|
3
|
-
FormApi,
|
|
4
|
-
FormOptions,
|
|
5
|
-
ValidationError,
|
|
6
|
-
Validator,
|
|
7
|
-
} from '@tanstack/form-core'
|
|
8
|
-
|
|
9
|
-
type OnServerValidateFn<TFormData> = (props: {
|
|
10
|
-
value: TFormData
|
|
11
|
-
}) => ValidationError
|
|
12
|
-
|
|
13
|
-
type OnServerValidateOrFn<
|
|
14
|
-
TFormData,
|
|
15
|
-
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
16
|
-
> = TFormValidator extends Validator<TFormData, infer FFN>
|
|
17
|
-
? FFN | OnServerValidateFn<TFormData>
|
|
18
|
-
: OnServerValidateFn<TFormData>
|
|
19
|
-
|
|
20
|
-
declare module '@tanstack/form-core' {
|
|
21
|
-
// eslint-disable-next-line no-shadow
|
|
22
|
-
interface FormOptions<
|
|
23
|
-
TFormData,
|
|
24
|
-
TFormValidator extends
|
|
25
|
-
| Validator<TFormData, unknown>
|
|
26
|
-
| undefined = undefined,
|
|
27
|
-
> {
|
|
28
|
-
onServerValidate?: OnServerValidateOrFn<TFormData, TFormValidator>
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type ValidateFormData<
|
|
33
|
-
TFormData,
|
|
34
|
-
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
35
|
-
> = (
|
|
36
|
-
formData: FormData,
|
|
37
|
-
info?: Parameters<typeof decode>[1],
|
|
38
|
-
) => Promise<Partial<FormApi<TFormData, TFormValidator>['state']>>
|
|
39
|
-
|
|
40
|
-
export const createServerValidate = <
|
|
41
|
-
TFormData,
|
|
42
|
-
TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
|
|
43
|
-
>(
|
|
44
|
-
defaultOpts?: FormOptions<TFormData, TFormValidator>,
|
|
45
|
-
) =>
|
|
46
|
-
(async (
|
|
47
|
-
formData: FormData,
|
|
48
|
-
info?: Parameters<typeof decode>[1],
|
|
49
|
-
): Promise<Partial<FormApi<TFormData, TFormValidator>['state']>> => {
|
|
50
|
-
const { validatorAdapter, onServerValidate } = defaultOpts || {}
|
|
51
|
-
|
|
52
|
-
const runValidator = (propsValue: { value: TFormData }) => {
|
|
53
|
-
if (validatorAdapter && typeof onServerValidate !== 'function') {
|
|
54
|
-
return validatorAdapter().validate(propsValue, onServerValidate)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return (onServerValidate as OnServerValidateFn<TFormData>)(propsValue)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const data = decode(formData, info) as never as TFormData
|
|
61
|
-
|
|
62
|
-
const onServerError = runValidator({ value: data })
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
errorMap: {
|
|
66
|
-
onServer: onServerError,
|
|
67
|
-
},
|
|
68
|
-
errors: onServerError ? [onServerError] : [],
|
|
69
|
-
}
|
|
70
|
-
}) as ValidateFormData<TFormData, TFormValidator>
|
|
71
|
-
|
|
72
|
-
export const initialFormState = {
|
|
73
|
-
errorMap: {
|
|
74
|
-
onServer: undefined,
|
|
75
|
-
},
|
|
76
|
-
errors: [],
|
|
77
|
-
}
|
package/src/nextjs-index.ts
DELETED