types(Calendar): improve default-date typing (#9358)

This commit is contained in:
neverland 2021-08-31 11:18:24 +08:00 committed by GitHub
parent 4f393c93a8
commit 43b78002d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 48 deletions

View File

@ -1,7 +1,6 @@
import { import {
ref, ref,
watch, watch,
reactive,
computed, computed,
PropType, PropType,
TeleportProps, TeleportProps,
@ -62,9 +61,7 @@ const props = {
rangePrompt: String, rangePrompt: String,
lazyRender: truthProp, lazyRender: truthProp,
showConfirm: truthProp, showConfirm: truthProp,
// TODO: remove any defaultDate: [Date, Array] as PropType<Date | Date[] | null>,
// see: https://github.com/vuejs/vue-next/issues/2668
defaultDate: [Date, Array] as any,
allowSameDay: Boolean, allowSameDay: Boolean,
showSubtitle: truthProp, showSubtitle: truthProp,
closeOnPopstate: truthProp, closeOnPopstate: truthProp,
@ -178,10 +175,8 @@ export default defineComponent({
const bodyRef = ref<HTMLElement>(); const bodyRef = ref<HTMLElement>();
const state = reactive({ const subtitle = ref('');
subtitle: '', const currentDate = ref(getInitialDate());
currentDate: getInitialDate(),
});
const [monthRefs, setMonthRefs] = useRefs<CalendarMonthInstance>(); const [monthRefs, setMonthRefs] = useRefs<CalendarMonthInstance>();
@ -204,18 +199,18 @@ export default defineComponent({
}); });
const buttonDisabled = computed(() => { const buttonDisabled = computed(() => {
const { currentDate } = state; if (currentDate.value) {
if (currentDate) {
if (props.type === 'range') { if (props.type === 'range') {
return !(currentDate as Date[])[0] || !(currentDate as Date[])[1]; return (
!(currentDate.value as Date[])[0] ||
!(currentDate.value as Date[])[1]
);
} }
if (props.type === 'multiple') { if (props.type === 'multiple') {
return !(currentDate as Date[]).length; return !(currentDate.value as Date[]).length;
} }
} }
return !currentDate.value;
return !currentDate;
}); });
// calculate the position of the elements // calculate the position of the elements
@ -270,7 +265,7 @@ export default defineComponent({
/* istanbul ignore else */ /* istanbul ignore else */
if (currentMonth) { if (currentMonth) {
state.subtitle = currentMonth.getTitle(); subtitle.value = currentMonth.getTitle();
} }
}; };
@ -297,10 +292,11 @@ export default defineComponent({
return; return;
} }
const { currentDate } = state; if (currentDate.value) {
if (currentDate) {
const targetDate = const targetDate =
props.type === 'single' ? currentDate : (currentDate as Date[])[0]; props.type === 'single'
? (currentDate.value as Date)
: (currentDate.value as Date[])[0];
scrollToDate(targetDate); scrollToDate(targetDate);
} else { } else {
raf(onScroll); raf(onScroll);
@ -321,7 +317,7 @@ export default defineComponent({
}; };
const reset = (date = getInitialDate()) => { const reset = (date = getInitialDate()) => {
state.currentDate = date; currentDate.value = date;
scrollIntoView(); scrollIntoView();
}; };
@ -339,12 +335,13 @@ export default defineComponent({
return true; return true;
}; };
const onConfirm = () => emit('confirm', cloneDates(state.currentDate)); const onConfirm = () =>
emit('confirm', currentDate.value ?? cloneDates(currentDate.value!));
const select = (date: Date | Date[], complete?: boolean) => { const select = (date: Date | Date[], complete?: boolean) => {
const setCurrentDate = (date: Date | Date[]) => { const setCurrentDate = (date: Date | Date[]) => {
state.currentDate = date; currentDate.value = date;
emit('select', cloneDates(state.currentDate)); emit('select', cloneDates(date));
}; };
if (complete && props.type === 'range') { if (complete && props.type === 'range') {
@ -378,15 +375,14 @@ export default defineComponent({
const { date } = item; const { date } = item;
const { type } = props; const { type } = props;
const { currentDate } = state;
if (type === 'range') { if (type === 'range') {
if (!currentDate) { if (!currentDate.value) {
select([date]); select([date]);
return; return;
} }
const [startDay, endDay] = currentDate; const [startDay, endDay] = currentDate.value as [Date, Date];
if (startDay && !endDay) { if (startDay && !endDay) {
const compareToStart = compareDay(date, startDay); const compareToStart = compareDay(date, startDay);
@ -402,29 +398,23 @@ export default defineComponent({
select([date]); select([date]);
} }
} else if (type === 'multiple') { } else if (type === 'multiple') {
if (!currentDate) { if (!currentDate.value) {
select([date]); select([date]);
return; return;
} }
const dates = currentDate.value as Date[];
let selectedIndex; const selectedIndex = dates.findIndex(
const selected = state.currentDate.some( (dateItem: Date) => compareDay(dateItem, date) === 0
(dateItem: Date, index: number) => {
const equal = compareDay(dateItem, date) === 0;
if (equal) {
selectedIndex = index;
}
return equal;
}
); );
if (selected) { if (selectedIndex !== -1) {
const [unselectedDate] = currentDate.splice(selectedIndex, 1); const [unselectedDate] = dates.splice(selectedIndex, 1);
emit('unselect', cloneDate(unselectedDate)); emit('unselect', cloneDate(unselectedDate));
} else if (props.maxRange && currentDate.length >= props.maxRange) { } else if (props.maxRange && dates.length >= props.maxRange) {
Toast(props.rangePrompt || t('rangePrompt', props.maxRange)); Toast(props.rangePrompt || t('rangePrompt', props.maxRange));
} else { } else {
select([...currentDate, date]); select([...dates, date]);
} }
} else { } else {
select(date, true); select(date, true);
@ -440,7 +430,7 @@ export default defineComponent({
v-slots={pick(slots, ['top-info', 'bottom-info'])} v-slots={pick(slots, ['top-info', 'bottom-info'])}
ref={setMonthRefs(index)} ref={setMonthRefs(index)}
date={date} date={date}
currentDate={state.currentDate} currentDate={currentDate.value}
showMonthTitle={showMonthTitle} showMonthTitle={showMonthTitle}
firstDayOfWeek={dayOffset.value} firstDayOfWeek={dayOffset.value}
{...pick(props, [ {...pick(props, [
@ -503,7 +493,7 @@ export default defineComponent({
<CalendarHeader <CalendarHeader
v-slots={pick(slots, ['title', 'subtitle'])} v-slots={pick(slots, ['title', 'subtitle'])}
title={props.title} title={props.title}
subtitle={state.subtitle} subtitle={subtitle.value}
showTitle={props.showTitle} showTitle={props.showTitle}
showSubtitle={props.showSubtitle} showSubtitle={props.showSubtitle}
firstDayOfWeek={dayOffset.value} firstDayOfWeek={dayOffset.value}
@ -522,13 +512,13 @@ export default defineComponent({
watch( watch(
() => [props.type, props.minDate, props.maxDate], () => [props.type, props.minDate, props.maxDate],
() => { () => {
reset(getInitialDate(state.currentDate)); reset(getInitialDate(currentDate.value));
} }
); );
watch( watch(
() => props.defaultDate, () => props.defaultDate,
(value) => { (value = null) => {
state.currentDate = value; currentDate.value = value;
scrollIntoView(); scrollIntoView();
} }
); );

View File

@ -38,7 +38,7 @@ const props = {
rowHeight: [Number, String], rowHeight: [Number, String],
formatter: Function as PropType<(item: CalendarDayItem) => CalendarDayItem>, formatter: Function as PropType<(item: CalendarDayItem) => CalendarDayItem>,
lazyRender: Boolean, lazyRender: Boolean,
currentDate: [Date, Array] as PropType<Date | Date[]>, currentDate: [Date, Array] as PropType<Date | Date[] | null>,
allowSameDay: Boolean, allowSameDay: Boolean,
showSubtitle: Boolean, showSubtitle: Boolean,
showMonthTitle: Boolean, showMonthTitle: Boolean,

View File

@ -162,13 +162,13 @@ const show = (type: string, id: string) => {
const formatDate = (date: Date) => { const formatDate = (date: Date) => {
if (date) { if (date) {
return `${state.date.getMonth() + 1}/${state.date.getDate()}`; return `${date.getMonth() + 1}/${date.getDate()}`;
} }
}; };
const formatFullDate = (date: Date) => { const formatFullDate = (date: Date) => {
if (date) { if (date) {
return `${state.date.getFullYear()}/${formatDate(date)}`; return `${date.getFullYear()}/${formatDate(date)}`;
} }
}; };