@@ -110,6 +110,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
110110 if ( ! divRef . current ) return
111111 divRef . current . innerText = ""
112112 setContent ( "" )
113+ fireOnChange ( "" , 0 )
113114 } ,
114115 getCaretPosition : ( ) => {
115116 if ( ! divRef . current ) return 0
@@ -120,21 +121,14 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
120121
121122 useEffect ( ( ) => {
122123 if ( updatedContent !== null && updatedContent !== undefined ) {
123- setContent ( updatedContent )
124- if ( divRef . current ) divRef . current . innerText = updatedContent
124+ setContent ( ( prev ) => prev === updatedContent ? prev : updatedContent )
125+ if ( divRef . current && divRef . current . innerText !== updatedContent ) {
126+ divRef . current . innerText = updatedContent
127+ }
125128 if ( onContentExternalUpdate ) onContentExternalUpdate ( updatedContent )
126129 }
127130 } , [ updatedContent , onContentExternalUpdate ] )
128131
129- useEffect ( ( ) => {
130- if ( divRef . current ) {
131- divRef . current . style . height = "auto"
132- if ( onChange && isContentWithinMaxLength ( content , maxLength ) ) {
133- onChange ( content , { caretPosition : lastCaretPosition . current } )
134- }
135- }
136- } , [ content , onChange , maxLength ] )
137-
138132 useEffect ( ( ) => {
139133 if ( divRef . current && autoFocus ) {
140134 divRef . current . focus ( )
@@ -157,6 +151,12 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
157151
158152 // --- Helper functions ---
159153
154+ function fireOnChange ( newContent : string , caretPos ?: number ) {
155+ if ( onChange && isContentWithinMaxLength ( newContent , maxLength ) ) {
156+ onChange ( newContent , { caretPosition : caretPos ?? lastCaretPosition . current } )
157+ }
158+ }
159+
160160 function getCaretPositionFromElement ( editableDiv : HTMLElement ) : number {
161161 const sel = window . getSelection ( )
162162 if ( ! sel || sel . rangeCount === 0 ) return - 1
@@ -235,6 +235,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
235235
236236 const newPos = currentCaretPos + text . length
237237 lastCaretPosition . current = newPos
238+ fireOnChange ( divRef . current . innerText , newPos )
238239 }
239240
240241 function isCaretOnLastLine ( element : HTMLElement ) : boolean {
@@ -312,6 +313,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
312313 const pos = getCaretPositionFromElement ( divRef . current )
313314 if ( pos >= 0 ) lastCaretPosition . current = pos
314315 }
316+ fireOnChange ( newContent )
315317 }
316318 } else {
317319 const availableSpace = maxLength
@@ -358,6 +360,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
358360 divRef . current . innerText = previousContent
359361 setCaretAtTheEnd ( divRef . current )
360362 }
363+ fireOnChange ( previousContent )
361364 }
362365 return
363366 }
@@ -376,6 +379,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
376379 divRef . current . innerText = nextContent
377380 setCaretAtTheEnd ( divRef . current )
378381 }
382+ fireOnChange ( nextContent )
379383 }
380384 return
381385 }
@@ -397,6 +401,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
397401 e . preventDefault ( )
398402 divRef . current . innerText = ""
399403 setContent ( "" )
404+ fireOnChange ( "" , 0 )
400405 }
401406 }
402407
@@ -459,6 +464,7 @@ const ContentEditable = forwardRef<ContentEditableHandle, ContentEditableProps>(
459464 if ( pos >= 0 ) lastCaretPosition . current = pos
460465 }
461466 }
467+ fireOnChange ( processed )
462468 } }
463469 onPaste = { ( e : React . ClipboardEvent < HTMLElement > ) => {
464470 if ( disabled ) return
0 commit comments