From 0e38352613edb2ad91451562fa7d93c818325f15 Mon Sep 17 00:00:00 2001 From: gpbl Date: Wed, 16 Apr 2025 07:11:37 -0500 Subject: [PATCH 1/3] Update handleMonthChange/handleYearChange with displayIndex Signed-off-by: gpbl --- src/DayPicker.tsx | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/DayPicker.tsx b/src/DayPicker.tsx index 371b780bc2..55c698ad9c 100644 --- a/src/DayPicker.tsx +++ b/src/DayPicker.tsx @@ -1,6 +1,8 @@ import React, { useCallback, useMemo, useRef } from "react"; import type { MouseEvent, FocusEvent, KeyboardEvent, ChangeEvent } from "react"; +import { addMonths } from "date-fns"; + import { UI, DayFlag, SelectionState } from "./UI.js"; import type { CalendarDay } from "./classes/CalendarDay.js"; import { DateLib, defaultLocale } from "./classes/DateLib.js"; @@ -228,20 +230,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 +365,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 +386,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)} From de587399d4485b3bc5354e44f370598f481b8689 Mon Sep 17 00:00:00 2001 From: gpbl Date: Wed, 16 Apr 2025 07:11:49 -0500 Subject: [PATCH 2/3] Add test Signed-off-by: gpbl --- examples/MultipleMonthsWithDropdown.test.tsx | 41 ++++++++++++++++++++ examples/MultipleMonthsWithDropdown.tsx | 7 ++++ examples/index.ts | 1 + 3 files changed, 49 insertions(+) create mode 100644 examples/MultipleMonthsWithDropdown.test.tsx create mode 100644 examples/MultipleMonthsWithDropdown.tsx 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"; From 58a46fdf7cfefdb12a06ed72365b7530499b856f Mon Sep 17 00:00:00 2001 From: gpbl Date: Wed, 16 Apr 2025 07:15:17 -0500 Subject: [PATCH 3/3] Lint file Signed-off-by: gpbl --- src/DayPicker.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DayPicker.tsx b/src/DayPicker.tsx index 55c698ad9c..c0463929a3 100644 --- a/src/DayPicker.tsx +++ b/src/DayPicker.tsx @@ -1,8 +1,6 @@ import React, { useCallback, useMemo, useRef } from "react"; import type { MouseEvent, FocusEvent, KeyboardEvent, ChangeEvent } from "react"; -import { addMonths } from "date-fns"; - import { UI, DayFlag, SelectionState } from "./UI.js"; import type { CalendarDay } from "./classes/CalendarDay.js"; import { DateLib, defaultLocale } from "./classes/DateLib.js";