diff --git a/src/components/quicklaunch.jsx b/src/components/quicklaunch.jsx index 23f7cef9b..aaa40493c 100644 --- a/src/components/quicklaunch.jsx +++ b/src/components/quicklaunch.jsx @@ -120,7 +120,7 @@ export default function QuickLaunch({ }); if (showSearchSuggestions && searchProvider.suggestionUrl) { - if (searchString.trim() !== searchSuggestions[0]) { + if (searchString.trim() !== searchSuggestions[0]?.trim()) { fetch( `/api/search/searchSuggestion?query=${encodeURIComponent(searchString)}&providerName=${ searchProvider.name ?? "Custom" diff --git a/src/components/widgets/search/search.jsx b/src/components/widgets/search/search.jsx index 6a634308a..c9391d355 100644 --- a/src/components/widgets/search/search.jsx +++ b/src/components/widgets/search/search.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, Fragment } from "react"; +import { useState, useEffect, Fragment } from "react"; import { useTranslation } from "next-i18next"; import { FiSearch } from "react-icons/fi"; import { SiDuckduckgo, SiMicrosoftbing, SiGoogle, SiBaidu, SiBrave } from "react-icons/si"; @@ -119,20 +119,27 @@ export default function Search({ options }) { }; }, [selectedProvider, options, query, searchSuggestions]); - const submitCallback = useCallback( - (value) => { - const q = encodeURIComponent(value); - const { url } = selectedProvider; - if (url) { - window.open(`${url}${q}`, options.target || "_blank"); - } else { - window.open(`${options.url}${q}`, options.target || "_blank"); - } + let currentSuggestion; - setQuery(""); - }, - [selectedProvider, options.url, options.target], - ); + function doSearch(value) { + const q = encodeURIComponent(value); + const { url } = selectedProvider; + if (url) { + window.open(`${url}${q}`, options.target || "_blank"); + } else { + window.open(`${options.url}${q}`, options.target || "_blank"); + } + + setQuery(""); + currentSuggestion = null; + } + + const handleSearchKeyDown = (event) => { + const useSuggestion = searchSuggestions.length && currentSuggestion; + if (event.key === "Enter") { + doSearch(useSuggestion ? currentSuggestion : event.target.value); + } + }; if (!availableProviderIds) { return null; @@ -148,7 +155,7 @@ export default function Search({ options }) {
- + setQuery(event.target.value)} + onChange={(event) => { + setQuery(event.target.value); + }} required autoCapitalize="off" autoCorrect="off" autoComplete="off" // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus={options.focus} + onBlur={(e) => e.preventDefault()} + onKeyDown={handleSearchKeyDown} /> {searchSuggestions[1].map((suggestion) => ( - - {({ active }) => ( -
- {suggestion.indexOf(query) === 0 ? query : ""} - - {suggestion.indexOf(query) === 0 ? suggestion.substring(query.length) : suggestion} - -
- )} + { + doSearch(suggestion); + }} + className="flex w-full" + > + {({ active }) => { + if (active) currentSuggestion = suggestion; + return ( +
+ {suggestion.indexOf(query) === 0 ? query : ""} + + {suggestion.indexOf(query) === 0 ? suggestion.substring(query.length) : suggestion} + +
+ ); + }}
))}