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

Commit

Permalink
feat: Add option to prevent navigation before/after minDate or maxDate (
Browse files Browse the repository at this point in the history
resolves #94)
  • Loading branch information
Jasenkoo committed Feb 11, 2022
1 parent 04bb761 commit 8be8bb7
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 4 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ interface Vue3DatePicker {
multiDates?: boolean;
presetRanges?: { label: string; range: Date[] | string[] }[];
flow?: ('month' | 'year' | 'calendar' | 'time' | 'minutes' | 'hours' | 'seconds')[];
preventMinMaxNavigation?: boolean;
}

interface PublicMethods extends MethodOptions {
Expand Down
2 changes: 2 additions & 0 deletions src/Vue3DatePicker/Vue3DatePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
multiDates,
presetRanges,
flow,
preventMinMaxNavigation,
}"
v-model:internalModelValue="internalModelValue"
@close-picker="closeMenu"
Expand Down Expand Up @@ -274,6 +275,7 @@
multiDates: { type: Boolean as PropType<boolean>, default: false },
presetRanges: { type: Array as PropType<PresetRange[]>, default: () => [] },
flow: { type: Array as PropType<Flow>, default: () => [] },
preventMinMaxNavigation: { type: Boolean as PropType<boolean>, default: false },
});
const slots = useSlots();
const isOpen = ref(false);
Expand Down
2 changes: 2 additions & 0 deletions src/Vue3DatePicker/components/DatepickerMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
instance,
minDate,
maxDate,
preventMinMaxNavigation,
}"
@mount="childMount('monthYearInput')"
@reset-flow="resetFlow"
Expand Down Expand Up @@ -284,6 +285,7 @@
multiDates: { type: Boolean as PropType<boolean>, default: false },
presetRanges: { type: Array as PropType<PresetRange[]>, default: () => [] },
flow: { type: Array as PropType<Flow>, default: () => [] },
preventMinMaxNavigation: { type: Boolean as PropType<boolean>, default: false },
});
const slots = useSlots();
const calendarWrapperRef = ref(null);
Expand Down
19 changes: 16 additions & 3 deletions src/Vue3DatePicker/components/MonthYearInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@
<transition :name="transitionName(showMonthPicker)" :css="showTransition">
<SelectionGrid
v-if="showMonthPicker"
v-bind="{ modelValue: month, items: groupedMonths, disabledValues: filters.months }"
v-bind="{
modelValue: month,
items: groupedMonths,
disabledValues: filters.months,
minValue: minMonth,
maxValue: maxMonth,
}"
@update:model-value="onMonthUpdate"
@toggle="toggleMonthPicker"
>
Expand All @@ -59,7 +65,13 @@
<transition :name="transitionName(showYearPicker)" :css="showTransition">
<SelectionGrid
v-if="showYearPicker"
v-bind="{ modelValue: year, items: groupedYears, disabledValues: filters.years }"
v-bind="{
modelValue: year,
items: groupedYears,
disabledValues: filters.years,
minValue: minYear,
maxValue: maxYear,
}"
@update:model-value="onYearUpdate"
@toggle="toggleYearPicker"
><template #button-icon>
Expand Down Expand Up @@ -187,6 +199,7 @@
multiCalendarsSolo: { type: Boolean as PropType<boolean>, default: false },
minDate: { type: [Date, String] as PropType<Date | string>, default: null },
maxDate: { type: [Date, String] as PropType<Date | string>, default: null },
preventMinMaxNavigation: { type: Boolean as PropType<boolean>, default: false },
});
const { transitionName, showTransition } = useTransitions();
Expand Down Expand Up @@ -225,7 +238,7 @@
const maxMonth = computed(() => {
if (props.maxDate && maxYear.value) {
if (maxYear.value < props.year) return -1;
if (maxYear.value === props.year) return getMonth(new Date(props.maxDate));
if (maxYear.value === props.year) return getMonth(new Date(props.maxDate)) - 1;
}
return null;
});
Expand Down
20 changes: 19 additions & 1 deletion src/Vue3DatePicker/components/composition/month-year.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { addMonths, addYears, getMonth, getYear, set, subMonths, subYears } from 'date-fns';
import { UseMonthYearPick, VueEmit } from '../../interfaces';
import { isDateAfter, isDateBefore } from '../../utils/date-utils';

export const useMontYearPick = (
props: UseMonthYearPick,
Expand All @@ -23,6 +24,23 @@ export const useMontYearPick = (
return yearDate;
};

const getDateForCompare = (propValue: 'minDate' | 'maxDate', month: number, year: number): [Date, Date] => {
return [new Date(props[propValue]), set(new Date(), { month, year })];
};

const validateMonthYear = (month: number, year: number, isNext: boolean): void => {
if (props.preventMinMaxNavigation && (props.minDate || props.maxDate)) {
if (props.maxDate && isNext && isDateAfter(...getDateForCompare('maxDate', month, year))) {
updateMonthYear(month, year);
}
if (props.minDate && !isNext && isDateBefore(...getDateForCompare('minDate', month, year))) {
updateMonthYear(month, year);
}
} else {
updateMonthYear(month, year);
}
};

const handleMonthYearChange = (isNext: boolean): void => {
const initialDate = set(new Date(), { month: props.month, year: props.year });
let date = isNext ? addMonths(initialDate, 1) : subMonths(initialDate, 1);
Expand All @@ -40,7 +58,7 @@ export const useMontYearPick = (
date = recursiveYearAdjust(date, isNext);
year = getYear(date);
}
updateMonthYear(month, year);
validateMonthYear(month, year, isNext);
};

const updateMonthYear = (month: number, year: number): void => {
Expand Down
3 changes: 3 additions & 0 deletions src/Vue3DatePicker/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ export interface UseMonthYearPick {
filters: IDateFilter;
year: number;
month: number;
preventMinMaxNavigation: boolean;
maxDate: Date | string;
minDate: Date | string;
}

export type MaybeRef<T> = T | Ref<T>;
Expand Down

0 comments on commit 8be8bb7

Please sign in to comment.