From 3174edb2535160fa71c98f206451b4d69d2c68a6 Mon Sep 17 00:00:00 2001 From: sujikim Date: Sun, 20 Aug 2023 16:01:24 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=EC=B0=BD=20=EB=93=9C?= =?UTF-8?q?=EB=A1=AD=EB=8B=A4=EC=9A=B4=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 검색창 및 드롭다운 Blur 이벤트 추가 --- src/asset/css/SearchBar.css | 1 + src/asset/css/SearchBarDropDown.css | 21 ++++++++ src/component/utils/BookSearchBar.tsx | 22 ++++++-- src/component/utils/BookSearchPreview.tsx | 5 ++ .../utils/BookSearchRecentKeywords.tsx | 5 ++ src/component/utils/SearchBar.tsx | 2 + src/component/utils/SearchBarDropDown.tsx | 50 +++++++++++++++++++ 7 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/asset/css/SearchBarDropDown.css create mode 100644 src/component/utils/BookSearchPreview.tsx create mode 100644 src/component/utils/BookSearchRecentKeywords.tsx create mode 100644 src/component/utils/SearchBarDropDown.tsx diff --git a/src/asset/css/SearchBar.css b/src/asset/css/SearchBar.css index 66a404a3..ef68ab2e 100644 --- a/src/asset/css/SearchBar.css +++ b/src/asset/css/SearchBar.css @@ -4,6 +4,7 @@ display: flex; border-radius: 6.1rem; background-color: #f2f2f2; + position: relative; } .search-bar__wrapper.short { diff --git a/src/asset/css/SearchBarDropDown.css b/src/asset/css/SearchBarDropDown.css new file mode 100644 index 00000000..1c2ff4c5 --- /dev/null +++ b/src/asset/css/SearchBarDropDown.css @@ -0,0 +1,21 @@ +.search-bar__dropdown { + text-align: left; + background-color: white !important; + position: absolute; + top: 6.4rem; + padding: 1rem; + margin-right: 2.6rem; + white-space: wrap; +} + +@media screen and (max-width: 1200px) { + .search-bar__dropdown { + top: 5.5rem; + } +} + +@media screen and (max-width: 767px) { + .search-bar__dropdown { + top: 5rem; + } +} diff --git a/src/component/utils/BookSearchBar.tsx b/src/component/utils/BookSearchBar.tsx index 605ce343..ebae7490 100644 --- a/src/component/utils/BookSearchBar.tsx +++ b/src/component/utils/BookSearchBar.tsx @@ -1,10 +1,14 @@ -import { FormEventHandler, useEffect, useState } from "react"; +import { FormEventHandler, useEffect, useRef, useState } from "react"; import { useNavigate, useSearchParams } from "react-router-dom"; -import SearchBar from "./SearchBar"; +import SearchBar from "~/component/utils/SearchBar"; +import BookSearchPreview from "~/component/utils/BookSearchPreview"; +import BookSearchRecentKeyword from "~/component/utils/BookSearchRecentKeywords"; const BookSearchBar = () => { + const [isOpened, setIsOpened] = useState(false); const [keyword, setKeyword] = useState(""); const [params] = useSearchParams(); + const ref = useRef(null); const navigate = useNavigate(); const goToSearchPage: FormEventHandler = e => { @@ -23,8 +27,20 @@ const BookSearchBar = () => { setKeyword(e.target.value)} - ref={undefined} + onFocus={() => setIsOpened(true)} + ref={ref} /> + + {keyword.length == 0 ? ( + + ) : ( + + )} + ); diff --git a/src/component/utils/BookSearchPreview.tsx b/src/component/utils/BookSearchPreview.tsx new file mode 100644 index 00000000..c621e2c8 --- /dev/null +++ b/src/component/utils/BookSearchPreview.tsx @@ -0,0 +1,5 @@ +const BookSearchPreview = () => { + return
결과 미리보기
; +}; + +export default BookSearchPreview; diff --git a/src/component/utils/BookSearchRecentKeywords.tsx b/src/component/utils/BookSearchRecentKeywords.tsx new file mode 100644 index 00000000..ac28ede1 --- /dev/null +++ b/src/component/utils/BookSearchRecentKeywords.tsx @@ -0,0 +1,5 @@ +const BookSearchRecentKeyword = () => { + return
최근 검색어
; +}; + +export default BookSearchRecentKeyword; diff --git a/src/component/utils/SearchBar.tsx b/src/component/utils/SearchBar.tsx index b41360a1..b792fbec 100644 --- a/src/component/utils/SearchBar.tsx +++ b/src/component/utils/SearchBar.tsx @@ -1,6 +1,7 @@ import { ComponentProps } from "react"; import SearchBarInput from "~/component/utils/SearchBarInput"; import SearchBarButton from "~/component/utils/SearchBarButton"; +import SearchBarDropDown from "~/component/utils/SearchBarDropDown"; import "~/asset/css/SearchBar.css"; export type Props = ComponentProps<"form"> & { @@ -24,3 +25,4 @@ export default SearchBar; SearchBar.Input = SearchBarInput; SearchBar.Button = SearchBarButton; +SearchBar.DropDown = SearchBarDropDown; diff --git a/src/component/utils/SearchBarDropDown.tsx b/src/component/utils/SearchBarDropDown.tsx new file mode 100644 index 00000000..a2acd998 --- /dev/null +++ b/src/component/utils/SearchBarDropDown.tsx @@ -0,0 +1,50 @@ +import { + Dispatch, + ReactNode, + RefObject, + SetStateAction, + useEffect, + useRef, +} from "react"; +import "~/asset/css/SearchBarDropdown.css"; + +type Props = { + isOpened: boolean; + setIsOpened: Dispatch>; + searchBarRef: RefObject; + children: ReactNode; +}; +const SearchBarDropDown = ({ + isOpened, + setIsOpened, + searchBarRef, + children, +}: Props) => { + const dropDownRef = useRef(null); + + useEffect(() => { + const closeWhenClickedOutside = (e: MouseEvent) => { + if ( + searchBarRef.current && + dropDownRef.current && + !searchBarRef.current.contains(e.target as Node) && + !dropDownRef.current.contains(e.target as Node) + ) + setIsOpened(false); + }; + document.addEventListener("click", closeWhenClickedOutside); + return () => { + document.removeEventListener("click", closeWhenClickedOutside); + }; + }, []); + + if (isOpened) + return ( +
+ {children} +
+ ); + return null; +}; + +export default SearchBarDropDown;