React 显示整年日历 标记节假日

大致要实现这样一个效果

 

 

3.x antd的Calendar 没找着这个功能,菜鸡记录一下

JS

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Button, Calendar, Col, message, Row } from 'antd';
import classNames from 'classnames';
import moment from 'moment';

import './index.less';

const monthArr = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
const arrow_icon = require('../../assets/icon/arrow_left.svg');
const FULL_DATE = 'YYYY-MM-DD';
const DAY = 'DD';

const VacationSetting = (props: any) => {

  const [curYear, setCurYear] = useState<any>(moment().format('YYYY'));
  const [holiday, setHoliday] = useState<any[]>([]);

  const [selectArr, setSelectArr] = useState<any[]>([]);
  const [cancelArr, setCancelArr] = useState<any[]>([]);

  //获取节假日
  useEffect(() => {
    init();
  }, []);

  const init = () => {
    setSelectArr([]);
    setCancelArr([]);
	//这里获取holiday 的数据
  };

  //选中
  const select = (date: any) => {
    let dateText = moment(date).format(FULL_DATE);
    if (holiday.includes(dateText)) return;
    let tmpArr = [...selectArr];
    if (tmpArr.includes(dateText)) {
      let idx = tmpArr.findIndex((item: string) => {
        return item === dateText;
      });
      if (idx !== -1) {
        tmpArr.splice(idx, 1);
      }
    } else {
      tmpArr.push(dateText);
    }
    setSelectArr(tmpArr);
  };

  //取消
  const cancel = (date: any) => {
    let dateText = moment(date).format(FULL_DATE);
    let tmpArr = [...cancelArr];
    if (tmpArr.includes(dateText)) {
      let idx = tmpArr.findIndex((item: string) => {
        return item === dateText;
      });
      if (idx !== -1) {
        tmpArr.splice(idx, 1);
      }
    } else {
      tmpArr.push(dateText);
    }
    setCancelArr(tmpArr);
  };

   //保存逻辑
  const save = useCallback(() => {
  }, [selectArr, cancelArr]);

  const CalendarDOM = useMemo(() => {
    return (
      <Row gutter={[16, 16]}>
        {
          monthArr.map((item) => {
            return (
              <Col span={6}>
                <Calendar
                  fullscreen={false}
                  value={moment(`${curYear}-${item}`)}
                  onSelect={select}
                  disabledDate={((current) => {
                    let month = moment(current).format('MM');
                    return month !== item;
                  })}
                  dateFullCellRender={(date: any) => {
                    let dateText = moment(date).format(FULL_DATE);
                    let month = moment(date).format('MM');
                    let isHoliday = holiday.includes(moment(date).format(FULL_DATE));
                    let isSelect = selectArr.includes(moment(date).format(FULL_DATE));
                    let text = moment(date).format(DAY);

                    return (
                      <div className="calendar-day-content">
                        {
                          !cancelArr.includes(dateText) &&
                          <div
                            className={
                              classNames({
                                [`calendar-day-box`]: true,
                                [`not-this-month-day`]: item !== month,
                                [`is-holiday`]: isHoliday,
                                [`is-select`]: isSelect,
                              })
                            }
                          >
                            {text}
                          </div>
                        }
                        {
                          isHoliday && !(item !== month) &&
                          <div className="cancel-holiday" onClick={() => {
                            cancel(date);
                          }}>
                            取消
                          </div>
                        }
                      </div>
                    );
                  }}
                  headerRender={({ value, type, onChange, onTypeChange }) => {
                    return (
                      <div className={'calendar-header'}>{moment(value).format('MM月')}</div>
                    );
                  }}
                />
              </Col>
            )
              ;
          })
        }
      </Row>
    );
  }, [selectArr, cancelArr, curYear, holiday]);

  return (
    <div className="my-calendar-box">
      <div className="my-calendar-header">
        <div className="title">节假日设置</div>
        <Button type="primary" onClick={save}>批量设置节假日</Button>
      </div>
      <div className="my-calendar-content">
        <div className="calendar-change-box">
          <img
            src={arrow_icon}
            className={'calendar-change-arrow'}
            onClick={() => {
              setCurYear(Number(curYear) - 1);
            }}
          />
          <span style={{ margin: '0 12px' }}>{curYear}年</span>
          <img
            src={arrow_icon}
            className={classNames('calendar-change-arrow', 'calendar-change-arrow-right')}
            onClick={() => {
              setCurYear(Number(curYear) + 1);
            }}
          />
        </div>
        {CalendarDOM}
      </div>
    </div>
  );
};

export default VacationSetting;

LESS文件

.my-calendar-box {
 background-color: #e7ebec;
 height: 100%;
 width: 100%;
 display: grid;
 grid-template-rows: 48px 1fr;
 grid-template-columns: 100%;
 overflow: auto;

 .my-calendar-header {
   display: flex;
   flex-direction: row;
   align-items: center;
   justify-content: space-between;
   width: 100%;
   padding: 13px 16px;
   background-color: #fff;

   .title {
     width: 80px;
     height: 22px;
     color: rgba(14, 38, 38, 1);
     font-size: 16px;
     font-weight: 700;
   }
 }

 .my-calendar-content {
   display: grid;
   grid-template-rows: 48px 1fr;
   grid-template-columns: 100%;
   padding: 16px;

   .calendar-change-box {
     display: flex;
     flex-direction: row;
     align-items: center;
     justify-content: flex-start;
     font-size: 18px;
     font-weight: 600;

     .calendar-change-arrow {
       width: 18px;
       height: 18px;
       cursor: pointer;

       &-right {
         transform: rotate(180deg);
       }
     }
   }

   .ant-fullcalendar-header {
     background-color: #fff;
   }

   .calendar-header {
     background-color: #fff;
     height: 46px;
     display: flex;
     flex-direction: row;
     align-items: center;
     justify-content: center;
   }

   .ant-fullcalendar-calendar-body {
     background-color: #fff;

     .ant-fullcalendar-table {
       thead {
         tr {
           th:nth-child(6) {
             color: #D40000 !important;
           }

           th:nth-child(7) {
             color: #D40000 !important;
           }
         }
       }
     }


     .calendar-day-content {
       display: flex;
       flex-direction: row;
       align-items: center;
       justify-content: center;
       text-align: center;
       width: 100%;
       height: 100%;
       position: relative;

       .calendar-day-box {
         display: flex;
         flex-direction: row;
         align-items: center;
         justify-content: center;
         width: 75%;
         height: 100%;
         background-color: #fff;
         position: absolute;
         top: 0;
         left: 10%;
       }

       .calendar-day-box:hover {
         background-color: #dfe8e7;
         cursor: pointer;
       }

       .cancel-holiday {
         width: 75%;
         height: 100%;
         border-radius: 8px;
         color: #13939E;
         background: #DFE8E8;
         display: flex;
         flex-direction: row;
         align-items: center;
         justify-content: center;
         position: absolute;
         top: 0;
         left: 10%;
         z-index: 9;
         cursor: pointer;
       }

       .cancel-holiday:hover {
         z-index: 11;
       }

       .is-holiday {
         color: #D40000 !important;
         font-weight: 700;
         z-index: 10;
       }

       .is-holiday:hover {
         z-index: 8;
       }

       .is-select {
         background-color: #13939E;
         border-radius: 100px;
         color: #ffffff;
       }

       .not-this-month-day {
         opacity: .25;
         color: #000000 !important;
         background-color: #fff !important;
         cursor: auto !important;
       }
     }
   }
 }
}

posted @   不如去吃喝  阅读(825)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示