@@ -18,6 +18,8 @@ import {
1818export * from "./types" ;
1919export { SignatureInput , ConsentCheckbox } ;
2020
21+ type Editor = NonNullable < SuperDoc [ "activeEditor" ] > ;
22+
2123const SuperDocESign = forwardRef < any , Types . SuperDocESignProps > (
2224 ( props , ref ) => {
2325 const {
@@ -41,7 +43,9 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
4143 const [ scrolled , setScrolled ] = useState (
4244 ! document . displayOptions ?. scrollRequired ,
4345 ) ;
44- const [ fieldValues , setFieldValues ] = useState < Map < string , any > > ( new Map ( ) ) ;
46+ const [ fieldValues , setFieldValues ] = useState <
47+ Map < string , Types . FieldValue >
48+ > ( new Map ( ) ) ;
4549 const [ isValid , setIsValid ] = useState ( false ) ;
4650 const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
4751 const [ auditTrail , setAuditTrail ] = useState < Types . AuditEvent [ ] > ( [ ] ) ;
@@ -64,13 +68,76 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
6468 editor . commands . updateStructuredContentById ( field . id , {
6569 text : textValue ,
6670 } ) ;
67- } else if ( field . alias ) {
71+ }
72+ if ( field . alias ) {
6873 editor . commands . updateStructuredContentByAlias ( field . alias , {
6974 text : textValue ,
7075 } ) ;
7176 }
7277 } , [ ] ) ;
7378
79+ // Discover fields in document and apply initial values
80+ const discoverAndApplyFields = useCallback (
81+ ( editor : Editor ) => {
82+ if ( ! editor ) return ;
83+
84+ const tags =
85+ editor . helpers . structuredContentCommands . getStructuredContentTags (
86+ editor . state ,
87+ ) ;
88+
89+ // Build initial values map
90+ const configValues = new Map < string , Types . FieldValue > ( ) ;
91+
92+ fieldsRef . current . document ?. forEach ( ( f ) => {
93+ if ( f . id ) configValues . set ( f . id , f . value ) ;
94+ if ( f . alias ) configValues . set ( f . alias , f . value ) ;
95+ } ) ;
96+
97+ fieldsRef . current . signer ?. forEach ( ( f ) => {
98+ if ( f . value !== undefined ) {
99+ configValues . set ( f . id , f . value ) ;
100+ if ( f . alias ) configValues . set ( f . alias , f . value ) ;
101+ }
102+ } ) ;
103+
104+ // Discover fields
105+ const discovered : Types . FieldInfo [ ] = tags
106+ . map ( ( { node } : any ) => ( {
107+ id : node . attrs . id ,
108+ alias : node . attrs . alias ,
109+ label : node . attrs . alias ,
110+ value :
111+ configValues . get ( node . attrs . id ) ??
112+ configValues . get ( node . attrs . alias ) ??
113+ node . textContent ??
114+ "" ,
115+ } ) )
116+ . filter ( ( f : Types . FieldInfo ) => f . id || f . alias ) ;
117+
118+ if ( discovered . length > 0 ) {
119+ onFieldsDiscovered ?.( discovered ) ;
120+
121+ // Apply initial values from both document and signer fields
122+ const allFields = [
123+ ...( fieldsRef . current . document || [ ] ) ,
124+ ...( fieldsRef . current . signer || [ ] ) ,
125+ ] ;
126+
127+ allFields
128+ . filter ( ( field ) => field . value !== undefined )
129+ . forEach ( ( field ) =>
130+ updateFieldInDocument ( {
131+ id : field . id ,
132+ alias : field . alias ,
133+ value : field . value ! ,
134+ } ) ,
135+ ) ;
136+ }
137+ } ,
138+ [ onFieldsDiscovered , updateFieldInDocument ] ,
139+ ) ;
140+
74141 // Add audit event
75142 const addAuditEvent = ( event : Omit < Types . AuditEvent , "timestamp" > ) => {
76143 const auditEvent : Types . AuditEvent = {
@@ -92,80 +159,9 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
92159 document : document . source ,
93160 documentMode : "viewing" ,
94161 onReady : ( ) => {
95- // Inline field discovery to avoid dependency issues
96162 if ( instance . activeEditor ) {
97- const editor = instance . activeEditor ;
98- const tags =
99- editor . helpers . structuredContentCommands . getStructuredContentTags (
100- editor . state ,
101- ) ;
102-
103- // Create a map of initial values
104- const configValues = new Map < string , any > ( ) ;
105-
106- // Add document field values
107- fieldsRef . current . document ?. forEach ( ( f ) => {
108- if ( f . id ) configValues . set ( f . id , f . value ) ;
109- if ( f . alias ) configValues . set ( f . alias , f . value ) ;
110- } ) ;
111-
112- // Add signer field initial values
113- fieldsRef . current . signer ?. forEach ( ( f ) => {
114- if ( f . value !== undefined ) {
115- configValues . set ( f . id , f . value ) ;
116- if ( f . alias ) configValues . set ( f . alias , f . value ) ;
117- }
118- } ) ;
119-
120- // Discover fields in document
121- const discovered : Types . FieldInfo [ ] = tags
122- . map ( ( { node } : any ) => ( {
123- id : node . attrs . id ,
124- alias : node . attrs . alias ,
125- label : node . attrs . alias ,
126- value :
127- configValues . get ( node . attrs . id ) ??
128- configValues . get ( node . attrs . alias ) ??
129- node . textContent ??
130- "" ,
131- } ) )
132- . filter ( ( f : Types . FieldInfo ) => f . id || f . alias ) ; // Keep fields with at least id or alias
133-
134- if ( discovered . length > 0 ) {
135- onFieldsDiscovered ?.( discovered ) ;
136-
137- // Apply initial values to document
138- fieldsRef . current . document ?. forEach ( ( field ) => {
139- if (
140- field . value !== undefined &&
141- superdocRef . current ?. activeEditor
142- ) {
143- const textValue = String ( field . value ) ;
144- if ( field . id ) {
145- editor . commands . updateStructuredContentById ( field . id , {
146- text : textValue ,
147- } ) ;
148- } else if ( field . alias ) {
149- editor . commands . updateStructuredContentByAlias (
150- field . alias ,
151- { text : textValue } ,
152- ) ;
153- }
154- }
155- } ) ;
156-
157- // Apply signer field initial values if any
158- fieldsRef . current . signer ?. forEach ( ( field ) => {
159- if ( field . value !== undefined ) {
160- const textValue = String ( field . value ) ;
161- editor . commands . updateStructuredContentById ( field . id , {
162- text : textValue ,
163- } ) ;
164- }
165- } ) ;
166- }
163+ discoverAndApplyFields ( instance . activeEditor ) ;
167164 }
168-
169165 addAuditEvent ( { type : "ready" } ) ;
170166 setIsReady ( true ) ;
171167 } ,
@@ -182,7 +178,7 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
182178 superdocRef . current = null ;
183179 }
184180 } ;
185- } , [ document . source , document . mode , onFieldsDiscovered ] ) ; // Removed function dependency
181+ } , [ document . source , document . mode , discoverAndApplyFields ] ) ;
186182
187183 // Track scroll manually
188184 useEffect ( ( ) => {
@@ -213,7 +209,7 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
213209
214210 // Handle field change from signer inputs
215211 const handleFieldChange = useCallback (
216- ( fieldId : string , value : any ) => {
212+ ( fieldId : string , value : Types . FieldValue ) => {
217213 setFieldValues ( ( prev ) => {
218214 const previousValue = prev . get ( fieldId ) ;
219215 const newMap = new Map ( prev ) ;
@@ -250,47 +246,34 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
250246 [ onFieldChange , updateFieldInDocument ] ,
251247 ) ;
252248
253- // Validate form
254- useEffect ( ( ) => {
255- const checkValidity = ( ) => {
256- // Check scroll requirement
257- if ( document . displayOptions ?. scrollRequired && ! scrolled ) {
258- return false ;
259- }
260-
261- // Check required fields
262- const signerFields = fields . signer || [ ] ;
263- for ( const field of signerFields ) {
264- if ( field . validation ?. required ) {
265- const value = fieldValues . get ( field . id ) ;
266- if ( ! value || ( typeof value === "string" && ! value . trim ( ) ) ) {
267- return false ;
268- }
269- }
270- }
249+ // Check if form is valid
250+ const checkIsValid = useCallback ( ( ) : boolean => {
251+ // Check scroll requirement
252+ if ( document . displayOptions ?. scrollRequired && ! scrolled ) {
253+ return false ;
254+ }
271255
272- return true ;
273- } ;
256+ // Check required fields
257+ return ( fields . signer || [ ] ) . every ( ( field ) => {
258+ if ( ! field . validation ?. required ) return true ;
259+ const value = fieldValues . get ( field . id ) ;
260+ return value && ( typeof value !== "string" || value . trim ( ) ) ;
261+ } ) ;
262+ } , [ scrolled , fields . signer , fieldValues , document . displayOptions ] ) ;
274263
275- const valid = checkValidity ( ) ;
264+ // Validate form and notify state changes
265+ useEffect ( ( ) => {
266+ const valid = checkIsValid ( ) ;
276267 setIsValid ( valid ) ;
277268
278- // Notify state change
279269 const state : Types . SigningState = {
280270 scrolled,
281271 fields : fieldValues ,
282272 isValid : valid ,
283273 isSubmitting,
284274 } ;
285275 onStateChange ?.( state ) ;
286- } , [
287- scrolled ,
288- fieldValues ,
289- fields . signer ,
290- document . displayOptions ,
291- isSubmitting ,
292- onStateChange ,
293- ] ) ;
276+ } , [ scrolled , fieldValues , isSubmitting , checkIsValid , onStateChange ] ) ;
294277
295278 // Handle download
296279 const handleDownload = useCallback ( async ( ) => {
@@ -330,7 +313,7 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
330313 signerFields : ( fields . signer || [ ] ) . map ( ( field ) => ( {
331314 id : field . id ,
332315 alias : field . alias ,
333- value : fieldValues . get ( field . id ) ,
316+ value : fieldValues . get ( field . id ) ?? null ,
334317 } ) ) ,
335318 isFullyCompleted : isValid ,
336319 } ;
@@ -358,9 +341,9 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
358341 return (
359342 < Component
360343 key = { field . id }
361- value = { fieldValues . get ( field . id ) }
344+ value = { fieldValues . get ( field . id ) ?? null }
362345 onChange = { ( value ) => handleFieldChange ( field . id , value ) }
363- isDisabled = { isDisabled } //|| Boolean(document.displayOptions?.scrollRequired && !scrolled)
346+ isDisabled = { isDisabled }
364347 label = { field . label }
365348 />
366349 ) ;
@@ -380,10 +363,33 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
380363 }
381364 } ;
382365
383- // Create button components
384- const DownloadButton =
385- download ?. component || createDownloadButton ( download ) ;
386- const SubmitButton = submit ?. component || createSubmitButton ( submit ) ;
366+ // Render action buttons
367+ const renderActionButtons = ( ) => {
368+ const DownloadButton =
369+ download ?. component || createDownloadButton ( download ) ;
370+ const SubmitButton = submit ?. component || createSubmitButton ( submit ) ;
371+
372+ return (
373+ < div
374+ className = "superdoc-esign-actions"
375+ style = { { display : "flex" , gap : "10px" } }
376+ >
377+ { document . mode !== "download" && (
378+ < SubmitButton
379+ onClick = { handleSubmit }
380+ isValid = { isValid }
381+ isDisabled = { isDisabled }
382+ isSubmitting = { isSubmitting }
383+ />
384+ ) }
385+ < DownloadButton
386+ onClick = { handleDownload }
387+ fileName = { download ?. fileName }
388+ isDisabled = { isDisabled }
389+ />
390+ </ div >
391+ ) ;
392+ } ;
387393
388394 // Expose methods via ref
389395 useImperativeHandle ( ref , ( ) => ( {
@@ -428,24 +434,7 @@ const SuperDocESign = forwardRef<any, Types.SuperDocESignProps>(
428434 ) }
429435
430436 { /* Action buttons */ }
431- < div
432- className = "superdoc-esign-actions"
433- style = { { display : "flex" , gap : "10px" } }
434- >
435- { document . mode !== "download" && (
436- < SubmitButton
437- onClick = { handleSubmit }
438- isValid = { isValid }
439- isDisabled = { isDisabled }
440- isSubmitting = { isSubmitting }
441- />
442- ) }
443- < DownloadButton
444- onClick = { handleDownload }
445- fileName = { download ?. fileName }
446- isDisabled = { isDisabled }
447- />
448- </ div >
437+ { renderActionButtons ( ) }
449438 </ div >
450439 </ div >
451440 ) ;
0 commit comments