@@ -50,6 +50,7 @@ import type {
5050import type { ResolvedInternalFieldUpdateOptions } from '../types.lib'
5151import type { FieldUpdateOptions , Updater } from '../types.public'
5252import type { AnyInternalFormApi } from '../FormApi/FormApi.lib'
53+ import type { AnyInternalFormGroupApi } from '../FormGroupApi/FormGroupApi.lib'
5354import type { ReadonlyAtom } from '@tanstack/store'
5455import type { FieldApi , FieldApiOptions } from './FieldApi.public'
5556import type {
@@ -310,6 +311,8 @@ export class InternalFieldApi<
310311 _listeners : Array < AnyFieldListener > | null
311312 _errorVisibility : ErrorVisibility < any , any > | undefined
312313 _errorBoundary : boolean
314+ /** The form group occupying this trie node. */
315+ _formGroup : AnyInternalFormGroupApi | null = null
313316
314317 // TODO implement
315318 /**
@@ -651,15 +654,15 @@ export class InternalFieldApi<
651654
652655 const seenValidatorFields = new WeakSet < AnyInternalFieldApi > ( )
653656
654- visitFieldAndAncestors ( this , ( current ) => {
655- if ( current . _isKilled ) return false
657+ visitFieldAndAncestors ( this , ( current , stop ) => {
658+ if ( current . _isKilled ) return stop
656659
657660 current . _runFieldValidation ( event )
658661 current . _notifyValidator ( event , seenValidatorFields )
659662 return undefined
660663 } )
661664
662- const group = this . form . _getNearestFormGroupForField ( this . name )
665+ const group = this . _getFormGroup ( )
663666 if ( group ) {
664667 group . validate ( event , { triggerFieldApi : this } )
665668 return
@@ -677,6 +680,7 @@ export class InternalFieldApi<
677680 options ?: {
678681 onResult ?: boolean
679682 onlyRunValidatorIndeces ?: Array < number > | null
683+ _startValidation ?: ( ) => ( ) => void
680684 } ,
681685 ) : Promise < FieldValidatorPipelineResult > {
682686 if ( this . _isKilled )
@@ -695,7 +699,14 @@ export class InternalFieldApi<
695699 thrownError : null ,
696700 }
697701
698- this . _setValidationCount ( ( count ) => count + 1 )
702+ let finishValidation = options ?. _startValidation ?.( )
703+ if ( ! finishValidation ) {
704+ this . _setValidationCount ( ( count ) => count + 1 )
705+ finishValidation = ( ) => {
706+ this . _setValidationCount ( ( count ) => Math . max ( 0 , count - 1 ) )
707+ }
708+ }
709+
699710 try {
700711 return await runFieldValidatorPipeline ( {
701712 pipeline : validators ,
@@ -712,7 +723,7 @@ export class InternalFieldApi<
712723 validatorIndecesToRun : options ?. onlyRunValidatorIndeces ?? null ,
713724 } )
714725 } finally {
715- this . _setValidationCount ( ( count ) => Math . max ( 0 , count - 1 ) )
726+ finishValidation ( )
716727 }
717728 }
718729
@@ -848,7 +859,7 @@ export class InternalFieldApi<
848859 batch ( ( ) => {
849860 const seenListenerFields = new WeakSet < AnyInternalFieldApi > ( )
850861
851- visitFieldAndAncestors ( this , ( currNode ) => {
862+ visitFieldAndAncestors ( this , ( currNode , stop ) => {
852863 const isOriginalField = currNode === originalField
853864 const { isSelfDirty, isSelfTouched, isBlurred } = currNode . meta
854865 const shouldUpdateDirty = isOriginalField && markAsDirty && ! isSelfDirty
@@ -868,7 +879,7 @@ export class InternalFieldApi<
868879
869880 currNode . _notifyListener ( event , seenListenerFields )
870881
871- if ( ! doPropagate ) return false
882+ if ( ! doPropagate ) return stop
872883 return undefined
873884 } )
874885 } )
@@ -1084,6 +1095,30 @@ export class InternalFieldApi<
10841095 pruneFieldIfUnused ( this )
10851096 }
10861097
1098+ /** Updates the form group occupying this trie node. */
1099+ _setFormGroup ( formGroup : AnyInternalFormGroupApi | null ) : void {
1100+ if ( this . _formGroup === formGroup ) return
1101+
1102+ this . _formGroup = formGroup
1103+ devtools ( ) . updateField ?.( this )
1104+
1105+ if ( ! formGroup ) this . _pruneIfUnused ( )
1106+ }
1107+
1108+ /** Returns the form group containing this trie node, if one exists. */
1109+ _getFormGroup ( ) : AnyInternalFormGroupApi | null {
1110+ let formGroup : AnyInternalFormGroupApi | null = null
1111+
1112+ visitFieldAndAncestors ( this , ( field , stop ) => {
1113+ if ( ! field . _formGroup ) return
1114+
1115+ formGroup = field . _formGroup
1116+ return stop
1117+ } )
1118+
1119+ return formGroup
1120+ }
1121+
10871122 _getValue ( ) : any {
10881123 return this . form . getFieldValue ( this . name )
10891124 }
0 commit comments