diff --git a/examples/Dropdown.test.tsx b/examples/Dropdown.test.tsx index 3f93ea86d..9f40a1fd6 100644 --- a/examples/Dropdown.test.tsx +++ b/examples/Dropdown.test.tsx @@ -23,43 +23,65 @@ test("should display the year dropdown", () => { expect(yearDropdown()).toBeInTheDocument(); }); -test("should disable the months out of range", () => { - expect( - within(monthDropdown()).getByRole("option", { name: "January" }) - ).toBeDisabled(); +test("should disable the months before startMonth", () => { + const disablesMonth = [ + "January", + "February", + "March", + "April", + "May", + "June" + ]; + for (const month of disablesMonth) { + expect( + within(monthDropdown()).getByRole("option", { name: month }) + ).toBeDisabled(); + } +}); + +test("should disable the months after endMonth", async () => { + await user.selectOptions(yearDropdown(), "2025"); + const disablesMonth = ["November", "December"]; + for (const month of disablesMonth) { + expect( + within(monthDropdown()).getByRole("option", { name: month }) + ).toBeDisabled(); + } }); describe("when choosing a month", () => { - const monthName = "December"; - beforeEach(async () => { + test("should display the month", async () => { + const monthName = "December"; await user.selectOptions(monthDropdown(), monthName); - }); - test("should display the month", () => { expect(grid()).toHaveAccessibleName(`${monthName} 2024`); }); - test("should disable the years out of range", () => { - expect( - within(yearDropdown()).getByRole("option", { name: "2025" }) - ).toBeDisabled(); - }); }); describe("when choosing a year", () => { - const year = "2025"; - beforeEach(async () => { + test("should display the year", async () => { + const year = "2025"; await user.selectOptions(yearDropdown(), year); - }); - test("should display the year", () => { expect(grid()).toHaveAccessibleName(`July ${year}`); }); + + test("should display the first available month when selecting a month before startMonth", async () => { + await user.selectOptions(yearDropdown(), "2025"); + await user.selectOptions(monthDropdown(), "January"); + await user.selectOptions(yearDropdown(), "2024"); + expect(grid()).toHaveAccessibleName(`July 2024`); + }); + + test("should display the last available month when selecting a month after endMonth", async () => { + await user.selectOptions(monthDropdown(), "December"); + await user.selectOptions(yearDropdown(), "2025"); + expect(grid()).toHaveAccessibleName(`October 2025`); + }); }); describe("when choosing a disabled month", () => { - const monthName = "February"; - beforeEach(async () => { + test("should display the first available month", async () => { + const monthName = "February"; await user.selectOptions(monthDropdown(), monthName); - }); - test("should display the first available month", () => { expect(grid()).toHaveAccessibleName(`July 2024`); }); }); diff --git a/examples/DropdownMultipleMonths.test.tsx b/examples/DropdownMultipleMonths.test.tsx index f8bd58df6..e7366cc10 100644 --- a/examples/DropdownMultipleMonths.test.tsx +++ b/examples/DropdownMultipleMonths.test.tsx @@ -26,7 +26,7 @@ describe("when choosing a month from the first dropdown", () => { await user.selectOptions(firstDropDown, monthName); }); test("should display the month in the first dropdown", () => { - expect(grid(`${monthName} 2023`)).toBeInTheDocument(); + expect(grid(`${monthName} 2024`)).toBeInTheDocument(); }); }); @@ -39,6 +39,6 @@ describe("when choosing a month from the third dropdown", () => { await user.selectOptions(thirdDropDown, newMonthName); }); test("should display the month selected the third dropdown", () => { - expect(grid(`${newMonthName} 2023`)).toBeInTheDocument(); + expect(grid(`${newMonthName} 2024`)).toBeInTheDocument(); }); }); diff --git a/examples/DropdownMultipleMonths.tsx b/examples/DropdownMultipleMonths.tsx index 4c7458f09..2dc3c9958 100644 --- a/examples/DropdownMultipleMonths.tsx +++ b/examples/DropdownMultipleMonths.tsx @@ -6,9 +6,10 @@ export function DropdownMultipleMonths() { return ( ); } diff --git a/src/DayPicker.tsx b/src/DayPicker.tsx index 4fefa9460..c343c548d 100644 --- a/src/DayPicker.tsx +++ b/src/DayPicker.tsx @@ -308,7 +308,6 @@ export function DayPicker(props: DayPickerProps) { ); const dropdownYears = getYearOptions( - months[0].date, navStart, navEnd, formatters, diff --git a/src/helpers/getYearOptions.test.ts b/src/helpers/getYearOptions.test.ts index 98dc615a5..c5473bea0 100644 --- a/src/helpers/getYearOptions.test.ts +++ b/src/helpers/getYearOptions.test.ts @@ -4,19 +4,16 @@ import { getFormatters } from "./getFormatters"; import { getYearOptions } from "./getYearOptions"; test("return undefined if startMonth or endMonth is not provided", () => { - const displayMonth = new Date(2022, 0, 1); // January 2022 const formatters = getFormatters({ formatYearDropdown: (year: number) => `${year}` }); const result1 = getYearOptions( - displayMonth, undefined, new Date(2022, 11, 31), formatters, defaultDateLib ); const result2 = getYearOptions( - displayMonth, new Date(2022, 0, 1), undefined, formatters, @@ -28,7 +25,6 @@ test("return undefined if startMonth or endMonth is not provided", () => { }); test("return correct dropdown options", () => { - const displayMonth = new Date(2022, 0, 1); // January 2022 const startMonth = new Date(2022, 0, 1); // January 2022 const endMonth = new Date(2024, 11, 31); // December 2024 const formatters = getFormatters({ @@ -36,7 +32,6 @@ test("return correct dropdown options", () => { }); const result = getYearOptions( - displayMonth, startMonth, endMonth, formatters, diff --git a/src/helpers/getYearOptions.ts b/src/helpers/getYearOptions.ts index fba0b0fb5..4c88f3161 100644 --- a/src/helpers/getYearOptions.ts +++ b/src/helpers/getYearOptions.ts @@ -4,25 +4,16 @@ import type { Formatters } from "../types/index.js"; /** Return the years to show in the dropdown. */ export function getYearOptions( - displayMonth: Date, - calendarStart: Date | undefined, - calendarEnd: Date | undefined, + navStart: Date | undefined, + navEnd: Date | undefined, formatters: Pick, dateLib: DateLib ): DropdownOption[] | undefined { - if (!calendarStart) return undefined; - if (!calendarEnd) return undefined; - const { - startOfMonth, - startOfYear, - endOfYear, - addYears, - isBefore, - isSameYear - } = dateLib; - const month = displayMonth.getMonth(); - const firstNavYear = startOfYear(calendarStart); - const lastNavYear = endOfYear(calendarEnd); + if (!navStart) return undefined; + if (!navEnd) return undefined; + const { startOfYear, endOfYear, addYears, isBefore, isSameYear } = dateLib; + const firstNavYear = startOfYear(navStart); + const lastNavYear = endOfYear(navEnd); const years: number[] = []; let year = firstNavYear; @@ -32,18 +23,11 @@ export function getYearOptions( } return years.map((value) => { - const year = dateLib.Date - ? new dateLib.Date(value, month) - : new Date(value, month); - const disabled = - (calendarStart && year < startOfMonth(calendarStart)) || - (month && calendarEnd && year > startOfMonth(calendarEnd)) || - false; const label = formatters.formatYearDropdown(value); return { value, label, - disabled + disabled: false }; }); } diff --git a/src/types/props.ts b/src/types/props.ts index 95a77a483..12774682b 100644 --- a/src/types/props.ts +++ b/src/types/props.ts @@ -209,7 +209,8 @@ export interface PropsBase { * - `year`: display only the dropdown for the years * * **Note:** showing the dropdown will set the start/end months - * {@link fromYear} to 100 years ago, and {@link toYear} to the current year. + * {@link startMonth} to 100 years ago, and {@link endMonth} to the end of the + * current year. * * @see https://daypicker.dev/docs/customization#caption-layouts */