Skip to content

Commit

Permalink
fix: calendar reset after selection (#2429)
Browse files Browse the repository at this point in the history
* Add test case

* Apply fix

* Update test

* Remove test to revert commit with bug
  • Loading branch information
gpbl authored Sep 7, 2024
1 parent c645b02 commit f3f364b
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 34 deletions.
41 changes: 41 additions & 0 deletions examples/TestCase2389.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react";

import { labelGrid } from "react-day-picker";

import { dateButton, grid, gridcell, nextButton } from "@/test/elements";
import { render } from "@/test/render";
import { user } from "@/test/user";

import { TestCase2389 } from "./TestCase2389";

const today = new Date(2024, 8, 6);

beforeAll(() => jest.setSystemTime(today));
afterAll(() => jest.useRealTimers());

beforeEach(async () => {
render(<TestCase2389 />);
});

describe("when moving to the next month", () => {
beforeEach(async () => {
await user.click(nextButton());
});
test("should display the next month", () => {
const nextMonth = new Date(2024, 9, 1);
expect(grid(labelGrid(nextMonth))).toBeVisible();
});
describe("when clicking a day button", () => {
const day = new Date(2024, 9, 10);
beforeEach(async () => {
await user.click(dateButton(day));
});
test("should select the day", async () => {
expect(gridcell(day, true)).toHaveAttribute("aria-selected", "true");
});
test("should still display the next month", () => {
const nextMonth = new Date(2024, 9, 1);
expect(grid(labelGrid(nextMonth))).toBeVisible();
});
});
});
18 changes: 18 additions & 0 deletions examples/TestCase2389.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, { useState } from "react";

import { DayPicker, DateRange } from "react-day-picker";
import "react-day-picker/style.css";

export function TestCase2389() {
const [selectedPeriod, setSelectedPeriod] = useState<DateRange | undefined>();

return (
<DayPicker
mode="range"
startMonth={new Date("2024-07-01")}
endMonth={new Date("2025-07-31")}
onSelect={setSelectedPeriod}
selected={selectedPeriod}
/>
);
}
1 change: 1 addition & 0 deletions examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export * from "./StylingModifiers";
export * from "./TailwindCSS";
export * from "./Testcase1567";
export * from "./TestCase2047";
export * from "./TestCase2389";
export * from "./Utc";
export * from "./WeekIso";
export * from "./Weeknumber";
Expand Down
16 changes: 1 addition & 15 deletions src/DayPicker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";

import { addMonths, startOfDay, startOfMonth } from "date-fns";
import { startOfDay, startOfMonth } from "date-fns";
import { defaultLocale } from "react-day-picker";

import {
Expand All @@ -16,7 +16,6 @@ import { user } from "@/test/user";
import { DayPicker } from "./DayPicker";
import { MonthProps } from "./components/Month";
import { MonthsProps } from "./components/Months";
import { labelGrid } from "./labels";

const testId = "test";
const dayPicker = () => screen.getByTestId(testId);
Expand Down Expand Up @@ -147,19 +146,6 @@ describe("when the `month` is changed programmatically", () => {
});
});

describe("when the `startMonth` is changed programmatically", () => {
test("should update the calendar to reflect the new month", async () => {
const initialStartMonth = new Date();
const newStartMonth = addMonths(new Date(), 2);
const { rerender } = render(
<DayPicker startMonth={initialStartMonth} mode="single" />
);
expect(grid(labelGrid(initialStartMonth))).toBeInTheDocument();
rerender(<DayPicker startMonth={newStartMonth} mode="single" />);
expect(grid(labelGrid(newStartMonth))).toBeInTheDocument();
});
});

test("extends the default locale", () => {
render(
<DayPicker
Expand Down
24 changes: 5 additions & 19 deletions src/useCalendar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useEffect, useState } from "react";

import type {
CalendarWeek,
CalendarDay,
Expand All @@ -14,6 +12,7 @@ import { getNavMonths } from "./helpers/getNavMonth.js";
import { getNextMonth } from "./helpers/getNextMonth.js";
import { getPreviousMonth } from "./helpers/getPreviousMonth.js";
import { getWeeks } from "./helpers/getWeeks.js";
import { useControlledValue } from "./helpers/useControlledValue.js";
import type { DayPickerProps } from "./types/props.js";
import type { DateLib } from "./types/shared.js";

Expand Down Expand Up @@ -94,23 +93,10 @@ export function useCalendar(

const initialMonth = getInitialMonth(props, dateLib);

const [firstMonth, setFirstMonth] = useState(initialMonth);

// Update the displayed month if `month` changes
useEffect(() => {
const initialDisplayMonth = getInitialMonth(props, dateLib);
setFirstMonth(initialDisplayMonth);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.month]);

// Update the displayed month if start/end month changes
useEffect(() => {
// TOFIX: this effect should do nothing if the current firstMonth is between
// startMonth and endMonth
const initialDisplayMonth = getInitialMonth(props, dateLib);
setFirstMonth(initialDisplayMonth);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.startMonth, props.endMonth]);
const [firstMonth, setFirstMonth] = useControlledValue(
initialMonth,
props.month ? startOfMonth(props.month) : undefined
);

/** The months displayed in the calendar. */
const displayMonths = getDisplayMonths(firstMonth, navEnd, props, dateLib);
Expand Down

0 comments on commit f3f364b

Please sign in to comment.