UNPKG

taro-ui-vue3

Version:

Taro UI Rewritten in Vue 3.0

264 lines (263 loc) 8.18 kB
import {h, defineComponent, reactive, toRefs, watch, nextTick, mergeProps} from "vue"; import dayjs from "dayjs/esm/index"; import {View} from "@tarojs/components"; import AtCalendarBody from "./body"; import AtCalendarController from "./controller"; const AtCalendar = defineComponent({ name: "AtCalendar", components: { AtCalendarBody, AtCalendarController }, data: () => ({addGlobalClass: true}), props: { currentDate: { type: [Number, String, Date, Object], default: Date.now() }, minDate: [String, Number, Date], maxDate: [String, Number, Date], isSwiper: { type: Boolean, default: true }, marks: { type: Array, default: () => [] }, validDates: { type: Array, default: () => [] }, format: { type: String, default: "YYYY-MM-DD" }, monthFormat: { type: String, default: "YYYY \u5E74 MM \u6708" }, hideArrow: Boolean, isVertical: Boolean, isMultiSelect: Boolean, selectedDates: { type: Array, default: () => [] }, onClickPreMonth: Function, onClickNextMonth: Function, onDayClick: Function, onDayLongClick: Function, onMonthChange: Function, onSelectDate: Function }, setup(props, {attrs}) { const {currentDate, isMultiSelect} = toRefs(props); let {generateDate, selectedDate} = getInitializedState(currentDate.value, isMultiSelect.value); const state = reactive({ generateDate, selectedDate }); watch(() => [ props.currentDate, props.isMultiSelect ], ([currentDate2, isMultiSelect2], [preCurrentDate, preIsMultiSelect]) => { if (!currentDate2 || currentDate2 === preCurrentDate) return; if (isMultiSelect2 && preIsMultiSelect) { const {start, end} = currentDate2; const {start: preStart, end: preEnd} = preCurrentDate; if (start === preStart && preEnd === end) { return; } } const stateValue = getInitializedState(currentDate2, isMultiSelect2); Object.assign(state, stateValue); }); function getSingleSelectedState(value) { const stateValue = { selectedDate: getSelectedDate(value.valueOf()) }; const dayjsGenerateDate = value.startOf("month"); const generateDateValue = dayjsGenerateDate.valueOf(); if (generateDateValue !== state.generateDate) { triggerChangeDate(dayjsGenerateDate); stateValue.generateDate = generateDateValue; } return stateValue; } function getMultiSelectedState(value) { const {end, start} = state.selectedDate; const valueUnix = value.valueOf(); const stateValue = { selectedDate: state.selectedDate }; if (end) { stateValue.selectedDate = getSelectedDate(valueUnix, 0); } else { stateValue.selectedDate.end = Math.max(valueUnix, +start); stateValue.selectedDate.start = Math.min(valueUnix, +start); } return stateValue; } function getInitializedState(currentDate2, isMultiSelect2) { let end; let start; let generateDateValue; if (!currentDate2) { const dayjsStart = dayjs(); start = dayjsStart.startOf("day").valueOf(); generateDateValue = dayjsStart.startOf("month").valueOf(); return { generateDate: generateDateValue, selectedDate: { start: "" } }; } if (isMultiSelect2) { const {start: cStart, end: cEnd} = currentDate2; const dayjsStart = dayjs(cStart); start = dayjsStart.startOf("day").valueOf(); generateDateValue = dayjsStart.startOf("month").valueOf(); end = cEnd ? dayjs(cEnd).startOf("day").valueOf() : start; } else { const dayjsStart = dayjs(currentDate2); start = dayjsStart.startOf("day").valueOf(); generateDateValue = dayjsStart.startOf("month").valueOf(); end = start; } return { generateDate: generateDateValue, selectedDate: getSelectedDate(start, end) }; } function getSelectedDate(start, end) { const stateValue = { start, end: start }; if (typeof end !== "undefined") { stateValue.end = end; } return stateValue; } function triggerChangeDate(value) { if (typeof props.onMonthChange !== "function") return; props.onMonthChange(value.format(props.format)); } function setMonth(vectorCount) { const _generateDate = dayjs(state.generateDate).add(vectorCount, "month"); state.generateDate = _generateDate.valueOf(); if (vectorCount && typeof props.onMonthChange === "function") { props.onMonthChange(_generateDate.format(props.format)); } } function handleClickPreMonth(isMinMonth) { if (isMinMonth === true) return; setMonth(-1); if (typeof props.onClickPreMonth === "function") { props.onClickPreMonth(); } } function handleClickNextMonth(isMaxMonth) { if (isMaxMonth === true) return; setMonth(1); if (typeof props.onClickNextMonth === "function") { props.onClickNextMonth(); } } function handleSelectDate(e) { const {value} = e.detail; const _generateDate = dayjs(value); const _generateDateValue = _generateDate.valueOf(); if (state.generateDate === _generateDateValue) return; triggerChangeDate(_generateDate); state.generateDate = _generateDateValue; } function handleDayClick(item) { const {isDisabled, value} = item; if (isDisabled) return; const dayjsDate = dayjs(value); let stateValue = {}; stateValue = props.isMultiSelect ? getMultiSelectedState(dayjsDate) : getSingleSelectedState(dayjsDate); Object.assign(state, stateValue); nextTick(() => { handleSelectedDate(); }); if (typeof props.onDayClick === "function") { props.onDayClick({value: item.value}); } } function handleSelectedDate() { if (typeof props.onSelectDate === "function") { const info = { start: dayjs(state.selectedDate.start).format(props.format) }; if (state.selectedDate.end) { info.end = dayjs(state.selectedDate.end).format(props.format); } props.onSelectDate({value: info}); } } function handleDayLongClick(item) { if (typeof props.onDayLongClick === "function") { props.onDayLongClick({value: item.value}); } } return () => { const { validDates, marks, format, minDate, maxDate, isSwiper, hideArrow, isVertical, monthFormat, selectedDates } = toRefs(props); return h(View, mergeProps(attrs, { class: "at-calendar" }), { default: () => [ h(AtCalendarController, { minDate: minDate == null ? void 0 : minDate.value, maxDate: maxDate == null ? void 0 : maxDate.value, hideArrow: hideArrow.value, monthFormat: monthFormat.value, generateDate: state.generateDate, onPreMonth: handleClickPreMonth, onNextMonth: handleClickNextMonth, onSelectDate: handleSelectDate }), h(AtCalendarBody, { validDates: validDates.value, marks: marks.value, format: format.value, minDate: minDate == null ? void 0 : minDate.value, maxDate: maxDate == null ? void 0 : maxDate.value, isSwiper: isSwiper.value, isVertical: isVertical.value, selectedDate: state.selectedDate, selectedDates: selectedDates.value, generateDate: state.generateDate, onSwipeMonth: setMonth, onDayClick: handleDayClick, onLongClick: handleDayLongClick }) ] }); }; } }); var calendar_default = AtCalendar; export { calendar_default as default };