Skip to content

Commit 0ed0dac

Browse files
authored
Add support for allowPartialRange (#351)
* Add support for allowPartialRange Closes #331
1 parent 01525ed commit 0ed0dac

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Displays a complete, interactive calendar.
9797
|Prop name|Description|Default value|Example values|
9898
|----|----|----|----|
9999
|activeStartDate|The beginning of a period that shall be displayed. If you wish to use React-Calendar in an uncontrolled way, use `defaultActiveStartDate` instead.|(today)|`new Date(2017, 0, 1)`|
100+
|allowPartialRange|Whether to call onChange with only partial result given `selectRange` prop.|`false`|`true`|
100101
|calendarType|Type of calendar that should be used. Can be `"ISO 8601"`, `"US"`, `"Arabic"`, or `"Hebrew"`. Setting to `"US"` or `"Hebrew"` will change the first day of the week to Sunday. Setting to `"Arabic"` will change the first day of the week to Saturday. Setting to `"Arabic"` or `"Hebrew"` will make weekends appear on Friday to Saturday.|Type of calendar most commonly used in a given locale|`"ISO 8601"`|
101102
|className|Class name(s) that will be added along with `"react-calendar"` to the main React-Calendar `<div>` element.|n/a|<ul><li>String: `"class1 class2"`</li><li>Array of strings: `["class1", "class2 class3"]`</li></ul>|
102103
|defaultActiveStartDate|The beginning of a period that shall be displayed by default. If you wish to use React-Calendar in a controlled way, use `activeStartDate` instead.|(today)|`new Date(2017, 0, 1)`|

src/Calendar.jsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ function getInitialActiveStartDate(props) {
154154
});
155155
}
156156

157-
const isSingleValue = value => value && [].concat(value).length === 1;
157+
const getIsSingleValue = value => value && [].concat(value).length === 1;
158158

159159
export default class Calendar extends Component {
160160
state = {
@@ -177,7 +177,7 @@ export default class Calendar extends Component {
177177
const { value: valueState } = this.state;
178178

179179
// In the middle of range selection, use value from state
180-
if (selectRange && isSingleValue(valueState)) {
180+
if (selectRange && getIsSingleValue(valueState)) {
181181
return valueState;
182182
}
183183

@@ -251,7 +251,11 @@ export default class Calendar extends Component {
251251
} = this;
252252

253253
const {
254-
onActiveStartDateChange, onChange, onViewChange, selectRange,
254+
allowPartialRange,
255+
onActiveStartDateChange,
256+
onChange,
257+
onViewChange,
258+
selectRange,
255259
} = this.props;
256260

257261
const prevArgs = {
@@ -291,8 +295,18 @@ export default class Calendar extends Component {
291295
}
292296

293297
if (shouldUpdate('value')) {
294-
if (!selectRange || !isSingleValue(nextState.value)) {
295-
if (onChange) onChange(nextState.value);
298+
if (onChange) {
299+
if (selectRange) {
300+
const isSingleValue = getIsSingleValue(nextState.value);
301+
302+
if (!isSingleValue) {
303+
onChange(nextState.value);
304+
} else if (allowPartialRange) {
305+
onChange([nextState.value]);
306+
}
307+
} else {
308+
onChange(nextState.value);
309+
}
296310
}
297311
}
298312

@@ -351,7 +365,7 @@ export default class Calendar extends Component {
351365
if (selectRange) {
352366
// Range selection turned on
353367
const { value: previousValue, valueType } = this;
354-
if (!isSingleValue(previousValue)) {
368+
if (!getIsSingleValue(previousValue)) {
355369
// Value has 0 or 2 elements - either way we're starting a new array
356370
// First value
357371
nextValue = getBegin(valueType, value);
@@ -620,6 +634,7 @@ const isLooseValue = PropTypes.oneOfType([
620634

621635
Calendar.propTypes = {
622636
activeStartDate: isActiveStartDate,
637+
allowPartialRange: PropTypes.bool,
623638
calendarType: isCalendarType,
624639
className: isClassName,
625640
defaultActiveStartDate: isActiveStartDate,

src/Calendar.spec.jsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ describe('Calendar', () => {
756756
expect(onChange).toHaveBeenCalledWith(new Date(2017, 0, 1, 12));
757757
});
758758

759-
it('does not call onChange function returning a range when selected one piece of a range', () => {
759+
it('does not call onChange function returning a range when selected one piece of a range by default', () => {
760760
const onChange = jest.fn();
761761
const component = shallow(
762762
<Calendar
@@ -771,6 +771,41 @@ describe('Calendar', () => {
771771
expect(onChange).not.toHaveBeenCalled();
772772
});
773773

774+
it('does not call onChange function returning a range when selected one piece of a range given allowPartialRange = false', () => {
775+
const onChange = jest.fn();
776+
const component = shallow(
777+
<Calendar
778+
allowPartialRange={false}
779+
onChange={onChange}
780+
selectRange
781+
view="month"
782+
/>,
783+
);
784+
785+
component.instance().onChange(new Date(2018, 0, 1));
786+
787+
expect(onChange).not.toHaveBeenCalled();
788+
});
789+
790+
it('calls onChange function returning a partial range when selected one piece of a range given allowPartialRange = true', () => {
791+
const onChange = jest.fn();
792+
const component = shallow(
793+
<Calendar
794+
allowPartialRange
795+
onChange={onChange}
796+
selectRange
797+
view="month"
798+
/>,
799+
);
800+
801+
component.instance().onChange(new Date(2018, 0, 1));
802+
803+
expect(onChange).toHaveBeenCalledTimes(1);
804+
expect(onChange).toHaveBeenCalledWith([
805+
new Date(2018, 0, 1),
806+
]);
807+
});
808+
774809
it('calls onChange function returning a range when selected two pieces of a range', () => {
775810
const onChange = jest.fn();
776811
const component = shallow(

0 commit comments

Comments
 (0)