@@ -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 { useKeyboardNavigate } from 'sentry-docs/hooks/useKeyboardNavigate' ;
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,16 +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} = useKeyboardNavigate ( {
185- list : flatHits ,
186- onSelect : hit => router . push ( relativizeUrl ( hit . url ) ) ,
187- } ) ;
188-
189171 const trackSearchResultClick = useCallback ( ( hit : Hit , position : number ) : void => {
190172 try {
191173 algoliaInsights ( 'clickedObjectIDsAfterSearch' , {
@@ -305,77 +287,13 @@ export function Search({path, autoFocus, searchPlatforms = [], showChatBot}: Pro
305287 { loading && < Logo loading /> }
306288
307289 { ! loading && totalHits > 0 && (
308- < div className = { styles [ 'sgs-search-results-scroll-container' ] } >
309- { results
310- . filter ( x => x . hits . length > 0 )
311- . map ( ( result , i ) => (
312- < Fragment key = { result . site } >
313- { showOffsiteResults && (
314- < h4 className = { styles [ 'sgs-site-result-heading' ] } >
315- From { result . name }
316- </ h4 >
317- ) }
318- < ul
319- className = { `${ styles [ 'sgs-hit-list' ] } ${ i === 0 ? '' : styles [ 'sgs-offsite' ] } ` }
320- >
321- { result . hits . slice ( 0 , MAX_HITS ) . map ( ( hit , index ) => (
322- < li
323- key = { hit . id }
324- className = { `${ styles [ 'sgs-hit-item' ] } ${
325- focused ?. id === hit . id ? styles [ 'sgs-hit-focused' ] : ''
326- } `}
327- ref = {
328- // Scroll to element on focus
329- hit . id === focused ?. id
330- ? el => el ?. scrollIntoView ( { block : 'nearest' } )
331- : undefined
332- }
333- >
334- < Link
335- href = { relativizeUrl ( hit . url ) }
336- onClick = { e => handleSearchResultClick ( e , hit , index ) }
337- >
338- { hit . title && (
339- < h6 >
340- < span
341- dangerouslySetInnerHTML = { {
342- __html : DOMPurify . sanitize ( hit . title , {
343- ALLOWED_TAGS : [ 'mark' ] ,
344- } ) ,
345- } }
346- />
347- </ h6 >
348- ) }
349- { hit . text && (
350- < span
351- dangerouslySetInnerHTML = { {
352- __html : DOMPurify . sanitize ( hit . text , {
353- ALLOWED_TAGS : [ 'mark' ] ,
354- } ) ,
355- } }
356- />
357- ) }
358- { hit . context && (
359- < div className = { styles [ 'sgs-hit-context' ] } >
360- { hit . context . context1 && (
361- < div className = { styles [ 'sgs-hit-context-left' ] } >
362- { hit . context . context1 }
363- </ div >
364- ) }
365- { hit . context . context2 && (
366- < div className = { styles [ 'sgs-hit-context-right' ] } >
367- { hit . context . context2 }
368- </ div >
369- ) }
370- </ div >
371- ) }
372- </ Link >
373- </ li >
374- ) ) }
375- </ ul >
376- </ Fragment >
377- ) ) }
378- </ div >
290+ < SearchResultItems
291+ results = { results }
292+ onSearchResultClick = { ( { event, hit, position} ) =>
293+ handleSearchResultClick ( event , hit , position )
294+ }
295+ showOffsiteResults = { showOffsiteResults }
296+ />
379297 ) }
380298
381299 { ! loading && totalHits === 0 && (
0 commit comments