@cainiaofe/cn-ui-m
Version:
264 lines (263 loc) • 13 kB
JavaScript
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 };