본 게시글에서는 react-calendar
라이브러리로 react 앱에 달력을 적용하는 방법을 공유하고자 합니다.
React-calendar 라이브러리에 대한 설명입니다:
yarn add react-calendar
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css'; // css import
function MyApp() {
const [value, onChange] = useState(new Date());
return (
<div>
<Calendar onChange={onChange} value={value} />
</div>
);
}
return (
<div>
<Calendar onChange={onChange} value={value} />
<div className="text-gray-500 mt-4">
{moment(value).format("YYYY년 MM월 DD일")}
</div>
</div>
);
.react-calendar
, .react-calendar__navigation button
.react-calendar__tile--now
클래스 등 )post를 작성한 날짜에 dot 표시를 추가해보겠습니다.
react-query를 이용해 post를 작성한 날짜를 array 형태로 가져오도록 했습니다. 그리고 useState를 이용해 가져온 배열을 mark 라는 변수에 저장했습니다.
const [mark, setMark] = useState([]);
const { data } = useQuery(
["logDate", month],
async () => {
const result = await axios.get(
`/api/healthLogs?health_log_type=DIET`
);
return result.data;
},
{
onSuccess: (data: any) => {
setMark(data);
// ["2022-02-02", "2022-02-02", "2022-02-10"] 형태로 가져옴
},
}
);
<div class="dot"></div>
html 를 추가하도록 적용했습니다.<Calendar
onChange={onChange}
formatDay={(locale, date) => moment(date).format("DD")}
value={value}
className="mx-auto w-full text-sm border-b"
tileContent={({ date, view }) => {
if (mark.find((x) => x === moment(date).format("YYYY-MM-DD"))) {
return (
<>
<div className="flex justify-center items-center absoluteDiv">
<div className="dot"></div>
</div>
</>
);
}
}}
/>
개발자 도구로 확인해보면 아래와 같이 div가 추가됩니다.
<button class="react-calendar__tile">
<abbr>날짜</abbr>
<!--tileContent로 추가되는 위치 시작-->
<div class="flex ...">
<div class="dot"></div>
</div>
<!--tileContent로 추가되는 위치 끝-->
</button>
.dot {
height: 8px;
width: 8px;
background-color: #f87171;
border-radius: 50%;
display: flex;
margin-left: 1px;
}
.dot
클래스가 추가된 화면 예시 입니다.
<Calendar
onChange={onChange} // useState로 포커스 변경 시 현재 날짜 받아오기
formatDay={(locale, date) => moment(date).format("DD")} // 날'일' 제외하고 숫자만 보이도록 설정
value={value}
minDetail="month" // 상단 네비게이션에서 '월' 단위만 보이게 설정
maxDetail="month" // 상단 네비게이션에서 '월' 단위만 보이게 설정
navigationLabel={null}
showNeighboringMonth={false} // 이전, 이후 달의 날짜는 보이지 않도록 설정
className="mx-auto w-full text-sm border-b"
tileContent={({ date, view }) => { // 날짜 타일에 컨텐츠 추가하기 (html 태그)
// 추가할 html 태그를 변수 초기화
let html = [];
// 현재 날짜가 post 작성한 날짜 배열(mark)에 있다면, dot div 추가
if (mark.find((x) => x === moment(date).format("YYYY-MM-DD"))) {
html.push(<div className="dot"></div>);
}
// 다른 조건을 주어서 html.push 에 추가적인 html 태그를 적용할 수 있음.
return (
<>
<div className="flex justify-center items-center absoluteDiv">
{html}
</div>
</>
);
}}
/>
안녕하세요 포스팅 잘 봤습니다 감사합니다. 선택된 날짜(24일)에 동그라미는 css를 어떻게 조작해야 하는지 여쭤봐도 될까요!?