Skip to content

Commit 65d7c82

Browse files
Merge pull request #5800 from ilchenkoArtem/fix-reverse-range
fix: Improve behaviour of highlight dates with swapRange
2 parents cf2eaa1 + 0b685f0 commit 65d7c82

File tree

2 files changed

+186
-14
lines changed

2 files changed

+186
-14
lines changed

src/day.tsx

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ interface DayProps
6767
locale?: Locale;
6868
monthShowsDuplicateDaysEnd?: boolean;
6969
monthShowsDuplicateDaysStart?: boolean;
70+
swapRange?: boolean;
7071
}
7172

7273
/**
@@ -288,6 +289,7 @@ export default class Day extends Component<DayProps> {
288289
selectsRange,
289290
selectsDisabledDaysInRange,
290291
startDate,
292+
swapRange,
291293
endDate,
292294
} = this.props;
293295

@@ -317,13 +319,18 @@ export default class Day extends Component<DayProps> {
317319
return isDayInRange(day, startDate, selectingDate);
318320
}
319321

320-
if (
321-
selectsRange &&
322-
startDate &&
323-
!endDate &&
324-
(isAfter(selectingDate, startDate) || isEqual(selectingDate, startDate))
325-
) {
326-
return isDayInRange(day, startDate, selectingDate);
322+
if (selectsRange && startDate && !endDate) {
323+
if (isEqual(selectingDate, startDate)) {
324+
return isDayInRange(day, startDate, selectingDate);
325+
}
326+
327+
if (isAfter(selectingDate, startDate)) {
328+
return isDayInRange(day, startDate, selectingDate);
329+
}
330+
331+
if (swapRange && isBefore(selectingDate, startDate)) {
332+
return isDayInRange(day, selectingDate, startDate);
333+
}
327334
}
328335

329336
return false;
@@ -334,29 +341,49 @@ export default class Day extends Component<DayProps> {
334341
return false;
335342
}
336343

337-
const { day, startDate, selectsStart } = this.props;
344+
const { day, startDate, selectsStart, swapRange, selectsRange } =
345+
this.props;
338346
const selectingDate = this.props.selectingDate ?? this.props.preSelection;
339347

340348
if (selectsStart) {
341349
return isSameDay(day, selectingDate);
342-
} else {
343-
return isSameDay(day, startDate);
344350
}
351+
352+
if (selectsRange && swapRange && startDate && selectingDate) {
353+
return isSameDay(
354+
day,
355+
isBefore(selectingDate, startDate) ? selectingDate : startDate,
356+
);
357+
}
358+
359+
return isSameDay(day, startDate);
345360
};
346361

347362
isSelectingRangeEnd = () => {
348363
if (!this.isInSelectingRange()) {
349364
return false;
350365
}
351366

352-
const { day, endDate, selectsEnd, selectsRange } = this.props;
367+
const { day, endDate, selectsEnd, selectsRange, swapRange, startDate } =
368+
this.props;
353369
const selectingDate = this.props.selectingDate ?? this.props.preSelection;
354370

355-
if (selectsEnd || selectsRange) {
371+
if (selectsEnd) {
372+
return isSameDay(day, selectingDate);
373+
}
374+
375+
if (selectsRange && swapRange && startDate && selectingDate) {
376+
return isSameDay(
377+
day,
378+
isBefore(selectingDate, startDate) ? startDate : selectingDate,
379+
);
380+
}
381+
382+
if (selectsRange) {
356383
return isSameDay(day, selectingDate);
357-
} else {
358-
return isSameDay(day, endDate);
359384
}
385+
386+
return isSameDay(day, endDate);
360387
};
361388

362389
isRangeStart = () => {

src/test/day_test.test.tsx

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,151 @@ describe("Day", () => {
896896
).toBe(true);
897897
});
898898
});
899+
900+
describe("for a date picker with selectsRange and swapRange prop", () => {
901+
it("should select range from startDate to selectingDate if selectingDate is after startDate", () => {
902+
const startDate = newDate();
903+
const dayInRange = addDays(startDate, 1);
904+
const selectingDate = addDays(startDate, 2);
905+
906+
const containerStartDay = renderDay(dayInRange, {
907+
startDate,
908+
selectingDate,
909+
selectsRange: true,
910+
swapRange: true,
911+
});
912+
expect(
913+
containerStartDay
914+
.querySelector(".react-datepicker__day")
915+
?.classList.contains(rangeDayClassName),
916+
).toBe(true);
917+
});
918+
919+
it("should select range from selectingDate to startDate if selectingDate is before startDate", () => {
920+
const startDate = newDate();
921+
const dayInRange = subDays(startDate, 1);
922+
const selectingDate = subDays(startDate, 2);
923+
924+
const containerStartDay = renderDay(dayInRange, {
925+
startDate,
926+
selectingDate,
927+
selectsRange: true,
928+
swapRange: true,
929+
});
930+
expect(
931+
containerStartDay
932+
.querySelector(".react-datepicker__day")
933+
?.classList.contains(rangeDayClassName),
934+
).toBe(true);
935+
});
936+
937+
it("should select as range if selectingDate is equal to startDate", () => {
938+
const startDate = newDate();
939+
const selectingDate = startDate;
940+
941+
const containerStartDay = renderDay(startDate, {
942+
startDate,
943+
selectingDate,
944+
selectsRange: true,
945+
swapRange: true,
946+
});
947+
expect(
948+
containerStartDay
949+
.querySelector(".react-datepicker__day")
950+
?.classList.contains(rangeDayClassName),
951+
).toBe(true);
952+
});
953+
954+
it("should set selectingDate as the start of range and startDate as the end of range if selectingDate is before startDate", () => {
955+
const startDate = newDate();
956+
const selectingDate = subDays(startDate, 1);
957+
958+
const containerStartDay = renderDay(selectingDate, {
959+
startDate,
960+
selectingDate,
961+
selectsRange: true,
962+
swapRange: true,
963+
});
964+
expect(
965+
containerStartDay
966+
.querySelector(".react-datepicker__day")
967+
?.classList.contains(rangeDayStartClassName),
968+
).toBe(true);
969+
970+
const containerEndDay = renderDay(startDate, {
971+
startDate,
972+
selectingDate,
973+
selectsRange: true,
974+
swapRange: true,
975+
});
976+
977+
expect(
978+
containerEndDay
979+
.querySelector(".react-datepicker__day")
980+
?.classList.contains(rangeDayEndClassName),
981+
).toBe(true);
982+
});
983+
984+
it("should set selectingDate as the end of range and startDate as the start of range if selectingDate is after startDate", () => {
985+
const startDate = newDate();
986+
const selectingDate = addDays(startDate, 1);
987+
988+
const containerStartDay = renderDay(startDate, {
989+
startDate,
990+
selectingDate,
991+
selectsRange: true,
992+
swapRange: true,
993+
});
994+
expect(
995+
containerStartDay
996+
.querySelector(".react-datepicker__day")
997+
?.classList.contains(rangeDayStartClassName),
998+
).toBe(true);
999+
1000+
const containerEndDay = renderDay(selectingDate, {
1001+
startDate,
1002+
selectingDate,
1003+
selectsRange: true,
1004+
swapRange: true,
1005+
});
1006+
1007+
expect(
1008+
containerEndDay
1009+
.querySelector(".react-datepicker__day")
1010+
?.classList.contains(rangeDayEndClassName),
1011+
).toBe(true);
1012+
});
1013+
1014+
it("should set startDate as the end and start range if selectionDate equal startDate", () => {
1015+
const startDate = newDate();
1016+
const selectingDate = startDate;
1017+
1018+
const containerStartDay = renderDay(startDate, {
1019+
startDate,
1020+
selectingDate,
1021+
selectsRange: true,
1022+
swapRange: true,
1023+
});
1024+
expect(
1025+
containerStartDay
1026+
.querySelector(".react-datepicker__day")
1027+
?.classList.contains(rangeDayStartClassName),
1028+
).toBe(true);
1029+
1030+
const containerEndDay = renderDay(selectingDate, {
1031+
startDate,
1032+
selectingDate,
1033+
selectsRange: true,
1034+
swapRange: true,
1035+
});
1036+
1037+
expect(
1038+
containerEndDay
1039+
.querySelector(".react-datepicker__day")
1040+
?.classList.contains(rangeDayEndClassName),
1041+
).toBe(true);
1042+
});
1043+
});
8991044
});
9001045

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

0 commit comments

Comments
 (0)