From b3e1048fa4155e7b37ed8040aa60404e331a71fc Mon Sep 17 00:00:00 2001 From: KevIsDev Date: Thu, 1 May 2025 17:19:29 +0100 Subject: [PATCH] refactor(Search): improve search UX with loader timing and state management Enhance the search experience by ensuring the loader is displayed for a minimum duration to avoid flickering. Additionally, introduce a `hasSearched` state to accurately display "No results found" only after a search has been performed. --- app/components/workbench/Search.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/components/workbench/Search.tsx b/app/components/workbench/Search.tsx index fed64ef..f3d026d 100644 --- a/app/components/workbench/Search.tsx +++ b/app/components/workbench/Search.tsx @@ -3,7 +3,6 @@ import type { TextSearchOptions, TextSearchOnProgressCallback, WebContainer } fr import { workbenchStore } from '~/lib/stores/workbench'; import { webcontainer } from '~/lib/webcontainer'; import { WORK_DIR } from '~/utils/constants'; -import { Loader2 } from 'lucide-react'; import { debounce } from '~/utils/debounce'; interface DisplayMatch { @@ -94,6 +93,7 @@ export function Search() { const [searchResults, setSearchResults] = useState([]); const [isSearching, setIsSearching] = useState(false); const [expandedFiles, setExpandedFiles] = useState>({}); + const [hasSearched, setHasSearched] = useState(false); const groupedResults = useMemo(() => groupResultsByFile(searchResults), [searchResults]); @@ -112,6 +112,7 @@ export function Search() { setSearchResults([]); setIsSearching(false); setExpandedFiles({}); + setHasSearched(false); return; } @@ -119,6 +120,10 @@ export function Search() { setIsSearching(true); setSearchResults([]); setExpandedFiles({}); + setHasSearched(true); + + const minLoaderTime = 300; // ms + const start = Date.now(); try { const instance = await webcontainer; @@ -144,7 +149,13 @@ export function Search() { } catch (error) { console.error('Failed to initiate search:', error); } finally { - setIsSearching(false); + const elapsed = Date.now() - start; + + if (elapsed < minLoaderTime) { + setTimeout(() => setIsSearching(false), minLoaderTime - elapsed); + } else { + setIsSearching(false); + } } }, []); @@ -178,10 +189,10 @@ export function Search() {
{isSearching && (
- Searching... +
Searching...
)} - {!isSearching && searchResults.length === 0 && ( + {!isSearching && hasSearched && searchResults.length === 0 && searchQuery.trim() !== '' && (
No results found.
)} {!isSearching &&