@tanstack/react-form 1.14.2 → 1.15.1
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/createFormHook.cjs +21 -1
- package/dist/cjs/createFormHook.cjs.map +1 -1
- package/dist/cjs/createFormHook.d.cts +16 -2
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/useField.cjs.map +1 -1
- package/dist/cjs/useField.d.cts +6 -0
- package/dist/cjs/useFieldGroup.cjs +60 -0
- package/dist/cjs/useFieldGroup.cjs.map +1 -0
- package/dist/cjs/useFieldGroup.d.cts +29 -0
- package/dist/cjs/useForm.cjs.map +1 -1
- package/dist/esm/createFormHook.d.ts +16 -2
- package/dist/esm/createFormHook.js +21 -1
- package/dist/esm/createFormHook.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/useField.d.ts +6 -0
- package/dist/esm/useField.js.map +1 -1
- package/dist/esm/useFieldGroup.d.ts +29 -0
- package/dist/esm/useFieldGroup.js +60 -0
- package/dist/esm/useFieldGroup.js.map +1 -0
- package/dist/esm/useForm.js.map +1 -1
- package/package.json +2 -2
- package/src/createFormHook.tsx +129 -2
- package/src/index.ts +4 -1
- package/src/useField.tsx +49 -0
- package/src/useFieldGroup.tsx +248 -0
- package/src/useForm.tsx +2 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { useStore } from '@tanstack/react-store'
|
|
3
|
+
import { FieldGroupApi, functionalUpdate } from '@tanstack/form-core'
|
|
4
|
+
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
|
|
5
|
+
import type {
|
|
6
|
+
AnyFieldGroupApi,
|
|
7
|
+
DeepKeysOfType,
|
|
8
|
+
FieldGroupState,
|
|
9
|
+
FieldsMap,
|
|
10
|
+
FormAsyncValidateOrFn,
|
|
11
|
+
FormValidateOrFn,
|
|
12
|
+
} from '@tanstack/form-core'
|
|
13
|
+
import type { AppFieldExtendedReactFormApi } from './createFormHook'
|
|
14
|
+
import type { ComponentType, PropsWithChildren, ReactNode } from 'react'
|
|
15
|
+
import type { LensFieldComponent } from './useField'
|
|
16
|
+
|
|
17
|
+
function LocalSubscribe({
|
|
18
|
+
lens,
|
|
19
|
+
selector,
|
|
20
|
+
children,
|
|
21
|
+
}: PropsWithChildren<{
|
|
22
|
+
lens: AnyFieldGroupApi
|
|
23
|
+
selector: (state: FieldGroupState<any>) => FieldGroupState<any>
|
|
24
|
+
}>) {
|
|
25
|
+
const data = useStore(lens.store, selector)
|
|
26
|
+
|
|
27
|
+
return functionalUpdate(children, data)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
export type AppFieldExtendedReactFieldGroupApi<
|
|
34
|
+
TFormData,
|
|
35
|
+
TFieldGroupData,
|
|
36
|
+
TFields extends
|
|
37
|
+
| DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>
|
|
38
|
+
| FieldsMap<TFormData, TFieldGroupData>,
|
|
39
|
+
TOnMount extends undefined | FormValidateOrFn<TFormData>,
|
|
40
|
+
TOnChange extends undefined | FormValidateOrFn<TFormData>,
|
|
41
|
+
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
42
|
+
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
|
|
43
|
+
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
44
|
+
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
|
|
45
|
+
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
46
|
+
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
47
|
+
TSubmitMeta,
|
|
48
|
+
TFieldComponents extends Record<string, ComponentType<any>>,
|
|
49
|
+
TFormComponents extends Record<string, ComponentType<any>>,
|
|
50
|
+
> = FieldGroupApi<
|
|
51
|
+
TFormData,
|
|
52
|
+
TFieldGroupData,
|
|
53
|
+
TFields,
|
|
54
|
+
TOnMount,
|
|
55
|
+
TOnChange,
|
|
56
|
+
TOnChangeAsync,
|
|
57
|
+
TOnBlur,
|
|
58
|
+
TOnBlurAsync,
|
|
59
|
+
TOnSubmit,
|
|
60
|
+
TOnSubmitAsync,
|
|
61
|
+
TOnServer,
|
|
62
|
+
TSubmitMeta
|
|
63
|
+
> &
|
|
64
|
+
NoInfer<TFormComponents> & {
|
|
65
|
+
AppField: LensFieldComponent<
|
|
66
|
+
TFieldGroupData,
|
|
67
|
+
TSubmitMeta,
|
|
68
|
+
NoInfer<TFieldComponents>
|
|
69
|
+
>
|
|
70
|
+
AppForm: ComponentType<PropsWithChildren>
|
|
71
|
+
/**
|
|
72
|
+
* A React component to render form fields. With this, you can render and manage individual form fields.
|
|
73
|
+
*/
|
|
74
|
+
Field: LensFieldComponent<TFieldGroupData, TSubmitMeta>
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 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.
|
|
78
|
+
*/
|
|
79
|
+
Subscribe: <TSelected = NoInfer<FieldGroupState<TFieldGroupData>>>(props: {
|
|
80
|
+
selector?: (state: NoInfer<FieldGroupState<TFieldGroupData>>) => TSelected
|
|
81
|
+
children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode
|
|
82
|
+
}) => ReactNode
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function useFieldGroup<
|
|
86
|
+
TFormData,
|
|
87
|
+
TFieldGroupData,
|
|
88
|
+
TFields extends
|
|
89
|
+
| DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>
|
|
90
|
+
| FieldsMap<TFormData, TFieldGroupData>,
|
|
91
|
+
TOnMount extends undefined | FormValidateOrFn<TFormData>,
|
|
92
|
+
TOnChange extends undefined | FormValidateOrFn<TFormData>,
|
|
93
|
+
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
94
|
+
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
|
|
95
|
+
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
96
|
+
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
|
|
97
|
+
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
98
|
+
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
|
|
99
|
+
TComponents extends Record<string, ComponentType<any>>,
|
|
100
|
+
TFormComponents extends Record<string, ComponentType<any>>,
|
|
101
|
+
TSubmitMeta = never,
|
|
102
|
+
>(opts: {
|
|
103
|
+
form:
|
|
104
|
+
| AppFieldExtendedReactFormApi<
|
|
105
|
+
TFormData,
|
|
106
|
+
TOnMount,
|
|
107
|
+
TOnChange,
|
|
108
|
+
TOnChangeAsync,
|
|
109
|
+
TOnBlur,
|
|
110
|
+
TOnBlurAsync,
|
|
111
|
+
TOnSubmit,
|
|
112
|
+
TOnSubmitAsync,
|
|
113
|
+
TOnServer,
|
|
114
|
+
TSubmitMeta,
|
|
115
|
+
TComponents,
|
|
116
|
+
TFormComponents
|
|
117
|
+
>
|
|
118
|
+
| AppFieldExtendedReactFieldGroupApi<
|
|
119
|
+
// Since this only occurs if you nest it within other form lenses, it can be more
|
|
120
|
+
// lenient with the types.
|
|
121
|
+
unknown,
|
|
122
|
+
TFormData,
|
|
123
|
+
string | FieldsMap<unknown, TFormData>,
|
|
124
|
+
any,
|
|
125
|
+
any,
|
|
126
|
+
any,
|
|
127
|
+
any,
|
|
128
|
+
any,
|
|
129
|
+
any,
|
|
130
|
+
any,
|
|
131
|
+
any,
|
|
132
|
+
TSubmitMeta,
|
|
133
|
+
TComponents,
|
|
134
|
+
TFormComponents
|
|
135
|
+
>
|
|
136
|
+
fields: TFields
|
|
137
|
+
defaultValues?: TFieldGroupData
|
|
138
|
+
onSubmitMeta?: TSubmitMeta
|
|
139
|
+
formComponents: TFormComponents
|
|
140
|
+
}): AppFieldExtendedReactFieldGroupApi<
|
|
141
|
+
TFormData,
|
|
142
|
+
TFieldGroupData,
|
|
143
|
+
TFields,
|
|
144
|
+
TOnMount,
|
|
145
|
+
TOnChange,
|
|
146
|
+
TOnChangeAsync,
|
|
147
|
+
TOnBlur,
|
|
148
|
+
TOnBlurAsync,
|
|
149
|
+
TOnSubmit,
|
|
150
|
+
TOnSubmitAsync,
|
|
151
|
+
TOnServer,
|
|
152
|
+
TSubmitMeta,
|
|
153
|
+
TComponents,
|
|
154
|
+
TFormComponents
|
|
155
|
+
> {
|
|
156
|
+
const [formLensApi] = useState(() => {
|
|
157
|
+
const api = new FieldGroupApi(opts)
|
|
158
|
+
const form =
|
|
159
|
+
opts.form instanceof FieldGroupApi
|
|
160
|
+
? (opts.form.form as AppFieldExtendedReactFormApi<
|
|
161
|
+
TFormData,
|
|
162
|
+
TOnMount,
|
|
163
|
+
TOnChange,
|
|
164
|
+
TOnChangeAsync,
|
|
165
|
+
TOnBlur,
|
|
166
|
+
TOnBlurAsync,
|
|
167
|
+
TOnSubmit,
|
|
168
|
+
TOnSubmitAsync,
|
|
169
|
+
TOnServer,
|
|
170
|
+
TSubmitMeta,
|
|
171
|
+
TComponents,
|
|
172
|
+
TFormComponents
|
|
173
|
+
>)
|
|
174
|
+
: opts.form
|
|
175
|
+
|
|
176
|
+
const extendedApi: AppFieldExtendedReactFieldGroupApi<
|
|
177
|
+
TFormData,
|
|
178
|
+
TFieldGroupData,
|
|
179
|
+
TFields,
|
|
180
|
+
TOnMount,
|
|
181
|
+
TOnChange,
|
|
182
|
+
TOnChangeAsync,
|
|
183
|
+
TOnBlur,
|
|
184
|
+
TOnBlurAsync,
|
|
185
|
+
TOnSubmit,
|
|
186
|
+
TOnSubmitAsync,
|
|
187
|
+
TOnServer,
|
|
188
|
+
TSubmitMeta,
|
|
189
|
+
TComponents,
|
|
190
|
+
TFormComponents
|
|
191
|
+
> = api as never
|
|
192
|
+
|
|
193
|
+
extendedApi.AppForm = function AppForm(appFormProps) {
|
|
194
|
+
return <form.AppForm {...appFormProps} />
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
extendedApi.AppField = function AppField({ name, ...appFieldProps }) {
|
|
198
|
+
return (
|
|
199
|
+
<form.AppField
|
|
200
|
+
name={formLensApi.getFormFieldName(name)}
|
|
201
|
+
{...(appFieldProps as any)}
|
|
202
|
+
/>
|
|
203
|
+
) as never
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
extendedApi.Field = function Field({ name, ...fieldProps }) {
|
|
207
|
+
return (
|
|
208
|
+
<form.Field
|
|
209
|
+
name={formLensApi.getFormFieldName(name)}
|
|
210
|
+
{...(fieldProps as any)}
|
|
211
|
+
/>
|
|
212
|
+
) as never
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
extendedApi.Subscribe = function Subscribe(props: any) {
|
|
216
|
+
return (
|
|
217
|
+
<LocalSubscribe
|
|
218
|
+
lens={formLensApi}
|
|
219
|
+
selector={props.selector}
|
|
220
|
+
children={props.children}
|
|
221
|
+
/>
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return Object.assign(extendedApi, {
|
|
226
|
+
...opts.formComponents,
|
|
227
|
+
}) as AppFieldExtendedReactFieldGroupApi<
|
|
228
|
+
TFormData,
|
|
229
|
+
TFieldGroupData,
|
|
230
|
+
TFields,
|
|
231
|
+
TOnMount,
|
|
232
|
+
TOnChange,
|
|
233
|
+
TOnChangeAsync,
|
|
234
|
+
TOnBlur,
|
|
235
|
+
TOnBlurAsync,
|
|
236
|
+
TOnSubmit,
|
|
237
|
+
TOnSubmitAsync,
|
|
238
|
+
TOnServer,
|
|
239
|
+
TSubmitMeta,
|
|
240
|
+
TComponents,
|
|
241
|
+
TFormComponents
|
|
242
|
+
>
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
useIsomorphicLayoutEffect(formLensApi.mount, [formLensApi])
|
|
246
|
+
|
|
247
|
+
return formLensApi
|
|
248
|
+
}
|
package/src/useForm.tsx
CHANGED
|
@@ -6,12 +6,13 @@ import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
|
|
|
6
6
|
import type {
|
|
7
7
|
AnyFormApi,
|
|
8
8
|
AnyFormState,
|
|
9
|
+
BaseFormOptions,
|
|
9
10
|
FormAsyncValidateOrFn,
|
|
10
11
|
FormOptions,
|
|
11
12
|
FormState,
|
|
12
13
|
FormValidateOrFn,
|
|
13
14
|
} from '@tanstack/form-core'
|
|
14
|
-
import type { PropsWithChildren, ReactNode } from 'react'
|
|
15
|
+
import type { ComponentType, JSX, PropsWithChildren, ReactNode } from 'react'
|
|
15
16
|
import type { FieldComponent } from './useField'
|
|
16
17
|
import type { NoInfer } from '@tanstack/react-store'
|
|
17
18
|
|