From 915f8e0e896e5ceb58c82978bdf08c301671c114 Mon Sep 17 00:00:00 2001 From: gpbl Date: Mon, 10 Oct 2022 17:09:05 -0500 Subject: [PATCH] fix: range_middle class is added to days not in the selected range (#1581) --- .../Modifiers/utils/isDateInRange.test.ts | 33 +- .../contexts/Modifiers/utils/isDateInRange.ts | 11 +- .../SelectRange/SelectRangeContext.test.ts | 23 +- .../SelectRange/SelectRangeContext.tsx | 15 +- .../__snapshots__/range.test.tsx.snap | 1269 +++++++++++++++++ .../test-integration/examples/range.test.tsx | 9 +- 6 files changed, 1338 insertions(+), 22 deletions(-) create mode 100644 website/test-integration/examples/__snapshots__/range.test.tsx.snap diff --git a/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.test.ts b/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.test.ts index 2d36276f6e..62d4915ce8 100644 --- a/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.test.ts +++ b/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.test.ts @@ -1,3 +1,4 @@ +import { addDays } from 'date-fns'; import { DateRange } from 'index'; import { isDateInRange } from './isDateInRange'; @@ -13,16 +14,32 @@ describe('when range is missing the "from" date', () => { }); describe('when range is missing the "to" date', () => { - const to = undefined; - describe('when the from date is the same as date', () => { - const range: DateRange = { from: date, to }; - const result = isDateInRange(date, range); - test('should return true', () => { - expect(result).toBe(true); - }); + const result = isDateInRange(date, { from: date, to: undefined }); + test('should return true', () => { + expect(result).toBe(true); }); - const result = isDateInRange(date, { from: undefined }); +}); + +describe('when the range dates are the same as date', () => { + const range: DateRange = { from: date, to: date }; + const result = isDateInRange(date, range); + test('should return true', () => { + expect(result).toBe(true); + }); +}); + +describe('when the range dates are the same but not as date', () => { + const range: DateRange = { from: date, to: date }; + const result = isDateInRange(addDays(date, 1), range); test('should return false', () => { expect(result).toBe(false); }); }); + +describe('when the range is inverted', () => { + const range: DateRange = { from: addDays(date, 1), to: date }; + const result = isDateInRange(date, range); + test('should return true', () => { + expect(result).toBe(true); + }); +}); diff --git a/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.ts b/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.ts index 14dff1c88c..74256adfc3 100644 --- a/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.ts +++ b/packages/react-day-picker/src/contexts/Modifiers/utils/isDateInRange.ts @@ -15,13 +15,12 @@ export function isDateInRange(date: Date, range: DateRange): boolean { if (!to) { return false; } - const isToBeforeFrom = differenceInCalendarDays(to, from) < 0; - if (to && isToBeforeFrom) { + const isRangeInverted = differenceInCalendarDays(to, from) < 0; + if (isRangeInverted) { [from, to] = [to, from]; } - - return ( + const isInRange = differenceInCalendarDays(date, from) >= 0 && - differenceInCalendarDays(to, date) >= 0 - ); + differenceInCalendarDays(to, date) >= 0; + return isInRange; } diff --git a/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.test.ts b/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.test.ts index 16f522f748..bbfd00e3d9 100644 --- a/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.test.ts +++ b/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.test.ts @@ -67,7 +67,7 @@ describe('when no days are selected', () => { stubEvent ); }); - test('should call "onSelect" with the clicked day as the "from" propx', () => { + test('should call "onSelect" with the clicked day as the "from" prop', () => { expect(initialProps.onSelect).toHaveBeenCalledWith( { from: day, to: undefined }, day, @@ -146,6 +146,27 @@ describe('when a complete range of days is selected', () => { }); }); +describe('when "from" and "to" are the same', () => { + const date = new Date(); + const selected = { from: date, to: date }; + const dayPickerProps: DayPickerRangeProps = { + ...initialProps, + selected + }; + beforeAll(() => { + setup(dayPickerProps); + }); + test('should return the "range_start" modifier with the date', () => { + expect(result.current.modifiers.range_start).toEqual([date]); + }); + test('should return the "range_end" modifier with the date', () => { + expect(result.current.modifiers.range_end).toEqual([date]); + }); + test('should return an empty "range_middle"', () => { + expect(result.current.modifiers.range_middle).toEqual([]); + }); +}); + describe('when the max number of the selected days is reached', () => { const from = today; const to = addDays(today, 6); diff --git a/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.tsx b/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.tsx index 37f9fdd421..94ae940b77 100644 --- a/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.tsx +++ b/packages/react-day-picker/src/contexts/SelectRange/SelectRangeContext.tsx @@ -1,5 +1,6 @@ import React, { createContext, ReactNode, useContext } from 'react'; +import { isSameDay } from 'date-fns'; import addDays from 'date-fns/addDays'; import differenceInCalendarDays from 'date-fns/differenceInCalendarDays'; import subDays from 'date-fns/subDays'; @@ -107,12 +108,14 @@ export function SelectRangeProviderInternal({ modifiers.range_end = [selectedFrom]; } else { modifiers.range_end = [selectedTo]; - modifiers.range_middle = [ - { - after: selectedFrom, - before: selectedTo - } - ]; + if (!isSameDay(selectedFrom, selectedTo)) { + modifiers.range_middle = [ + { + after: selectedFrom, + before: selectedTo + } + ]; + } } } diff --git a/website/test-integration/examples/__snapshots__/range.test.tsx.snap b/website/test-integration/examples/__snapshots__/range.test.tsx.snap new file mode 100644 index 0000000000..6ebf27275f --- /dev/null +++ b/website/test-integration/examples/__snapshots__/range.test.tsx.snap @@ -0,0 +1,1269 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should match the snapshot 1`] = ` +
+
+
+
+

+ November 2020 +

+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Sunday + + + + + Monday + + + + + Tuesday + + + + + Wednesday + + + + + Thursday + + + + + Friday + + + + + Saturday + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + +
+

+ November 15th, 2020 + – + November 19th, 2020 +

+
+
+
+
+`; + +exports[`when a day in the range is clicked when the day is clicked again when a day in the range is clicked again should match the snapshot 1`] = ` +
+
+
+
+

+ November 2020 +

+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Sunday + + + + + Monday + + + + + Tuesday + + + + + Wednesday + + + + + Thursday + + + + + Friday + + + + + Saturday + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + +
+

+ November 17th, 2020 + – + November 17th, 2020 +

+
+
+
+
+`; diff --git a/website/test-integration/examples/range.test.tsx b/website/test-integration/examples/range.test.tsx index 57b02d19ce..68b10cc467 100644 --- a/website/test-integration/examples/range.test.tsx +++ b/website/test-integration/examples/range.test.tsx @@ -10,8 +10,9 @@ import Example from '@examples/range'; const pastMonth = new Date(2020, 10, 15); +let firstChild: ChildNode; beforeEach(() => { - render(); + firstChild = render().container.firstChild; }); const days = [ @@ -22,6 +23,9 @@ const days = [ addDays(pastMonth, 4) ]; +test('should match the snapshot', () => { + expect(firstChild).toMatchSnapshot(); +}); test.each(days)('%s should be selected', (day) => { expect(getDayButton(day)).toHaveAttribute('aria-pressed', 'true'); }); @@ -53,6 +57,9 @@ describe('when a day in the range is clicked', () => { test('only one day should be selected', () => { expect(getAllSelectedDays()).toHaveLength(1); }); + test('should match the snapshot', () => { + expect(firstChild).toMatchSnapshot(); + }); }); }); });