@@ -2,12 +2,13 @@ import React, { useState, useEffect, useRef, ReactNode, RefObject } from 'react'
22import { useRouter } from 'next/router'
33import useSWR from 'swr'
44import cx from 'classnames'
5- import { ActionList , Label , Overlay } from '@primer/components'
5+ import { ActionList , DropdownMenu , Label , Overlay } from '@primer/components'
6+ import { ItemInput } from '@primer/components/lib/ActionList/List'
67
78import { useTranslation } from 'components/hooks/useTranslation'
89import { sendEvent , EventType } from 'components/lib/events'
910import { useMainContext } from './context/MainContext'
10- import { useVersion } from 'components/hooks/useVersion'
11+ import { DEFAULT_VERSION , useVersion } from 'components/hooks/useVersion'
1112import { useQuery } from 'components/hooks/useQuery'
1213import { Link } from 'components/Link'
1314import { useLanguages } from './context/LanguagesContext'
@@ -294,6 +295,8 @@ function ShowSearchResults({
294295 const { currentVersion } = useVersion ( )
295296 const { allVersions } = useMainContext ( )
296297 const searchVersion = allVersions [ currentVersion ] . versionTitle
298+ const [ selectedVersion , setSelectedVersion ] = useState < ItemInput | undefined > ( )
299+
297300 const latestVersions = new Set (
298301 Object . keys ( allVersions )
299302 . map ( ( version ) => allVersions [ version ] . latestVersion )
@@ -307,13 +310,39 @@ function ShowSearchResults({
307310 }
308311 } )
309312
313+ const searchVersions : ItemInput [ ] = versions . map ( ( { title, version } ) => {
314+ return {
315+ text : title ,
316+ key : version ,
317+ }
318+ } )
319+
310320 const redirectParams : {
311321 query : string
312322 debug ?: string
313323 } = { query }
324+
314325 if ( debug ) redirectParams . debug = JSON . stringify ( debug )
326+
315327 const redirectQuery = `?${ new URLSearchParams ( redirectParams ) . toString ( ) } `
316328
329+ useEffect ( ( ) => {
330+ if ( selectedVersion ) {
331+ const params = new URLSearchParams ( redirectParams )
332+ let asPath = `/${ router . locale } `
333+
334+ if ( params . toString ( ) ) {
335+ asPath += `?${ params . toString ( ) } `
336+ }
337+
338+ if ( selectedVersion . key === DEFAULT_VERSION ) {
339+ router . push ( `/?${ params . toString ( ) } ` , asPath )
340+ } else {
341+ router . push ( `/${ router . locale } /${ selectedVersion . key } ${ redirectQuery } ` )
342+ }
343+ }
344+ } , [ selectedVersion ] )
345+
317346 if ( results ) {
318347 if ( results . length === 0 ) {
319348 // When there results, but exactly 0, it matters if this is the overlay or not.
@@ -341,22 +370,23 @@ function ShowSearchResults({
341370 isHeaderSearch && 'overflow-auto'
342371 ) }
343372 >
344- < div className = "my-4" >
345- < p className = "mx-4" >
346- You're searching the < span className = "color-fg-attention" > { searchVersion } </ span > { ' ' }
347- version. Didn't find what you're looking for? Click a different version to try again.
373+ < div className = "mt-4 pb-6 width-full border-bottom" >
374+ < p className = { cx ( styles . searchWording , 'f6 ml-4 d-inline-block' ) } >
375+ You're searching the < strong > { searchVersion } </ strong > version.
348376 </ p >
349- { versions . map ( ( { title, version } ) => {
350- return (
351- < button key = { version } className = "btn mr-2 mt-4 ml-4" type = "button" >
352- < a href = { `/${ router . locale } /${ version } ${ redirectQuery } ` } > { title } </ a >
353- </ button >
354- )
355- } ) }
377+ < div className = "float-right mr-4" >
378+ < p className = { cx ( styles . selectWording , 'f6 d-inline-block' ) } > Select version:</ p >
379+ < DropdownMenu
380+ placeholder = { searchVersion }
381+ items = { searchVersions }
382+ selectedItem = { selectedVersion }
383+ onChange = { setSelectedVersion }
384+ />
385+ </ div >
356386 </ div >
357387 { /* We might have results AND isLoading. For example, the user typed
358388 a first word, and is now typing more. */ }
359- < p className = "d-block mt-4" >
389+ < p className = "d-block ml-4 mt-4" >
360390 { isLoading ? < span > { t ( 'loading' ) } ...</ span > : < span > </ span > }
361391 </ p >
362392
@@ -368,7 +398,10 @@ function ShowSearchResults({
368398 renderItem : ( ) => (
369399 < ActionList . Item as = "div" >
370400 < Link href = { url } className = "no-underline color-fg-default" >
371- < li data-testid = "search-result" className = { cx ( 'list-style-none' ) } >
401+ < li
402+ data-testid = "search-result"
403+ className = { cx ( 'list-style-none' , styles . resultsContainer ) }
404+ >
372405 < div className = { cx ( 'py-2 px-3' ) } >
373406 { /* Breadcrumbs in search records don't include the page title. These fields may contain <mark> elements that we need to render */ }
374407 < Label variant = "small" sx = { { bg : 'accent.emphasis' } } >
@@ -425,9 +458,6 @@ function ShowSearchResults({
425458 < div >
426459 { ! isHeaderSearch && ! isMobileSearch ? (
427460 < >
428- { /* Only if you're going to use an <Overlay> do you need
429- to specify a portal div tag. */ }
430- < div id = "__primerPortalRoot__" />
431461 < Overlay
432462 initialFocusRef = { anchorRef }
433463 returnFocusRef = { anchorRef }
@@ -436,17 +466,26 @@ function ShowSearchResults({
436466 onClickOutside = { ( ) => closeSearch ( ) }
437467 aria-labelledby = "title"
438468 sx = {
439- ( isHeaderSearch && {
440- background : 'none' ,
441- boxShadow : 'none' ,
442- position : 'static' ,
443- overflowY : 'auto' ,
444- maxHeight : '80vh' ,
445- maxWidth : '96%' ,
446- margin : '1.5em 2em 0 0.5em' ,
447- scrollbarWidth : 'none' ,
448- } ) ||
449- { }
469+ isHeaderSearch
470+ ? {
471+ background : 'none' ,
472+ boxShadow : 'none' ,
473+ position : 'static' ,
474+ overflowY : 'auto' ,
475+ maxHeight : '80vh' ,
476+ maxWidth : '96%' ,
477+ margin : '1.5em 2em 0 0.5em' ,
478+ scrollbarWidth : 'none' ,
479+ }
480+ : window . innerWidth < 1012
481+ ? {
482+ marginTop : '28rem' ,
483+ marginLeft : '5rem' ,
484+ }
485+ : {
486+ marginTop : '15rem' ,
487+ marginLeft : '5rem' ,
488+ }
450489 }
451490 >
452491 { ActionListResults }
0 commit comments