diff --git a/docs-site/src/components/Examples/index.js b/docs-site/src/components/Examples/index.js
index fef9e6f2f..b7120c0eb 100644
--- a/docs-site/src/components/Examples/index.js
+++ b/docs-site/src/components/Examples/index.js
@@ -105,6 +105,7 @@ import SelectsMultiple from "../../examples/selectsMultiple";
import CalendarIconExternal from "../../examples/calendarIconExternal";
import CalendarIconSvgIcon from "../../examples/calendarIconSvgIcon";
import ToggleCalendarOnIconClick from "../../examples/toggleCalendarOnIconClick";
+import SwapRange from "../../examples/rangeSwapRange";
import "./style.scss";
import "react-datepicker/dist/react-datepicker.css";
@@ -461,6 +462,12 @@ export default class exampleComponents extends React.Component {
title: "Range Quarter Picker for one quarter picker",
component: RangeQuarterPickerSelectsRange,
},
+ {
+ title: "Range Swap Range",
+ description:
+ "Swap the start and end date if the end date is before the start date in a pick sequence.",
+ component: SwapRange,
+ },
{
title: "Read only datepicker",
component: ReadOnly,
diff --git a/docs-site/src/examples/rangeSwapRange.js b/docs-site/src/examples/rangeSwapRange.js
new file mode 100644
index 000000000..d78e30da3
--- /dev/null
+++ b/docs-site/src/examples/rangeSwapRange.js
@@ -0,0 +1,22 @@
+() => {
+ const [startDate, setStartDate] = useState(new Date());
+ const [endDate, setEndDate] = useState(null);
+ const onChange = (dates) => {
+ const [start, end] = dates;
+ setStartDate(start);
+ setEndDate(end);
+ };
+ return (
+
+ );
+};
diff --git a/src/index.jsx b/src/index.jsx
index 03d84ba3f..5168b25d3 100644
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -115,6 +115,7 @@ export default class DatePicker extends React.Component {
showQuarterYearPicker: false,
showWeekPicker: false,
strictParsing: false,
+ swapRange: false,
timeIntervals: 30,
timeCaption: "Time",
previousMonthAriaLabel: "Previous Month",
@@ -253,6 +254,7 @@ export default class DatePicker extends React.Component {
showWeekNumbers: PropTypes.bool,
showYearDropdown: PropTypes.bool,
strictParsing: PropTypes.bool,
+ swapRange: PropTypes.bool,
forceShowMonthNavigation: PropTypes.bool,
showDisabledMonthNavigation: PropTypes.bool,
startDate: PropTypes.instanceOf(Date),
@@ -634,6 +636,7 @@ export default class DatePicker extends React.Component {
selectsMultiple,
selectedDates,
minTime,
+ swapRange,
} = this.props;
if (
@@ -690,7 +693,11 @@ export default class DatePicker extends React.Component {
if (changedDate === null) {
onChange([null, null], event);
} else if (isDateBefore(changedDate, startDate)) {
- onChange([changedDate, null], event);
+ if (swapRange) {
+ onChange([changedDate, startDate], event);
+ } else {
+ onChange([changedDate, null], event);
+ }
} else {
onChange([startDate, changedDate], event);
}
diff --git a/test/datepicker_test.test.js b/test/datepicker_test.test.js
index bd2c7b372..bc51ebcb1 100644
--- a/test/datepicker_test.test.js
+++ b/test/datepicker_test.test.js
@@ -2217,6 +2217,42 @@ describe("DatePicker", () => {
);
expect(endDate).toBeNull();
});
+
+ it("should swap dates of range when endDate set before startDate", () => {
+ const selected = utils.newDate("2024-04-03");
+ const selectedPrevious = utils.subDays(selected, 3);
+ let [startDate, endDate] = [selected, null];
+ const onChange = (dates = []) => {
+ [startDate, endDate] = dates;
+ };
+ const { container } = render(
+ ,
+ );
+
+ let selectedDay = findSelectedDay(container, selectedPrevious);
+ // Ensure that we're dealing with a date at the beginning of the month
+ if (!selectedDay) {
+ // If it's the beginning of the month & if the selectedPrevious is not being displayed, navigate to the previous month and reselect the selectedPrevious
+ goToLastMonth(container);
+ selectedDay = findSelectedDay(container, selectedPrevious);
+ }
+
+ fireEvent.click(selectedDay);
+ expect(utils.formatDate(startDate, "yyyy-MM-dd")).toBe(
+ utils.formatDate(selectedPrevious, "yyyy-MM-dd"),
+ );
+ expect(utils.formatDate(endDate, "yyyy-MM-dd")).toBe(
+ utils.formatDate(selected, "yyyy-MM-dd"),
+ );
+ });
});
describe("selectsRange without inline", () => {