From 96e2e436741fe40c3ac61dca1c6913c66759d026 Mon Sep 17 00:00:00 2001 From: "MD. MOHIBUR RAHMAN" <35300157+mrpmohiburrahman@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:47:00 +0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5=20working=20search=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SearchComponent.module.css | 62 +++++++- .../search_component/SearchComponent.tsx | 142 +++++++++++++----- 2 files changed, 164 insertions(+), 40 deletions(-) diff --git a/website/similar-react-native-libraries/components/search_component/SearchComponent.module.css b/website/similar-react-native-libraries/components/search_component/SearchComponent.module.css index b676612..624c222 100644 --- a/website/similar-react-native-libraries/components/search_component/SearchComponent.module.css +++ b/website/similar-react-native-libraries/components/search_component/SearchComponent.module.css @@ -1,10 +1,33 @@ /* SearchComponent.module.css */ +:root { + --bg-color: #fff; + --text-color: #333; + --border-color: #ccc; + --hover-bg-color: #f0f0f0; + --suggestion-bg-color: #fff; + --suggestion-text-color: #333; + --active-bg-color: #0070f3; + --active-text-color: #fff; +} + +[data-theme='dark'] { + --bg-color: #333; + --text-color: #fff; + --border-color: #555; + --hover-bg-color: #444; + --suggestion-bg-color: #444; + --suggestion-text-color: #fff; + --active-bg-color: #1a73e8; + --active-text-color: #fff; +} + .container { display: flex; flex-direction: column; align-items: center; text-align: left; width: 100%; + position: relative; } .searchInput { @@ -12,8 +35,43 @@ max-width: 800px; padding: 1rem; font-size: 1.5rem; - border: 1px solid #ccc; + border: 1px solid var(--border-color); border-radius: 5px; + background-color: var(--bg-color); + color: var(--text-color); +} + +.suggestionsContainer { + position: absolute; + top: 60px; + /* Adjust this value as needed */ + width: 100%; + max-width: 800px; + border: 1px solid var(--border-color); + border-top: none; + background-color: var(--suggestion-bg-color); + z-index: 1000; + border-radius: 0 0 5px 5px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.suggestionItem { + padding: 1rem; + border-bottom: 1px solid var(--border-color); + cursor: pointer; + background-color: var(--suggestion-bg-color); + color: var(--suggestion-text-color); + transition: background-color 0.2s; +} + +.suggestionItem:hover, +.suggestionItem.active { + background-color: var(--hover-bg-color); +} + +.suggestionItem.active { + background-color: var(--active-bg-color); + color: var(--active-text-color); } .resultsContainer { @@ -23,7 +81,7 @@ } .resultItem { - border-bottom: 1px solid #ddd; + border-bottom: 1px solid var(--border-color); padding: 1rem 0; } diff --git a/website/similar-react-native-libraries/components/search_component/SearchComponent.tsx b/website/similar-react-native-libraries/components/search_component/SearchComponent.tsx index 8af51b0..8b9f68f 100644 --- a/website/similar-react-native-libraries/components/search_component/SearchComponent.tsx +++ b/website/similar-react-native-libraries/components/search_component/SearchComponent.tsx @@ -1,8 +1,7 @@ -import React, { useState, useEffect, ChangeEvent } from 'react'; -import debounce from 'lodash/debounce'; +import React, { useState, useEffect, useRef, ChangeEvent, KeyboardEvent, MouseEvent } from 'react'; import combinedData from '../../../../category-selector/data/combinedFromChunks.json'; // Adjust the path to your JSON file import categoryData from '../../../../category-selector/data/uniqueCategoryToLib.json'; // Adjust the path to your JSON file -import styles from './SearchComponent.module.css'; // Assuming styles are imported +import styles from './SearchComponent.module.css'; interface GithubData { githubUrl: string; @@ -72,62 +71,129 @@ interface GithubData { const SearchComponent: React.FC = () => { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); + const [suggestions, setSuggestions] = useState([]); + const [showSuggestions, setShowSuggestions] = useState(false); + const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(0); + const [hasSearched, setHasSearched] = useState(false); + const inputRef = useRef(null); - const handleSearch = debounce((searchTerm: string) => { - if (searchTerm) { - const item = (combinedData as { [key: string]: GithubData })[searchTerm]; - if (item) { - const uniqueCategory = item.uniqueCategory; - const relatedLibs = (categoryData as { [key: string]: string[] })[uniqueCategory]; - if (relatedLibs) { - const fetchedResults = relatedLibs - .map(libUrl => (combinedData as { [key: string]: GithubData })[libUrl]) - .filter(Boolean) as GithubData[]; - setResults(fetchedResults); - } else { - setResults([]); - } + useEffect(() => { + inputRef.current?.focus(); + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === '/') { + e.preventDefault(); + inputRef.current?.focus(); + } + }; + + document.addEventListener('keydown', handleKeyDown); + + return () => { + document.removeEventListener('keydown', handleKeyDown); + }; + }, []); + + const fetchResults = (searchTerm: string) => { + const item = (combinedData as { [key: string]: GithubData })[searchTerm]; + if (item) { + const uniqueCategory = item.uniqueCategory; + const relatedLibs = (categoryData as { [key: string]: string[] })[uniqueCategory]; + if (relatedLibs) { + const fetchedResults = relatedLibs + .map(libUrl => (combinedData as { [key: string]: GithubData })[libUrl]) + .filter(Boolean) as GithubData[]; + setResults(fetchedResults); } else { setResults([]); } } else { setResults([]); } - }, 300); - - useEffect(() => { - handleSearch(query); - }, [query]); + setHasSearched(true); + }; const handleChange = (e: ChangeEvent) => { - setQuery(e.target.value); + const value = e.target.value; + setQuery(value); + setActiveSuggestionIndex(0); + + if (value) { + setShowSuggestions(true); + const filteredSuggestions = Object.keys(combinedData).filter(key => + key.toLowerCase().includes(value.toLowerCase()), + ); + setSuggestions(filteredSuggestions); + } else { + setShowSuggestions(false); + setResults([]); + setHasSearched(false); + } + }; + + const handleKeyDownInput = (e: KeyboardEvent) => { + if (e.key === 'ArrowDown') { + setActiveSuggestionIndex(prevIndex => (prevIndex + 1) % suggestions.length); + } else if (e.key === 'ArrowUp') { + setActiveSuggestionIndex(prevIndex => (prevIndex - 1 + suggestions.length) % suggestions.length); + } else if (e.key === 'Enter') { + if (suggestions.length > 0) { + const selectedSuggestion = suggestions[activeSuggestionIndex]; + setQuery(selectedSuggestion); + setShowSuggestions(false); + fetchResults(selectedSuggestion); + } + } + }; + + const handleSuggestionClick = (e: MouseEvent) => { + const selectedSuggestion = e.currentTarget.innerText; + setQuery(selectedSuggestion); + setShowSuggestions(false); + fetchResults(selectedSuggestion); }; return (
-
- {results.length > 0 ? ( - results.map(result => ( -
-

- - {result.github?.name} - -

-

{result.github?.description}

- {/* Display other relevant data from the JSON object as needed */} + {showSuggestions && suggestions.length > 0 && ( +
+ {suggestions.map((suggestion, index) => ( +
+ {suggestion}
- )) - ) : ( -
{query &&

No results found

}
- )} + ))} +
+ )} +
+ {hasSearched && results.length > 0 + ? results.map(result => ( +
+

+ + {result.github?.name} + +

+

{result.github?.description}

+ {/* Display other relevant data from the JSON object as needed */} +
+ )) + : hasSearched && ( +
+

No results found

+
+ )}
);