- 참고 블로그
- 라이브러리 추천
React에서 활용 가능한 DatePicker Library 정리
datepicker library 사용 후기
velog.io
- react-datePicker 커스텀
&& , || : 네이버 블로그
당신의 모든 기록을 담는 공간
blog.naver.com
- 문서
- react-datePicker
React Datepicker crafted by HackerOne
reactdatepicker.com
- react-datePicker > 함수 import 라이브러리
Modern JavaScript Date Utility Library
date-fns provides the most comprehensive yet simple and consistent toolset for manipulating JavaScript dates in a browser & Node.js.
date-fns.org
- 날짜 format 형식 참고
[JavaScript] Date Format (yyyy-MM-dd)
● Date format (yyyy-MM-dd) 자바스크립트에서 날짜를 yyyy-MM-dd 형식으로 표기하기 위해 아래와 같...
blog.naver.com
달력 라이브러리를 찾던 중 react-datePicker 라이브러리를 사용하게 되었다. (예제가 많아서? 선택했다.)
첫번째 과정
react-datePicker 라이브러리를 터미널에 설치한다.
npm install react-datepicker --save
(or)
yarn add react-datepicker
두번째 과정
react-dattePicker 문서에 있는 예제 중 하나를 가져와서 달력 컴포넌트를 하나 생성한다.
(나는 아래 두가지 예제를 가져와서 사용했다.)
세번째 과정
이때 addMonths 또는 getDay가 없다는 오류가 발생하였는 데 이는 상단에 date-fns를 import 받고, {} 안에 함수 이름을 적어주면 된다.
import { getDay, addMonths } from "date-fns";
// DatePicker에 부가적인 기능 가져오고 싶을 때 해당 함수들 date-fns에서 import 해오기
네번째 과정
위 과정이 끝나면 달력이 기본적인 달력이 만들어 진다.
import { useState } from "react";
import DatePicker, { registerLocale } from "react-datepicker"; // DatePicker 컴포넌트 가져오기
import { getDay, addMonths } from "date-fns"; // DatePicker에 부가적인 기능 가져오고 싶을 때 해당 함수들 date-fns에서 import 해오기
// 출처: https://reactdatepicker.com/#example-filter-dates
// 출처: https://date-fns.org/
import ko from "date-fns/locale/ko"; // 한국어로
registerLocale("ko", ko); // 한국어로
const _ = require("lodash"); // _.range를 표현하기 위하여 사용
// 출처: https://blog.naver.com/PostList.naver?blogId=marsdo
const test2 = () => {
const [selectDate, setSelectDate] = useState(null); // 선택한 날짜
// 주말 filter 함수
const isWeekday = (date) => {
const day = getDay(date);
return day !== 0 && day !== 6;
};
return (
<DatePicker
className="datePicker"
selected={selectDate}
onChange={(date) => setSelectDate(date)}
minDate={new Date()}
maxDate={addMonths(new Date(), 100)}
showDisabledMonthNavigation
// minDate, maxDate, showDisabledMonthNavigation => Date Range with disabled navigation shown
filterDate={isWeekday}
placeholderText="Select a weekday"
// filterDate, placeholderText => Filter dates
/>
);
};
export default test2;
5. 달력 라이브러리가 문제 없이 작동하는 걸 확인하여 커스텀을 시작했다.
상단에 커스텀 블로그를 참고했고, styled-components 라이브러리를 사용하여 커스텀을 진행했다.
전체 코드에 주석을 달아 놓았기 때문에 따로 설명하지는 않겠다.
+ 부가설명
날짜 형식이 안예쁘게 나와서 date format 함수를 생성하여 날짜 형식을 변경 했더니 오류가 발생했다.
RangeError: invalid date
찾아보니 날짜 형식이 안맞을 때 나타나는 오류라는 데 datePicker에서 뭔가가 꼬인게 아닐까 싶다.
RangeError: invalid date - JavaScript | MDN
RangeError
developer.mozilla.org
안된다고 해서 안할 건 아니라서.. ㅇㅅㅇ date format 함수는 보류 시키고 원상태로 돌렸다.
그 다음 input 박스를 달력 이미지로 변경하고, 달력 이미지 클릭 시 달력이 나타나도록 커스텀 해서 바꾸고,
[CSS] 체크박스 꾸미기
체크박스 꾸미는 방법 체크박스는 체크박스와 연결된 label을 만들고, 라베을 꾸미며 됩니다. 그렇게 할 경우 라벨을 클릭하면 체크박스가 클릭되고, 다시 클릭하면 체크가 해제되는 성질을 가지
eundol1113.tistory.com
날짜는 JSX에서 date format 함수를 불러오는 방식으로 사용했다.
(사용자가 선택한 날짜가 있으면 날짜 format 해서 return 하고, 사용자가 선택한 날짜가 없으면 문구 출력)
전체 코드
import { useState } from "react";
import styled from "styled-components";
import DatePicker, { registerLocale } from "react-datepicker"; // DatePicker 컴포넌트 가져오기
import { getDay, addMonths } from "date-fns"; // DatePicker에 부가적인 기능 가져오고 싶을 때 해당 함수들 date-fns에서 import 해오기
// 출처: https://reactdatepicker.com/#example-filter-dates
// 출처: https://date-fns.org/
import ko from "date-fns/locale/ko"; // 한국어로
registerLocale("ko", ko); // 한국어로
const _ = require("lodash"); // _.range를 표현하기 위하여 사용
// 출처: https://blog.naver.com/PostList.naver?blogId=marsdo
import ArrowLeftSvg from "public/img/common/arrow-left.svg";
import ArrowRightSvg from "public/img/common/arrow-right.svg";
const test2 = () => {
const [selectDate, setSelectDate] = useState(null); // 선택한 날짜
const months = [
// 월 표시
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
];
// 주말 filter 함수
const isWeekday = (date) => {
const day = getDay(date);
return day !== 0 && day !== 6;
};
// 날짜 형식 format 함수
const dateChangeHandler = () => {
if (selectDate) {
// 선택한 날짜가 있을 경우 (selectDate: true)
const date = selectDate;
const year = date.getFullYear(); // 년
let month = date.getMonth() + 1; // 월
month = month >= 10 ? month : "0" + month; // 월 두자리로 저장
let day = date.getDate(); // 일
day = day >= 10 ? day : "0" + day; // 일 두자리로 저장
return `${year}-${month}-${day}`;
} else {
// 선택한 날짜가 없을 경우 (selectDate: false)
return "날짜를 선택 해주세요.";
}
};
return (
<DateStyle>
<DatePicker
className="datePicker"
id="datePicker"
selected={selectDate}
onChange={(date) => setSelectDate(date)}
minDate={new Date()}
maxDate={addMonths(new Date(), 100)}
showDisabledMonthNavigation
// minDate, maxDate, showDisabledMonthNavigation => Date Range with disabled navigation shown
filterDate={isWeekday}
placeholderText="Select a weekday"
// filterDate, placeholderText => Filter dates
locale="ko"
showPoperArrow={false}
fixedHeight
renderCustomHeader={({
date,
decreaseMonth,
increaseMonth,
prevMonthButtonDisabled,
nexMonthButtonDisabled,
}) => (
<div className="date-customheader">
<ArrowLeftSvg
onClick={decreaseMonth}
width={20}
height={20}
style={
prevMonthButtonDisabled
? { visibility: "hidden" }
: { display: "block" }
}
/>
<div className="custom-month">
<span className="month">{months[date.getMonth()]}월,</span>
<span className="year"> {date.getFullYear()}</span>
</div>
<ArrowRightSvg
onClick={increaseMonth}
width={20}
height={20}
style={
nexMonthButtonDisabled
? { display: "none" }
: { display: "block" }
}
/>
</div>
)}
/>
<label
htmlFor="datePicker"
style={{
width: "50px",
height: "50px",
backgroundImage: "url(/img/nav/sharedOffice/lease/calendar@4x.png)",
backgroundSize: "cover",
}}
/>
{/* 날짜를 출력하는 부분 */}
<div>날짜 : {dateChangeHandler()}</div>
</DateStyle>
);
};
const DateStyle = styled.section`
position: relative;
// 드래그 방지
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
// 달력 위치 조절
.react-datepicker-popper {
top: -100px !important;
left: 60px !important;
}
// 달력 이미지 사용을 위해 input 박스 커스텀하는 부분
& #datePicker:checked + label {
background-color: #038dff;
border: 2px solid #038dff;
}
& #datePicker {
display: none;
}
.datePicker::before,
.datePicker::after {
content: "\e99c";
display: inline-block;
position: absolute;
top: 7px;
left: 7px;
font-family: icomoon !important;
font-size: 1rem;
color: #333;
border: 1px solid #ffffff;
}
// 달력 Header 조절
.date-customheader {
display: flex;
justify-content: space-between;
margin: 0 10px;
svg {
cursor: pointer;
stroke: #666666;
stroke-width: 2px;
margin-top: 4px;
}
}
.react-datepicker__day-names {
font-size: 12px;
margin-top: 10px;
.react-datepicker__day-name {
color: #0072de;
}
}
.react-datepicker__header {
background: #fff;
border-bottom: 1px solid #eeeeee;
padding: 10px;
}
// 달력 헤더 > 월, 년 부분
.custom-month {
.month {
color: #000000;
font-size: 17px;
}
.year {
color: #666666;
font-size: 15px;
}
}
// 달력 Content 부분
.react-datepicker-popper[data-placement^="bottom"]
.react-datepicker__triangle::before,
.react-datepicker-popper[data-placement^="bottom"]
.react-datepicker__triangle::after {
top: -100px;
left: -100px;
border-bottom-color: white;
}
.react-datepicker__day--keyboard-selected,
.react-datepicker__month-text--keyboard-selected,
.react-datepicker__quarter-text--keyboard-selected,
.react-datepicker__year-text--keyboard-selected {
background: #0072de;
}
`;
export default test2;
20220415 - 변경된 CSS 코드
const DateStyle = styled.section`
position: relative;
margin-top: 10px;
.calendar_wrap_1 {
display: flex;
margin: 10px 25px;
position: relative;
.startDate_label {
width: 25px;
height: 25px;
background-image: url(/img/nav/sharedOffice/lease/calendar@4x.png);
background-size: cover;
cursor: pointer;
position: absolute;
right: 350px;
span {
margin-top: 2px;
margin-left: 30px;
font: normal normal normal 16px/19px Pretendard;
letter-spacing: 0px;
color: #333333;
}
}
}
.calendar_wrap_2 {
display: flex;
margin: 10px 25px;
position: relative;
.endDate_label {
width: 25px;
height: 25px;
background-image: url(/img/nav/sharedOffice/lease/calendar@4x.png);
background-size: cover;
cursor: pointer;
position: absolute;
right: 350px;
span {
margin-top: 2px;
margin-left: 30px;
font: normal normal normal 16px/19px Pretendard;
letter-spacing: 0px;
color: #333333;
}
}
}
.select_hr {
margin-top: -5px;
}
// 드래그 방지
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
// 이미지 위치 조절
.react-datepicker-wrapper {
display: none;
}
// 달력 위치 조절
.react-datepicker-popper {
top: -130px !important;
left: 54% !important;
transform: translate(0, 0) !important;
z-index: 100;
transition: all 0.5s;
@media screen and (max-width: 2300px) {
left: 45% !important;
}
@media screen and (max-width: 2100px) {
left: 35% !important;
}
}
// 달력 이미지 사용을 위해 input 박스 커스텀하는 부분
& #startDate:checked + label,
& #endDate:checked + label {
background-color: #038dff;
border: 2px solid #038dff;
}
& #startDate,
#endDate {
display: none;
}
#startDate::before,
#startDate::after,
#endDate::before,
#endDate::after {
content: "\e99c";
display: inline-block;
position: absolute;
top: 7px;
left: 7px;
font-family: icomoon !important;
font-size: 1rem;
color: #333;
border: 1px solid #ffffff;
}
// 달력 Header 조절
.date-customheader {
display: flex;
justify-content: space-between;
margin: 0 10px;
svg {
cursor: pointer;
stroke: #666666;
stroke-width: 2px;
margin-top: 4px;
}
}
.react-datepicker__day-names {
font-size: 12px;
margin-top: 10px;
.react-datepicker__day-name {
color: #0072de;
}
}
.react-datepicker__header {
background: #fff;
border-bottom: 1px solid #eeeeee;
padding: 10px;
}
// 달력 헤더 > 월, 년 부분
.custom-month {
margin-top: 5px;
.month {
color: #000000;
font-size: 17px;
}
.year {
color: #666666;
font-size: 15px;
}
}
// 달력 Content 부분
.react-datepicker-popper[data-placement^="bottom"]
.react-datepicker__triangle::before,
.react-datepicker-popper[data-placement^="bottom"]
.react-datepicker__triangle::after {
border-top: none;
border-bottom: none;
}
.react-datepicker-popper[data-placement^="top"]
.react-datepicker__triangle::before,
.react-datepicker-popper[data-placement^="top"]
.react-datepicker__triangle::after {
border-top: none;
border-bottom: none;
}
.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 {
background: #0072de;
}
`;
'더 알아보기 > 기능' 카테고리의 다른 글
[Next.js] Chart.js (0) | 2022.04.06 |
---|---|
차트(Chart) 라이브러리 (0) | 2022.04.06 |
[React] 다음 주소 API 적용하기 (0) | 2022.03.28 |
[Next.js] 이미지 미리보기 (0) | 2022.03.24 |
[Editor] String 형태의 HTML 렌더링 하기 (2) | 2022.03.23 |
댓글