UNPKG

@cainiaofe/cn-ui-m

Version:
264 lines (263 loc) 13 kB
import { __assign } from "tslib"; import $i18n from "../../locales/i18n"; import React, { forwardRef, useState, useImperativeHandle, useMemo, } from 'react'; import { withNativeProps } from "../../utils/with-native-props"; import dayjs from 'dayjs'; import classNames from 'classnames'; import cloneDeep from 'lodash/cloneDeep'; import { mergeProps } from "../../utils/with-default-props"; import { ArrowLeft } from './arrow-left'; import { ArrowLeftDouble } from './arrow-left-double'; // import { useConfig } from './config-provider'; import { useUpdateEffect } from 'ahooks'; import { usePropsValue } from "../../utils/use-props-value"; import { convertValueToRange, convertPageToDayjs, } from './convert'; import CalendarTimePicker from './time-picker'; import { getRangeValid } from './utils/get-range-valid'; var classPrefix = 'cn-ui-m-calendar'; var renderYearAndMonth = function (year, month) { return $i18n.get({ id: 'YearMonth', dm: '{year}年{month}月', }, { year: year, month: month }); }; var defaultProps = { weekStartsOn: 'Sunday', defaultValue: null, allowClear: true, prevMonthButton: React.createElement(ArrowLeft, null), prevYearButton: React.createElement(ArrowLeftDouble, null), nextMonthButton: React.createElement(ArrowLeft, null), nextYearButton: React.createElement(ArrowLeftDouble, null), panelMode: 'date', }; var firstDayOfWeek = dayjs.localeData().firstDayOfWeek(); var Calendar = forwardRef(function (p, ref) { var today = dayjs(); var props = mergeProps(defaultProps, p); // const { locale } = useConfig(); // TODO 已挪走自添加结构 // const markItems = [...locale.Calendar.markItems]; var markItems = cloneDeep(dayjs.weekdaysMin()); if (props.weekStartsOn === 'Monday' || firstDayOfWeek === 1) { var item = markItems.shift(); if (item) markItems.push(item); } var _a = usePropsValue({ value: props.value === undefined ? undefined : convertValueToRange(props.selectionMode, props.value), defaultValue: convertValueToRange(props.selectionMode, props.defaultValue), onChange: function (v) { var _a, _b, _c; if (props.selectionMode === 'single') { (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v ? v[0] : null); } else if (props.selectionMode === 'range' && props.panelMode === 'date') { (_b = props.onChange) === null || _b === void 0 ? void 0 : _b.call(props, v); } else if (props.selectionMode === 'range' && props.panelMode === 'week') { var weekStr = (v === null || v === void 0 ? void 0 : v.map(function (date) { var weekTime = dayjs(date); if (weekTime.isValid()) { return weekTime.format('gggg-wo'); } return null; })) || null; (_c = props.onChange) === null || _c === void 0 ? void 0 : _c.call(props, v, weekStr); } }, }), dateRange = _a[0], setDateRange = _a[1]; var _b = useState(false), intermediate = _b[0], setIntermediate = _b[1]; var _c = useState(function () { var initialDate; if (dateRange && dateRange[0] && dayjs(dateRange[0]).isValid()) { initialDate = dateRange[0]; } else { initialDate = today; } return dayjs(initialDate).date(1); }), current = _c[0], setCurrent = _c[1]; useUpdateEffect(function () { var _a; (_a = props.onPageChange) === null || _a === void 0 ? void 0 : _a.call(props, current.year(), current.month() + 1); }, [current]); useImperativeHandle(ref, function () { return ({ jumpTo: function (pageOrPageGenerator) { var page; if (typeof pageOrPageGenerator === 'function') { page = pageOrPageGenerator({ year: current.year(), month: current.month() + 1, }); } else { page = pageOrPageGenerator; } setCurrent(convertPageToDayjs(page)); }, jumpToToday: function () { setCurrent(dayjs().date(1)); }, }); }); var handlePageChange = function (action, num, type) { var nxtCurrent = current[action](num, type); if (action === 'subtract' && props.minPage) { var minPage = convertPageToDayjs(props.minPage); if (nxtCurrent.isBefore(minPage, type)) { return; } } if (action === 'add' && props.maxPage) { var maxPage = convertPageToDayjs(props.maxPage); if (nxtCurrent.isAfter(maxPage, type)) { return; } } setCurrent(current[action](num, type)); }; var header = (React.createElement("div", { className: "".concat(classPrefix, "-header") }, React.createElement("a", { className: "".concat(classPrefix, "-arrow-button ").concat(classPrefix, "-arrow-button-year"), onClick: function () { handlePageChange('subtract', 1, 'year'); } }, props.prevYearButton), React.createElement("a", { className: "".concat(classPrefix, "-arrow-button ").concat(classPrefix, "-arrow-button-month"), onClick: function () { handlePageChange('subtract', 1, 'month'); } }, props.prevMonthButton), React.createElement("div", { className: "".concat(classPrefix, "-title") }, renderYearAndMonth(current.year(), current.month() + 1)), React.createElement("a", { className: classNames("".concat(classPrefix, "-arrow-button"), "".concat(classPrefix, "-arrow-button-right"), "".concat(classPrefix, "-arrow-button-right-month")), onClick: function () { handlePageChange('add', 1, 'month'); } }, props.nextMonthButton), React.createElement("a", { className: classNames("".concat(classPrefix, "-arrow-button"), "".concat(classPrefix, "-arrow-button-right"), "".concat(classPrefix, "-arrow-button-right-year")), onClick: function () { handlePageChange('add', 1, 'year'); } }, props.nextYearButton))); var maxDay = useMemo(function () { return props.max && dayjs(props.max); }, [props.max]); var minDay = useMemo(function () { return props.min && dayjs(props.min); }, [props.min]); function renderCells() { var _a, _b; var cells = []; var iterator = current.subtract(current.isoWeekday(), 'day'); if (props.weekStartsOn === 'Monday' || firstDayOfWeek === 1) { iterator = iterator.add(1, 'day'); } var _loop_1 = function () { var _c; var d = iterator; var isSelect = false; var isBegin = false; var isEnd = false; if (dateRange) { var begin = dateRange[0], end = dateRange[1]; if (props.panelMode === 'week') { var beginStart = dayjs(begin).isoWeekday(1); var beginLast = dayjs(begin).isoWeekday(7); var endStart = dayjs(end).isoWeekday(1); var endLast = dayjs(end).isoWeekday(7); isBegin = d.isSame(beginStart, 'day') || d.isSame(endStart, 'day'); isEnd = d.isSame(beginLast, 'day') || d.isSame(endLast, 'day'); isSelect = isBegin || isEnd || (d.isAfter(beginStart, 'day') && d.isBefore(beginLast, 'day')) || (d.isAfter(beginLast, 'day') && d.isBefore(endStart, 'day')) || (d.isAfter(endStart, 'day') && d.isBefore(endLast, 'day')); } else if (props.panelMode === 'date') { isBegin = d.isSame(begin, 'day'); isEnd = d.isSame(end, 'day'); isSelect = isBegin || isEnd || (d.isAfter(begin, 'day') && d.isBefore(end, 'day')); } } var inThisMonth = d.month() === current.month(); var disabled = props.disabledDate ? props.disabledDate(d.toDate(), 'date') : (maxDay && d.isAfter(maxDay, 'day')) || (minDay && d.isBefore(minDay, 'day')); cells.push(React.createElement("div", { key: d.valueOf(), className: classNames("".concat(classPrefix, "-cell"), (disabled || !inThisMonth) && "".concat(classPrefix, "-cell-disabled"), inThisMonth && (_c = {}, _c["".concat(classPrefix, "-cell-today")] = d.isSame(today, 'day'), _c["".concat(classPrefix, "-cell-selected")] = isSelect, _c["".concat(classPrefix, "-cell-selected-begin")] = isBegin, _c["".concat(classPrefix, "-cell-selected-end")] = isEnd, _c["".concat(classPrefix, "-cell-selected-end-range")] = isSelect && isEnd && props.selectionMode === 'range' && getRangeValid(dateRange), _c)), onClick: function () { if (!props.selectionMode) return; if (disabled) return; var date = d.toDate(); if (!inThisMonth) { setCurrent(d.clone().date(1)); } function shouldClear() { if (!props.allowClear) return false; if (!dateRange) return false; var begin = dateRange[0], end = dateRange[1]; return d.isSame(begin, 'date') && d.isSame(end, 'day'); } if (props.selectionMode === 'single') { if (props.allowClear && shouldClear()) { setDateRange(null); return; } setDateRange([date, date]); } else if (props.selectionMode === 'range') { if (!dateRange) { setDateRange([date, date]); setIntermediate(true); return; } if (shouldClear()) { setDateRange(null); setIntermediate(false); return; } if (intermediate) { var another = dateRange[0]; setDateRange(another > date ? [date, another] : [another, date]); setIntermediate(false); } else { setDateRange([date, date]); setIntermediate(true); } } } }, React.createElement("div", { className: "".concat(classPrefix, "-cell-top") }, props.renderDate ? (_a = props.renderDate) === null || _a === void 0 ? void 0 : _a.call(props, d.toDate()) : d.date()), React.createElement("div", { className: "".concat(classPrefix, "-cell-bottom") }, (_b = props.renderLabel) === null || _b === void 0 ? void 0 : _b.call(props, d.toDate())))); iterator = iterator.add(1, 'day'); }; while (cells.length < 6 * 7) { _loop_1(); } return cells; } var body = React.createElement("div", { className: "".concat(classPrefix, "-cells") }, renderCells()); var mark = (React.createElement("div", { className: "".concat(classPrefix, "-mark") }, markItems.map(function (item, index) { return (React.createElement("div", { key: index, className: "".concat(classPrefix, "-mark-cell") }, item)); }))); var time = null; if (props.showTime) { time = (React.createElement(CalendarTimePicker, __assign({}, props.timePanelProps, { label: $i18n.get({ id: 'Time', dm: '时间' }), prefix: classPrefix, value: dateRange ? dateRange[0] : today.toDate(), onChange: function (date) { var _a; (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, date); } }))); } return withNativeProps(props, React.createElement("div", { className: classNames(CN_UI_HASH_CLASS_NAME, classPrefix) }, header, mark, body, time)); }); var CnCalendar = Calendar; CnCalendar.displayName = 'CnCalendar'; export { CnCalendar };