UNPKG

gui-one-nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

581 lines (580 loc) 23.4 kB
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 };