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;
}
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!