Skip to content

Commit 0087d36

Browse files
authored
Merge pull request #1 from 10xjs/react-16.4-compat
Fix compatibility with React 16.4
2 parents 4456886 + 43bc8cb commit 0087d36

10 files changed

Lines changed: 4629 additions & 4305 deletions

.eslintrc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
extends:
22
- metalab
33
- metalab/react
4-
rules:
5-
complexity: 0
6-
max-len: 0
74
overrides:
85
-
96
files: "*.test.js"

.flowconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[version]
2-
0.71.0
2+
0.84.0
33

44
[include]
55
<PROJECT_ROOT>/**/node_modules

package-lock.json

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

package.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.1.5",
44
"scripts": {
55
"build": "npm run clean && npm run build:flow && npm run build:lib && npm run build:esnext",
6-
"build:flow": "ncp src lib && ncp src esnext && npx renamer --regex --find '$' --replace '.flow' '@(lib|esnext)/**/*.js'",
6+
"build:flow": "ncp src lib && ncp src esnext && npx renamer --find '$' --replace '.flow' '@(lib|esnext)/**/*.js'",
77
"build:lib": "BABEL_ENV=lib npx rollup src/index.js --file lib/index.js --config",
88
"build:esnext": "npx babel -s -d esnext src",
99
"clean": "npx rimraf lib",
@@ -31,28 +31,28 @@
3131
"react": ">=16.3.0"
3232
},
3333
"devDependencies": {
34-
"@babel/cli": "^7.0.0-beta.46",
35-
"@babel/core": "^7.0.0-beta.46",
36-
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.46",
37-
"@babel/plugin-syntax-class-properties": "^7.0.0-beta.46",
38-
"@babel/plugin-syntax-dynamic-import": "^7.0.0-beta.46",
39-
"@babel/plugin-transform-flow-strip-types": "^7.0.0-beta.46",
40-
"@babel/plugin-transform-object-assign": "^7.0.0-beta.46",
41-
"@babel/preset-env": "^7.0.0-beta.46",
42-
"@babel/preset-react": "^7.0.0-beta.46",
34+
"@babel/cli": "^7.1.2",
35+
"@babel/core": "^7.1.2",
36+
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
37+
"@babel/plugin-syntax-class-properties": "^7.0.0",
38+
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
39+
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
40+
"@babel/plugin-transform-object-assign": "^7.0.0",
41+
"@babel/preset-env": "^7.1.0",
42+
"@babel/preset-react": "^7.0.0",
4343
"babel-core": "^7.0.0-bridge.0",
44-
"eslint": "^4.19.1",
45-
"eslint-config-metalab": "^9.0.1",
46-
"flow-bin": "^0.71.0",
47-
"jest": "^22.4.3",
44+
"eslint": "^5.8.0",
45+
"eslint-config-metalab": "^10.0.0",
46+
"flow-bin": "^0.84.0",
47+
"jest": "^23.6.0",
4848
"ncp": "^2.0.0",
49-
"prettier": "^1.12.1",
50-
"react": "^16.3.2",
51-
"react-dom": "^16.3.2",
52-
"renamer": "^0.6.1",
49+
"prettier": "^1.14.3",
50+
"react": "^16.4",
51+
"react-dom": "^16.4",
52+
"renamer": "^1.1.0",
5353
"rimraf": "^2.6.2",
54-
"rollup": "^0.58.2",
55-
"rollup-plugin-babel": "^4.0.0-beta.4"
54+
"rollup": "^0.66.6",
55+
"rollup-plugin-babel": "^4.0.3"
5656
},
5757
"jest": {
5858
"modulePathIgnorePatterns": [

rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ export default {
1111
exclude: 'node_modules/**',
1212
}),
1313
],
14-
external: ['es6-error', 'react', 'hoist-non-react-statics'],
14+
external: ['react'],
1515
};

src/DateInputController.js

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,29 +98,22 @@ DateInputController.defaultProps = {
9898
};
9999

100100
DateInputController.getDerivedStateFromProps = (props: Props, state: State) => {
101-
const newValue = !areEqualDates(state.value, props.value);
102-
const newMin = !areEqualDates(state.min, props.min);
103-
const newMax = !areEqualDates(state.max, props.max);
104-
const newUTC = state.utc !== props.utc;
101+
const {value = new Date(0), min, max, utc} = props;
102+
103+
const newValue = !areEqualDates(state.props.value, value);
104+
const newMin = !areEqualDates(state.props.min, min);
105+
const newMax = !areEqualDates(state.props.max, max);
106+
const newUTC = state.props.utc !== utc;
105107

106108
// Check if any of the props that can affect state have changed.
107109
if (!newValue && !newMin && !newMax && !newUTC) {
108110
return null;
109111
}
110112

111-
let nextState = Object.assign({}, state);
112-
nextState.utc = props.utc;
113-
114-
if (newMin) {
115-
nextState.min = props.min;
116-
}
117-
118-
if (newMax) {
119-
nextState.max = props.max;
120-
}
113+
let nextState = Object.assign({}, state, {props: {value, min, max, utc}});
121114

122115
const updaters = fieldKeys.map((_, i) =>
123-
updateField(i, getDateField[i](props.value, props.utc)),
116+
updateField(i, getDateField[i](newValue ? value : state.value, utc)),
124117
);
125118

126119
// Calculate a new state from the incoming props.

src/types.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ export type FieldActions = {
3333
};
3434

3535
export type State = {
36+
props: {
37+
value: Date,
38+
min?: Date,
39+
max?: Date,
40+
utc: boolean,
41+
},
3642
value: Date,
37-
min?: Date,
38-
max?: Date,
39-
utc: boolean,
4043

4144
setFields(fields: {
4245
year?: number | string,

src/util.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const fieldKeys = ['year', 'month', 'day', 'hour', 'minute', 'second'];
4040

4141
export const dateValue = (state: State): Date => {
4242
const args = fieldKeys.map((_, i) => state[fieldKeys[i]]);
43-
if (state.utc) {
43+
if (state.props.utc) {
4444
return new Date(Date.UTC.apply(null, args));
4545
}
4646
// $ExpectError Flow doesn't like us touching Date.bind
@@ -53,11 +53,11 @@ const atMin = (state: State, index: number) => {
5353
return true;
5454
}
5555

56-
const min = state.min;
56+
const min = state.props.min;
5757
return (
5858
min &&
5959
((index === 0 ? true : atMin(state, index - 1)) &&
60-
getDateField[index](min, state.utc) >= state[fieldKeys[index]])
60+
getDateField[index](min, state.props.utc) >= state[fieldKeys[index]])
6161
);
6262
};
6363

@@ -66,11 +66,11 @@ const atMax = (state: State, index: number) => {
6666
return true;
6767
}
6868

69-
const max = state.max;
69+
const max = state.props.max;
7070
return (
7171
max &&
7272
((index === 0 ? true : atMax(state, index - 1)) &&
73-
getDateField[index](max, state.utc) <= state[fieldKeys[index]])
73+
getDateField[index](max, state.props.utc) <= state[fieldKeys[index]])
7474
);
7575
};
7676

@@ -84,21 +84,21 @@ const resolveDefaultMax = (state: State, index: number) => {
8484
};
8585

8686
export const getMin = (state: State, index: number) => {
87-
const min = state.min;
87+
const min = state.props.min;
8888
// If min date is defined and the next-largest field is at its min value...
8989
return min && atMin(state, index - 1)
9090
? // return the value of the min date at the current field...
91-
getDateField[index](min, state.utc)
91+
getDateField[index](min, state.props.utc)
9292
: // or return a default min value for the field.
9393
defaultMin[index];
9494
};
9595

9696
export const getMax = (state: State, index: number) => {
97-
const max = state.max;
97+
const max = state.props.max;
9898
// If max date is defined and the next-largest field is at its max value...
9999
return max && atMax(state, index - 1)
100100
? // return the value of the max date at the current field...
101-
getDateField[index](max, state.utc)
101+
getDateField[index](max, state.props.utc)
102102
: // or return a default max value for the field.
103103
resolveDefaultMax(state, index);
104104
};
@@ -144,16 +144,18 @@ export const getInitialState = (
144144
): {state: State, actions: FieldActions} => {
145145
const updaters = [];
146146

147+
const {value = new Date(0), min, max, utc} = target.props;
148+
147149
const actions: $Shape<FieldActions> = {};
148150
let state: $Shape<State> = {
149-
value: target.props.value === undefined ? new Date(0) : target.props.value,
150-
min: target.props.min,
151-
max: target.props.max,
152-
utc: target.props.utc,
151+
value,
152+
props: {value, min, max, utc},
153153
};
154154

155155
fieldKeys.forEach((field, i) => {
156-
updaters.push(updateField(i, getDateField[i](state.value, state.utc)));
156+
updaters.push(
157+
updateField(i, getDateField[i](state.value, state.props.utc)),
158+
);
157159

158160
const setter = (value) => {
159161
const fields = {};

test/DateInputController.test.js

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ describe('<DateInputController/>', () => {
7979
expect(state).toEqual(null);
8080
});
8181

82+
it('should default undefined value to date with value 0', () => {
83+
const instance = getInstance({value: date});
84+
85+
const nextProps = {...instance.props, value: undefined};
86+
87+
const state = DateInputController.getDerivedStateFromProps(
88+
nextProps,
89+
instance.state,
90+
);
91+
92+
expect(state.props.value.getTime()).toEqual(new Date(0).getTime());
93+
});
94+
8295
it('should return updated state if value prop has changed', () => {
8396
const instance = getInstance({value: date});
8497

@@ -99,7 +112,7 @@ describe('<DateInputController/>', () => {
99112
// $ExpectError cast nullable state as any
100113
): any);
101114

102-
const {value, day, second, ...rest} = state;
115+
const {value, day, second, props: _props, ...rest} = state;
103116

104117
expect(day).toEqual(nextDate.getDate());
105118

@@ -132,11 +145,9 @@ describe('<DateInputController/>', () => {
132145
// $ExpectError cast nullable state as any
133146
): any);
134147

135-
const {value, min, hour, hourMin, ...rest} = state;
136-
137-
expect(min).toBe(min);
148+
const {value, hour, hourMin, props, ...rest} = state;
138149

139-
expect(value.getHours()).toBe(min.getHours());
150+
expect(value.getHours()).toBe(props.min.getHours());
140151

141152
expect(hour).toBe(nextMin.getHours());
142153

@@ -166,11 +177,9 @@ describe('<DateInputController/>', () => {
166177
// $ExpectError cast nullable state as any
167178
): any);
168179

169-
const {value, max, hour, hourMax, ...rest} = state;
180+
const {value, hour, hourMax, props, ...rest} = state;
170181

171-
expect(max).toBe(max);
172-
173-
expect(value.getHours()).toBe(max.getHours());
182+
expect(value.getHours()).toBe(props.max.getHours());
174183

175184
expect(hour).toBe(nextMax.getHours());
176185

@@ -192,28 +201,42 @@ describe('<DateInputController/>', () => {
192201
): any);
193202

194203
const {
195-
max,
196204
yearMax,
197205
monthMax,
198206
dayMax,
199207
hourMax,
200208
minuteMax,
201209
secondMax,
210+
props,
202211
...rest
203212
} = state;
204213

205-
expect(max).toBe(date);
214+
expect(props.max).toBe(date);
206215

207-
expect(yearMax).toBe(max.getFullYear());
208-
expect(monthMax).toBe(max.getMonth());
209-
expect(dayMax).toBe(max.getDate());
210-
expect(hourMax).toBe(max.getHours());
211-
expect(minuteMax).toBe(max.getMinutes());
212-
expect(secondMax).toBe(max.getSeconds());
216+
expect(yearMax).toBe(props.max.getFullYear());
217+
expect(monthMax).toBe(props.max.getMonth());
218+
expect(dayMax).toBe(props.max.getDate());
219+
expect(hourMax).toBe(props.max.getHours());
220+
expect(minuteMax).toBe(props.max.getMinutes());
221+
expect(secondMax).toBe(props.max.getSeconds());
213222

214223
// it should leave remaining state value unchanged
215224
expect(shallowIntersect(rest, instance.state)).toBe(true);
216225
});
226+
227+
it('should not overwrite state change with props', () => {
228+
const instance = getInstance({value: date});
229+
230+
// Update internal state.
231+
instance.setFields({year: date.getFullYear() + 1});
232+
233+
const state = DateInputController.getDerivedStateFromProps(
234+
instance.props,
235+
instance.state,
236+
);
237+
238+
expect(state).toEqual(null);
239+
});
217240
});
218241
});
219242

test/util.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ describe('utils', () => {
208208
});
209209

210210
it('should return a Date representation of the state in UTC', () => {
211-
state.utc = true;
211+
state.props.utc = true;
212212

213213
expect(dateValue(state).getTime()).toEqual(
214214
Date.UTC(

0 commit comments

Comments
 (0)