import clsx from 'clsx' ; import { useRouter } from 'next/router' ; import { HTMLProps , useEffect , useState } from 'react' ; import { Search } from '@/components/icons' ; import { SEARCH_QUERY_PARAM } from '@/constants/query' ; import { createUrl } from '@/utils/url' ; interface Props extends HTMLProps < HTMLFormElement > { /**
     * Render large variant of search input with a larger font size and search icon.
     */ large ? : boolean ; } /**
 * Search input component. This renders an input field with a underline and
 * magnifying glass icon to the right of the component. When the user submits a
 * query, it redirects them to the search page with search results for the
 * query.
 */ export function SearchInput ( { large , ... props } ) { const router = useRouter ( ) ; const [ localQuery , setLocalQuery ] = useState ( ( ) => { const params = createUrl ( router . asPath ) . searchParams ; return params . get ( SEARCH_QUERY_PARAM ) ?? '' ; } ) ; useEffect ( ( ) => { function clearQuery ( path ) { if ( router . asPath . includes ( '/search' ) && ! path . includes ( '/search' ) ) { setLocalQuery ( '' ) ; } } router . events . on ( 'routeChangeComplete' , clearQuery ) ; return ( ) => router . events . off ( 'routeChangeComplete' , clearQuery ) ; } , [ router ] ) ; const iconClassName = clsx ( 'h-5 w-5' , large && 'h-[1.375rem] w-[1.375rem]' ) ; /**
     * Performs a search query on form submission. If the user is on the search
     * page, this runs the query through the search engine. Otherwise, it
     * redirects to the search page with the query added to the URL.
     */ function submitForm ( searchQuery ) { const query = searchQuery . trim ( ) ; if ( ! query ) { return ; } const url = createUrl ( '/search.html' , window . location . origin ) ; url . searchParams . set ( SEARCH_QUERY_PARAM , query ) ; window . location . href = url . href ; } return ( < form data - testid = "searchInputForm" className = { clsx ( 'flex flex-auto items-center' , 'border-b-2 border-black' , large && 'text-xl' ) } onSubmit = { ( event ) => { event . preventDefault ( ) ; submitForm ( localQuery ) ; } } { ... props } > < input aria - label = "Search input for searching napari.org site." data - testid = "searchInputTextInput" className = { clsx ( 'flex flex-auto' , 'border-none outline-none' , 'bg-transparent' , 'w-0' ) } onChange = { ( event ) => { const { value } = event . target ; setLocalQuery ( value ) ; } } value = { localQuery } / > < button aria - label = "Submit search query" onClick = { ( ) => submitForm ( localQuery ) } type = "button" > < Search className = { iconClassName } /> < /button> < /form>); }