@@ -171,7 +171,7 @@ const toolbarOptions = [
171171] ;
172172
173173const childrenMap = {
174- value :stringExposingStateControl ( "value" ) ,
174+ value :stringExposingStateControl ( "value" ) ,
175175delta :stringExposingStateControl ( "delta" ) ,
176176hideToolbar :BoolControl ,
177177readOnly :BoolControl ,
@@ -195,7 +195,7 @@ interface IProps {
195195hideToolbar :boolean ;
196196readOnly :boolean ;
197197autoHeight :boolean ;
198- onChange :( html :string , deltaJSON :string , text :string ) => void ;
198+ onChange :( html :string , deltaJSON :string , text :string ) => void ;
199199$style :RichTextEditorStyleType ;
200200contentScrollBar :boolean ;
201201tabIndex ?:number ;
@@ -209,6 +209,13 @@ function RichTextEditor(props: IProps) {
209209const wrapperRef = useRef < HTMLDivElement > ( null ) ;
210210const editorRef = useRef < ReactQuill > ( null ) ;
211211
212+ // know exactly when the editor mounts
213+ const [ editorReady , setEditorReady ] = useState ( false ) ;
214+ const setEditorRef = ( node :ReactQuill | null ) => {
215+ ( editorRef as any ) . current = node as any ;
216+ setEditorReady ( ! ! node ) ;
217+ } ;
218+
212219const getQuill = ( ) => ( editorRef . current as any ) ?. getEditor ?.( ) ;
213220
214221const tryParseDelta = ( v :unknown ) => {
@@ -251,7 +258,7 @@ function RichTextEditor(props: IProps) {
251258( editor . scroll . domNode as HTMLElement ) . tabIndex = props . tabIndex ;
252259}
253260}
254- } , [ props . tabIndex , key ] ) ;
261+ } , [ props . tabIndex , key ] ) ;
255262
256263const contains = ( parent :HTMLElement , descendant :HTMLElement ) => {
257264try {
@@ -267,11 +274,7 @@ function RichTextEditor(props: IProps) {
267274
268275useEffect ( ( ) => {
269276const q = getQuill ( ) ;
270-
271277if ( ! q ) {
272- const v = props . value ?? "" ;
273- const looksHtml = / < \/ ? [ a - z ] [ \s \S ] * > / i. test ( v ) ;
274- setContent ( looksHtml ?v :`<p class="">${ v } </p>` ) ;
275278return ;
276279}
277280
@@ -282,12 +285,11 @@ function RichTextEditor(props: IProps) {
282285setContent ( html ) ;
283286return ;
284287}
285-
286288const v = props . value ?? "" ;
287289const looksHtml = / < \/ ? [ a - z ] [ \s \S ] * > / i. test ( v ) ;
288290const html = looksHtml ?v :`<p class="">${ v } </p>` ;
289291setContent ( html ) ;
290- } , [ props . value ] ) ;
292+ } , [ props . value , editorReady ] ) ;
291293
292294
293295const handleClickWrapper = ( e :React . MouseEvent < HTMLDivElement > ) => {
@@ -316,7 +318,7 @@ function RichTextEditor(props: IProps) {
316318< Suspense fallback = { < Skeleton /> } >
317319< ReactQuillEditor
318320key = { key }
319- ref = { editorRef }
321+ ref = { setEditorRef }
320322bounds = { `#${ id } ` }
321323modules = { {
322324toolbar :JSON . parse ( props . toolbar ) ,
@@ -339,17 +341,26 @@ function RichTextEditor(props: IProps) {
339341}
340342
341343const RichTextEditorCompBase = new UICompBuilder ( childrenMap , ( props ) => {
344+ const propsRef = useRef ( props ) ;
345+ propsRef . current = props ;
346+
342347const debouncedOnChangeRef = useRef (
343348debounce ( ( html :string , deltaJSON :string , text :string ) => {
344- props . value . onChange ( html ) ;
345- props . delta . onChange ( deltaJSON ) ;
346- props . onEvent ( "change" ) ;
347- } , 1000 )
349+ propsRef . current . value . onChange ( html ) ;
350+ propsRef . current . delta . onChange ( deltaJSON ) ;
351+ propsRef . current . onEvent ( "change" ) ;
352+ } , 500 )
348353) ;
349354
350- const handleChange = ( html :string , deltaJSON :string , text :string ) => {
351- debouncedOnChangeRef . current ?.( html , deltaJSON , text ) ;
355+ useEffect ( ( ) => {
356+ return ( ) => {
357+ debouncedOnChangeRef . current ?. cancel ( ) ;
352358} ;
359+ } , [ ] ) ;
360+
361+ const handleChange = ( html :string , deltaJSON :string , text :string ) => {
362+ debouncedOnChangeRef . current ?.( html , deltaJSON , text ) ;
363+ } ;
353364
354365return (
355366< RichTextEditor