From c53131027369f799669d28684386e68d2e27f056 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:41:45 +0000 Subject: [PATCH 1/2] fix(DateInput): fix maxDate and minDate restrictions being applied globally The DateInput component was incorrectly disabling months and years based only on the month or year part of maxDate/minDate, ignoring the full date. This prevented users from selecting months after February in years prior to a maxDate of 2026-02-28, for example. This commit: - Updates MonthSelectorGrid to accept a year prop and correctly disable months based on the full date range. - Updates YearSelectorGrid to respect minDate and maxDate props. - Fixes a typo in MonthSelectorGrid's isMothDisabled function. - Updates DateInput.vue to pass the necessary props to internal components. - Updates snapshots for DateInput.spec.js. Co-authored-by: lucasn4s <17988272+lucasn4s@users.noreply.github.com> --- src/components/DateInput.vue | 1 + .../InternalComponents/MonthSelectorGrid.vue | 42 +++++++++---------- .../InternalComponents/YearSelectorGrid.vue | 34 +++++++++++---- .../__snapshots__/DateInput.spec.js.snap | 2 +- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/components/DateInput.vue b/src/components/DateInput.vue index ca284ea4..f8d84d73 100644 --- a/src/components/DateInput.vue +++ b/src/components/DateInput.vue @@ -128,6 +128,7 @@ :min-date="minDate" :max-date="maxDate" :variant="variant" + :year="currentDate.year" @click="handleMonthSelection" /> diff --git a/src/components/InternalComponents/MonthSelectorGrid.vue b/src/components/InternalComponents/MonthSelectorGrid.vue index 6adb19d9..7a88fe8a 100644 --- a/src/components/InternalComponents/MonthSelectorGrid.vue +++ b/src/components/InternalComponents/MonthSelectorGrid.vue @@ -43,6 +43,10 @@ const props = defineProps({ default: '', required: false, }, + year: { + type: Number, + default: new Date().getFullYear(), + }, }); const emits = defineEmits(['click']); @@ -53,19 +57,10 @@ const internalMinDate = ref(props.minDate); const internalMaxDate = ref(props.maxDate); /* COMPUTED */ -const maxMonth = computed(() => { - if (!props.maxDate) return 12; - return extractMonth(props.maxDate); -}); - -const minMonth = computed(() => { - if (!props.minDate) return 1; - return extractMonth(props.minDate); -}); - const currentMonth = computed(() => { if (!internalDate.value) return 1; - return extractMonth(internalDate.value); + const month = internalDate.value.split('-')[1]; + return month ? parseInt(month) : 1; }); /* WATCHERS */ @@ -87,27 +82,30 @@ onMounted(() => { }); /* FUNCTIONS */ -function isMothDisabled(month) { - if (props.minDate && (month + 1 < minMonth.value)) { - return true; +function isMonthDisabled(monthIndex) { + const month = monthIndex + 1; + const year = props.year; + + if (props.minDate) { + const [minYear, minMonth] = props.minDate.split('-').map(Number); + if (year < minYear) return true; + if (year === minYear && month < minMonth) return true; } - if (props.maxDate && (month + 1 > maxMonth.value)) { - return true; + if (props.maxDate) { + const [maxYear, maxMonth] = props.maxDate.split('-').map(Number); + if (year > maxYear) return true; + if (year === maxYear && month > maxMonth) return true; } return false; } -function extractMonth(date) { - let month = date.split('-')[1]; - return month < 9 ? month.replace('0', '') : month; -} function monthSelectorClasses(index) { let classes = { [`month-selector__month--${props.variant}`]: true, - 'month-selector__month--disabled': isMothDisabled(index), + 'month-selector__month--disabled': isMonthDisabled(index), [`month-selector__month--selected--${props.variant}`]: (index + 1) == currentMonth.value, } @@ -122,7 +120,7 @@ function payload(month, index) { } function handleClick(month, index) { - if(isMothDisabled(index)) return; + if(isMonthDisabled(index)) return; emits('click', payload(month, index)); } diff --git a/src/components/InternalComponents/YearSelectorGrid.vue b/src/components/InternalComponents/YearSelectorGrid.vue index 9025ba05..3685953c 100644 --- a/src/components/InternalComponents/YearSelectorGrid.vue +++ b/src/components/InternalComponents/YearSelectorGrid.vue @@ -48,14 +48,32 @@ const props = defineProps({ default: '', required: false, }, + minDate: { + type: String, + default: '', + }, + maxDate: { + type: String, + default: '', + }, }); const emits = defineEmits(['click']); /* REACTIVE DATA */ const currentYear = ref(new Date().getFullYear()); -const minYear = currentYear.value - 120; -const maxYear = currentYear.value + 50; +const minYear = computed(() => { + if (props.minDate) { + return parseInt(props.minDate.split('-')[0]); + } + return currentYear.value - 120; +}); +const maxYear = computed(() => { + if (props.maxDate) { + return parseInt(props.maxDate.split('-')[0]); + } + return currentYear.value + 50; +}); const initialYear = ref(currentYear.value - 7); const scrollThumbHeight = ref(33); const isDragging = ref(false); @@ -69,8 +87,8 @@ const yearSpan = computed(() => { }); const scrollThumbPosition = computed(() => { - const range = maxYear - minYear; - const currentProgress = (initialYear.value - minYear) / range; + const range = maxYear.value - minYear.value; + const currentProgress = (initialYear.value - minYear.value) / range; return currentProgress * (100 - scrollThumbHeight.value); }); @@ -94,7 +112,7 @@ function handleScroll(event) { function yearSelectorClasses(year) { let classes = { [`year-selector__year--${props.variant}`]: true, - 'year-selector__year--disabled':( year < minYear) || (year > maxYear), + 'year-selector__year--disabled':( year < minYear.value) || (year > maxYear.value), [`year-selector__year--selected--${props.variant}`]: year == currentYear.value, } @@ -102,13 +120,13 @@ function yearSelectorClasses(year) { } function incrementYear() { - if (initialYear.value + 11 < maxYear) { + if (initialYear.value + 11 < maxYear.value) { initialYear.value += 3; } } function decrementYear() { - if (initialYear.value > minYear) { + if (initialYear.value > minYear.value) { initialYear.value -= 3; } } @@ -132,7 +150,7 @@ function handleDragScroll(event) { if (yearChange !== 0) { const newInitialYear = initialScrollPosition.value + (yearChange > 0 ? 3 : -3); - if (newInitialYear >= minYear && newInitialYear + 11 <= maxYear) { + if (newInitialYear >= minYear.value && newInitialYear + 11 <= maxYear.value) { initialYear.value = newInitialYear; startY.value = event.clientY; initialScrollPosition.value = initialYear.value; diff --git a/src/tests/__snapshots__/DateInput.spec.js.snap b/src/tests/__snapshots__/DateInput.spec.js.snap index bc83f58f..ec44b8bf 100644 --- a/src/tests/__snapshots__/DateInput.spec.js.snap +++ b/src/tests/__snapshots__/DateInput.spec.js.snap @@ -108,7 +108,7 @@ exports[`DateInput > renders correctly 1`] = `
nov
dez
-