본문 바로가기
개발/React

[react] react-datepicker 커스텀

by 코딩하는 갓디노 2021. 9. 2.

datepicker 커스텀

 

react-datepicker를 
커스텀하는 방법 입니다.

 

react에서 사용하는 datepicker 중 가장 인기있는 캘린더 데이트피커 라이브러리,
react-datepicker 입니다.

react-datepicker는 기본적으로 제공하는 기능이 많아 여러가지 옵션으로 출력이 가능하고,
여기서 css를 이용하여 이쁘게 UI를 만들 수 있습니다.

 

구현 내용
- react, hooks 방식, style은 tailwind, css 사용
- 예약일 버튼 클릭시 datepicker 토글(출력/사라짐) 기능
- datepicker 출현시 현재 날짜 기본 설정
- datepicker에서 날짜 클릭 후 확인 선택시 예약일 저장, 취소시 datepicker 닫기
- datepicker 한국어 설정
- 화면에 날짜 출력시 연,월,일 및 datepicker 전체 UI 수정

 

react-datepicker 완성 화면

 

react-datepicker 화면 동영상

 

react-datepicker 홈페이지

https://www.npmjs.com/package/react-datepicker

 

react-datepicker

A simple and reusable datepicker component for React

www.npmjs.com

 

react-datepicker 데모

https://reactdatepicker.com/

 

React Datepicker crafted by HackerOne

 

reactdatepicker.com

 

react-datepicker import

import DatePicker, { registerLocale } from "react-datepicker";
import ko from 'date-fns/locale/ko';
import "react-datepicker/dist/react-datepicker.css";

 

DatePicker 기본

<DatePicker 
    	selected={startDate} 
    	onChange={handleChange} 
    	disabledKeyboardNavigation //다른 월의 같은 날짜시 자동 selected 되는 현상 방지
    	locale="ko" 
    	inline 
    	maxDate={new Date()} 
    	popperModifiers={{ //화면을  벗어나지 않도록 하는 설정
        	preventOverflow: { enabled: true }
           	}} 
        popperPlacement="auto" //화면 중앙에 팝업이 출현 
  />

 

전체 코드

<div className={"fixed bottom-16 left-0 z-10 w-full flex-shrink-0 
transition-all transform duration-300" + (isOpen ? " " : " translate-y-full" )}>
  <div className='boxshadow relative p-4 bg-white rounded-t-3xl shadow-inner text-center'>
    <div className='text-gray-600 mb-4'>
      <h1 className='text-lg font-bold mb-2'>예약일</h1>
      <p>예약 날짜를 선택해 주세요</p>
    </div>
    <DatePicker 
    	selected={startDate} 
    	onChange={handleChange} 
    	disabledKeyboardNavigation //다른 월의 같은 날짜시 자동 selected 되는 현상 방지
    	locale="ko" //한국어로 설정
    	inline //팝업이 아닌 inline
    	maxDate={new Date()} 
    	popperModifiers={{ //화면을  벗어나지 않도록 하는 설정
        	preventOverflow: { enabled: true }
           	}} 
        popperPlacement="auto" //화면 중앙에 팝업이 출현 
        renderCustomHeader={({ date, decreaseMonth, increaseMonth })=> ( //header 커스텀 설정
      <div className="datepickerHeader">
        <div onClick={decreaseMonth}>
          <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" d="M15 19l-7-7 7-7" />
          </svg>
        </div>
        <div>{formatDate(date)}</div>
        <div onClick={increaseMonth}>
          <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" strokeWidth="2" d="M9 5l7 7-7 7" />
          </svg>
        </div>
      </div>
      )}
      />
      <div className="flex justify-between items-center pt-4 px-10 gap-4">
        <button onClick={handleClick} className="w-1/2 bg-gray-point py-2 rounded-md text-white">
          취소
        </button>
        <button onClick={onSaveVisitDay} className="w-1/2 bg-yellow-point py-2 rounded-md text-gray-600">
          확인
        </button>
      </div>
  </div>
</div>

 

함수 내 삽입 코드

 registerLocale("ko", ko); //한국어 설정
 
  const [startDate, setStartDate] = useState(new Date());
  const [isOpen, setIsOpen] = useState(false);
  const handleChange = (e: any) => {
    setStartDate(e);
  };

  const handleClick = (e: any) => {
    e.preventDefault();
    setIsOpen(!isOpen);
    setStartDate(new Date());
  };

  const onSaveVisitDay = () => { 
    axios
      .post(api 주소)
      .then((res) => {
        if (res.data.ok) {
          setIsOpen(!isOpen);
          toast.success(`예약일이 저장되었습니다`, { autoClose: 3000, position: toast.POSITION.TOP_RIGHT });
        } else {
          toast.error(res.data.error, { autoClose: 3000, position: toast.POSITION.TOP_RIGHT });
        }
      })
      .catch((err) => console.log(err));
  }

 const formatDate = (d) => { //달력 년, 월, 일 header 
   const date = new Date(d);
   const monthIndex = date.getMonth() + 1;
   const year = date.getFullYear();
   return `${year}년 ${`0${monthIndex}`.slice(-2)}월`;
 };

 

 

반응형

댓글