11// This example is for an Editor with `ReactEditor` and `HistoryEditor`
22import { Descendant , Editor } from "slate" ;
33import { Editable , RenderPlaceholderProps , Slate } from "slate-react" ;
4- import { useCallback , useEffect , useMemo , useRef } from "react" ;
4+ import { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
55import { useAutosuggestions } from "../../hooks/use-autosuggestions" ;
66import { AutosuggestionState } from "../../types/autosuggestion-state" ;
77import { clearAutocompletionsFromEditor } from "../../lib/slatejs-edits/clear-autocompletions" ;
@@ -14,7 +14,11 @@ import {
1414 defaultAutosuggestionsConfig ,
1515} from "../../types/autosuggestions-config" ;
1616import { makeRenderPlaceholderFunction } from "./render-placeholder" ;
17- import { getFullEditorTextWithNewlines , getTextAroundCursor } from "../../lib/get-text-around-cursor" ;
17+ import {
18+ getFullEditorTextWithNewlines ,
19+ getTextAroundCursor ,
20+ } from "../../lib/get-text-around-cursor" ;
21+ import { replaceEditorText } from "../../lib/slatejs-edits/replace-text" ;
1822
1923export interface CopilotTextareaProps {
2024 className ?: string ;
@@ -32,6 +36,9 @@ export function CopilotTextarea(props: CopilotTextareaProps): JSX.Element {
3236 } ;
3337
3438 const valueOnInitialRender = useMemo ( ( ) => props . value ?? "" , [ ] ) ;
39+ const [ lastKnownFullEditorText , setLastKnownFullEditorText ] =
40+ useState ( valueOnInitialRender ) ;
41+
3542 const initialValue : Descendant [ ] = useMemo ( ( ) => {
3643 return [
3744 {
@@ -97,17 +104,27 @@ export function CopilotTextarea(props: CopilotTextareaProps): JSX.Element {
97104 return makeRenderPlaceholderFunction ( placeholderStyleAugmented ) ;
98105 } , [ props . placeholderStyle ] ) ;
99106
107+ // update the editor text, but only when the value changes from outside the component
108+ useEffect ( ( ) => {
109+ if ( props . value === lastKnownFullEditorText ) {
110+ return ;
111+ }
112+
113+ setLastKnownFullEditorText ( props . value ?? "" ) ;
114+ replaceEditorText ( editor , props . value ?? "" ) ;
115+ } , [ props . value ] ) ;
116+
100117 return (
101118 // Add the editable component inside the context.
102119 < Slate
103120 editor = { editor }
104121 initialValue = { initialValue }
105122 onChange = { ( value ) => {
106- const newEditorState = getTextAroundCursor ( editor )
123+ const newEditorState = getTextAroundCursor ( editor ) ;
107124
108125 const fullEditorText = newEditorState
109- ? newEditorState . textBeforeCursor + newEditorState . textAfterCursor
110- : getFullEditorTextWithNewlines ( editor ) ; // we don't double-parse the editor. When `newEditorState` is null, we didn't parse the editor yet.
126+ ? newEditorState . textBeforeCursor + newEditorState . textAfterCursor
127+ : getFullEditorTextWithNewlines ( editor ) ; // we don't double-parse the editor. When `newEditorState` is null, we didn't parse the editor yet.
111128
112129 setLastKnownFullEditorText ( fullEditorText ) ;
113130 onChangeHandlerForAutocomplete ( newEditorState ) ;
0 commit comments