gui-one-nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
581 lines (580 loc) • 23.4 kB
JavaScript
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _regeneratorRuntime from "@babel/runtime/regenerator";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import React__default, { useState, useRef, useEffect } from 'react';
import classNames from 'classnames';
import { c as cn } from './bem-893ad28d.js';
import { u as useConfig } from './configprovider.taro-6c7b3056.js';
import { g as getRectByTaro } from './useClientRect-bf69d7b3.js';
var Utils = {
/**
* 是否为闫年
* @return {Boolse} true|false
*/
isLeapYear: function isLeapYear(y) {
return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
},
/**
* 返回星期数
* @return {String}
*/
getWhatDay: function getWhatDay(year, month, day) {
var date = new Date("".concat(year, "/").concat(month, "/").concat(day));
var index = date.getDay();
var dayNames = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
return dayNames[index];
},
/**
* 返回星期数
* @return {Number}
*/
getMonthPreDay: function getMonthPreDay(year, month) {
var date = new Date("".concat(year, "/").concat(month, "/01"));
var day = date.getDay();
if (day == 0) {
day = 7;
}
return day;
},
/**
* 返回月份天数
* @return {Number}
*/
getMonthDays: function getMonthDays(year, month) {
if (/^0/.test(month)) {
month = month.split('')[1];
}
return [0, 31, this.isLeapYear(Number(year)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
},
/**
* 补齐数字位数
* @return {string}
*/
getNumTwoBit: function getNumTwoBit(n) {
n = Number(n);
return (n > 9 ? '' : '0') + n;
},
/**
* 日期对象转成字符串
* @return {string}
*/
date2Str: function date2Str(date, split) {
split = split || '-';
var y = date.getFullYear();
var m = this.getNumTwoBit(date.getMonth() + 1);
var d = this.getNumTwoBit(date.getDate());
return [y, m, d].join(split);
},
/**
* 返回日期格式字符串
* @param {Number} 0返回今天的日期、1返回明天的日期,2返回后天得日期,依次类推
* @return {string} '2014-12-31'
*/
getDay: function getDay(i) {
i = i || 0;
var date = new Date();
var diff = i * (1000 * 60 * 60 * 24);
date = new Date(date.getTime() + diff);
return this.date2Str(date);
},
/**
* 时间比较
* @return {Boolean}
*/
compareDate: function compareDate(date1, date2) {
var startTime = new Date(date1.replace('-', '/').replace('-', '/'));
var endTime = new Date(date2.replace('-', '/').replace('-', '/'));
if (startTime >= endTime) {
return false;
}
return true;
},
/**
* 时间是否相等
* @return {Boolean}
*/
isEqual: function isEqual(date1, date2) {
var startTime = new Date(date1).getTime();
var endTime = new Date(date2).getTime();
if (startTime == endTime) {
return true;
}
return false;
}
};
function requestAniFrame() {
if (typeof window !== 'undefined') {
return window.requestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
}
return function (callback) {
setTimeout(callback, 1000 / 60);
};
}
var requestAniFrame$1 = requestAniFrame();
var defaultProps = {
type: 'one',
isAutoBackFill: false,
poppable: true,
visible: false,
title: '日历选择',
defaultValue: '',
startDate: Utils.getDay(0),
endDate: Utils.getDay(365),
onChoose: function onChoose(data) {},
onUpdate: function onUpdate() {},
onClose: function onClose() {}
};
var CalendarItem = function CalendarItem(props) {
var _classNames, _classNames2;
var _useConfig = useConfig(),
locale = _useConfig.locale;
var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props),
type = _defaultProps$props.type,
isAutoBackFill = _defaultProps$props.isAutoBackFill,
poppable = _defaultProps$props.poppable,
title = _defaultProps$props.title,
defaultValue = _defaultProps$props.defaultValue,
startDate = _defaultProps$props.startDate,
endDate = _defaultProps$props.endDate,
onChoose = _defaultProps$props.onChoose,
onUpdate = _defaultProps$props.onUpdate,
onClose = _defaultProps$props.onClose;
var weeks = locale.calendaritem.weekdays;
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
yearMonthTitle = _useState2[0],
setYearMonthTitle = _useState2[1];
var _useState3 = useState(false),
_useState4 = _slicedToArray(_useState3, 2),
unLoadPrev = _useState4[0],
setUnLoadPrev = _useState4[1];
var _useState5 = useState([]),
_useState6 = _slicedToArray(_useState5, 2),
monthsData = _useState6[0],
setMonthsData = _useState6[1];
var _useState7 = useState({
currDate: '',
touchParams: {
startY: 0,
endY: 0,
startTime: 0,
endTime: 0,
lastY: 0,
lastTime: 0
},
transformY: 0,
translateY: 0,
scrollDistance: 0,
defaultData: [],
chooseData: [],
monthsData: [],
dayPrefix: 'calendar-month-day',
startData: '',
endData: '',
isRange: type === 'range',
timer: 0
}),
_useState8 = _slicedToArray(_useState7, 1),
state = _useState8[0];
var weeksPanel = useRef(null);
var months = useRef(null);
var monthsPanel = useRef(null);
var b = cn('calendar');
var classes = classNames((_classNames = {}, _defineProperty(_classNames, "".concat(b(''), "-tile"), !poppable), _defineProperty(_classNames, "".concat(b(''), "-nofooter"), !!isAutoBackFill), _classNames), b(''));
var headerClasses = classNames((_classNames2 = {}, _defineProperty(_classNames2, "".concat(b(''), "-header"), true), _defineProperty(_classNames2, "".concat(b(''), "-header-tile"), !poppable), _classNames2));
var monthitemclasses = classNames(_defineProperty({
'calendar-month-item': true
}, "".concat(type === 'range' ? 'month-item-range' : ''), true));
var splitDate = function splitDate(date) {
return date.split('-');
};
var isStart = function isStart(currDate) {
return Utils.isEqual(state.currDate[0], currDate);
};
var isEnd = function isEnd(currDate) {
return Utils.isEqual(state.currDate[1], currDate);
};
var getCurrDate = function getCurrDate(day, month, isRange) {
return isRange ? "".concat(month.curData[3], "-").concat(month.curData[4], "-").concat(Utils.getNumTwoBit(+day.day)) : "".concat(month.curData[0], "-").concat(month.curData[1], "-").concat(Utils.getNumTwoBit(+day.day));
};
var getClass = function getClass(day, month, isRange) {
var currDate = getCurrDate(day, month, isRange);
if (day.type === 'curr') {
if (!state.isRange && Utils.isEqual(state.currDate, currDate) || state.isRange && (isStart(currDate) || isEnd(currDate))) {
return "".concat(state.dayPrefix, "-active");
}
if (startDate && Utils.compareDate(currDate, startDate) || endDate && Utils.compareDate(endDate, currDate)) {
return "".concat(state.dayPrefix, "-disabled");
}
if (state.isRange && Array.isArray(state.currDate) && Object.values(state.currDate).length === 2 && Utils.compareDate(state.currDate[0], currDate) && Utils.compareDate(currDate, state.currDate[1])) {
return "".concat(state.dayPrefix, "-choose");
}
return null;
}
return "".concat(state.dayPrefix, "-disabled");
};
var isActive = function isActive(day, month) {
return state.isRange && day.type === 'curr' && getClass(day, month) === 'calendar-month-day-active';
};
var isCurrDay = function isCurrDay(month, day) {
var date = "".concat(month.curData[0], "-").concat(month.curData[1], "-").concat(day);
return Utils.isEqual(date, Utils.date2Str(new Date()));
};
var confirm = function confirm() {
if (state.isRange && state.chooseData.length === 2 || !state.isRange) {
onChoose && onChoose(state.chooseData);
if (poppable) {
onUpdate && onUpdate();
}
}
};
var chooseDay = function chooseDay(day, month, isFirst, isRange) {
if (getClass(day, month, isRange) !== "".concat(state.dayPrefix, "-disabled")) {
var days = _toConsumableArray(month.curData);
days = isRange ? days.splice(3) : days.splice(0, 3);
days[2] = typeof day.day === 'number' ? Utils.getNumTwoBit(day.day) : day.day;
days[3] = "".concat(days[0], "-").concat(days[1], "-").concat(days[2]);
days[4] = Utils.getWhatDay(+days[0], +days[1], +days[2]);
if (!state.isRange) {
state.currDate = days[3];
state.chooseData = _toConsumableArray(days);
} else {
if (Object.values(state.currDate).length === 2) {
state.currDate = [days[3]];
} else if (Utils.compareDate(state.currDate[0], days[3])) {
Array.isArray(state.currDate) && state.currDate.push(days[3]);
} else {
Array.isArray(state.currDate) && state.currDate.unshift(days[3]);
}
if (state.chooseData.length === 2 || !state.chooseData.length) {
state.chooseData = _toConsumableArray(days);
} else if (Utils.compareDate(state.chooseData[3], days[3])) {
state.chooseData = [_toConsumableArray(state.chooseData), _toConsumableArray(days)];
} else {
state.chooseData = [_toConsumableArray(days), _toConsumableArray(state.chooseData)];
}
}
if (isAutoBackFill && !isFirst) {
confirm();
}
setMonthsData(state.monthsData.slice());
}
};
var isStartTip = function isStartTip(day, month) {
if (isActive(day, month)) {
return isStart(getCurrDate(day, month));
}
return false;
};
// 是否有结束提示
var isEndTip = function isEndTip(day, month) {
if (isStartTip(day, month)) {
return false;
}
return isActive(day, month);
};
// 获取当前月数据
var getCurrData = function getCurrData(type) {
var monthData = type === 'prev' ? state.monthsData[0] : state.monthsData[state.monthsData.length - 1];
var year = parseInt(monthData.curData[0]);
var month = parseInt(monthData.curData[1].toString().replace(/^0/, ''));
switch (type) {
case 'prev':
month === 1 && (year -= 1);
month = month === 1 ? 12 : --month;
break;
case 'next':
month === 12 && (year += 1);
month = month === 12 ? 1 : ++month;
break;
}
return [year, Utils.getNumTwoBit(month), Utils.getMonthDays(String(year), String(month))];
};
// 获取日期状态
var getDaysStatus = function getDaysStatus(days, type) {
// 修复:当某个月的1号是周日时,月份下方会空出来一行
if (type === 'prev' && days >= 7) {
days -= 7;
}
return Array.from(Array(days), function (v, k) {
return {
day: k + 1,
type: type
};
});
};
// 获取月数据
var getMonth = function getMonth(curData, type) {
var preMonthDays = Utils.getMonthPreDay(+curData[0], +curData[1]);
var currMonthDays = Utils.getMonthDays(curData[0], curData[1]);
var title = {
year: curData[0],
month: curData[1]
};
var monthInfo = {
curData: curData,
title: locale.calendaritem.monthTitle(title.year, title.month),
monthData: [].concat(_toConsumableArray(getDaysStatus(preMonthDays, 'prev')), _toConsumableArray(getDaysStatus(currMonthDays, 'curr')))
};
if (type === 'next') {
if (!state.endData || !Utils.compareDate("".concat(state.endData[0], "-").concat(state.endData[1], "-").concat(Utils.getMonthDays(state.endData[0], state.endData[1])), "".concat(curData[0], "-").concat(curData[1], "-").concat(curData[2]))) {
state.monthsData.push(monthInfo);
}
} else if (!state.startData || !Utils.compareDate("".concat(curData[0], "-").concat(curData[1], "-").concat(curData[2]), "".concat(state.startData[0], "-").concat(state.startData[1], "-01"))) {
state.monthsData.unshift(monthInfo);
} else {
setUnLoadPrev(true);
}
setMonthsData(state.monthsData);
};
// 监听月份滚动,改变月份标题
var loadScroll = function loadScroll() {
if (!props.poppable) {
return false;
}
requestAniFrame$1( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var weeksPanelRes, monthsDoms, i;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(weeksPanel !== null && weeksPanel !== void 0 && weeksPanel.current && monthsPanel !== null && monthsPanel !== void 0 && monthsPanel.current)) {
_context.next = 7;
break;
}
_context.next = 3;
return getRectByTaro(weeksPanel === null || weeksPanel === void 0 ? void 0 : weeksPanel.current);
case 3:
weeksPanelRes = _context.sent;
weeksPanelRes === null || weeksPanelRes === void 0 ? void 0 : weeksPanelRes.bottom;
monthsDoms = monthsPanel.current.getElementsByClassName('calendar-month');
for (i = 0; i < monthsDoms.length; i++) {}
case 7:
case "end":
return _context.stop();
}
}
}, _callee);
})));
};
// 设置月份滚动距离和速度
var setTransform = function setTransform() {
var translateY = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var type = arguments.length > 1 ? arguments[1] : undefined;
var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
if (monthsPanel !== null && monthsPanel !== void 0 && monthsPanel.current) {
if (type === 'end') {
monthsPanel.current.style.webkitTransition = "transform ".concat(time, "ms cubic-bezier(0.19, 1, 0.22, 1)");
clearTimeout(state.timer);
state.timer = setTimeout(function () {
loadScroll();
}, time);
} else {
monthsPanel.current.style.webkitTransition = '';
loadScroll();
}
monthsPanel.current.style.webkitTransform = "translateY(".concat(translateY, "px)");
state.scrollDistance = translateY;
}
};
// 计算滚动方向和距离
var setMove = function setMove(move, type, time) {
var _months$current, _monthsPanel$current;
var updateMove = move + state.transformY;
var h = ((_months$current = months.current) === null || _months$current === void 0 ? void 0 : _months$current.offsetHeight) || 0;
var offsetHeight = ((_monthsPanel$current = monthsPanel.current) === null || _monthsPanel$current === void 0 ? void 0 : _monthsPanel$current.offsetHeight) || 0;
if (type === 'end') {
// 限定滚动距离
if (updateMove > 0) {
updateMove = 0;
}
if (updateMove < 0 && updateMove < -offsetHeight + h) {
updateMove = -offsetHeight + h;
}
if (offsetHeight <= h && state.monthsData.length === 1) {
updateMove = 0;
}
setTransform(updateMove, type, time);
} else {
if (updateMove > 0 && updateMove > 100) {
updateMove = 100;
}
if (updateMove < -offsetHeight + h - 100 && state.monthsData.length > 1) {
updateMove = -offsetHeight + h - 100;
}
if (updateMove < 0 && updateMove < -100 && state.monthsData.length === 1) {
updateMove = -100;
}
setTransform(updateMove);
}
};
var onTouchStart = function onTouchStart(event) {
event.stopPropagation();
var changedTouches = event.changedTouches[0];
state.touchParams.startY = changedTouches.pageY;
state.touchParams.startTime = event.timeStamp || Date.now();
state.transformY = state.scrollDistance;
};
var onTouchMove = function onTouchMove(event) {
event.stopPropagation();
var changedTouches = event.changedTouches[0];
state.touchParams.lastY = changedTouches.pageY;
state.touchParams.lastTime = event.timeStamp || Date.now();
var move = state.touchParams.lastY - state.touchParams.startY;
if (Math.abs(move) < 5) {
return false;
}
setMove(move);
};
var onTouchEnd = function onTouchEnd(event) {
var _months$current2, _monthsPanel$current2;
event.stopPropagation();
var changedTouches = event.changedTouches[0];
state.touchParams.lastY = changedTouches.pageY;
state.touchParams.lastTime = event.timeStamp || Date.now();
var move = state.touchParams.lastY - state.touchParams.startY;
if (Math.abs(move) < 5) {
return false;
}
var updateMove = move + state.transformY;
var h = ((_months$current2 = months.current) === null || _months$current2 === void 0 ? void 0 : _months$current2.offsetHeight) || 0;
var offsetHeight = ((_monthsPanel$current2 = monthsPanel.current) === null || _monthsPanel$current2 === void 0 ? void 0 : _monthsPanel$current2.offsetHeight) || 0;
if (updateMove > 0) {
getMonth(getCurrData('prev'), 'prev');
} else if (updateMove < 0 && updateMove < -offsetHeight + (Math.abs(move) > h ? Math.abs(move) : h) * 5) {
getMonth(getCurrData('next'), 'next');
if (Math.abs(move) >= 300) {
getMonth(getCurrData('next'), 'next');
}
}
var moveTime = state.touchParams.lastTime - state.touchParams.startTime;
if (moveTime <= 300) {
move *= 2;
moveTime += 1000;
setMove(move, 'end', moveTime);
} else {
setMove(move, 'end');
}
};
var initData = function initData() {
// 初始化开始结束数据
state.startData = startDate ? splitDate(startDate) : '';
state.endData = endDate ? splitDate(endDate) : '';
// 初始化当前日期
if (!defaultValue) {
state.currDate = state.isRange ? [Utils.date2Str(new Date()), Utils.getDay(1)] : Utils.date2Str(new Date());
} else {
state.currDate = state.isRange ? _toConsumableArray(defaultValue) : defaultValue;
}
// 日期转化为数组
if (state.isRange && Array.isArray(state.currDate)) {
if (startDate && Utils.compareDate(state.currDate[0], startDate)) {
state.currDate.splice(0, 1, startDate);
}
if (endDate && Utils.compareDate(endDate, state.currDate[1])) {
state.currDate.splice(1, 1, endDate);
}
state.defaultData = [].concat(_toConsumableArray(splitDate(state.currDate[0])), _toConsumableArray(splitDate(state.currDate[1])));
} else {
if (startDate && Utils.compareDate(state.currDate, startDate)) {
state.currDate = startDate;
} else if (endDate && !Utils.compareDate(state.currDate, endDate)) {
state.currDate = endDate;
}
state.defaultData = _toConsumableArray(splitDate(state.currDate));
}
getMonth(state.defaultData, 'next');
setYearMonthTitle(state.monthsData[0].title);
var i = 1;
do {
getMonth(getCurrData('next'), 'next');
} while (i++ < 4);
if (state.isRange) {
chooseDay({
day: state.defaultData[2],
type: 'curr'
}, state.monthsData[0], true);
chooseDay({
day: state.defaultData[5],
type: 'curr'
}, state.monthsData[0], true, true);
} else {
chooseDay({
day: state.defaultData[2],
type: 'curr'
}, state.monthsData[0], true);
}
};
useEffect(function () {
initData();
}, []);
return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
className: classes
}, React__default.createElement("div", {
className: headerClasses
}, poppable ? React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
className: "calendar-title"
}, locale.calendaritem.title), React__default.createElement("div", {
className: "calendar-curr-month"
}, yearMonthTitle)) : '', React__default.createElement("div", {
className: "calendar-weeks",
ref: weeksPanel
}, weeks.map(function (item) {
return React__default.createElement("div", {
className: "calendar-week-item",
key: item
}, item);
}))), React__default.createElement("div", {
className: "nut-calendar-content",
onTouchStart: onTouchStart,
onTouchMove: onTouchMove,
onTouchEnd: onTouchEnd,
ref: months
}, React__default.createElement("div", {
className: "calendar-months-panel",
ref: monthsPanel
}, React__default.createElement("div", {
className: "calendar-loading-tip"
}, !unLoadPrev ? locale.calendaritem.loadPreviousMonth : locale.calendaritem.noEarlierMonth), monthsData.map(function (month, key) {
return React__default.createElement("div", {
className: "calendar-month",
key: key
}, React__default.createElement("div", {
className: "calendar-month-title"
}, month.title), React__default.createElement("div", {
className: "calendar-month-con"
}, React__default.createElement("div", {
className: monthitemclasses
}, month.monthData && month.monthData.map(function (day, index) {
return React__default.createElement("div", {
className: ['calendar-month-day', getClass(day, month)].join(' '),
key: index,
onClick: function onClick() {
chooseDay(day, month);
}
}, React__default.createElement("div", {
className: "calendar-day"
}, day.type === 'curr' ? day.day : ''), isCurrDay(month, day.day) ? React__default.createElement("div", {
className: "calendar-curr-tip-curr"
}, locale.calendaritem.today) : '', isStartTip(day, month) ? React__default.createElement("div", {
className: "calendar-day-tip"
}, locale.calendaritem.start) : '', isEndTip(day, month) ? React__default.createElement("div", {
className: "calendar-day-tip"
}, locale.calendaritem.end) : '');
}))));
}))), poppable && !isAutoBackFill ? React__default.createElement("div", {
className: "nut-calendar-footer"
}, React__default.createElement("div", {
className: "calendar-confirm-btn",
onClick: confirm
}, locale.confirm)) : ''));
};
CalendarItem.defaultProps = defaultProps;
CalendarItem.displayName = 'NutCalendarItem';
export { CalendarItem as C, Utils as U };