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