Skip to content

Commit 25ff3a4

Browse files
fix: prevent in-selecting-range highlight for days outside current month
Fixes #4350 When using a date range picker, selecting a start date and navigating to a different month would incorrectly highlight dates from the 1st to the same day number as the start date. This was because isInSelectingRange() didn't check if the day was outside the currently displayed month. Added an early return in isInSelectingRange() to prevent highlighting days that are displayed from adjacent months in the calendar grid. Also updated the renderDay test helper to use the day's actual month as the default instead of hardcoded month 0, and added 4 new tests to verify the fix.
1 parent 4f3d752 commit 25ff3a4

File tree

2 files changed

+100
-2
lines changed

2 files changed

+100
-2
lines changed

src/day.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ export default class Day extends Component<DayProps> {
296296

297297
const selectingDate = this.props.selectingDate ?? this.props.preSelection;
298298

299+
// Don't highlight days outside the current month
300+
if (this.isAfterMonth() || this.isBeforeMonth()) {
301+
return false;
302+
}
303+
299304
if (
300305
!(selectsStart || selectsEnd || selectsRange) ||
301306
!selectingDate ||

src/test/day_test.test.tsx

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ import Day from "../day";
1717

1818
import { safeQuerySelector } from "./test_utils";
1919

20-
function renderDay(day: Date, props = {}) {
20+
function renderDay(day: Date, props: Record<string, unknown> = {}) {
21+
const month = props.month !== undefined ? props.month : getMonth(day);
2122
return render(
22-
<Day day={day} month={0} handleOnKeyDown={() => {}} {...props} />,
23+
<Day
24+
day={day}
25+
month={month as number}
26+
handleOnKeyDown={() => {}}
27+
{...props}
28+
/>,
2329
).container;
2430
}
2531

@@ -1089,6 +1095,93 @@ describe("Day", () => {
10891095
).toBe(true);
10901096
});
10911097
});
1098+
1099+
describe("for days outside the current month", () => {
1100+
it("should not apply the in-selecting-range class for days before the current month", () => {
1101+
// Day is in the previous month but displayed in the current month's calendar
1102+
const day = newDate("2023-08-29"); // August 29
1103+
const startDate = newDate("2023-08-29"); // August 29
1104+
const selectingDate = newDate("2023-10-05"); // October 5
1105+
1106+
// Render the day as if it's displayed in September's calendar (month = 8, 0-indexed)
1107+
const container = renderDay(day, {
1108+
month: 8, // September (0-indexed)
1109+
startDate,
1110+
selectingDate,
1111+
selectsEnd: true,
1112+
});
1113+
1114+
expect(
1115+
container
1116+
.querySelector(".react-datepicker__day")
1117+
?.classList.contains(rangeDayClassName),
1118+
).toBe(false);
1119+
});
1120+
1121+
it("should not apply the in-selecting-range class for days after the current month", () => {
1122+
// Day is in the next month but displayed in the current month's calendar
1123+
const day = newDate("2023-10-01"); // October 1
1124+
const startDate = newDate("2023-08-29"); // August 29
1125+
const selectingDate = newDate("2023-10-05"); // October 5
1126+
1127+
// Render the day as if it's displayed in September's calendar (month = 8, 0-indexed)
1128+
const container = renderDay(day, {
1129+
month: 8, // September (0-indexed)
1130+
startDate,
1131+
selectingDate,
1132+
selectsEnd: true,
1133+
});
1134+
1135+
expect(
1136+
container
1137+
.querySelector(".react-datepicker__day")
1138+
?.classList.contains(rangeDayClassName),
1139+
).toBe(false);
1140+
});
1141+
1142+
it("should apply the in-selecting-range class for days within the current month", () => {
1143+
// Day is in the current month
1144+
const day = newDate("2023-09-15"); // September 15
1145+
const startDate = newDate("2023-09-10"); // September 10
1146+
const selectingDate = newDate("2023-09-20"); // September 20
1147+
1148+
// Render the day as if it's displayed in September's calendar (month = 8, 0-indexed)
1149+
const container = renderDay(day, {
1150+
month: 8, // September (0-indexed)
1151+
startDate,
1152+
selectingDate,
1153+
selectsEnd: true,
1154+
});
1155+
1156+
expect(
1157+
container
1158+
.querySelector(".react-datepicker__day")
1159+
?.classList.contains(rangeDayClassName),
1160+
).toBe(true);
1161+
});
1162+
1163+
it("should not highlight days from previous month when navigating to next month with selectsRange", () => {
1164+
// This is the exact scenario from issue #4350
1165+
// User selects August 29 as start date, navigates to October
1166+
// Days 1-29 in October should NOT be highlighted
1167+
const day = newDate("2023-09-29"); // September 29 (shown in October's calendar)
1168+
const startDate = newDate("2023-08-29"); // August 29
1169+
1170+
// Render the day as if it's displayed in October's calendar (month = 9, 0-indexed)
1171+
const container = renderDay(day, {
1172+
month: 9, // October (0-indexed)
1173+
startDate,
1174+
selectingDate: newDate("2023-10-15"),
1175+
selectsRange: true,
1176+
});
1177+
1178+
expect(
1179+
container
1180+
.querySelector(".react-datepicker__day")
1181+
?.classList.contains(rangeDayClassName),
1182+
).toBe(false);
1183+
});
1184+
});
10921185
});
10931186

10941187
describe("today", () => {

0 commit comments

Comments
 (0)