@@ -15,6 +15,10 @@ export const useMentions = () => {
15
15
) ;
16
16
const [ mentionSearchText , setMentionSearchText ] = useState < string > ( '' ) ;
17
17
const [ mentions , setMentions ] = useState < Mention [ ] > ( [ ] ) ;
18
+ const [ wasDismissedByEscape , setWasDismissedByEscape ] = useState ( false ) ;
19
+ const [ lastDismissedTriggerIndex , setLastDismissedTriggerIndex ] = useState <
20
+ number | null
21
+ > ( null ) ;
18
22
19
23
const handleMention = ( oldText : string , newText : string ) => {
20
24
// Find cursor position by comparing old and new text
@@ -28,6 +32,25 @@ export const useMentions = () => {
28
32
}
29
33
}
30
34
35
+ // Clear escape state when starting a new word
36
+ if (
37
+ oldText . length < newText . length &&
38
+ newText [ cursorPosition - 1 ] === ' '
39
+ ) {
40
+ setWasDismissedByEscape ( false ) ;
41
+ }
42
+
43
+ // Clear escape state when deleting past the escaped trigger
44
+ if ( wasDismissedByEscape && lastDismissedTriggerIndex !== null ) {
45
+ if (
46
+ oldText . length > newText . length &&
47
+ cursorPosition <= lastDismissedTriggerIndex
48
+ ) {
49
+ setWasDismissedByEscape ( false ) ;
50
+ setLastDismissedTriggerIndex ( null ) ;
51
+ }
52
+ }
53
+
31
54
// Check if we're deleting a trigger symbol
32
55
if ( newText . length < oldText . length && showMentionPopup ) {
33
56
const deletedChar = oldText [ cursorPosition ] ;
@@ -55,9 +78,15 @@ export const useMentions = () => {
55
78
) ;
56
79
const hasSpace = textBetweenTriggerAndCursor . includes ( ' ' ) ;
57
80
58
- // Only show popup if we're right after the trigger or actively searching
81
+ // Only show popup if:
82
+ // 1. We're right after the trigger or actively searching
83
+ // 2. AND it wasn't dismissed by escape for this trigger index
84
+ // 3. OR it's a new trigger position different from the dismissed one
85
+ const isDismissedTrigger =
86
+ wasDismissedByEscape && lastTriggerIndex === lastDismissedTriggerIndex ;
59
87
if (
60
88
! hasSpace &&
89
+ ! isDismissedTrigger &&
61
90
( cursorPosition === lastTriggerIndex + 1 ||
62
91
( cursorPosition > lastTriggerIndex && ! afterCursor . includes ( ' ' ) ) )
63
92
) {
@@ -109,10 +138,18 @@ export const useMentions = () => {
109
138
setShowMentionPopup ( false ) ;
110
139
setMentionStartIndex ( null ) ;
111
140
setMentionSearchText ( '' ) ;
141
+ setWasDismissedByEscape ( false ) ;
142
+ setLastDismissedTriggerIndex ( null ) ;
112
143
113
144
return newText ;
114
145
} ;
115
146
147
+ const handleMentionEscape = ( ) => {
148
+ setShowMentionPopup ( false ) ;
149
+ setWasDismissedByEscape ( true ) ;
150
+ setLastDismissedTriggerIndex ( mentionStartIndex ) ;
151
+ } ;
152
+
116
153
return {
117
154
mentions,
118
155
setMentions,
@@ -122,5 +159,6 @@ export const useMentions = () => {
122
159
handleSelectMention,
123
160
showMentionPopup,
124
161
setShowMentionPopup,
162
+ handleMentionEscape,
125
163
} ;
126
164
} ;
0 commit comments