自定义日历组件

import React, { useEffect, useState, useRef } from 'react';
import { DatePicker, DatePickerProps, Tabs, Radio, Select, Col, Row, Image } from 'antd';
import styles from './style.less';const PLTable: React.FC<any> = (props) => {const user = getUserInfo();const [nowMonth, setNowMonth] = useState(Number);const [nowYear, setNowYear] = useState(Number);const [monthBtn, setMonthBtn] = useState(Number);const [yearBtn, setYearBtn] = useState(Number);const [isHide, setIsHide] = useState(true);const [isDataHide, setIsDataHide] = useState(false);// Get the current date and determine which type the current month is.const nowDate = async () => {const month = new Date().getMonth() + 1const year = new Date().getFullYear()setNowYear(year)setYearBtn(year)switch (month) {case (1 || 2 || 3):setMonthBtn(1)setNowMonth(1)break;case (4 || 5 || 6):setMonthBtn(2)setNowMonth(2)break;case (7 || 8 || 9):setMonthBtn(3)setNowMonth(3)break;default:setMonthBtn(4)setNowMonth(4)}};useEffect(() => {nowDate();// 判断点击日历内部还是外部,外部关闭日历弹窗document.addEventListener("click", (e) => {const inputEl = document.querySelector('.test-content');const clickEl = e.target as HTMLElement;if (!inputEl || !clickEl) return;if (inputEl.contains(clickEl)) {console.log('children')setIsDataHide(true)return;} else {console.log('parent')setIsDataHide(false)return;}});}, [])// 封装后的阻止冒泡功能const stopPropagation = (e) => {e.nativeEvent.stopImmediatePropagation();}const dataClick = async (e) => {stopPropagation(e);setIsDataHide(!isDataHide)};// 处理top tab切换日期const switchDateInterval = (type: any) => {if (type == 'add') {if (yearBtn < nowYear) {// 其他年份,判断是否切换年份,是4切换if (monthBtn === 4) {const year = yearBtn + 1setYearBtn(year)setMonthBtn(1)} else {// 其他年分不是4,正常执行const num = Number(monthBtn) + 1setMonthBtn(num)setIsHide(false)}} else {// 当前年份const num = Number(monthBtn) + 1setMonthBtn(num)if (num >= nowMonth) {setIsHide(true)} else {setIsHide(false)}}} else {// 不是当前年份,判断是否是1,是1切换if (monthBtn === 1) {const year = yearBtn - 1setYearBtn(year)setMonthBtn(4)} else {// 不是1,正常执行const num = monthBtn - 1setMonthBtn(num)if (num >= nowMonth) {setIsHide(true)} else {setIsHide(false)}}}};const switchBtn = (type: any) => {setMonthBtn(type)};const calendar = async (type: any) => {if (type == 'add') {if (yearBtn<nowYear) {const year = yearBtn + 1setYearBtn(year)}} else {const year = yearBtn - 1setYearBtn(year)}}return (<div className={styles.plTabMain}><div className={styles.title}><div className={styles.update}>Last Sync:{'11-20-2022 12:00 a.m. CT'}</div><div className={styles.titleCenter}><imgalt='left'src={`/icons/leftIcon_pro.svg`}className={styles.scoreIcon}onClick={() => {switchDateInterval('subtract');}}/>{monthBtn == 1 && `Jan – Mar ${yearBtn}`}{monthBtn == 2 && `Apr – Jun ${yearBtn}`}{monthBtn == 3 && `Jul – Sep ${yearBtn}`}{monthBtn == 4 && `Oct – Dec ${yearBtn}`}<imgalt='right'src={`/icons/rightIcon_pro.svg`}className={styles.scoreIcon}onClick={() => {switchDateInterval('add');}}style={{ display: isHide ? 'none' : '' }}/></div><div className={styles.datetime}><div className={styles.inputName} onClick={dataClick}><span>{monthBtn == 1 && `Jan – Mar ${yearBtn}`}{monthBtn == 2 && `Apr – Jun ${yearBtn}`}{monthBtn == 3 && `Jul – Sep ${yearBtn}`}{monthBtn == 4 && `Oct – Dec ${yearBtn}`}</span><img className={styles.headerArrowIcon} src={`/svgs/iuessDown.svg`} /></div><div className={`${styles.post} test-content`} style={{ display: `${isDataHide ? 'block' : 'none'}` }}><div className={styles.postTitle}><img src={`/svgs/finaLeft.svg`} onClick={() => {calendar('subtract');}} alt="" /><span>{yearBtn}</span><img src={`/svgs/finaRight.svg`} onClick={() => {calendar('add');}} alt="" className={`${yearBtn>=nowYear? styles.nopoint:''}`} /></div><div className={styles.connect}><div className={`${styles.btn} ${monthBtn == 1 && styles.clickNow}`} onClick={()=>switchBtn(1)}><span>Jan</span><span>Feb</span><span>Mar</span></div><div className={`${styles.btn} ${monthBtn == 2 && styles.clickNow}`} onClick={()=>switchBtn(2)}><span>Apr</span><span>May</span><span>Jun</span></div><div className={`${styles.btn} ${monthBtn == 3 && styles.clickNow}`} onClick={()=>switchBtn(3)}><span>Jul</span><span>Aug</span><span>Sep</span></div><div className={`${styles.btn} ${monthBtn == 4 && styles.clickNow}`} onClick={()=>switchBtn(4)}><span>Oct</span><span>Nov</span><span>Dec</span></div></div></div></div></div></div>);
};
export default PLTable;

css 样式

@import '~antd/es/style/themes/default.less';// P&L table.plTabMain{.overTit{margin-bottom: 8px;margin-top: 56px;color: #0D2B56;font-size: 24px;font-family: 'Futura-PT-Demi';}.overTit2{margin-bottom: 24px;color: #0D2B56;font-size: 21px;font-family: 'Futura-PT-Demi';}.title{display: flex;flex-direction: row;align-items: center;justify-content: space-between;margin-bottom: 16px;.update{font-size: 14px;line-height: 20px;color: #848688;}.titleCenter {font-size: 18px;color: #0D2B56;font-family: 'Futura-PT-Demi';line-height: 24px;display: flex;.scoreIcon {width: 10px;height: 22px;margin: 0 39px;cursor: pointer;}.guideMonth {vertical-align: middle;font-style: normal;font-weight: 500;font-size: 18px;line-height: 24px;color: #0D2B56;font-family: 'Futura-PT-Demi';}}.datetime{position: relative;.inputName{width: 170px;height: 40px;padding: 8px 16px;color: #4E5153;border: 1px solid #D6D8DC;border-radius: 4px;display: flex;flex-direction: row;align-items: center;justify-content: space-between;background: #fff;cursor: pointer;.headerArrowIcon{width: 12px;vertical-align: baseline;}}.post{display: none;position: absolute;width: 268px;height: 264px;border-radius: 4px;box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);background: #fff;z-index: 9999;// cursor: pointer;.postTitle{width: 100%;height: 40px;padding: 10px 24px;border-bottom: 1px solid #ECEEF1;display: flex;flex-direction: row;align-items: center;justify-content: space-between;img{cursor: pointer;}.nopoint{cursor: not-allowed !important;}}.connect{height: calc(100% - 40px);padding: 23px 24px;box-sizing: border-box;display: flex;flex-direction: column;align-items: center;justify-content: space-between;.btn{width: 100%;height: 28px;padding: 4px 16px;font-size: 14px;color: #4E5153;border: 1px solid #E1990F;border-radius: 4px;display: flex;flex-direction: row;align-items: center;justify-content: space-between;cursor: pointer;}.clickNow{background: #EFB041 !important;border: 1px solid #EFB041 !important;color: #fff !important;}}}}}.tableCenter{padding: 24px;background: #fff;box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);border-radius: 4px;.itemFirst{background: #F9F9F9;border-top: 1px solid #D6D8DC !important;border-width: 1px;border-bottom: none !important;}.itemFirst2{background: #ECEEF1;border-bottom: 1px solid #D6D8DC !important;border-width: 1px;border-top: none !important;}.itemFirst3{border-top: 1px solid #eee !important;}.itemFirst4{border-bottom: 1px solid #D6D8DC;}}}.topCenter{display: flex;flex-direction: row;.leftScore{width: 604px;height: 608px;box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);margin-right: 24px;border-radius: 4px;background: #fff;padding: 24px;}.riList{display: flex;flex-direction: column;.topGrowth{width: 604px;height: 292px;box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);margin-bottom: 24px;border-radius: 4px;background: #fff;padding: 24px;box-sizing: border-box;}.btmCash{width: 604px;height: 292px;box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);border-radius: 4px;background: #fff;padding: 24px;box-sizing: border-box;}.ribbtmContent{width: 100%;display: flex;flex-direction: row;.baifen{width: 35%;margin-left: 16px;display: flex;flex-direction: column;.rule{font-size: 14px;color: #4E5153;margin-top: 24px;margin-bottom: 24px;}.num{font-size: 36px;color: #009344;margin-bottom: 40px;line-height: 32px;}.num2{font-size: 36px;color: #D01D1D;margin-bottom: 40px;line-height: 32px;}.btn{width: 96px;height: 24px;display: flex;flex-direction: row;align-items: center;background: #CAE7CE;border-radius: 4px;padding: 4px 16px;font-size: 12px;color: #009344;img{margin-right: 9px;}}.btn2{width: 96px;height: 24px;display: flex;flex-direction: row;align-items: center;background: #FBC4C6;border-radius: 4px;padding: 4px 16px;font-size: 12px;color: #D01D1D;img{margin-right: 9px;}}}.table{width: 65%;}}}.ritopTitle{width: 100%;padding: 12px 16px;box-sizing: border-box;display: flex;flex-direction: row;align-items: center;justify-content: space-between;background: #ECEEF1;color: #4E5153;font-family: 'Futura-PT-Medium';border-bottom: 1px solid #D6D8DC;.name{display: flex;flex-direction: row;align-items: center;span{width: 24px;height: 24px;display: flex;align-items: center;justify-content: center;background: #106FC4;color: #fff;margin-right: 16px;}}img{cursor: pointer;}}.Metricstop{display: flex;flex-direction: row;align-items: center;margin-bottom: 32px;.sp1{color: #C88C1A;font-size: 36px;font-family: 'Futura-PT-Demi';margin-right: 8px;}.sp2{width: 40px;height: 40px;border-radius: 50%;background: #C88C1A;font-size: 18px;color: #fff;display: flex;align-items: center;justify-content: center;}.classNaa{display: flex;flex-direction: row;align-items: center;}}}.tip{color: #4E5153;font-size: 14px;letter-spacing: 0;:global{.ant-tooltip-content{.ant-tooltip-arrow{display: none;}}}}}.aaaaaa2 {:global{.ant-form-item-label > label {color: #848688;}.ant-checkbox{color: #848688;}.ant-checkbox-wrapper {color: #848688;}.ant-modal-body {padding: 24px;}.ant-modal-confirm-btns{margin-top: 0;}.ant-modal-confirm-btns button:first-child{display: none;}.ant-modal-confirm-body{.anticon svg {display: none;}}.ant-modal-close-x {width: 75px;height: 75px;line-height: 75px;}.ant-modal-confirm-body .ant-modal-confirm-content {margin-top: 24px;}.ant-modal-confirm-body>.anticon+.ant-modal-confirm-title+.ant-modal-confirm-content {margin-left: 0;}.ant-btn-primary {color: #fff;background: #E1990F !important;border-color: #E1990F !important;border-radius: 4px;}.ant-modal-confirm-body .ant-modal-confirm-title {display: block;overflow: hidden;color: #0D2B56 !important;font-weight: 600 !important;font-size: 24px !important;line-height: 1.4;}.ant-modal-confirm-body > .anticon + .ant-modal-confirm-title + .ant-modal-confirm-content {margin-left: 0;color: #4E5153 !important;font-size: 16px !important;}}
}
:global{.ant-tabs {overflow: revert;}
}

React 前端日历组件相关推荐

  1. 前端ui组件(1):日程排班—11个优秀JavaScript 日历插件

    日历是我们生活中重要的一部分.在当今世界,人们大多使用网络或移动日历.它们随处可见,包括在各种软件中:预订应用.旅行软件.项目管理.管理面板等. 出于多种原因,用户可能需要在网站上使用日历.用户需要容 ...

  2. 组件分享之前端组件——甘特图时间表时间线日历组件

    组件分享之前端组件--甘特图时间表时间线日历组件 背景 近期正在探索前端.后端.系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件专题,后续该专题将包含各类语言中的一些常用组 ...

  3. 【日历组件】前端使用fullcalendar组件实现会议室预约功能

    ##框架描述 ###使用框架技术 使用fullcalendar,作为日历组件的基本框架 使用layer弹出框,作为填写会议室预约详情的组件 ##关键技术讲解 ###日历组件的点击事件 点击事件使用ev ...

  4. react 日历组件拖拽部分逻辑/元素

    目标 我们在上半部分实现了一个可以渲染年月的月视图的日历组件.其中有一个api是cellAppend,可以往日历内容区域写内容. 代码示例如下: <CalendarcellAppend={(ce ...

  5. 可视化搭建平台的地图组件和日历组件方案选型

    可视化搭建平台除了需要为用户提供简单便捷的操作方式之外, 还需要提供丰富的组件支持和组件扩展, 这样才能满足更多用户的业务需求. 在 H5-dooring 创建的初期主要考虑的方向是用户使用的便捷性, ...

  6. APICloud AVM框架 封装日历组件

    AVM(Application-View-Model)前端组件化开发模式基于标准Web Components组件化思想,提供包含虚拟DOM和Runtime的编程框架avm.js以及多端统一编译工具,完 ...

  7. react前端开发_是的,React正在接管前端开发。 问题是为什么。

    react前端开发 by Samer Buna 通过Samer Buna 是的,React正在接管前端开发. 问题是为什么. (Yes, React is taking over front-end ...

  8. element ui input视图没刷新_聊聊前端 UI 组件:组件体系

    本文是文章系列「聊聊前端 UI 组件」的第三篇. 在本系列的上篇文章<聊聊前端 UI 组件:组件特征>中,通过从关注点分离的角度进行前端 UI 组件的构成分析,并以较为抽象的视角对 UI ...

  9. react实现汉堡_利用 React 高阶组件实现一个面包屑导航

    什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理完成后的 React 组件.React 高阶组件在 React 生态中使用的非常频繁, ...

最新文章

  1. 关于编译原理的一点看法
  2. 芯片数据手册datasheet哪里找?
  3. 【动态数组】数据结构01-(java实现)
  4. 【重要】有三AI计算机视觉培养计划组合优惠,4月份起发生重大变化
  5. 康奈尔ECE MEng项目拒信+1 哈哈哈
  6. STM32L1X系列GPIO运用
  7. java 内部类异常_Java笔记(三 内部类、异常、编程规范)
  8. druid jar包_使用druid实现Spring boot配置文件中数据库密码密文存储
  9. 学计算机随随便便上万,大学“最烧钱”专业排行榜,“家境一般”慎入,“土豪”请随意...
  10. PHP文字转语音合成网源码 百度API开发
  11. Python模块——HashLib(摘要算法)与base64
  12. entity framework 动态条件
  13. 万字长文人脸识别深度研究:发展与市场、市场研究、流程及主要技术、行业应用、产品落地和个人看法
  14. java项目配置双数据源,对两个不同服务器上的数据库中的数据进行CRUD
  15. 因为计算机中丢失d3dx926.dll,win10系统打开程序提示丢失d3dx9 26.dll的解决方法
  16. 大二妹子问锋哥,学Java还是学C,考研还是就业?
  17. android 多人视频,Android QQ 5.0 正式版:全新界面、精彩动态、多人视频/音频
  18. javaWeb 中Tomcat 10 jsp文件内置对象不能正常使用的问题(已解决)
  19. kaggle——Santander Customer Transaction Prediction
  20. linux 禁用本地策略应用,如何在AOSP 9构建中的SELinux策略中禁用SELinux或允许新域?...

热门文章

  1. 手把手教你使用 VirtualBox 挂载虚拟光驱
  2. 【杂事随写】 记一次移动硬盘写入速度骤降
  3. C++文件操作无法写入的问题
  4. 智慧旅游海内外现况详情及发展对策
  5. android:报Activity has leaked IntentReceiver或者receiver is not registered错误
  6. ClickHouse最版本源码编译(X86)
  7. 一文入门Golang文件操作——增删改查【超基础】
  8. pomtail 启动失败
  9. 微信小程序跳转页面带参数
  10. opencv 四 Mat的基本操作3(高通滤波、低通滤波、对比度调节)