11// This example is for an Editor with `ReactEditor` and `HistoryEditor`
2- import { Descendant , Editor } from "slate" ;
3- import { Editable , RenderPlaceholderProps , Slate } from "slate-react" ;
4- import {
5- useCallback ,
6- useEffect ,
7- useMemo ,
8- useRef ,
9- useState ,
10- TextareaHTMLAttributes ,
11- } from "react" ;
12- import { useAutosuggestions } from "../../hooks/use-autosuggestions" ;
13- import { AutosuggestionState } from "../../types/autosuggestion-state" ;
14- import { clearAutocompletionsFromEditor } from "../../lib/slatejs-edits/clear-autocompletions" ;
15- import { addAutocompletionsToEditor } from "../../lib/slatejs-edits/add-autocompletions" ;
16- import { useCopilotTextareaEditor } from "../../hooks/use-copilot-textarea-editor" ;
17- import { renderElement } from "./render-element" ;
18- import { useMakeAutosuggestionFunction } from "../../hooks" ;
2+ import { useMakeAutosuggestionFunction as useMakeStandardAutosuggestionFunction } from "../../hooks" ;
193import {
204 AutosuggestionsConfig ,
215 defaultAutosuggestionsConfig ,
226} from "../../types/autosuggestions-config" ;
23- import { makeRenderPlaceholderFunction } from "./render-placeholder" ;
247import {
25- getFullEditorTextWithNewlines ,
26- getTextAroundCursor ,
27- } from "../../lib/get-text-around-cursor" ;
28- import { replaceEditorText } from "../../lib/slatejs-edits/replace-text" ;
8+ BaseCopilotTextarea ,
9+ BaseCopilotTextareaProps ,
10+ } from "./base-copilot-textarea/base-copilot-textarea" ;
2911
30- export interface CopilotTextareaProps
31- extends TextareaHTMLAttributes < HTMLDivElement > {
32- placeholderStyle ?: React . CSSProperties ;
33- value ?: string ;
34- onValueChange ?: ( value : string ) => void ;
12+ export interface CopilotTextareaProps extends BaseCopilotTextareaProps {
3513 autosuggestionsConfig : Partial < AutosuggestionsConfig > ;
3614}
3715
@@ -41,30 +19,7 @@ export function CopilotTextarea(props: CopilotTextareaProps): JSX.Element {
4119 ...props . autosuggestionsConfig ,
4220 } ;
4321
44- // separate into TextareaHTMLAttributes<HTMLDivElement> and CopilotTextareaProps
45- const {
46- placeholderStyle,
47- value,
48- onValueChange,
49- autosuggestionsConfig : autosuggestionsConfigFromProps ,
50- ...textareaLikeProps
51- } = props ;
52-
53- const valueOnInitialRender = useMemo ( ( ) => props . value ?? "" , [ ] ) ;
54- const [ lastKnownFullEditorText , setLastKnownFullEditorText ] =
55- useState ( valueOnInitialRender ) ;
56-
57- const initialValue : Descendant [ ] = useMemo ( ( ) => {
58- return [
59- {
60- type : "paragraph" ,
61- children : [ { text : valueOnInitialRender } ] ,
62- } ,
63- ] ;
64- } , [ valueOnInitialRender ] ) ;
65-
66- const editor = useCopilotTextareaEditor ( ) ;
67- const autosuggestionsFunction = useMakeAutosuggestionFunction (
22+ const autosuggestionsFunction = useMakeStandardAutosuggestionFunction (
6823 autosuggestionsConfig . textareaPurpose ,
6924 autosuggestionsConfig . apiEndpoint ,
7025 autosuggestionsConfig . makeSystemMessage ,
@@ -73,85 +28,11 @@ export function CopilotTextarea(props: CopilotTextareaProps): JSX.Element {
7328 autosuggestionsConfig . disableWhenEmpty
7429 ) ;
7530
76- const insertText = useCallback (
77- ( autosuggestion : AutosuggestionState ) => {
78- Editor . insertText ( editor , autosuggestion . text , {
79- at : autosuggestion . point ,
80- } ) ;
81- } ,
82- [ editor ]
83- ) ;
84- const {
85- currentAutocompleteSuggestion,
86- onChangeHandler : onChangeHandlerForAutocomplete ,
87- onKeyDownHandler : onKeyDownHandlerForAutocomplete ,
88- } = useAutosuggestions (
89- autosuggestionsConfig . debounceTime ,
90- autosuggestionsConfig . acceptAutosuggestionKey ,
91- autosuggestionsFunction ,
92- insertText
93- ) ;
94-
95- // sync autosuggestions state with the editor
96- useEffect ( ( ) => {
97- clearAutocompletionsFromEditor ( editor ) ;
98- if ( currentAutocompleteSuggestion ) {
99- addAutocompletionsToEditor (
100- editor ,
101- currentAutocompleteSuggestion . text ,
102- currentAutocompleteSuggestion . point
103- ) ;
104- }
105- } , [ currentAutocompleteSuggestion ] ) ;
106-
107- const renderElementMemoized = useCallback ( renderElement , [ ] ) ;
108- const renderPlaceholderMemoized = useMemo ( ( ) => {
109- // For some reason slateJS specifies a top value of 0, which makes for strange styling. We override this here.
110- const placeholderStyleSlatejsOverrides : React . CSSProperties = {
111- top : undefined ,
112- } ;
113-
114- const placeholderStyleAugmented : React . CSSProperties = {
115- ...placeholderStyleSlatejsOverrides ,
116- ...props . placeholderStyle ,
117- } ;
118-
119- return makeRenderPlaceholderFunction ( placeholderStyleAugmented ) ;
120- } , [ props . placeholderStyle ] ) ;
121-
122- // update the editor text, but only when the value changes from outside the component
123- useEffect ( ( ) => {
124- if ( props . value === lastKnownFullEditorText ) {
125- return ;
126- }
127-
128- setLastKnownFullEditorText ( props . value ?? "" ) ;
129- replaceEditorText ( editor , props . value ?? "" ) ;
130- } , [ props . value ] ) ;
131-
13231 return (
133- // Add the editable component inside the context.
134- < Slate
135- editor = { editor }
136- initialValue = { initialValue }
137- onChange = { ( value ) => {
138- const newEditorState = getTextAroundCursor ( editor ) ;
139-
140- const fullEditorText = newEditorState
141- ? newEditorState . textBeforeCursor + newEditorState . textAfterCursor
142- : getFullEditorTextWithNewlines ( editor ) ; // we don't double-parse the editor. When `newEditorState` is null, we didn't parse the editor yet.
143-
144- setLastKnownFullEditorText ( fullEditorText ) ;
145- onChangeHandlerForAutocomplete ( newEditorState ) ;
146- props . onValueChange ?.( fullEditorText ) ;
147- } }
148- >
149- < Editable
150- renderElement = { renderElementMemoized }
151- renderPlaceholder = { renderPlaceholderMemoized }
152- onKeyDown = { onKeyDownHandlerForAutocomplete }
153- { ...textareaLikeProps }
154- />
155- </ Slate >
32+ < BaseCopilotTextarea
33+ { ...props }
34+ autosuggestionsConfig = { autosuggestionsConfig }
35+ autosuggestionsFunction = { autosuggestionsFunction }
36+ />
15637 ) ;
15738}
0 commit comments