@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.
@@ -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