taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
264 lines (263 loc) • 8.18 kB
JavaScript
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
};