@@ -29,6 +29,7 @@ type FormProps<TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<T
2929 left ?: React . ReactNode ;
3030 right ?: React . ReactNode ;
3131 } ;
32+ beforeSubmit ?: ( data : NoInfer < TData > ) => Promisable < { errorMessage : string ; success : false } | { success : true } > ;
3233 className ?: string ;
3334 content : FormContent < TData > ;
3435 customStyles ?: {
@@ -51,6 +52,7 @@ type FormProps<TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<T
5152
5253const Form = < TSchema extends z . ZodType < FormDataType > , TData extends z . TypeOf < TSchema > = z . TypeOf < TSchema > > ( {
5354 additionalButtons,
55+ beforeSubmit,
5456 className,
5557 content,
5658 customStyles,
@@ -78,6 +80,7 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
7880
7981 const handleError = ( error : z . ZodError < TData > ) => {
8082 const fieldErrors : FormErrors < TData > = { } ;
83+ const rootErrors : string [ ] = [ ] ;
8184 for ( const issue of error . issues ) {
8285 if ( issue . path . length > 0 ) {
8386 const current = get ( fieldErrors , issue . path ) as string [ ] | undefined ;
@@ -87,10 +90,11 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
8790 set ( fieldErrors , issue . path , [ issue . message ] ) ;
8891 }
8992 } else {
90- setRootErrors ( ( prevErrors ) => [ ... prevErrors , issue . message ] ) ;
93+ rootErrors . push ( issue . message ) ;
9194 }
9295 }
9396 setErrors ( fieldErrors ) ;
97+ setRootErrors ( rootErrors ) ;
9498 if ( onError ) {
9599 onError ( error ) ;
96100 }
@@ -112,6 +116,15 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
112116 handleError ( result . error ) ;
113117 return ;
114118 }
119+ if ( beforeSubmit ) {
120+ const beforeSubmitResult = await beforeSubmit ( result . data ) ;
121+ if ( ! beforeSubmitResult . success ) {
122+ setErrors ( { } ) ;
123+ setRootErrors ( [ beforeSubmitResult . errorMessage ] ) ;
124+ return ;
125+ }
126+ }
127+
115128 try {
116129 setIsSubmitting ( true ) ;
117130 await Promise . all ( [
@@ -193,6 +206,7 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
193206 values = { values }
194207 />
195208 ) }
209+ { Boolean ( rootErrors . length ) && < ErrorMessage className = "-mt-3" error = { rootErrors } /> }
196210 { fieldsFooter }
197211 < div className = "flex w-full gap-3" >
198212 { additionalButtons ?. left }
@@ -234,7 +248,6 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
234248 ) }
235249 { additionalButtons ?. right }
236250 </ div >
237- { Boolean ( rootErrors . length ) && < ErrorMessage error = { rootErrors } /> }
238251 </ form >
239252 ) ;
240253} ;
0 commit comments