Skip to content

Commit

Permalink
Merge pull request #3 from wojtekmaj/react-17
Browse files Browse the repository at this point in the history
Implement compatibility with React 17
  • Loading branch information
wojtekmaj authored Mar 31, 2018
2 parents 6190d1f + 47a083b commit 2493b96
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 99 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"no-restricted-globals": "off",
"prefer-destructuring": "warn",
"prefer-spread": "warn",
"react/require-default-props": "off"
"react/require-default-props": "off",
"react/sort-comp": "off"
}
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@
"lodash.once": "^4.1.1",
"merge-class-names": "^1.1.1",
"prop-types": "^15.6.0",
"react-calendar": "^2.13.4",
"react-calendar": "^2.14.0",
"react-clock": "^2.2.1",
"react-date-picker": "^6.9.1",
"react-time-picker": "^2.3.1"
"react-date-picker": "^6.10.0",
"react-lifecycles-compat": "^1.1.0",
"react-time-picker": "^2.4.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
Expand Down
90 changes: 49 additions & 41 deletions src/DateTimeInput.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import polyfill from 'react-lifecycles-compat';

import DayInput from 'react-date-picker/dist/DateInput/DayInput';
import MonthInput from 'react-date-picker/dist/DateInput/MonthInput';
Expand All @@ -13,11 +14,11 @@ import NativeInput from './DateTimeInput/NativeInput';
import { formatDate, formatTime } from './shared/dateFormatter';
import {
getDay,
getMonth,
getYear,
getHours,
getMinutes,
getMonth,
getSeconds,
getYear,
} from './shared/dates';
import { isMaxDate, isMinDate } from './shared/propTypes';

Expand Down Expand Up @@ -64,41 +65,52 @@ const removeUnwantedCharacters = str => str
))
.join('');

export default class DateTimeInput extends Component {
state = {
year: null,
month: null,
day: null,
hour: null,
minute: null,
second: null,
}
export default class DateTimeInput extends PureComponent {
static getDerivedStateFromProps(nextProps, prevState) {
const nextState = {};

componentWillMount() {
this.updateValues();
}

componentWillReceiveProps(nextProps) {
const { value: nextValue } = nextProps;
const { value } = this.props;
/**
* If isWidgetOpen flag has changed, we have to update it.
* It's saved in state purely for use in getDerivedStateFromProps.
*/
if (nextProps.isWidgetOpen !== prevState.isWidgetOpen) {
nextState.isWidgetOpen = nextProps.isWidgetOpen;
}

/**
* If the next value is different from the current one (with an exception of situation in
* which values provided are limited by minDate and maxDate so that the dates are the same),
* get a new one.
*/
const nextValue = nextProps.value;
if (
// Toggling clock visibility resets values
(nextProps.isWidgetOpen !== this.props.isWidgetOpen) ||
datesAreDifferent(nextValue, value)
// Toggling calendar visibility resets values
nextState.isCalendarOpen || // Flag was toggled
datesAreDifferent(nextValue, prevState.value)
) {
this.updateValues(nextProps);
if (nextValue) {
nextState.year = getYear(nextValue);
nextState.month = getMonth(nextValue);
nextState.day = getDay(nextValue);
nextState.hour = getHours(nextValue);
nextState.minute = getMinutes(nextValue);
nextState.second = getSeconds(nextValue);
} else {
nextState.year = null;
nextState.month = null;
nextState.day = null;
nextState.hour = null;
nextState.minute = null;
nextState.second = null;
}
nextState.value = nextValue;
}
}

/**
* Returns value type that can be returned with currently applied settings.
*/
get valueType() {
const { maxDetail } = this.props;
return maxDetail;
return nextState;
}

state = {};

// eslint-disable-next-line class-methods-use-this
get dateDivider() {
const { locale } = this.props;
Expand Down Expand Up @@ -168,17 +180,11 @@ export default class DateTimeInput extends Component {
};
}

updateValues(props = this.props) {
const { value } = props;

this.setState({
year: value ? getYear(value) : null,
month: value ? getMonth(value) : null,
day: value ? getDay(value) : null,
hour: value ? getHours(value) : null,
minute: value ? getMinutes(value) : null,
second: value ? getSeconds(value) : null,
});
/**
* Returns value type that can be returned with currently applied settings.
*/
get valueType() {
return this.props.maxDetail;
}

onKeyDown = (event) => {
Expand Down Expand Up @@ -471,3 +477,5 @@ DateTimeInput.propTypes = {
PropTypes.instanceOf(Date),
]),
};

polyfill(DateTimeInput);
89 changes: 45 additions & 44 deletions src/DateTimePicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,24 @@ import { isMaxDate, isMinDate } from './shared/propTypes';
const allViews = ['hour', 'minute', 'second'];

export default class DateTimePicker extends PureComponent {
state = {
isCalendarOpen: this.props.isCalendarOpen,
isClockOpen: this.props.isClockOpen,
static getDerivedStateFromProps(nextProps, prevState) {
const nextState = {};

if (nextProps.isCalendarOpen !== prevState.propsIsCalendarOpen) {
nextState.isCalendarOpen = nextProps.isCalendarOpen;
nextState.propsIsCalendarOpen = nextProps.isCalendarOpen;
}

if (nextProps.isClockOpen !== prevState.propsIsClockOpen) {
nextState.isClockOpen = nextProps.isClockOpen;
nextState.propsIsClockOpen = nextProps.isClockOpen;
}

return nextState;
}

state = {};

componentDidMount() {
document.addEventListener('mousedown', this.onClick);
}
Expand All @@ -26,53 +39,12 @@ export default class DateTimePicker extends PureComponent {
document.removeEventListener('mousedown', this.onClick);
}

componentWillReceiveProps(nextProps) {
const { props } = this;

if (nextProps.isCalendarOpen !== props.isCalendarOpen) {
this.setState({ isCalendarOpen: nextProps.isCalendarOpen });
}

if (nextProps.isClockOpen !== props.isClockOpen) {
this.setState({ isClockOpen: nextProps.isClockOpen });
}
}

onClick = (event) => {
if (this.wrapper && !this.wrapper.contains(event.target)) {
this.closeWidgets();
}
}

openClock = () => {
this.setState({
isCalendarOpen: false,
isClockOpen: true,
});
}

closeWidgets = () => {
this.setState({
isCalendarOpen: false,
isClockOpen: false,
});
}

openCalendar = () => {
this.setState({
isCalendarOpen: true,
isClockOpen: false,
});
}

closeCalendar = () => {
this.setState({ isCalendarOpen: false });
}

toggleCalendar = () => {
this.setState(prevState => ({ isCalendarOpen: !prevState.isCalendarOpen }));
}

onDateChange = (value, closeWidgets = true) => {
const { value: prevValue } = this.props;

Expand Down Expand Up @@ -123,6 +95,35 @@ export default class DateTimePicker extends PureComponent {
}
}

openClock = () => {
this.setState({
isCalendarOpen: false,
isClockOpen: true,
});
}

closeWidgets = () => {
this.setState({
isCalendarOpen: false,
isClockOpen: false,
});
}

openCalendar = () => {
this.setState({
isCalendarOpen: true,
isClockOpen: false,
});
}

closeCalendar = () => {
this.setState({ isCalendarOpen: false });
}

toggleCalendar = () => {
this.setState(prevState => ({ isCalendarOpen: !prevState.isCalendarOpen }));
}

stopPropagation = event => event.stopPropagation()

clear = () => this.onChange(null);
Expand Down
24 changes: 24 additions & 0 deletions src/__tests__/DateTimeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,30 @@ describe('DateTimeInput', () => {
expect(customInputs.at(5).getDOMNode().value).toBe('0');
});

it('clears the value correctly', () => {
const date = new Date(2017, 8, 30, 22, 17, 0);

const component = mount(
<DateTimeInput
maxDetail="second"
value={date}
/>
);

component.setProps({ value: null });

const nativeInput = component.find('input[type="datetime-local"]');
const customInputs = component.find('input[type="number"]');

expect(nativeInput.getDOMNode().value).toBe('');
expect(customInputs.at(0).getDOMNode().value).toBe('');
expect(customInputs.at(1).getDOMNode().value).toBe('');
expect(customInputs.at(2).getDOMNode().value).toBe('');
expect(customInputs.at(3).getDOMNode().value).toBe('');
expect(customInputs.at(4).getDOMNode().value).toBe('');
expect(customInputs.at(5).getDOMNode().value).toBe('');
});

it('renders custom inputs in a proper order (en-US)', () => {
const component = mount(
<DateTimeInput
Expand Down
27 changes: 17 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3683,13 +3683,14 @@ rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"

react-calendar@^2.13.4:
version "2.13.4"
resolved "https://registry.yarnpkg.com/react-calendar/-/react-calendar-2.13.4.tgz#8bda746ed6d1fbe29c539bc875adbd103871665f"
react-calendar@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/react-calendar/-/react-calendar-2.14.0.tgz#03ffce0d6e64052e552aaafdd142d1764ed88b45"
dependencies:
lodash.once "^4.1.1"
merge-class-names "^1.1.1"
prop-types "^15.6.0"
react-lifecycles-compat "^1.1.0"

react-clock@^2.2.1:
version "2.2.1"
Expand All @@ -3698,15 +3699,16 @@ react-clock@^2.2.1:
merge-class-names "^1.1.1"
prop-types "^15.6.0"

react-date-picker@^6.9.1:
version "6.9.1"
resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-6.9.1.tgz#99b3e9b4d2ea28074c39cf9cd9d5fefe0568044b"
react-date-picker@^6.10.0:
version "6.10.0"
resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-6.10.0.tgz#2108e34a11f0b1f6b641fe7772d07de12039fcc2"
dependencies:
detect-element-overflow "^1.1.1"
lodash.once "^4.1.1"
merge-class-names "^1.1.1"
prop-types "^15.6.0"
react-calendar "^2.13.4"
react-calendar "^2.14.0"
react-lifecycles-compat "^1.1.0"

react-dom@^16.3.0:
version "16.3.0"
Expand All @@ -3717,6 +3719,10 @@ react-dom@^16.3.0:
object-assign "^4.1.1"
prop-types "^15.6.0"

react-lifecycles-compat@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-1.1.0.tgz#6641d0709bd5505329b5c90322147ef2d343485c"

react-reconciler@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
Expand All @@ -3734,15 +3740,16 @@ react-test-renderer@^16.0.0-0:
object-assign "^4.1.1"
prop-types "^15.6.0"

react-time-picker@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/react-time-picker/-/react-time-picker-2.3.1.tgz#4d09f6e860b108f68bde4679cb2fc3e33d475d3a"
react-time-picker@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/react-time-picker/-/react-time-picker-2.4.0.tgz#66c66848713c0a385484da560334de2b5708ff58"
dependencies:
detect-element-overflow "^1.1.1"
lodash.once "^4.1.1"
merge-class-names "^1.1.1"
prop-types "^15.6.0"
react-clock "^2.2.1"
react-lifecycles-compat "^1.1.0"

react@^16.3.0:
version "16.3.0"
Expand Down

0 comments on commit 2493b96

Please sign in to comment.