Skip to content
This repository was archived by the owner on May 19, 2025. It is now read-only.

Commit a530f57

Browse files
committed
introduce retainEndDateOnFirstSelection prop for backwards compatibility
1 parent d20e0ea commit a530f57

File tree

4 files changed

+57
-18
lines changed

4 files changed

+57
-18
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ scroll | Object | { enabled: false }| infinite
113113
showMonthArrow | Boolean | true | show/hide month arrow button
114114
navigatorRenderer | Func | | renderer for focused date navigation area. fn(currentFocusedDate: Date, changeShownDate: func, props: object)
115115
ranges | *Object[] | [] | Defines ranges. array of range object
116-
moveRangeOnFirstSelection(DateRange) | Boolean | false | move range on startDate selection. Otherwise endDate will replace with startDate.
116+
moveRangeOnFirstSelection(DateRange) | Boolean | false | move range on startDate selection. Otherwise endDate will replace with startDate unless `retainEndDateOnFirstSelection` is set to true.
117+
retainEndDateOnFirstSelection(DateRange) | Boolean | false | Retain end date when the start date is changed, unless start date is later than end date. Ignored if `moveRangeOnFirstSelection` is set to true.
117118
onChange(Calendar) | Func | | callback function for date changes. fn(date: Date)
118119
onChange(DateRange) | Func | | callback function for range changes. fn(changes). changes contains changed ranges with new `startDate`/`endDate` properties.
119120
color(Calendar) | String | `#3d91ff` | defines color for selected date in Calendar

src/components/DateRange/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ This component extends all the props of **[Calendar](#calendar)** component. In
33
| Prop Name | Type |
44
|---|---|
55
| **moveRangeOnFirstSelection** | boolean |
6-
| **onRangeFocusChange** | function |
7-
| **rangeColors** | array |
8-
| **ranges** | array |
6+
| **retainEndDateOnFirstSelection** | boolean |
7+
| **onRangeFocusChange** | function |
8+
| **rangeColors** | array |
9+
| **ranges** | array |
910

1011

1112
#### Example: Editable Date Inputs

src/components/DateRange/index.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,38 @@ class DateRange extends Component {
1818
}
1919
calcNewSelection = (value, isSingleValue = true) => {
2020
const focusedRange = this.props.focusedRange || this.state.focusedRange;
21-
const { ranges, onChange, maxDate, moveRangeOnFirstSelection, disabledDates } = this.props;
21+
const {
22+
ranges,
23+
onChange,
24+
maxDate,
25+
moveRangeOnFirstSelection,
26+
retainEndDateOnFirstSelection,
27+
disabledDates,
28+
} = this.props;
2229
const focusedRangeIndex = focusedRange[0];
2330
const selectedRange = ranges[focusedRangeIndex];
2431
if (!selectedRange || !onChange) return {};
25-
2632
let { startDate, endDate } = selectedRange;
33+
const now = new Date();
2734
let nextFocusRange;
2835
if (!isSingleValue) {
2936
startDate = value.startDate;
3037
endDate = value.endDate;
3138
} else if (focusedRange[1] === 0) {
3239
// startDate selection
33-
const dayOffset = differenceInCalendarDays(endDate, startDate);
40+
const dayOffset = differenceInCalendarDays(endDate || now, startDate);
3441
const calculateEndDate = () => {
3542
if (moveRangeOnFirstSelection) {
3643
return addDays(value, dayOffset);
3744
}
38-
// allow continous range to stay as-is
39-
if (!endDate) {
40-
return endDate;
45+
if (retainEndDateOnFirstSelection) {
46+
// allow the unset end date to stay as-is
47+
if (!endDate) {
48+
return endDate;
49+
}
50+
return !isBefore(value, endDate) ? value : endDate;
4151
}
42-
return !isBefore(value, endDate) ? value : endDate;
52+
return value || now;
4353
};
4454
startDate = value;
4555
endDate = calculateEndDate();
@@ -140,6 +150,7 @@ DateRange.defaultProps = {
140150
classNames: {},
141151
ranges: [],
142152
moveRangeOnFirstSelection: false,
153+
retainEndDateOnFirstSelection: false,
143154
rangeColors: ['#3d91ff', '#3ecf8e', '#fed14c'],
144155
disabledDates: [],
145156
};
@@ -151,6 +162,7 @@ DateRange.propTypes = {
151162
className: PropTypes.string,
152163
ranges: PropTypes.arrayOf(rangeShape),
153164
moveRangeOnFirstSelection: PropTypes.bool,
165+
retainEndDateOnFirstSelection: PropTypes.bool,
154166
};
155167

156168
export default DateRange;

src/components/DateRange/index.test.js

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import DateRange from '../DateRange';
44
import renderer from 'react-test-renderer';
55

66
let testRenderer = null;
7+
let instance = null;
78
const endDate = new Date();
89
const startDate = subDays(endDate, 7);
910

@@ -14,30 +15,33 @@ const commonProps = {
1415
};
1516

1617
const compareRanges = (newRange, assertionRange) => {
17-
expect(isSameDay(newRange.startDate, assertionRange.startDate)).toEqual(true);
18-
expect(isSameDay(newRange.endDate, assertionRange.endDate)).toEqual(true);
18+
['startDate', 'endDate'].forEach(key => {
19+
if (!newRange[key] || !assertionRange[key]) {
20+
return expect(newRange[key]).toEqual(assertionRange[key]);
21+
}
22+
return expect(isSameDay(newRange[key], assertionRange[key])).toEqual(true);
23+
})
1924
};
2025

2126
beforeEach(() => {
2227
testRenderer = renderer.create(<DateRange {...commonProps} />);
28+
instance = testRenderer.getInstance();
2329
});
2430

2531
describe('DateRange', () => {
2632
test('Should resolve', () => {
2733
expect(DateRange).toEqual(expect.anything());
2834
});
2935

30-
test('calculate new selection without moving end date', () => {
31-
const instance = testRenderer.getInstance();
36+
test('calculate new selection by resetting end date', () => {
3237
const methodResult = instance.calcNewSelection(subDays(endDate, 10), true);
3338
compareRanges(methodResult.range, {
3439
startDate: subDays(endDate, 10),
35-
endDate,
40+
endDate: subDays(endDate, 10),
3641
});
3742
});
3843

3944
test('calculate new selection by resetting end date if start date is not before', () => {
40-
const instance = testRenderer.getInstance();
4145
const methodResult = instance.calcNewSelection(addDays(endDate, 2), true);
4246
compareRanges(methodResult.range, {
4347
startDate: addDays(endDate, 2),
@@ -47,11 +51,32 @@ describe('DateRange', () => {
4751

4852
test('calculate new selection based on moveRangeOnFirstSelection prop', () => {
4953
testRenderer.update(<DateRange {...commonProps} moveRangeOnFirstSelection />);
50-
const instance = testRenderer.getInstance();
5154
const methodResult = instance.calcNewSelection(subDays(endDate, 10), true);
5255
compareRanges(methodResult.range, {
5356
startDate: subDays(endDate, 10),
5457
endDate: subDays(endDate, 3),
5558
});
5659
});
60+
61+
test('calculate new selection by retaining end date, based on retainEndDateOnFirstSelection prop', () => {
62+
testRenderer.update(<DateRange {...commonProps} retainEndDateOnFirstSelection />);
63+
const methodResult = instance.calcNewSelection(subDays(endDate, 10), true);
64+
compareRanges(methodResult.range, {
65+
startDate: subDays(endDate, 10),
66+
endDate,
67+
});
68+
});
69+
70+
test('calculate new selection by retaining the unset end date, based on retainEndDateOnFirstSelection prop', () => {
71+
testRenderer.update(<DateRange
72+
{...commonProps}
73+
ranges={[{ ...commonProps.ranges[0], endDate: null }]}
74+
retainEndDateOnFirstSelection
75+
/>);
76+
const methodResult = instance.calcNewSelection(subDays(endDate, 10), true);
77+
compareRanges(methodResult.range, {
78+
startDate: subDays(endDate, 10),
79+
endDate: null,
80+
});
81+
});
5782
});

0 commit comments

Comments
 (0)