@@ -9,27 +9,30 @@ import { defaultKeymap } from '@codemirror/commands';
99import { syntaxHighlighting , defaultHighlightStyle , HighlightStyle , StreamLanguage } from '@codemirror/language' ;
1010import { autocompletion , CompletionContext } from '@codemirror/autocomplete' ;
1111import { tags , styleTags } from '@lezer/highlight' ;
12+ import { isEqual } from 'lodash' ;
1213
13- // Define the autocomplete function
14- const myCompletions = ( context ) => {
15- let word = context . matchBefore ( / { { \w * $ / ) ;
16- if ( ! word ) return null ;
17-
18- return {
19- from : word . from ,
20- options : [
21- { label : '{{example1}}' , type : 'keyword' } ,
22- { label : '{{example2}}' , type : 'variable' } ,
23- { label : '{{example3}}' , type : 'text' } ,
24- ] ,
14+ // Function to dynamically generate autocomplete options
15+ const createAutocompleteSource = ( options ) => {
16+ return ( context ) => {
17+ let word = context . matchBefore ( / \{ \{ \w * $ / ) ;
18+ if ( ! word ) return null ;
19+
20+ return {
21+ from : word . from ,
22+ options : options . map ( ( option ) => ( { label : `{{${ option } }}` , type : 'keyword' } ) ) ,
23+ } ;
2524 } ;
2625} ;
2726
28- // Configure the autocomplete extension
29- const myAutocomplete = autocompletion ( {
30- override : [ myCompletions ] ,
31- activateOnTyping : true ,
32- } ) ;
27+ // Create a Compartment for autocomplete
28+ const autocompleteCompartment = new Compartment ( ) ;
29+
30+ // Function to update autocomplete options
31+ const updateAutocompleteOptions = ( view , newOptions ) => {
32+ view . dispatch ( {
33+ effects : autocompleteCompartment . reconfigure ( autocompletion ( { override : [ createAutocompleteSource ( newOptions ) ] } ) ) ,
34+ } ) ;
35+ } ;
3336
3437// Custom styles to hide scrollbar
3538const hideScrollbar = EditorView . theme ( {
@@ -94,11 +97,16 @@ const highlightStyle = EditorView.baseTheme({
9497 } ,
9598} ) ;
9699
97- export const TextEditor = ( { id , placeHolder, onChangeHandler, name , value, disableState } ) => {
100+ export const TextEditor = ( { placeHolder, onChangeHandler, value, disableState, completionOptions , styles } ) => {
98101 const editor1 = useRef ( ) ;
99102 const [ view , setView ] = useState ( null ) ;
103+ const [ dynamicOptions , setDynamicOptions ] = useState ( [ ] ) ;
100104
101105 if ( view ) {
106+ if ( ! isEqual ( dynamicOptions , completionOptions ) ) {
107+ updateAutocompleteOptions ( view , completionOptions ) ;
108+ setDynamicOptions ( completionOptions ) ;
109+ }
102110 if ( value != view . state . doc . toString ( ) ) {
103111 view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : value } } ) ;
104112 }
@@ -116,7 +124,7 @@ export const TextEditor = ({ id, placeHolder, onChangeHandler, name, value, disa
116124 extensions : [
117125 //EditorView.lineWrapping,
118126 placeholder ( placeHolder ) ,
119- myAutocomplete ,
127+ // myAutocomplete,
120128 //basicSetup,
121129 keymap . of ( [ defaultKeymap , indentWithTab ] ) ,
122130 onUpdate ,
@@ -126,6 +134,7 @@ export const TextEditor = ({ id, placeHolder, onChangeHandler, name, value, disa
126134 rebindEnterKey ,
127135 highlightPlugin ,
128136 highlightStyle ,
137+ autocompleteCompartment . of ( autocompletion ( { override : [ createAutocompleteSource ( dynamicOptions ) ] } ) ) ,
129138 ] ,
130139 } ) ;
131140
@@ -139,8 +148,8 @@ export const TextEditor = ({ id, placeHolder, onChangeHandler, name, value, disa
139148 } , [ ] ) ;
140149
141150 const mainStyles =
142- 'nodrag nowheel block w-3/4 rounded border border-slate-700 bg-background-light p-2.5 text-sm outline-none' ;
151+ 'nodrag nowheel block rounded border border-slate-700 bg-background-light p-2.5 text-sm outline-none' ;
143152 const intentStyles = disableState ? 'cursor-not-allowed text-slate-400' : 'text-slate-900' ;
144153
145- return < div ref = { editor1 } className = { `${ mainStyles } ${ intentStyles } ` } > </ div > ;
154+ return < div ref = { editor1 } className = { `${ mainStyles } ${ intentStyles } ${ styles } ` } > </ div > ;
146155} ;
0 commit comments