diff --git a/src/components/Search/RelatedSearch.tsx b/src/components/Search/RelatedSearch.tsx index 7172b9f..bc2d3bd 100644 --- a/src/components/Search/RelatedSearch.tsx +++ b/src/components/Search/RelatedSearch.tsx @@ -1,41 +1,26 @@ import { styled } from "styled-components"; + +import { useEffect, useRef } from "react"; import { SearchItem } from "../../common/interface/searchItem"; -import { getSearchItems } from "../../common/api"; -import useQuery from "../../common/hook/useQuery"; -import { useEffect, useRef, useState } from "react"; interface RelatedSearchProps { + data: SearchItem[] | null; + loading: boolean; + error: any; + focusIdx: number; searchText: string; + handleKeyDown: (e: React.KeyboardEvent) => void; } -const RelatedSearch = ({ searchText }: RelatedSearchProps) => { - const queryKey = `search ${searchText}`; - - const { data, loading, error } = useQuery( - queryKey, - () => getSearchItems({ q: searchText }), - { enabled: !!searchText, cacheTime: 6000 } - ); - - if (error) { - return
error
; - } - +const RelatedSearch = ({ + data, + loading, + error, + focusIdx, + searchText, + handleKeyDown, +}: RelatedSearchProps) => { const itemRefs = useRef<(HTMLDivElement | null)[]>([]); - const [focusIdx, setFocusIdx] = useState(-1); - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (data) { - if (e.key === "ArrowUp") { - e.preventDefault(); - setFocusIdx((prevIdx) => Math.max(prevIdx - 1, -1)); - } - if (e.key === "ArrowDown") { - e.preventDefault(); - setFocusIdx((prevIdx) => Math.min(prevIdx + 1, data.length - 1)); - } - } - }; useEffect(() => { if (data) { @@ -43,16 +28,14 @@ const RelatedSearch = ({ searchText }: RelatedSearchProps) => { } }, [data]); - useEffect(() => { - if (itemRefs.current[focusIdx]) { - itemRefs.current[focusIdx]?.focus(); - } - }, [focusIdx]); + if (error) { + return
Error: {error}
; + } return ( 추천 검색어 - + {!!!searchText ? (
검색어 없음
) : loading ? ( @@ -62,8 +45,8 @@ const RelatedSearch = ({ searchText }: RelatedSearchProps) => { (itemRefs.current[idx] = el)} - tabIndex={idx === focusIdx ? 0 : -1} focus={idx === focusIdx} + tabIndex={idx === focusIdx ? 0 : -1} > 🔍 {item.sickNm} @@ -95,9 +78,10 @@ const RelatedSearchBox = styled.div` `; const RelatedSearchItem = styled.div<{ focus: boolean }>` - padding: 4px 0px; + padding: 4px 8px; + border-radius: 8px; - ${(props) => props.focus && "box-shadow: inset 0 0 0 2px red;"} + ${(props) => props.focus && "background-color: #eeeeee"} `; export default RelatedSearch; diff --git a/src/pages/Search.tsx b/src/pages/Search.tsx index 6b118c6..afac249 100644 --- a/src/pages/Search.tsx +++ b/src/pages/Search.tsx @@ -3,10 +3,39 @@ import { styled } from "styled-components"; import SearchBar from "../components/Search/SearchBar"; import RelatedSearch from "../components/Search/RelatedSearch"; import TextField from "../components/TextField"; +import useQuery from "../common/hook/useQuery"; +import { SearchItem } from "../common/interface/searchItem"; +import { getSearchItems } from "../common/api"; const Search = () => { const [searchText, setSearchText] = useState(""); const [isFocus, setIsFocus] = useState(false); + const [focusIdx, setFocusIdx] = useState(-2); + + const queryKey = `search ${searchText}`; + + const { data, loading, error } = useQuery( + queryKey, + () => getSearchItems({ q: searchText }), + { + enabled: !!searchText, + cacheTime: 6000, + } + ); + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "ArrowUp" || e.key === "ArrowDown") { + e.preventDefault(); + setFocusIdx((prevIdx) => { + const maxIdx = data ? Math.max(data.length - 1, 0) : 0; + if (e.key === "ArrowUp") { + return Math.max(prevIdx - 1, -1); + } else { + return Math.min(prevIdx + 1, maxIdx); + } + }); + } + }; return ( @@ -28,9 +57,19 @@ const Search = () => { onBlur={() => { setIsFocus(false); }} + onKeyDown={handleKeyDown} /> - + {isFocus && ( + + )} );