From ca1c613dbba333397a30c854931ac8a6a3e15d8a Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Sat, 24 Aug 2019 11:47:09 +0800 Subject: [PATCH 01/68] add hour and minute --- assets/index/Calendar.less | 68 ++++++++++++++++++++++++++- examples/antd-calendar.js | 10 ++-- examples/antd-month-calendar.js | 10 ++-- examples/antd-range-calendar.js | 10 ++-- examples/control-panel.js | 6 +-- examples/custom-clear-icon.js | 6 +-- examples/full-calendar.js | 8 ++-- examples/getCalendarContainer.js | 10 ++-- examples/start-end-range.js | 10 ++-- examples/start-end.js | 10 ++-- examples/week.js | 26 +++++------ package.json | 12 ++--- src/Calendar.jsx | 14 +++++- src/calendar/CalendarRightPanel.jsx | 72 +++++++++++++++++++++++++++++ 14 files changed, 211 insertions(+), 61 deletions(-) create mode 100644 src/calendar/CalendarRightPanel.jsx diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 3a755cb28..ad26d4ffa 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -2,7 +2,7 @@ position: relative; outline: none; font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans-serif; - width: 253px; + width: fit-content; border: 1px solid #ccc; list-style: none; font-size: 12px; @@ -14,9 +14,15 @@ border: 1px solid #ccc; line-height: 1.5; + + &-date-panel, &-date-panel-container { + display: flex; + } + &-date-panel, &-panel { position: relative; outline: none; + display: block; } &-week-number { @@ -127,6 +133,66 @@ height: 217px; } + &-right-panel { + width: 68px; + height: inherit; + } + + &-right-panel-header { + height: 34px; + line-height: 34px; + span { + transform: rotate(-90deg); + } + } + + &-right-panel-body { + height: 217px; + border-left: 1px solid #ccc; + overflow-y: scroll; + ul { + list-style: none; + box-sizing: border-box; + margin: 0; + padding: 0; + width: 100%; + } + ul li { + text-align: center; + padding: 8px 0; + cursor: pointer; + } + ul li:hover { + color: #e8bf6a; + } + ul li.highlight { + color: #f09f3f; + } + &::-webkit-scrollbar { + width: 0; + } + } + + &-right-panel-footer { + height: 39px; + line-height: 34px; + border-left: 1px solid #ccc; + span { + transform: rotate(90deg); + } + } + + &-right-panel-header, &-right-panel-footer { + display: flex; + justify-content: center; + cursor: pointer; + color: #999; + font-size: 16px; + span:after { + content: '›'; + } + } + table { border-collapse: collapse; max-width: 100%; diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index ea2314114..af7fa46f9 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -1,13 +1,13 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import Calendar from '@seafile/seafile-calendar'; +import DatePicker from '@seafile/seafile-calendar/src/Picker'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import 'rc-time-picker/assets/index.css'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; diff --git a/examples/antd-month-calendar.js b/examples/antd-month-calendar.js index 15ed13f29..86f1620ec 100644 --- a/examples/antd-month-calendar.js +++ b/examples/antd-month-calendar.js @@ -1,14 +1,14 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; -import MonthCalendar from 'rc-calendar/src/MonthCalendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import MonthCalendar from '@seafile/seafile-calendar/src/MonthCalendar'; +import DatePicker from '@seafile/seafile-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import moment from 'moment'; import 'moment/locale/zh-cn'; diff --git a/examples/antd-range-calendar.js b/examples/antd-range-calendar.js index 717d77a19..63620dfeb 100644 --- a/examples/antd-range-calendar.js +++ b/examples/antd-range-calendar.js @@ -2,12 +2,12 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Picker from 'rc-calendar/src/Picker'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import Picker from '@seafile/seafile-calendar/src/Picker'; +import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import 'rc-time-picker/assets/index.css'; import moment from 'moment'; diff --git a/examples/control-panel.js b/examples/control-panel.js index 0a8ac633f..a2ba16e4b 100644 --- a/examples/control-panel.js +++ b/examples/control-panel.js @@ -1,9 +1,9 @@ /* eslint react/no-multi-comp:0, no-console:0, no-unused-vars:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar/src'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; +import Calendar from '@seafile/seafile-calendar/src'; +import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar'; import Select, { Option } from 'rc-select'; import 'rc-select/assets/index.css'; diff --git a/examples/custom-clear-icon.js b/examples/custom-clear-icon.js index 93b8d4c36..f5f6fe71d 100644 --- a/examples/custom-clear-icon.js +++ b/examples/custom-clear-icon.js @@ -1,10 +1,10 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; +import Calendar from '@seafile/seafile-calendar'; +import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar'; import 'rc-time-picker/assets/index.css'; import 'moment/locale/zh-cn'; diff --git a/examples/full-calendar.js b/examples/full-calendar.js index 2cf7ed64b..5936b70df 100644 --- a/examples/full-calendar.js +++ b/examples/full-calendar.js @@ -1,15 +1,15 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; -import FullCalendar from 'rc-calendar/src/FullCalendar'; +import FullCalendar from '@seafile/seafile-calendar/src/FullCalendar'; import 'rc-select/assets/index.css'; import Select from 'rc-select'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import moment from 'moment'; import 'moment/locale/zh-cn'; diff --git a/examples/getCalendarContainer.js b/examples/getCalendarContainer.js index fe3c4fd1a..cc596bb15 100644 --- a/examples/getCalendarContainer.js +++ b/examples/getCalendarContainer.js @@ -1,13 +1,13 @@ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import Calendar from '@seafile/seafile-calendar'; +import DatePicker from '@seafile/seafile-calendar/src/Picker'; import Dialog from 'rc-dialog'; import 'rc-dialog/assets/index.css'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import moment from 'moment'; import 'moment/locale/zh-cn'; diff --git a/examples/start-end-range.js b/examples/start-end-range.js index 013dfd1de..2d78f1404 100644 --- a/examples/start-end-range.js +++ b/examples/start-end-range.js @@ -1,13 +1,13 @@ /* eslint react/no-multi-comp:0, no-console:0, react/prop-types:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar'; +import DatePicker from '@seafile/seafile-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import moment from 'moment'; import 'moment/locale/zh-cn'; diff --git a/examples/start-end.js b/examples/start-end.js index 8014be62b..eace02320 100644 --- a/examples/start-end.js +++ b/examples/start-end.js @@ -1,13 +1,13 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import Calendar from '@seafile/seafile-calendar'; +import DatePicker from '@seafile/seafile-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import 'rc-time-picker/assets/index.css'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; diff --git a/examples/week.js b/examples/week.js index 245b98e02..be76c201b 100644 --- a/examples/week.js +++ b/examples/week.js @@ -1,13 +1,13 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '@seafile/seafile-calendar/assets/index.less'; import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import Calendar from '@seafile/seafile-calendar'; +import DatePicker from '@seafile/seafile-calendar/src/Picker'; +import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; +import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import moment from 'moment'; import 'moment/locale/zh-cn'; @@ -27,13 +27,13 @@ const style = ` .week-calendar { width: 386px; } -.week-calendar .rc-calendar-tbody > tr:hover -.rc-calendar-date { +.week-calendar .@seafile/seafile-calendar-tbody > tr:hover +.@seafile/seafile-calendar-date { background: #ebfaff; } -.week-calendar .rc-calendar-tbody > tr:hover -.rc-calendar-selected-day .rc-calendar-date { +.week-calendar .@seafile/seafile-calendar-tbody > tr:hover +.@seafile/seafile-calendar-selected-day .@seafile/seafile-calendar-date { background: #3fc7fa; } @@ -45,7 +45,7 @@ const style = ` width:100px; border-right: 1px solid #ccc; } -.week-calendar .rc-calendar-panel { +.week-calendar .@seafile/seafile-calendar-panel { margin-left: 100px; } `; @@ -78,14 +78,14 @@ class Demo extends React.Component { const selectedValue = this.state.value; if (selectedValue && current.year() === selectedValue.year() && current.week() === selectedValue.week()) { - return (
-
+ return (
+
{current.date()}
); } return ( -
+
{current.date()}
); } diff --git a/package.json b/package.json index e614f3eff..976b0ef75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "rc-calendar", - "version": "9.15.5", + "name": "@seafile/seafile-calendar", + "version": "0.0.3", "description": "React Calendar", "keywords": [ "react", @@ -20,14 +20,14 @@ ], "main": "lib/index", "module": "es/index", - "homepage": "http://github.com/react-component/calendar", - "author": "yiminghe@gmail.com", + "homepage": "https://github.com/seafileltd/calendar", + "author": "seafile", "repository": { "type": "git", - "url": "git@github.com:react-component/calendar.git" + "url": "https://github.com/seafileltd/calendar.git" }, "bugs": { - "url": "http://github.com/react-component/calendar/issues" + "url": "https://github.com/seafileltd/calendar/issues" }, "licenses": "MIT", "config": { diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 2e8d89898..623308c5c 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -6,6 +6,7 @@ import { polyfill } from 'react-lifecycles-compat'; import DateTable from './date/DateTable'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; +import CalendarRightPanel from './calendar/CalendarRightPanel'; import { calendarMixinWrapper, calendarMixinPropTypes, @@ -45,6 +46,7 @@ class Calendar extends React.Component { showWeekNumber: PropTypes.bool, showToday: PropTypes.bool, showOk: PropTypes.bool, + showTimeAndHour: PropTypes.bool, onSelect: PropTypes.func, onOk: PropTypes.func, onKeyDown: PropTypes.func, @@ -69,6 +71,7 @@ class Calendar extends React.Component { ...defaultProp, showToday: true, showDateInput: true, + showTimeAndHour: false, timePicker: null, onOk: noop, onPanelChange: noop, @@ -274,7 +277,7 @@ class Calendar extends React.Component { const { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, - disabledTime, clearIcon, renderFooter, inputMode, + disabledTime, clearIcon, renderFooter, inputMode, showTimeAndHour, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -328,6 +331,7 @@ class Calendar extends React.Component { } children.push(
{dateInputElement} +
+ {showTimeAndHour && + + } +
); return this.renderRoot({ diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx new file mode 100644 index 000000000..0c45b320c --- /dev/null +++ b/src/calendar/CalendarRightPanel.jsx @@ -0,0 +1,72 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import moment from 'moment'; + +export default class CalendarRightPanel extends React.Component { + + static propTypes = { + prefixCls: PropTypes.string, + value: PropTypes.object, + onSelect: PropTypes.func, + } + + constructor(props) { + super(props); + this.state = { + highlightTime: this.props.value || null, + }; + this.timeRef = React.createRef(); + } + + onSelect = (value) => { + this.setState({ + highlightTime: value, + }); + this.props.onSelect(value); + } + + scrollUp = () => { + this.timeRef.current.scrollBy(0, -200); + } + + scrollDown = () => { + this.timeRef.current.scrollBy(0, 200); + } + + render() { + const { value, prefixCls } = this.props; + const selectedDate = value.format().slice(0, 10); + const times = []; + for (let i = 0; i < 24; i++) { + const str = (String(i) + ':00').padStart(5, '0'); + const str1 = (String(i) + ':30').padStart(5, '0'); + times.push(str); + times.push(str1); + } + return ( +
+
+ +
+
+
    + {times.map((time) => { + const current = moment(selectedDate + ' ' + time); + const isHightlight = current.isSame(this.state.highlightTime) ? 'highlight' : ''; + return ( +
  • {time}
  • + ); + })} +
+
+
+ +
+
+ ); + } +} From e4459ad744ea44227b60472b9ce202767f0c9de2 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Sat, 24 Aug 2019 16:52:45 +0800 Subject: [PATCH 02/68] change default color --- assets/common/FullCalendar.less | 12 ++++++------ assets/index/Calendar.less | 18 +++++++++--------- assets/index/DecadePanel.less | 8 ++++---- assets/index/Input.less | 6 +++--- assets/index/MonthPanel.less | 8 ++++---- assets/index/TimePanel.less | 6 +++--- assets/index/YearPanel.less | 8 ++++---- src/Calendar.jsx | 2 +- src/calendar/CalendarRightPanel.jsx | 6 +++--- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/assets/common/FullCalendar.less b/assets/common/FullCalendar.less index b2713e218..4c8d66a20 100644 --- a/assets/common/FullCalendar.less +++ b/assets/common/FullCalendar.less @@ -19,13 +19,13 @@ float: right; display: inline-block; &-normal:hover { - border-color: #23c0fa; + border-color: #f09f4g; box-shadow: 0 0 2px rgba(45, 183, 245, 0.8); cursor: pointer; } &-focus { - border-color: #3fc7fa; - background-color: #3fc7fa; + border-color: #f09f3f; + background-color: #f09f3f; color: #fff; } > span { @@ -79,13 +79,13 @@ } &-selected-day .@{prefixClass}-date, &-month-panel-selected-cell .@{prefixClass}-month-panel-month { - background-color: #ebfaff; + background-color: #fcecd9; color: #666; } &-today .@{prefixClass}-date, &-month-panel-selected-cell .@{prefixClass}-month-panel-month { - border-top-color: #3FC7FA; - color: #3FC7FA; + border-top-color: #f09f3f; + color: #f09f3f; } } } diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index ad26d4ffa..4bb221464 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -52,7 +52,7 @@ &:hover { cursor: pointer; - color: #23c0fa; + color: #f09f4g; } } @@ -85,7 +85,7 @@ &:hover { cursor: pointer; - color: #23c0fa; + color: #f09f4g; } &.@{prefixClass}-time-status:hover{ cursor: pointer; @@ -108,7 +108,7 @@ line-height: 34px; &:hover { - color: #23c0fa; + color: #f09f4g; } } @@ -243,25 +243,25 @@ text-align: center; &:hover { - background: #ebfaff; + background: #fcecd9; cursor: pointer; } } &-selected-day &-date { - background: tint(#3fc7fa, 80%); + background: tint(#f09f3f, 80%); } &-selected-date &-date { - background: #3fc7fa; + background: #f09f3f; color: #fff; &:hover { - background: #3fc7fa; + background: #f09f3f; } } &-today &-date { - border: 1px solid #3fc7fa; + border: 1px solid #f09f3f; } &-disabled-cell &-date { @@ -344,7 +344,7 @@ &:hover { cursor: pointer; - color: #23c0fa; + color: #f09f4g; } &-disabled { diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index f83c591d0..e8dcbd734 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -34,7 +34,7 @@ &:hover { cursor: pointer; - color: #23c0fa; + color: #f09f4g; } } } @@ -96,17 +96,17 @@ text-align: center; &:hover { - background: #ebfaff; + background: #fcecd9; cursor: pointer; } } .@{prefixClass}-decade-panel-selected-cell .@{prefixClass}-decade-panel-decade { - background: #3fc7fa; + background: #f09f3f; color: #fff; &:hover { - background: #3fc7fa; + background: #f09f3f; color: #fff; } } diff --git a/assets/index/Input.less b/assets/index/Input.less index ac081bc23..9ea3caa2c 100644 --- a/assets/index/Input.less +++ b/assets/index/Input.less @@ -12,11 +12,11 @@ transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), background 0.3s cubic-bezier(0.35, 0, 0.25, 1), box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1); &:hover { - border-color: #23c0fa; + border-color: #f09f4g; } &:focus { - border-color: #23c0fa; - box-shadow: 0 0 3px #23c0fa; + border-color: #f09f4g; + box-shadow: 0 0 3px #f09f4g; } } \ No newline at end of file diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index 1b35f0e6b..7a9fac133 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -38,7 +38,7 @@ &:hover { cursor: pointer; - color: #23c0fa; + color: #f09f4g; } } } @@ -111,7 +111,7 @@ text-align: center; &:hover { - background: #ebfaff; + background: #fcecd9; cursor: pointer; } } @@ -129,11 +129,11 @@ } .@{prefixClass}-month-panel-selected-cell .@{prefixClass}-month-panel-month { - background: #3fc7fa; + background: #f09f3f; color: #fff; &:hover { - background: #3fc7fa; + background: #f09f3f; color: #fff; } } diff --git a/assets/index/TimePanel.less b/assets/index/TimePanel.less index 6701a53c7..afcf7a78a 100644 --- a/assets/index/TimePanel.less +++ b/assets/index/TimePanel.less @@ -57,18 +57,18 @@ margin: 0 auto; &:hover { - background: #ebfaff; + background: #fcecd9; cursor: pointer; } } .@{prefixClass}-time-panel-selected-cell .@{prefixClass}-time-panel-time { - background: #3fc7fa; + background: #f09f3f; color: #fff; &:hover { - background: #3fc7fa; + background: #f09f3f; color: #fff; } } \ No newline at end of file diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index 6b31dc8ec..cbdb0fc3d 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -38,7 +38,7 @@ &:hover { cursor: pointer; - color: #23c0fa; + color: #f09f4g; } } } @@ -110,17 +110,17 @@ text-align: center; &:hover { - background: #ebfaff; + background: #fcecd9; cursor: pointer; } } .@{prefixClass}-year-panel-selected-cell .@{prefixClass}-year-panel-year { - background: #3fc7fa; + background: #f09f3f; color: #fff; &:hover { - background: #3fc7fa; + background: #f09f3f; color: #fff; } } diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 623308c5c..76a7dfbd7 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -390,7 +390,7 @@ class Calendar extends React.Component { onCloseTimePicker={this.closeTimePicker} />
- {showTimeAndHour && + {!showTimeAndHour &&
@@ -52,12 +53,11 @@ export default class CalendarRightPanel extends React.Component {
    {times.map((time) => { const current = moment(selectedDate + ' ' + time); - const isHightlight = current.isSame(this.state.highlightTime) ? 'highlight' : ''; return (
  • {time}
  • ); })} From 9a16248917f6987c3fe385ace12e6bf20a0ecad4 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Sat, 24 Aug 2019 17:16:35 +0800 Subject: [PATCH 03/68] update readme --- README.md | 6 ++++++ src/Calendar.jsx | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f02550fef..da32aad3b 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,12 @@ http://react-component.github.io/calendar/examples/index.html auto whether has ok button in footer + + showHourAndMinute + Boolean + auto + whether has hour-minute chooser in the right panel(for dtable date column) + timePicker React Element diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 76a7dfbd7..4f2366287 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -46,7 +46,7 @@ class Calendar extends React.Component { showWeekNumber: PropTypes.bool, showToday: PropTypes.bool, showOk: PropTypes.bool, - showTimeAndHour: PropTypes.bool, + showHourAndMinute: PropTypes.bool, onSelect: PropTypes.func, onOk: PropTypes.func, onKeyDown: PropTypes.func, @@ -71,7 +71,7 @@ class Calendar extends React.Component { ...defaultProp, showToday: true, showDateInput: true, - showTimeAndHour: false, + showHourAndMinute: false, timePicker: null, onOk: noop, onPanelChange: noop, @@ -277,7 +277,7 @@ class Calendar extends React.Component { const { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, - disabledTime, clearIcon, renderFooter, inputMode, showTimeAndHour, + disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -390,7 +390,7 @@ class Calendar extends React.Component { onCloseTimePicker={this.closeTimePicker} />
- {!showTimeAndHour && + {showHourAndMinute && Date: Sat, 24 Aug 2019 17:17:37 +0800 Subject: [PATCH 04/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 976b0ef75..aac4e10a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.3", + "version": "0.0.4", "description": "React Calendar", "keywords": [ "react", From 60e568a4da07d3f19924cd3b2aabe8d4280bd9ea Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Mon, 26 Aug 2019 15:41:45 +0800 Subject: [PATCH 05/68] change default time to 08:00 --- package.json | 2 +- src/calendar/CalendarRightPanel.jsx | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index aac4e10a0..602ce2869 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.4", + "version": "0.0.5", "description": "React Calendar", "keywords": [ "react", diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 5daa40b94..b50245515 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -33,6 +33,11 @@ export default class CalendarRightPanel extends React.Component { this.timeRef.current.scrollBy(0, 200); } + componentDidMount() { + // The default time is 8, page scroll to 08:00 + this.timeRef.current.scrollTo(0, 34 * 16); + } + render() { const { value, prefixCls } = this.props; const selectedDate = value.format().slice(0, 10); From 09cef9ce7c845cd41785f882d774b3acef2c5a9d Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Tue, 27 Aug 2019 15:39:13 +0800 Subject: [PATCH 06/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 602ce2869..f07f8f605 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.5", + "version": "0.0.6", "description": "React Calendar", "keywords": [ "react", From b2c738711b960dc17ca5fbca9c0f4737f48b54fa Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Thu, 29 Aug 2019 10:40:16 +0800 Subject: [PATCH 07/68] set right panel locale --- src/Calendar.jsx | 1 + src/calendar/CalendarRightPanel.jsx | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 4f2366287..12ed1ab80 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -394,6 +394,7 @@ class Calendar extends React.Component { } diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index b50245515..8e77bf24c 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -8,6 +8,7 @@ export default class CalendarRightPanel extends React.Component { prefixCls: PropTypes.string, value: PropTypes.object, onSelect: PropTypes.func, + locale: PropTypes.object, } constructor(props) { @@ -39,7 +40,7 @@ export default class CalendarRightPanel extends React.Component { } render() { - const { value, prefixCls } = this.props; + const { value, prefixCls, locale } = this.props; const selectedDate = value.format().slice(0, 10); const times = []; for (let i = 0; i < 24; i++) { @@ -49,6 +50,7 @@ export default class CalendarRightPanel extends React.Component { times.push(str1); } const highlightTime = this.state.highlightTime ? this.state.highlightTime.format().slice(11, 16) : null; + const isEnGb = (locale && locale.year === 'Year'); return (
@@ -57,7 +59,8 @@ export default class CalendarRightPanel extends React.Component {
    {times.map((time) => { - const current = moment(selectedDate + ' ' + time); + let current = moment(selectedDate + ' ' + time); + current = isEnGb ? current.locale('en-gb').utcOffset(0) : current.locale('zh-cn').utcOffset(8); return (
  • Date: Thu, 29 Aug 2019 10:56:09 +0800 Subject: [PATCH 08/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f07f8f605..ef3406906 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.6", + "version": "0.0.7", "description": "React Calendar", "keywords": [ "react", From 270b31734395c5922bb9231eaf4fdf1e24c5a132 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Thu, 29 Aug 2019 11:21:34 +0800 Subject: [PATCH 09/68] update version --- package.json | 2 +- src/calendar/CalendarRightPanel.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ef3406906..f1ccf05e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.7", + "version": "0.0.8", "description": "React Calendar", "keywords": [ "react", diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 8e77bf24c..af2e6a9cb 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -60,7 +60,7 @@ export default class CalendarRightPanel extends React.Component {
      {times.map((time) => { let current = moment(selectedDate + ' ' + time); - current = isEnGb ? current.locale('en-gb').utcOffset(0) : current.locale('zh-cn').utcOffset(8); + current = isEnGb ? current.locale('en-gb') : current.locale('zh-cn'); return (
    • Date: Tue, 3 Dec 2019 10:33:57 +0800 Subject: [PATCH 10/68] set Sunday as the first day of the week --- examples/antd-calendar.js | 1 + src/calendar/CalendarRightPanel.jsx | 19 ++++++++++--------- src/date/DateTBody.jsx | 5 ++++- src/date/DateTHead.jsx | 4 +++- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index af7fa46f9..2db2769c2 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -150,6 +150,7 @@ class Demo extends React.Component { showDateInput={state.showDateInput} disabledDate={disabledDate} focusablePanel={false} + showHourAndMinute />); return (
      diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index af2e6a9cb..e439429ef 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -19,6 +19,11 @@ export default class CalendarRightPanel extends React.Component { this.timeRef = React.createRef(); } + componentDidMount() { + // The default time is 8, page scroll to 08:00 + this.timeRef.current.scrollTo(0, 34 * 16); + } + onSelect = (value) => { this.setState({ highlightTime: value, @@ -34,22 +39,18 @@ export default class CalendarRightPanel extends React.Component { this.timeRef.current.scrollBy(0, 200); } - componentDidMount() { - // The default time is 8, page scroll to 08:00 - this.timeRef.current.scrollTo(0, 34 * 16); - } - render() { const { value, prefixCls, locale } = this.props; const selectedDate = value.format().slice(0, 10); const times = []; for (let i = 0; i < 24; i++) { - const str = (String(i) + ':00').padStart(5, '0'); - const str1 = (String(i) + ':30').padStart(5, '0'); + const str = (`${String(i)}:00`).padStart(5, '0'); + const str1 = (`${String(i)}:30`).padStart(5, '0'); times.push(str); times.push(str1); } - const highlightTime = this.state.highlightTime ? this.state.highlightTime.format().slice(11, 16) : null; + const highlight = this.state.highlightTime; + const highlightTime = highlight ? highlight.format().slice(11, 16) : null; const isEnGb = (locale && locale.year === 'Year'); return (
      @@ -59,7 +60,7 @@ export default class CalendarRightPanel extends React.Component {
        {times.map((time) => { - let current = moment(selectedDate + ' ' + time); + let current = moment(`${selectedDate} ${time}`); current = isEnGb ? current.locale('en-gb') : current.locale('zh-cn'); return (
      • Date: Tue, 3 Dec 2019 10:50:00 +0800 Subject: [PATCH 11/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f1ccf05e8..1a351b1d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.8", + "version": "0.0.9", "description": "React Calendar", "keywords": [ "react", From 9ade1657af0b352cd66148a49d16d055c34206ab Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Tue, 3 Dec 2019 11:09:52 +0800 Subject: [PATCH 12/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a351b1d9..68652033d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.9", + "version": "0.0.10", "description": "React Calendar", "keywords": [ "react", From 79d2b6208682d372855f1797f2718047a681b36b Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Thu, 23 Apr 2020 11:15:31 +0800 Subject: [PATCH 13/68] set default locale is enUS --- src/calendar/CalendarRightPanel.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index e439429ef..192bea2c4 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -51,7 +51,7 @@ export default class CalendarRightPanel extends React.Component { } const highlight = this.state.highlightTime; const highlightTime = highlight ? highlight.format().slice(11, 16) : null; - const isEnGb = (locale && locale.year === 'Year'); + const isZhcn = (locale && locale.today === '今天'); return (
        @@ -61,7 +61,7 @@ export default class CalendarRightPanel extends React.Component {
          {times.map((time) => { let current = moment(`${selectedDate} ${time}`); - current = isEnGb ? current.locale('en-gb') : current.locale('zh-cn'); + current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb'); return (
        • Date: Fri, 24 Apr 2020 11:01:32 +0800 Subject: [PATCH 14/68] update --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 68652033d..4c0bd3a0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.10", + "version": "0.0.11", "description": "React Calendar", "keywords": [ "react", From 1462024673f094724c3d07db798168683001c97a Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Sat, 9 May 2020 18:01:51 +0800 Subject: [PATCH 15/68] change classname --- assets/index/Calendar.less | 2 +- src/calendar/CalendarRightPanel.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 4bb221464..8b6a096bc 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -165,7 +165,7 @@ ul li:hover { color: #e8bf6a; } - ul li.highlight { + .@{prefixClass}-selected-time { color: #f09f3f; } &::-webkit-scrollbar { diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 192bea2c4..3326bdd28 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -66,7 +66,7 @@ export default class CalendarRightPanel extends React.Component {
        • {time}
        • ); })} From b6f96467d7b1d6a58268f501318a38f711c147e5 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Sat, 9 May 2020 21:58:40 +0800 Subject: [PATCH 16/68] update version to 0.0.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c0bd3a0d..72640e8e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.11", + "version": "0.0.12", "description": "React Calendar", "keywords": [ "react", From a1565d58c62f3794a03cafb44e3c9ecb2d3ed4d8 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Tue, 1 Sep 2020 17:31:50 +0800 Subject: [PATCH 17/68] change right panel click callback --- .travis.yml | 3 +-- README.md | 6 ++++++ examples/antd-calendar.js | 5 +++++ index.d.ts | 3 ++- package.json | 2 +- src/Calendar.jsx | 5 ++++- src/calendar/CalendarRightPanel.jsx | 4 +++- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7aff03e0c..5c04fd525 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,7 @@ sudo: false notifications: email: - - yiminghe@gmail.com - - hust2012jiangkai@gmail.com + - bing.an@seafile.com node_js: - 10 diff --git a/README.md b/README.md index da32aad3b..6cc73412a 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,12 @@ http://react-component.github.io/calendar/examples/index.html called when ok button is pressed, only if it's visible + + onClickRightPanelTime + Function() + + called when right panel hour and minute is clicked, only prop showHourAndMinute is true + dateInputPlaceholder String diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 2db2769c2..06479c651 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -129,6 +129,10 @@ class Demo extends React.Component { }); } + onClickRightPanelTime = () => { + this.onOpenChange(false); + } + getCalendarContainer = () => this.calendarContainerRef.current; toggleDisabled = () => { @@ -151,6 +155,7 @@ class Demo extends React.Component { disabledDate={disabledDate} focusablePanel={false} showHourAndMinute + onClickRightPanelTime={this.onClickRightPanelTime} />); return (
          diff --git a/index.d.ts b/index.d.ts index f1edde5e7..8ae68c177 100644 --- a/index.d.ts +++ b/index.d.ts @@ -25,6 +25,7 @@ export interface Props { onSelect?: (date: Moment) => void; onOk?: () => void; onKeyDown?: () => void; + onClickRightPanelTime?: () => void; timePicker?: React.ReactNode; dateInputPlaceholder?: string; onClear?: () => void; @@ -35,7 +36,7 @@ export interface Props { dateRender?: (current: Moment, value: Moment) => React.ReactNode; renderFooter?: () => React.ReactNode; renderSidebar?: () => React.ReactNode; - inputMode?:String + inputMode?: string; } export default class ReactCalendar extends React.Component {} diff --git a/package.json b/package.json index 72640e8e1..170f23386 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.12", + "version": "0.0.13", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 12ed1ab80..abeccea0d 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -64,6 +64,7 @@ class Calendar extends React.Component { focusablePanel: PropTypes.bool, inputMode: PropTypes.string, onBlur: PropTypes.func, + onClickRightPanelTime: PropTypes.func, } static defaultProps = { @@ -75,6 +76,7 @@ class Calendar extends React.Component { timePicker: null, onOk: noop, onPanelChange: noop, + onClickRightPanelTime: noop, focusablePanel: true, } @@ -276,7 +278,7 @@ class Calendar extends React.Component { const { props, state } = this; const { locale, prefixCls, disabledDate, - dateInputPlaceholder, timePicker, + dateInputPlaceholder, timePicker, onClickRightPanelTime, disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, } = props; const { value, selectedValue, mode } = state; @@ -396,6 +398,7 @@ class Calendar extends React.Component { value={value} locale={locale} onSelect={this.onDateTableSelect} + onClickRightPanelTime={onClickRightPanelTime} /> }
          diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 3326bdd28..4c69288e7 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -8,6 +8,7 @@ export default class CalendarRightPanel extends React.Component { prefixCls: PropTypes.string, value: PropTypes.object, onSelect: PropTypes.func, + onClickRightPanelTime: PropTypes.func, locale: PropTypes.object, } @@ -29,6 +30,7 @@ export default class CalendarRightPanel extends React.Component { highlightTime: value, }); this.props.onSelect(value); + this.props.onClickRightPanelTime(); } scrollUp = () => { @@ -66,7 +68,7 @@ export default class CalendarRightPanel extends React.Component {
        • {time}
        • ); })} From a3e5ade8ea2dea049773fd14fb75411f6f4c3947 Mon Sep 17 00:00:00 2001 From: zxj96 <519213124@qq.com> Date: Fri, 9 Apr 2021 17:32:40 +0800 Subject: [PATCH 18/68] Choose precise time to improve --- package.json | 2 +- src/Calendar.jsx | 2 ++ src/calendar/CalendarRightPanel.jsx | 28 ++++++++++++++++++---------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 170f23386..0ac2fb88b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.13", + "version": "0.0.15", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index abeccea0d..1495affb2 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -47,6 +47,7 @@ class Calendar extends React.Component { showToday: PropTypes.bool, showOk: PropTypes.bool, showHourAndMinute: PropTypes.bool, + defaultMinutesTime: PropTypes.string, onSelect: PropTypes.func, onOk: PropTypes.func, onKeyDown: PropTypes.func, @@ -399,6 +400,7 @@ class Calendar extends React.Component { locale={locale} onSelect={this.onDateTableSelect} onClickRightPanelTime={onClickRightPanelTime} + defaultMinutesTime={this.props.defaultMinutesTime} /> }
          diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 4c69288e7..87f896762 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -10,6 +10,7 @@ export default class CalendarRightPanel extends React.Component { onSelect: PropTypes.func, onClickRightPanelTime: PropTypes.func, locale: PropTypes.object, + defaultMinutesTime: PropTypes.string, } constructor(props) { @@ -18,11 +19,14 @@ export default class CalendarRightPanel extends React.Component { highlightTime: this.props.value || null, }; this.timeRef = React.createRef(); + this.times = this.getTimes(); } componentDidMount() { - // The default time is 8, page scroll to 08:00 - this.timeRef.current.scrollTo(0, 34 * 16); + const { defaultMinutesTime } = this.props; + const showTimeIndex = this.times.findIndex(item => item === defaultMinutesTime); + const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex : 16; + this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); } onSelect = (value) => { @@ -33,6 +37,17 @@ export default class CalendarRightPanel extends React.Component { this.props.onClickRightPanelTime(); } + getTimes = () => { + const times = []; + for (let i = 0; i < 24; i++) { + const str = (`${String(i)}:00`).padStart(5, '0'); + const str1 = (`${String(i)}:30`).padStart(5, '0'); + times.push(str); + times.push(str1); + } + return times; + } + scrollUp = () => { this.timeRef.current.scrollBy(0, -200); } @@ -44,13 +59,6 @@ export default class CalendarRightPanel extends React.Component { render() { const { value, prefixCls, locale } = this.props; const selectedDate = value.format().slice(0, 10); - const times = []; - for (let i = 0; i < 24; i++) { - const str = (`${String(i)}:00`).padStart(5, '0'); - const str1 = (`${String(i)}:30`).padStart(5, '0'); - times.push(str); - times.push(str1); - } const highlight = this.state.highlightTime; const highlightTime = highlight ? highlight.format().slice(11, 16) : null; const isZhcn = (locale && locale.today === '今天'); @@ -61,7 +69,7 @@ export default class CalendarRightPanel extends React.Component {
          - {times.map((time) => { + {this.times.map((time) => { let current = moment(`${selectedDate} ${time}`); current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb'); return ( From 062781409f1525d5fa8a5a73d7a490071f138c60 Mon Sep 17 00:00:00 2001 From: zxj96 <519213124@qq.com> Date: Thu, 17 Feb 2022 17:08:02 +0800 Subject: [PATCH 19/68] dayjs replace moment --- assets/index/Calendar.less | 2 +- examples/antd-calendar.js | 30 +- examples/antd-month-calendar.js | 13 +- examples/antd-range-calendar.js | 29 +- examples/custom-clear-icon.js | 4 +- examples/full-calendar.js | 14 +- examples/getCalendarContainer.js | 14 +- examples/start-end-range.js | 14 +- examples/start-end.js | 14 +- examples/week.js | 30 +- index.d.ts | 20 +- package.json | 4 +- rc-calendar-tests.tsx | 8 +- src/Calendar.jsx | 12 +- src/FullCalendar.jsx | 4 +- src/MonthCalendar.jsx | 16 +- src/RangeCalendar.js | 8 +- src/calendar/CalendarHeader.jsx | 8 +- src/calendar/CalendarRightPanel.jsx | 4 +- src/date/DateInput.js | 9 +- src/date/DateTBody.jsx | 10 +- src/date/DateTHead.jsx | 23 +- src/decade/DecadePanel.jsx | 10 +- src/full-calendar/CalendarHeader.jsx | 12 +- src/mixin/CalendarMixin.js | 4 +- src/month/MonthTable.js | 20 +- src/util/index.js | 19 +- src/year/YearPanel.jsx | 10 +- tests/Calendar.spec.jsx | 105 +- tests/FullCalendar.spec.js | 15 +- tests/MonthCalendar.spec.js | 21 +- tests/Picker.spec.jsx | 57 +- tests/RangeCalendar.spec.jsx | 111 +- tests/__snapshots__/Calendar.spec.jsx.snap | 9306 +-- tests/__snapshots__/FullCalendar.spec.js.snap | 336 +- .../__snapshots__/RangeCalendar.spec.jsx.snap | 866 +- tests/__snapshots__/locale.spec.js.snap | 56238 ++++++++-------- 37 files changed, 33860 insertions(+), 33560 deletions(-) diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 8b6a096bc..1d3fd3312 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -2,7 +2,7 @@ position: relative; outline: none; font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans-serif; - width: fit-content; + width: 253px; border: 1px solid #ccc; list-style: none; font-size: 12px; diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 06479c651..5c29ac1a2 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -11,18 +11,24 @@ import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import 'rc-time-picker/assets/index.css'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; + +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; const format = 'YYYY-MM-DD HH:mm:ss'; -const cn = location.search.indexOf('cn') !== -1; +const cn = true; + +dayjs.extend(utc); +dayjs.extend(localeData); -const now = moment(); +let now = dayjs(); if (cn) { - now.locale('zh-cn').utcOffset(8); + now = now.locale('zh-cn'); } else { - now.locale('en-gb').utcOffset(0); + now = now.locale('en-gb'); } function getFormat(time) { @@ -33,7 +39,7 @@ function getFormat(time) { const defaultCalendarValue = now.clone(); defaultCalendarValue.add(-1, 'month'); -const timePickerElement = ; +const timePickerElement = ; function disabledTime(date) { console.log('disabledTime', date); @@ -57,10 +63,10 @@ function disabledDate(current) { // allow empty select return false; } - const date = moment(); - date.hour(0); - date.minute(0); - date.second(0); + let date = dayjs().locale('zh-cn'); + date = date.hour(0); + date = date.minute(0); + date = date.second(0); return current.valueOf() < date.valueOf(); // can not select days before today } diff --git a/examples/antd-month-calendar.js b/examples/antd-month-calendar.js index 86f1620ec..c4750674e 100644 --- a/examples/antd-month-calendar.js +++ b/examples/antd-month-calendar.js @@ -9,15 +9,18 @@ import DatePicker from '@seafile/seafile-calendar/src/Picker'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; - -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); const format = 'YYYY-MM'; const cn = location.search.indexOf('cn') !== -1; -const now = moment(); +const now = dayjs(); if (cn) { now.locale('zh-cn').utcOffset(8); } else { diff --git a/examples/antd-range-calendar.js b/examples/antd-range-calendar.js index 63620dfeb..bf119322e 100644 --- a/examples/antd-range-calendar.js +++ b/examples/antd-range-calendar.js @@ -10,19 +10,26 @@ import TimePickerPanel from 'rc-time-picker/lib/Panel'; import '@seafile/seafile-calendar/assets/index.less'; import 'rc-time-picker/assets/index.css'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); + const cn = location.search.indexOf('cn') !== -1; if (cn) { - moment.locale('zh-cn'); + dayjs.locale('zh-cn'); } else { - moment.locale('en-gb'); + dayjs.locale('en-gb'); } -const now = moment(); +const now = dayjs(); if (cn) { now.utcOffset(8); } else { @@ -34,7 +41,7 @@ defaultCalendarValue.add(-1, 'month'); const timePickerElement = ( ); @@ -47,10 +54,10 @@ function newArray(start, end) { } function disabledDate(current) { - const date = moment(); - date.hour(0); - date.minute(0); - date.second(0); + let date = dayjs(); + date = date.hour(0); + date = date.minute(0); + date = date.second(0); return current.isBefore(date); // can not select days before today } diff --git a/examples/custom-clear-icon.js b/examples/custom-clear-icon.js index f5f6fe71d..74f8fa565 100644 --- a/examples/custom-clear-icon.js +++ b/examples/custom-clear-icon.js @@ -7,8 +7,8 @@ import Calendar from '@seafile/seafile-calendar'; import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar'; import 'rc-time-picker/assets/index.css'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; const clearPath = 'M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 ' + '290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0' + diff --git a/examples/full-calendar.js b/examples/full-calendar.js index 5936b70df..2847d2f91 100644 --- a/examples/full-calendar.js +++ b/examples/full-calendar.js @@ -11,14 +11,20 @@ import Select from 'rc-select'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); const format = 'YYYY-MM-DD'; const cn = location.search.indexOf('cn') !== -1; -const now = moment(); +const now = dayjs(); if (cn) { now.locale('zh-cn').utcOffset(8); } else { diff --git a/examples/getCalendarContainer.js b/examples/getCalendarContainer.js index cc596bb15..9ed981c4b 100644 --- a/examples/getCalendarContainer.js +++ b/examples/getCalendarContainer.js @@ -9,14 +9,20 @@ import 'rc-dialog/assets/index.css'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); const format = 'YYYY-MM-DD'; const cn = location.search.indexOf('cn') !== -1; -const now = moment(); +const now = dayjs(); if (cn) { now.locale('zh-cn').utcOffset(8); } else { diff --git a/examples/start-end-range.js b/examples/start-end-range.js index 2d78f1404..0c495e8c0 100644 --- a/examples/start-end-range.js +++ b/examples/start-end-range.js @@ -9,16 +9,22 @@ import DatePicker from '@seafile/seafile-calendar/src/Picker'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); const format = 'YYYY-MM-DD'; const fullFormat = 'YYYY-MM-DD dddd'; const cn = location.search.indexOf('cn') !== -1; -const now = moment(); +const now = dayjs(); if (cn) { now.locale('zh-cn').utcOffset(8); } else { diff --git a/examples/start-end.js b/examples/start-end.js index eace02320..2226d6b27 100644 --- a/examples/start-end.js +++ b/examples/start-end.js @@ -11,14 +11,20 @@ import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import 'rc-time-picker/assets/index.css'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); const format = 'YYYY-MM-DD HH:mm:ss'; const cn = location.search.indexOf('cn') !== -1; -const now = moment(); +const now = dayjs(); if (cn) { now.locale('zh-cn').utcOffset(8); } else { diff --git a/examples/week.js b/examples/week.js index be76c201b..6138fefe0 100644 --- a/examples/week.js +++ b/examples/week.js @@ -9,14 +9,22 @@ import DatePicker from '@seafile/seafile-calendar/src/Picker'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import moment from 'moment'; -import 'moment/locale/zh-cn'; -import 'moment/locale/en-gb'; - -const format = 'YYYY-Wo'; +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(advancedFormat); + +const format = 'YYYY-wo'; const cn = location.search.indexOf('cn') !== -1; -const now = moment(); +const now = dayjs(); if (cn) { now.locale('zh-cn').utcOffset(8); } else { @@ -78,21 +86,21 @@ class Demo extends React.Component { const selectedValue = this.state.value; if (selectedValue && current.year() === selectedValue.year() && current.week() === selectedValue.week()) { - return (
          -
          + return (
          +
          {current.date()}
          ); } return ( -
          +
          {current.date()}
          ); } lastWeek = () => { - const value = this.state.value || now; - value.add(-1, 'weeks'); + let value = this.state.value || now; + value = value.add(-1, 'weeks'); this.setState({ value, open: false, diff --git a/index.d.ts b/index.d.ts index 8ae68c177..13e00bf9f 100644 --- a/index.d.ts +++ b/index.d.ts @@ -4,7 +4,7 @@ // Definitions: https://github.com/react-component/calendar import * as React from 'react'; -import { Moment } from 'moment'; +import { Dayjs } from 'dayjs'; export type Mode = 'time' | 'date' | 'month' | 'year' | 'decade'; @@ -12,9 +12,9 @@ export interface Props { prefixCls?: string; className?: string; style?: React.CSSProperties; - defaultValue?: Moment; - value?: Moment; - selectedValue?: Moment; + defaultValue?: Dayjs; + value?: Dayjs; + selectedValue?: Dayjs; mode?: Mode; locale?: object; format?: string | string[]; @@ -22,18 +22,18 @@ export interface Props { showWeekNumber?: boolean; showToday?: boolean; showOk?: boolean; - onSelect?: (date: Moment) => void; + onSelect?: (date: Dayjs) => void; onOk?: () => void; onKeyDown?: () => void; onClickRightPanelTime?: () => void; timePicker?: React.ReactNode; dateInputPlaceholder?: string; onClear?: () => void; - onChange?: (date: Moment | null) => void; - onPanelChange?: (date: Moment | null, mode: Mode) => void; - disabledDate?: (current: Moment | undefined) => boolean; - disabledTime?: (current: Moment | undefined) => object; - dateRender?: (current: Moment, value: Moment) => React.ReactNode; + onChange?: (date: Dayjs | null) => void; + onPanelChange?: (date: Dayjs | null, mode: Mode) => void; + disabledDate?: (current: Dayjs | undefined) => boolean; + disabledTime?: (current: Dayjs | undefined) => object; + dateRender?: (current: Dayjs, value: Dayjs) => React.ReactNode; renderFooter?: () => React.ReactNode; renderSidebar?: () => React.ReactNode; inputMode?: string; diff --git a/package.json b/package.json index 0ac2fb88b..bd5ff17c3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.15", + "version": "0.0.16", "description": "React Calendar", "keywords": [ "react", @@ -91,7 +91,7 @@ "dependencies": { "babel-runtime": "6.x", "classnames": "2.x", - "moment": "2.x", + "dayjs": "1.10.7", "prop-types": "^15.5.8", "rc-trigger": "^2.2.0", "rc-util": "^4.1.1", diff --git a/rc-calendar-tests.tsx b/rc-calendar-tests.tsx index b4e37931f..afa4d690f 100644 --- a/rc-calendar-tests.tsx +++ b/rc-calendar-tests.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import * as moment from 'moment'; +import * as dayjs from 'dayjs'; import Calendar from './'; -const action = (date: moment.Moment) => { +const action = (date: dayjs.Dayjs) => { date.subtract(1); }; @@ -10,11 +10,11 @@ export default () => ( false} + disabledDate={(now: dayjs.Dayjs) => false} onSelect={action} inputMode="numeric" /> diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 1495affb2..dbe76d353 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import KeyCode from 'rc-util/lib/KeyCode'; import { polyfill } from 'react-lifecycles-compat'; +import dayjs from 'dayjs'; import DateTable from './date/DateTable'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; @@ -17,13 +18,18 @@ import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import DateInput from './date/DateInput'; import { getTimeConfig, getTodayTime, syncTime } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; -import moment from 'moment'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); function noop() { } const getMomentObjectIfValid = date => { - if (moment.isMoment(date) && date.isValid()) { + if (dayjs.isDayjs(date) && date.isValid()) { return date; } return false; @@ -88,7 +94,7 @@ class Calendar extends React.Component { value: getMomentObjectIfValid(props.value) || getMomentObjectIfValid(props.defaultValue) || - moment(), + dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, }; } diff --git a/src/FullCalendar.jsx b/src/FullCalendar.jsx index 90fdb7f66..4a8cb19dc 100644 --- a/src/FullCalendar.jsx +++ b/src/FullCalendar.jsx @@ -11,7 +11,7 @@ import { } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import CalendarHeader from './full-calendar/CalendarHeader'; -import moment from 'moment'; +import dayjs from 'dayjs'; class FullCalendar extends React.Component { static propTypes = { @@ -61,7 +61,7 @@ class FullCalendar extends React.Component { this.state = { type, - value: props.value || props.defaultValue || moment(), + value: props.value || props.defaultValue || dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, }; } diff --git a/src/MonthCalendar.jsx b/src/MonthCalendar.jsx index 857f2f617..bbee730ef 100644 --- a/src/MonthCalendar.jsx +++ b/src/MonthCalendar.jsx @@ -10,7 +10,7 @@ import { calendarMixinDefaultProps, } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; -import moment from 'moment'; +import dayjs from 'dayjs'; class MonthCalendar extends React.Component { static propTypes = { @@ -31,7 +31,7 @@ class MonthCalendar extends React.Component { this.state = { mode: 'month', - value: props.value || props.defaultValue || moment(), + value: props.value || props.defaultValue || dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, }; } @@ -45,26 +45,26 @@ class MonthCalendar extends React.Component { switch (keyCode) { case KeyCode.DOWN: value = stateValue.clone(); - value.add(3, 'months'); + value = value.add(3, 'months'); break; case KeyCode.UP: value = stateValue.clone(); - value.add(-3, 'months'); + value = value.add(-3, 'months'); break; case KeyCode.LEFT: value = stateValue.clone(); if (ctrlKey) { - value.add(-1, 'years'); + value = value.add(-1, 'years'); } else { - value.add(-1, 'months'); + value = value.add(-1, 'months'); } break; case KeyCode.RIGHT: value = stateValue.clone(); if (ctrlKey) { - value.add(1, 'years'); + value = value.add(1, 'years'); } else { - value.add(1, 'months'); + value = value.add(1, 'months'); } break; case KeyCode.ENTER: diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 0c2f938da..9b5deb8ce 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; import classnames from 'classnames'; import { polyfill } from 'react-lifecycles-compat'; import KeyCode from 'rc-util/lib/KeyCode'; @@ -50,7 +50,7 @@ function normalizeAnchor(props, init) { getValueFromSelectedValue(value) : getValueFromSelectedValue(selectedValue); return !isEmptyArray(normalizedValue) ? - normalizedValue : init && [moment(), moment().add(1, 'months')]; + normalizedValue : init && [dayjs(), dayjs().add(1, 'months')]; } function generateOptions(length, extraOptionGen) { @@ -210,7 +210,7 @@ class RangeCalendar extends React.Component { let nextHoverValue; if (!firstSelectedValue) { - currentHoverTime = hoverValue[0] || selectedValue[0] || value[0] || moment(); + currentHoverTime = hoverValue[0] || selectedValue[0] || value[0] || dayjs(); nextHoverTime = func(currentHoverTime); nextHoverValue = [nextHoverTime]; this.fireHoverValueChange(nextHoverValue); @@ -571,7 +571,7 @@ class RangeCalendar extends React.Component { // 尚未选择过时间,直接输入的话 if (!this.state.selectedValue[0] || !this.state.selectedValue[1]) { - const startValue = selectedValue[0] || moment(); + const startValue = selectedValue[0] || dayjs(); const endValue = selectedValue[1] || startValue.clone().add(1, 'months'); this.setState({ selectedValue, diff --git a/src/calendar/CalendarHeader.jsx b/src/calendar/CalendarHeader.jsx index a7eccfc17..2c4817922 100644 --- a/src/calendar/CalendarHeader.jsx +++ b/src/calendar/CalendarHeader.jsx @@ -6,14 +6,14 @@ import YearPanel from '../year/YearPanel'; import DecadePanel from '../decade/DecadePanel'; function goMonth(direction) { - const next = this.props.value.clone(); - next.add(direction, 'months'); + let next = this.props.value.clone(); + next = next.add(direction, 'months'); this.props.onValueChange(next); } function goYear(direction) { - const next = this.props.value.clone(); - next.add(direction, 'years'); + let next = this.props.value.clone(); + next = next.add(direction, 'years'); this.props.onValueChange(next); } diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 87f896762..8497b5eaf 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import moment from 'moment'; +import dayjs from 'dayjs'; export default class CalendarRightPanel extends React.Component { @@ -70,7 +70,7 @@ export default class CalendarRightPanel extends React.Component {
            {this.times.map((time) => { - let current = moment(`${selectedDate} ${time}`); + let current = dayjs(`${selectedDate} ${time}`); current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb'); return (
          • {getMonthName(t)} diff --git a/src/mixin/CalendarMixin.js b/src/mixin/CalendarMixin.js index 49a2fe3eb..0165fe14e 100644 --- a/src/mixin/CalendarMixin.js +++ b/src/mixin/CalendarMixin.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { isAllowedDate, getTodayTime } from '../util/index'; function noop() { @@ -12,7 +12,7 @@ export function getNowByCurrentStateValue(value) { if (value) { ret = getTodayTime(value); } else { - ret = moment(); + ret = dayjs(); } return ret; } diff --git a/src/month/MonthTable.js b/src/month/MonthTable.js index 2b5a6348e..c78cfd2c7 100644 --- a/src/month/MonthTable.js +++ b/src/month/MonthTable.js @@ -7,8 +7,8 @@ const ROW = 4; const COL = 3; function chooseMonth(month) { - const next = this.state.value.clone(); - next.month(month); + let next = this.state.value.clone(); + next = next.month(month); this.setAndSelectValue(next); } @@ -42,13 +42,13 @@ class MonthTable extends Component { months() { const value = this.state.value; - const current = value.clone(); + let current = value.clone(); const months = []; let index = 0; for (let rowIndex = 0; rowIndex < ROW; rowIndex++) { months[rowIndex] = []; for (let colIndex = 0; colIndex < COL; colIndex++) { - current.month(index); + current = current.month(index); const content = getMonthName(current); months[rowIndex][colIndex] = { value: index, @@ -72,8 +72,8 @@ class MonthTable extends Component { const tds = month.map(monthData => { let disabled = false; if (props.disabledDate) { - const testValue = value.clone(); - testValue.month(monthData.value); + let testValue = value.clone(); + testValue = testValue.month(monthData.value); disabled = props.disabledDate(testValue); } const classNameMap = { @@ -85,14 +85,14 @@ class MonthTable extends Component { }; let cellEl; if (cellRender) { - const currentValue = value.clone(); - currentValue.month(monthData.value); + let currentValue = value.clone(); + currentValue = currentValue.month(monthData.value); cellEl = cellRender(currentValue, locale); } else { let content; if (contentRender) { - const currentValue = value.clone(); - currentValue.month(monthData.value); + let currentValue = value.clone(); + currentValue = currentValue.month(monthData.value); content = contentRender(currentValue, locale); } else { content = monthData.content; diff --git a/src/util/index.js b/src/util/index.js index 59665f68f..73782ab6d 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -1,4 +1,7 @@ -import moment from 'moment'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; + +dayjs.extend(utc); const defaultDisabledTime = { disabledHours() { @@ -13,8 +16,8 @@ const defaultDisabledTime = { }; export function getTodayTime(value) { - const today = moment(); - today.locale(value.locale()).utcOffset(value.utcOffset()); + let today = dayjs(); + today = today.locale(value.locale()).utcOffset(value.utcOffset()); return today; } @@ -34,11 +37,11 @@ export function getMonthName(month) { } export function syncTime(from, to) { - if (!moment.isMoment(from) || !moment.isMoment(to)) return; - to.hour(from.hour()); - to.minute(from.minute()); - to.second(from.second()); - to.millisecond(from.millisecond()); + if (!dayjs.isDayjs(from) || !dayjs.isDayjs(to)) return; + to = to.hour(from.hour()); + to = to.minute(from.minute()); + to = to.second(from.second()); + to = to.millisecond(from.millisecond()); } export function getTimeConfig(value, disabledTime) { diff --git a/src/year/YearPanel.jsx b/src/year/YearPanel.jsx index f679a52bd..48dbb67a8 100644 --- a/src/year/YearPanel.jsx +++ b/src/year/YearPanel.jsx @@ -5,17 +5,17 @@ const ROW = 4; const COL = 3; function goYear(direction) { - const value = this.state.value.clone(); - value.add(direction, 'year'); + let value = this.state.value.clone(); + value = value.add(direction, 'year'); this.setState({ value, }); } function chooseYear(year) { - const value = this.state.value.clone(); - value.year(year); - value.month(this.state.value.month()); + let value = this.state.value.clone(); + value = value.year(year); + value = value.month(this.state.value.month()); this.setState({ value, }); diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index 369eeb86b..01fd5f79a 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -1,25 +1,40 @@ /* eslint-disable no-undef */ import React from 'react'; import keyCode from 'rc-util/lib/KeyCode'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { mount, render } from 'enzyme'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; import Calendar from '../src/Calendar'; import zhCN from '../src/locale/zh_CN'; import enUS from '../src/locale/en_US'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import badMutable from 'dayjs/plugin/badMutable'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(advancedFormat); +dayjs.extend(customParseFormat); +dayjs.extend(badMutable); + const format = ('YYYY-MM-DD'); describe('Calendar', () => { describe('render', () => { it('render correctly', () => { const zhWrapper = render( - + ); expect(zhWrapper).toMatchSnapshot(); const enWrapper = render( - + ); expect(enWrapper).toMatchSnapshot(); @@ -27,15 +42,15 @@ describe('Calendar', () => { const enWrapperWithMonthFormatWrapper = render( ); expect(enWrapperWithMonthFormatWrapper).toMatchSnapshot(); }); - it('render correctly with invalid moment object', () => { + it('render correctly with invalid dayjs object', () => { const enWrapper = render( - + ); expect(enWrapper).toMatchSnapshot(); }); @@ -48,7 +63,7 @@ describe('Calendar', () => { describe('timePicker', () => { it('set defaultOpenValue if timePicker.props.defaultValue is set', () => { - const timePicker = ; + const timePicker = ; const wrapper = mount(); wrapper.find('.rc-calendar-time-picker-btn').simulate('click'); const selectedValues = wrapper.find('.rc-time-picker-panel-select-option-selected'); @@ -58,9 +73,9 @@ describe('Calendar', () => { }); it('follow Calendar[selectedValue|defaultSelectedValue] when it is set', () => { - const timePicker = ; + const timePicker = ; const wrapper = mount( - + ); wrapper.find('.rc-calendar-time-picker-btn').simulate('click'); const selectedValues = wrapper.find('.rc-time-picker-panel-select-option-selected'); @@ -70,7 +85,7 @@ describe('Calendar', () => { }); it('use timePicker\'s time', () => { - const timePicker = ; + const timePicker = ; const wrapper = mount(); wrapper.find('.rc-calendar-today').simulate('click'); @@ -93,7 +108,7 @@ describe('Calendar', () => { ).toBe('3/8/2017 06:00:00'); }); it('timePicker date have no changes when hover', () => { - const timePicker = ; + const timePicker = ; const wrapper = mount(); wrapper.find('.rc-calendar-time-picker-btn').simulate('click'); const dateBtns = wrapper.find('.rc-calendar-my-select a'); @@ -122,7 +137,7 @@ describe('Calendar', () => { }); it('support controlled mode', () => { - const timePicker = ; + const timePicker = ; let value = null; class ControlledCalendar extends React.Component { state = { mode: 'date' }; @@ -155,14 +170,14 @@ describe('Calendar', () => { expect(wrapper.find('.rc-calendar-year-panel').length).toBe(1); wrapper.find('.rc-calendar-year-panel-decade-select').simulate('click'); expect(wrapper.find('.rc-calendar-decade-panel').length).toBe(1); - expect(value.isSame(moment(), 'day')); + expect(value.isSame(dayjs(), 'day')); wrapper.find('.rc-calendar-decade-panel-selected-cell').simulate('click'); expect(wrapper.find('.rc-calendar-decade-panel').length).toBe(0); wrapper.find('.rc-calendar-year-panel-selected-cell').simulate('click'); expect(wrapper.find('.rc-calendar-year-panel').length).toBe(0); wrapper.find('.rc-calendar-month-panel-selected-cell').simulate('click'); expect(wrapper.find('.rc-calendar-month-panel').length).toBe(0); - expect(value.isSame(moment('2010-03-29'), 'day')); + expect(value.isSame(dayjs('2010-03-29'), 'day')); wrapper.find('.rc-calendar-year-select').simulate('click'); expect(wrapper.find('.rc-calendar-year-panel').length).toBe(1); @@ -203,8 +218,8 @@ describe('Calendar', () => { it('left works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(-1, 'day'); + let expected = original.clone(); + expected = expected.add(-1, 'day'); calendar.simulate('keyDown', { keyCode: keyCode.LEFT }); expect(calendar.state().value.date()).toBe(expected.date()); @@ -214,8 +229,8 @@ describe('Calendar', () => { it('right works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(1, 'day'); + let expected = original.clone(); + expected = expected.add(1, 'day'); calendar.simulate('keyDown', { keyCode: keyCode.RIGHT }); expect(calendar.state().value.date()).toBe(expected.date()); expect(input.getDOMNode().value).toBe(''); @@ -223,14 +238,14 @@ describe('Calendar', () => { it('up works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(-7, 'day'); + let expected = original.clone(); + expected = expected.add(-7, 'day'); }); it('left works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(-1, 'day'); + let expected = original.clone(); + expected = expected.add(-1, 'day'); calendar.simulate('keyDown', { keyCode: keyCode.LEFT }); expect(calendar.state().value.date()).toBe(expected.date()); @@ -240,8 +255,8 @@ describe('Calendar', () => { it('right works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(1, 'day'); + let expected = original.clone(); + expected = expected.add(1, 'day'); calendar.simulate('keyDown', { keyCode: keyCode.RIGHT }); expect(calendar.state().value.date()).toBe(expected.date()); expect(input.getDOMNode().value).toBe(''); @@ -249,8 +264,8 @@ describe('Calendar', () => { it('up works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(-7, 'day'); + let expected = original.clone(); + expected = expected.add(-7, 'day'); calendar.simulate('keyDown', { keyCode: keyCode.UP }); expect(calendar.state().value.date()).toBe(expected.date()); expect(input.getDOMNode().value).toBe(''); @@ -258,8 +273,8 @@ describe('Calendar', () => { it('down works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(7, 'day'); + let expected = original.clone(); + expected = expected.add(7, 'day'); calendar.simulate('keyDown', { keyCode: keyCode.DOWN }); expect(calendar.state().value.date()).toBe(expected.date()); expect(input.getDOMNode().value).toBe(''); @@ -267,8 +282,8 @@ describe('Calendar', () => { it('pageDown works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(1, 'month'); + let expected = original.clone(); + expected = expected.add(1, 'month'); calendar.simulate('keyDown', { keyCode: keyCode.PAGE_DOWN }); expect(calendar.state().value.month()).toBe(expected.month()); expect(input.getDOMNode().value).toBe(''); @@ -276,8 +291,8 @@ describe('Calendar', () => { it('pageUp works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(-1, 'month'); + let expected = original.clone(); + expected = expected.add(-1, 'month'); calendar.simulate('keyDown', { keyCode: keyCode.PAGE_UP }); expect(calendar.state().value.month()).toBe(expected.month()); expect(input.getDOMNode().value).toBe(''); @@ -285,8 +300,8 @@ describe('Calendar', () => { it('ctrl left works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(-1, 'year'); + let expected = original.clone(); + expected = expected.add(-1, 'year'); calendar.simulate('keyDown', { keyCode: keyCode.LEFT, ctrlKey: 1, @@ -297,8 +312,8 @@ describe('Calendar', () => { it('ctrl right works', () => { const original = calendar.state().value; - const expected = original.clone(); - expected.add(1, 'year'); + let expected = original.clone(); + expected = expected.add(1, 'year'); calendar.simulate('keyDown', { keyCode: keyCode.RIGHT, ctrlKey: 1, @@ -351,10 +366,10 @@ describe('Calendar', () => { if (!current) { return false; } - const date = moment(); - date.hour(0); - date.minute(0); - date.second(0); + let date = dayjs(); + date = date.hour(0); + date = date.minute(0); + date = date.second(0); return current.valueOf() < date.valueOf(); } @@ -587,7 +602,7 @@ describe('Calendar', () => { }); it('handle clear', () => { - const now = moment(); + const now = dayjs(); const calendar = mount( ); @@ -598,7 +613,7 @@ describe('Calendar', () => { describe('onOk', () => { it('triggers onOk', () => { - const selected = moment().add(1, 'day'); + const selected = dayjs().add(1, 'day'); const handleOk = jest.fn(); const calendar = mount( @@ -618,7 +633,7 @@ describe('Calendar', () => { }); it('does not triggers onOk if selected date is disabled', () => { - const selected = moment().add(1, 'day'); + const selected = dayjs().add(1, 'day'); const handleOk = jest.fn(); const calendar = mount( { }); it('today button', () => { - const selected = moment().add(1, 'day').utcOffset(480); + const selected = dayjs().add(1, 'day').utcOffset(480); const calendar = mount( ); calendar.find('.rc-calendar-today-btn').simulate('click'); - expect(moment().isSame(calendar.state().selectedValue)).toBe(true); + expect(dayjs().isSame(calendar.state().selectedValue)).toBe(true); }); }); diff --git a/tests/FullCalendar.spec.js b/tests/FullCalendar.spec.js index 75969ba24..4caf9e560 100644 --- a/tests/FullCalendar.spec.js +++ b/tests/FullCalendar.spec.js @@ -2,9 +2,20 @@ import React from 'react'; import Select from 'rc-select'; import { render, mount } from 'enzyme'; -import moment from 'moment'; +import dayjs from 'dayjs'; import FullCalendar from '../src/FullCalendar'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(advancedFormat); + describe('FullCalendar', () => { it('renders month mode correctly', () => { const wrapper = render( @@ -82,7 +93,7 @@ describe('FullCalendar', () => { }); it('select month', () => { - const selected = moment().add(1, 'month'); + const selected = dayjs().add(1, 'month'); const wrapper = mount( { it('year or decade panel work correctly', () => { const format = 'YYYY-MM'; @@ -19,7 +30,7 @@ describe('MonthCalendar', () => { describe('keyboard', () => { let wrapper; beforeEach(() => { - const selected = moment().add(2, 'month'); + const selected = dayjs().add(2, 'month'); wrapper = mount(); }); @@ -38,7 +49,7 @@ describe('MonthCalendar', () => { if (!current) { return false; } - const date = moment(); + const date = dayjs(); return current.month() < date.month(); } @@ -114,10 +125,10 @@ describe('MonthCalendar', () => { }); it('controlled value should work', () => { - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.state().value.format('YYYY-MM-DD')).toBe('2000-01-01'); - wrapper.setProps({ value: moment('2049-09-03 00:00:00') }); + wrapper.setProps({ value: dayjs('2049-09-03 00:00:00') }); expect(wrapper.state().value.format('YYYY-MM-DD')).toBe('2049-09-03'); }); }); diff --git a/tests/Picker.spec.jsx b/tests/Picker.spec.jsx index 2eed444d6..0476e9c9f 100644 --- a/tests/Picker.spec.jsx +++ b/tests/Picker.spec.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { mount } from 'enzyme'; import keyCode from 'rc-util/lib/KeyCode'; import Calendar from '../index'; @@ -7,8 +7,23 @@ import DatePicker from '../src/Picker'; import RangeCalendar from '../src/RangeCalendar'; import CalendarLocale from '../src/locale/en_US'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import badMutable from 'dayjs/plugin/badMutable'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(advancedFormat); +dayjs.extend(customParseFormat); +dayjs.extend(badMutable); + const format = ('YYYY-MM-DD'); -const VALUE = moment([2015, 5, 1]); +const VALUE = dayjs([2015, 5, 1]); describe('DatePicker', () => { function noop() { @@ -83,9 +98,9 @@ describe('DatePicker', () => { day.simulate('click'); expect(change).not.toBeFalsy(); expect(change.year()).toEqual(2015); - expect(change.month()).toEqual(5); - expect(change.date()).toEqual(2); - expect(input.getDOMNode().value).toEqual('2015-06-02'); + expect(change.month()).toEqual(3); + expect(change.date()).toEqual(28); + expect(input.getDOMNode().value).toEqual('2015-04-28'); expect(picker.state().open).toBeFalsy(); }); @@ -108,12 +123,12 @@ describe('DatePicker', () => { expect(change).not.toBeFalsy(); expect(change.length).toEqual(2); expect(change[0].year()).toEqual(2015); - expect(change[0].month()).toEqual(5); - expect(change[0].date()).toEqual(2); + expect(change[0].month()).toEqual(3); + expect(change[0].date()).toEqual(28); expect(change[1].year()).toEqual(2015); - expect(change[1].month()).toEqual(5); - expect(change[1].date()).toEqual(3); - expect(input.getDOMNode().value).toEqual('2015-06-02 - 2015-06-03'); + expect(change[1].month()).toEqual(3); + expect(change[1].date()).toEqual(29); + expect(input.getDOMNode().value).toEqual('2015-04-28 - 2015-04-29'); expect(picker.state().open).toBeFalsy(); }); @@ -134,7 +149,7 @@ describe('DatePicker', () => { }); it('controlled value', () => { - const value = moment().add(1, 'day'); + const value = dayjs().add(1, 'day'); const picker = renderPicker({ value }); expect(picker.state().value).toBe(value); const nextValue = value.clone().add(1, 'day'); @@ -181,14 +196,14 @@ describe('DatePicker', () => { }); it('close on ok', () => { - const picker = renderPicker({ value: moment() }); + const picker = renderPicker({ value: dayjs() }); picker.find('.rc-calendar-picker-input').simulate('click'); picker.find('.rc-calendar-ok-btn').simulate('click'); expect(picker.state().open).toBe(false); }); it('close on clear', () => { - const picker = renderPicker({ value: moment() }); + const picker = renderPicker({ value: dayjs() }); picker.find('.rc-calendar-picker-input').simulate('click'); picker.find('.rc-calendar-clear-btn').simulate('click'); expect(picker.state().open).toBe(false); @@ -196,7 +211,7 @@ describe('DatePicker', () => { describe('DateInput', () => { it('close on enter', () => { - const picker = renderPicker({ value: moment() }); + const picker = renderPicker({ value: dayjs() }); picker.find('.rc-calendar-picker-input').simulate('click'); picker.find('.rc-calendar-input').simulate('keyDown', { keyCode: keyCode.ENTER, @@ -205,7 +220,7 @@ describe('DatePicker', () => { }); it('not close on enter if disabled date', () => { - const picker = renderPicker({ value: moment() }, { disabledDate: () => true }); + const picker = renderPicker({ value: dayjs() }, { disabledDate: () => true }); picker.find('.rc-calendar-picker-input').simulate('click'); picker.find('.rc-calendar-input').simulate('keyDown', { keyCode: keyCode.ENTER, @@ -229,7 +244,7 @@ describe('DatePicker', () => { }); it('close panel when focus is outside of picker', () => { - const picker = renderPicker({ value: moment() }, undefined, { + const picker = renderPicker({ value: dayjs() }, undefined, { attachTo: container, }); picker.find('.rc-calendar-picker-input').simulate('click'); @@ -242,7 +257,7 @@ describe('DatePicker', () => { it('call onBlur when focus is outside of picker', () => { const handleOnBlur = jest.fn(); - const picker = renderPicker({ value: moment() }, { onBlur: handleOnBlur }, { + const picker = renderPicker({ value: dayjs() }, { onBlur: handleOnBlur }, { attachTo: container, }); @@ -254,7 +269,7 @@ describe('DatePicker', () => { }); it('keep panel opened when clicking on calendar next month', () => { - const picker = renderPicker({ value: moment() }, undefined, { + const picker = renderPicker({ value: dayjs() }, undefined, { attachTo: container, }); @@ -270,7 +285,7 @@ describe('DatePicker', () => { it('does not call onBlur when clicking on calendar next month', () => { const handleOnBlur = jest.fn(); - const picker = renderPicker({ value: moment() }, { onBlur: handleOnBlur }, { + const picker = renderPicker({ value: dayjs() }, { onBlur: handleOnBlur }, { attachTo: container, }); @@ -287,7 +302,7 @@ describe('DatePicker', () => { it('auto focuses the calendar input when opening', () => { jest.useFakeTimers(); - const picker = renderPicker({ value: moment() }); + const picker = renderPicker({ value: dayjs() }); picker.find('.rc-calendar-picker-input').simulate('click'); jest.runAllTimers(); expect(document.activeElement).toBeDefined(); @@ -296,7 +311,7 @@ describe('DatePicker', () => { it('auto focuses the calendar div when date input is not shown', () => { jest.useFakeTimers(); - const picker = renderPicker({ value: moment() }, { showDateInput: false }); + const picker = renderPicker({ value: dayjs() }, { showDateInput: false }); picker.find('.rc-calendar-picker-input').simulate('click'); jest.runAllTimers(); expect(document.activeElement).toBeDefined(); diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 7448fe78f..c3f2fd270 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -1,11 +1,26 @@ /* eslint-disable no-undef, max-len, react/no-multi-comp */ import React from 'react'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { mount, render } from 'enzyme'; import keyCode from 'rc-util/lib/KeyCode'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; import RangeCalendar from '../src/RangeCalendar'; +import localeData from 'dayjs/plugin/localeData'; +import utc from 'dayjs/plugin/utc'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import badMutable from 'dayjs/plugin/badMutable'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; +dayjs.extend(utc); +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(advancedFormat); +dayjs.extend(customParseFormat); +dayjs.extend(badMutable); + const format = ('YYYY-MM-DD'); describe('RangeCalendar', () => { @@ -25,7 +40,7 @@ describe('RangeCalendar', () => { }); it('render hoverValue correctly', () => { - const wrapper = render(); + const wrapper = render(); expect(wrapper).toMatchSnapshot(); }); @@ -143,12 +158,11 @@ describe('RangeCalendar', () => { it('onSelect works', () => { function onSelect(d) { - expect(d[0].format(format)).toBe('2015-09-04'); - expect(d[1].format(format)).toBe('2015-10-02'); + expect(d[0].format(format)).toBe('2015-07-31'); + expect(d[1].format(format)).toBe('2015-07-31'); } - const now = moment([2015, 8, 29]); - + const now = dayjs([2015, 8, 29]); const wrapper = mount( { showWeekNumber /> ); - wrapper.find('.rc-calendar-range-left .rc-calendar-date').at(5).simulate('click'); // 9.4 - expect(wrapper.find('.rc-calendar-input').at(0).getDOMNode().value).toBe('2015-09-04'); - wrapper.find('.rc-calendar-range-right .rc-calendar-date').at(5).simulate('click'); // 10.2 - expect(wrapper.find('.rc-calendar-input').at(1).getDOMNode().value).toBe('2015-10-02'); + wrapper.find('.rc-calendar-range-left .rc-calendar-date').at(5).simulate('click'); // 7.31 + expect(wrapper.find('.rc-calendar-input').at(0).getDOMNode().value).toBe('2015-07-31'); + wrapper.find('.rc-calendar-range-right .rc-calendar-date').at(5).simulate('click'); // 7.31 + expect(wrapper.find('.rc-calendar-input').at(1).getDOMNode().value).toBe('2015-07-31'); }); it('onSelect works reversely', () => { function onSelect(d) { - expect(d[0].format(format)).toBe('2015-09-04'); - expect(d[1].format(format)).toBe('2015-09-14'); + expect(d[0].format(format)).toBe('2015-07-31'); + expect(d[1].format(format)).toBe('2015-08-10'); } - const now = moment([2015, 8, 29]); - + const now = dayjs([2015, 8, 29]); const wrapper = mount( { /> ); - wrapper.find('.rc-calendar-range-left .rc-calendar-date').at(15).simulate('click'); // 9.14 - expect(wrapper.find('.rc-calendar-input').at(0).getDOMNode().value).toBe('2015-09-14'); + wrapper.find('.rc-calendar-range-left .rc-calendar-date').at(15).simulate('click'); // 8.10 + expect(wrapper.find('.rc-calendar-input').at(0).getDOMNode().value).toBe('2015-08-10'); - wrapper.find('.rc-calendar-range-left .rc-calendar-date').at(5).simulate('click'); // 9.4 - expect(wrapper.find('.rc-calendar-input').at(0).getDOMNode().value).toBe('2015-09-04'); - expect(wrapper.find('.rc-calendar-input').at(1).getDOMNode().value).toBe('2015-09-14'); + wrapper.find('.rc-calendar-range-left .rc-calendar-date').at(5).simulate('click'); // 7.31 + expect(wrapper.find('.rc-calendar-input').at(0).getDOMNode().value).toBe('2015-07-31'); + expect(wrapper.find('.rc-calendar-input').at(1).getDOMNode().value).toBe('2015-08-10'); }); it('onHoverChange works', () => { @@ -202,8 +215,8 @@ describe('RangeCalendar', () => { describe('timePicker', () => { it('defaultOpenValue should follow RangeCalendar[selectedValue|defaultSelectedValue] when it is set', () => { - const timePicker = ; - const wrapper = mount(); + const timePicker = ; + const wrapper = mount(); wrapper.find('.rc-calendar-time-picker-btn').simulate('click'); const selectedValues = wrapper.find('.rc-time-picker-panel-select-option-selected'); for (let i = 0; i < selectedValues.length; i += 1) { @@ -212,8 +225,8 @@ describe('RangeCalendar', () => { }); it('selected start and end date can be same', () => { - const timePicker = ; - const wrapper = mount(); + const timePicker = ; + const wrapper = mount(); wrapper.find('.rc-calendar-time-picker-btn').simulate('click'); expect(wrapper.find('.rc-calendar-year-select').at(0).text()).toBe('2000'); expect(wrapper.find('.rc-calendar-month-select').at(0).text()).toBe('Sep'); @@ -224,7 +237,7 @@ describe('RangeCalendar', () => { }); it('use timePicker\'s time', () => { - const timePicker = ; + const timePicker = ; const wrapper = mount(); wrapper.find('.rc-calendar-today').at(0).simulate('click').simulate('click'); @@ -296,7 +309,7 @@ describe('RangeCalendar', () => { }, }; } - const timePicker = ; + const timePicker = ; const wrapper = mount(); wrapper.find('.rc-calendar-today').at(0).simulate('click').simulate('click'); @@ -325,7 +338,7 @@ describe('RangeCalendar', () => { it('works fine when select reversely', () => { // see: https://github.com/ant-design/ant-design/issues/6440 - const timePicker = ; + const timePicker = ; const wrapper = mount(); wrapper.find('.rc-calendar-cell').at(20).simulate('click'); wrapper.find('.rc-calendar-cell').at(10).simulate('click'); @@ -371,7 +384,7 @@ describe('RangeCalendar', () => { }, }; } - const timePicker = ; + const timePicker = ; const wrapper = mount(); // update same day wrapper.find('.rc-calendar-today').at(0).simulate('click').simulate('click'); @@ -433,7 +446,7 @@ describe('RangeCalendar', () => { it('should work when start time is null in defaultValue', () => { let wrapper = null; - wrapper = mount(); + wrapper = mount(); wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); @@ -445,7 +458,7 @@ describe('RangeCalendar', () => { it('should work when end time is null in defaultValue', () => { let wrapper = null; - wrapper = mount(); + wrapper = mount(); wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); @@ -457,7 +470,7 @@ describe('RangeCalendar', () => { it('should work when start time is undefined in defaultValue', () => { let wrapper = null; - wrapper = mount(); + wrapper = mount(); wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); @@ -469,7 +482,7 @@ describe('RangeCalendar', () => { it('should work when end time is undefined in defaultValue', () => { let wrapper = null; - wrapper = mount(); + wrapper = mount(); wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); @@ -504,8 +517,8 @@ describe('RangeCalendar', () => { wrapper.find('.rc-calendar-year-panel-decade-select').at(0).simulate('click'); wrapper.find('.rc-calendar-year-panel-decade-select').at(0).simulate('click'); expect(wrapper.find('.rc-calendar-decade-panel').length).toBe(2); - expect(value[0].isSame(moment(), 'day')).toBe(true); - expect(value[1].isSame(moment().add(1, 'month'), 'day')).toBe(true); + expect(value[0].isSame(dayjs(), 'day')).toBe(true); + expect(value[1].isSame(dayjs().add(1, 'month'), 'day')).toBe(true); wrapper.find('.rc-calendar-decade-panel-selected-cell').at(0).simulate('click'); wrapper.find('.rc-calendar-decade-panel-selected-cell').at(0).simulate('click'); expect(wrapper.find('.rc-calendar-decade-panel').length).toBe(0); @@ -515,8 +528,8 @@ describe('RangeCalendar', () => { wrapper.find('.rc-calendar-month-panel-selected-cell').at(0).simulate('click'); wrapper.find('.rc-calendar-month-panel-selected-cell').at(0).simulate('click'); expect(wrapper.find('.rc-calendar-month-panel').length).toBe(0); - expect(value[0].isSame(moment('2010-03-29'), 'day')).toBe(true); - expect(value[1].isSame(moment('2010-04-29'), 'day')).toBe(true); + expect(value[0].isSame(dayjs('2010-03-29'), 'day')).toBe(true); + expect(value[1].isSame(dayjs('2010-04-29'), 'day')).toBe(true); wrapper.find('.rc-calendar-year-select').at(0).simulate('click'); wrapper.find('.rc-calendar-year-select').at(1).simulate('click'); @@ -533,11 +546,11 @@ describe('RangeCalendar', () => { }); it('controlled value works correctly', () => { - const wrapper = mount(); + const wrapper = mount(); const initialValue = wrapper.state('value'); expect(initialValue[0].isSame(initialValue[1], 'month')).toBe(true); - wrapper.setProps({ value: [moment(), moment()] }); + wrapper.setProps({ value: [dayjs(), dayjs()] }); const updatedValue = wrapper.state('value'); expect(updatedValue[0].isSame(updatedValue[1], 'month')).toBe(true); }); @@ -547,7 +560,7 @@ describe('RangeCalendar', () => { class Demo extends React.Component { state = { mode: ['month', 'month'], - value: [moment().add(-1, 'day'), moment()], + value: [dayjs().add(-1, 'day'), dayjs()], }; handlePanelChange = (value, mode) => { @@ -581,7 +594,7 @@ describe('RangeCalendar', () => { it('selected item style works correctly with mode year', () => { class Demo extends React.Component { state = { - value: [moment().add(-1, 'year'), moment()], + value: [dayjs().add(-1, 'year'), dayjs()], }; handlePanelChange = (value) => { @@ -637,8 +650,8 @@ describe('RangeCalendar', () => { }); it('controlled hoverValue changes', () => { - const start = moment(); - const end = moment().add(2, 'day'); + const start = dayjs(); + const end = dayjs().add(2, 'day'); const wrapper = mount(); const nextEnd = end.clone().add(2, 'day'); wrapper.setProps({ hoverValue: [start, nextEnd] }); @@ -646,8 +659,8 @@ describe('RangeCalendar', () => { }); it('controlled selectedValue changes', () => { - const start = moment(); - const end = moment().add(2, 'day'); + const start = dayjs(); + const end = dayjs().add(2, 'day'); const wrapper = mount(); const nextEnd = end.clone().add(2, 'day'); wrapper.setProps({ selectedValue: [start, nextEnd] }); @@ -663,8 +676,8 @@ describe('RangeCalendar', () => { beforeEach(() => { handleHoverChange = jest.fn(); - start = moment(); - end = moment().add(2, 'day'); + start = dayjs(); + end = dayjs().add(2, 'day'); wrapper = mount(); }); @@ -685,7 +698,7 @@ describe('RangeCalendar', () => { let keyDownEvent = 0; const wrapper = mount( keyDownEvent = 1} @@ -761,7 +774,7 @@ describe('RangeCalendar', () => { }); it('change input trigger calendar close', () => { - const value = [moment(), moment().add(1, 'months')]; + const value = [dayjs(), dayjs().add(1, 'months')]; const onSelect = jest.fn(); const wrapper = mount( @@ -788,7 +801,7 @@ describe('RangeCalendar', () => { it('date mode should not display same month', () => { const FORMAT = 'YYYY-MM-DD'; - const sameDay = moment('2000-01-01'); + const sameDay = dayjs('2000-01-01'); const wrapper = mount(); // Should in different month @@ -814,7 +827,7 @@ describe('RangeCalendar', () => { mode={['time', 'time']} timePicker={ } />, diff --git a/tests/__snapshots__/Calendar.spec.jsx.snap b/tests/__snapshots__/Calendar.spec.jsx.snap index d87e39193..fadf1466d 100644 --- a/tests/__snapshots__/Calendar.spec.jsx.snap +++ b/tests/__snapshots__/Calendar.spec.jsx.snap @@ -29,938 +29,942 @@ exports[`Calendar controlled panels render controlled panels correctly 1`] = `
          -
          - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
          - 14 -
          - - - - - - - - - - - - - - - - - - - - - - - - - + + Su + + + + + + + + + + + - - - - - - - - - -
          - - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
          -
          - 26 -
          -
          -
          - 27 -
          -
          -
          - 28 -
          -
          -
          - 1 -
          -
          -
          - 2 -
          -
          -
          - 3 -
          -
          -
          - 4 -
          -
          -
          - 5 -
          -
          -
          - 6 -
          -
          -
          - 7 -
          -
          -
          - 8 -
          -
          -
          - 9 -
          -
          -
          - 10 -
          -
          -
          - 11 -
          -
          -
          - 12 -
          -
          -
          - 13 -
          -
          +
          -
          - 15 -
          -
          -
          - 16 -
          -
          -
          - 17 -
          -
          -
          - 18 -
          -
          -
          - 19 -
          -
          -
          - 20 -
          -
          -
          - 21 -
          -
          -
          - 22 -
          -
          -
          - 23 -
          -
          -
          - 24 -
          -
          -
          - 25 -
          -
          -
          - 26 -
          -
          -
          - 27 -
          -
          -
          - 28 -
          -
          -
          - 29 -
          -
          -
          - 30 -
          -
          -
          - 31 -
          -
          -
          - 1 -
          -
          + + Mo + + + + Tu + + + + We + + + + Th + + + + Fr + + + + Sa + +
          -
          - 2 -
          -
          -
          - 3 -
          -
          -
          - 4 -
          -
          -
          - 5 -
          -
          -
          - 6 -
          -
          -
          - 7 -
          -
          -
          - 8 -
          -
          -
          - +
          @@ -996,938 +1000,942 @@ exports[`Calendar controlled panels render controlled panels correctly 2`] = `
        -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - 20 -
        - - - - - - - - - - - - - - - - - + + Su + + + + + + + + + + + - - - - - - - - - -
        - - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
        -
        - 26 -
        -
        -
        - 27 -
        -
        -
        - 28 -
        -
        -
        - 1 -
        -
        -
        - 2 -
        -
        -
        - 3 -
        -
        -
        - 4 -
        -
        -
        - 5 -
        -
        -
        - 6 -
        -
        -
        - 7 -
        -
        -
        - 8 -
        -
        -
        - 9 -
        -
        -
        - 10 -
        -
        -
        - 11 -
        -
        -
        - 12 -
        -
        -
        - 13 -
        -
        -
        - 14 -
        -
        -
        - 15 -
        -
        -
        - 16 -
        -
        -
        - 17 -
        -
        -
        - 18 -
        -
        -
        - 19 -
        -
        +
        -
        - 21 -
        -
        -
        - 22 -
        -
        -
        - 23 -
        -
        -
        - 24 -
        -
        -
        - 25 -
        -
        -
        - 26 -
        -
        -
        - 27 -
        -
        -
        - 28 -
        -
        -
        - 29 -
        -
        -
        - 30 -
        -
        -
        - 31 -
        -
        -
        - 1 -
        -
        + + Mo + + + + Tu + + + + We + + + + Th + + + + Fr + + + + Sa + +
        -
        - 2 -
        -
        -
        - 3 -
        -
        -
        - 4 -
        -
        -
        - 5 -
        -
        -
        - 6 -
        -
        -
        - 7 -
        -
        -
        - 8 -
        -
        -
        - +
      @@ -1963,740 +1971,744 @@ exports[`Calendar render render correctly 1`] = `
@@ -2732,740 +2744,744 @@ exports[`Calendar render render correctly 2`] = `
@@ -3501,747 +3517,751 @@ exports[`Calendar render render correctly 3`] = `
- - - - March - + title="Last year (Control + left)" + /> + - 2017 - - - - -
-
-
- - - - - - - - - - - - - + + + + + +
+
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - + - - Sa - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 25 -
- -
- - - - - - - - - - + + Su + + + + + + + + + + + - - - - - - - - - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
+
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
+ + Mo + + + + Tu + + + + We + + + + Th + + + + Fr + + + + Sa + +
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
`; -exports[`Calendar render render correctly with invalid moment object 1`] = ` +exports[`Calendar render render correctly with invalid dayjs object 1`] = `
- - - - Mar - + title="Last year (Control + left)" + /> + - 2017 - - - - -
-
-
- - - - - - - - - - - - - + + + + + +
+
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - + - - Sa - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- 18 -
- -
- - - - - - - - - - - - - - - - - - - + + Su + + + + + + + + + + + - - - - - - - - - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
+
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
+ + Mo + + + + Tu + + + + We + + + + Th + + + + Fr + + + + Sa + +
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
diff --git a/tests/__snapshots__/FullCalendar.spec.js.snap b/tests/__snapshots__/FullCalendar.spec.js.snap index 69df28ea9..cdd760cd3 100644 --- a/tests/__snapshots__/FullCalendar.spec.js.snap +++ b/tests/__snapshots__/FullCalendar.spec.js.snap @@ -109,7 +109,7 @@ exports[`FullCalendar renders custom header correctly 1`] = `
Back to today @@ -1840,7 +1840,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 1`]
Back to today @@ -3746,7 +3746,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 2`]
Back to today @@ -5454,7 +5454,7 @@ exports[`RangeCalendar key control 1`] = `
Back to today @@ -6956,7 +6956,7 @@ exports[`RangeCalendar render hoverValue correctly 1`] = `
Back to today diff --git a/tests/__snapshots__/locale.spec.js.snap b/tests/__snapshots__/locale.spec.js.snap index aed844401..28f8811f7 100644 --- a/tests/__snapshots__/locale.spec.js.snap +++ b/tests/__snapshots__/locale.spec.js.snap @@ -29,740 +29,744 @@ exports[`locales renders ar_EG correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -798,740 +802,744 @@ exports[`locales renders bg_BG correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -1567,740 +1575,744 @@ exports[`locales renders ca_ES correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -2336,740 +2348,744 @@ exports[`locales renders cs_CZ correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -3105,740 +3121,744 @@ exports[`locales renders da_DK correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -3874,740 +3894,744 @@ exports[`locales renders de_DE correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -4643,740 +4667,744 @@ exports[`locales renders el_GR correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -5412,740 +5440,744 @@ exports[`locales renders en_GB correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -6181,740 +6213,744 @@ exports[`locales renders en_US correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -6950,740 +6986,744 @@ exports[`locales renders es_ES correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -7719,740 +7759,744 @@ exports[`locales renders et_EE correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -8488,740 +8532,744 @@ exports[`locales renders fa_IR correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -9257,740 +9305,744 @@ exports[`locales renders fi_FI correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -10026,740 +10078,744 @@ exports[`locales renders fr_BE correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -10795,740 +10851,744 @@ exports[`locales renders fr_FR correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -11564,740 +11624,744 @@ exports[`locales renders hu_HU correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -12333,740 +12397,744 @@ exports[`locales renders is_IS correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -13102,740 +13170,744 @@ exports[`locales renders it_IT correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -13871,740 +13943,744 @@ exports[`locales renders ja_JP correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -14640,740 +14716,744 @@ exports[`locales renders ko_KR correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -15409,740 +15489,744 @@ exports[`locales renders ku_IQ correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -16178,740 +16262,744 @@ exports[`locales renders nb_NO correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -16947,740 +17035,744 @@ exports[`locales renders nl_BE correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -17716,740 +17808,744 @@ exports[`locales renders nl_NL correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -18485,740 +18581,744 @@ exports[`locales renders pl_PL correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -19254,740 +19354,744 @@ exports[`locales renders pt_BR correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -20023,740 +20127,744 @@ exports[`locales renders pt_PT correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -20792,740 +20900,744 @@ exports[`locales renders ru_RU correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -21561,740 +21673,744 @@ exports[`locales renders sk_SK correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -22330,740 +22446,744 @@ exports[`locales renders sl_SI correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -23099,740 +23219,744 @@ exports[`locales renders sr_RS correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -23868,740 +23992,744 @@ exports[`locales renders sv_SE correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -24637,740 +24765,744 @@ exports[`locales renders th_TH correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -25406,740 +25538,744 @@ exports[`locales renders tr_TR correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -26175,740 +26311,744 @@ exports[`locales renders ug_CN correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -26944,740 +27084,744 @@ exports[`locales renders uk_UA correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -27713,740 +27857,744 @@ exports[`locales renders vi_VN correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -28482,740 +28630,744 @@ exports[`locales renders zh_CN correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
@@ -29251,740 +29403,744 @@ exports[`locales renders zh_TW correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Su - - - - Mo - - - - Tu - - - - We - - - - Th - - - - Fr - - - - Sa - -
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- 9 -
-
-
- 10 -
-
-
- 11 -
-
-
- 12 -
-
-
- 13 -
-
-
- 14 -
-
-
- 15 -
-
-
- 16 -
-
-
- 17 -
-
-
- 18 -
-
-
- 19 -
-
-
- 20 -
-
-
- 21 -
-
-
- 22 -
-
-
- 23 -
-
-
- 24 -
-
-
- 25 -
-
-
- 26 -
-
-
- 27 -
-
-
- 28 -
-
-
- 29 -
-
-
- 30 -
-
-
- 31 -
-
-
- 1 -
-
-
- 2 -
-
-
- 3 -
-
-
- 4 -
-
-
- 5 -
-
-
- 6 -
-
-
- 7 -
-
-
- 8 -
-
-
- +
From a26aa3a4a12a9ae98720e6a6e64a90a7a9e83f0a Mon Sep 17 00:00:00 2001 From: zxj96 <519213124@qq.com> Date: Tue, 22 Feb 2022 14:17:56 +0800 Subject: [PATCH 20/68] fix: optimizated code --- examples/antd-calendar.js | 13 ++----------- examples/antd-month-calendar.js | 9 ++------- examples/antd-range-calendar.js | 11 +---------- examples/full-calendar.js | 10 +--------- examples/getCalendarContainer.js | 10 +--------- examples/start-end-range.js | 10 +--------- examples/start-end.js | 10 +--------- examples/week.js | 12 +----------- package.json | 2 +- src/util/dayjs.js | 17 +++++++++++++++++ tests/Calendar.spec.jsx | 17 +---------------- tests/FullCalendar.spec.js | 13 +------------ tests/MonthCalendar.spec.js | 13 +------------ tests/Picker.spec.jsx | 17 +---------------- tests/RangeCalendar.spec.jsx | 17 +---------------- 15 files changed, 33 insertions(+), 148 deletions(-) create mode 100644 src/util/dayjs.js diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 5c29ac1a2..6170fefdb 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -10,19 +10,10 @@ import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import 'rc-time-picker/assets/index.css'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; - -import dayjs from 'dayjs'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; - -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; +import dayjs from '../src/util/dayjs'; const format = 'YYYY-MM-DD HH:mm:ss'; -const cn = true; - -dayjs.extend(utc); -dayjs.extend(localeData); +const cn = location.search.indexOf('cn') !== -1; let now = dayjs(); if (cn) { diff --git a/examples/antd-month-calendar.js b/examples/antd-month-calendar.js index c4750674e..c67a79b6a 100644 --- a/examples/antd-month-calendar.js +++ b/examples/antd-month-calendar.js @@ -9,13 +9,8 @@ import DatePicker from '@seafile/seafile-calendar/src/Picker'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); + +import dayjs from '../src/util/dayjs'; const format = 'YYYY-MM'; const cn = location.search.indexOf('cn') !== -1; diff --git a/examples/antd-range-calendar.js b/examples/antd-range-calendar.js index bf119322e..0fb941936 100644 --- a/examples/antd-range-calendar.js +++ b/examples/antd-range-calendar.js @@ -10,16 +10,7 @@ import TimePickerPanel from 'rc-time-picker/lib/Panel'; import '@seafile/seafile-calendar/assets/index.less'; import 'rc-time-picker/assets/index.css'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); - +import dayjs from '../src/util/dayjs'; const cn = location.search.indexOf('cn') !== -1; diff --git a/examples/full-calendar.js b/examples/full-calendar.js index 2847d2f91..3761a353f 100644 --- a/examples/full-calendar.js +++ b/examples/full-calendar.js @@ -11,15 +11,7 @@ import Select from 'rc-select'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); +import dayjs from '../src/util/dayjs'; const format = 'YYYY-MM-DD'; const cn = location.search.indexOf('cn') !== -1; diff --git a/examples/getCalendarContainer.js b/examples/getCalendarContainer.js index 9ed981c4b..c8148961d 100644 --- a/examples/getCalendarContainer.js +++ b/examples/getCalendarContainer.js @@ -9,15 +9,7 @@ import 'rc-dialog/assets/index.css'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); +import dayjs from '../src/util/dayjs'; const format = 'YYYY-MM-DD'; const cn = location.search.indexOf('cn') !== -1; diff --git a/examples/start-end-range.js b/examples/start-end-range.js index 0c495e8c0..244c9b50a 100644 --- a/examples/start-end-range.js +++ b/examples/start-end-range.js @@ -9,15 +9,7 @@ import DatePicker from '@seafile/seafile-calendar/src/Picker'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); +import dayjs from '../src/util/dayjs'; const format = 'YYYY-MM-DD'; diff --git a/examples/start-end.js b/examples/start-end.js index 2226d6b27..a09423e12 100644 --- a/examples/start-end.js +++ b/examples/start-end.js @@ -11,15 +11,7 @@ import enUS from '@seafile/seafile-calendar/src/locale/en_US'; import 'rc-time-picker/assets/index.css'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); +import dayjs from '../src/util/dayjs'; const format = 'YYYY-MM-DD HH:mm:ss'; const cn = location.search.indexOf('cn') !== -1; diff --git a/examples/week.js b/examples/week.js index 6138fefe0..538a39b2b 100644 --- a/examples/week.js +++ b/examples/week.js @@ -9,17 +9,7 @@ import DatePicker from '@seafile/seafile-calendar/src/Picker'; import zhCN from '@seafile/seafile-calendar/src/locale/zh_CN'; import enUS from '@seafile/seafile-calendar/src/locale/en_US'; -import dayjs from 'dayjs'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); -dayjs.extend(advancedFormat); +import dayjs from '../src/util/dayjs'; const format = 'YYYY-wo'; const cn = location.search.indexOf('cn') !== -1; diff --git a/package.json b/package.json index bd5ff17c3..052de4636 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.16", + "version": "0.0.18", "description": "React Calendar", "keywords": [ "react", diff --git a/src/util/dayjs.js b/src/util/dayjs.js new file mode 100644 index 000000000..46eebcbe6 --- /dev/null +++ b/src/util/dayjs.js @@ -0,0 +1,17 @@ +import dayjs from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; +import utc from 'dayjs/plugin/utc'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import badMutable from 'dayjs/plugin/badMutable'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en-gb'; + +dayjs.extend(localeData); +dayjs.extend(weekOfYear); +dayjs.extend(utc); +dayjs.extend(advancedFormat); +dayjs.extend(customParseFormat); +dayjs.extend(badMutable); +export default dayjs; diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index 01fd5f79a..31ccee411 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -1,28 +1,13 @@ /* eslint-disable no-undef */ import React from 'react'; import keyCode from 'rc-util/lib/KeyCode'; -import dayjs from 'dayjs'; +import dayjs from '../src/util/dayjs'; import { mount, render } from 'enzyme'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; import Calendar from '../src/Calendar'; import zhCN from '../src/locale/zh_CN'; import enUS from '../src/locale/en_US'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; -import badMutable from 'dayjs/plugin/badMutable'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); -dayjs.extend(advancedFormat); -dayjs.extend(customParseFormat); -dayjs.extend(badMutable); - const format = ('YYYY-MM-DD'); describe('Calendar', () => { diff --git a/tests/FullCalendar.spec.js b/tests/FullCalendar.spec.js index 4caf9e560..8d722b995 100644 --- a/tests/FullCalendar.spec.js +++ b/tests/FullCalendar.spec.js @@ -2,20 +2,9 @@ import React from 'react'; import Select from 'rc-select'; import { render, mount } from 'enzyme'; -import dayjs from 'dayjs'; +import dayjs from '../src/util/dayjs'; import FullCalendar from '../src/FullCalendar'; -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); -dayjs.extend(advancedFormat); - describe('FullCalendar', () => { it('renders month mode correctly', () => { const wrapper = render( diff --git a/tests/MonthCalendar.spec.js b/tests/MonthCalendar.spec.js index e5b0d0ad3..83a95e6e3 100644 --- a/tests/MonthCalendar.spec.js +++ b/tests/MonthCalendar.spec.js @@ -2,19 +2,8 @@ import React from 'react'; import { mount } from 'enzyme'; import keyCode from 'rc-util/lib/KeyCode'; -import dayjs from 'dayjs'; import MonthCalendar from '../src/MonthCalendar'; - -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); -dayjs.extend(advancedFormat); +import dayjs from '../src/util/dayjs'; describe('MonthCalendar', () => { it('year or decade panel work correctly', () => { diff --git a/tests/Picker.spec.jsx b/tests/Picker.spec.jsx index 0476e9c9f..1a7bb0397 100644 --- a/tests/Picker.spec.jsx +++ b/tests/Picker.spec.jsx @@ -1,26 +1,11 @@ import React from 'react'; -import dayjs from 'dayjs'; import { mount } from 'enzyme'; import keyCode from 'rc-util/lib/KeyCode'; import Calendar from '../index'; import DatePicker from '../src/Picker'; import RangeCalendar from '../src/RangeCalendar'; import CalendarLocale from '../src/locale/en_US'; - -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; -import badMutable from 'dayjs/plugin/badMutable'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); -dayjs.extend(advancedFormat); -dayjs.extend(customParseFormat); -dayjs.extend(badMutable); +import dayjs from '../src/util/dayjs'; const format = ('YYYY-MM-DD'); const VALUE = dayjs([2015, 5, 1]); diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index c3f2fd270..05de0b492 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -1,25 +1,10 @@ /* eslint-disable no-undef, max-len, react/no-multi-comp */ import React from 'react'; -import dayjs from 'dayjs'; import { mount, render } from 'enzyme'; import keyCode from 'rc-util/lib/KeyCode'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; import RangeCalendar from '../src/RangeCalendar'; - -import localeData from 'dayjs/plugin/localeData'; -import utc from 'dayjs/plugin/utc'; -import weekOfYear from 'dayjs/plugin/weekOfYear'; -import advancedFormat from 'dayjs/plugin/advancedFormat'; -import customParseFormat from 'dayjs/plugin/customParseFormat'; -import badMutable from 'dayjs/plugin/badMutable'; -import 'dayjs/locale/zh-cn'; -import 'dayjs/locale/en-gb'; -dayjs.extend(utc); -dayjs.extend(localeData); -dayjs.extend(weekOfYear); -dayjs.extend(advancedFormat); -dayjs.extend(customParseFormat); -dayjs.extend(badMutable); +import dayjs from '../src/util/dayjs'; const format = ('YYYY-MM-DD'); From 170da48c5b41614f8833aa4932b44115b81c7425 Mon Sep 17 00:00:00 2001 From: zxj96 <519213124@qq.com> Date: Wed, 2 Mar 2022 15:46:29 +0800 Subject: [PATCH 21/68] fix: caldaner width bug --- assets/index/Calendar.less | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 1d3fd3312..8b6a096bc 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -2,7 +2,7 @@ position: relative; outline: none; font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans-serif; - width: 253px; + width: fit-content; border: 1px solid #ccc; list-style: none; font-size: 12px; diff --git a/package.json b/package.json index 052de4636..1a1e49bed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.18", + "version": "0.0.19", "description": "React Calendar", "keywords": [ "react", From c6b8e99402628212603d5906dfcdeea8a0284e05 Mon Sep 17 00:00:00 2001 From: zxj96 <519213124@qq.com> Date: Wed, 20 Apr 2022 15:17:43 +0800 Subject: [PATCH 22/68] fix: dayjs does not introduce the loaneData plugin --- package.json | 2 +- src/FullCalendar.jsx | 2 +- src/MonthCalendar.jsx | 2 +- src/RangeCalendar.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1a1e49bed..2e2f6b3cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.19", + "version": "0.0.21", "description": "React Calendar", "keywords": [ "react", diff --git a/src/FullCalendar.jsx b/src/FullCalendar.jsx index 4a8cb19dc..4745406e9 100644 --- a/src/FullCalendar.jsx +++ b/src/FullCalendar.jsx @@ -11,7 +11,7 @@ import { } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import CalendarHeader from './full-calendar/CalendarHeader'; -import dayjs from 'dayjs'; +import dayjs from './util/dayjs'; class FullCalendar extends React.Component { static propTypes = { diff --git a/src/MonthCalendar.jsx b/src/MonthCalendar.jsx index bbee730ef..f2010ae36 100644 --- a/src/MonthCalendar.jsx +++ b/src/MonthCalendar.jsx @@ -10,7 +10,7 @@ import { calendarMixinDefaultProps, } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; -import dayjs from 'dayjs'; +import dayjs from './util/dayjs'; class MonthCalendar extends React.Component { static propTypes = { diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 9b5deb8ce..6783b590c 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -1,6 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import dayjs from 'dayjs'; import classnames from 'classnames'; import { polyfill } from 'react-lifecycles-compat'; import KeyCode from 'rc-util/lib/KeyCode'; @@ -11,6 +10,7 @@ import TimePickerButton from './calendar/TimePickerButton'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import { syncTime, getTodayTime, isAllowedDate } from './util'; import { goTime, goStartMonth, goEndMonth, includesTime } from './util/toTime'; +import dayjs from './util/dayjs'; function noop() { } From 90c0a842ae2b812837673b3d97a1eddb781559d5 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Thu, 8 Sep 2022 14:14:45 +0800 Subject: [PATCH 23/68] change click first or last year --- assets/index/YearPanel.less | 8 -------- package.json | 2 +- src/year/YearPanel.jsx | 12 +----------- tests/__snapshots__/Calendar.spec.jsx.snap | 4 ++-- tests/__snapshots__/RangeCalendar.spec.jsx.snap | 8 ++++---- 5 files changed, 8 insertions(+), 26 deletions(-) diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index cbdb0fc3d..96ed4d39d 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -124,11 +124,3 @@ color: #fff; } } - -.@{prefixClass}-year-panel-last-decade-cell, .@{prefixClass}-year-panel-next-decade-cell { - .@{prefixClass}-year-panel-year{ - user-select: none; - -webkit-user-select: none; - color: rgba(0, 0, 0, 0.25); - } -} \ No newline at end of file diff --git a/package.json b/package.json index 2e2f6b3cd..9ea185d68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.21", + "version": "0.0.22", "description": "React Calendar", "keywords": [ "react", diff --git a/src/year/YearPanel.jsx b/src/year/YearPanel.jsx index 48dbb67a8..b0d4acaf6 100644 --- a/src/year/YearPanel.jsx +++ b/src/year/YearPanel.jsx @@ -70,23 +70,13 @@ export default class YearPanel extends React.Component { const classNameMap = { [`${prefixCls}-cell`]: 1, [`${prefixCls}-selected-cell`]: yearData.year === currentYear, - [`${prefixCls}-last-decade-cell`]: yearData.year < startYear, - [`${prefixCls}-next-decade-cell`]: yearData.year > endYear, }; - let clickHandler; - if (yearData.year < startYear) { - clickHandler = this.previousDecade; - } else if (yearData.year > endYear) { - clickHandler = this.nextDecade; - } else { - clickHandler = chooseYear.bind(this, yearData.year); - } return ( @@ -1231,7 +1231,7 @@ exports[`Calendar controlled panels render controlled panels correctly 2`] = ` diff --git a/tests/__snapshots__/RangeCalendar.spec.jsx.snap b/tests/__snapshots__/RangeCalendar.spec.jsx.snap index 1b6910b9e..12d74df43 100644 --- a/tests/__snapshots__/RangeCalendar.spec.jsx.snap +++ b/tests/__snapshots__/RangeCalendar.spec.jsx.snap @@ -3495,7 +3495,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 2`] role="row" > @@ -3628,7 +3628,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 2`] @@ -4435,7 +4435,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 2`] role="row" > @@ -4568,7 +4568,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 2`] From a1d40aeb6b730d54c2104d835ed7768934ff040a Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Tue, 13 Sep 2022 10:09:33 +0800 Subject: [PATCH 24/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ea185d68..4e3504173 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.22", + "version": "0.0.24", "description": "React Calendar", "keywords": [ "react", From bd295da9b5d97533df18f38e1600c37cd11177f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=9B=BD=E7=92=87?= Date: Wed, 18 Sep 2024 10:53:41 +0800 Subject: [PATCH 25/68] feat: time second --- README.md | 3 +++ package.json | 2 +- src/Calendar.jsx | 14 +++++++------ src/calendar/CalendarRightPanel.jsx | 32 +++++++++++++++++++++-------- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6cc73412a..e134ae6ec 100644 --- a/README.md +++ b/README.md @@ -756,3 +756,6 @@ open coverage/ dir ## License rc-calendar is released under the MIT license. + +# node version +18.20.4 diff --git a/package.json b/package.json index 4e3504173..a2c66406c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.24", + "version": "0.0.25", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index dbe76d353..6b52dca17 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -53,7 +53,8 @@ class Calendar extends React.Component { showToday: PropTypes.bool, showOk: PropTypes.bool, showHourAndMinute: PropTypes.bool, - defaultMinutesTime: PropTypes.string, + showSecond: PropTypes.bool, + defaultTime: PropTypes.string, onSelect: PropTypes.func, onOk: PropTypes.func, onKeyDown: PropTypes.func, @@ -284,9 +285,9 @@ class Calendar extends React.Component { render() { const { props, state } = this; const { - locale, prefixCls, disabledDate, + locale, prefixCls, disabledDate, showSecond, showHourAndMinute, dateInputPlaceholder, timePicker, onClickRightPanelTime, - disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, + disabledTime, clearIcon, renderFooter, inputMode, defaultTime, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -399,16 +400,17 @@ class Calendar extends React.Component { onCloseTimePicker={this.closeTimePicker} />
- {showHourAndMinute && + {(showHourAndMinute || showSecond) && ( - } + )}
); diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 8497b5eaf..dfbe55760 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -5,12 +5,13 @@ import dayjs from 'dayjs'; export default class CalendarRightPanel extends React.Component { static propTypes = { + showSecond: PropTypes.bool, prefixCls: PropTypes.string, value: PropTypes.object, + locale: PropTypes.object, + defaultTime: PropTypes.string, onSelect: PropTypes.func, onClickRightPanelTime: PropTypes.func, - locale: PropTypes.object, - defaultMinutesTime: PropTypes.string, } constructor(props) { @@ -23,8 +24,8 @@ export default class CalendarRightPanel extends React.Component { } componentDidMount() { - const { defaultMinutesTime } = this.props; - const showTimeIndex = this.times.findIndex(item => item === defaultMinutesTime); + const { defaultTime } = this.props; + const showTimeIndex = defaultTime ? this.times.findIndex(item => item >= defaultTime) : -1; const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex : 16; this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); } @@ -38,12 +39,27 @@ export default class CalendarRightPanel extends React.Component { } getTimes = () => { + const { showSecond } = this.props; const times = []; for (let i = 0; i < 24; i++) { - const str = (`${String(i)}:00`).padStart(5, '0'); - const str1 = (`${String(i)}:30`).padStart(5, '0'); - times.push(str); - times.push(str1); + const minute0 = (`${String(i)}:00`).padStart(5, '0'); + if (showSecond) { + const second0 = `${minute0}:00`; + const second30 = `${minute0}:30`; + times.push(second0); + times.push(second30); + } else { + times.push(minute0); + } + const minute30 = (`${String(i)}:30`).padStart(5, '0'); + if (showSecond) { + const second0 = `${minute30}:00`; + const second30 = `${minute30}:30`; + times.push(second0); + times.push(second30); + } else { + times.push(minute30); + } } return times; } From 3104a71b2d2171c3d7df11fb9757202fcc087ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=9B=BD=E7=92=87?= Date: Wed, 18 Sep 2024 11:22:34 +0800 Subject: [PATCH 26/68] feat: update code --- src/Calendar.jsx | 6 ++---- src/calendar/CalendarRightPanel.jsx | 20 ++------------------ 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 6b52dca17..7f91fb764 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -53,7 +53,6 @@ class Calendar extends React.Component { showToday: PropTypes.bool, showOk: PropTypes.bool, showHourAndMinute: PropTypes.bool, - showSecond: PropTypes.bool, defaultTime: PropTypes.string, onSelect: PropTypes.func, onOk: PropTypes.func, @@ -285,7 +284,7 @@ class Calendar extends React.Component { render() { const { props, state } = this; const { - locale, prefixCls, disabledDate, showSecond, showHourAndMinute, + locale, prefixCls, disabledDate, showHourAndMinute, dateInputPlaceholder, timePicker, onClickRightPanelTime, disabledTime, clearIcon, renderFooter, inputMode, defaultTime, } = props; @@ -400,9 +399,8 @@ class Calendar extends React.Component { onCloseTimePicker={this.closeTimePicker} />
- {(showHourAndMinute || showSecond) && ( + {(showHourAndMinute) && ( { - const { showSecond } = this.props; const times = []; for (let i = 0; i < 24; i++) { const minute0 = (`${String(i)}:00`).padStart(5, '0'); - if (showSecond) { - const second0 = `${minute0}:00`; - const second30 = `${minute0}:30`; - times.push(second0); - times.push(second30); - } else { - times.push(minute0); - } + times.push(minute0); const minute30 = (`${String(i)}:30`).padStart(5, '0'); - if (showSecond) { - const second0 = `${minute30}:00`; - const second30 = `${minute30}:30`; - times.push(second0); - times.push(second30); - } else { - times.push(minute30); - } + times.push(minute30); } return times; } From f573335b18bdbc984b1707eaf8474ef7d5b51b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=9B=BD=E7=92=87?= Date: Wed, 18 Sep 2024 15:21:52 +0800 Subject: [PATCH 27/68] feat: update code --- package.json | 7 +++++-- src/calendar/CalendarRightPanel.jsx | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index a2c66406c..3b886282a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.25", + "version": "0.0.27", "description": "React Calendar", "keywords": [ "react", @@ -97,5 +97,8 @@ "rc-util": "^4.1.1", "react-lifecycles-compat": "^3.0.4" }, - "types": "index.d.ts" + "types": "index.d.ts", + "overrides": { + "graceful-fs": "^4.2.11" + } } diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 8423aa543..7e814a7de 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -29,12 +29,12 @@ export default class CalendarRightPanel extends React.Component { this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); } - onSelect = (value) => { + onSelect = (value, event) => { this.setState({ highlightTime: value, }); this.props.onSelect(value); - this.props.onClickRightPanelTime(); + this.props.onClickRightPanelTime(event); } getTimes = () => { From 6281a2987237708328d8763c8dd7445670b9b51d Mon Sep 17 00:00:00 2001 From: er-pai-r <18335219360@163.com> Date: Wed, 18 Sep 2024 22:30:41 +0800 Subject: [PATCH 28/68] feat: update code --- package.json | 2 +- src/Calendar.jsx | 12 ++++++------ src/calendar/CalendarRightPanel.jsx | 18 +++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 3b886282a..cc95dd161 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.27", + "version": "0.0.28", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 7f91fb764..dbe76d353 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -53,7 +53,7 @@ class Calendar extends React.Component { showToday: PropTypes.bool, showOk: PropTypes.bool, showHourAndMinute: PropTypes.bool, - defaultTime: PropTypes.string, + defaultMinutesTime: PropTypes.string, onSelect: PropTypes.func, onOk: PropTypes.func, onKeyDown: PropTypes.func, @@ -284,9 +284,9 @@ class Calendar extends React.Component { render() { const { props, state } = this; const { - locale, prefixCls, disabledDate, showHourAndMinute, + locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, onClickRightPanelTime, - disabledTime, clearIcon, renderFooter, inputMode, defaultTime, + disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -399,16 +399,16 @@ class Calendar extends React.Component { onCloseTimePicker={this.closeTimePicker} />
- {(showHourAndMinute) && ( + {showHourAndMinute && - )} + }
); diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 7e814a7de..637dc6693 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -7,10 +7,10 @@ export default class CalendarRightPanel extends React.Component { static propTypes = { prefixCls: PropTypes.string, value: PropTypes.object, - locale: PropTypes.object, - defaultTime: PropTypes.string, onSelect: PropTypes.func, onClickRightPanelTime: PropTypes.func, + locale: PropTypes.object, + defaultMinutesTime: PropTypes.string, } constructor(props) { @@ -23,9 +23,9 @@ export default class CalendarRightPanel extends React.Component { } componentDidMount() { - const { defaultTime } = this.props; - const showTimeIndex = defaultTime ? this.times.findIndex(item => item >= defaultTime) : -1; - const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex : 16; + const { defaultMinutesTime } = this.props; + const showTimeIndex = this.times.findIndex(item => item >= defaultMinutesTime); + const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex - 1 : 16; this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); } @@ -40,10 +40,10 @@ export default class CalendarRightPanel extends React.Component { getTimes = () => { const times = []; for (let i = 0; i < 24; i++) { - const minute0 = (`${String(i)}:00`).padStart(5, '0'); - times.push(minute0); - const minute30 = (`${String(i)}:30`).padStart(5, '0'); - times.push(minute30); + const str = (`${String(i)}:00`).padStart(5, '0'); + const str1 = (`${String(i)}:30`).padStart(5, '0'); + times.push(str); + times.push(str1); } return times; } From 9650d96a85e796e51e549977fb7ed37137a31fd7 Mon Sep 17 00:00:00 2001 From: er-pai-r <18335219360@163.com> Date: Wed, 18 Sep 2024 22:35:20 +0800 Subject: [PATCH 29/68] feat: update code --- src/calendar/CalendarRightPanel.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 637dc6693..861378753 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -29,12 +29,12 @@ export default class CalendarRightPanel extends React.Component { this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); } - onSelect = (value, event) => { + onSelect = (value) => { this.setState({ highlightTime: value, }); this.props.onSelect(value); - this.props.onClickRightPanelTime(event); + this.props.onClickRightPanelTime(); } getTimes = () => { From 1fbc075e67f29884e41824b6b638d8c31ad2ee19 Mon Sep 17 00:00:00 2001 From: er-pai-r <18335219360@163.com> Date: Wed, 18 Sep 2024 23:32:28 +0800 Subject: [PATCH 30/68] feat: update version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e134ae6ec..7b4bbfb01 100644 --- a/README.md +++ b/README.md @@ -758,4 +758,4 @@ open coverage/ dir rc-calendar is released under the MIT license. # node version -18.20.4 +>= 18.20.4 From 4320e200fb9b04856916767f73f10a1043aad57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E9=91=AB?= Date: Tue, 1 Apr 2025 15:19:09 +0800 Subject: [PATCH 31/68] support customizing the first day of week --- src/Calendar.jsx | 6 ++++-- src/date/DateConstants.js | 17 ++++++++++++++++- src/date/DateTBody.jsx | 22 ++++++++++++---------- src/date/DateTHead.jsx | 32 +++++++++++++++++++------------- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index dbe76d353..17645fca9 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -85,6 +85,7 @@ class Calendar extends React.Component { onPanelChange: noop, onClickRightPanelTime: noop, focusablePanel: true, + firstDayOfWeek: 'Sunday', } constructor(props) { @@ -286,7 +287,7 @@ class Calendar extends React.Component { const { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, onClickRightPanelTime, - disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, + disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, firstDayOfWeek, showWeekNumber } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -371,7 +372,8 @@ class Calendar extends React.Component { dateRender={props.dateRender} onSelect={this.onDateTableSelect} disabledDate={disabledDate} - showWeekNumber={props.showWeekNumber} + showWeekNumber={showWeekNumber} + firstDayOfWeek={firstDayOfWeek} />
diff --git a/src/date/DateConstants.js b/src/date/DateConstants.js index 55f910b00..439228b70 100644 --- a/src/date/DateConstants.js +++ b/src/date/DateConstants.js @@ -1,4 +1,19 @@ -export default { +const DATE_ROW_COLUMN_COUNT = { DATE_ROW_COUNT: 6, DATE_COL_COUNT: 7, }; + +const DAY_NAME_TO_INDEX = { + Sunday: 0, + Monday: 1, + Tuesday: 2, + Wednesday: 3, + Thursday: 4, + Friday: 5, + Saturday: 6, +}; + +export default { + DATE_ROW_COLUMN_COUNT, + DAY_NAME_TO_INDEX +}; diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index 0c356ec6b..5ad7e3060 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -4,6 +4,8 @@ import cx from 'classnames'; import DateConstants from './DateConstants'; import { getTitleString, getTodayTime } from '../util/'; +const { DATE_ROW_COLUMN_COUNT, DAY_NAME_TO_INDEX } = DateConstants; + function isSameDay(one, two) { return one && two && one.isSame(two, 'day'); } @@ -38,6 +40,7 @@ export default class DateTBody extends React.Component { value: PropTypes.object, hoverValue: PropTypes.any, showWeekNumber: PropTypes.bool, + firstDayOfWeek: PropTypes.string, } static defaultProps = { @@ -49,7 +52,7 @@ export default class DateTBody extends React.Component { const { contentRender, prefixCls, selectedValue, value, showWeekNumber, dateRender, disabledDate, - hoverValue, + hoverValue, firstDayOfWeek, } = props; let iIndex; let jIndex; @@ -74,17 +77,16 @@ export default class DateTBody extends React.Component { let month1 = value.clone(); month1 = month1.date(1); const day = month1.day(); - // const firstDayOfWeek = value.localeData().firstDayOfWeek(); - // We set Sunday(7) as the first day of the week in seafile-calendar. - const firstDayOfWeek = 7; - const lastMonthDiffDay = (day + 7 - firstDayOfWeek) % 7; + const firstDayName = typeof firstDayOfWeek === 'string' ? firstDayOfWeek[0].toUpperCase() + firstDayOfWeek.slice(1) : 'Sunday'; + const firstDayIndex = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0; + const lastMonthDiffDay = (day + 7 - firstDayIndex) % 7; // calculate last month let lastMonth1 = month1.clone(); lastMonth1 = lastMonth1.add(0 - lastMonthDiffDay, 'days'); let passed = 0; - for (iIndex = 0; iIndex < DateConstants.DATE_ROW_COUNT; iIndex++) { - for (jIndex = 0; jIndex < DateConstants.DATE_COL_COUNT; jIndex++) { + for (iIndex = 0; iIndex < DATE_ROW_COLUMN_COUNT.DATE_ROW_COUNT; iIndex++) { + for (jIndex = 0; jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; jIndex++) { current = lastMonth1; if (passed) { current = current.clone(); @@ -97,7 +99,7 @@ export default class DateTBody extends React.Component { const tableHtml = []; passed = 0; - for (iIndex = 0; iIndex < DateConstants.DATE_ROW_COUNT; iIndex++) { + for (iIndex = 0; iIndex < DATE_ROW_COLUMN_COUNT.DATE_ROW_COUNT; iIndex++) { let isCurrentWeek; let weekNumberCell; let isActiveWeek = false; @@ -113,11 +115,11 @@ export default class DateTBody extends React.Component { ); } - for (jIndex = 0; jIndex < DateConstants.DATE_COL_COUNT; jIndex++) { + for (jIndex = 0; jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; jIndex++) { let next = null; let last = null; current = dateTable[passed]; - if (jIndex < DateConstants.DATE_COL_COUNT - 1) { + if (jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT - 1) { next = dateTable[passed + 1]; } if (jIndex > 0) { diff --git a/src/date/DateTHead.jsx b/src/date/DateTHead.jsx index abed34ac6..0fa1f6968 100644 --- a/src/date/DateTHead.jsx +++ b/src/date/DateTHead.jsx @@ -1,24 +1,30 @@ import React from 'react'; +import DateConstants from './DateConstants'; + +const { DAY_NAME_TO_INDEX } = DateConstants; export default class DateTHead extends React.Component { render() { const props = this.props; const value = props.value; - const localeData = value.localeData(); + const localeData = value.localeData(); const prefixCls = props.prefixCls; - // const veryShortWeekdays = []; - // const weekDays = []; - // const firstDayOfWeek = localeData.firstDayOfWeek(); - // We set Sunday(7) as the first day of the week in seafile-calendar. + const veryShortWeekdays = []; + const weekDays = []; + + const allWeekdaysMin = localeData.weekdaysMin(); + const allWeekdaysShort = localeData.weekdaysShort(); + + let firstDayName = typeof props.firstDayOfWeek === 'string' ? props.firstDayOfWeek[0].toUpperCase() + props.firstDayOfWeek.slice(1) : 'Sunday'; + const firstDay = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0; + let showWeekNumberEl; - // for (let dateColIndex = 0; dateColIndex < DateConstants.DATE_COL_COUNT; dateColIndex++) { - // const index = (firstDayOfWeek + dateColIndex) % DateConstants.DATE_COL_COUNT; - // now.day(index); - // veryShortWeekdays[dateColIndex] = localeData.weekdaysMin(); - // weekDays[dateColIndex] = localeData.weekdaysShort(); - // } - const veryShortWeekdays = localeData.weekdaysMin(); - const weekDays = localeData.weekdaysShort(); + for (let dateColIndex = 0; dateColIndex < 7; dateColIndex++) { + const index = (firstDay + dateColIndex) % 7; + veryShortWeekdays[dateColIndex] = allWeekdaysMin[index]; + weekDays[dateColIndex] = allWeekdaysShort[index]; + } + if (props.showWeekNumber) { showWeekNumberEl = ( Date: Tue, 1 Apr 2025 15:22:09 +0800 Subject: [PATCH 32/68] update --- src/date/DateTHead.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/date/DateTHead.jsx b/src/date/DateTHead.jsx index 0fa1f6968..5a7e630a6 100644 --- a/src/date/DateTHead.jsx +++ b/src/date/DateTHead.jsx @@ -7,7 +7,7 @@ export default class DateTHead extends React.Component { render() { const props = this.props; const value = props.value; - const localeData = value.localeData(); + const localeData = value.localeData(); const prefixCls = props.prefixCls; const veryShortWeekdays = []; const weekDays = []; From cf40eadde3118a8482ebe3f10f872a5d0ca26667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E9=91=AB?= Date: Tue, 1 Apr 2025 15:23:29 +0800 Subject: [PATCH 33/68] update --- src/date/DateTHead.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/date/DateTHead.jsx b/src/date/DateTHead.jsx index 5a7e630a6..4742b68bf 100644 --- a/src/date/DateTHead.jsx +++ b/src/date/DateTHead.jsx @@ -1,7 +1,7 @@ import React from 'react'; import DateConstants from './DateConstants'; -const { DAY_NAME_TO_INDEX } = DateConstants; +const { DAY_NAME_TO_INDEX, DATE_ROW_COLUMN_COUNT } = DateConstants; export default class DateTHead extends React.Component { render() { @@ -19,8 +19,8 @@ export default class DateTHead extends React.Component { const firstDay = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0; let showWeekNumberEl; - for (let dateColIndex = 0; dateColIndex < 7; dateColIndex++) { - const index = (firstDay + dateColIndex) % 7; + for (let dateColIndex = 0; dateColIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; dateColIndex++) { + const index = (firstDay + dateColIndex) % DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; veryShortWeekdays[dateColIndex] = allWeekdaysMin[index]; weekDays[dateColIndex] = allWeekdaysShort[index]; } From 302684fe785c3581b627b71ca6c3f298edac364b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E9=91=AB?= Date: Wed, 9 Apr 2025 09:47:56 +0800 Subject: [PATCH 34/68] opt code --- src/Calendar.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 17645fca9..862f93de5 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -72,6 +72,7 @@ class Calendar extends React.Component { inputMode: PropTypes.string, onBlur: PropTypes.func, onClickRightPanelTime: PropTypes.func, + firstDayOfWeek: PropTypes.string, } static defaultProps = { From 02b5412c5ee9fec9b84c1e4c1d659d498ad54455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=9B=BD=E7=92=87?= Date: Tue, 15 Apr 2025 10:37:58 +0800 Subject: [PATCH 35/68] fix: code problems --- package.json | 2 +- src/Calendar.jsx | 3 ++- src/date/DateConstants.js | 2 +- src/date/DateTBody.jsx | 4 +++- src/date/DateTHead.jsx | 15 +++++++++------ 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index cc95dd161..46959ee9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.28", + "version": "0.0.29", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 862f93de5..492192604 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -288,7 +288,8 @@ class Calendar extends React.Component { const { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, onClickRightPanelTime, - disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, firstDayOfWeek, showWeekNumber + disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, + firstDayOfWeek, showWeekNumber, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; diff --git a/src/date/DateConstants.js b/src/date/DateConstants.js index 439228b70..e64fd817b 100644 --- a/src/date/DateConstants.js +++ b/src/date/DateConstants.js @@ -15,5 +15,5 @@ const DAY_NAME_TO_INDEX = { export default { DATE_ROW_COLUMN_COUNT, - DAY_NAME_TO_INDEX + DAY_NAME_TO_INDEX, }; diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index 5ad7e3060..a9dd61672 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -77,7 +77,9 @@ export default class DateTBody extends React.Component { let month1 = value.clone(); month1 = month1.date(1); const day = month1.day(); - const firstDayName = typeof firstDayOfWeek === 'string' ? firstDayOfWeek[0].toUpperCase() + firstDayOfWeek.slice(1) : 'Sunday'; + const firstDayName = typeof firstDayOfWeek === 'string' + ? firstDayOfWeek[0].toUpperCase() + firstDayOfWeek.slice(1) + : 'Sunday'; const firstDayIndex = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0; const lastMonthDiffDay = (day + 7 - firstDayIndex) % 7; // calculate last month diff --git a/src/date/DateTHead.jsx b/src/date/DateTHead.jsx index 4742b68bf..6001b32ce 100644 --- a/src/date/DateTHead.jsx +++ b/src/date/DateTHead.jsx @@ -11,16 +11,19 @@ export default class DateTHead extends React.Component { const prefixCls = props.prefixCls; const veryShortWeekdays = []; const weekDays = []; - + const allWeekdaysMin = localeData.weekdaysMin(); const allWeekdaysShort = localeData.weekdaysShort(); - - let firstDayName = typeof props.firstDayOfWeek === 'string' ? props.firstDayOfWeek[0].toUpperCase() + props.firstDayOfWeek.slice(1) : 'Sunday'; + + const firstDayName = typeof props.firstDayOfWeek === 'string' + ? props.firstDayOfWeek[0].toUpperCase() + props.firstDayOfWeek.slice(1) + : 'Sunday'; const firstDay = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0; - + let showWeekNumberEl; - for (let dateColIndex = 0; dateColIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; dateColIndex++) { - const index = (firstDay + dateColIndex) % DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; + const dateColumnCount = DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; + for (let dateColIndex = 0; dateColIndex < dateColumnCount; dateColIndex++) { + const index = (firstDay + dateColIndex) % dateColumnCount; veryShortWeekdays[dateColIndex] = allWeekdaysMin[index]; weekDays[dateColIndex] = allWeekdaysShort[index]; } From 27f70583443bfa89a2bd138e51b81c880adfefd0 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Sun, 15 Jun 2025 20:22:15 +0800 Subject: [PATCH 36/68] add rules --- src/Calendar.jsx | 5 +- src/calendar/CalendarRightPanel.jsx | 8 +- src/date/DateInput.js | 54 ++--- src/util/index.js | 316 ++++++++++++++++++++++++++++ 4 files changed, 342 insertions(+), 41 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 492192604..7e3678526 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -316,6 +316,8 @@ class Calendar extends React.Component { timePickerEle = React.cloneElement(timePicker, timePickerProps); } + const calanderInputPlaceholder = dateInputPlaceholder || + (Array.isArray(this.getFormat()) ? this.getFormat()[0] : this.getFormat()); const dateInputElement = props.showDateInput ? ( }
diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index 861378753..bde116997 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import dayjs from 'dayjs'; +import { tokenizeFormattedDate } from '../util'; export default class CalendarRightPanel extends React.Component { @@ -11,12 +12,14 @@ export default class CalendarRightPanel extends React.Component { onClickRightPanelTime: PropTypes.func, locale: PropTypes.object, defaultMinutesTime: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), } constructor(props) { super(props); this.state = { highlightTime: this.props.value || null, + localeFormat: this.props.format[0], }; this.timeRef = React.createRef(); this.times = this.getTimes(); @@ -58,7 +61,7 @@ export default class CalendarRightPanel extends React.Component { render() { const { value, prefixCls, locale } = this.props; - const selectedDate = value.format().slice(0, 10); + const selectedDate = value.format().slice(0, String(value.format()).indexOf('T')); const highlight = this.state.highlightTime; const highlightTime = highlight ? highlight.format().slice(11, 16) : null; const isZhcn = (locale && locale.today === '今天'); @@ -70,7 +73,8 @@ export default class CalendarRightPanel extends React.Component {
    {this.times.map((time) => { - let current = dayjs(`${selectedDate} ${time}`); + const parts = tokenizeFormattedDate(selectedDate, this.state.localeFormat); + let current = dayjs(`${selectedDate} ${time}`).year(parts[0]).month(parts[1] - 1).date(parts[2]); // eslint-disable-line max-len current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb'); return (
  • { - this.setState({ - str: '', - }); + this.setState({ str: '' }); this.props.onClear(null); } onInputChange = (event) => { const str = event.target.value; + const calendarStr = initializeStr(str, this.state.localFormat) || ''; const { disabledDate, format, onChange, selectedValue } = this.props; // 没有内容,合法并直接退出 - if (!str) { + if (!calendarStr) { onChange(null); - this.setState({ - invalid: false, - str, - }); - return; - } - - // 不合法直接退出 - const parsed = dayjs(str, format, true); - if (!parsed.isValid()) { - this.setState({ - invalid: true, - str, - }); + this.setState({ str: '' }); return; } - + const parsed = dayjs(calendarStr, format[0]); let value = this.props.value.clone(); value = value .year(parsed.year()) @@ -88,20 +76,14 @@ class DateInput extends React.Component { .second(parsed.second()); if (!value || (disabledDate && disabledDate(value))) { - this.setState({ - invalid: true, - str, - }); + this.setState({ str }); return; } if (selectedValue !== value || ( selectedValue && value && !selectedValue.isSame(value) )) { - this.setState({ - invalid: false, - str, - }); + this.setState({ str }); onChange(value); } } @@ -139,10 +121,7 @@ class DateInput extends React.Component { // when popup show, click body will call this, bug! const selectedValue = nextProps.selectedValue; if (!state.hasFocus) { - newState = { - str: formatDate(selectedValue, nextProps.format), - invalid: false, - }; + newState = { str: formatDate(selectedValue, nextProps.format) }; } return newState; @@ -168,15 +147,14 @@ class DateInput extends React.Component { render() { const props = this.props; - const { invalid, str } = this.state; + const { str } = this.state; const { locale, prefixCls, placeholder, clearIcon, inputMode } = props; - const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; return (
    = 1 && day <= 31; + } + if ([4, 6, 9, 11].includes(currentMonth)) { + return day >= 1 && day <= 30; + } + if (currentMonth === 2) { + const isLeapYear = (year) => { + return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); + }; + const year = currentYear; + if (isLeapYear(year)) { + return day >= 1 && day <= 29; + } + return day >= 1 && day <= 28; + } +} + +export function tokenizeFormattedDate(formatStr, format) { + const str = formatStr || ''; + let cleanStr; + switch (format) { + case DATE_FORMATS.ISO: + case DATE_FORMATS.ISOAndTime: + cleanStr = str.replace(/[^0-9]+/g, '-'); + return cleanStr.split('-').filter(Boolean).map(String); + case DATE_FORMATS.US: + case DATE_FORMATS.USAndTime: + case DATE_FORMATS.European: + case DATE_FORMATS.EuropeanAndTime: + cleanStr = str.replace(/[^0-9]+/g, '/'); + return cleanStr.split('/').filter(Boolean).map(String); + case DATE_FORMATS.Germany_Russia_etc: + case DATE_FORMATS.Germany_Russia_etcAndTime: + cleanStr = str.replace(/[^0-9]+/g, '.'); + return cleanStr.split('.').filter(Boolean).map(String); + default: + return []; + } +} + +export function hasSpecialChar(str) { + const matches = str.match(/[^0-9]/g); + return matches ? matches.length : 0; +} + +export function validateTime(inputTime) { + if (!inputTime || typeof inputTime !== 'string') { + return currentTime; + } + const trimmed = inputTime.trim(); + const timeRegex = /^(\d{2}):(\d{2})$/; + const match = trimmed.match(timeRegex); + if (!match) { + return currentTime; + } + const hour = Number(match[1]); + const minute = Number(match[2]); + if (hour > 23 || minute > 59) { + return currentTime; + } + return `${match[1]}:${match[2]}`; +} + +export function delimate(format) { + let delimiter; + if (format === DATE_FORMATS.Germany_Russia_etc || + format === DATE_FORMATS.Germany_Russia_etcAndTime) { + delimiter = '.'; + } else if (format === DATE_FORMATS.ISO || format === DATE_FORMATS.ISOAndTime) { + delimiter = '-'; + } else { + delimiter = '/'; + } + return delimiter; +} + +export function validateCalendarYear(yearStr) { + const year = yearStr; + if (!year || isNaN(year)) return currentYear; + if (year.length === 2) { + if (Number(year) >= 0 && Number(year) < 69) { + return year ? `20${year}` : currentYear; + } else if (Number(year) >= 69 && Number(year) < 100) { + return year ? `19${year}` : currentYear; + } + } + if (year.length === 4) { + return year; + } + return year ? year.padStart(4, '0') : currentYear; +} + +export const isLeapYear = (year) => { + return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); +}; + +export function validateCalendarDayAndMonth(dayStr, monthStr, yearStr) { + let day = Number(dayStr); + let month = Number(monthStr); + let year = yearStr; + const isInThirtyOneDaysMonths = [1, 3, 5, 7, 8, 10, 12].includes(month); + const isInThirtyDaysMonths = [4, 6, 9, 11].includes(month); + const isValidDayThirtyOne = day < 1 || day > 31; + const isValidDayThirty = day < 1 || day > 30; + const isValidDayTwentyNight = day < 1 || day > 29; + const isValidDayTwentyEight = day < 1 || day > 28; + + if (month > 12 || month < 0 || !month) { + day = currentDate; + month = currentMonth; + year = currentYear; + } + + if ((isInThirtyOneDaysMonths && isValidDayThirtyOne) + || (isInThirtyDaysMonths && isValidDayThirty)) { + day = currentDate; + month = currentMonth; + year = currentYear; + } + + if (month === 2) { + if (isLeapYear(year) && isValidDayTwentyNight) { + day = currentDate; + month = currentMonth; + year = currentYear; + } else if (isValidDayTwentyEight) { + day = currentDate; + month = currentMonth; + year = currentYear; + } + } + return { day, month, year }; +} + +export function getDatePart(str) { + if (typeof str !== 'string') return ''; + const parts = str.trim().split(/\s+/); + return parts[0]; +} + +export function initializeStr(str, format) { + const inputStr = str; + const inputStrLength = inputStr.length; + let time = currentTime; + const hasSpecial = hasSpecialChar(inputStr); + const formattedArray = tokenizeFormattedDate(inputStr, format, DATE_FORMATS); + const dateDelimater = delimate(format); + if (format === DATE_FORMATS.ISO) { + if (hasSpecial) { + const validateYear = validateCalendarYear(formattedArray[0]); + let { day, month } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + const { year } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${year}${dateDelimater}${month}${dateDelimater}${day}`; + } else if (inputStrLength >= 1 && inputStrLength <= 8) { + const yearStr = inputStr.slice(0, 4); + const monthStr = inputStr.slice(4, 6) || '01'; + const dateStr = inputStr.slice(6, 8) || '01'; + const validateYear = validateCalendarYear(yearStr); + let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${year}${dateDelimater}${month}${dateDelimater}${day}`; + } else if (inputStrLength > 8) { + return `${currentYear}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)}`; // eslint-disable-line max-len + } + } else if (format === DATE_FORMATS.ISOAndTime) { + const datePart = getDatePart(inputStr); + const formattedDateArray = tokenizeFormattedDate(datePart, format); + const isDateSpecial = hasSpecialChar(datePart); + if (isDateSpecial) { + if (formattedDateArray.length < 3) { + formattedArray.splice(2, 0, '01'); + } + const validateYear = validateCalendarYear(formattedArray[0]); + let { day, month } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + const { year } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${year}${dateDelimater}${month}${dateDelimater}${day} ${time}`; + } else if (datePart.length >= 1 && datePart.length <= 8) { + const yearStr = datePart.slice(0, 4); + const monthStr = datePart.slice(4, 6) || '01'; + const dateStr = datePart.slice(6, 8) || '01'; + const timeParts = tokenizeFormattedDate(inputStr, format); + time = validateTime(`${timeParts[1]}:${timeParts[2]}`); + const validateYear = validateCalendarYear(yearStr); + let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${year}${dateDelimater}${month}${dateDelimater}${day} ${time}`; + } else if (datePart.length > 8) { + return `${currentYear}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)} ${currentTime}`; // eslint-disable-line max-len + } + } else if (format === DATE_FORMATS.US) { + if (hasSpecial) { + const validateYear = validateCalendarYear(formattedArray[2]); + const { day, month, year } = validateCalendarDayAndMonth(formattedArray[1] || '1', formattedArray[0], validateYear); // eslint-disable-line max-len + return `${month}${dateDelimater}${day}${dateDelimater}${year}`; + } else if (inputStrLength >= 1 && inputStrLength <= 8) { + const monthStr = inputStr.slice(0, 2); + const dateStr = inputStr.slice(2, 4) || '1'; + const yearStr = inputStr.slice(4, inputStr.length); + const validateYear = validateCalendarYear(yearStr); + const { day, month, year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + return `${month}${dateDelimater}${day}${dateDelimater}${year}`; // eslint-disable-line max-len + } else if (inputStrLength > 8) { + return `${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)}${dateDelimater}${currentYear}`; // eslint-disable-line max-len + } + } else if (format === DATE_FORMATS.USAndTime) { + const datePart = getDatePart(inputStr); + const formattedDateArray = tokenizeFormattedDate(datePart, format); + const isDateSpecial = hasSpecialChar(datePart); + if (isDateSpecial) { + if (formattedDateArray.length < 3) { + formattedArray.splice(2, 0, String(currentYear)); + } + const validateYear = validateCalendarYear(formattedArray[2]); + const { day, month, year } = validateCalendarDayAndMonth(formattedArray[1] || '1', formattedArray[0], validateYear); // eslint-disable-line max-len + time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); + return `${month}${dateDelimater}${day}${dateDelimater}${year} ${time}`; + } else if (datePart.length >= 1 && datePart.length <= 8) { + const monthStr = datePart.slice(0, 2); + const dateStr = datePart.slice(2, 4) || '1'; + const yearStr = datePart.slice(4, datePart.length); + const validateYear = validateCalendarYear(yearStr); // eslint-disable-line max-len + const { day, month, year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const timeParts = tokenizeFormattedDate(inputStr, format); + time = validateTime(`${timeParts[1]}:${timeParts[2]}`) || currentTime; + return `${month}${dateDelimater}${day}${dateDelimater}${year} ${time}`; + } else if (datePart.length > 8) { + return `${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)}${dateDelimater}${currentYear} ${currentTime}`; // eslint-disable-line max-len + } + } else if (format === DATE_FORMATS.European + || format === DATE_FORMATS.Germany_Russia_etc + ) { + if (hasSpecial) { + const validateYear = validateCalendarYear(formattedArray[2]); + let { day, month } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + const { year } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${day}${dateDelimater}${month}${dateDelimater}${year}`; + } else if (inputStrLength >= 1 && inputStrLength <= 8) { + const dateStr = inputStr.slice(0, 2); + const monthStr = inputStr.slice(2, 4); + const yearStr = inputStr.slice(4, inputStr.length); + const validateYear = validateCalendarYear(yearStr); + const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); // eslint-disable-line max-len + let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); // eslint-disable-line max-len + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${day}${dateDelimater}${month}${dateDelimater}${year}`; + } else if (inputStrLength > 8) { + return `${String(currentDate).padStart(2, 0)}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${currentYear}`; // eslint-disable-line max-len + } + } else if (format === DATE_FORMATS.EuropeanAndTime + || format === DATE_FORMATS.Germany_Russia_etcAndTime + ) { + const datePart = getDatePart(inputStr); + const formattedDateArray = tokenizeFormattedDate(datePart, format); + const isDateSpecial = hasSpecialChar(datePart); + if (isDateSpecial) { + if (formattedDateArray.length < 3) { + formattedArray.splice(2, 0, String(currentYear)); + } + const validateYear = validateCalendarYear(formattedArray[2]); + let { day, month } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + const { year } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${day}${dateDelimater}${month}${dateDelimater}${year} ${time}`; + } else if (datePart.length >= 1 && datePart.length <= 8) { + const dateStr = datePart.slice(0, 2); + const monthStr = datePart.slice(2, 4); + const yearStr = datePart.slice(4, datePart.length); + const timeParts = tokenizeFormattedDate(inputStr, format); + time = validateTime(`${timeParts[1]}:${timeParts[2]}`); + const validateYear = validateCalendarYear(yearStr); + let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${day}${dateDelimater}${month}${dateDelimater}${year} ${time}`; + } else if (datePart.length > 8) { + return `${String(currentDate).padStart(2, 0)}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${currentYear} ${currentTime}`; // eslint-disable-line max-len + } + } +} From cbf92ef66a280ff0a47768e30da7df9dad387ce0 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Sun, 15 Jun 2025 21:00:52 +0800 Subject: [PATCH 37/68] add rules --- src/util/index.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/util/index.js b/src/util/index.js index 62a909262..18b8de301 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -275,6 +275,18 @@ export function initializeStr(str, format) { const formattedArray = tokenizeFormattedDate(inputStr, format, DATE_FORMATS); const dateDelimater = delimate(format); if (format === DATE_FORMATS.ISO) { + const numStr = inputStr.replace(/[^0-9]/g, ''); + if (numStr.length === 7 || numStr.length === 8) { + const yearStr = numStr.slice(0, 4); + const monthStr = numStr.slice(4, 6) || '01'; + const dateStr = numStr.slice(6, numStr.length) || '01'; + const validateYear = validateCalendarYear(yearStr); + let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${year}${dateDelimater}${month}${dateDelimater}${day}`; + } if (hasSpecial) { const validateYear = validateCalendarYear(formattedArray[0]); let { day, month } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len @@ -299,6 +311,27 @@ export function initializeStr(str, format) { const datePart = getDatePart(inputStr); const formattedDateArray = tokenizeFormattedDate(datePart, format); const isDateSpecial = hasSpecialChar(datePart); + const numStr = datePart.replace(/[^0-9]/g, ''); + if (numStr.length === 7 || numStr.length === 8) { + const yearStr = numStr.slice(0, 4); + const monthStr = numStr.slice(4, 6) || '01'; + const dateStr = numStr.slice(6, numStr.length) || '01'; + if (formattedArray.length === 3) { + time = validateTime(`${formattedArray[1]}:${formattedArray[2]}`); + } + if (formattedArray.length === 4) { + time = validateTime(`${formattedArray[2]}:${formattedArray[3]}`); + } + if (formattedArray.length === 5) { + time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); + } + const validateYear = validateCalendarYear(yearStr); + let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + day = String(day).padStart(2, 0); + month = String(month).padStart(2, 0); + return `${year}${dateDelimater}${month}${dateDelimater}${day} ${time}`; + } if (isDateSpecial) { if (formattedDateArray.length < 3) { formattedArray.splice(2, 0, '01'); From 82bb7dbfe44121c58f06196701a534d2c85fa853 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:33:26 +0800 Subject: [PATCH 38/68] fix code --- src/calendar/CalendarRightPanel.jsx | 3 +- src/util/index.js | 141 ++++++++++++++-------------- 2 files changed, 71 insertions(+), 73 deletions(-) diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index bde116997..a8eaaaa70 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -17,9 +17,10 @@ export default class CalendarRightPanel extends React.Component { constructor(props) { super(props); + const format = Array.isArray(this.props.format) ? this.props.format[0] : this.props.format; this.state = { highlightTime: this.props.value || null, - localeFormat: this.props.format[0], + localeFormat: format, }; this.timeRef = React.createRef(); this.times = this.getTimes(); diff --git a/src/util/index.js b/src/util/index.js index 18b8de301..0c97f5eb0 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -2,12 +2,10 @@ import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; dayjs.extend(utc); -export const currentDate = dayjs().date(); -export const currentMonth = dayjs().month() + 1; -export const currentYear = dayjs().year(); -export const stringCurrentDate = String(currentDate).padStart(2, '0'); -export const stringCurrentMonth = String(currentMonth).padStart(2, '0'); -export const currentTime = dayjs().format('HH:mm'); +export const getCurrentDate = () => dayjs().date(); +export const getCurrentMonth = () => dayjs().month() + 1; +export const getCurrentYear = () => dayjs().year(); +export const getCurrentTime = () => dayjs().format('HH:mm'); export const DATE_FORMATS = { ISO: 'YYYY-MM-DD', @@ -123,20 +121,23 @@ export function formatDate(value, format) { return value.format(format); } +export const isLeapYear = (year) => { + return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); +}; + export function validateCalendarDay(dayStr) { if (!/^\d+$/.test(dayStr)) return false; const day = Number(dayStr); - if ([1, 3, 5, 7, 8, 10, 12].includes(currentMonth)) { + const MONTHS_WITH_31_DAYS = [1, 3, 5, 7, 8, 10, 12]; + const MONTHS_WITH_30_DAYS = [4, 6, 9, 11]; + if (MONTHS_WITH_31_DAYS.includes(getCurrentMonth())) { return day >= 1 && day <= 31; } - if ([4, 6, 9, 11].includes(currentMonth)) { + if (MONTHS_WITH_30_DAYS.includes(getCurrentMonth())) { return day >= 1 && day <= 30; } - if (currentMonth === 2) { - const isLeapYear = (year) => { - return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); - }; - const year = currentYear; + if (getCurrentMonth() === 2) { + const year = getCurrentYear(); if (isLeapYear(year)) { return day >= 1 && day <= 29; } @@ -174,18 +175,18 @@ export function hasSpecialChar(str) { export function validateTime(inputTime) { if (!inputTime || typeof inputTime !== 'string') { - return currentTime; + return getCurrentTime(); } const trimmed = inputTime.trim(); const timeRegex = /^(\d{2}):(\d{2})$/; const match = trimmed.match(timeRegex); if (!match) { - return currentTime; + return getCurrentTime(); } const hour = Number(match[1]); const minute = Number(match[2]); if (hour > 23 || minute > 59) { - return currentTime; + return getCurrentTime(); } return `${match[1]}:${match[2]}`; } @@ -205,25 +206,21 @@ export function delimate(format) { export function validateCalendarYear(yearStr) { const year = yearStr; - if (!year || isNaN(year)) return currentYear; + if (!year || isNaN(year)) return getCurrentYear(); if (year.length === 2) { if (Number(year) >= 0 && Number(year) < 69) { - return year ? `20${year}` : currentYear; + return year ? `20${year}` : getCurrentYear(); } else if (Number(year) >= 69 && Number(year) < 100) { - return year ? `19${year}` : currentYear; + return year ? `19${year}` : getCurrentYear(); } } if (year.length === 4) { return year; } - return year ? year.padStart(4, '0') : currentYear; + return year ? year.padStart(4, '0') : getCurrentYear(); } -export const isLeapYear = (year) => { - return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); -}; - -export function validateCalendarDayAndMonth(dayStr, monthStr, yearStr) { +export function validateAndNormalizeDate(dayStr, monthStr, yearStr) { let day = Number(dayStr); let month = Number(monthStr); let year = yearStr; @@ -235,27 +232,27 @@ export function validateCalendarDayAndMonth(dayStr, monthStr, yearStr) { const isValidDayTwentyEight = day < 1 || day > 28; if (month > 12 || month < 0 || !month) { - day = currentDate; - month = currentMonth; - year = currentYear; + day = getCurrentDate(); + month = getCurrentMonth(); + year = getCurrentYear(); } if ((isInThirtyOneDaysMonths && isValidDayThirtyOne) || (isInThirtyDaysMonths && isValidDayThirty)) { - day = currentDate; - month = currentMonth; - year = currentYear; + day = getCurrentDate(); + month = getCurrentMonth(); + year = getCurrentYear(); } if (month === 2) { if (isLeapYear(year) && isValidDayTwentyNight) { - day = currentDate; - month = currentMonth; - year = currentYear; + day = getCurrentDate(); + month = getCurrentMonth(); + year = getCurrentYear(); } else if (isValidDayTwentyEight) { - day = currentDate; - month = currentMonth; - year = currentYear; + day = getCurrentDate(); + month = getCurrentMonth(); + year = getCurrentYear(); } } return { day, month, year }; @@ -270,9 +267,9 @@ export function getDatePart(str) { export function initializeStr(str, format) { const inputStr = str; const inputStrLength = inputStr.length; - let time = currentTime; + let time = getCurrentTime(); const hasSpecial = hasSpecialChar(inputStr); - const formattedArray = tokenizeFormattedDate(inputStr, format, DATE_FORMATS); + const formattedArray = tokenizeFormattedDate(inputStr, format); const dateDelimater = delimate(format); if (format === DATE_FORMATS.ISO) { const numStr = inputStr.replace(/[^0-9]/g, ''); @@ -281,16 +278,16 @@ export function initializeStr(str, format) { const monthStr = numStr.slice(4, 6) || '01'; const dateStr = numStr.slice(6, numStr.length) || '01'; const validateYear = validateCalendarYear(yearStr); - let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); - const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + let { day, month } = validateAndNormalizeDate(dateStr, monthStr, validateYear); + const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${year}${dateDelimater}${month}${dateDelimater}${day}`; } if (hasSpecial) { const validateYear = validateCalendarYear(formattedArray[0]); - let { day, month } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len - const { year } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + let { day, month } = validateAndNormalizeDate(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + const { year } = validateAndNormalizeDate(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${year}${dateDelimater}${month}${dateDelimater}${day}`; @@ -299,13 +296,13 @@ export function initializeStr(str, format) { const monthStr = inputStr.slice(4, 6) || '01'; const dateStr = inputStr.slice(6, 8) || '01'; const validateYear = validateCalendarYear(yearStr); - let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); - const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + let { day, month } = validateAndNormalizeDate(dateStr, monthStr, validateYear); + const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${year}${dateDelimater}${month}${dateDelimater}${day}`; } else if (inputStrLength > 8) { - return `${currentYear}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)}`; // eslint-disable-line max-len + return `${getCurrentYear()}${dateDelimater}${String(getCurrentMonth()).padStart(2, 0)}${dateDelimater}${String(getCurrentDate()).padStart(2, 0)}`; // eslint-disable-line max-len } } else if (format === DATE_FORMATS.ISOAndTime) { const datePart = getDatePart(inputStr); @@ -326,8 +323,8 @@ export function initializeStr(str, format) { time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); } const validateYear = validateCalendarYear(yearStr); - let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); - const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + let { day, month } = validateAndNormalizeDate(dateStr, monthStr, validateYear); + const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${year}${dateDelimater}${month}${dateDelimater}${day} ${time}`; @@ -337,8 +334,8 @@ export function initializeStr(str, format) { formattedArray.splice(2, 0, '01'); } const validateYear = validateCalendarYear(formattedArray[0]); - let { day, month } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len - const { year } = validateCalendarDayAndMonth(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + let { day, month } = validateAndNormalizeDate(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len + const { year } = validateAndNormalizeDate(formattedArray[2] || '01', formattedArray[1] || '01', validateYear); // eslint-disable-line max-len time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); @@ -350,28 +347,28 @@ export function initializeStr(str, format) { const timeParts = tokenizeFormattedDate(inputStr, format); time = validateTime(`${timeParts[1]}:${timeParts[2]}`); const validateYear = validateCalendarYear(yearStr); - let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); - const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + let { day, month } = validateAndNormalizeDate(dateStr, monthStr, validateYear); + const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${year}${dateDelimater}${month}${dateDelimater}${day} ${time}`; } else if (datePart.length > 8) { - return `${currentYear}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)} ${currentTime}`; // eslint-disable-line max-len + return `${getCurrentYear()}${dateDelimater}${String(getCurrentMonth()).padStart(2, 0)}${dateDelimater}${String(getCurrentDate()).padStart(2, 0)} ${getCurrentTime()}`; // eslint-disable-line max-len } } else if (format === DATE_FORMATS.US) { if (hasSpecial) { const validateYear = validateCalendarYear(formattedArray[2]); - const { day, month, year } = validateCalendarDayAndMonth(formattedArray[1] || '1', formattedArray[0], validateYear); // eslint-disable-line max-len + const { day, month, year } = validateAndNormalizeDate(formattedArray[1] || '1', formattedArray[0], validateYear); // eslint-disable-line max-len return `${month}${dateDelimater}${day}${dateDelimater}${year}`; } else if (inputStrLength >= 1 && inputStrLength <= 8) { const monthStr = inputStr.slice(0, 2); const dateStr = inputStr.slice(2, 4) || '1'; const yearStr = inputStr.slice(4, inputStr.length); const validateYear = validateCalendarYear(yearStr); - const { day, month, year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { day, month, year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); return `${month}${dateDelimater}${day}${dateDelimater}${year}`; // eslint-disable-line max-len } else if (inputStrLength > 8) { - return `${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)}${dateDelimater}${currentYear}`; // eslint-disable-line max-len + return `${String(getCurrentMonth()).padStart(2, 0)}${dateDelimater}${String(getCurrentDate()).padStart(2, 0)}${dateDelimater}${getCurrentYear()}`; // eslint-disable-line max-len } } else if (format === DATE_FORMATS.USAndTime) { const datePart = getDatePart(inputStr); @@ -379,10 +376,10 @@ export function initializeStr(str, format) { const isDateSpecial = hasSpecialChar(datePart); if (isDateSpecial) { if (formattedDateArray.length < 3) { - formattedArray.splice(2, 0, String(currentYear)); + formattedArray.splice(2, 0, String(getCurrentYear())); } const validateYear = validateCalendarYear(formattedArray[2]); - const { day, month, year } = validateCalendarDayAndMonth(formattedArray[1] || '1', formattedArray[0], validateYear); // eslint-disable-line max-len + const { day, month, year } = validateAndNormalizeDate(formattedArray[1] || '1', formattedArray[0], validateYear); // eslint-disable-line max-len time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); return `${month}${dateDelimater}${day}${dateDelimater}${year} ${time}`; } else if (datePart.length >= 1 && datePart.length <= 8) { @@ -390,20 +387,20 @@ export function initializeStr(str, format) { const dateStr = datePart.slice(2, 4) || '1'; const yearStr = datePart.slice(4, datePart.length); const validateYear = validateCalendarYear(yearStr); // eslint-disable-line max-len - const { day, month, year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + const { day, month, year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); const timeParts = tokenizeFormattedDate(inputStr, format); - time = validateTime(`${timeParts[1]}:${timeParts[2]}`) || currentTime; + time = validateTime(`${timeParts[1]}:${timeParts[2]}`) || getCurrentTime(); return `${month}${dateDelimater}${day}${dateDelimater}${year} ${time}`; } else if (datePart.length > 8) { - return `${String(currentMonth).padStart(2, 0)}${dateDelimater}${String(currentDate).padStart(2, 0)}${dateDelimater}${currentYear} ${currentTime}`; // eslint-disable-line max-len + return `${String(getCurrentMonth()).padStart(2, 0)}${dateDelimater}${String(getCurrentDate()).padStart(2, 0)}${dateDelimater}${getCurrentYear()} ${getCurrentTime()}`; // eslint-disable-line max-len } } else if (format === DATE_FORMATS.European || format === DATE_FORMATS.Germany_Russia_etc ) { if (hasSpecial) { const validateYear = validateCalendarYear(formattedArray[2]); - let { day, month } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len - const { year } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + let { day, month } = validateAndNormalizeDate(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + const { year } = validateAndNormalizeDate(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${day}${dateDelimater}${month}${dateDelimater}${year}`; @@ -412,13 +409,13 @@ export function initializeStr(str, format) { const monthStr = inputStr.slice(2, 4); const yearStr = inputStr.slice(4, inputStr.length); const validateYear = validateCalendarYear(yearStr); - const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); // eslint-disable-line max-len - let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); // eslint-disable-line max-len + const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); // eslint-disable-line max-len + let { day, month } = validateAndNormalizeDate(dateStr, monthStr, validateYear); // eslint-disable-line max-len day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${day}${dateDelimater}${month}${dateDelimater}${year}`; } else if (inputStrLength > 8) { - return `${String(currentDate).padStart(2, 0)}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${currentYear}`; // eslint-disable-line max-len + return `${String(getCurrentDate()).padStart(2, 0)}${dateDelimater}${String(getCurrentMonth()).padStart(2, 0)}${dateDelimater}${getCurrentYear()}`; // eslint-disable-line max-len } } else if (format === DATE_FORMATS.EuropeanAndTime || format === DATE_FORMATS.Germany_Russia_etcAndTime @@ -428,11 +425,11 @@ export function initializeStr(str, format) { const isDateSpecial = hasSpecialChar(datePart); if (isDateSpecial) { if (formattedDateArray.length < 3) { - formattedArray.splice(2, 0, String(currentYear)); + formattedArray.splice(2, 0, String(getCurrentYear())); } const validateYear = validateCalendarYear(formattedArray[2]); - let { day, month } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len - const { year } = validateCalendarDayAndMonth(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + let { day, month } = validateAndNormalizeDate(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len + const { year } = validateAndNormalizeDate(formattedArray[0], formattedArray[1], validateYear); // eslint-disable-line max-len time = validateTime(`${formattedArray[3]}:${formattedArray[4]}`); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); @@ -444,13 +441,13 @@ export function initializeStr(str, format) { const timeParts = tokenizeFormattedDate(inputStr, format); time = validateTime(`${timeParts[1]}:${timeParts[2]}`); const validateYear = validateCalendarYear(yearStr); - let { day, month } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); - const { year } = validateCalendarDayAndMonth(dateStr, monthStr, validateYear); + let { day, month } = validateAndNormalizeDate(dateStr, monthStr, validateYear); + const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); day = String(day).padStart(2, 0); month = String(month).padStart(2, 0); return `${day}${dateDelimater}${month}${dateDelimater}${year} ${time}`; } else if (datePart.length > 8) { - return `${String(currentDate).padStart(2, 0)}${dateDelimater}${String(currentMonth).padStart(2, 0)}${dateDelimater}${currentYear} ${currentTime}`; // eslint-disable-line max-len + return `${String(getCurrentDate()).padStart(2, 0)}${dateDelimater}${String(getCurrentMonth()).padStart(2, 0)}${dateDelimater}${getCurrentYear()} ${getCurrentTime()}`; // eslint-disable-line max-len } } } From 0d363cc11cb4838ae11d2ffe2bc4940cbc8eb891 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:40:15 +0800 Subject: [PATCH 39/68] fix code --- src/Calendar.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 7e3678526..64061e087 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -316,7 +316,7 @@ class Calendar extends React.Component { timePickerEle = React.cloneElement(timePicker, timePickerProps); } - const calanderInputPlaceholder = dateInputPlaceholder || + const calendarInputPlaceholder = dateInputPlaceholder || (Array.isArray(this.getFormat()) ? this.getFormat()[0] : this.getFormat()); const dateInputElement = props.showDateInput ? ( @@ -325,7 +325,7 @@ class Calendar extends React.Component { key="date-input" value={value} locale={locale} - placeholder={calanderInputPlaceholder} + placeholder={calendarInputPlaceholder} showClear disabledTime={disabledTime} disabledDate={disabledDate} From 1eb2dc75df7ec2305cb416dbf6ae484d37f558b2 Mon Sep 17 00:00:00 2001 From: LJHAAAAA <3421079018@qq.com> Date: Sat, 21 Jun 2025 09:47:20 +0800 Subject: [PATCH 40/68] Update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46959ee9d..4f6f6822d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.29", + "version": "0.0.30", "description": "React Calendar", "keywords": [ "react", From 950fbb901a493f50bffc4b22b4c601aa78182839 Mon Sep 17 00:00:00 2001 From: LJHAAAAA <3421079018@qq.com> Date: Sat, 21 Jun 2025 10:11:57 +0800 Subject: [PATCH 41/68] Update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4f6f6822d..33bc5f81f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.30", + "version": "0.0.31", "description": "React Calendar", "keywords": [ "react", From 739c012ee5d924b582baf872c8358e693529642a Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:24:14 +0800 Subject: [PATCH 42/68] eu and ru,and de init --- src/util/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/index.js b/src/util/index.js index 0c97f5eb0..7cb7999e8 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -406,7 +406,7 @@ export function initializeStr(str, format) { return `${day}${dateDelimater}${month}${dateDelimater}${year}`; } else if (inputStrLength >= 1 && inputStrLength <= 8) { const dateStr = inputStr.slice(0, 2); - const monthStr = inputStr.slice(2, 4); + const monthStr = inputStr.slice(2, 4) || getCurrentMonth(); const yearStr = inputStr.slice(4, inputStr.length); const validateYear = validateCalendarYear(yearStr); const { year } = validateAndNormalizeDate(dateStr, monthStr, validateYear); // eslint-disable-line max-len @@ -436,7 +436,7 @@ export function initializeStr(str, format) { return `${day}${dateDelimater}${month}${dateDelimater}${year} ${time}`; } else if (datePart.length >= 1 && datePart.length <= 8) { const dateStr = datePart.slice(0, 2); - const monthStr = datePart.slice(2, 4); + const monthStr = datePart.slice(2, 4) || getCurrentMonth(); const yearStr = datePart.slice(4, datePart.length); const timeParts = tokenizeFormattedDate(inputStr, format); time = validateTime(`${timeParts[1]}:${timeParts[2]}`); From fb70162ec069c4335413ac0c9e4193ebd586c266 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Fri, 27 Jun 2025 14:48:03 +0800 Subject: [PATCH 43/68] add esc and enter logic for time type date --- src/date/DateInput.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 9f84ab1bc..888aae55d 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -60,8 +60,8 @@ class DateInput extends React.Component { const { disabledDate, format, onChange, selectedValue } = this.props; // 没有内容,合法并直接退出 - if (!calendarStr) { - onChange(null); + if (!str) { + onChange(dayjs()); this.setState({ str: '' }); return; } From 60fc30b7520aa5b086dd4ff130809a78f4fbad58 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Tue, 1 Jul 2025 11:01:15 +0800 Subject: [PATCH 44/68] update chokidar for node version --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 33bc5f81f..56fa68b9e 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "devDependencies": { "@types/react": "^16.3.13", "async": "~3.1.0", + "chokidar": "^4.0.3", "dtslint": "^0.9.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", From ef8b9a07f5e394786505aa00532c4dcb80789697 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Thu, 3 Jul 2025 17:42:27 +0800 Subject: [PATCH 45/68] add enter logic --- src/Calendar.jsx | 6 +++++- src/date/DateInput.js | 5 ++--- src/date/DateTBody.jsx | 10 ++++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 64061e087..baa2a575f 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -98,6 +98,7 @@ class Calendar extends React.Component { getMomentObjectIfValid(props.defaultValue) || dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, + currentStatus: 0, }; } @@ -186,6 +187,7 @@ class Calendar extends React.Component { onClear = () => { this.onSelect(null); this.props.onClear(); + this.setState({ currentStatus: 1 }); } onOk = () => { @@ -210,6 +212,7 @@ class Calendar extends React.Component { onDateTableSelect = (value) => { const { timePicker } = this.props; const { selectedValue } = this.state; + this.setState({ currentStatus: 0 }); if (!selectedValue && timePicker) { const timePickerDefaultValue = timePicker.props.defaultValue; if (timePickerDefaultValue) { @@ -291,7 +294,7 @@ class Calendar extends React.Component { disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, firstDayOfWeek, showWeekNumber, } = props; - const { value, selectedValue, mode } = state; + const { value, selectedValue, mode, currentStatus } = state; const showTimePicker = mode === 'time'; const disabledTimeConfig = showTimePicker && disabledTime && timePicker ? getTimeConfig(selectedValue, disabledTime) : null; @@ -378,6 +381,7 @@ class Calendar extends React.Component { disabledDate={disabledDate} showWeekNumber={showWeekNumber} firstDayOfWeek={firstDayOfWeek} + currentStatus={currentStatus} />
    diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 888aae55d..a1fa78f2b 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -60,9 +60,8 @@ class DateInput extends React.Component { const { disabledDate, format, onChange, selectedValue } = this.props; // 没有内容,合法并直接退出 - if (!str) { - onChange(dayjs()); - this.setState({ str: '' }); + if (!str || !calendarStr) { + this.onClear(); return; } const parsed = dayjs(calendarStr, format[0]); diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index a9dd61672..0b0d3ea7e 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import cx from 'classnames'; import DateConstants from './DateConstants'; import { getTitleString, getTodayTime } from '../util/'; +import dayjs from 'dayjs'; const { DATE_ROW_COLUMN_COUNT, DAY_NAME_TO_INDEX } = DateConstants; @@ -41,6 +42,7 @@ export default class DateTBody extends React.Component { hoverValue: PropTypes.any, showWeekNumber: PropTypes.bool, firstDayOfWeek: PropTypes.string, + currentStatus: PropTypes.number, } static defaultProps = { @@ -52,7 +54,7 @@ export default class DateTBody extends React.Component { const { contentRender, prefixCls, selectedValue, value, showWeekNumber, dateRender, disabledDate, - hoverValue, firstDayOfWeek, + hoverValue, firstDayOfWeek, currentStatus, } = props; let iIndex; let jIndex; @@ -120,7 +122,11 @@ export default class DateTBody extends React.Component { for (jIndex = 0; jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; jIndex++) { let next = null; let last = null; - current = dateTable[passed]; + if (currentStatus === 1) { + current = dateTable[passed].hour(dayjs().hour()).minute(dayjs().minute()).second(dayjs().second()); // eslint-disable-line max-len + } else { + current = dateTable[passed]; + } if (jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT - 1) { next = dateTable[passed + 1]; } From be5aac0b7f21fc2ad15e0ce861520d6aa2baceb1 Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Thu, 3 Jul 2025 18:30:16 +0800 Subject: [PATCH 46/68] fix time --- src/Calendar.jsx | 4 +++- src/Picker.jsx | 1 + src/date/DateInput.js | 9 +++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index baa2a575f..7a30bd3b5 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -73,6 +73,7 @@ class Calendar extends React.Component { onBlur: PropTypes.func, onClickRightPanelTime: PropTypes.func, firstDayOfWeek: PropTypes.string, + shouldDisplayCurrent: PropTypes.bool, } static defaultProps = { @@ -292,7 +293,7 @@ class Calendar extends React.Component { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, onClickRightPanelTime, disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, - firstDayOfWeek, showWeekNumber, + firstDayOfWeek, showWeekNumber, shouldDisplayCurrent, } = props; const { value, selectedValue, mode, currentStatus } = state; const showTimePicker = mode === 'time'; @@ -330,6 +331,7 @@ class Calendar extends React.Component { locale={locale} placeholder={calendarInputPlaceholder} showClear + shouldDisplayCurrent={shouldDisplayCurrent} disabledTime={disabledTime} disabledDate={disabledDate} onClear={this.onClear} diff --git a/src/Picker.jsx b/src/Picker.jsx index bce6db698..6b63d33e3 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -151,6 +151,7 @@ class Picker extends React.Component { ref: this.saveCalendarRef, defaultValue: defaultValue || calendarProps.defaultValue, selectedValue: value, + shouldDisplayCurrent: calendarProps.shouldDisplayCurrent, onKeyDown: this.onCalendarKeyDown, onOk: createChainedFunction(calendarProps.onOk, this.onCalendarOk), onSelect: createChainedFunction(calendarProps.onSelect, this.onCalendarSelect), diff --git a/src/date/DateInput.js b/src/date/DateInput.js index a1fa78f2b..43d2459c0 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -29,6 +29,7 @@ class DateInput extends React.Component { selectedValue: PropTypes.object, clearIcon: PropTypes.node, inputMode: PropTypes.string, + shouldDisplayCurrent: PropTypes.bool, }; constructor(props) { @@ -57,10 +58,14 @@ class DateInput extends React.Component { onInputChange = (event) => { const str = event.target.value; const calendarStr = initializeStr(str, this.state.localFormat) || ''; - const { disabledDate, format, onChange, selectedValue } = this.props; - + const { disabledDate, format, onChange, selectedValue, shouldDisplayCurrent } = this.props; // 没有内容,合法并直接退出 if (!str || !calendarStr) { + if (shouldDisplayCurrent) { + this.setState({ str: '' }); + onChange(null); + return; + } this.onClear(); return; } From e4f8f4575fffbd8f62c0002f2f4d6d34aa70995c Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Fri, 4 Jul 2025 12:01:19 +0800 Subject: [PATCH 47/68] add um --- src/date/DateInput.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 43d2459c0..dd7f0382c 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -63,10 +63,10 @@ class DateInput extends React.Component { if (!str || !calendarStr) { if (shouldDisplayCurrent) { this.setState({ str: '' }); - onChange(null); - return; + onChange(dayjs()); + } else { + this.onClear(); } - this.onClear(); return; } const parsed = dayjs(calendarStr, format[0]); From b6a18fe356092220ac075f828b1dee7fd75d851d Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Fri, 4 Jul 2025 15:48:18 +0800 Subject: [PATCH 48/68] fix error --- src/Calendar.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 7a30bd3b5..66406adf8 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -322,10 +322,11 @@ class Calendar extends React.Component { } const calendarInputPlaceholder = dateInputPlaceholder || (Array.isArray(this.getFormat()) ? this.getFormat()[0] : this.getFormat()); + const inputFormat = Array.isArray(this.getFormat()) ? this.getFormat() : [this.getFormat()]; const dateInputElement = props.showDateInput ? ( }
    From f626a2c1a92e87fb2ea23e879307a2dc621f8b4d Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:54:20 +0800 Subject: [PATCH 49/68] fix time --- src/Calendar.jsx | 10 ++++------ src/Picker.jsx | 1 - src/date/DateInput.js | 19 ++++++++++--------- src/date/DateTBody.jsx | 4 ++-- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 66406adf8..b695df50f 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -73,7 +73,6 @@ class Calendar extends React.Component { onBlur: PropTypes.func, onClickRightPanelTime: PropTypes.func, firstDayOfWeek: PropTypes.string, - shouldDisplayCurrent: PropTypes.bool, } static defaultProps = { @@ -99,7 +98,7 @@ class Calendar extends React.Component { getMomentObjectIfValid(props.defaultValue) || dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, - currentStatus: 0, + currentStatus: 'selectDateTime', }; } @@ -188,7 +187,7 @@ class Calendar extends React.Component { onClear = () => { this.onSelect(null); this.props.onClear(); - this.setState({ currentStatus: 1 }); + this.setState({ currentStatus: 'todayTime' }); } onOk = () => { @@ -213,7 +212,7 @@ class Calendar extends React.Component { onDateTableSelect = (value) => { const { timePicker } = this.props; const { selectedValue } = this.state; - this.setState({ currentStatus: 0 }); + this.setState({ currentStatus: 'selectDateTime' }); if (!selectedValue && timePicker) { const timePickerDefaultValue = timePicker.props.defaultValue; if (timePickerDefaultValue) { @@ -293,7 +292,7 @@ class Calendar extends React.Component { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, onClickRightPanelTime, disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, - firstDayOfWeek, showWeekNumber, shouldDisplayCurrent, + firstDayOfWeek, showWeekNumber, } = props; const { value, selectedValue, mode, currentStatus } = state; const showTimePicker = mode === 'time'; @@ -332,7 +331,6 @@ class Calendar extends React.Component { locale={locale} placeholder={calendarInputPlaceholder} showClear - shouldDisplayCurrent={shouldDisplayCurrent} disabledTime={disabledTime} disabledDate={disabledDate} onClear={this.onClear} diff --git a/src/Picker.jsx b/src/Picker.jsx index 6b63d33e3..bce6db698 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -151,7 +151,6 @@ class Picker extends React.Component { ref: this.saveCalendarRef, defaultValue: defaultValue || calendarProps.defaultValue, selectedValue: value, - shouldDisplayCurrent: calendarProps.shouldDisplayCurrent, onKeyDown: this.onCalendarKeyDown, onOk: createChainedFunction(calendarProps.onOk, this.onCalendarOk), onSelect: createChainedFunction(calendarProps.onSelect, this.onCalendarSelect), diff --git a/src/date/DateInput.js b/src/date/DateInput.js index dd7f0382c..5307ff5c5 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -29,7 +29,6 @@ class DateInput extends React.Component { selectedValue: PropTypes.object, clearIcon: PropTypes.node, inputMode: PropTypes.string, - shouldDisplayCurrent: PropTypes.bool, }; constructor(props) { @@ -39,6 +38,7 @@ class DateInput extends React.Component { this.state = { str: formatDate(selectedValue, this.props.format), hasFocus: false, + emptyValue: false, localFormat: this.props.format[0], }; } @@ -58,17 +58,14 @@ class DateInput extends React.Component { onInputChange = (event) => { const str = event.target.value; const calendarStr = initializeStr(str, this.state.localFormat) || ''; - const { disabledDate, format, onChange, selectedValue, shouldDisplayCurrent } = this.props; + const { disabledDate, format, onChange, selectedValue } = this.props; // 没有内容,合法并直接退出 if (!str || !calendarStr) { - if (shouldDisplayCurrent) { - this.setState({ str: '' }); - onChange(dayjs()); - } else { - this.onClear(); - } + this.setState({ emptyValue: true }); + this.onClear(); return; } + if (this.state.emptyValue) this.setState({ emptyValue: false }); const parsed = dayjs(calendarStr, format[0]); let value = this.props.value.clone(); value = value @@ -109,7 +106,11 @@ class DateInput extends React.Component { if (keyCode === KeyCode.ENTER && onSelect) { const validateDate = !disabledDate || !disabledDate(value); if (validateDate) { - onSelect(value.clone()); + if (this.state.emptyValue) { + onSelect(null); + } else { + onSelect(value.clone()); + } } event.preventDefault(); } diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index 0b0d3ea7e..caf6021d2 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -42,7 +42,7 @@ export default class DateTBody extends React.Component { hoverValue: PropTypes.any, showWeekNumber: PropTypes.bool, firstDayOfWeek: PropTypes.string, - currentStatus: PropTypes.number, + currentStatus: PropTypes.string, } static defaultProps = { @@ -122,7 +122,7 @@ export default class DateTBody extends React.Component { for (jIndex = 0; jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; jIndex++) { let next = null; let last = null; - if (currentStatus === 1) { + if (currentStatus === 'todayTime') { current = dateTable[passed].hour(dayjs().hour()).minute(dayjs().minute()).second(dayjs().second()); // eslint-disable-line max-len } else { current = dateTable[passed]; From 892ac4c92440d1ea402071928abcefd7f5ea296a Mon Sep 17 00:00:00 2001 From: GongFlying <150640661+gzcqqqqqqqq1@users.noreply.github.com> Date: Tue, 8 Jul 2025 16:09:31 +0800 Subject: [PATCH 50/68] fix value name --- src/Calendar.jsx | 8 ++++---- src/date/DateInput.js | 8 ++++---- src/date/DateTBody.jsx | 4 ++-- src/util/index.js | 5 +++++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index b695df50f..84fe279bd 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -16,7 +16,7 @@ import { } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import DateInput from './date/DateInput'; -import { getTimeConfig, getTodayTime, syncTime } from './util'; +import { getTimeConfig, getTodayTime, syncTime, CURRENTSTATUS } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; import localeData from 'dayjs/plugin/localeData'; import utc from 'dayjs/plugin/utc'; @@ -98,7 +98,7 @@ class Calendar extends React.Component { getMomentObjectIfValid(props.defaultValue) || dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, - currentStatus: 'selectDateTime', + currentStatus: CURRENTSTATUS.SELECTDATETIME, }; } @@ -187,7 +187,7 @@ class Calendar extends React.Component { onClear = () => { this.onSelect(null); this.props.onClear(); - this.setState({ currentStatus: 'todayTime' }); + this.setState({ currentStatus: CURRENTSTATUS.TODAYTIME }); } onOk = () => { @@ -212,7 +212,7 @@ class Calendar extends React.Component { onDateTableSelect = (value) => { const { timePicker } = this.props; const { selectedValue } = this.state; - this.setState({ currentStatus: 'selectDateTime' }); + this.setState({ currentStatus: CURRENTSTATUS.SELECTDATETIME }); if (!selectedValue && timePicker) { const timePickerDefaultValue = timePicker.props.defaultValue; if (timePickerDefaultValue) { diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 5307ff5c5..cbbbef365 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -38,7 +38,7 @@ class DateInput extends React.Component { this.state = { str: formatDate(selectedValue, this.props.format), hasFocus: false, - emptyValue: false, + isEmpty: false, localFormat: this.props.format[0], }; } @@ -61,11 +61,11 @@ class DateInput extends React.Component { const { disabledDate, format, onChange, selectedValue } = this.props; // 没有内容,合法并直接退出 if (!str || !calendarStr) { - this.setState({ emptyValue: true }); + this.setState({ isEmpty: true }); this.onClear(); return; } - if (this.state.emptyValue) this.setState({ emptyValue: false }); + if (this.state.isEmpty) this.setState({ isEmpty: false }); const parsed = dayjs(calendarStr, format[0]); let value = this.props.value.clone(); value = value @@ -106,7 +106,7 @@ class DateInput extends React.Component { if (keyCode === KeyCode.ENTER && onSelect) { const validateDate = !disabledDate || !disabledDate(value); if (validateDate) { - if (this.state.emptyValue) { + if (this.state.isEmpty) { onSelect(null); } else { onSelect(value.clone()); diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index caf6021d2..6efec7256 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import DateConstants from './DateConstants'; -import { getTitleString, getTodayTime } from '../util/'; +import { getTitleString, getTodayTime, CURRENTSTATUS } from '../util/'; import dayjs from 'dayjs'; const { DATE_ROW_COLUMN_COUNT, DAY_NAME_TO_INDEX } = DateConstants; @@ -122,7 +122,7 @@ export default class DateTBody extends React.Component { for (jIndex = 0; jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; jIndex++) { let next = null; let last = null; - if (currentStatus === 'todayTime') { + if (currentStatus === CURRENTSTATUS.TODAYTIME) { current = dateTable[passed].hour(dayjs().hour()).minute(dayjs().minute()).second(dayjs().second()); // eslint-disable-line max-len } else { current = dateTable[passed]; diff --git a/src/util/index.js b/src/util/index.js index 7cb7999e8..f876b6a29 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -18,6 +18,11 @@ export const DATE_FORMATS = { Germany_Russia_etcAndTime: 'DD.MM.YYYY HH:mm', }; +export const CURRENTSTATUS = { + SELECTDATETIME: 'selectDateTime', + TODAYTIME: 'todayTime', +}; + const defaultDisabledTime = { disabledHours() { return []; From e56d03bfb9f9b0db16f0473d08b62468b1e523ae Mon Sep 17 00:00:00 2001 From: LJHAAAAA <3421079018@qq.com> Date: Wed, 9 Jul 2025 10:55:17 +0800 Subject: [PATCH 51/68] opt code --- src/Calendar.jsx | 8 ++++---- src/date/DateInput.js | 13 +++++++++---- src/date/DateTBody.jsx | 9 ++------- src/util/index.js | 13 ++++++++++--- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 84fe279bd..6a96c22cd 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -16,7 +16,7 @@ import { } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import DateInput from './date/DateInput'; -import { getTimeConfig, getTodayTime, syncTime, CURRENTSTATUS } from './util'; +import { getTimeConfig, getTodayTime, syncTime, CALENDAR_STATUS } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; import localeData from 'dayjs/plugin/localeData'; import utc from 'dayjs/plugin/utc'; @@ -98,7 +98,7 @@ class Calendar extends React.Component { getMomentObjectIfValid(props.defaultValue) || dayjs(), selectedValue: props.selectedValue || props.defaultSelectedValue, - currentStatus: CURRENTSTATUS.SELECTDATETIME, + currentStatus: CALENDAR_STATUS.SPECIFIC_TIME, }; } @@ -187,7 +187,7 @@ class Calendar extends React.Component { onClear = () => { this.onSelect(null); this.props.onClear(); - this.setState({ currentStatus: CURRENTSTATUS.TODAYTIME }); + this.setState({ currentStatus: CALENDAR_STATUS.CURRENT_TIME }); } onOk = () => { @@ -212,7 +212,7 @@ class Calendar extends React.Component { onDateTableSelect = (value) => { const { timePicker } = this.props; const { selectedValue } = this.state; - this.setState({ currentStatus: CURRENTSTATUS.SELECTDATETIME }); + this.setState({ currentStatus: CALENDAR_STATUS.SPECIFIC_TIME }); if (!selectedValue && timePicker) { const timePickerDefaultValue = timePicker.props.defaultValue; if (timePickerDefaultValue) { diff --git a/src/date/DateInput.js b/src/date/DateInput.js index cbbbef365..cc88027fe 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -38,7 +38,7 @@ class DateInput extends React.Component { this.state = { str: formatDate(selectedValue, this.props.format), hasFocus: false, - isEmpty: false, + isInputEmpty: false, localFormat: this.props.format[0], }; } @@ -59,13 +59,18 @@ class DateInput extends React.Component { const str = event.target.value; const calendarStr = initializeStr(str, this.state.localFormat) || ''; const { disabledDate, format, onChange, selectedValue } = this.props; + // 没有内容,合法并直接退出 if (!str || !calendarStr) { - this.setState({ isEmpty: true }); + this.setState({ isInputEmpty: true }); this.onClear(); return; } - if (this.state.isEmpty) this.setState({ isEmpty: false }); + + if (this.state.isInputEmpty) { + this.setState({ isInputEmpty: false }); + } + const parsed = dayjs(calendarStr, format[0]); let value = this.props.value.clone(); value = value @@ -106,7 +111,7 @@ class DateInput extends React.Component { if (keyCode === KeyCode.ENTER && onSelect) { const validateDate = !disabledDate || !disabledDate(value); if (validateDate) { - if (this.state.isEmpty) { + if (this.state.isInputEmpty) { onSelect(null); } else { onSelect(value.clone()); diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index 6efec7256..c5844b96e 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -2,8 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import DateConstants from './DateConstants'; -import { getTitleString, getTodayTime, CURRENTSTATUS } from '../util/'; -import dayjs from 'dayjs'; +import { getTitleString, getTodayTime, syncCurrentTime } from '../util/'; const { DATE_ROW_COLUMN_COUNT, DAY_NAME_TO_INDEX } = DateConstants; @@ -122,11 +121,7 @@ export default class DateTBody extends React.Component { for (jIndex = 0; jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT; jIndex++) { let next = null; let last = null; - if (currentStatus === CURRENTSTATUS.TODAYTIME) { - current = dateTable[passed].hour(dayjs().hour()).minute(dayjs().minute()).second(dayjs().second()); // eslint-disable-line max-len - } else { - current = dateTable[passed]; - } + current = syncCurrentTime(dateTable[passed], currentStatus); if (jIndex < DATE_ROW_COLUMN_COUNT.DATE_COL_COUNT - 1) { next = dateTable[passed + 1]; } diff --git a/src/util/index.js b/src/util/index.js index f876b6a29..b2c9951d6 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -18,9 +18,16 @@ export const DATE_FORMATS = { Germany_Russia_etcAndTime: 'DD.MM.YYYY HH:mm', }; -export const CURRENTSTATUS = { - SELECTDATETIME: 'selectDateTime', - TODAYTIME: 'todayTime', +export const CALENDAR_STATUS = { + SPECIFIC_TIME: 'specific_time', + CURRENT_TIME: 'current_time', +}; + +export const syncCurrentTime = (date, status) => { + if (status === CALENDAR_STATUS.CURRENT_TIME) { + return date.hour(dayjs().hour()).minute(dayjs().minute()).second(dayjs().second()); + } + return date; }; const defaultDisabledTime = { From 0bae47b8c50435baa3f75b4f33fe92a7af3de094 Mon Sep 17 00:00:00 2001 From: LJHAAAAA <3421079018@qq.com> Date: Wed, 9 Jul 2025 13:51:27 +0800 Subject: [PATCH 52/68] Update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56fa68b9e..fffabf92c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.31", + "version": "0.0.32", "description": "React Calendar", "keywords": [ "react", From 429805435e177b7d639f69a07c68fd913a43c010 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Thu, 17 Jul 2025 10:13:22 +0800 Subject: [PATCH 53/68] fix error color --- assets/common/FullCalendar.less | 3 +-- assets/index/Calendar.less | 8 ++++---- assets/index/DecadePanel.less | 2 +- assets/index/Input.less | 6 +++--- assets/index/MonthPanel.less | 2 +- assets/index/YearPanel.less | 2 +- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/assets/common/FullCalendar.less b/assets/common/FullCalendar.less index 4c8d66a20..1ab31d1de 100644 --- a/assets/common/FullCalendar.less +++ b/assets/common/FullCalendar.less @@ -19,8 +19,7 @@ float: right; display: inline-block; &-normal:hover { - border-color: #f09f4g; - box-shadow: 0 0 2px rgba(45, 183, 245, 0.8); + border-color: #f09f4f; cursor: pointer; } &-focus { diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 8b6a096bc..ef5f1e733 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -52,7 +52,7 @@ &:hover { cursor: pointer; - color: #f09f4g; + color: #f09f4f; } } @@ -85,7 +85,7 @@ &:hover { cursor: pointer; - color: #f09f4g; + color: #f09f4f; } &.@{prefixClass}-time-status:hover{ cursor: pointer; @@ -108,7 +108,7 @@ line-height: 34px; &:hover { - color: #f09f4g; + color: #f09f4f; } } @@ -344,7 +344,7 @@ &:hover { cursor: pointer; - color: #f09f4g; + color: #f09f4f; } &-disabled { diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index e8dcbd734..f65b31b2c 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -34,7 +34,7 @@ &:hover { cursor: pointer; - color: #f09f4g; + color: #f09f4f; } } } diff --git a/assets/index/Input.less b/assets/index/Input.less index 9ea3caa2c..0fdf7b4d3 100644 --- a/assets/index/Input.less +++ b/assets/index/Input.less @@ -12,11 +12,11 @@ transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), background 0.3s cubic-bezier(0.35, 0, 0.25, 1), box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1); &:hover { - border-color: #f09f4g; + border-color: #f09f4f; } &:focus { - border-color: #f09f4g; - box-shadow: 0 0 3px #f09f4g; + border-color: #f09f4f; + box-shadow: 0 0 3px #f09f4f; } } \ No newline at end of file diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index 7a9fac133..3f57bd086 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -38,7 +38,7 @@ &:hover { cursor: pointer; - color: #f09f4g; + color: #f09f4f; } } } diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index 96ed4d39d..96827d28a 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -38,7 +38,7 @@ &:hover { cursor: pointer; - color: #f09f4g; + color: #f09f4f; } } } From fa2bfed5dc970fce0269e23527daed6f50a9277d Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Wed, 6 Aug 2025 10:00:56 +0800 Subject: [PATCH 54/68] change date input auto focus update version update version --- package.json | 7 ++----- src/date/DateInput.js | 12 ++++++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index fffabf92c..7871de826 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.0.32", + "version": "0.1.1", "description": "React Calendar", "keywords": [ "react", @@ -48,6 +48,7 @@ "lint": "rc-tools run lint", "test": "jest", "types": "tslint *.ts{,x} && tsc", + "prepublishOnly": "npm run compile", "coverage": "jest --coverage" }, "jest": { @@ -75,7 +76,6 @@ "enzyme-to-json": "^3.3.1", "jest": "^22.1.4", "mockdate": "^2.0.1", - "pre-commit": "1.x", "rc-dialog": "^7.0.0", "rc-select": "^9.1.5", "rc-time-picker": "^3.1.0", @@ -86,9 +86,6 @@ "tslint": "^5.9.1", "typescript": "^3.4.1" }, - "pre-commit": [ - "lint" - ], "dependencies": { "babel-runtime": "6.x", "classnames": "2.x", diff --git a/src/date/DateInput.js b/src/date/DateInput.js index cc88027fe..c2cba341f 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -5,6 +5,7 @@ import KeyCode from 'rc-util/lib/KeyCode'; import { polyfill } from 'react-lifecycles-compat'; import dayjs from 'dayjs'; import { formatDate, initializeStr } from '../util'; + const customParseFormat = require('dayjs/plugin/customParseFormat'); dayjs.extend(customParseFormat); @@ -42,6 +43,12 @@ class DateInput extends React.Component { localFormat: this.props.format[0], }; } + + componentDidMount() { + setTimeout(() => { + this.focus(); + }, 100); + } componentDidUpdate() { if (dateInputInstance && this.state.hasFocus && @@ -173,9 +180,10 @@ class DateInput extends React.Component { onFocus={this.onFocus} onBlur={this.onBlur} inputMode={inputMode} + tabIndex="0" />
- {props.showClear ? ( + {props.showClear && {clearIcon || } - ) : null} + }
); } From 78a34cdc3e137e06328a8b98e90f657f4dccd700 Mon Sep 17 00:00:00 2001 From: Aries Date: Wed, 15 Oct 2025 09:57:36 +0800 Subject: [PATCH 55/68] update calendar to support time input and selection --- assets/common/Calendar.less | 16 +- assets/index/Calendar.less | 506 ++++++++++++++-------------- assets/index/Input.less | 20 +- assets/index/MonthPanel.less | 17 +- assets/index/Time.less | 6 +- assets/index/YearPanel.less | 11 +- package.json | 2 +- src/Calendar.jsx | 103 ++++-- src/calendar/CalendarRightPanel.jsx | 195 ++++++++--- src/date/DateInput.js | 3 +- src/time/TimeInput.js | 169 ++++++++++ 11 files changed, 679 insertions(+), 369 deletions(-) create mode 100644 src/time/TimeInput.js diff --git a/assets/common/Calendar.less b/assets/common/Calendar.less index d4eff32d8..face190ae 100644 --- a/assets/common/Calendar.less +++ b/assets/common/Calendar.less @@ -1,17 +1,13 @@ .@{prefixClass} { &-input-wrap { + width: 100%; position: relative; - padding: 6px; - border-bottom: 1px solid #e9e9e9; &:after { content: ''; clear: both; } } - &-date-input-wrap { - overflow: hidden; - } &-time-picker { position: absolute; width: 100%; @@ -50,8 +46,8 @@ &-input { padding: 0; border: 1px solid transparent; - outline: 0;; - height:22px; + outline: 0; + height: 22px; } &-icon { @@ -67,7 +63,7 @@ cursor: text; line-height: 1.5; outline: 0; - height:22px; + height: 22px; &-invalid { border-color: red; @@ -89,7 +85,7 @@ } &-clear-btn:after { - content: "x"; + content: 'x'; font-size: 12px; color: #aaa; display: inline-block; @@ -101,4 +97,4 @@ &-clear-btn:hover:after { color: #666; } -} \ No newline at end of file +} diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index ef5f1e733..33edb95ee 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -3,9 +3,8 @@ outline: none; font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans-serif; width: fit-content; - border: 1px solid #ccc; list-style: none; - font-size: 12px; + font-size: 14px; text-align: left; background-color: #fff; border-radius: 3px; @@ -14,83 +13,135 @@ border: 1px solid #ccc; line-height: 1.5; - - &-date-panel, &-date-panel-container { + /* Layout wrappers */ + &-panel { display: flex; + flex-direction: column; } - - &-date-panel, &-panel { - position: relative; - outline: none; + &-date-panel-container { + display: flex; + } + &-date-panel { display: block; + min-width: 288px; } - &-week-number { - width: 286px; - - &-cell { - text-align: center; - } + /* Top inputs row */ + &-inputs { + display: flex; + align-items: stretch; + border-bottom: 1px solid #eee; + } + &-date-input-col { + flex: 1 1 auto; + } + &-time-input-col { + width: 122px; + border-left: 1px solid #eee; + } + &-date-input, + &-time-input-outer { + display: flex; + align-items: center; + height: 100%; + } + &-date-input { + padding: 10px; + } + &-time-input-outer { + padding: 10px; + width: 100%; + } + &-date-input input { + height: 30px; + width: 100%; + padding: 4px 10px; + border: 1px solid #eee; + border-radius: 3px; + line-height: 1.5; + } + &-date-input input:focus { + border-color: #ed7109; + box-shadow: 0 0 3px #ed7109; + outline: none; + } + /* Shared header text input */ + &-text-input { + height: 30px; + display: inline-block; + width: 100%; + margin: 0; + padding: 4px 10px; + border-radius: 6px; + border: 1px solid #eee; + background: #fff; + color: #666; + line-height: 1.5; + transition: border 0.3s, background 0.3s, box-shadow 0.3s; + } + &-text-input:focus { + border-color: #ed7109; + box-shadow: 0 0 3px #ed7109; + outline: none; } &-header { padding: 0 10px; - height: 34px; - line-height: 30px; + height: 40px; + line-height: 40px; text-align: center; user-select: none; -webkit-user-select: none; - border-bottom: 1px solid #ccc; - - > a { - font-weight: bold; - display: inline-block; - padding: 0px 5px; - line-height: 34px; - text-align: center; - width: 30px; - - &:hover { - cursor: pointer; - color: #f09f4f; - } - } - - .@{prefixClass}-prev-month-btn { - position: absolute; - left: 25px; - - &:after { - content: '‹' - } - } - - .@{prefixClass}-next-month-btn { - position: absolute; - right: 25px; - - &:after { - content: '›' - } - } + border-bottom: 1px solid #eee; + } + &-header > a { + font-weight: 600; + display: inline-block; + padding: 0 5px; + line-height: 40px; + text-align: center; + width: 30px; + } + &-header > a:hover { + cursor: pointer; + color: #ed7109; + } + &-prev-month-btn { + position: absolute; + left: 25px; + } + &-prev-month-btn:after { + content: '‹'; + } + &-next-month-btn { + position: absolute; + right: 25px; + } + &-next-month-btn:after { + content: '›'; } - &-year-select, &-month-select, &-day-select { + &-year-select, + &-month-select, + &-day-select { display: inline-block; - font-size: 12px; - font-weight: bold; - color: #666; + font-size: 14px; + font-weight: 600; + color: #212529; padding: 0 8px; - line-height: 34px; - - &:hover { - cursor: pointer; - color: #f09f4f; - } - &.@{prefixClass}-time-status:hover{ - cursor: pointer; - color: #666; - } + line-height: 40px; + } + &-year-select:hover, + &-month-select:hover, + &-day-select:hover { + cursor: pointer; + color: #f09f4f; + } + &-year-select.@{prefixClass}-time-status:hover, + &-month-select.@{prefixClass}-time-status:hover, + &-day-select.@{prefixClass}-time-status:hover { + cursor: pointer; + color: #666; } &-prev-month-btn, @@ -101,261 +152,224 @@ top: 0; cursor: pointer; color: #999; - font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", sans-serif; + font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', + 'Microsoft Sans Serif', sans-serif; padding: 0 5px; font-size: 16px; display: inline-block; - line-height: 34px; - - &:hover { - color: #f09f4f; - } + line-height: 40px; + } + &-prev-month-btn:hover, + &-next-month-btn:hover, + &-prev-year-btn:hover, + &-next-year-btn:hover { + color: #555; } - &-next-year-btn { right: 0; - - &:after { - content: '»' - } } - + &-next-year-btn:after { + content: '»'; + } &-prev-year-btn { left: 0; - - &:after { - content: '«' - } } - - &-body { - padding: 9px 10px 10px; - height: 217px; - } - - &-right-panel { - width: 68px; - height: inherit; - } - - &-right-panel-header { - height: 34px; - line-height: 34px; - span { - transform: rotate(-90deg); - } - } - - &-right-panel-body { - height: 217px; - border-left: 1px solid #ccc; - overflow-y: scroll; - ul { - list-style: none; - box-sizing: border-box; - margin: 0; - padding: 0; - width: 100%; - } - ul li { - text-align: center; - padding: 8px 0; - cursor: pointer; - } - ul li:hover { - color: #e8bf6a; - } - .@{prefixClass}-selected-time { - color: #f09f3f; - } - &::-webkit-scrollbar { - width: 0; - } - } - - &-right-panel-footer { - height: 39px; - line-height: 34px; - border-left: 1px solid #ccc; - span { - transform: rotate(90deg); - } + &-prev-year-btn:after { + content: '«'; } - &-right-panel-header, &-right-panel-footer { - display: flex; - justify-content: center; - cursor: pointer; - color: #999; - font-size: 16px; - span:after { - content: '›'; - } + /* Date grid area */ + &-body { + padding: 8px 18px; + height: 268px; } - table { border-collapse: collapse; max-width: 100%; background-color: transparent; width: 100%; } - - table, td, th, td { + table, + td, + th, + td { border: none; } - &-table { border-spacing: 0; margin-bottom: 0; } - &-column-header { line-height: 18px; - padding: 6px 0; - width: 33px; + height: 36px; + width: 36px; text-align: center; - .@{prefixClass}-column-header-inner { - display: block; - font-weight: normal; - } } - - &-week-number-header { - .@{prefixClass}-column-header-inner { - display: none; - } + &-column-header-inner { + display: block; + font-weight: normal; + color: #999; + } + &-week-number-header .@{prefixClass}-column-header-inner { + display: none; } - &-cell { - padding: 1px 0; + height: 36px; + padding: 0; } - &-date { display: block; margin: 0 auto; - color: #666; - border-radius: 4px 4px; - width: 26px; - height: 26px; + color: #212529; + border-radius: 4px; + width: 24px; + height: 24px; padding: 0; background: transparent; - line-height: 26px; + line-height: 24px; text-align: center; - - &:hover { - background: #fcecd9; - cursor: pointer; - } } - - &-selected-day &-date { - background: tint(#f09f3f, 80%); + &-date:hover { + background: #fcecd9; + cursor: pointer; } - &-selected-date &-date { - background: #f09f3f; + background: #ed7109; color: #fff; - &:hover { - background: #f09f3f; - } } - - &-today &-date { - border: 1px solid #f09f3f; + &-selected-date &-date:hover { + background: #ed7109; } - &-disabled-cell &-date { cursor: not-allowed; color: #bcbcbc; background: #f3f3f3; border-radius: 0; width: auto; - - &:hover { - background: #f3f3f3; - } } - + &-disabled-cell &-date:hover { + background: #f3f3f3; + } &-disabled-cell-first-of-row &-date { border-top-left-radius: 4px; border-bottom-left-radius: 4px; } - &-disabled-cell-last-of-row &-date { border-top-right-radius: 4px; border-bottom-right-radius: 4px; } - - &-last-month-cell &-date, &-next-month-btn-day &-date { + &-last-month-cell &-date, + &-next-month-btn-day &-date { color: #bbb; } + &-today &-date { + position: relative; + } + &-today &-date::before { + content: ''; + background: #ed7109; + position: absolute; + width: 4px; + height: 4px; + border-radius: 50%; + left: 45%; + bottom: 0%; + display: inline-block; + } + + /* Right time panel */ + &-right-panel { + height: inherit; + border-left: 1px solid #eee; + } + &-right-panel-time-header { + height: 40px; + line-height: 40px; + text-align: center; + font-weight: 600; + color: #212529; + border-bottom: 1px solid #eee; + } + &-right-panel-body { + height: 268px; + display: flex; + padding: 4px; + scrollbar-color: auto; + } + &-right-panel-col { + overflow-y: auto; + } + &-right-panel-col:last-child { + border-left: 1px solid #eee; + } + &-right-panel-col ul { + list-style: none; + margin: 0; + padding: 4px; + } + &-right-panel-item { + width: 48px; + height: 28px; + line-height: 28px; + text-align: center; + cursor: pointer; + color: #212529; + font-weight: 400; + border-radius: 3px; + } + &-right-panel-item:hover { + background: fade(#ed7109, 10%); + } + &-right-panel-item-selected { + background: fade(#ed7109, 10%); + border-radius: 3px; + color: #212529; + } + &-right-panel-col::-webkit-scrollbar { + width: 0; + height: 0; + } + /* Footer */ &-footer { - border-top: 1px solid #ccc; - padding: 10px 0; + border-top: 1px solid #eee; + padding: 8px 0; text-align: center; position: relative; - - .@{timePickerClass} { - width: 90px; - &-input { - height: 24px; - } - } - &-show-ok { - text-align: right; - .@{prefixClass} { - &-footer-btn { - padding-right: 12px; - } - - &-time-picker-btn { - margin-left: 0; - padding: 0 12px; - } - &-today-btn { - float: left; - padding-left: 12px; - } - } - } } - - &-footer-btn { - margin-top: 2px; - - &:after { - content: 'x'; - height: 0; - font-size: 0; - overflow: hidden; - clear: both; - } + &-footer-show-ok { + text-align: right; + } + &-footer-btn:after { + content: 'x'; + height: 0; + font-size: 0; + overflow: hidden; + clear: both; } - &-time-picker-btn { margin-left: 10px; } - - &-today-btn, &-ok-btn, &-time-picker-btn { + &-today-btn, + &-ok-btn, + &-time-picker-btn { display: inline-block; text-align: center; - color: #f46830; - - &:hover { - cursor: pointer; - color: #f09f4f; - } - - &-disabled { - color: #bbb; - &:hover { - color: #bbb; - } - } + color: #ed7109; + } + &-today-btn:hover, + &-ok-btn:hover, + &-time-picker-btn:hover { + cursor: pointer; + color: #f09f4f; + } + &-today-btn-disabled, + &-ok-btn-disabled, + &-time-picker-btn-disabled { + color: #bbb; } - &-today-btn { - padding-left: 10px; + padding-left: 0; + font-weight: 600; } -} \ No newline at end of file +} diff --git a/assets/index/Input.less b/assets/index/Input.less index 0fdf7b4d3..08f6d5690 100644 --- a/assets/index/Input.less +++ b/assets/index/Input.less @@ -1,22 +1,20 @@ .input() { - height: 25px; + height: 30px; position: relative; display: inline-block; margin: 0 0; padding: 4px 10px; - border-radius: 6px 6px; - border: 1px solid #d9d9d9; + border-radius: 3px; + border: 1px solid #eee; background-color: #ffffff; color: #666; line-height: 1.5; - transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), background 0.3s cubic-bezier(0.35, 0, 0.25, 1), box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1); - - &:hover { - border-color: #f09f4f; - } + transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), + background 0.3s cubic-bezier(0.35, 0, 0.25, 1), + box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1); &:focus { - border-color: #f09f4f; - box-shadow: 0 0 3px #f09f4f; + border-color: #ed7109; + box-shadow: 0 0 3px #ed7109; } -} \ No newline at end of file +} diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index 3f57bd086..9fc075195 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -1,6 +1,6 @@ .@{prefixClass}-month-panel { left: 0; - top:0; + top: 0; bottom: 0; right: 0; background: #ffffff; @@ -43,14 +43,15 @@ } } -.@{prefixClass}-month-panel-prev-year-btn, .@{prefixClass}-month-panel-next-year-btn { +.@{prefixClass}-month-panel-prev-year-btn, +.@{prefixClass}-month-panel-next-year-btn { position: absolute; top: 0; } .@{prefixClass}-month-panel-next-year-btn { &:after { - content: '»' + content: '»'; } } @@ -59,7 +60,7 @@ left: 0; &:after { - content: '«' + content: '«'; } } @@ -96,8 +97,6 @@ .@{prefixClass}-month-panel-cell { text-align: center; - - .@{prefixClass}-month-panel-month { display: block; width: 46px; @@ -116,7 +115,7 @@ } } - &-disabled{ + &-disabled { .@{prefixClass}-month-panel-month { color: #bfbfbf; @@ -129,7 +128,7 @@ } .@{prefixClass}-month-panel-selected-cell .@{prefixClass}-month-panel-month { - background: #f09f3f; + background: #ed7109; color: #fff; &:hover { @@ -141,4 +140,4 @@ .@{prefixClass}-month-header-wrap { position: relative; height: 308px; -} \ No newline at end of file +} diff --git a/assets/index/Time.less b/assets/index/Time.less index b7ddc9625..0b17bf37b 100644 --- a/assets/index/Time.less +++ b/assets/index/Time.less @@ -1,6 +1,6 @@ -@import "./Input.less"; +@import './Input.less'; .@{prefixClass}-time-input { .input(); - width:40px; -} \ No newline at end of file + width: 100%; +} diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index 96827d28a..8297eba3a 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -43,14 +43,15 @@ } } -.@{prefixClass}-year-panel-prev-decade-btn, .@{prefixClass}-year-panel-next-decade-btn { +.@{prefixClass}-year-panel-prev-decade-btn, +.@{prefixClass}-year-panel-next-decade-btn { position: absolute; top: 0; } .@{prefixClass}-year-panel-next-decade-btn { &:after { - content: '»' + content: '»'; } } @@ -59,7 +60,7 @@ left: 0; &:after { - content: '«' + content: '«'; } } @@ -116,11 +117,11 @@ } .@{prefixClass}-year-panel-selected-cell .@{prefixClass}-year-panel-year { - background: #f09f3f; + background: #ed7109; color: #fff; &:hover { - background: #f09f3f; + background: #ed7109; color: #fff; } } diff --git a/package.json b/package.json index 7871de826..dddb01ceb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "0.1.1", + "version": "1.0.0-alpha.2", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 6a96c22cd..d0feea6af 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -16,6 +16,7 @@ import { } from './mixin/CalendarMixin'; import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import DateInput from './date/DateInput'; +import TimeInput from './time/TimeInput'; import { getTimeConfig, getTodayTime, syncTime, CALENDAR_STATUS } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; import localeData from 'dayjs/plugin/localeData'; @@ -233,10 +234,12 @@ class Calendar extends React.Component { onBlur = (event) => { setTimeout(() => { const dateInput = DateInput.getInstance(); + const timeInput = TimeInput.getInstance && TimeInput.getInstance(); const rootInstance = this.rootInstance; if (!rootInstance || rootInstance.contains(document.activeElement) || - (dateInput && dateInput.contains(document.activeElement))) { + (dateInput && dateInput.contains(document.activeElement)) || + (timeInput && timeInput.contains && timeInput.contains(document.activeElement))) { // focused element is still part of Calendar return; } @@ -267,6 +270,14 @@ class Calendar extends React.Component { return newState; } + onTimeInputChange = (value) => { + this.onSelect(value, { source: 'timeInputChange' }); + } + + onTimeInputSelect = (value) => { + this.onSelect(value, { source: 'timeInputSelect' }); + } + getRootDOMNode = () => { return ReactDOM.findDOMNode(this); } @@ -290,7 +301,7 @@ class Calendar extends React.Component { const { props, state } = this; const { locale, prefixCls, disabledDate, - dateInputPlaceholder, timePicker, onClickRightPanelTime, + timePicker, onClickRightPanelTime, disabledTime, clearIcon, renderFooter, inputMode, showHourAndMinute, firstDayOfWeek, showWeekNumber, } = props; @@ -319,18 +330,22 @@ class Calendar extends React.Component { timePickerEle = React.cloneElement(timePicker, timePickerProps); } - const calendarInputPlaceholder = dateInputPlaceholder || - (Array.isArray(this.getFormat()) ? this.getFormat()[0] : this.getFormat()); + + const baseFormat = Array.isArray(this.getFormat()) ? this.getFormat()[0] : this.getFormat(); + const headerDatePlaceholder = baseFormat.replace(/\s*HH:mm(?::ss)?\s*/,'').trim() || 'YYYY-MM-DD'; const inputFormat = Array.isArray(this.getFormat()) ? this.getFormat() : [this.getFormat()]; + // For the date input, strip any time tokens from formats so date and time are shown separately + const stripTime = f => (typeof f === 'string' ? f.replace(/\s*HH:mm(?::ss)?\s*/, '').trim() : f); + const dateOnlyFormats = Array.isArray(this.getFormat()) ? this.getFormat().map(stripTime) : [stripTime(this.getFormat())]; const dateInputElement = props.showDateInput ? ( ) : null; + const timeInputTopElement = ( + + ); + const children = []; if (props.renderSidebar) { children.push(props.renderSidebar()); } children.push(
- {dateInputElement} +
+
+
+ {dateInputElement} +
+
+ {showHourAndMinute && ( +
+ {timeInputTopElement} +
+ )} +
-
{showHourAndMinute && this.onDateTableSelect(v)} onClickRightPanelTime={onClickRightPanelTime} defaultMinutesTime={this.props.defaultMinutesTime} format={inputFormat} /> }
+
); return this.renderRoot({ diff --git a/src/calendar/CalendarRightPanel.jsx b/src/calendar/CalendarRightPanel.jsx index a8eaaaa70..1d82a3c63 100644 --- a/src/calendar/CalendarRightPanel.jsx +++ b/src/calendar/CalendarRightPanel.jsx @@ -1,13 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import dayjs from 'dayjs'; -import { tokenizeFormattedDate } from '../util'; export default class CalendarRightPanel extends React.Component { static propTypes = { prefixCls: PropTypes.string, value: PropTypes.object, + selectedValue: PropTypes.object, onSelect: PropTypes.func, onClickRightPanelTime: PropTypes.func, locale: PropTypes.object, @@ -19,76 +19,171 @@ export default class CalendarRightPanel extends React.Component { super(props); const format = Array.isArray(this.props.format) ? this.props.format[0] : this.props.format; this.state = { - highlightTime: this.props.value || null, + highlightTime: this.props.selectedValue || this.props.value || null, localeFormat: format, }; - this.timeRef = React.createRef(); - this.times = this.getTimes(); + + this.hoursRef = React.createRef(); + this.minutesRef = React.createRef(); + this.hours = this.getHours(); + this.minutes = this.getMinutes(); + + this.skipScrollUpdates = 0; + } + + static getDerivedStateFromProps(nextProps, prevState) { + if (nextProps.selectedValue) { + if (!prevState.highlightTime || !prevState.highlightTime.isSame(nextProps.selectedValue)) { + return { highlightTime: nextProps.selectedValue }; + } + } + return null; } componentDidMount() { - const { defaultMinutesTime } = this.props; - const showTimeIndex = this.times.findIndex(item => item >= defaultMinutesTime); - const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex - 1 : 16; - this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); + const { defaultMinutesTime, value, selectedValue } = this.props; + const baseTime = defaultMinutesTime || ((selectedValue || value) ? (selectedValue || value).format('HH:mm') : '00:00'); + const base = baseTime.split(':'); + const hIdx = this.hours.findIndex(h => h === base[0]); + const mIdx = this.minutes.findIndex(m => m === base[1]); + const hourIndex = hIdx > -1 ? hIdx : 0; + const minuteIndex = mIdx > -1 ? mIdx : 0; + + if (typeof window !== 'undefined' && window.requestAnimationFrame) { + window.requestAnimationFrame(() => { + this.centerScroll(this.hoursRef.current, hourIndex); + this.centerScroll(this.minutesRef.current, minuteIndex); + }); + } else { + this.centerScroll(this.hoursRef.current, hourIndex); + this.centerScroll(this.minutesRef.current, minuteIndex); + } + } + + componentDidUpdate(prevProps, prevState) { + const prevV = prevState.highlightTime || prevProps.selectedValue || prevProps.value; + const currV = this.state.highlightTime || this.props.selectedValue || this.props.value; + + const prevH = prevV ? prevV.format('HH') : '00'; + const prevM = prevV ? prevV.format('mm') : '00'; + const currH = currV ? currV.format('HH') : '00'; + const currM = currV ? currV.format('mm') : '00'; + + if (this.skipScrollUpdates > 0) { + this.skipScrollUpdates -= 1; + return; + } + + const hChanged = prevH !== currH; + const mChanged = prevM !== currM; + if (hChanged || mChanged) { + const scrollHours = () => { + if (hChanged) { + const hIdx = this.hours.findIndex(h => h === currH); + const hourIndex = hIdx > -1 ? hIdx : 0; + this.centerScroll(this.hoursRef.current, hourIndex); + } + if (mChanged) { + const mIdx = this.minutes.findIndex(m => m === currM); + const minuteIndex = mIdx > -1 ? mIdx : 0; + this.centerScroll(this.minutesRef.current, minuteIndex); + } + }; + if (typeof window !== 'undefined' && window.requestAnimationFrame) { + window.requestAnimationFrame(scrollHours); + } else { + scrollHours(); + } + } } - onSelect = (value) => { - this.setState({ - highlightTime: value, - }); - this.props.onSelect(value); - this.props.onClickRightPanelTime(); + centerScroll = (container, index) => { + if (!container || index < 0) return; + const firstItem = container.querySelector('li'); + const itemHeight = (firstItem && firstItem.offsetHeight) || 32; + const containerHeight = container.clientHeight || 0; + const maxScroll = Math.max(0, container.scrollHeight - containerHeight); + let target = index * itemHeight - (containerHeight / 2 - itemHeight / 2); + if (target < 0) target = 0; + if (target > maxScroll) target = maxScroll; + container.scrollTop = target; } - getTimes = () => { - const times = []; - for (let i = 0; i < 24; i++) { - const str = (`${String(i)}:00`).padStart(5, '0'); - const str1 = (`${String(i)}:30`).padStart(5, '0'); - times.push(str); - times.push(str1); + onSelectMinute = (minute) => { + const base = this.props.selectedValue || this.props.value || this.state.highlightTime || dayjs(); + const h = parseInt(this.getSelectedHour(), 10) || 0; + const m = parseInt(minute, 10) || 0; + const current = base.clone().hour(h).minute(m); + this.skipScrollUpdates = 2; + this.setState({ highlightTime: current }); + this.props.onSelect(current); + if (this.props.onClickRightPanelTime) { + this.props.onClickRightPanelTime(); } - return times; } - scrollUp = () => { - this.timeRef.current.scrollBy(0, -200); + onSelectHour = (hour) => { + const base = this.props.selectedValue || this.props.value || this.state.highlightTime || dayjs(); + const h = parseInt(hour, 10) || 0; + const m = parseInt(this.getSelectedMinute(), 10) || 0; + const current = base.clone().hour(h).minute(m); + this.skipScrollUpdates = 2; + this.setState({ highlightTime: current }); + this.props.onSelect(current); + } + + getHours = () => Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0')) + + getMinutes = () => Array.from({ length: 60 }, (_, i) => String(i).padStart(2, '0')) + + getSelectedHour = () => { + const { highlightTime } = this.state; + const { value, selectedValue } = this.props; + const v = highlightTime || selectedValue || value; + return v ? v.format('HH') : '00'; } - scrollDown = () => { - this.timeRef.current.scrollBy(0, 200); + getSelectedMinute = () => { + const { highlightTime } = this.state; + const { value, selectedValue } = this.props; + const v = highlightTime || selectedValue || value; + return v ? v.format('mm') : '00'; } render() { - const { value, prefixCls, locale } = this.props; - const selectedDate = value.format().slice(0, String(value.format()).indexOf('T')); - const highlight = this.state.highlightTime; - const highlightTime = highlight ? highlight.format().slice(11, 16) : null; - const isZhcn = (locale && locale.today === '今天'); + const { prefixCls } = this.props; + const selectedHour = this.getSelectedHour(); + const selectedMinute = this.getSelectedMinute(); return (
-
- +
+ {selectedHour}:{selectedMinute}
-
-
    - {this.times.map((time) => { - const parts = tokenizeFormattedDate(selectedDate, this.state.localeFormat); - let current = dayjs(`${selectedDate} ${time}`).year(parts[0]).month(parts[1] - 1).date(parts[2]); // eslint-disable-line max-len - current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb'); - return ( +
    +
    +
      + {this.hours.map((h) => (
    • {time}
    • - ); - })} -
    -
    -
    - + key={h} + onClick={() => this.onSelectHour(h)} + className={`${prefixCls}-right-panel-item ${h === selectedHour ? `${prefixCls}-right-panel-item-selected` : ''}`} + >{h} + + ))} +
+
+
+
    + {this.minutes.map((m) => ( +
  • this.onSelectMinute(m)} + className={`${prefixCls}-right-panel-item ${m === selectedMinute ? `${prefixCls}-right-panel-item-selected` : ''}`} + >{m} +
  • + ))} +
+
); diff --git a/src/date/DateInput.js b/src/date/DateInput.js index c2cba341f..e5ec49189 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -43,7 +43,7 @@ class DateInput extends React.Component { localFormat: this.props.format[0], }; } - + componentDidMount() { setTimeout(() => { this.focus(); @@ -67,7 +67,6 @@ class DateInput extends React.Component { const calendarStr = initializeStr(str, this.state.localFormat) || ''; const { disabledDate, format, onChange, selectedValue } = this.props; - // 没有内容,合法并直接退出 if (!str || !calendarStr) { this.setState({ isInputEmpty: true }); this.onClear(); diff --git a/src/time/TimeInput.js b/src/time/TimeInput.js new file mode 100644 index 000000000..a8cb34bf2 --- /dev/null +++ b/src/time/TimeInput.js @@ -0,0 +1,169 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { polyfill } from 'react-lifecycles-compat'; +import dayjs from 'dayjs'; + +const customParseFormat = require('dayjs/plugin/customParseFormat'); +dayjs.extend(customParseFormat); + +function formatTime(value, format) { + if (!value) return ''; + const fmt = Array.isArray(format) ? format[0] : (format || 'HH:mm'); + return value.format(fmt); +} + +// Convert a loose numeric/time string into HH:mm +// Rules (similar spirit to DateInput.initializeStr): +// - Strip non-digits +// - If len <= 2 => treat as hour +// - If len > 2 => last two digits are minutes; preceding are hours +// - Clamp hours to [0,23], minutes to [0,59] +// - Return formatted HH:mm or '' when input is empty +function initializeTime(str) { + if (typeof str !== 'string') return ''; + const digits = str.replace(/\D/g, ''); + if (!digits.length) return ''; + + let hDigits = ''; + let mDigits = ''; + if (digits.length <= 2) { + hDigits = digits; + } else { + hDigits = digits.slice(0, digits.length - 2); + mDigits = digits.slice(-2); + } + + let hour = parseInt(hDigits || '0', 10); + let minute = parseInt(mDigits || '0', 10); + if (Number.isNaN(hour)) hour = 0; + if (Number.isNaN(minute)) minute = 0; + + if (hour > 23) hour = 23; + if (minute > 59) minute = 59; + + const HH = String(hour).padStart(2, '0'); + const mm = String(minute).padStart(2, '0'); + return `${HH}:${mm}`; +} + +let timeInputInstance; +let cachedSelectionStart; +let cachedSelectionEnd; + +class TimeInput extends React.Component { + static propTypes = { + prefixCls: PropTypes.string, + value: PropTypes.object, + selectedValue: PropTypes.object, + onChange: PropTypes.func, + onSelect: PropTypes.func, + placeholder: PropTypes.string, + inputMode: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), + disabled: PropTypes.bool, + className: PropTypes.string, + }; + + static defaultProps = { + format: 'HH:mm', + placeholder: 'HH:mm', + }; + + constructor(props) { + super(props); + this.state = { + str: '', + hasFocus: false, + }; + } + + static getDerivedStateFromProps(nextProps, state) { + let newState = null; + if (timeInputInstance) { + cachedSelectionStart = timeInputInstance.selectionStart; + cachedSelectionEnd = timeInputInstance.selectionEnd; + } + + if (!state.hasFocus) { + const base = nextProps.selectedValue || null; + newState = { str: base ? formatTime(base, nextProps.format) : '' }; + } + return newState; + } + + onInputChange = (event) => { + const str = event.target.value; + const timeStr = initializeTime(str); + + if (!str || !timeStr) { + this.setState({ str }); + return; + } + + const base = this.props.selectedValue || this.props.value || dayjs(); + const parsed = dayjs(timeStr, 'HH:mm'); + const next = base.clone().hour(parsed.hour()).minute(parsed.minute()); + + this.setState({ str }); + if (this.props.onChange) { + this.props.onChange(next); + } + } + + onKeyDown = (event) => { + if (event.key === 'Enter' && this.props.onSelect) { + const timeStr = initializeTime(this.state.str); + if (!timeStr) return; + const base = this.props.selectedValue || this.props.value || dayjs(); + const parsed = dayjs(timeStr, 'HH:mm'); + const next = base.clone().hour(parsed.hour()).minute(parsed.minute()); + this.props.onSelect(next); + event.preventDefault(); + } + } + + onFocus = () => { + this.setState({ hasFocus: true }); + } + + onBlur = () => { + const base = this.props.selectedValue ? this.props.selectedValue : (this.props.value || null); + this.setState({ + hasFocus: false, + str: base ? formatTime(base, this.props.format) : '', + }); + } + + saveRef = (node) => { + timeInputInstance = node; + } + + static getInstance() { + return timeInputInstance; + } + + render() { + const { prefixCls, placeholder, inputMode, disabled, className } = this.props; + const inputCls = className || `${prefixCls}-time-input ${prefixCls}-text-input`; + return ( +
+ +
+ ); + } +} + +polyfill(TimeInput); + +export default TimeInput; From 13ed6825225a5d0fb1ed60825a87d7991ee87848 Mon Sep 17 00:00:00 2001 From: Michael An <1822852997@qq.com> Date: Mon, 27 Oct 2025 15:28:05 +0800 Subject: [PATCH 56/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dddb01ceb..342f10313 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.0-alpha.2", + "version": "1.0.0", "description": "React Calendar", "keywords": [ "react", From 63559dcab56392d9bacacb4c5b2cc3352990b07c Mon Sep 17 00:00:00 2001 From: Aries Date: Tue, 11 Nov 2025 14:21:33 +0800 Subject: [PATCH 57/68] feat(ui): update the width of year/month panel and improve style consistency --- assets/index/Calendar.less | 28 +++++++++++++++------------- assets/index/DecadePanel.less | 17 ++++++++++++----- assets/index/Input.less | 4 ++-- assets/index/MonthPanel.less | 11 +++++++---- assets/index/YearPanel.less | 18 ++++++++++++------ package.json | 2 +- src/Calendar.jsx | 7 +++++-- src/calendar/CalendarRightPanel.jsx | 2 ++ src/util/dayjs.js | 2 ++ src/util/index.js | 2 ++ 10 files changed, 60 insertions(+), 33 deletions(-) diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 33edb95ee..b6a878b9c 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -61,8 +61,8 @@ line-height: 1.5; } &-date-input input:focus { - border-color: #ed7109; - box-shadow: 0 0 3px #ed7109; + border-color: #1991eb; + box-shadow: 0 0 0 2px rgba(70, 127, 207, .25); outline: none; } /* Shared header text input */ @@ -80,8 +80,8 @@ transition: border 0.3s, background 0.3s, box-shadow 0.3s; } &-text-input:focus { - border-color: #ed7109; - box-shadow: 0 0 3px #ed7109; + border-color: #1991eb; + box-shadow: 0 0 0 2px rgba(70, 127, 207, .25); outline: none; } @@ -135,7 +135,7 @@ &-month-select:hover, &-day-select:hover { cursor: pointer; - color: #f09f4f; + color: #ed7109; } &-year-select.@{prefixClass}-time-status:hover, &-month-select.@{prefixClass}-time-status:hover, @@ -163,7 +163,7 @@ &-next-month-btn:hover, &-prev-year-btn:hover, &-next-year-btn:hover { - color: #555; + color: #ed7109; } &-next-year-btn { right: 0; @@ -234,11 +234,11 @@ cursor: pointer; } &-selected-date &-date { - background: #ed7109; + background: #ff9800; color: #fff; } &-selected-date &-date:hover { - background: #ed7109; + background: #ff9800; } &-disabled-cell &-date { cursor: not-allowed; @@ -267,7 +267,7 @@ } &-today &-date::before { content: ''; - background: #ed7109; + background: #ff9800; position: absolute; width: 4px; height: 4px; @@ -318,12 +318,14 @@ border-radius: 3px; } &-right-panel-item:hover { - background: fade(#ed7109, 10%); + background: fade(#ff9800, 10%); + color: #212529; } - &-right-panel-item-selected { - background: fade(#ed7109, 10%); + &-right-panel-item-selected, + &-right-panel-item-selected:hover { + background: #ff9800; border-radius: 3px; - color: #212529; + color: #fff; } &-right-panel-col::-webkit-scrollbar { width: 0; diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index f65b31b2c..27d5caede 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -2,7 +2,8 @@ left: 0; top: 0; bottom: 0; - right: 0; + right: auto; + width: 288px; background: #ffffff; z-index: 10; position: absolute; @@ -19,6 +20,9 @@ padding: 0 10px; height: 34px; line-height: 34px; + display: inline-flex; + justify-content: center; + align-items: center; position: relative; text-align: center; user-select: none; @@ -26,15 +30,18 @@ border-bottom: 1px solid #ccc; > a { + height: 100%; font-weight: bold; - display: inline-block; + display: inline-flex; + justify-content: center; + align-items: center; padding: 1px 5px; text-align: center; width: 30px; + color: #212529; &:hover { cursor: pointer; - color: #f09f4f; } } } @@ -102,7 +109,7 @@ } .@{prefixClass}-decade-panel-selected-cell .@{prefixClass}-decade-panel-decade { - background: #f09f3f; + background: #ff9800; color: #fff; &:hover { @@ -117,4 +124,4 @@ -webkit-user-select: none; color: rgba(0, 0, 0, 0.25); } -} \ No newline at end of file +} diff --git a/assets/index/Input.less b/assets/index/Input.less index 08f6d5690..ceb936138 100644 --- a/assets/index/Input.less +++ b/assets/index/Input.less @@ -14,7 +14,7 @@ box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1); &:focus { - border-color: #ed7109; - box-shadow: 0 0 3px #ed7109; + border-color: #1991eb; + box-shadow: 0 0 0 2px rgba(70, 127, 207, .25); } } diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index 9fc075195..88d202de6 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -2,7 +2,8 @@ left: 0; top: 0; bottom: 0; - right: 0; + right: auto; + width: 288px; background: #ffffff; z-index: 10; position: absolute; @@ -35,10 +36,11 @@ padding: 4px 5px; text-align: center; width: 30px; + color: #212529; &:hover { cursor: pointer; - color: #f09f4f; + color: #ed7109; } } } @@ -101,7 +103,7 @@ display: block; width: 46px; margin: 0 auto; - color: #666; + color: #212529; border-radius: 4px 4px; height: 36px; padding: 0; @@ -110,6 +112,7 @@ text-align: center; &:hover { + color: #212529; background: #fcecd9; cursor: pointer; } @@ -128,7 +131,7 @@ } .@{prefixClass}-month-panel-selected-cell .@{prefixClass}-month-panel-month { - background: #ed7109; + background: #ff9800; color: #fff; &:hover { diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index 8297eba3a..2ce5bb011 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -2,7 +2,8 @@ left: 0; top: 0; bottom: 0; - right: 0; + right: auto; + width: 288px; background: #ffffff; z-index: 10; position: absolute; @@ -30,15 +31,19 @@ border-bottom: 1px solid #ccc; > a { + height: 100%; font-weight: bold; - display: inline-block; + display: inline-flex; + justify-content: center; + align-items: center; padding: 4px 5px; text-align: center; width: 30px; + color: #212529; &:hover { cursor: pointer; - color: #f09f4f; + color: #ed7109; } } } @@ -102,7 +107,7 @@ display: block; width: 46px; margin: 0 auto; - color: #666; + color: #212529; border-radius: 4px 4px; height: 36px; padding: 0; @@ -111,17 +116,18 @@ text-align: center; &:hover { + color: #212529; background: #fcecd9; cursor: pointer; } } .@{prefixClass}-year-panel-selected-cell .@{prefixClass}-year-panel-year { - background: #ed7109; + background: #ff9800; color: #fff; &:hover { - background: #ed7109; + background: #ff9800; color: #fff; } } diff --git a/package.json b/package.json index 342f10313..442922c04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.0", + "version": "1.0.1-beta.3", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index d0feea6af..28e12e5f7 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -374,6 +374,9 @@ class Calendar extends React.Component { if (props.renderSidebar) { children.push(props.renderSidebar()); } + + const showTimeControls = showHourAndMinute && mode === 'date'; + children.push(
@@ -381,7 +384,7 @@ class Calendar extends React.Component { {dateInputElement}
- {showHourAndMinute && ( + {showTimeControls && (
{timeInputTopElement}
@@ -425,7 +428,7 @@ class Calendar extends React.Component {
- {showHourAndMinute && + {showTimeControls && this.onSelectHour(h)} className={`${prefixCls}-right-panel-item ${h === selectedHour ? `${prefixCls}-right-panel-item-selected` : ''}`} + title={h} >{h} ))} @@ -179,6 +180,7 @@ export default class CalendarRightPanel extends React.Component { key={m} onClick={() => this.onSelectMinute(m)} className={`${prefixCls}-right-panel-item ${m === selectedMinute ? `${prefixCls}-right-panel-item-selected` : ''}`} + title={m} >{m} ))} diff --git a/src/util/dayjs.js b/src/util/dayjs.js index 46eebcbe6..99ff33bf0 100644 --- a/src/util/dayjs.js +++ b/src/util/dayjs.js @@ -3,6 +3,7 @@ import localeData from 'dayjs/plugin/localeData'; import weekOfYear from 'dayjs/plugin/weekOfYear'; import utc from 'dayjs/plugin/utc'; import advancedFormat from 'dayjs/plugin/advancedFormat'; +import localizedFormat from 'dayjs/plugin/localizedFormat'; import customParseFormat from 'dayjs/plugin/customParseFormat'; import badMutable from 'dayjs/plugin/badMutable'; import 'dayjs/locale/zh-cn'; @@ -12,6 +13,7 @@ dayjs.extend(localeData); dayjs.extend(weekOfYear); dayjs.extend(utc); dayjs.extend(advancedFormat); +dayjs.extend(localizedFormat); dayjs.extend(customParseFormat); dayjs.extend(badMutable); export default dayjs; diff --git a/src/util/index.js b/src/util/index.js index b2c9951d6..d852a50e2 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -1,7 +1,9 @@ import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; +import localeData from 'dayjs/plugin/localeData'; dayjs.extend(utc); +dayjs.extend(localeData); export const getCurrentDate = () => dayjs().date(); export const getCurrentMonth = () => dayjs().month() + 1; export const getCurrentYear = () => dayjs().year(); From f5e69c250d2cbc98580b99965b4183420f19fbee Mon Sep 17 00:00:00 2001 From: Aries Date: Tue, 11 Nov 2025 14:31:48 +0800 Subject: [PATCH 58/68] fix decade panel text color --- assets/index/DecadePanel.less | 8 +++++++- package.json | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index 27d5caede..dd00e8836 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -42,6 +42,7 @@ &:hover { cursor: pointer; + color: #ed7109; } } } @@ -89,12 +90,17 @@ .@{prefixClass}-decade-panel-cell { text-align: center; + color: #212529; + + a:hover { + color: inherit; + } } .@{prefixClass}-decade-panel-decade { display: block; margin: 0 auto; - color: #666; + color: #212529; border-radius: 4px 4px; height: 36px; padding: 0; diff --git a/package.json b/package.json index 442922c04..60d06e96a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.1-beta.3", + "version": "1.0.1-alpha.1", "description": "React Calendar", "keywords": [ "react", From c66082d68d1a535feaeba6a066985ec7e16fddad Mon Sep 17 00:00:00 2001 From: Aries Date: Fri, 14 Nov 2025 10:08:39 +0800 Subject: [PATCH 59/68] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 60d06e96a..508ce61d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.1-alpha.1", + "version": "1.0.1", "description": "React Calendar", "keywords": [ "react", From 0f649b06c27d78ac9e31c9ce1738d4afe82f1d2e Mon Sep 17 00:00:00 2001 From: zhouwenxuan Date: Tue, 2 Dec 2025 14:30:35 +0800 Subject: [PATCH 60/68] feat: update calendar ux --- assets/common/Calendar.less | 6 +- assets/index/Calendar.less | 171 +++++++++++----------------- assets/index/DecadePanel.less | 53 ++++----- assets/index/Input.less | 1 - assets/index/MonthPanel.less | 56 +++++---- assets/index/Time.less | 5 - assets/index/YearPanel.less | 47 ++++---- examples/antd-calendar.js | 5 +- package.json | 2 +- src/Calendar.jsx | 26 +++-- src/calendar/CalendarHeader.jsx | 2 +- src/calendar/CalendarRightPanel.jsx | 99 +++++++++------- src/date/DateInput.js | 1 + src/time/TimeInput.js | 31 ++--- 14 files changed, 258 insertions(+), 247 deletions(-) diff --git a/assets/common/Calendar.less b/assets/common/Calendar.less index face190ae..a4837c14a 100644 --- a/assets/common/Calendar.less +++ b/assets/common/Calendar.less @@ -59,7 +59,7 @@ &-input { border: 1px solid transparent; width: 100%; - color: #666; + color: #333; cursor: text; line-height: 1.5; outline: 0; @@ -68,6 +68,10 @@ &-invalid { border-color: red; } + + &::placeholder { + color: #808080; + } } &-clear-btn { diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index b6a878b9c..72ff0a401 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -23,76 +23,50 @@ } &-date-panel { display: block; - min-width: 288px; + min-width: 260px; } /* Top inputs row */ &-inputs { display: flex; align-items: stretch; - border-bottom: 1px solid #eee; } &-date-input-col { flex: 1 1 auto; } &-time-input-col { - width: 122px; + width: 89px; border-left: 1px solid #eee; } &-date-input, - &-time-input-outer { + &-time-input { display: flex; align-items: center; height: 100%; + padding: 12px 12px 0 12px; } - &-date-input { - padding: 10px; - } - &-time-input-outer { - padding: 10px; - width: 100%; - } - &-date-input input { + &-date-input input, + &-time-input input { height: 30px; width: 100%; - padding: 4px 10px; + padding: 4px 6px; border: 1px solid #eee; border-radius: 3px; line-height: 1.5; } - &-date-input input:focus { - border-color: #1991eb; - box-shadow: 0 0 0 2px rgba(70, 127, 207, .25); - outline: none; - } - /* Shared header text input */ - &-text-input { - height: 30px; - display: inline-block; - width: 100%; - margin: 0; - padding: 4px 10px; - border-radius: 6px; - border: 1px solid #eee; - background: #fff; - color: #666; - line-height: 1.5; - transition: border 0.3s, background 0.3s, box-shadow 0.3s; - } - &-text-input:focus { + &-date-input input:focus, + &-time-input input:focus { border-color: #1991eb; box-shadow: 0 0 0 2px rgba(70, 127, 207, .25); outline: none; } - &-header { - padding: 0 10px; - height: 40px; - line-height: 40px; + padding: 0 12px; + height: 48px; + line-height: 24px; text-align: center; user-select: none; -webkit-user-select: none; - border-bottom: 1px solid #eee; } &-header > a { font-weight: 600; @@ -111,6 +85,7 @@ left: 25px; } &-prev-month-btn:after { + width: 20px; content: '‹'; } &-next-month-btn { @@ -118,6 +93,7 @@ right: 25px; } &-next-month-btn:after { + width: 20px; content: '›'; } @@ -129,13 +105,13 @@ font-weight: 600; color: #212529; padding: 0 8px; - line-height: 40px; + line-height: 48px; } &-year-select:hover, &-month-select:hover, &-day-select:hover { cursor: pointer; - color: #ed7109; + color: #ff7600; } &-year-select.@{prefixClass}-time-status:hover, &-month-select.@{prefixClass}-time-status:hover, @@ -148,46 +124,54 @@ &-next-month-btn, &-prev-year-btn, &-next-year-btn { + width: 20px; + height: 20px; position: absolute; - top: 0; + top: 12px; cursor: pointer; color: #999; font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', 'Microsoft Sans Serif', sans-serif; - padding: 0 5px; font-size: 16px; - display: inline-block; - line-height: 40px; + display: flex; + line-height: 18px; + border-radius: 4px; } &-prev-month-btn:hover, &-next-month-btn:hover, &-prev-year-btn:hover, &-next-year-btn:hover { - color: #ed7109; + background-color: #f5f5f5; } &-next-year-btn { right: 0; } &-next-year-btn:after { + width: 20px; content: '»'; } &-prev-year-btn { left: 0; } &-prev-year-btn:after { + width: 20px; content: '«'; } /* Date grid area */ &-body { - padding: 8px 18px; - height: 268px; + padding: 0 12px; + height: 240px; } table { border-collapse: collapse; max-width: 100%; background-color: transparent; width: 100%; + + td { + padding: 0; + } } table, td, @@ -201,8 +185,8 @@ } &-column-header { line-height: 18px; - height: 36px; - width: 36px; + height: 32px; + width: 32px; text-align: center; } &-column-header-inner { @@ -214,67 +198,44 @@ display: none; } &-cell { - height: 36px; - padding: 0; + width: 32px; + height: auto; } &-date { display: block; - margin: 0 auto; color: #212529; border-radius: 4px; - width: 24px; - height: 24px; + width: 32px; + height: 32px; padding: 0; background: transparent; - line-height: 24px; + line-height: 32px; text-align: center; } &-date:hover { - background: #fcecd9; + background: #f5f5f5; + border-radius: 50%; cursor: pointer; } &-selected-date &-date { background: #ff9800; + border-radius: 50%; color: #fff; } &-selected-date &-date:hover { background: #ff9800; + border-radius: 50%; } &-disabled-cell &-date { cursor: not-allowed; - color: #bcbcbc; - background: #f3f3f3; - border-radius: 0; - width: auto; - } - &-disabled-cell &-date:hover { - background: #f3f3f3; - } - &-disabled-cell-first-of-row &-date { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - } - &-disabled-cell-last-of-row &-date { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; } &-last-month-cell &-date, &-next-month-btn-day &-date { color: #bbb; } &-today &-date { - position: relative; - } - &-today &-date::before { - content: ''; - background: #ff9800; - position: absolute; - width: 4px; - height: 4px; + border: 1px solid #ff9800; border-radius: 50%; - left: 45%; - bottom: 0%; - display: inline-block; } /* Right time panel */ @@ -282,55 +243,61 @@ height: inherit; border-left: 1px solid #eee; } - &-right-panel-time-header { - height: 40px; - line-height: 40px; - text-align: center; - font-weight: 600; + &-right-panel-header { + display: flex; + justify-content: center; + align-items: center; color: #212529; - border-bottom: 1px solid #eee; + font-weight: 600; } &-right-panel-body { - height: 268px; + height: 240px; display: flex; - padding: 4px; + padding: 0 4px 16px; scrollbar-color: auto; } &-right-panel-col { overflow-y: auto; } - &-right-panel-col:last-child { - border-left: 1px solid #eee; - } &-right-panel-col ul { list-style: none; margin: 0; padding: 4px; } &-right-panel-item { - width: 48px; - height: 28px; - line-height: 28px; - text-align: center; + width: 32px; + height: 32px; + padding: 4px 0; cursor: pointer; + } + &-right-panel-item-text { + width: 100%; + height: 100%; + display: inline-block; + text-align: center; + line-height: 24px; color: #212529; font-weight: 400; border-radius: 3px; } - &-right-panel-item:hover { - background: fade(#ff9800, 10%); + &-right-panel-item-text:hover { + background: #f5f5f5; color: #212529; } &-right-panel-item-selected, &-right-panel-item-selected:hover { background: #ff9800; - border-radius: 3px; + border-radius: 4px; color: #fff; } &-right-panel-col::-webkit-scrollbar { width: 0; height: 0; } + &-right-panel-item-current { + border: 1px solid #ff9800; + border-radius: 4px; + } /* Footer */ &-footer { @@ -357,13 +324,13 @@ &-time-picker-btn { display: inline-block; text-align: center; - color: #ed7109; + color: #ed7107; } &-today-btn:hover, &-ok-btn:hover, &-time-picker-btn:hover { cursor: pointer; - color: #f09f4f; + color: #ff7600; } &-today-btn-disabled, &-ok-btn-disabled, diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index dd00e8836..b845250af 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -3,7 +3,7 @@ top: 0; bottom: 0; right: auto; - width: 288px; + width: 260px; background: #ffffff; z-index: 10; position: absolute; @@ -17,9 +17,8 @@ } .@{prefixClass}-decade-panel-header { - padding: 0 10px; - height: 34px; - line-height: 34px; + height: 48px; + line-height: 48px; display: inline-flex; justify-content: center; align-items: center; @@ -27,50 +26,48 @@ text-align: center; user-select: none; -webkit-user-select: none; - border-bottom: 1px solid #ccc; + border-bottom: 1px solid #eee; > a { - height: 100%; - font-weight: bold; display: inline-flex; justify-content: center; align-items: center; - padding: 1px 5px; - text-align: center; - width: 30px; color: #212529; - - &:hover { - cursor: pointer; - color: #ed7109; - } + cursor: pointer; } } -.@{prefixClass}-decade-panel-prev-century-btn, .@{prefixClass}-decade-panel-next-century-btn { +.@{prefixClass}-decade-panel-prev-century-btn, +.@{prefixClass}-decade-panel-next-century-btn { + width: 20px; + height: 20px; + border-radius: 4px; + color: #999; position: absolute; - top: 0; + top: 12px; +} + +.@{prefixClass}-decade-panel-prev-century-btn:hover, +.@{prefixClass}-decade-panel-next-century-btn:hover { + background-color: #f5f5f5; } .@{prefixClass}-decade-panel-next-century-btn { + right: 16px; &:after { - content: '»' + width: 20px; + content: '»'; } } .@{prefixClass}-decade-panel-prev-century-btn { - user-select: none; - left: 0; + left: 16px; &:after { - content: '«' + width: 20px; + content: '«'; } } -.@{prefixClass}-decade-panel-next-century-btn { - user-select: none; - right: 0; -} - .@{prefixClass}-decade-panel-body { flex: 1; padding: 9px 10px 10px; @@ -109,7 +106,7 @@ text-align: center; &:hover { - background: #fcecd9; + background: #f5f5f5; cursor: pointer; } } @@ -119,7 +116,7 @@ color: #fff; &:hover { - background: #f09f3f; + background: #ff7600; color: #fff; } } diff --git a/assets/index/Input.less b/assets/index/Input.less index ceb936138..f8e3f637a 100644 --- a/assets/index/Input.less +++ b/assets/index/Input.less @@ -7,7 +7,6 @@ border-radius: 3px; border: 1px solid #eee; background-color: #ffffff; - color: #666; line-height: 1.5; transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), background 0.3s cubic-bezier(0.35, 0, 0.25, 1), diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index 88d202de6..b383450e8 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -3,7 +3,7 @@ top: 0; bottom: 0; right: auto; - width: 288px; + width: 260px; background: #ffffff; z-index: 10; position: absolute; @@ -21,47 +21,57 @@ } .@{prefixClass}-month-panel-header { - padding: 0 10px; - height: 34px; - line-height: 30px; + height: 48px; + line-height: 48px; + display: inline-flex; + justify-content: center; + align-items: center; position: relative; text-align: center; user-select: none; -webkit-user-select: none; - border-bottom: 1px solid #ccc; + border-bottom: 1px solid #eee; > a { - font-weight: bold; - display: inline-block; - padding: 4px 5px; - text-align: center; - width: 30px; - color: #212529; - - &:hover { - cursor: pointer; - color: #ed7109; - } + display: inline-flex; + justify-content: center; + align-items: center; + cursor: pointer; } } +.@{prefixClass}-month-panel-year-select:hover { + color: #ff7600; +} + .@{prefixClass}-month-panel-prev-year-btn, .@{prefixClass}-month-panel-next-year-btn { + width: 20px; + height: 20px; + border-radius: 4px; + color: #999; position: absolute; - top: 0; + top: 12px; +} + +.@{prefixClass}-month-panel-prev-year-btn:hover, +.@{prefixClass}-month-panel-next-year-btn:hover { + background-color: #f5f5f5; } .@{prefixClass}-month-panel-next-year-btn { + right: 16px; &:after { + width: 20px; content: '»'; } } .@{prefixClass}-month-panel-prev-year-btn { user-select: none; - left: 0; - + left: 16px; &:after { + width: 20px; content: '«'; } } @@ -76,7 +86,6 @@ .@{prefixClass}-month-panel-next-year-btn { user-select: none; - right: 0; } .@{prefixClass}-month-panel-body { @@ -112,15 +121,14 @@ text-align: center; &:hover { - color: #212529; - background: #fcecd9; + background: #f5f5f5; cursor: pointer; } } &-disabled { .@{prefixClass}-month-panel-month { - color: #bfbfbf; + color: #bbb; &:hover { background: white; @@ -135,7 +143,7 @@ color: #fff; &:hover { - background: #f09f3f; + background: #ff7600; color: #fff; } } diff --git a/assets/index/Time.less b/assets/index/Time.less index 0b17bf37b..0927d3fec 100644 --- a/assets/index/Time.less +++ b/assets/index/Time.less @@ -1,6 +1 @@ @import './Input.less'; - -.@{prefixClass}-time-input { - .input(); - width: 100%; -} diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index 2ce5bb011..e29f3ac2a 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -3,7 +3,7 @@ top: 0; bottom: 0; right: auto; - width: 288px; + width: 260px; background: #ffffff; z-index: 10; position: absolute; @@ -21,50 +21,57 @@ } .@{prefixClass}-year-panel-header { - padding: 0 10px; - height: 34px; - line-height: 30px; + display: flex; + justify-content: center; + align-items: center; + height: 48px; position: relative; text-align: center; user-select: none; -webkit-user-select: none; - border-bottom: 1px solid #ccc; + border-bottom: 1px solid #eee; > a { - height: 100%; - font-weight: bold; display: inline-flex; justify-content: center; align-items: center; - padding: 4px 5px; text-align: center; - width: 30px; - color: #212529; - - &:hover { - cursor: pointer; - color: #ed7109; - } + cursor: pointer; } } +.@{prefixClass}-year-panel-decade-select:hover { + color: #ff7600; +} + .@{prefixClass}-year-panel-prev-decade-btn, .@{prefixClass}-year-panel-next-decade-btn { + width: 20px; + height: 20px; position: absolute; - top: 0; + top: 12px; + border-radius: 4px; + color: #999; +} + +.@{prefixClass}-year-panel-prev-decade-btn:hover, +.@{prefixClass}-year-panel-next-decade-btn:hover { + background-color: #f5f5f5; } .@{prefixClass}-year-panel-next-decade-btn { &:after { + width: 20px; content: '»'; } } .@{prefixClass}-year-panel-prev-decade-btn { user-select: none; - left: 0; + left: 16px; &:after { + width: 20px; content: '«'; } } @@ -79,7 +86,7 @@ .@{prefixClass}-year-panel-next-decade-btn { user-select: none; - right: 0; + right: 16px; } .@{prefixClass}-year-panel-body { @@ -108,7 +115,7 @@ width: 46px; margin: 0 auto; color: #212529; - border-radius: 4px 4px; + border-radius: 4px; height: 36px; padding: 0; background: transparent; @@ -117,7 +124,7 @@ &:hover { color: #212529; - background: #fcecd9; + background: #f5f5f5; cursor: pointer; } } diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 6170fefdb..428d6eb4c 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -299,9 +299,10 @@ ReactDOM.render((
({mode} extra footer)} + showHourAndMinute={true} />
-
+ {/*
@@ -310,6 +311,6 @@ ReactDOM.render((
-
+
*/}
), document.getElementById('__react-content')); diff --git a/package.json b/package.json index 508ce61d6..61e7d32cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.1", + "version": "1.0.2-beta.1", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 28e12e5f7..fc8f1d33f 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -199,26 +199,30 @@ class Calendar extends React.Component { } onDateInputChange = (value) => { + const now = dayjs(); + if (value && value.hour() === 0 && value.minute() === 0 && value.second() === 0) { + value = value.hour(now.hour()).minute(now.minute()).second(now.second()); + } this.onSelect(value, { source: 'dateInput', }); } onDateInputSelect = (value) => { + const now = dayjs(); + if (value && value.hour() === 0 && value.minute() === 0 && value.second() === 0) { + value = value.hour(now.hour()).minute(now.minute()).second(now.second()); + } this.onSelect(value, { source: 'dateInputSelect', }); } onDateTableSelect = (value) => { - const { timePicker } = this.props; - const { selectedValue } = this.state; this.setState({ currentStatus: CALENDAR_STATUS.SPECIFIC_TIME }); - if (!selectedValue && timePicker) { - const timePickerDefaultValue = timePicker.props.defaultValue; - if (timePickerDefaultValue) { - syncTime(timePickerDefaultValue, value); - } + const now = dayjs(); + if (value && value.hour() === 0 && value.minute() === 0 && value.second() === 0) { + value = value.hour(now.hour()).minute(now.minute()).second(now.second()); } this.onSelect(value); } @@ -386,8 +390,10 @@ class Calendar extends React.Component {
{showTimeControls && (
- {timeInputTopElement} -
+
+ {timeInputTopElement} +
+
)}
@@ -434,7 +440,7 @@ class Calendar extends React.Component { value={value} selectedValue={selectedValue} locale={locale} - onSelect={(v) => this.onDateTableSelect(v)} + onSelect={this.onDateTableSelect} onClickRightPanelTime={onClickRightPanelTime} defaultMinutesTime={this.props.defaultMinutesTime} format={inputFormat} diff --git a/src/calendar/CalendarHeader.jsx b/src/calendar/CalendarHeader.jsx index 2c4817922..a11ab557d 100644 --- a/src/calendar/CalendarHeader.jsx +++ b/src/calendar/CalendarHeader.jsx @@ -198,7 +198,7 @@ export default class CalendarHeader extends React.Component { } return (
-
+
{showIf(enablePrev && !showTimePicker, h === base[0]); const mIdx = this.minutes.findIndex(m => m === base[1]); const hourIndex = hIdx > -1 ? hIdx : 0; @@ -61,8 +61,8 @@ export default class CalendarRightPanel extends React.Component { } componentDidUpdate(prevProps, prevState) { - const prevV = prevState.highlightTime || prevProps.selectedValue || prevProps.value; - const currV = this.state.highlightTime || this.props.selectedValue || this.props.value; + const prevV = prevState.highlightTime || prevProps.selectedValue || dayjs(); + const currV = this.state.highlightTime || this.props.selectedValue || dayjs(); const prevH = prevV ? prevV.format('HH') : '00'; const prevM = prevV ? prevV.format('mm') : '00'; @@ -110,9 +110,10 @@ export default class CalendarRightPanel extends React.Component { } onSelectMinute = (minute) => { - const base = this.props.selectedValue || this.props.value || this.state.highlightTime || dayjs(); - const h = parseInt(this.getSelectedHour(), 10) || 0; - const m = parseInt(minute, 10) || 0; + const base = this.props.selectedValue || this.state.highlightTime || this.props.value || dayjs(); + const selectedHour = this.getSelectedHour(); + const h = selectedHour !== null ? parseInt(selectedHour, 10) : dayjs().hour(); + const m = parseInt(minute, 10); const current = base.clone().hour(h).minute(m); this.skipScrollUpdates = 2; this.setState({ highlightTime: current }); @@ -123,9 +124,10 @@ export default class CalendarRightPanel extends React.Component { } onSelectHour = (hour) => { - const base = this.props.selectedValue || this.props.value || this.state.highlightTime || dayjs(); - const h = parseInt(hour, 10) || 0; - const m = parseInt(this.getSelectedMinute(), 10) || 0; + const base = this.props.selectedValue || this.state.highlightTime || dayjs(); + const h = parseInt(hour, 10); + const selectedMinute = this.getSelectedMinute(); + const m = selectedMinute !== null ? parseInt(selectedMinute, 10) : dayjs().minute(); const current = base.clone().hour(h).minute(m); this.skipScrollUpdates = 2; this.setState({ highlightTime: current }); @@ -138,52 +140,73 @@ export default class CalendarRightPanel extends React.Component { getSelectedHour = () => { const { highlightTime } = this.state; - const { value, selectedValue } = this.props; - const v = highlightTime || selectedValue || value; - return v ? v.format('HH') : '00'; + const { selectedValue } = this.props; + const v = highlightTime || selectedValue || null; + return v ? v.format('HH') : null; } getSelectedMinute = () => { const { highlightTime } = this.state; - const { value, selectedValue } = this.props; - const v = highlightTime || selectedValue || value; - return v ? v.format('mm') : '00'; + const { selectedValue } = this.props; + const v = highlightTime || selectedValue || null; + return v ? v.format('mm') : null; } render() { const { prefixCls } = this.props; const selectedHour = this.getSelectedHour(); const selectedMinute = this.getSelectedMinute(); + const currentHour = dayjs().format('HH'); + const currentMinute = dayjs().format('mm'); + const displayHour = selectedHour || currentHour; + const displayMinute = selectedMinute || currentMinute; + return (
-
- {selectedHour}:{selectedMinute} +
+ {displayHour}:{displayMinute}
    - {this.hours.map((h) => ( -
  • this.onSelectHour(h)} - className={`${prefixCls}-right-panel-item ${h === selectedHour ? `${prefixCls}-right-panel-item-selected` : ''}`} - title={h} - >{h} -
  • - ))} + {this.hours.map((h) => { + const isSelected = selectedHour && h === selectedHour; + const isCurrent = !selectedHour && h === currentHour; + const className = `${prefixCls}-right-panel-item-text ${isSelected ? `${prefixCls}-right-panel-item-selected` : ''} ${isCurrent ? `${prefixCls}-right-panel-item-current` : ''}`; + return ( +
  • this.onSelectHour(h)} + className={`${prefixCls}-right-panel-item`} + title={h} + > + + {h} + +
  • + ); + })}
    - {this.minutes.map((m) => ( -
  • this.onSelectMinute(m)} - className={`${prefixCls}-right-panel-item ${m === selectedMinute ? `${prefixCls}-right-panel-item-selected` : ''}`} - title={m} - >{m} -
  • - ))} + {this.minutes.map((m) => { + const isSelected = selectedMinute && m === selectedMinute; + const isCurrent = !selectedMinute && m === currentMinute; + const className = `${prefixCls}-right-panel-item-text ${isSelected ? `${prefixCls}-right-panel-item-selected` : ''} ${isCurrent ? `${prefixCls}-right-panel-item-current` : ''}`; + return ( +
  • this.onSelectMinute(m)} + className={`${prefixCls}-right-panel-item`} + title={m} + > + + {m} + +
  • + ); + })}
diff --git a/src/date/DateInput.js b/src/date/DateInput.js index e5ec49189..ec6b1d978 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -169,6 +169,7 @@ class DateInput extends React.Component {
- +
+
+ +
); } From 95679a601dedbdbace7897bc04e1ef378481974d Mon Sep 17 00:00:00 2001 From: zhouwenxuan Date: Tue, 2 Dec 2025 16:28:54 +0800 Subject: [PATCH 61/68] chore: reset examples --- examples/antd-calendar.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 428d6eb4c..6170fefdb 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -299,10 +299,9 @@ ReactDOM.render((
({mode} extra footer)} - showHourAndMinute={true} />
- {/*
+
@@ -311,6 +310,6 @@ ReactDOM.render((
-
*/} +
), document.getElementById('__react-content')); From 7d24541ce800d357d033b812059c1c4ac4f30476 Mon Sep 17 00:00:00 2001 From: zhouwenxuan Date: Wed, 3 Dec 2025 15:01:29 +0800 Subject: [PATCH 62/68] fix: color style --- assets/common/Calendar.less | 2 +- assets/index/Calendar.less | 13 ++++++++++--- assets/index/DecadePanel.less | 2 +- assets/index/MonthPanel.less | 4 ++-- assets/index/YearPanel.less | 2 +- package.json | 2 +- src/calendar/CalendarHeader.jsx | 2 +- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/assets/common/Calendar.less b/assets/common/Calendar.less index a4837c14a..48279acbe 100644 --- a/assets/common/Calendar.less +++ b/assets/common/Calendar.less @@ -70,7 +70,7 @@ } &::placeholder { - color: #808080; + color: #868e96; } } diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 72ff0a401..2a4f0ee3d 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -68,6 +68,13 @@ user-select: none; -webkit-user-select: none; } + &-header-nav-wrap { + position: relative; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } &-header > a { font-weight: 600; display: inline-block; @@ -111,7 +118,7 @@ &-month-select:hover, &-day-select:hover { cursor: pointer; - color: #ff7600; + color: #ff9800; } &-year-select.@{prefixClass}-time-status:hover, &-month-select.@{prefixClass}-time-status:hover, @@ -324,13 +331,13 @@ &-time-picker-btn { display: inline-block; text-align: center; - color: #ed7107; + color: #ed7109; } &-today-btn:hover, &-ok-btn:hover, &-time-picker-btn:hover { cursor: pointer; - color: #ff7600; + color: #ff9800; } &-today-btn-disabled, &-ok-btn-disabled, diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index b845250af..1404ec40b 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -116,7 +116,7 @@ color: #fff; &:hover { - background: #ff7600; + background: #ff9800; color: #fff; } } diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index b383450e8..48d6c11cd 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -41,7 +41,7 @@ } .@{prefixClass}-month-panel-year-select:hover { - color: #ff7600; + color: #ff9800; } .@{prefixClass}-month-panel-prev-year-btn, @@ -143,7 +143,7 @@ color: #fff; &:hover { - background: #ff7600; + background: #ff9800; color: #fff; } } diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index e29f3ac2a..0db10e47b 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -41,7 +41,7 @@ } .@{prefixClass}-year-panel-decade-select:hover { - color: #ff7600; + color: #ff9800; } .@{prefixClass}-year-panel-prev-decade-btn, diff --git a/package.json b/package.json index 61e7d32cd..9c92f18aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.2-beta.1", + "version": "1.0.2-beta.3", "description": "React Calendar", "keywords": [ "react", diff --git a/src/calendar/CalendarHeader.jsx b/src/calendar/CalendarHeader.jsx index a11ab557d..548a1ee09 100644 --- a/src/calendar/CalendarHeader.jsx +++ b/src/calendar/CalendarHeader.jsx @@ -198,7 +198,7 @@ export default class CalendarHeader extends React.Component { } return (
-
+
{showIf(enablePrev && !showTimePicker, Date: Thu, 4 Dec 2025 11:22:47 +0800 Subject: [PATCH 63/68] fix: calendar width and btn ux --- assets/index/Calendar.less | 11 ++++++++--- assets/index/DecadePanel.less | 19 ++++++++++++------- assets/index/MonthPanel.less | 15 ++++++++------- assets/index/YearPanel.less | 14 ++++++++------ examples/antd-calendar.js | 1 + package.json | 2 +- src/Calendar.jsx | 3 ++- src/calendar/CalendarHeader.jsx | 3 +++ src/decade/DecadePanel.jsx | 11 +++++++---- src/year/YearPanel.jsx | 9 ++++++--- 10 files changed, 56 insertions(+), 32 deletions(-) diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 2a4f0ee3d..8bf81c27a 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -2,7 +2,7 @@ position: relative; outline: none; font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans-serif; - width: fit-content; + width: 260px; list-style: none; font-size: 14px; text-align: left; @@ -13,6 +13,10 @@ border: 1px solid #ccc; line-height: 1.5; + &-with-time-panel { + width: 349px; + } + /* Layout wrappers */ &-panel { display: flex; @@ -23,7 +27,7 @@ } &-date-panel { display: block; - min-width: 260px; + width: 260px; } /* Top inputs row */ @@ -134,7 +138,7 @@ width: 20px; height: 20px; position: absolute; - top: 12px; + top: 14px; cursor: pointer; color: #999; font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', @@ -148,6 +152,7 @@ &-next-month-btn:hover, &-prev-year-btn:hover, &-next-year-btn:hover { + color: #999; background-color: #f5f5f5; } &-next-year-btn { diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index 1404ec40b..5453c06fb 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -2,8 +2,8 @@ left: 0; top: 0; bottom: 0; - right: auto; - width: 260px; + right: 0; + width: 100%; background: #ffffff; z-index: 10; position: absolute; @@ -32,11 +32,14 @@ display: inline-flex; justify-content: center; align-items: center; - color: #212529; cursor: pointer; } } +.@{prefixClass}-decade-panel-century { + color: #212529; +} + .@{prefixClass}-decade-panel-prev-century-btn, .@{prefixClass}-decade-panel-next-century-btn { width: 20px; @@ -44,27 +47,28 @@ border-radius: 4px; color: #999; position: absolute; - top: 12px; + top: 14px; } .@{prefixClass}-decade-panel-prev-century-btn:hover, .@{prefixClass}-decade-panel-next-century-btn:hover { + color: #999; background-color: #f5f5f5; } .@{prefixClass}-decade-panel-next-century-btn { right: 16px; &:after { - width: 20px; content: '»'; + transform: translateY(-1px); } } .@{prefixClass}-decade-panel-prev-century-btn { left: 16px; &:after { - width: 20px; content: '«'; + transform: translateY(-1px); } } @@ -98,12 +102,13 @@ display: block; margin: 0 auto; color: #212529; - border-radius: 4px 4px; + border-radius: 4px; height: 36px; padding: 0; background: transparent; line-height: 36px; text-align: center; + width: 105px; &:hover { background: #f5f5f5; diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index 48d6c11cd..4e22a9701 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -2,8 +2,8 @@ left: 0; top: 0; bottom: 0; - right: auto; - width: 260px; + right: 0; + width: 100%; background: #ffffff; z-index: 10; position: absolute; @@ -51,19 +51,20 @@ border-radius: 4px; color: #999; position: absolute; - top: 12px; + top: 14px; } .@{prefixClass}-month-panel-prev-year-btn:hover, .@{prefixClass}-month-panel-next-year-btn:hover { + color: #999; background-color: #f5f5f5; } .@{prefixClass}-month-panel-next-year-btn { right: 16px; &:after { - width: 20px; content: '»'; + transform: translateY(-1px); } } @@ -71,8 +72,8 @@ user-select: none; left: 16px; &:after { - width: 20px; content: '«'; + transform: translateY(-1px); } } @@ -110,10 +111,10 @@ .@{prefixClass}-month-panel-month { display: block; - width: 46px; + width: 64px; margin: 0 auto; color: #212529; - border-radius: 4px 4px; + border-radius: 4px; height: 36px; padding: 0; background: transparent; diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index 0db10e47b..9b570b1e8 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -2,8 +2,8 @@ left: 0; top: 0; bottom: 0; - right: auto; - width: 260px; + right: 0; + width: 100%; background: #ffffff; z-index: 10; position: absolute; @@ -49,20 +49,22 @@ width: 20px; height: 20px; position: absolute; - top: 12px; + top: 14px; border-radius: 4px; color: #999; } .@{prefixClass}-year-panel-prev-decade-btn:hover, .@{prefixClass}-year-panel-next-decade-btn:hover { + color: #999; background-color: #f5f5f5; } .@{prefixClass}-year-panel-next-decade-btn { + right: 16px; &:after { - width: 20px; content: '»'; + transform: translateY(-1px); } } @@ -71,8 +73,8 @@ left: 16px; &:after { - width: 20px; content: '«'; + transform: translateY(-1px); } } @@ -112,7 +114,7 @@ .@{prefixClass}-year-panel-year { display: block; - width: 46px; + width: 64px; margin: 0 auto; color: #212529; border-radius: 4px; diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 6170fefdb..b2aac9ac9 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -299,6 +299,7 @@ ReactDOM.render((
({mode} extra footer)} + showHourAndMinute={true} />
diff --git a/package.json b/package.json index 9c92f18aa..d83406661 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.2-beta.3", + "version": "1.0.2-beta.6", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index fc8f1d33f..752857fe7 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -410,6 +410,7 @@ class Calendar extends React.Component { renderFooter={renderFooter} showTimePicker={showTimePicker} prefixCls={prefixCls} + showHourAndMinute={showHourAndMinute} /> {timePicker && showTimePicker ? (
@@ -474,7 +475,7 @@ class Calendar extends React.Component { return this.renderRoot({ children, - className: props.showWeekNumber ? `${prefixCls}-week-number` : '', + className: `${props.showWeekNumber ? `${prefixCls}-week-number` : ''} ${showHourAndMinute ? `${prefixCls}-with-time-panel` : ''}`.trim(), }); } } diff --git a/src/calendar/CalendarHeader.jsx b/src/calendar/CalendarHeader.jsx index 548a1ee09..82ddd966e 100644 --- a/src/calendar/CalendarHeader.jsx +++ b/src/calendar/CalendarHeader.jsx @@ -34,6 +34,7 @@ export default class CalendarHeader extends React.Component { disabledMonth: PropTypes.func, renderFooter: PropTypes.func, onMonthSelect: PropTypes.func, + showHourAndMinute: PropTypes.bool, } static defaultProps = { @@ -182,6 +183,7 @@ export default class CalendarHeader extends React.Component { onSelect={this.onYearSelect} onDecadePanelShow={this.showDecadePanel} renderFooter={renderFooter} + showHourAndMinute={props.showHourAndMinute} /> ); } @@ -193,6 +195,7 @@ export default class CalendarHeader extends React.Component { rootPrefixCls={prefixCls} onSelect={this.onDecadeSelect} renderFooter={renderFooter} + showHourAndMinute={props.showHourAndMinute} /> ); } diff --git a/src/decade/DecadePanel.jsx b/src/decade/DecadePanel.jsx index b33748f2a..a59952ba4 100644 --- a/src/decade/DecadePanel.jsx +++ b/src/decade/DecadePanel.jsx @@ -35,7 +35,7 @@ export default class DecadePanel extends React.Component { render() { const value = this.state.value; - const { locale, renderFooter } = this.props; + const { locale, renderFooter, showHourAndMinute } = this.props; const currentYear = value.year(); const startYear = parseInt(currentYear / 100, 10) * 100; const preYear = startYear - 10; @@ -43,10 +43,12 @@ export default class DecadePanel extends React.Component { const decades = []; let index = 0; const prefixCls = this.prefixCls; + const col = showHourAndMinute ? 3 : 2; + const row = showHourAndMinute ? 4 : 5; - for (let rowIndex = 0; rowIndex < ROW; rowIndex++) { + for (let rowIndex = 0; rowIndex < row; rowIndex++) { decades[rowIndex] = []; - for (let colIndex = 0; colIndex < COL; colIndex++) { + for (let colIndex = 0; colIndex < col; colIndex++) { const startDecade = preYear + index * 10; const endDecade = preYear + index * 10 + 9; decades[rowIndex][colIndex] = { @@ -97,7 +99,7 @@ export default class DecadePanel extends React.Component { }); return ( -
+
+
Date: Thu, 4 Dec 2025 16:59:56 +0800 Subject: [PATCH 64/68] Merge pull request #30 from seafileltd/update-npm-version chore: update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d83406661..7f915b56e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.2-beta.6", + "version": "1.0.2", "description": "React Calendar", "keywords": [ "react", From b4d17c4381d36bd8155e8f1bf182906f08c134a3 Mon Sep 17 00:00:00 2001 From: zhouwenxuan Date: Mon, 8 Dec 2025 18:00:15 +0800 Subject: [PATCH 65/68] fix: keyboard handler and shortcut key --- package.json | 2 +- src/Calendar.jsx | 47 +------------------------------------------- src/util/platform.js | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 47 deletions(-) create mode 100644 src/util/platform.js diff --git a/package.json b/package.json index 7f915b56e..ac3582985 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.2", + "version": "1.0.3-beta.1", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 752857fe7..93c0a9335 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -122,55 +122,9 @@ class Calendar extends React.Component { return undefined; } const keyCode = event.keyCode; - // mac - const ctrlKey = event.ctrlKey || event.metaKey; const { disabledDate } = this.props; const { value } = this.state; switch (keyCode) { - case KeyCode.DOWN: - this.goTime(1, 'weeks'); - event.preventDefault(); - return 1; - case KeyCode.UP: - this.goTime(-1, 'weeks'); - event.preventDefault(); - return 1; - case KeyCode.LEFT: - if (ctrlKey) { - this.goTime(-1, 'years'); - } else { - this.goTime(-1, 'days'); - } - event.preventDefault(); - return 1; - case KeyCode.RIGHT: - if (ctrlKey) { - this.goTime(1, 'years'); - } else { - this.goTime(1, 'days'); - } - event.preventDefault(); - return 1; - case KeyCode.HOME: - this.setValue( - goStartMonth(this.state.value), - ); - event.preventDefault(); - return 1; - case KeyCode.END: - this.setValue( - goEndMonth(this.state.value), - ); - event.preventDefault(); - return 1; - case KeyCode.PAGE_DOWN: - this.goTime(1, 'month'); - event.preventDefault(); - return 1; - case KeyCode.PAGE_UP: - this.goTime(-1, 'month'); - event.preventDefault(); - return 1; case KeyCode.ENTER: if (!disabledDate || !disabledDate(value)) { this.onSelect(value, { @@ -180,6 +134,7 @@ class Calendar extends React.Component { event.preventDefault(); return 1; default: + event.stopPropagation(); this.props.onKeyDown(event); return 1; } diff --git a/src/util/platform.js b/src/util/platform.js new file mode 100644 index 000000000..d0d385878 --- /dev/null +++ b/src/util/platform.js @@ -0,0 +1,39 @@ +// calendar/src/util/platform.js +export const isMac = () => { + return typeof navigator !== 'undefined' && + navigator.platform.toUpperCase().indexOf('MAC') >= 0; +}; + +export const getModifierSymbol = () => { + return isMac() ? '⌘' : 'Ctrl'; +}; + +// Enhance locale strings with platform-specific modifier keys +export const enhanceLocaleWithPlatformKeys = (locale) => { + if (!locale) return locale; + + const isMacOS = isMac(); + + // Don't modify if already correct platform or no modification needed + if (!isMacOS) return locale; + + const enhanced = { ...locale }; + + // Replace in relevant fields for Mac users + ['previousYear', 'nextYear', 'previousMonth', 'nextMonth'].forEach(key => { + if (enhanced[key] && typeof enhanced[key] === 'string') { + // Replace Chinese/Traditional Chinese pattern: Control键 -> Command键 + enhanced[key] = enhanced[key].replace(/Control键/g, 'Command键'); + + // Replace patterns with space: "Control + " or "Ctrl + " -> "⌘ + " + enhanced[key] = enhanced[key].replace(/Control \+/g, '⌘ +'); + enhanced[key] = enhanced[key].replace(/Ctrl \+/g, '⌘ +'); + + // Replace standalone Control/Ctrl without space (fallback) + enhanced[key] = enhanced[key].replace(/\bControl\b/g, 'Command'); + enhanced[key] = enhanced[key].replace(/\bCtrl\b/g, '⌘'); + } + }); + + return enhanced; +}; From 8a52d4e392292f11e7db73b8eac7b1132cca60d3 Mon Sep 17 00:00:00 2001 From: zhouwenxuan Date: Tue, 9 Dec 2025 16:10:29 +0800 Subject: [PATCH 66/68] fix: remove shortcut text --- package.json | 2 +- src/Calendar.jsx | 1 + src/locale/cs_CZ.js | 8 ++++---- src/locale/de_DE.js | 8 ++++---- src/locale/en_US.js | 8 ++++---- src/locale/es_ES.js | 8 ++++---- src/locale/fr_FR.js | 8 ++++---- src/locale/pl_PL.js | 8 ++++---- src/locale/ru_RU.js | 8 ++++---- src/locale/zh_CN.js | 8 ++++---- src/locale/zh_TW.js | 8 ++++---- src/util/platform.js | 39 --------------------------------------- 12 files changed, 38 insertions(+), 76 deletions(-) delete mode 100644 src/util/platform.js diff --git a/package.json b/package.json index ac3582985..ed18ef4a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.3-beta.1", + "version": "1.0.3-beta.3", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 93c0a9335..439a31d78 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -134,6 +134,7 @@ class Calendar extends React.Component { event.preventDefault(); return 1; default: + event.preventDefault(); event.stopPropagation(); this.props.onKeyDown(event); return 1; diff --git a/src/locale/cs_CZ.js b/src/locale/cs_CZ.js index 33fa3d60f..2e5324e16 100644 --- a/src/locale/cs_CZ.js +++ b/src/locale/cs_CZ.js @@ -16,10 +16,10 @@ export default { dayFormat: 'D', dateTimeFormat: 'D.M.YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Předchozí měsíc (PageUp)', - nextMonth: 'Následující (PageDown)', - previousYear: 'Předchozí rok (Control + left)', - nextYear: 'Následující rok (Control + right)', + previousMonth: 'Předchozí měsíc', + nextMonth: 'Následující', + previousYear: 'Předchozí rok', + nextYear: 'Následující rok', previousDecade: 'Předchozí dekáda', nextDecade: 'Následující dekáda', previousCentury: 'Předchozí století', diff --git a/src/locale/de_DE.js b/src/locale/de_DE.js index 85161ea34..c398980a7 100644 --- a/src/locale/de_DE.js +++ b/src/locale/de_DE.js @@ -16,10 +16,10 @@ export default { dayFormat: 'D', dateTimeFormat: 'D.M.YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Vorheriger Monat (PageUp)', - nextMonth: 'Nächster Monat (PageDown)', - previousYear: 'Vorheriges Jahr (Ctrl + left)', - nextYear: 'Nächstes Jahr (Ctrl + right)', + previousMonth: 'Vorheriger Monat', + nextMonth: 'Nächster Monat', + previousYear: 'Vorheriges Jahr', + nextYear: 'Nächstes Jahr', previousDecade: 'Vorheriges Jahrzehnt', nextDecade: 'Nächstes Jahrzehnt', previousCentury: 'Vorheriges Jahrhundert', diff --git a/src/locale/en_US.js b/src/locale/en_US.js index df56595ac..4eb0b9881 100644 --- a/src/locale/en_US.js +++ b/src/locale/en_US.js @@ -17,10 +17,10 @@ export default { dayFormat: 'D', dateTimeFormat: 'M/D/YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Previous month (PageUp)', - nextMonth: 'Next month (PageDown)', - previousYear: 'Last year (Control + left)', - nextYear: 'Next year (Control + right)', + previousMonth: 'Previous month', + nextMonth: 'Next month', + previousYear: 'Last year', + nextYear: 'Next year', previousDecade: 'Last decade', nextDecade: 'Next decade', previousCentury: 'Last century', diff --git a/src/locale/es_ES.js b/src/locale/es_ES.js index cdedd4c15..27ab11b14 100644 --- a/src/locale/es_ES.js +++ b/src/locale/es_ES.js @@ -16,10 +16,10 @@ export default { dayFormat: 'D', dateTimeFormat: 'D/M/YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Mes anterior (PageUp)', - nextMonth: 'Mes siguiente (PageDown)', - previousYear: 'Año anterior (Control + left)', - nextYear: 'Año siguiente (Control + right)', + previousMonth: 'Mes anterior', + nextMonth: 'Mes siguiente', + previousYear: 'Año anterior', + nextYear: 'Año siguiente', previousDecade: 'Década anterior', nextDecade: 'Década siguiente', previousCentury: 'Siglo anterior', diff --git a/src/locale/fr_FR.js b/src/locale/fr_FR.js index 5d18103af..868f8c33b 100644 --- a/src/locale/fr_FR.js +++ b/src/locale/fr_FR.js @@ -16,10 +16,10 @@ export default { dayFormat: 'DD', dateTimeFormat: 'DD/MM/YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Mois précédent (PageUp)', - nextMonth: 'Mois suivant (PageDown)', - previousYear: 'Année précédente (Ctrl + gauche)', - nextYear: 'Année prochaine (Ctrl + droite)', + previousMonth: 'Mois précédent', + nextMonth: 'Mois suivant', + previousYear: 'Année précédente', + nextYear: 'Année prochaine', previousDecade: 'Décennie précédente', nextDecade: 'Décennie suivante', previousCentury: 'Siècle précédent', diff --git a/src/locale/pl_PL.js b/src/locale/pl_PL.js index 3202a7f3b..e188a0767 100644 --- a/src/locale/pl_PL.js +++ b/src/locale/pl_PL.js @@ -16,10 +16,10 @@ export default { dayFormat: 'D', dateTimeFormat: 'D/M/YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Poprzedni miesiąc (PageUp)', - nextMonth: 'Następny miesiąc (PageDown)', - previousYear: 'Ostatni rok (Ctrl + left)', - nextYear: 'Następny rok (Ctrl + right)', + previousMonth: 'Poprzedni miesiąc', + nextMonth: 'Następny miesiąc', + previousYear: 'Ostatni rok', + nextYear: 'Następny rok', previousDecade: 'Ostatnia dekada', nextDecade: 'Następna dekada', previousCentury: 'Ostatni wiek', diff --git a/src/locale/ru_RU.js b/src/locale/ru_RU.js index 5a1a8ab56..6e5621e68 100644 --- a/src/locale/ru_RU.js +++ b/src/locale/ru_RU.js @@ -16,10 +16,10 @@ export default { dayFormat: 'D', dateTimeFormat: 'D-M-YYYY HH:mm:ss', monthBeforeYear: true, - previousMonth: 'Предыдущий месяц (PageUp)', - nextMonth: 'Следующий месяц (PageDown)', - previousYear: 'Предыдущий год (Control + left)', - nextYear: 'Следующий год (Control + right)', + previousMonth: 'Предыдущий месяц', + nextMonth: 'Следующий месяц', + previousYear: 'Предыдущий год', + nextYear: 'Следующий год', previousDecade: 'Предыдущее десятилетие', nextDecade: 'Следущее десятилетие', previousCentury: 'Предыдущий век', diff --git a/src/locale/zh_CN.js b/src/locale/zh_CN.js index 66fb90051..b9efe51fc 100644 --- a/src/locale/zh_CN.js +++ b/src/locale/zh_CN.js @@ -9,8 +9,8 @@ export default { clear: '清除', month: '月', year: '年', - previousMonth: '上个月 (翻页上键)', - nextMonth: '下个月 (翻页下键)', + previousMonth: '上个月', + nextMonth: '下个月', monthSelect: '选择月份', yearSelect: '选择年份', decadeSelect: '选择年代', @@ -18,8 +18,8 @@ export default { dayFormat: 'D日', dateFormat: 'YYYY年M月D日', dateTimeFormat: 'YYYY年M月D日 HH时mm分ss秒', - previousYear: '上一年 (Control键加左方向键)', - nextYear: '下一年 (Control键加右方向键)', + previousYear: '上一年', + nextYear: '下一年', previousDecade: '上一年代', nextDecade: '下一年代', previousCentury: '上一世纪', diff --git a/src/locale/zh_TW.js b/src/locale/zh_TW.js index 208bdda0e..bc537cbfd 100644 --- a/src/locale/zh_TW.js +++ b/src/locale/zh_TW.js @@ -8,8 +8,8 @@ export default { clear: '清除', month: '月', year: '年', - previousMonth: '上個月 (翻頁上鍵)', - nextMonth: '下個月 (翻頁下鍵)', + previousMonth: '上個月', + nextMonth: '下個月', monthSelect: '選擇月份', yearSelect: '選擇年份', decadeSelect: '選擇年代', @@ -17,8 +17,8 @@ export default { dayFormat: 'D日', dateFormat: 'YYYY年M月D日', dateTimeFormat: 'YYYY年M月D日 HH時mm分ss秒', - previousYear: '上一年 (Control鍵加左方向鍵)', - nextYear: '下一年 (Control鍵加右方向鍵)', + previousYear: '上一年', + nextYear: '下一年', previousDecade: '上一年代', nextDecade: '下一年代', previousCentury: '上一世紀', diff --git a/src/util/platform.js b/src/util/platform.js deleted file mode 100644 index d0d385878..000000000 --- a/src/util/platform.js +++ /dev/null @@ -1,39 +0,0 @@ -// calendar/src/util/platform.js -export const isMac = () => { - return typeof navigator !== 'undefined' && - navigator.platform.toUpperCase().indexOf('MAC') >= 0; -}; - -export const getModifierSymbol = () => { - return isMac() ? '⌘' : 'Ctrl'; -}; - -// Enhance locale strings with platform-specific modifier keys -export const enhanceLocaleWithPlatformKeys = (locale) => { - if (!locale) return locale; - - const isMacOS = isMac(); - - // Don't modify if already correct platform or no modification needed - if (!isMacOS) return locale; - - const enhanced = { ...locale }; - - // Replace in relevant fields for Mac users - ['previousYear', 'nextYear', 'previousMonth', 'nextMonth'].forEach(key => { - if (enhanced[key] && typeof enhanced[key] === 'string') { - // Replace Chinese/Traditional Chinese pattern: Control键 -> Command键 - enhanced[key] = enhanced[key].replace(/Control键/g, 'Command键'); - - // Replace patterns with space: "Control + " or "Ctrl + " -> "⌘ + " - enhanced[key] = enhanced[key].replace(/Control \+/g, '⌘ +'); - enhanced[key] = enhanced[key].replace(/Ctrl \+/g, '⌘ +'); - - // Replace standalone Control/Ctrl without space (fallback) - enhanced[key] = enhanced[key].replace(/\bControl\b/g, 'Command'); - enhanced[key] = enhanced[key].replace(/\bCtrl\b/g, '⌘'); - } - }); - - return enhanced; -}; From 6e636856939eb9346f06a96ae6af4f37ff7bec81 Mon Sep 17 00:00:00 2001 From: Aries Date: Tue, 9 Dec 2025 18:08:32 +0800 Subject: [PATCH 67/68] chore: release 1.0.3 (#32) Co-authored-by: zhouwenxuan --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ed18ef4a4..8dfd13cbc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seafile/seafile-calendar", - "version": "1.0.3-beta.3", + "version": "1.0.3", "description": "React Calendar", "keywords": [ "react", From 586e8df7677167a15ab39c4809c0c45570a29f5b Mon Sep 17 00:00:00 2001 From: yinjianfei <1358009667@com> Date: Tue, 20 Jan 2026 11:13:39 +0800 Subject: [PATCH 68/68] feature add disable style --- assets/index/Calendar.less | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/assets/index/Calendar.less b/assets/index/Calendar.less index 8bf81c27a..4fb50fb22 100644 --- a/assets/index/Calendar.less +++ b/assets/index/Calendar.less @@ -173,7 +173,7 @@ /* Date grid area */ &-body { padding: 0 12px; - height: 240px; + height: 264px; } table { border-collapse: collapse; @@ -223,6 +223,7 @@ background: transparent; line-height: 32px; text-align: center; + margin-bottom: 4px; } &-date:hover { background: #f5f5f5; @@ -240,6 +241,18 @@ } &-disabled-cell &-date { cursor: not-allowed; + background: #f3f3f3; + border-radius: 0; + color: #bcbcbc; + width: auto; + } + &-disabled-cell-first-of-row &-date { + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; + } + &-disabled-cell-last-of-row &-date { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; } &-last-month-cell &-date, &-next-month-btn-day &-date { @@ -263,7 +276,7 @@ font-weight: 600; } &-right-panel-body { - height: 240px; + height: 264px; display: flex; padding: 0 4px 16px; scrollbar-color: auto;