From bbd38ecbf2a571a87eb27e0af70544bfa6c866cb Mon Sep 17 00:00:00 2001 From: Gabriel Mechali Date: Wed, 13 Nov 2024 14:07:16 -0500 Subject: [PATCH] Desensitize hiding the autocomplete results on scroll. (#4731) Only hides the autocomplete results after 15% of window width has been scrolled through. https://screencast.googleplex.com/cast/NjMyMDgzNjY5MTYyMzkzNnxmNjAxODU2Yy0xZQ --- .../nl_search_bar/auto_complete_input.tsx | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/static/js/components/nl_search_bar/auto_complete_input.tsx b/static/js/components/nl_search_bar/auto_complete_input.tsx index 80d1e68f2b..10f41ee709 100644 --- a/static/js/components/nl_search_bar/auto_complete_input.tsx +++ b/static/js/components/nl_search_bar/auto_complete_input.tsx @@ -79,23 +79,38 @@ export function AutoCompleteInput( const [inputActive, setInputActive] = useState(false); const [lastAutoCompleteSelection, setLastAutoCompleteSelection] = useState(""); + // Used to reduce sensitivity to scrolling for autocomplete result dismissal. + // Tracks the last scrollY value at time of autocomplete request. + const [lastScrollYOnTrigger, setLastScrollYOnTrigger] = useState(0); + // Tracks the last scrollY value for current height offsett. + const [lastScrollY, setLastScrollY] = useState(0); const isHeaderBar = props.barType == "header"; let lang = ""; useEffect(() => { // One time initialization of event listener to clear suggested results on scroll. - // It allows the user to navigate through the page without being annoyed by the results. window.addEventListener("scroll", () => { - if (results.placeResults) { - setResults({ placeResults: [], svResults: [] }); - } + setLastScrollY(window.scrollY); }); const urlParams = new URLSearchParams(window.location.search); lang = urlParams.has("hl") ? urlParams.get("hl") : "en"; }, []); + // Whenever any of the scrollY states change, recompute to see if we need to hide the results. + // We only hide the results when the user has scrolled past 15% of the window height since the autocomplete request. + // It allows the user to navigate through the page without being annoyed by the results, + // and to scroll through the results without them disappearing. + useEffect(() => { + if ( + results.placeResults.length > 0 && + Math.abs(lastScrollY - lastScrollYOnTrigger) > window.outerHeight * 0.15 + ) { + setResults({ placeResults: [], svResults: [] }); + } + }, [lastScrollY, lastScrollYOnTrigger]); + useEffect(() => { // For the first load when q= param is set, we want to ensure the // props.value is propagated if it doesn't match input text. @@ -172,6 +187,7 @@ export function AutoCompleteInput( } const triggerAutoCompleteRequest = useCallback(async (query: string) => { + setLastScrollYOnTrigger(window.scrollY); await axios .get(`/api/autocomplete?query=${query}&hl=${lang}`, {}) .then((response) => {