@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
318 lines (317 loc) • 13.8 kB
JavaScript
import React__default, { useState, useRef, useEffect } from "react";
import { P as Popup } from "./popup.taro-JynjcLCn.js";
import { s as splitDate, g as getPreMonths, a as getMonths, b as getPreQuarters, c as getQuarters, d as getNextQuarters, C as CalendarItem } from "./calendaritem.taro-B0QA0q4N.js";
import classNames from "classnames";
import Taro from "@tarojs/taro";
import { View, ScrollView } from "@tarojs/components";
import { C as ComponentDefaults } from "./typings-DV9RBfhj.js";
import { g as getDateString } from "./date-C7eJqrqk.js";
import { r as requestAniFrame } from "./raf-Di10dXPS.js";
import { useConfig } from "./ConfigProvider.js";
import { u as usePropsValue } from "./use-props-value-SH9krhkx.js";
import { u as useConfig$1 } from "./configprovider.taro-DpK4IiCE.js";
const YearMonthPanelHeight = 231;
const YearQuarterPanelHeight = 103;
const defaultProps$1 = Object.assign(Object.assign({}, ComponentDefaults), { type: "single", viewMode: "month", title: "", startDate: getDateString(0), endDate: getDateString(365), showToday: true, showTitle: true, scrollAnimation: true, renderDay: void 0, onItemClick: () => {
} });
const CalendarViewModeItem = React__default.forwardRef((props) => {
const { locale } = useConfig();
const { style, className, viewMode, title, value, defaultValue, startDate, endDate, showTitle, renderDay, onItemClick } = Object.assign(Object.assign({}, defaultProps$1), props);
const classPrefix = "nut-calendar-viewmode";
const [panelDate, setPanelDate] = useState({
months: [
{
year: (/* @__PURE__ */ new Date()).getFullYear(),
months: [],
cssHeight: 0,
scrollTop: 0,
currYear: false
}
],
quarters: [
{
year: (/* @__PURE__ */ new Date()).getFullYear(),
quarters: [],
cssHeight: 0,
scrollTop: 0,
currYear: false
}
]
});
const [scrollTop, setScrollTop] = useState(0);
const propStartDate = startDate || getDateString(0);
const propEndDate = endDate || getDateString(365);
const startDates = splitDate(propStartDate);
const endDates = splitDate(propEndDate);
const [innerValue, setInnerValue] = usePropsValue({
value,
defaultValue,
finalValue: [],
onChange: (val) => {
}
});
const monthsRef = useRef(null);
const monthsPanel = useRef(null);
const viewAreaRef = useRef(null);
const getMonthsPanel = () => {
return monthsPanel.current;
};
const getMonthsRef = () => {
return monthsRef.current;
};
const requestAniFrameFunc = (viewMode2) => {
switch (viewMode2) {
case "month":
{
const lastItem = panelDate.months[panelDate.months.length - 1];
const containerHeight = lastItem.cssHeight + lastItem.scrollTop;
const currentIndex = panelDate.months.findIndex((item) => item.currYear === true);
requestAniFrame(() => {
var _a;
if (monthsRef && monthsPanel && viewAreaRef) {
getMonthsRef().clientHeight;
getMonthsPanel().style.height = `${containerHeight}px`;
const currTop = ((_a = panelDate.months[currentIndex]) === null || _a === void 0 ? void 0 : _a.scrollTop) || 0;
getMonthsRef().scrollTop = currTop;
setScrollTop(currTop);
}
});
}
break;
case "quarter":
{
const lastItem = panelDate.quarters[panelDate.quarters.length - 1];
const containerHeight = lastItem.cssHeight + lastItem.scrollTop;
const currentIndex = panelDate.quarters.findIndex((item) => item.currYear === true);
requestAniFrame(() => {
var _a;
if (monthsRef && monthsPanel && viewAreaRef) {
getMonthsRef().clientHeight;
getMonthsPanel().style.height = `${containerHeight}px`;
const currTop = ((_a = panelDate.quarters[currentIndex]) === null || _a === void 0 ? void 0 : _a.scrollTop) || 0;
getMonthsRef().scrollTop = currTop;
setScrollTop(currTop);
}
});
}
break;
}
};
const isCurrYear = (year) => {
return innerValue.split("-")[0] === `${year}`;
};
const getMonthsData = () => {
const startYear = Number(startDates[0]);
const startMonth = Number(startDates[1]);
const endYear = Number(endDates[0]);
const endMonth = Number(endDates[1]);
const panelData = [];
const addPanelData = (year, months, scrollTop2) => {
panelData.push({
year,
months,
scrollTop: scrollTop2,
cssHeight: YearMonthPanelHeight,
currYear: isCurrYear(year)
});
};
if (startYear === endYear) {
addPanelData(startYear, [
...getPreMonths("prev", startYear, startMonth),
...getMonths("curr", startYear, startMonth, endMonth),
...getMonths("next", endYear, endMonth + 1)
], 0);
} else {
let scrollTop2 = panelData.length * YearMonthPanelHeight;
const startMonths = [
...getPreMonths("prev", startYear, startMonth),
...getMonths("curr", startYear, startMonth)
];
addPanelData(startYear, startMonths, scrollTop2);
for (let i = startYear + 1; i < endYear; i++) {
scrollTop2 = panelData.length * YearMonthPanelHeight;
const midMonths = [...getMonths("curr", i, 1)];
addPanelData(i, midMonths, scrollTop2);
}
const lastMonths = [
...getPreMonths("curr", endYear, endMonth + 1),
...getMonths("next", endYear, endMonth + 1)
];
scrollTop2 = panelData.length * YearMonthPanelHeight;
addPanelData(endYear, lastMonths, scrollTop2);
}
return panelData;
};
const getQuartersData = () => {
const startYear = Number(startDates[0]);
const startMonth = Number(startDates[1]);
const endYear = Number(endDates[0]);
const endMonth = Number(endDates[1]);
const panelData = [];
const addPanelData = (year, quarters, scrollTop2) => {
panelData.push({
year,
quarters,
scrollTop: scrollTop2,
cssHeight: YearQuarterPanelHeight,
currYear: isCurrYear(year)
});
};
if (startYear === endYear) {
const quarters = [
...getPreQuarters("prev", startYear, startMonth),
...getQuarters("curr", startYear, startMonth, endMonth),
...getNextQuarters("next", endYear, endMonth)
];
addPanelData(startYear, quarters, 0);
} else {
let scrollTop2 = panelData.length * YearQuarterPanelHeight;
const startQuarters = [
...getPreQuarters("prev", startYear, startMonth),
...getQuarters("curr", startYear, startMonth)
];
addPanelData(startYear, startQuarters, scrollTop2);
for (let i = startYear + 1; i < endYear; i++) {
scrollTop2 = panelData.length * YearQuarterPanelHeight;
const midQuarters = [...getQuarters("curr", i, 1)];
addPanelData(i, midQuarters, scrollTop2);
}
const lastQuarters = [
...getQuarters("curr", endYear, 1, endMonth),
...getNextQuarters("next", endYear, endMonth)
];
scrollTop2 = panelData.length * YearQuarterPanelHeight;
addPanelData(endYear, lastQuarters, scrollTop2);
}
return panelData;
};
const initData = () => {
const data = (
// eslint-disable-next-line no-nested-ternary
viewMode === "month" ? getMonthsData() : viewMode === "quarter" ? getQuartersData() : null
);
setPanelDate(Object.assign(Object.assign({}, panelDate), { [`${viewMode}s`]: data }));
};
useEffect(() => {
requestAniFrameFunc(viewMode);
}, [panelDate]);
useEffect(() => {
initData();
}, []);
const monthsViewScroll = (e) => {
const scrollTop2 = e.target.scrollTop;
Taro.getEnv() === "WEB" && setScrollTop(scrollTop2);
};
const handleItemClick = (viewMode2, item) => {
if (item.type !== "curr")
return;
const val = viewMode2 === "month" ? item.yearAndMonth : item.yearAndQuarter;
setInnerValue(val);
onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick(val);
};
const isDisable = (item) => {
return item.type === "prev" || item.type === "next";
};
const isActive = (item) => {
const val = viewMode === "month" ? item.yearAndMonth : item.yearAndQuarter;
return val === innerValue;
};
const getClasses = (item) => {
if (isDisable(item)) {
return ["disabled"];
}
const res = [];
if (item.type === "curr") {
if (isActive(item)) {
res.push("active");
}
}
return res;
};
const classes = classNames(classPrefix, className);
const renderHeader = () => {
return showTitle && React__default.createElement(
View,
{ className: classNames({
[`${classPrefix}-header`]: true
}) },
React__default.createElement(View, { className: `${classPrefix}-title` }, title)
);
};
const renderItem = (item, index) => {
const units = {
month: locale.calendaritem.month,
quarter: locale.calendaritem.quarter
};
return React__default.createElement(
"div",
{ className: classNames(`${classPrefix}-item`, item.type, getClasses(item)), onClick: () => handleItemClick(viewMode, item), key: index },
React__default.createElement("div", { className: `${classPrefix}-item-${item.type}` }, renderDay ? renderDay(item) : `${item[viewMode]}${units[viewMode]}`)
);
};
const renderPanel = () => {
return React__default.createElement(React__default.Fragment, null, panelDate[`${viewMode}s`].map((item, key) => React__default.createElement(
"div",
{ className: `${classPrefix}-panel`, key },
React__default.createElement("div", { className: `${classPrefix}-panel-title` }, item.year),
React__default.createElement("div", { className: `${classPrefix}-content` }, item[`${viewMode}s`].map((item2, i) => renderItem(item2, i)))
)));
};
const renderContent = () => {
return React__default.createElement(
ScrollView,
{ scrollTop, scrollY: true, className: `${classPrefix}-content`, onScroll: monthsViewScroll, ref: monthsRef },
React__default.createElement(
"div",
{ className: `${classPrefix}-pannel`, ref: monthsPanel },
React__default.createElement("div", { ref: viewAreaRef }, renderPanel())
)
);
};
return React__default.createElement(
"div",
{ className: classes, style },
renderHeader(),
renderContent()
);
});
CalendarViewModeItem.displayName = "NutCalendarViewModeItem";
const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { type: "single", viewMode: "day", autoBackfill: false, popup: true, visible: false, title: "", value: "", defaultValue: "", startDate: getDateString(0), endDate: getDateString(365), showToday: true, startText: "", endText: "", confirmText: "", showTitle: true, showSubTitle: true, showMonthNumber: false, scrollAnimation: true, firstDayOfWeek: 0, disableDate: (date) => false, renderHeaderButtons: void 0, renderDay: void 0, renderDayTop: void 0, renderDayBottom: void 0, onClose: () => {
}, onConfirm: (param) => {
}, onDayClick: (data) => {
}, onItemClick: () => {
}, onPageChange: (param) => {
} });
const Calendar = React__default.forwardRef((props, ref) => {
const { locale } = useConfig$1();
const { style, className, children, popup, visible, type, viewMode, autoBackfill, title, value, defaultValue, startDate, endDate, showToday, startText, endText, confirmText, showTitle, showSubTitle, showMonthNumber, scrollAnimation, firstDayOfWeek, closeIcon, disableDate, renderHeaderButtons, renderBottomButton, renderDay, renderDayTop, renderDayBottom, onClose, onConfirm, onDayClick, onItemClick, onPageChange } = Object.assign(Object.assign({}, defaultProps), props);
const calendarRef = useRef(null);
const close = () => {
onClose && onClose();
};
const choose = (param) => {
close();
onConfirm && onConfirm(param);
};
const closePopup = () => {
close();
};
const scrollToDate = (date) => {
var _a;
(_a = calendarRef.current) === null || _a === void 0 ? void 0 : _a.scrollToDate(date);
};
const yearMonthChange = (param) => {
onPageChange && onPageChange(param);
};
React__default.useImperativeHandle(ref, () => ({
scrollToDate
}));
const renderItem = () => {
return React__default.createElement(React__default.Fragment, null, viewMode !== "day" ? React__default.createElement(CalendarViewModeItem, { ref: calendarRef, style, className, type, viewMode, title: title || locale.calendaritem.title, value, defaultValue, startDate, endDate, showTitle, scrollAnimation, renderDay, onItemClick }) : React__default.createElement(CalendarItem, { ref: calendarRef, style, className, children, type, autoBackfill, popup, title: title || locale.calendaritem.title, defaultValue, startDate, endDate, showToday, startText: startText || locale.calendaritem.start, endText: endText || locale.calendaritem.end, confirmText: confirmText || locale.calendaritem.confirm, showTitle, showSubTitle, showMonthNumber, scrollAnimation, firstDayOfWeek, disableDate, renderHeaderButtons, renderBottomButton, renderDay, renderDayTop, renderDayBottom, onConfirm: choose, onDayClick, onPageChange: yearMonthChange }));
};
return React__default.createElement(React__default.Fragment, null, popup && viewMode === "day" ? React__default.createElement(Popup, { className: "nut-calendar-popup", visible, position: "bottom", round: true, closeable: true, closeIcon, destroyOnClose: true, onOverlayClick: closePopup, onCloseIconClick: closePopup, style: { height: "83%" } }, renderItem()) : renderItem());
});
Calendar.displayName = "NutCalendar";
export {
Calendar as C
};