diff --git a/examples/MultipleMonthsWithDropdown.test.tsx b/examples/MultipleMonthsWithDropdown.test.tsx new file mode 100644 index 0000000000..229a2e0339 --- /dev/null +++ b/examples/MultipleMonthsWithDropdown.test.tsx @@ -0,0 +1,41 @@ +import React from "react"; + +import { render, screen } from "@/test/render"; +import { user } from "@/test/user"; + +import { MultipleMonthsWithDropdown } from "./MultipleMonthsWithDropdown"; + +const today = new Date(2025, 5, 16); + +beforeAll(() => jest.setSystemTime(today)); +afterAll(() => jest.useRealTimers()); + +beforeEach(() => { + render(); +}); + +describe("when choosing a month from the second dropdown", () => { + beforeEach(() => { + const select = screen.getAllByRole("combobox")[2]; + user.selectOptions(select, "June"); + }); + test('should update the first month to "May 2025"', () => { + expect(screen.getAllByRole("grid")[0]).toHaveAccessibleName("May 2025"); + }); + test('should update the second month to "June 2025"', () => { + expect(screen.getAllByRole("grid")[1]).toHaveAccessibleName("June 2025"); + }); +}); + +describe("when choosing a year from the second dropdown", () => { + beforeEach(() => { + const select = screen.getAllByRole("combobox")[3]; + user.selectOptions(select, "2022"); + }); + test('should update the first month to "April 2022"', () => { + expect(screen.getAllByRole("grid")[0]).toHaveAccessibleName("April 2022"); + }); + test('should update the second month to "May 2025"', () => { + expect(screen.getAllByRole("grid")[1]).toHaveAccessibleName("May 2022"); + }); +}); diff --git a/examples/MultipleMonthsWithDropdown.tsx b/examples/MultipleMonthsWithDropdown.tsx new file mode 100644 index 0000000000..a3a2790464 --- /dev/null +++ b/examples/MultipleMonthsWithDropdown.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +import { DayPicker } from "react-day-picker"; + +export function MultipleMonthsWithDropdown() { + return ; +} diff --git a/examples/index.ts b/examples/index.ts index a4d9bdd2a2..58f471dcbc 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -51,6 +51,7 @@ export * from "./MultipleMinMax"; export * from "./MultipleRequired"; export * from "./MultipleMonths"; export * from "./MultipleMonthsPaged"; +export * from "./MultipleMonthsWithDropdown"; export * from "./Numerals"; export * from "./OutsideDays"; export * from "./PastDatesDisabled"; diff --git a/src/DayPicker.tsx b/src/DayPicker.tsx index 371b780bc2..c0463929a3 100644 --- a/src/DayPicker.tsx +++ b/src/DayPicker.tsx @@ -228,20 +228,26 @@ export function DayPicker(props: DayPickerProps) { ); const handleMonthChange = useCallback( - (date: Date) => (e: ChangeEvent) => { - const selectedMonth = Number(e.target.value); - const month = dateLib.setMonth(dateLib.startOfMonth(date), selectedMonth); - goToMonth(month); - }, + (date: Date, displayIndex: number) => + (e: ChangeEvent) => { + const selectedMonth = Number(e.target.value); + const month = dateLib.setMonth( + dateLib.startOfMonth(date), + selectedMonth - displayIndex + ); + goToMonth(month); + }, [dateLib, goToMonth] ); const handleYearChange = useCallback( - (date: Date) => (e: ChangeEvent) => { - const selectedYear = Number(e.target.value); - const month = dateLib.setYear(dateLib.startOfMonth(date), selectedYear); - goToMonth(month); - }, + (date: Date, displayIndex: number) => + (e: ChangeEvent) => { + const selectedYear = Number(e.target.value); + let month = dateLib.setYear(dateLib.startOfMonth(date), selectedYear); + month = dateLib.addMonths(month, displayIndex * -1); + goToMonth(month); + }, [dateLib, goToMonth] ); @@ -357,7 +363,10 @@ export function DayPicker(props: DayPickerProps) { classNames={classNames} components={components} disabled={Boolean(props.disableNavigation)} - onChange={handleMonthChange(calendarMonth.date)} + onChange={handleMonthChange( + calendarMonth.date, + displayIndex + )} options={dropdownMonths} style={styles?.[UI.Dropdown]} value={dateLib.getMonth(calendarMonth.date)} @@ -375,7 +384,10 @@ export function DayPicker(props: DayPickerProps) { classNames={classNames} components={components} disabled={Boolean(props.disableNavigation)} - onChange={handleYearChange(calendarMonth.date)} + onChange={handleYearChange( + calendarMonth.date, + displayIndex + )} options={dropdownYears} style={styles?.[UI.Dropdown]} value={dateLib.getYear(calendarMonth.date)}