Skip to content

Commit

Permalink
swapRange prop was added > > The change adds an optional property to …
Browse files Browse the repository at this point in the history
…component that allows the functionality of swapping dates if we want to allow the end user to pick dates in any order. This is a real request from the end users, and it will be handy if you work with big date ranges.
  • Loading branch information
mirus-ua committed Apr 2, 2024
1 parent a78e0a5 commit c10c079
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs-site/src/components/Examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down
22 changes: 22 additions & 0 deletions docs-site/src/examples/rangeSwapRange.js
Original file line number Diff line number Diff line change
@@ -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 (
<DatePicker
swapRange
selected={startDate}
onChange={onChange}
startDate={startDate}
endDate={endDate}
excludeDates={[addDays(new Date(), 1), addDays(new Date(), 5)]}
selectsRange
selectsDisabledDaysInRange
inline
/>
);
};
5 changes: 5 additions & 0 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -634,6 +636,7 @@ export default class DatePicker extends React.Component {
selectsMultiple,
selectedDates,
minTime,
swapRange,
} = this.props;

if (
Expand Down Expand Up @@ -689,6 +692,8 @@ export default class DatePicker extends React.Component {
} else if (hasStartRange) {
if (changedDate === null) {
onChange([null, null], event);
} else if (isDateBefore(changedDate, startDate) && swapRange) {
onChange([changedDate, startDate], event);
} else if (isDateBefore(changedDate, startDate)) {
onChange([changedDate, null], event);
} else {
Expand Down
36 changes: 36 additions & 0 deletions test/datepicker_test.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,42 @@ describe("DatePicker", () => {
);
expect(endDate).toBeNull();
});

it("should swap dates of range when endDate set before startDate", () => {
const selected = utils.newDate();
const selectedPrevious = utils.subDays(utils.newDate(), 3);
let [startDate, endDate] = [selected, null];
const onChange = (dates = []) => {
[startDate, endDate] = dates;
};
const { container } = render(
<DatePicker
swapRange
selected={startDate}
onChange={onChange}
startDate={startDate}
endDate={endDate}
selectsRange
inline
/>,
);

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", () => {
Expand Down

0 comments on commit c10c079

Please sign in to comment.