Skip to content

Commit

Permalink
feat: update keyboard event (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
WONILLISM committed Jul 19, 2023
1 parent 05397cb commit 37ea91d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 40 deletions.
62 changes: 23 additions & 39 deletions src/components/Search/RelatedSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,41 @@
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<HTMLInputElement>) => void;
}

const RelatedSearch = ({ searchText }: RelatedSearchProps) => {
const queryKey = `search ${searchText}`;

const { data, loading, error } = useQuery<SearchItem[]>(
queryKey,
() => getSearchItems({ q: searchText }),
{ enabled: !!searchText, cacheTime: 6000 }
);

if (error) {
return <div>error</div>;
}

const RelatedSearch = ({
data,
loading,
error,
focusIdx,
searchText,
handleKeyDown,
}: RelatedSearchProps) => {
const itemRefs = useRef<(HTMLDivElement | null)[]>([]);
const [focusIdx, setFocusIdx] = useState<number>(-1);

const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
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) {
itemRefs.current = data.map(() => null);
}
}, [data]);

useEffect(() => {
if (itemRefs.current[focusIdx]) {
itemRefs.current[focusIdx]?.focus();
}
}, [focusIdx]);
if (error) {
return <div>Error: {error}</div>;
}

return (
<RelatedSearchArea>
<RelatedSearchTitle>추천 검색어</RelatedSearchTitle>
<RelatedSearchBox onKeyDown={handleKeyDown} tabIndex={0}>
<RelatedSearchBox onKeyDown={handleKeyDown}>
{!!!searchText ? (
<div>검색어 없음</div>
) : loading ? (
Expand All @@ -62,8 +45,8 @@ const RelatedSearch = ({ searchText }: RelatedSearchProps) => {
<RelatedSearchItem
key={item.sickCd}
ref={(el) => (itemRefs.current[idx] = el)}
tabIndex={idx === focusIdx ? 0 : -1}
focus={idx === focusIdx}
tabIndex={idx === focusIdx ? 0 : -1}
>
🔍 {item.sickNm}
</RelatedSearchItem>
Expand Down Expand Up @@ -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;
41 changes: 40 additions & 1 deletion src/pages/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>("");
const [isFocus, setIsFocus] = useState<boolean>(false);
const [focusIdx, setFocusIdx] = useState<number>(-2);

const queryKey = `search ${searchText}`;

const { data, loading, error } = useQuery<SearchItem[]>(
queryKey,
() => getSearchItems({ q: searchText }),
{
enabled: !!searchText,
cacheTime: 6000,
}
);

const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
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 (
<SearchStyle>
Expand All @@ -28,9 +57,19 @@ const Search = () => {
onBlur={() => {
setIsFocus(false);
}}
onKeyDown={handleKeyDown}
/>
</SearchBar>
<RelatedSearch searchText={searchText} />
{isFocus && (
<RelatedSearch
data={data}
loading={loading}
error={error}
focusIdx={focusIdx}
searchText={searchText}
handleKeyDown={handleKeyDown}
/>
)}
</SearchArea>
</SearchStyle>
);
Expand Down

0 comments on commit 37ea91d

Please sign in to comment.