11/* eslint-disable @eslint-react/no-context-provider */
2- import { createContext , useContext , useMemo , useState } from 'react'
3- import { FormLensApi , functionalUpdate } from '@tanstack/form-core'
4- import { useStore } from '@tanstack/react-store'
2+ import { createContext , useContext , useMemo } from 'react'
3+ import { FormLensApi } from '@tanstack/form-core'
54import { useForm } from './useForm'
6- import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect '
5+ import { useFieldGroup } from './useFieldGroup '
76import type {
87 AnyFieldApi ,
98 AnyFormApi ,
10- AnyFormLensApi ,
11- AnyFormLensState ,
129 BaseFormOptions ,
1310 DeepKeysOfType ,
1411 FieldApi ,
1512 FormAsyncValidateOrFn ,
16- FormLensState ,
1713 FormOptions ,
1814 FormValidateOrFn ,
1915} from '@tanstack/form-core'
20- import type {
21- ComponentType ,
22- Context ,
23- JSX ,
24- PropsWithChildren ,
25- ReactNode ,
26- } from 'react'
27- import type { FieldComponent , LensFieldComponent } from './useField'
16+ import type { ComponentType , Context , JSX , PropsWithChildren } from 'react'
17+ import type { FieldComponent } from './useField'
2818import type { ReactFormExtendedApi } from './useForm'
29-
30- function LocalSubscribe ( {
31- lens,
32- selector,
33- children,
34- } : PropsWithChildren < {
35- lens : AnyFormLensApi
36- selector : ( state : AnyFormLensState ) => AnyFormLensState
37- } > ) {
38- const data = useStore ( lens . store , selector )
39-
40- return functionalUpdate ( children , data )
41- }
19+ import type { AppFieldExtendedReactFormLensApi } from './useFieldGroup'
4220
4321/**
4422 * TypeScript inferencing is weird.
@@ -155,7 +133,10 @@ interface CreateFormHookProps<
155133 formContext : Context < AnyFormApi >
156134}
157135
158- type AppFieldExtendedReactFormApi <
136+ /**
137+ * @private
138+ */
139+ export type AppFieldExtendedReactFormApi <
159140 TFormData ,
160141 TOnMount extends undefined | FormValidateOrFn < TFormData > ,
161142 TOnChange extends undefined | FormValidateOrFn < TFormData > ,
@@ -197,100 +178,6 @@ type AppFieldExtendedReactFormApi<
197178 AppForm : ComponentType < PropsWithChildren >
198179 }
199180
200- type AppFieldExtendedReactFormLensApi <
201- TFormData ,
202- TName extends DeepKeysOfType < TFormData , TLensData > ,
203- TLensData ,
204- TOnMount extends undefined | FormValidateOrFn < TFormData > ,
205- TOnChange extends undefined | FormValidateOrFn < TFormData > ,
206- TOnChangeAsync extends undefined | FormAsyncValidateOrFn < TFormData > ,
207- TOnBlur extends undefined | FormValidateOrFn < TFormData > ,
208- TOnBlurAsync extends undefined | FormAsyncValidateOrFn < TFormData > ,
209- TOnSubmit extends undefined | FormValidateOrFn < TFormData > ,
210- TOnSubmitAsync extends undefined | FormAsyncValidateOrFn < TFormData > ,
211- TOnServer extends undefined | FormAsyncValidateOrFn < TFormData > ,
212- TSubmitMeta ,
213- TFieldComponents extends Record < string , ComponentType < any > > ,
214- TFormComponents extends Record < string , ComponentType < any > > ,
215- > = FormLensApi <
216- TFormData ,
217- TLensData ,
218- TName ,
219- TOnMount ,
220- TOnChange ,
221- TOnChangeAsync ,
222- TOnBlur ,
223- TOnBlurAsync ,
224- TOnSubmit ,
225- TOnSubmitAsync ,
226- TOnServer ,
227- TSubmitMeta
228- > &
229- NoInfer < TFormComponents > & {
230- form : AppFieldExtendedReactFormApi <
231- TFormData ,
232- TOnMount ,
233- TOnChange ,
234- TOnChangeAsync ,
235- TOnBlur ,
236- TOnBlurAsync ,
237- TOnSubmit ,
238- TOnSubmitAsync ,
239- TOnServer ,
240- TSubmitMeta ,
241- TFieldComponents ,
242- TFormComponents
243- >
244- AppField : LensFieldComponent <
245- TLensData ,
246- TSubmitMeta ,
247- NoInfer < TFieldComponents >
248- >
249- AppForm : ComponentType < PropsWithChildren >
250- /**
251- * A React component to render form fields. With this, you can render and manage individual form fields.
252- */
253- Field : LensFieldComponent < TLensData , TSubmitMeta >
254-
255- /**
256- * 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.
257- */
258- Subscribe : <
259- TSelected = NoInfer <
260- FormLensState <
261- TFormData ,
262- TLensData ,
263- TOnMount ,
264- TOnChange ,
265- TOnChangeAsync ,
266- TOnBlur ,
267- TOnBlurAsync ,
268- TOnSubmit ,
269- TOnSubmitAsync ,
270- TOnServer
271- >
272- > ,
273- > ( props : {
274- selector ?: (
275- state : NoInfer <
276- FormLensState <
277- TFormData ,
278- TLensData ,
279- TOnMount ,
280- TOnChange ,
281- TOnChangeAsync ,
282- TOnBlur ,
283- TOnBlurAsync ,
284- TOnSubmit ,
285- TOnSubmitAsync ,
286- TOnServer
287- >
288- > ,
289- ) => TSelected
290- children : ( ( state : NoInfer < TSelected > ) => ReactNode ) | ReactNode
291- } ) => ReactNode
292- }
293-
294181export interface WithFormProps <
295182 TFormData ,
296183 TOnMount extends undefined | FormValidateOrFn < TFormData > ,
@@ -385,132 +272,6 @@ export function createFormHook<
385272 formContext,
386273 formComponents,
387274} : CreateFormHookProps < TComponents , TFormComponents > ) {
388- function useFormLens <
389- TFormData ,
390- TName extends DeepKeysOfType < TFormData , TLensData > ,
391- TLensData ,
392- TOnMount extends undefined | FormValidateOrFn < TFormData > ,
393- TOnChange extends undefined | FormValidateOrFn < TFormData > ,
394- TOnChangeAsync extends undefined | FormAsyncValidateOrFn < TFormData > ,
395- TOnBlur extends undefined | FormValidateOrFn < TFormData > ,
396- TOnBlurAsync extends undefined | FormAsyncValidateOrFn < TFormData > ,
397- TOnSubmit extends undefined | FormValidateOrFn < TFormData > ,
398- TOnSubmitAsync extends undefined | FormAsyncValidateOrFn < TFormData > ,
399- TOnServer extends undefined | FormAsyncValidateOrFn < TFormData > ,
400- TSubmitMeta = never ,
401- > ( opts : {
402- form : AppFieldExtendedReactFormApi <
403- TFormData ,
404- TOnMount ,
405- TOnChange ,
406- TOnChangeAsync ,
407- TOnBlur ,
408- TOnBlurAsync ,
409- TOnSubmit ,
410- TOnSubmitAsync ,
411- TOnServer ,
412- TSubmitMeta ,
413- TComponents ,
414- TFormComponents
415- >
416- name : TName
417- defaultValues ?: TLensData
418- onSubmitMeta ?: TSubmitMeta
419- } ) : AppFieldExtendedReactFormLensApi <
420- TFormData ,
421- TName ,
422- TLensData ,
423- TOnMount ,
424- TOnChange ,
425- TOnChangeAsync ,
426- TOnBlur ,
427- TOnBlurAsync ,
428- TOnSubmit ,
429- TOnSubmitAsync ,
430- TOnServer ,
431- TSubmitMeta ,
432- TComponents ,
433- TFormComponents
434- > {
435- const [ formLensApi ] = useState ( ( ) => {
436- const api = new FormLensApi ( opts )
437-
438- const extendedApi : AppFieldExtendedReactFormLensApi <
439- TFormData ,
440- TName ,
441- TLensData ,
442- TOnMount ,
443- TOnChange ,
444- TOnChangeAsync ,
445- TOnBlur ,
446- TOnBlurAsync ,
447- TOnSubmit ,
448- TOnSubmitAsync ,
449- TOnServer ,
450- TSubmitMeta ,
451- TComponents ,
452- TFormComponents
453- > = api as never
454-
455- extendedApi . AppForm = function AppForm ( appFormProps ) {
456- return < opts . form . AppForm { ...appFormProps } />
457- }
458-
459- extendedApi . AppField = function AppField ( { name, ...appFieldProps } ) {
460- return (
461- // @ts -expect-error
462- < opts . form . AppField
463- name = { formLensApi . getFormFieldName ( name ) }
464- { ...appFieldProps }
465- />
466- ) as never
467- }
468-
469- extendedApi . Field = function Field ( { name, ...fieldProps } ) {
470- return (
471- // @ts -expect-error
472- < opts . form . Field
473- name = { formLensApi . getFormFieldName ( name ) }
474- { ...fieldProps }
475- />
476- ) as never
477- }
478-
479- extendedApi . Subscribe = function Subscribe ( props : any ) {
480- return (
481- < LocalSubscribe
482- lens = { formLensApi }
483- selector = { props . selector }
484- children = { props . children }
485- />
486- )
487- }
488-
489- return Object . assign ( extendedApi , {
490- ...formComponents ,
491- } ) as AppFieldExtendedReactFormLensApi <
492- TFormData ,
493- TName ,
494- TLensData ,
495- TOnMount ,
496- TOnChange ,
497- TOnChangeAsync ,
498- TOnBlur ,
499- TOnBlurAsync ,
500- TOnSubmit ,
501- TOnSubmitAsync ,
502- TOnServer ,
503- TSubmitMeta ,
504- TComponents ,
505- TFormComponents
506- >
507- } )
508-
509- useIsomorphicLayoutEffect ( formLensApi . mount , [ formLensApi ] )
510-
511- return formLensApi
512- }
513-
514275 function useAppForm <
515276 TFormData ,
516277 TOnMount extends undefined | FormValidateOrFn < TFormData > ,
@@ -644,7 +405,7 @@ export function createFormHook<
644405 return ( innerProps ) => render ( { ...props , ...innerProps } )
645406 }
646407
647- function withFormLens <
408+ function withFieldGroup <
648409 TLensData ,
649410 TSubmitMeta ,
650411 TRenderProps extends Record < string , unknown > = { } ,
@@ -734,16 +495,18 @@ export function createFormHook<
734495 > ,
735496 name : lens . getFormFieldName ( innerProps . name ) ,
736497 defaultValues,
498+ formComponents,
737499 }
738500 } else {
739501 return {
740502 form : innerProps . form ,
741503 name : innerProps . name ,
742504 defaultValues,
505+ formComponents,
743506 }
744507 }
745508 } , [ innerProps . form , innerProps . name ] )
746- const lensApi = useFormLens ( lensProps )
509+ const lensApi = useFieldGroup ( lensProps )
747510
748511 return render ( { ...props , ...innerProps , lens : lensApi as any } )
749512 }
@@ -752,6 +515,6 @@ export function createFormHook<
752515 return {
753516 useAppForm,
754517 withForm,
755- withFormLens ,
518+ withFieldGroup ,
756519 }
757520}
0 commit comments