Skip to content

Commit

Permalink
Refactor withIntl to be composable
Browse files Browse the repository at this point in the history
Refactor the call to withIntl to allow for HoC composing, such as:

export default compose(
  connect(...conntextOptions),
  withIntl(intlOptions)
)

This is done without changing the main API, options can still be passed
in as second arguments to withIntl too.

Add 'react-is' as a strict dependency, change the rollup config to be
able to properly build with it.
  • Loading branch information
mrijke committed May 19, 2019
1 parent 34539e0 commit 38849aa
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 3 deletions.
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -72,7 +72,8 @@
"intl-messageformat": "^2.1.0",
"intl-relativeformat": "^2.1.0",
"invariant": "^2.1.1",
"react-display-name": "^0.2.4"
"react-display-name": "^0.2.4",
"react-is": "^16.8.6"
},
"peerDependencies": {
"prop-types": "^15.5.4",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.dist.js
Expand Up @@ -41,6 +41,7 @@ export default {
}),
commonjs({
sourcemap: true,
namedExports: {'react-is': ['isValidElementType']},
}),
replace({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.lib.js
Expand Up @@ -27,7 +27,7 @@ export default {
],
plugins: [
babel(),
commonjs(),
commonjs({namedExports: {'react-is': ['isValidElementType']}}),
nodeResolve({
jsnext: true
})
Expand Down
14 changes: 13 additions & 1 deletion src/components/withIntl.js
@@ -1,4 +1,5 @@
import React, {Component, createContext} from 'react';
import {isValidElementType} from 'react-is';
import hoistNonReactStatics from 'hoist-non-react-statics';
import invariant from 'invariant';
import {invariantIntlContext} from '../utils';
Expand All @@ -13,7 +14,18 @@ const {Consumer: IntlConsumer, Provider: IntlProvider} = IntlContext;
export const Provider = IntlProvider;
export const Context = IntlContext;

export default function withIntl(WrappedComponent, options = {}) {
export default function withIntl(componentOrOptions, options) {
if (isValidElementType(componentOrOptions)) {
return createWrapper(componentOrOptions, options);
} else {
return createWrapper.bind({options: componentOrOptions});
}
}

function createWrapper(WrappedComponent, options) {
if (!options) {
options = (this && this.options) || {};
}
const {
intlPropName = 'intl',
forwardRef = false,
Expand Down
24 changes: 24 additions & 0 deletions test/unit/components/withIntl.js
Expand Up @@ -140,5 +140,29 @@ describe('withIntl()', () => {
expect(wrapperRef.current).toBe(wrapped.instance());
});
});

it('can also be used with a bound function', () => {
Wrapped = class extends React.Component {
render() {
return null;
}
};
const propName = 'myPropName';
const customWithIntl = withIntl({
forwardRef: true,
intlPropName: propName,
});
const wrapperRef = React.createRef();
const Injected = customWithIntl(Wrapped);

rendered = mountWithProvider(<Injected ref={wrapperRef} />);
const wrapped = rendered.find(Wrapped);

expect(wrapperRef.current).toBe(wrapped.instance());

const intlProvider = rendered.find(IntlProvider).childAt(0);

expect(wrapped.prop(propName)).toBe(intlProvider.instance().getContext());
});
});
});

0 comments on commit 38849aa

Please sign in to comment.