UNPKG

@nutui/nutui-react-taro

Version:

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

318 lines (317 loc) 13.8 kB
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 };