Skip to content

Commit 99824b9

Browse files
committed
Add support for date strings
1 parent e91d93a commit 99824b9

File tree

6 files changed

+66
-27
lines changed

6 files changed

+66
-27
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
"test-jest-coverage": "jest --coverage"
1818
},
1919
"jest": {
20+
"setupFiles": [
21+
"<rootDir>/jest.shim.js",
22+
"<rootDir>/jest.setup.js"
23+
],
2024
"collectCoverageFrom": [
2125
"**/src/**.{js,jsx}",
2226
"!**/src/entry.js"
@@ -58,7 +62,7 @@
5862
"merge-class-names": "^1.1.1",
5963
"prop-types": ">=15.5",
6064
"react": ">=15.5",
61-
"react-calendar": "^2.6.0",
65+
"react-calendar": "^2.7.0",
6266
"react-dom": ">=15.5"
6367
},
6468
"devDependencies": {

src/DateInput.jsx

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@ import {
1414
} from './shared/dates';
1515
import { setLocale } from './shared/locales';
1616
import { isMaxDate, isMinDate } from './shared/propTypes';
17+
import { between } from './shared/utils';
1718

1819
const allViews = ['century', 'decade', 'year', 'month'];
1920
const allValueTypes = [...allViews.slice(1), 'day'];
2021

22+
const datesAreDifferent = (date1, date2) => (
23+
(date1 && !date2) ||
24+
(!date1 && date2) ||
25+
(date1 && date2 && date1.getTime() !== date2.getTime())
26+
);
27+
2128
const updateInputWidth = (element) => {
2229
const span = document.createElement('span');
2330
span.innerHTML = element.value || element.placeholder;
@@ -70,30 +77,38 @@ const max = (...args) => Math.max(...args.filter(a => typeof a === 'number'));
7077
export default class DateInput extends Component {
7178
getValueFrom(value) {
7279
if (!value) {
73-
return value;
80+
return null;
7481
}
75-
const { minDate } = this.props;
82+
83+
const { minDate, maxDate } = this.props;
7684
const rawValueFrom = value instanceof Array ? value[0] : value;
77-
const valueFrom = getBegin(this.valueType, rawValueFrom);
78-
return (
79-
minDate && minDate > valueFrom ?
80-
minDate :
81-
valueFrom
82-
);
85+
const valueFromDate = new Date(rawValueFrom);
86+
87+
if (Number.isNaN(valueFromDate.getTime())) {
88+
throw new Error(`Invalid date: ${value}`);
89+
}
90+
91+
const valueFrom = getBegin(this.valueType, valueFromDate);
92+
93+
return between(valueFrom, minDate, maxDate);
8394
}
8495

8596
getValueTo(value) {
8697
if (!value) {
87-
return value;
98+
return null;
8899
}
89-
const { maxDate } = this.props;
90-
const rawValueFrom = value instanceof Array ? value[1] : value;
91-
const valueTo = getEnd(this.valueType, rawValueFrom);
92-
return (
93-
maxDate && maxDate < valueTo ?
94-
maxDate :
95-
valueTo
96-
);
100+
101+
const { minDate, maxDate } = this.props;
102+
const rawValueTo = value instanceof Array ? value[1] : value;
103+
const valueToDate = new Date(rawValueTo);
104+
105+
if (Number.isNaN(valueToDate.getTime())) {
106+
throw new Error(`Invalid date: ${value}`);
107+
}
108+
109+
const valueTo = getEnd(this.valueType, valueToDate);
110+
111+
return between(valueTo, minDate, maxDate);
97112
}
98113

99114
/**
@@ -125,15 +140,24 @@ export default class DateInput extends Component {
125140

126141
componentWillReceiveProps(nextProps) {
127142
const { props } = this;
143+
const { value: nextValue } = nextProps;
144+
const { value } = this.props;
128145

129146
if (nextProps.locale !== props.locale) {
130147
setLocale(nextProps.locale);
131148
}
132149

150+
const nextValueFrom = this.getValueFrom(nextValue);
151+
const valueFrom = this.getValueFrom(value);
152+
153+
const nextValueTo = this.getValueTo(nextValue);
154+
const valueTo = this.getValueTo(value);
155+
133156
if (
157+
// Toggling calendar visibility resets values
134158
(nextProps.isCalendarOpen !== props.isCalendarOpen) ||
135-
(!!nextProps.value !== !!props.value) ||
136-
(nextProps.value && props.value && (nextProps.value.getTime() !== props.value.getTime()))
159+
datesAreDifferent(nextValueFrom, valueFrom) ||
160+
datesAreDifferent(nextValueTo, valueTo)
137161
) {
138162
this.updateValues(nextProps);
139163
}
@@ -283,7 +307,7 @@ export default class DateInput extends Component {
283307
}
284308

285309
updateValues(props = this.props) {
286-
const { value } = props;
310+
const value = this.getValueFrom(props.value);
287311

288312
this.setState({
289313
year: value ? getYear(value) : '',
@@ -500,5 +524,8 @@ DateInput.propTypes = {
500524
onChange: PropTypes.func,
501525
returnValue: PropTypes.oneOf(['start', 'end']),
502526
required: PropTypes.bool,
503-
value: PropTypes.instanceOf(Date),
527+
value: PropTypes.oneOfType([
528+
PropTypes.string,
529+
PropTypes.instanceOf(Date),
530+
]),
504531
};

src/DatePicker.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,8 @@ DatePicker.propTypes = {
246246
required: PropTypes.bool,
247247
showNeighboringMonth: PropTypes.bool,
248248
showWeekNumbers: PropTypes.bool,
249-
value: isValue,
249+
value: PropTypes.oneOfType([
250+
PropTypes.string,
251+
isValue,
252+
]),
250253
};

src/shared/utils.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export {
2+
between,
3+
} from 'react-calendar/build/shared/utils';

test/ValueOptions.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export default class ValueOptions extends Component {
3535
type="date"
3636
value={this.startDate ? getISOLocalDate(this.startDate) : ''}
3737
/>&nbsp;
38-
<button onClick={() => this.setValue(null)}>Clear</button>
38+
<button onClick={() => this.setValue(null)}>Clear to null</button>
39+
<button onClick={() => this.setValue('')}>Clear to empty string</button>
3940
</div>
4041
</fieldset>
4142
);
@@ -45,6 +46,7 @@ export default class ValueOptions extends Component {
4546
ValueOptions.propTypes = {
4647
setState: PropTypes.func.isRequired,
4748
value: PropTypes.oneOfType([
49+
PropTypes.string,
4850
PropTypes.instanceOf(Date),
4951
PropTypes.arrayOf(PropTypes.instanceOf(Date)),
5052
]),

0 commit comments

Comments
 (0)