@@ -9,19 +9,19 @@ import {
99 SentryGlobalSearch ,
1010 standardSDKSlug ,
1111} from '@sentry-internal/global-search' ;
12- import DOMPurify from 'dompurify' ;
13- import Link from 'next/link' ;
14- import { usePathname , useRouter } from 'next/navigation' ;
12+ import { usePathname } from 'next/navigation' ;
1513import algoliaInsights from 'search-insights' ;
1614
1715import { useOnClickOutside } from 'sentry-docs/clientUtils' ;
18- import { useListKeyboardNavigate } from 'sentry-docs/hooks/useListKeyboardNavigate' ;
1916import { isDeveloperDocs } from 'sentry-docs/isDeveloperDocs' ;
2017
2118import styles from './search.module.scss' ;
2219
2320import { Logo } from '../logo' ;
2421
22+ import { SearchResultItems } from './searchResultItems' ;
23+ import { relativizeUrl } from './util' ;
24+
2525// Initialize Algolia Insights
2626algoliaInsights ( 'init' , {
2727 appId : process . env . NEXT_PUBLIC_ALGOLIA_APP_ID ,
@@ -33,8 +33,6 @@ algoliaInsights('init', {
3333// treat it as a random user.
3434const randomUserToken = crypto . randomUUID ( ) ;
3535
36- const MAX_HITS = 10 ;
37-
3836// this type is not exported from the global-search package
3937type SentryGlobalSearchConfig = ConstructorParameters < typeof SentryGlobalSearch > [ 0 ] ;
4038
@@ -59,12 +57,6 @@ const userDocsSites: SentryGlobalSearchConfig = [
5957const config = isDeveloperDocs ? developerDocsSites : userDocsSites ;
6058const search = new SentryGlobalSearch ( config ) ;
6159
62- function relativizeUrl ( url : string ) {
63- return isDeveloperDocs
64- ? url
65- : url . replace ( / ^ ( h t t p s ? : \/ \/ d o c s \. s e n t r y \. i o ) (? = \/ | $ ) / , '' ) ;
66- }
67-
6860type Props = {
6961 autoFocus ?: boolean ;
7062 path ?: string ;
@@ -79,7 +71,7 @@ export function Search({path, autoFocus, searchPlatforms = [], showChatBot}: Pro
7971 const [ inputFocus , setInputFocus ] = useState ( false ) ;
8072 const [ showOffsiteResults , setShowOffsiteResults ] = useState ( false ) ;
8173 const [ loading , setLoading ] = useState ( true ) ;
82- const router = useRouter ( ) ;
74+
8375 const pathname = usePathname ( ) ;
8476
8577 const handleClickOutside = useCallback ( ( ev : MouseEvent ) => {
@@ -176,17 +168,6 @@ export function Search({path, autoFocus, searchPlatforms = [], showChatBot}: Pro
176168
177169 const totalHits = results . reduce ( ( a , x ) => a + x . hits . length , 0 ) ;
178170
179- const flatHits = results . reduce < Hit [ ] > (
180- ( items , item ) => [ ...items , ...item . hits . slice ( 0 , MAX_HITS ) ] ,
181- [ ]
182- ) ;
183-
184- const { focused} = useListKeyboardNavigate ( {
185- list : flatHits ,
186- onSelect : hit => router . push ( relativizeUrl ( hit . url ) ) ,
187- disableEventListeners : ! inputFocus ,
188- } ) ;
189-
190171 const trackSearchResultClick = useCallback ( ( hit : Hit , position : number ) : void => {
191172 try {
192173 algoliaInsights ( 'clickedObjectIDsAfterSearch' , {
@@ -306,77 +287,13 @@ export function Search({path, autoFocus, searchPlatforms = [], showChatBot}: Pro
306287 { loading && < Logo loading /> }
307288
308289 { ! loading && totalHits > 0 && (
309- < div className = { styles [ 'sgs-search-results-scroll-container' ] } >
310- { results
311- . filter ( x => x . hits . length > 0 )
312- . map ( ( result , i ) => (
313- < Fragment key = { result . site } >
314- { showOffsiteResults && (
315- < h4 className = { styles [ 'sgs-site-result-heading' ] } >
316- From { result . name }
317- </ h4 >
318- ) }
319- < ul
320- className = { `${ styles [ 'sgs-hit-list' ] } ${ i === 0 ? '' : styles [ 'sgs-offsite' ] } ` }
321- >
322- { result . hits . slice ( 0 , MAX_HITS ) . map ( ( hit , index ) => (
323- < li
324- key = { hit . id }
325- className = { `${ styles [ 'sgs-hit-item' ] } ${
326- focused ?. id === hit . id ? styles [ 'sgs-hit-focused' ] : ''
327- } `}
328- ref = {
329- // Scroll to element on focus
330- hit . id === focused ?. id
331- ? el => el ?. scrollIntoView ( { block : 'nearest' } )
332- : undefined
333- }
334- >
335- < Link
336- href = { relativizeUrl ( hit . url ) }
337- onClick = { e => handleSearchResultClick ( e , hit , index ) }
338- >
339- { hit . title && (
340- < h6 >
341- < span
342- dangerouslySetInnerHTML = { {
343- __html : DOMPurify . sanitize ( hit . title , {
344- ALLOWED_TAGS : [ 'mark' ] ,
345- } ) ,
346- } }
347- />
348- </ h6 >
349- ) }
350- { hit . text && (
351- < span
352- dangerouslySetInnerHTML = { {
353- __html : DOMPurify . sanitize ( hit . text , {
354- ALLOWED_TAGS : [ 'mark' ] ,
355- } ) ,
356- } }
357- />
358- ) }
359- { hit . context && (
360- < div className = { styles [ 'sgs-hit-context' ] } >
361- { hit . context . context1 && (
362- < div className = { styles [ 'sgs-hit-context-left' ] } >
363- { hit . context . context1 }
364- </ div >
365- ) }
366- { hit . context . context2 && (
367- < div className = { styles [ 'sgs-hit-context-right' ] } >
368- { hit . context . context2 }
369- </ div >
370- ) }
371- </ div >
372- ) }
373- </ Link >
374- </ li >
375- ) ) }
376- </ ul >
377- </ Fragment >
378- ) ) }
379- </ div >
290+ < SearchResultItems
291+ results = { results }
292+ onSearchResultClick = { ( { event, hit, position} ) =>
293+ handleSearchResultClick ( event , hit , position )
294+ }
295+ showOffsiteResults = { showOffsiteResults }
296+ />
380297 ) }
381298
382299 { ! loading && totalHits === 0 && (
0 commit comments