Permalink
Browse files

React 16.3 (#594)

* Attempt move to React 16.3

* Add back React as peer dep

* Add hoist-non-react-statics to connect()

* Remove any from hoistStatics in withFormik()

* Introduct FormikContext<V> interface in addition to FormikProps<V>

* Use a forked version of Enzyme that's compatible with React 16 :shrug:

* Expose WrappedComponent with connect

* Move from cWM to cDM in Formik tests

* Start to use WrappedComponent in <Field> tests

* Use WrappedComponent in FastField tests

* Fix FastField innerRef test

* Fix usage of getDerivedStateFromProps

* Remove @types/enzyme

* Add back react as a peer dependency

* Bump React version on website

* Install formik from filesystem on website

* Fix types for Field and FastField

* v1.0.0-alpha.r16.3.1

* Bump typescript version to 2.8.3

* v1.0.0-alpha.r16.3.2

* Remove Fragment and export connect()

* Fix 16.3 builds

* Use esModuleInterop

* Fix builds, expose dev build like React does

* Move types to another directory

* Fix size-limit

* Add back size-limit
  • Loading branch information...
jaredpalmer committed May 11, 2018
1 parent 5fa659a commit 4ac3cd171b521a92d4f41500049e3a477a0a71ad
Showing with 1,498 additions and 690 deletions.
  1. +1 βˆ’1 .travis.yml
  2. +7 βˆ’0 index.js
  3. +20 βˆ’22 package.json
  4. +32 βˆ’9 rollup.config.js
  5. +57 βˆ’61 src/FastField.tsx
  6. +32 βˆ’34 src/Field.tsx
  7. +33 βˆ’21 src/FieldArray.tsx
  8. +5 βˆ’9 src/Form.tsx
  9. +63 βˆ’304 src/Formik.tsx
  10. +40 βˆ’0 src/connect.tsx
  11. +2 βˆ’0 src/index.tsx
  12. +0 βˆ’23 src/types.ts
  13. +259 βˆ’0 src/types.tsx
  14. +5 βˆ’4 src/utils.ts
  15. +5 βˆ’7 src/withFormik.tsx
  16. +37 βˆ’30 test/FastField.test.tsx
  17. +27 βˆ’23 test/Field.test.tsx
  18. +6 βˆ’6 test/Formik.test.tsx
  19. +2 βˆ’2 test/setupTest.ts
  20. +1 βˆ’1 test/withFormik.test.tsx
  21. +2 βˆ’1 tsconfig.base.json
  22. +1 βˆ’1 tsconfig.json
  23. +8 βˆ’0 typepatches/index.d.ts
  24. +3 βˆ’3 website/package.json
  25. +54 βˆ’10 website/yarn.lock
  26. +796 βˆ’118 yarn.lock
@@ -5,7 +5,7 @@ env:
- CI=true

script:
- yarn test -- --runInBand --no-cache --coverage
- yarn test -- --runInBand --no-cache --coverage && yarn size

deploy:
provider: script
@@ -0,0 +1,7 @@
'use strict'

if (process.env.NODE_ENV === 'production') {
module.exports = require('./formik.cjs.production.js');
} else {
module.exports = require('./formik.cjs.development.js');
}
@@ -1,7 +1,7 @@
{
"name": "formik",
"description": "Forms in React, without tears",
"version": "1.0.0-alpha.6",
"version": "1.0.0-alpha.r16.3.2",
"license": "MIT",
"author": "Jared Palmer <jared@palmer.net>",
"repository": "jaredpalmer/formik",
@@ -15,18 +15,21 @@
"higher order component",
"hoc"
],
"main": "dist/formik.js",
"main": "dist/index.js",
"module": "dist/formik.es6.js",
"typings": "dist/index.d.ts",
"files": [
"dist"
],
"peerDependencies": {
"react": ">=15"
},
"scripts": {
"test": "jest --env=jsdom",
"test:watch": "npm run test -- --watch",
"start": "cross-env NODE_ENV=development tsc-watch --project tsconfig.base.json --onSuccess \"rollup -c\"",
"start": "cp ./index.js ./dist/index.js && cross-env NODE_ENV=development rollup -w -c | tsc -w -p tsconfig.base.json",
"prebuild": "rimraf dist",
"build": "tsc -p tsconfig.base.json && rollup -c && rimraf compiled",
"build": "cross-env NODE_ENV=production tsc -p tsconfig.base.json && rollup -c && rimraf compiled && cp ./index.js ./dist/index.js",
"prepublish": "npm run build",
"format": "prettier --trailing-comma es5 --single-quote --write 'src/**/*' 'test/**/*' 'README.md'",
"precommit": "lint-staged",
@@ -37,41 +40,36 @@
"size": "size-limit"
},
"dependencies": {
"create-react-context": "^0.2.2",
"hoist-non-react-statics": "^2.5.0",
"lodash.clonedeep": "^4.5.0",
"lodash.topath": "4.5.2",
"prop-types": "^15.5.10",
"prop-types": "^15.6.1",
"react-fast-compare": "^1.0.0",
"react-lifecycles-compat": "^3.0.2",
"warning": "^3.0.0"
},
"peerDependencies": {
"react": ">=15"
},
"optionalDependencies": {},
"devDependencies": {
"@types/enzyme": "3.1.5",
"@types/enzyme-adapter-react-16": "1.0.1",
"@pisano/enzyme": "^3.3.0-pisano.public.1",
"@pisano/enzyme-adapter-react-16": "^1.1.1-pisano.public.1",
"@types/jest": "20.0.6",
"@types/lodash.clonedeep": "^4.5.3",
"@types/lodash.topath": "4.5.3",
"@types/prop-types": "^15.5.2",
"@types/react": "16.0.28",
"@types/react-dom": "^16.0.3",
"@types/react-test-renderer": "15.5.2",
"@types/warning": "^3.0.0",
"all-contributors-cli": "^4.4.0",
"cross-env": "5.0.5",
"doctoc": "^1.3.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"husky": "0.14.3",
"jest": "^21.2.1",
"jest": "^22.4.3",
"jest-cli": "^21.2.1",
"lint-staged": "4.0.2",
"prettier": "1.11.1",
"raf": "^3.4.0",
"react": "16.2.0",
"react-dom": "16.2.0",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"rimraf": "^2.6.2",
"rollup": "^0.55.3",
"rollup-plugin-commonjs": "8.1.0",
@@ -81,11 +79,11 @@
"rollup-plugin-sourcemaps": "0.4.2",
"rollup-plugin-uglify": "^3.0.0",
"size-limit": "^0.17.0",
"ts-jest": "^21.2.4",
"tsc-watch": "1.0.17",
"ts-jest": "^22.4.6",
"tsc-watch": "^1.0.21",
"tslint": "5.5.0",
"tslint-react": "3.2.0",
"typescript": "2.8.1",
"typescript": "2.8.3",
"yup": "0.21.3"
},
"lint-staged": {
@@ -125,15 +123,15 @@
},
"size-limit": [
{
"path": "./dist/formik.js",
"path": "./dist/index.js",
"limit": "14 kB"
},
{
"path": "./dist/formik.es6.js",
"limit": "14 kB"
},
{
"path": "./dist/formik.umd.js",
"path": "./dist/formik.umd.production.js",
"limit": "14 kB"
}
]
@@ -7,18 +7,19 @@ import uglify from 'rollup-plugin-uglify';
import pkg from './package.json';

const input = './compiled/index.js';
const external = ['react', 'react-native'];

const getUMDConfig = ({ env }) => ({
const buildUmd = ({ env }) => ({
input,
external: ['react', 'react-native'],
external,
output: {
name: 'Formik',
format: 'umd',
sourcemap: true,
file:
env === 'production'
? './dist/formik.umd.min.js'
: './dist/formik.umd.js',
? `./dist/formik.umd.${env}.js`
: `./dist/formik.umd.${env}.js`,
exports: 'named',
globals: {
react: 'React',
@@ -62,14 +63,35 @@ const getUMDConfig = ({ env }) => ({
],
});

export default [
getUMDConfig({ env: 'production' }),

getUMDConfig({ env: 'development' }),
const buildCjs = ({ env }) => ({
input,
external: external.concat(Object.keys(pkg.dependencies)),
output: [
{
file: `./dist/${pkg.name}.cjs.${env}.js`,
format: 'cjs',
sourcemap: true,
},
],
plugins: [
resolve(),
replace({
exclude: 'node_modules/**',
'process.env.NODE_ENV': JSON.stringify(env),
}),
sourceMaps(),
filesize(),
],
})

export default [
buildUmd({ env: 'production' }),
buildUmd({ env: 'development' }),
buildCjs({ env: 'production' }),
buildCjs({ env: 'development' }),
{
input,
external: id => !id.startsWith('.') && !id.startsWith('/'),
external: external.concat(Object.keys(pkg.dependencies)),
output: [
{
file: pkg.module,
@@ -84,6 +106,7 @@ export default [
],
plugins: [
resolve(),

sourceMaps(),
filesize(),
],
@@ -1,10 +1,12 @@
import * as PropTypes from 'prop-types';
import * as React from 'react';
import { validateYupSchema, yupToFormErrors, FormikProps } from './Formik';
import { getIn, isPromise, setIn, isFunction, isEmptyChildren } from './utils';
import React from 'react';
import isEqual from 'react-fast-compare';
import warning from 'warning';
import { polyfill } from 'react-lifecycles-compat';
import { FieldAttributes, FieldConfig, FieldProps } from './Field';
import isEqual from 'react-fast-compare';
import { validateYupSchema, yupToFormErrors } from './Formik';
import { connect } from './connect';
import { FormikContext } from './types';
import { getIn, isEmptyChildren, isFunction, isPromise, setIn } from './utils';

export interface FastFieldState {
value: any;
@@ -20,76 +22,58 @@ function isEqualExceptForKey(a: any, b: any, path: string) {
* Custom Field component for quickly hooking into Formik
* context and wiring up forms.
*/
export class FastField<
Props extends FieldAttributes = any
> extends React.Component<Props, FastFieldState> {
static contextTypes = {
formik: PropTypes.object,
};
class FastFieldInner<Props = {}, Values = {}> extends React.Component<
FieldAttributes<Props> & { formik: FormikContext<Values> },
FastFieldState
> {
reset: (nextValues?: any) => void;

static propTypes = {
name: PropTypes.string.isRequired,
component: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
render: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
validate: PropTypes.func,
innerRef: PropTypes.func,
};
static getDerivedStateFromProps(
nextProps: any /* FieldAttributes<Props> & { formik: FormikContext<Values> }*/,
prevState: FastFieldState
) {
const nextFieldValue = getIn(nextProps.formik.values, nextProps.name);
const nextFieldError = getIn(nextProps.formik.errors, nextProps.name);

reset: Function;
constructor(props: Props, context: any) {
let nextState = null;
if (!isEqual(nextFieldValue, prevState.value)) {
nextState = { value: nextFieldValue };
}

if (!isEqual(nextFieldError, prevState.error)) {
nextState = { error: nextFieldError };
}

return nextState;
}

constructor(
props: FieldAttributes<Props> & { formik: FormikContext<Values> }
) {
super(props);
this.state = {
value: getIn(context.formik.values, props.name),
error: getIn(context.formik.errors, props.name),
value: getIn(props.formik.values, props.name),
error: getIn(props.formik.errors, props.name),
};

this.reset = (nextValues?: any) => {
this.setState({
value: getIn(nextValues, props.name),
error: getIn(context.formik.errors, props.name),
error: getIn(props.formik.errors, props.name),
});
};

context.formik.registerField(props.name, this.reset);
}

componentWillReceiveProps(
nextProps: Props,
nextContext: { formik: FormikProps<any> }
) {
const nextFieldValue = getIn(nextContext.formik.values, nextProps.name);
const nextFieldError = getIn(nextContext.formik.errors, nextProps.name);

let nextState: any;
props.formik.registerField(props.name, this.reset);

if (nextFieldValue !== this.state.value) {
nextState = { value: nextFieldValue };
}

if (nextFieldError !== this.state.error) {
nextState = { ...nextState, error: nextFieldError };
}

if (nextState) {
this.setState(s => ({ ...s, ...nextState }));
}
}

componentWillUnmount() {
this.context.formik.unregisterField(this.props.name);
}

componentWillMount() {
const { render, children, component } = this.props;
const { render, children, component } = props;

warning(
!(component && render),
'You should not use <FastField component> and <FastField render> in the same <FastField> component; <FastField component> will be ignored'
);

warning(
!(this.props.component && children && isFunction(children)),
!(props.component && children && isFunction(children)),
'You should not use <FastField component> and <FastField children> as a function in the same <FastField> component; <FastField component> will be ignored.'
);

@@ -99,6 +83,10 @@ export class FastField<
);
}

componentWillUnmount() {
this.props.formik.unregisterField(this.props.name);
}

handleChange = (e: React.ChangeEvent<any>) => {
e.persist();
const {
@@ -108,7 +96,7 @@ export class FastField<
validationSchema,
errors,
setFormikState,
} = this.context.formik;
} = this.props.formik;
const { type, value, checked } = e.target;
const val = /number|range/.test(type)
? parseFloat(value)
@@ -213,7 +201,7 @@ export class FastField<
};

handleBlur = () => {
const { validateOnBlur, setFormikState } = this.context.formik;
const { validateOnBlur, setFormikState } = this.props.formik;
const { name, validate } = this.props;

// @todo refactor
@@ -261,10 +249,14 @@ export class FastField<
render,
children,
component = 'input',
formik,
...props
} = this.props as FieldConfig;

const { formik } = this.context;
} = this.props as FieldConfig & { formik: FormikContext<Values> };
const {
validate: _validate,
validationSchema: _validationSchema,
...restOfFormik
} = formik;
const field = {
value:
props.type === 'radio' || props.type === 'checkbox'
@@ -276,7 +268,7 @@ export class FastField<
};
const bag = {
field,
form: formik,
form: restOfFormik,
meta: { touched: getIn(formik.touched, name), error: this.state.error },
};

@@ -309,3 +301,7 @@ export class FastField<
});
}
}

export const FastField = connect<FieldAttributes<any>, any>(
polyfill(FastFieldInner)
);
Oops, something went wrong.

0 comments on commit 4ac3cd1

Please sign in to comment.