diff --git a/src/components/layout/SearchModal.tsx b/src/components/layout/SearchModal.tsx index 3c355a58..c7d5e677 100644 --- a/src/components/layout/SearchModal.tsx +++ b/src/components/layout/SearchModal.tsx @@ -9,6 +9,8 @@ import { searchArticles } from '@/utils/wikiSearch'; import { wikiSearchIndex } from '@/data/wikiSearchIndex'; import styles from './SearchModal.module.css'; +import { useDebounce } from '@/hooks/useDebounce'; + const STATIC_PAGES = [ { title: 'Home', href: '/', category: 'Navigation' }, { title: 'Courses', href: '/courses', category: 'Navigation' }, @@ -24,9 +26,14 @@ export default function SearchModal() { const router = useRouter(); const isSearchOpen = useSearchOpen(); const setSearchOpen = useSetSearchOpen(); + + // State for the input field (updates instantly) const [query, setQuery] = useState(''); const inputRef = useRef(null); + // 2. CREATED DEBOUNCED QUERY (300ms delay) + const debouncedQuery = useDebounce(query, 300); + useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') { @@ -53,15 +60,17 @@ export default function SearchModal() { wasOpenRef.current = isSearchOpen; }, [isSearchOpen]); + // 3. REPLACED `query` WITH `debouncedQuery` IN USEMEMO const wikiResults = useMemo(() => { - return searchArticles(wikiSearchIndex, query); - }, [query]); + return searchArticles(wikiSearchIndex, debouncedQuery); + }, [debouncedQuery]); + // 4. REPLACED `query` WITH `debouncedQuery` IN USEMEMO const pageResults = useMemo(() => { - if (!query.trim()) return []; - const q = query.toLowerCase(); + if (!debouncedQuery.trim()) return []; + const q = debouncedQuery.toLowerCase(); return STATIC_PAGES.filter((p) => p.title.toLowerCase().includes(q)); - }, [query]); + }, [debouncedQuery]); const selectItem = (href: string) => { router.push(href); @@ -111,7 +120,8 @@ export default function SearchModal() {
- {!query.trim() ? ( + {/* 5. DISPLAY RESULTS BASED ON DEBOUNCED QUERY */} + {!debouncedQuery.trim() ? (

Quick Navigation

@@ -182,7 +192,9 @@ export default function SearchModal() { {pageResults.length === 0 && wikiResults.length === 0 && (
-

No results found for “{query}”

+

+ No results found for “{debouncedQuery}” +

)}
diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts new file mode 100644 index 00000000..2bc67aab --- /dev/null +++ b/src/hooks/useDebounce.ts @@ -0,0 +1,21 @@ +import { useState, useEffect } from 'react'; + +export function useDebounce(value: T, delay: number): T { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + // Har keystroke par ek timer set hota hai + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + // Agar user delay se pehle dobara type karta hai, toh pichla timer cancel (cleanup) ho jata hai + return () => { + clearTimeout(handler); + }; + }, [value, delay]); // Only re-call effect if value or delay changes + + return debouncedValue; +} + +export default useDebounce;