11'use client' ;
22/* eslint-disable no-bitwise */
33
4+ /**
5+ * Form field context and type definitions
6+ * Provides comprehensive type-safe interfaces for form state management,
7+ * field operations, validation, and React context integration
8+ */
9+
410import { createContext , useContext } from 'react' ;
511import type {
612 AllPathsKeys ,
@@ -19,12 +25,21 @@ import type { FieldEntity, Meta, StoreValue } from '../../form-core/types';
1925import type { ValidateMessages } from '../../form-core/validate' ;
2026import type { Rule , ValidateOptions } from '../../form-core/validation' ;
2127
28+ /**
29+ * Interface for list item rendering in dynamic arrays
30+ * Provides stable keys and field names for array field management
31+ */
2232export type ListRenderItem = {
33+ /** Stable key for React rendering optimization */
2334 key : string ;
35+ /** Field name path for this array item */
2436 name : string ;
2537} ;
2638
27- // Core change: wrap each path with Meta
39+ /**
40+ * Utility type to build hierarchical metadata structure from field paths
41+ * Recursively wraps each path segment with Meta information
42+ */
2843type BuildMetaShape < T , P extends string > = P extends `${infer K } .${infer R } `
2944 ? K extends keyof T
3045 ? T [ K ] extends readonly ( infer U ) [ ]
@@ -37,160 +52,299 @@ type BuildMetaShape<T, P extends string> = P extends `${infer K}.${infer R}`
3752 : never
3853 : never ;
3954
40- // Convert an array of paths into a hierarchical Meta structure
55+ /**
56+ * Converts an array of field paths into a hierarchical Meta structure
57+ * Provides type-safe access to field metadata based on field paths
58+ */
4159export type MetaShapeFromPaths < T , Ps extends readonly string [ ] > = Ps extends never [ ] | [ ]
4260 ? { [ K in keyof T ] : Meta < K & string , PathToDeepType < T , K & string > > }
4361 : MergeUnion < Ps [ number ] extends infer P ? ( P extends string ? BuildMetaShape < T , P > : never ) : never > ;
4462
63+ /**
64+ * Comprehensive form state interface
65+ * Contains all form-level and field-level state information
66+ */
4567export interface FormState < Values = any > {
68+ /** Map of fields that have been modified from initial values */
4669 dirtyFields : Record < AllPathsKeys < Values > , boolean > ;
70+ /** Map of field validation errors */
4771 errors : Record < AllPathsKeys < Values > , string [ ] > ;
72+ /** Initial form values */
4873 initialValues : DeepPartial < Values > ;
49- // === Global booleans ===
50- isDirty : boolean ;
5174
75+ // === Global state flags ===
76+ /** Whether any field has been modified */
77+ isDirty : boolean ;
78+ /** Whether the last submission was successful */
5279 isSubmitSuccessful : boolean ;
53- // === Submission lifecycle ===
80+ /** Whether the form has been submitted at least once */
5481 isSubmitted : boolean ;
82+ /** Whether the form is currently being submitted */
5583 isSubmitting : boolean ;
84+ /** Whether all fields pass validation */
5685 isValid : boolean ;
57-
86+ /** Whether any field is currently being validated */
5887 isValidating : boolean ;
88+ /** Number of times the form has been submitted */
5989 submitCount : number ;
60- // === Field-level states ===
61- touchedFields : Record < AllPathsKeys < Values > , boolean > ;
6290
91+ // === Field-level state maps ===
92+ /** Map of fields that have been interacted with */
93+ touchedFields : Record < AllPathsKeys < Values > , boolean > ;
94+ /** Map of fields that have completed validation */
6395 validatedFields : Record < AllPathsKeys < Values > , boolean > ;
96+ /** Map of fields currently being validated */
6497 validatingFields : Record < AllPathsKeys < Values > , boolean > ;
65- // === Meta states ===
98+
99+ // === Form data ===
100+ /** Current form values */
66101 values : Values ;
102+ /** Map of field validation warnings */
67103 warnings : Record < AllPathsKeys < Values > , string [ ] > ;
68104}
69105
106+ /**
107+ * Interface for form value operations
108+ * Provides methods to get and set form field values
109+ */
70110export interface ValuesOptions < Values = any > {
111+ /** Get array operations for a specific array field */
71112 arrayOp : < K extends ArrayKeys < Values > > (
72113 name : K
73114 ) => {
115+ /** Insert item at specified index */
74116 insert : ( index : number , item : ArrayElementValue < Values , K > ) => void ;
117+ /** Move item from one index to another */
75118 move : ( from : number , to : number ) => void ;
119+ /** Remove item at specified index */
76120 remove : ( index : number ) => void ;
121+ /** Replace item at index with new value */
77122 replace : ( index : number , val : ArrayElementValue < Values , K > ) => void ;
123+ /** Swap positions of two items */
78124 swap : ( i : number , j : number ) => void ;
79125 } ;
126+ /** Get values of specified fields or all fields */
80127 getFieldsValue : < K extends AllPathsKeys < Values > [ ] > ( name ?: K ) => ShapeFromPaths < Values , K > ;
128+ /** Get value of a specific field */
81129 getFieldValue : < T extends AllPathsKeys < Values > > ( name : T ) => PathToDeepType < Values , T > ;
130+ /** Set values for multiple fields */
82131 setFieldsValue : ( values : DeepPartial < Values > ) => void ;
132+ /** Set value for a specific field */
83133 setFieldValue : < T extends AllPathsKeys < Values > > ( name : T , value : PathToDeepType < Values , T > ) => void ;
84134}
85135
136+ /**
137+ * Interface for form state query operations
138+ * Provides methods to access field metadata and form state
139+ */
86140export interface StateOptions < Values = any > {
141+ /** Get complete metadata for a specific field */
87142 getField : < T extends AllPathsKeys < Values > > ( name : T ) => Meta < T , PathToDeepType < Values , T > > ;
143+ /** Get validation errors for a specific field */
88144 getFieldError : ( name : AllPathsKeys < Values > ) => string [ ] ;
145+ /** Get metadata for specified fields or all fields */
89146 getFields : < T extends AllPathsKeys < Values > [ ] > ( names ?: T ) => MetaShapeFromPaths < Values , T > ;
147+ /** Get validation errors for specified fields */
90148 getFieldsError : ( names ?: AllPathsKeys < Values > [ ] ) => Record < AllPathsKeys < Values > , string [ ] > ;
149+ /** Check if any of the specified fields have been touched */
91150 getFieldsTouched : ( names ?: AllPathsKeys < Values > [ ] ) => boolean ;
151+ /** Check if any of the specified fields have been validated */
92152 getFieldsValidated : ( names ?: AllPathsKeys < Values > [ ] ) => boolean ;
153+ /** Check if any of the specified fields are currently validating */
93154 getFieldsValidating : ( names ?: AllPathsKeys < Values > [ ] ) => boolean ;
155+ /** Get validation warnings for specified fields */
94156 getFieldsWarning : ( names ?: AllPathsKeys < Values > [ ] ) => Record < AllPathsKeys < Values > , string [ ] > ;
157+ /** Check if a specific field has been touched */
95158 getFieldTouched : ( name : AllPathsKeys < Values > ) => boolean ;
159+ /** Check if a specific field has been validated */
96160 getFieldValidated : ( name : AllPathsKeys < Values > ) => boolean ;
161+ /** Check if a specific field is currently validating */
97162 getFieldValidating : ( name : AllPathsKeys < Values > ) => boolean ;
163+ /** Get validation warnings for a specific field */
98164 getFieldWarning : ( name : AllPathsKeys < Values > ) => string [ ] ;
165+ /** Get complete form state snapshot */
99166 getFormState : ( ) => FormState ;
100167}
101168
169+ /**
170+ * Extended validation options for multiple fields
171+ */
102172export interface ValidateFieldsOptions extends ValidateOptions {
173+ /** Only validate fields that have been modified */
103174 dirty ?: boolean ;
104175}
105176
177+ /**
178+ * Interface for form operation methods
179+ * Provides methods to perform form actions like validation, reset, and submission
180+ */
106181export interface OperationOptions < Values = any > {
182+ /** Reset specified fields to their initial values */
107183 resetFields : ( names ?: AllPathsKeys < Values > [ ] ) => void ;
184+ /** Submit the form after validation */
108185 submit : ( ) => void ;
186+ /** Add middleware to the form processing pipeline */
109187 use : ( mw : Middleware < Values , AllPathsKeys < Values > > ) => void ;
188+ /** Validate a specific field */
110189 validateField : ( name : AllPathsKeys < Values > , opts ?: ValidateOptions ) => Promise < boolean > ;
190+ /** Validate multiple fields */
111191 validateFields : ( names ?: AllPathsKeys < Values > [ ] , opts ?: ValidateFieldsOptions ) => Promise < boolean > ;
112192}
113193
194+ /**
195+ * Interface for validation error information
196+ * Used when form submission fails validation
197+ */
114198export interface ValidateErrorEntity < Values = any > {
115- // For UI to scroll directly
116- errorCount : number ; // Optional: values filtered by _pruneForSubmit (for analytics/replay)
117- errorFields : Meta < string , any > [ ] ; // Per-field list (used to scroll to the first error and show items)
118- errorMap : Record < string , string [ ] > ; // Same as above: warnings
119- firstErrorName ?: string ; // Full current values (not pruned)
199+ /** Total number of fields with validation errors */
200+ errorCount : number ;
201+ /** Array of field metadata with errors (for UI scrolling and display) */
202+ errorFields : Meta < string , any > [ ] ;
203+ /** Map of field names to their error messages */
204+ errorMap : Record < string , string [ ] > ;
205+ /** Name of the first field with an error (for auto-focus) */
206+ firstErrorName ?: string ;
207+ /** Timestamp when validation failed */
120208 submittedAt : number ;
121- values : Values ; // Fast index (header red dot, side group statistics)
209+ /** Current form values at time of validation failure */
210+ values : Values ;
211+ /** Map of field names to their warning messages */
122212 warningMap : Record < string , string [ ] > ;
123213}
124214
215+ /**
216+ * Interface for form lifecycle callback options
217+ * Defines callbacks that can be registered to respond to form events
218+ */
125219export interface RegisterCallbackOptions < Values = any > {
220+ /** Called when field metadata changes (errors, validation state, etc.) */
126221 onFieldsChange ?: (
127222 changedFields : Meta < AllPathsKeys < Values > , PathToDeepType < Values , AllPathsKeys < Values > > > [ ] ,
128223 allFields : Meta < AllPathsKeys < Values > , PathToDeepType < Values , AllPathsKeys < Values > > > [ ]
129224 ) => void ;
130225
226+ /** Called when form submission succeeds validation */
131227 onFinish ?: ( values : Values ) => void ;
132228
229+ /** Called when form submission fails validation */
133230 onFinishFailed ?: ( errorInfo : ValidateErrorEntity < Values > ) => void ;
134231
232+ /** Called when form values change */
135233 onValuesChange ?: ( changedValues : Partial < Values > , values : Values ) => void ;
136234}
137235
236+ /**
237+ * Interface for internal form configuration callbacks
238+ * Used internally to configure form behavior and lifecycle
239+ */
138240export interface InternalCallbacks < Values = any > {
241+ /** Destroy form instance and optionally clear data */
139242 destroyForm : ( clearOnDestroy ?: boolean ) => void ;
243+ /** Set form lifecycle callbacks */
140244 setCallbacks : ( callbacks : RegisterCallbackOptions < Values > ) => void ;
245+ /** Set initial form values */
141246 setInitialValues : ( values : DeepPartial < Values > ) => void ;
247+ /** Set field preservation behavior */
142248 setPreserve : ( preserve : boolean ) => void ;
249+ /** Set custom validation messages */
143250 setValidateMessages : ( messages : ValidateMessages ) => void ;
144251}
145252
253+ /**
254+ * Interface for internal field management hooks
255+ * Provides low-level field operations and state management
256+ */
146257export interface InternalFieldHooks < Values = any > {
258+ /** Perform array operations on array fields */
147259 arrayOp : ( name : AllPathsKeys < Values > , args : ArrayOpArgs ) => void ;
260+ /** Dispatch actions to the form store */
148261 dispatch : ( action : Action ) => void ;
262+ /** Get array field items with stable keys */
149263 getArrayFields : ( name : ArrayKeys < Values > , initialValue ?: StoreValue [ ] ) => ListRenderItem [ ] ;
264+ /** Get initial value for a field */
150265 getInitialValue : < T extends AllPathsKeys < Values > > ( name : T ) => PathToDeepType < Values , T > ;
266+ /** Register a computed field with dependencies */
151267 registerComputed : < T extends AllPathsKeys < Values > > (
152268 name : T ,
153269 deps : AllPathsKeys < Values > [ ] ,
154270 compute : ( get : ( n : AllPathsKeys < Values > ) => any , all : Values ) => PathToDeepType < Values , T >
155271 ) => ( ) => void ;
272+ /** Register a reactive effect with dependencies */
156273 registerEffect : (
157274 deps : AllPathsKeys < Values > [ ] ,
158275 effect : ( get : ( n : AllPathsKeys < Values > ) => any , all : Values ) => void
159276 ) => ( ) => void ;
277+ /** Register a field entity for state management */
160278 registerField : ( entity : FieldEntity ) => ( ) => void ;
279+ /** Set validation rules for a field */
161280 setFieldRules : ( name : AllPathsKeys < Values > , rules ?: Rule [ ] ) => void ;
281+ /** Set values for multiple fields */
162282 setFieldsValue : ( values : DeepPartial < Values > ) => void ;
283+ /** Set value for a specific field */
163284 setFieldValue : ( name : AllPathsKeys < Values > , value : PathToDeepType < Values , AllPathsKeys < Values > > ) => void ;
285+ /** Set validation rules for a field (alias for setFieldRules) */
164286 setRules : ( name : AllPathsKeys < Values > , rules ?: Rule [ ] ) => void ;
287+ /** Subscribe to field changes with optional filtering */
165288 subscribeField : < T extends AllPathsKeys < Values > > (
166289 name : T | T [ ] | undefined ,
167290 cb : ( value : PathToDeepType < Values , T > , name : T , values : Values , mask : ChangeMask ) => void ,
168291 opt ?: { includeChildren ?: boolean ; mask ?: ChangeMask }
169292 ) => ( ) => void ;
293+ /** Execute function within a transaction for batched updates */
170294 transaction : < T > ( fn : ( ) => T ) => T ;
295+ /** Execute async function within a transaction for batched updates */
171296 transactionAsync : < T > ( fn : ( ) => Promise < T > ) => Promise < T > ;
172297}
173298
299+ /**
300+ * Main form instance interface
301+ * Combines all form operation interfaces for external API
302+ */
174303export interface FormInstance < Values = any >
175304 extends ValuesOptions < Values > ,
176305 StateOptions < Values > ,
177306 OperationOptions < Values > { }
178307
308+ /**
309+ * Combined interface for all internal form hooks
310+ * Used internally for form configuration and field management
311+ */
179312export interface InternalFormHooks < Values = any > extends InternalCallbacks < Values > , InternalFieldHooks < Values > { }
180313
314+ /**
315+ * Internal form context interface
316+ * Extends FormInstance with additional context-specific properties
317+ */
181318export interface InternalFormContext < Values = any > extends FormInstance < Values > {
319+ /** Default validation trigger events for fields */
182320 validateTrigger : string | string [ ] ;
183321}
184322
323+ /**
324+ * Complete internal form instance interface
325+ * Provides access to both public API and internal hooks
326+ */
185327export interface InternalFormInstance < Values = any > extends InternalFormContext < Values > {
186- /** Internal API, not recommended for external use */
328+ /** Internal API for accessing low-level form operations - not recommended for external use */
187329 getInternalHooks : ( ) => InternalFormHooks < Values > ;
188330}
189331
332+ /**
333+ * React context for form field management
334+ * Provides form instance and configuration to child components
335+ */
190336export const FieldContext = createContext < InternalFormContext | null > ( null ) ;
191337
338+ /**
339+ * Context provider component for form fields
340+ * Wraps form components to provide form context
341+ */
192342export const FieldContextProvider = FieldContext . Provider ;
193343
344+ /**
345+ * Hook to access form context from child components
346+ * Returns the form instance and configuration from the nearest Form provider
347+ */
194348export const useFieldContext = < Values = any > ( ) : InternalFormContext < Values > | null => {
195349 const context = useContext ( FieldContext ) ;
196350
0 commit comments