Skip to content
This repository was archived by the owner on Apr 17, 2022. It is now read-only.

Commit 8be8bb7

Browse files
committed
feat: Add option to prevent navigation before/after minDate or maxDate (resolves #94)
1 parent 04bb761 commit 8be8bb7

File tree

6 files changed

+43
-4
lines changed

6 files changed

+43
-4
lines changed

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ interface Vue3DatePicker {
183183
multiDates?: boolean;
184184
presetRanges?: { label: string; range: Date[] | string[] }[];
185185
flow?: ('month' | 'year' | 'calendar' | 'time' | 'minutes' | 'hours' | 'seconds')[];
186+
preventMinMaxNavigation?: boolean;
186187
}
187188

188189
interface PublicMethods extends MethodOptions {

src/Vue3DatePicker/Vue3DatePicker.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
multiDates,
109109
presetRanges,
110110
flow,
111+
preventMinMaxNavigation,
111112
}"
112113
v-model:internalModelValue="internalModelValue"
113114
@close-picker="closeMenu"
@@ -274,6 +275,7 @@
274275
multiDates: { type: Boolean as PropType<boolean>, default: false },
275276
presetRanges: { type: Array as PropType<PresetRange[]>, default: () => [] },
276277
flow: { type: Array as PropType<Flow>, default: () => [] },
278+
preventMinMaxNavigation: { type: Boolean as PropType<boolean>, default: false },
277279
});
278280
const slots = useSlots();
279281
const isOpen = ref(false);

src/Vue3DatePicker/components/DatepickerMenu.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
instance,
5151
minDate,
5252
maxDate,
53+
preventMinMaxNavigation,
5354
}"
5455
@mount="childMount('monthYearInput')"
5556
@reset-flow="resetFlow"
@@ -284,6 +285,7 @@
284285
multiDates: { type: Boolean as PropType<boolean>, default: false },
285286
presetRanges: { type: Array as PropType<PresetRange[]>, default: () => [] },
286287
flow: { type: Array as PropType<Flow>, default: () => [] },
288+
preventMinMaxNavigation: { type: Boolean as PropType<boolean>, default: false },
287289
});
288290
const slots = useSlots();
289291
const calendarWrapperRef = ref(null);

src/Vue3DatePicker/components/MonthYearInput.vue

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@
4343
<transition :name="transitionName(showMonthPicker)" :css="showTransition">
4444
<SelectionGrid
4545
v-if="showMonthPicker"
46-
v-bind="{ modelValue: month, items: groupedMonths, disabledValues: filters.months }"
46+
v-bind="{
47+
modelValue: month,
48+
items: groupedMonths,
49+
disabledValues: filters.months,
50+
minValue: minMonth,
51+
maxValue: maxMonth,
52+
}"
4753
@update:model-value="onMonthUpdate"
4854
@toggle="toggleMonthPicker"
4955
>
@@ -59,7 +65,13 @@
5965
<transition :name="transitionName(showYearPicker)" :css="showTransition">
6066
<SelectionGrid
6167
v-if="showYearPicker"
62-
v-bind="{ modelValue: year, items: groupedYears, disabledValues: filters.years }"
68+
v-bind="{
69+
modelValue: year,
70+
items: groupedYears,
71+
disabledValues: filters.years,
72+
minValue: minYear,
73+
maxValue: maxYear,
74+
}"
6375
@update:model-value="onYearUpdate"
6476
@toggle="toggleYearPicker"
6577
><template #button-icon>
@@ -187,6 +199,7 @@
187199
multiCalendarsSolo: { type: Boolean as PropType<boolean>, default: false },
188200
minDate: { type: [Date, String] as PropType<Date | string>, default: null },
189201
maxDate: { type: [Date, String] as PropType<Date | string>, default: null },
202+
preventMinMaxNavigation: { type: Boolean as PropType<boolean>, default: false },
190203
});
191204
192205
const { transitionName, showTransition } = useTransitions();
@@ -225,7 +238,7 @@
225238
const maxMonth = computed(() => {
226239
if (props.maxDate && maxYear.value) {
227240
if (maxYear.value < props.year) return -1;
228-
if (maxYear.value === props.year) return getMonth(new Date(props.maxDate));
241+
if (maxYear.value === props.year) return getMonth(new Date(props.maxDate)) - 1;
229242
}
230243
return null;
231244
});

src/Vue3DatePicker/components/composition/month-year.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { addMonths, addYears, getMonth, getYear, set, subMonths, subYears } from 'date-fns';
22
import { UseMonthYearPick, VueEmit } from '../../interfaces';
3+
import { isDateAfter, isDateBefore } from '../../utils/date-utils';
34

45
export const useMontYearPick = (
56
props: UseMonthYearPick,
@@ -23,6 +24,23 @@ export const useMontYearPick = (
2324
return yearDate;
2425
};
2526

27+
const getDateForCompare = (propValue: 'minDate' | 'maxDate', month: number, year: number): [Date, Date] => {
28+
return [new Date(props[propValue]), set(new Date(), { month, year })];
29+
};
30+
31+
const validateMonthYear = (month: number, year: number, isNext: boolean): void => {
32+
if (props.preventMinMaxNavigation && (props.minDate || props.maxDate)) {
33+
if (props.maxDate && isNext && isDateAfter(...getDateForCompare('maxDate', month, year))) {
34+
updateMonthYear(month, year);
35+
}
36+
if (props.minDate && !isNext && isDateBefore(...getDateForCompare('minDate', month, year))) {
37+
updateMonthYear(month, year);
38+
}
39+
} else {
40+
updateMonthYear(month, year);
41+
}
42+
};
43+
2644
const handleMonthYearChange = (isNext: boolean): void => {
2745
const initialDate = set(new Date(), { month: props.month, year: props.year });
2846
let date = isNext ? addMonths(initialDate, 1) : subMonths(initialDate, 1);
@@ -40,7 +58,7 @@ export const useMontYearPick = (
4058
date = recursiveYearAdjust(date, isNext);
4159
year = getYear(date);
4260
}
43-
updateMonthYear(month, year);
61+
validateMonthYear(month, year, isNext);
4462
};
4563

4664
const updateMonthYear = (month: number, year: number): void => {

src/Vue3DatePicker/interfaces.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ export interface UseMonthYearPick {
9595
filters: IDateFilter;
9696
year: number;
9797
month: number;
98+
preventMinMaxNavigation: boolean;
99+
maxDate: Date | string;
100+
minDate: Date | string;
98101
}
99102

100103
export type MaybeRef<T> = T | Ref<T>;

0 commit comments

Comments
 (0)