저번에 다 다루지 못하였던 search 부분의 각각의 컴포넌트 들을 다룰 시간이다. 쉬운 부분도 있었지만 Date Picker 같은 경우 상당히 애를 먹었는데, 무엇보다 CSS 수정하는데 있어서 진짜 애를 먹었다...
남이 만든거 쓰는게 쉬울 줄 알았냐?~
라이브러리를 처음 제대로 사용해보는 것 같은데, 처음에는 쉬울 줄 알았는데 이럴거면 뭔가 차라리 내가 만드는 방법을 연구해보는게 더 좋지 않을까 싶었다.
(물론 달력만들 생각해보니 그냥 라이브러리를 잘 익혀보자 ㅎㅎ)
Location
최대한 에어비엔비와 비슷하게 만드려고 노력한것 같다.
여행지 버튼을 클릭할 시, (배경화면이 하얀색으로 변하고 그림자가 생기고) 모달창이 뜬다.
모달창을 생성하기만 하면 되는것이라서 코드는 그렇게 복잡하지는 않다.
const Location = ({ setLocation }) => {
return (
<ModalLocation>
<LocationContainer>
<LocationDoc>지역을 선택해주세요</LocationDoc>
<LocationMain>
<ImgContainer>
<LocationImg
src="/images/gyeonggido.png"
alt="location"
onClick={() => setLocation('경기도')}
/>
<ImgDoc>경기도</ImgDoc>
</ImgContainer>
<ImgContainer>
<LocationImg
src="/images/incheon.png"
alt="location"
onClick={() => setLocation('인천')}
/>
<ImgDoc>인천</ImgDoc>
</ImgContainer>
</LocationMain>
</LocationContainer>
</ModalLocation>
);
};
export default Location;
여기서 setLocation 은 저번 글에서 Search 부분 중 서버에게 데이터를 전달할 때 넘겨줄 location 을 상태변화 시키는 useState 함수를 props 로 전달한 것이다. (참고로 setLocation 만 전달해도 된다.)
Calender
영어를 잘 못 친거같지만, 일단 이렇게 이름을 저장하여서 그대로 작성하였다.
CSS 에서 조금 하자가 있지만 그래도 그럴싸하게 만들었다고 생각한다..
import React from 'react';
import DatePicker from 'react-datepicker'; // datePicker 라이브버리를 가져온다.
import { ko } from 'date-fns/locale'; // 한글로 바꿔주기 위한 조치
import styled, { createGlobalStyle } from 'styled-components';
import 'react-datepicker/dist/react-datepicker.css'; // 달력의 css 를 수정하기 위함
const Calender = ({ startDate, endDate, onChange }) => {
return (
<ModalChecked>
<DatePicker
locale={ko} // 한글
selected={startDate}
onChange={onChange}
startDate={startDate}
endDate={endDate}
disabledKeyboardNavigation
selectsRange // 두개의 달력에서 시작일과 끝일을 선택할수 있도록 설정
monthsShown={2} // 두개의 달력을 띄움
minDate={new Date()} // 최소일자를 오늘로 설정
inline // 항상 달력이 표시되도록 설정
wrapperClassName="react-datepicker__header react-datepicker__day" // 아래서 설명
/>
<DatePickerWrapperStyles /> // 역시.. 아래서 설명
</ModalChecked>
);
};
export default Calender;
모달창에서는 간단하게 달력만 들어가있기 때문에, 구성 자체는 간단한 편이다.
구성하고자 했던 달력은 2개의 달력이 항상 모달창 내에서 표현이 되어야 했고, 시작일과 종료일을 선택할 수 있어야 했다. 이를 설정해주기위해서 Date Picker 옵션들을 쭉 살펴보면서 위처럼 설정하였다.
여기서 wrapperClassName , <DatePickerWrapperStyles /> 2가지는 달력의 CSS 부분을 수정하기 위해서 필요한 부분이다. 우선 달력의 아무 클래스 이름을 가져온 뒤에(브라우저에서 알아본다) wrapperClassName 에다가 선언해주고,
<DatePickerWrapperStyles /> 를 달력 밑에 기입해주면 일단 접근준비는 끝났다.
이후부터는 노가다 작업이 필요한데, 기존에 정의되어있는 CSS classname 을 가져와서 하나하나 수정을 해주면 된다. 수정하고자 하는 부분을 브라우저에서 개발자 모드로 확인한 뒤, 같은 classname 을 찾아서 가져와서 기존 속성값을 변경해주면 된다.
여기까지는 뭐 기존 CSS 수정하는거랑 큰 차이가 없긴 하지만, 생각보다 양도 많고 무엇보다 가독성이 너무 불편하다...
위 파일에 접근해서 바로 바꿔주는것이 아니라, 위에서 접근 조치를 하였으니 이제
onst DatePickerWrapperStyles = createGlobalStyle`
.react-datepicker {
border: none;
}
.react-datepicker__header {
background-color: #fff;
border: none;
}
// 생략
이렇게 하나하나 속성을 바꿔주면 된다!!! 하나하나 바꿔주면 된다.
여기다가 코드를 전부 적어두긴 좀 그렇고 후반부에 참고하시라고 부록으로 빼놓겠다.
GuestType
위 모달창들과 작동 원리는 같다.
const GuestType = ({ decreseNum, increseNum, disabled, guest }) => {
return (
<ModalGuest>
<GuestSection>
<GuestContainer>
<GuestInfo>
<Guest>성인</Guest>
<GuestFilter>만 13세 이상</GuestFilter>
</GuestInfo>
<GuestNumber>
<GuestNumChange onClick={decreseNum} disabled={!disabled}>
-
</GuestNumChange>
<GuestSpan>{guest}</GuestSpan>
<GuestNumChange onClick={increseNum}>+</GuestNumChange>
</GuestNumber>
</GuestContainer>
</GuestSection>
</ModalGuest>
);
};
export default GuestType;
props 로 수를 증가시키는 함수인 increseNum, decreseNum 을 가져온다. 이 함수는 부모 컴포넌트인 Nav 에 있다. 이 함수가 Nav 에 있어야 하는 이유는 추후에 자연스럽게 이해할 수 있을 것이다. (쓰이는 곳이 많아서)
코드가 엄청 복잡한 것은 아니지만, DatePicker 가 생각 이상으로 속된 표현으로 짜증나게 해서 작업기간이 오래 걸렸던 부분이다. 지금 다시 작업하라고 한다면 좀 더 수월하게 작업할 수 있겠지만, 당시에는 멘붕에 멘붕에 멘붕 연속이었다.
부록으로 달력 CSS 수정본을 첨부하고 이번글도 마무리하겠다!
const DatePickerWrapperStyles = createGlobalStyle`
.react-datepicker {
border: none;
}
.react-datepicker__header {
background-color: #fff;
border: none;
}
.react-datepicker__day-name,
.react-datepicker__day,
.react-datepicker__time-name {
display: inline-block;
width: 2.5rem;
height: 2.5rem;
line-height: 2.5rem;
text-align: center;
vertical-align: middle;
margin: 0.166rem;
}
.react-datepicker__day-name {
color: rgba(0,0,0,0.5);
}
.react-datepicker__current-month {
font-size: 15px;
font-weight: 400;
margin-bottom: .6rem;
}
.react-datepicker__month-container {
margin: 0 27px;
}
.react-datepicker__year-read-view--down-arrow,
.react-datepicker__month-read-view--down-arrow,
.react-datepicker__month-year-read-view--down-arrow, .react-datepicker__navigation-icon::before {
width: 6px;
height: 6px;
border-width: 1px 1px 0 0;
border-color: #000;
}
.react-datepicker__day:hover,
.react-datepicker__month-text:hover,
.react-datepicker__quarter-text:hover,
.react-datepicker__year-text:hover {
border-radius: 50%;
background-color: #f0f0f0;
}
.react-datepicker__day--selected, .react-datepicker__day--in-selecting-range, .react-datepicker__day--in-range,
.react-datepicker__month-text--selected,
.react-datepicker__month-text--in-selecting-range,
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--selected,
.react-datepicker__quarter-text--in-selecting-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--selected,
.react-datepicker__year-text--in-selecting-range,
.react-datepicker__year-text--in-range {
border-radius: 50%;
background-color: rgba(0,0,0,0.1);
color: #000;
}
.react-datepicker__day--selected:hover, .react-datepicker__day--in-selecting-range:hover, .react-datepicker__day--in-range:hover,
.react-datepicker__month-text--selected:hover,
.react-datepicker__month-text--in-selecting-range:hover,
.react-datepicker__month-text--in-range:hover,
.react-datepicker__quarter-text--selected:hover,
.react-datepicker__quarter-text--in-selecting-range:hover,
.react-datepicker__quarter-text--in-range:hover,
.react-datepicker__year-text--selected:hover,
.react-datepicker__year-text--in-selecting-range:hover,
.react-datepicker__year-text--in-range:hover {
border-radius: 50%;
background-color: #000;
color: #fff;
}
.react-datepicker__day--keyboard-selected,
.react-datepicker__month-text--keyboard-selected,
.react-datepicker__quarter-text--keyboard-selected,
.react-datepicker__year-text--keyboard-selected {
border-radius: 0.3rem;
background-color: rgba(0,0,0,0.1);
color: #000;
}
.react-datepicker__day--keyboard-selected:hover,
.react-datepicker__month-text--keyboard-selected:hover,
.react-datepicker__quarter-text--keyboard-selected:hover,
.react-datepicker__year-text--keyboard-selected:hover {
border-radius: 50%;
background-color: rgba(0,0,0,0.1);
}
.react-datepicker__day--in-selecting-range:not(.react-datepicker__day--in-range,
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--in-range),
.react-datepicker__month-text--in-selecting-range:not(.react-datepicker__day--in-range,
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--in-range),
.react-datepicker__quarter-text--in-selecting-range:not(.react-datepicker__day--in-range,
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--in-range),
.react-datepicker__year-text--in-selecting-range:not(.react-datepicker__day--in-range,
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--in-range) {
background-color: #000;
color: #fff;
}
.react-datepicker__input-container {
position: relative;
display: inline-block;
width: 100%;
input {
width: 59px;
border: none;
background-color: white;
color: rgba(0,0,0,0.5);
font-size: 14px;
font-weight: 400;
}
}
.react-datepicker__day--outside-month,
.react-datepicker__day--outside-month:hover
{
background-color: white;
}
`;
'Programing > React' 카테고리의 다른 글
2차 프로젝트 - 에어비엔비 ProfileContainer(5) (0) | 2022.09.04 |
---|---|
2차 프로젝트 - 에어비엔비 우측 상단 프로필 버튼(4) (0) | 2022.09.03 |
2차 프로젝트 - 에어비엔비 상단 검색창 - Search(2) (0) | 2022.08.30 |
2차 프로젝트 - 에어비엔비 상단 검색창(1) (0) | 2022.08.24 |
테라로사 사이트 클론 프로젝트 - 2주차 (Search 구현) 및 회고 (0) | 2022.07.31 |