From d23af171f7cfef44d12eafc222f6e1d97ab51c9a Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:24:17 -0800 Subject: [PATCH] Refactor search suggestion keyboard interaction --- src/components/widgets/search/search.jsx | 91 +++++++++++++----------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/components/widgets/search/search.jsx b/src/components/widgets/search/search.jsx index c85a51f7..c9391d35 100644 --- a/src/components/widgets/search/search.jsx +++ b/src/components/widgets/search/search.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, Fragment, useRef } 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"; @@ -71,9 +71,6 @@ export function getStoredProvider() { export default function Search({ options }) { const { t } = useTranslation(); - const searchProviderButton = useRef(); - const comboboxOptions = useRef(); - const availableProviderIds = getAvailableProviderIds(options); const [query, setQuery] = useState(""); @@ -122,28 +119,28 @@ export default function Search({ options }) { }; }, [selectedProvider, options, query, searchSuggestions]); + let currentSuggestion; + + 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) => { - if (event.key === "Tab" && comboboxOptions.current?.getAttribute("data-headlessui-state") === "open") { - searchProviderButton.current.focus(); - event.preventDefault(); + const useSuggestion = searchSuggestions.length && currentSuggestion; + if (event.key === "Enter") { + doSearch(useSuggestion ? currentSuggestion : event.target.value); } }; - 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"); - } - - setQuery(""); - }, - [selectedProvider, options.url, options.target], - ); - if (!availableProviderIds) { return null; } @@ -158,7 +155,7 @@ export default function Search({ options }) {
- + setQuery(event.target.value)} + onChange={(event) => { + setQuery(event.target.value); + }} required autoCapitalize="off" autoCorrect="off" @@ -194,7 +193,6 @@ export default function Search({ options }) { text-white font-medium text-sm bg-theme-600/40 dark:bg-white/10 focus:ring-theme-500 dark:focus:ring-white/50" - ref={searchProviderButton} > {t("search.search")} @@ -238,27 +236,34 @@ export default function Search({ options }) { {searchSuggestions[1]?.length > 0 && ( - +
{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} + +
+ ); + }}
))}