@@ -243,6 +243,7 @@ class ReactTextareaAutocomplete extends React.Component<
243243 }
244244
245245 if ( oldValue !== value && this . lastValueBubbledEvent !== value ) {
246+ this . lastTrigger = 0 ;
246247 this . _changeHandler ( ) ;
247248 }
248249 }
@@ -361,6 +362,11 @@ class ReactTextareaAutocomplete extends React.Component<
361362 dataLoading : false
362363 } ,
363364 ( ) => {
365+ const insertedTrigger = this . tokenRegExpEnding . exec ( newTokenString ) ;
366+ const insertedTriggerModifier = insertedTrigger
367+ ? insertedTrigger [ 0 ] . length
368+ : 1 ;
369+ this . lastTrigger = newCaretPosition - insertedTriggerModifier ;
364370 this . textareaRef . value = newValue ;
365371 this . _changeHandler ( ) ;
366372
@@ -532,6 +538,22 @@ class ReactTextareaAutocomplete extends React.Component<
532538 . map ( a => `\\${ a } ` )
533539 . join ( "|" ) } )((?:(?!\\1)[^\\s])*$)`
534540 ) ;
541+
542+ this . tokenRegExpEnding = new RegExp (
543+ `(${ Object . keys ( trigger )
544+ // the sort is important for multi-char combos as "/kick", "/"
545+ . sort ( ( a , b ) => {
546+ if ( a < b ) {
547+ return 1 ;
548+ }
549+ if ( a > b ) {
550+ return - 1 ;
551+ }
552+ return 0 ;
553+ } )
554+ . map ( a => `\\${ a } ` )
555+ . join ( "|" ) } )$`
556+ ) ;
535557 } ;
536558
537559 /**
@@ -622,11 +644,28 @@ class ReactTextareaAutocomplete extends React.Component<
622644 value
623645 } ) ;
624646
625- let tokenMatch = this . tokenRegExp . exec ( value . slice ( 0 , selectionEnd ) ) ;
647+ const cleanLastTrigger = ( ) => {
648+ this . lastTrigger = selectionEnd - 1 ;
649+ } ;
650+
651+ if ( selectionEnd <= this . lastTrigger ) {
652+ cleanLastTrigger ( ) ;
653+ }
654+
655+ const affectedTextareaValue = value . slice ( this . lastTrigger , selectionEnd ) ;
656+
657+ let tokenMatch = this . tokenRegExp . exec ( affectedTextareaValue ) ;
626658 let lastToken = tokenMatch && tokenMatch [ 0 ] ;
627659
628660 let currentTrigger = ( tokenMatch && tokenMatch [ 1 ] ) || null ;
629661
662+ // with this approach we want to know if the user just inserted a new trigger sequence
663+ const isNewTrigger = this . tokenRegExpEnding . exec ( affectedTextareaValue ) ;
664+
665+ if ( isNewTrigger ) {
666+ cleanLastTrigger ( ) ;
667+ }
668+
630669 /*
631670 if we lost the trigger token or there is no following character we want to close
632671 the autocomplete
@@ -650,9 +689,8 @@ class ReactTextareaAutocomplete extends React.Component<
650689 */
651690 if (
652691 currentTrigger &&
653- value [ tokenMatch . index - 1 ] &&
654- ( trigger [ currentTrigger ] . afterWhitespace &&
655- ! value [ tokenMatch . index - 1 ] . match ( / \s / ) )
692+ trigger [ currentTrigger ] . afterWhitespace &&
693+ value [ selectionEnd - 2 ] !== " "
656694 ) {
657695 this . _closeAutocomplete ( ) ;
658696 return ;
@@ -797,6 +835,11 @@ class ReactTextareaAutocomplete extends React.Component<
797835
798836 lastValueBubbledEvent : string ;
799837
838+ tokenRegExpEnding : RegExp ;
839+
840+ // Last trigger index, to know when user selected the item and we should stop showing the autocomplete
841+ lastTrigger : number = 0 ;
842+
800843 render ( ) {
801844 const {
802845 loadingComponent : Loader ,
0 commit comments