33 StyleSchema ,
44} from '@blocknote/core' ;
55import { useBlockNoteEditor } from '@blocknote/react' ;
6+ import type { KeyboardEvent } from 'react' ;
67import { useEffect , useRef , useState } from 'react' ;
78import { useTranslation } from 'react-i18next' ;
89import { css } from 'styled-components' ;
@@ -99,6 +100,55 @@ export const SearchPage = ({
99100 } , 100 ) ;
100101 } , [ inputRef ] ) ;
101102
103+ const closeSearch = ( insertContent : string ) => {
104+ updateInlineContent ( {
105+ type : 'interlinkingSearchInline' ,
106+ props : {
107+ disabled : true ,
108+ trigger,
109+ } ,
110+ } ) ;
111+
112+ contentRef ( null ) ;
113+ editor . focus ( ) ;
114+ editor . insertInlineContent ( [ insertContent ] ) ;
115+ } ;
116+
117+ const handleKeyDown = ( e : KeyboardEvent < HTMLInputElement > ) => {
118+ if ( e . key === 'Escape' ) {
119+ e . preventDefault ( ) ;
120+ // Keep the trigger character ('@' or '/') in the editor when closing with Escape
121+ closeSearch ( trigger ) ;
122+ } else if ( e . key === 'Backspace' && search . length === 0 ) {
123+ e . preventDefault ( ) ;
124+ closeSearch ( '' ) ;
125+ } else if ( e . key === 'ArrowDown' || e . key === 'ArrowUp' ) {
126+ // Allow arrow keys to be handled by the command menu for navigation
127+ const commandList = e . currentTarget
128+ . closest ( '.inline-content' )
129+ ?. nextElementSibling ?. querySelector ( '[cmdk-list]' ) ;
130+
131+ // Create a synthetic keyboard event for the command menu
132+ const syntheticEvent = new KeyboardEvent ( 'keydown' , {
133+ key : e . key ,
134+ bubbles : true ,
135+ cancelable : true ,
136+ } ) ;
137+ commandList ?. dispatchEvent ( syntheticEvent ) ;
138+ e . preventDefault ( ) ;
139+ } else if ( e . key === 'Enter' ) {
140+ // Handle Enter key to select the currently highlighted item
141+ const selectedItem = e . currentTarget
142+ . closest ( '.inline-content' )
143+ ?. nextElementSibling ?. querySelector (
144+ '[cmdk-item][data-selected="true"]' ,
145+ ) as HTMLElement ;
146+
147+ selectedItem ?. click ( ) ;
148+ e . preventDefault ( ) ;
149+ }
150+ } ;
151+
102152 return (
103153 < Box as = "span" $position = "relative" >
104154 < Box
@@ -124,50 +174,7 @@ export const SearchPage = ({
124174 const value = ( e . target as HTMLInputElement ) . value ;
125175 setSearch ( value ) ;
126176 } }
127- onKeyDown = { ( e ) => {
128- if (
129- ( e . key === 'Backspace' && search . length === 0 ) ||
130- e . key === 'Escape'
131- ) {
132- e . preventDefault ( ) ;
133-
134- updateInlineContent ( {
135- type : 'interlinkingSearchInline' ,
136- props : {
137- disabled : true ,
138- trigger,
139- } ,
140- } ) ;
141-
142- contentRef ( null ) ;
143- editor . focus ( ) ;
144- editor . insertInlineContent ( [ '' ] ) ;
145- } else if ( e . key === 'ArrowDown' || e . key === 'ArrowUp' ) {
146- // Allow arrow keys to be handled by the command menu for navigation
147- const commandList = e . currentTarget
148- . closest ( '.inline-content' )
149- ?. nextElementSibling ?. querySelector ( '[cmdk-list]' ) ;
150-
151- // Create a synthetic keyboard event for the command menu
152- const syntheticEvent = new KeyboardEvent ( 'keydown' , {
153- key : e . key ,
154- bubbles : true ,
155- cancelable : true ,
156- } ) ;
157- commandList ?. dispatchEvent ( syntheticEvent ) ;
158- e . preventDefault ( ) ;
159- } else if ( e . key === 'Enter' ) {
160- // Handle Enter key to select the currently highlighted item
161- const selectedItem = e . currentTarget
162- . closest ( '.inline-content' )
163- ?. nextElementSibling ?. querySelector (
164- '[cmdk-item][data-selected="true"]' ,
165- ) as HTMLElement ;
166-
167- selectedItem ?. click ( ) ;
168- e . preventDefault ( ) ;
169- }
170- } }
177+ onKeyDown = { handleKeyDown }
171178 />
172179 </ Box >
173180 < Box
@@ -224,6 +231,8 @@ export const SearchPage = ({
224231 } ,
225232 } ) ;
226233
234+ contentRef ( null ) ;
235+
227236 editor . insertInlineContent ( [
228237 {
229238 type : 'interlinkingLinkInline' ,
0 commit comments