diff --git a/README.md b/README.md index a07a2a7..7cbdb85 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ import loader from 'hoc-react-loader' const Component = ({ data }) =>
Component {JSON.stringify(data)}
-export default loader(Component, { print: ['data'] }) +export default loader({ print: ['data'] })(Component) ``` In this case, the loader waits for `this.props.data` to be truthy, then mounts its child component and calls `this.props.load` if it exists. This is useful when the parent has control over the injected data, or when the `Component` is connected with `redux`. `this.props.load` should be injected by the parent component or injected by a `Container` (redux). @@ -33,7 +33,7 @@ import loader from 'hoc-react-loader' const MyLoadingIndicator = () =>
Waiting...
const Component = ({ data }) =>
Component {data}
-export default loader(Component, { print: ['data'], LoadingIndicator: MyLoadingIndicator }) +export default loader({ print: ['data'], LoadingIndicator: MyLoadingIndicator })(Component) ``` ### Don't wait @@ -42,7 +42,7 @@ import loader from 'hoc-react-loader' const Component = ({ data }) =>
Component {JSON.stringify(data)}
-export default loader(Component) +export default loader()(Component) ``` In this example, the loader component doesn't wait for props. `this.props.load` is called once, but the `LoadingIndicator` component isn't displayed. @@ -52,7 +52,7 @@ import loader from 'hoc-react-loader' const Component = ({ data }) =>
Component {JSON.stringify(data)}
-export default loader(Component, { load: () => console.log('here') }) +export default loader({ load: () => console.log('here') })(Component) ``` In this case, the loader calls `this.props.load` if it exists *AND* the `load` parameter, resulting in `here` to be printed. @@ -64,7 +64,7 @@ import loader from 'hoc-react-loader' const Component = ({ data }) =>
Component {JSON.stringify(data)}
-export default loader(Component, { load: 'myLoader' }) +export default loader({ load: 'myLoader' })(Component) ``` In this case, the loader calls `this.props.myLoader` if it exists. diff --git a/build/core.js b/build/core.js index 2243c14..9be4b38 100644 --- a/build/core.js +++ b/build/core.js @@ -43,100 +43,109 @@ var getDisplayName = function getDisplayName(c) { return c.displayName || c.name || 'Component'; }; -exports.default = function (ComposedComponent) { - var _class, _temp2; - - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, +exports.default = function () { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, LoadingIndicator = _ref.LoadingIndicator, print = _ref.print, load = _ref.load; var loadFunctionName = isString(load) ? load : 'load'; + var isPrintArray = Array.isArray(print); + var isPrintFunction = isFunction(print); + var isLoadFunction = isFunction(load); + + var isLoaded = function isLoaded(props, context) { + // Print is undefined, + // we rely on 'props.loaded' if present + // if not, we directly print the component + if (print === undefined) { + var loaded = props.loaded; + + return loaded === undefined ? true : !!loaded; + } - return _temp2 = _class = function (_Component) { - _inherits(_class, _Component); + // Print is an array + // Implicitly meaning that this is an array of props + if (isPrintArray) { + return print.map(function (p) { + return Boolean(props[p]); + }).reduce(function (allProps, currentProp) { + return allProps && currentProp; + }); + } - function _class() { - var _ref2; + // Print is a function + if (isPrintFunction) { + return !!print(props, context); + } - var _temp, _this, _ret; + // Anything else + return !!print; + }; - _classCallCheck(this, _class); + return function (ComposedComponent) { + var _class, _temp2; - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + var displayName = 'Loader(' + getDisplayName(ComposedComponent) + ')'; - return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref2, [this].concat(args))), _this), _this.state = { - props: {} - }, _this.isLoaded = function () { - // Print is undefined, - // we rely on 'props.loaded' if present - // if not, we directly print the component - if (print === undefined) { - var loaded = _this.props.loaded; + return _temp2 = _class = function (_Component) { + _inherits(_class, _Component); - return loaded === undefined ? true : !!loaded; - } + function _class() { + var _ref2; - // Print is an array - // Implicitly meaning that this is an array of props - if (Array.isArray(print)) { - return print.map(function (p) { - return Boolean(_this.props[p]); - }).reduce(function (allProps, currentProp) { - return allProps && currentProp; - }); - } + var _temp, _this, _ret; - // Print is a function - if (isFunction(print)) { - return !!print(_this.props, _this.context); - } + _classCallCheck(this, _class); - // Anything else - return !!print; - }, _this.omitLoadInProps = function (props) { - var isLoadAFunction = isFunction(props[loadFunctionName]); - - if (isLoadAFunction) { - _this.setState({ - props: _extends({}, props, _defineProperty({}, loadFunctionName, undefined)) - }); - } else { - _this.setState({ props: props }); + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; } - return isLoadAFunction; - }, _this.componentWillReceiveProps = function (nextProps) { - _this.omitLoadInProps(nextProps); - }, _temp), _possibleConstructorReturn(_this, _ret); - } + return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref2, [this].concat(args))), _this), _this.state = { + props: {} + }, _this.omitLoadInProps = function (props) { + var isLoadAFunction = isFunction(props[loadFunctionName]); + + if (isLoadAFunction) { + _this.setState({ + props: _extends({}, props, _defineProperty({}, loadFunctionName, undefined)) + }); + } else { + _this.setState({ props: props }); + } + + return isLoadAFunction; + }, _this.componentWillReceiveProps = function (nextProps) { + _this.omitLoadInProps(nextProps); + }, _temp), _possibleConstructorReturn(_this, _ret); + } - _createClass(_class, [{ - key: 'componentWillMount', - value: function componentWillMount() { - // Load from hoc argument - if (isFunction(load)) { - load(this.props, this.context); + _createClass(_class, [{ + key: 'componentWillMount', + value: function componentWillMount() { + // Load from hoc argument + if (isLoadFunction) { + load(this.props, this.context); + } + + // Load from props + if (this.omitLoadInProps(this.props)) { + this.props[loadFunctionName](this.props, this.context); + } } - - // Load from props - if (this.omitLoadInProps(this.props)) { - this.props[loadFunctionName](this.props, this.context); + }, { + key: 'render', + value: function render() { + if (!isLoaded(this.props, this.context)) { + return _react2.default.createElement(LoadingIndicator, this.state.props); + } + + return _react2.default.createElement(ComposedComponent, this.state.props); } - } - }, { - key: 'render', - value: function render() { - if (!this.isLoaded()) { - return _react2.default.createElement(LoadingIndicator, this.state.props); - } - - return _react2.default.createElement(ComposedComponent, this.state.props); - } - }]); + }]); - return _class; - }(_react.Component), _class.displayName = 'Loader(' + getDisplayName(ComposedComponent) + ')', _temp2; + return _class; + }(_react.Component), _class.displayName = displayName, _temp2; + }; }; \ No newline at end of file diff --git a/build/index.js b/build/index.js index 4e8085d..85eeaba 100644 --- a/build/index.js +++ b/build/index.js @@ -18,12 +18,12 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } -exports.default = function (ComposedComponent) { - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +exports.default = function () { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _ref$LoadingIndicator = _ref.LoadingIndicator, LoadingIndicator = _ref$LoadingIndicator === undefined ? _TailSpin2.default : _ref$LoadingIndicator, rest = _objectWithoutProperties(_ref, ['LoadingIndicator']); - return (0, _core2.default)(ComposedComponent, _extends({}, rest, { LoadingIndicator: LoadingIndicator })); + return (0, _core2.default)(_extends({}, rest, { LoadingIndicator: LoadingIndicator })); }; \ No newline at end of file diff --git a/examples/package.json b/examples/package.json index 38beb6c..b538b83 100644 --- a/examples/package.json +++ b/examples/package.json @@ -51,6 +51,7 @@ "hoc-react-loader": "file:../", "lodash": "^4.15.0", "normalize.css": "~4.2.0", + "prop-types": "^15.5.8", "react": "15.3.0", "react-dom": "15.3.0", "react-highlight": "^0.8.0", diff --git a/examples/src/components/Examples/Base.jsx b/examples/src/components/Examples/Base.jsx index 2ed143f..fe2ac10 100644 --- a/examples/src/components/Examples/Base.jsx +++ b/examples/src/components/Examples/Base.jsx @@ -9,4 +9,4 @@ Base.propTypes = { className: PropTypes.string, } -export default loader(Base) +export default loader()(Base) diff --git a/examples/src/components/Examples/DontWait.jsx b/examples/src/components/Examples/DontWait.jsx index 41d100e..976bffe 100644 --- a/examples/src/components/Examples/DontWait.jsx +++ b/examples/src/components/Examples/DontWait.jsx @@ -14,4 +14,4 @@ DontWait.propTypes = { prop: PropTypes.string.isRequired, } -export default loader(DontWait, { print: true }) +export default loader({ print: true })(DontWait) diff --git a/examples/src/components/Examples/Examples.jsx b/examples/src/components/Examples/Examples.jsx index ab16a4d..1ec794e 100644 --- a/examples/src/components/Examples/Examples.jsx +++ b/examples/src/components/Examples/Examples.jsx @@ -17,7 +17,7 @@ const Examples = ({ style, className }) => ( } > @@ -39,7 +39,7 @@ const Examples = ({ style, className }) => ( } > @@ -56,7 +56,7 @@ const Examples = ({ style, className }) => ( } > @@ -73,7 +73,7 @@ const Examples = ({ style, className }) => ( } > @@ -90,7 +90,7 @@ const Examples = ({ style, className }) => ( } > diff --git a/examples/src/components/Examples/LoadingIndicator.jsx b/examples/src/components/Examples/LoadingIndicator.jsx index 61bb8d7..fec58a0 100644 --- a/examples/src/components/Examples/LoadingIndicator.jsx +++ b/examples/src/components/Examples/LoadingIndicator.jsx @@ -11,4 +11,4 @@ LoadingIndicator.propTypes = { className: PropTypes.string, } -export default loader(LoadingIndicator, { LoadingIndicator: CustomLoadingIndicator }) +export default loader({ LoadingIndicator: CustomLoadingIndicator })(LoadingIndicator) diff --git a/examples/src/components/Examples/OneParam.jsx b/examples/src/components/Examples/OneParam.jsx index bdcd13c..b25a5ce 100644 --- a/examples/src/components/Examples/OneParam.jsx +++ b/examples/src/components/Examples/OneParam.jsx @@ -14,4 +14,4 @@ OneParam.propTypes = { prop: PropTypes.string.isRequired, } -export default loader(OneParam, { print: ['prop'] }) +export default loader({ print: ['prop'] })(OneParam) diff --git a/examples/src/components/Examples/TwoParams.jsx b/examples/src/components/Examples/TwoParams.jsx index 3fd1b26..ca30cc8 100644 --- a/examples/src/components/Examples/TwoParams.jsx +++ b/examples/src/components/Examples/TwoParams.jsx @@ -15,4 +15,4 @@ TwoParams.propTypes = { prop2: PropTypes.string.isRequired, } -export default loader(TwoParams, { print: ['prop', 'prop2'] }) +export default loader({ print: ['prop', 'prop2'] })(TwoParams) diff --git a/package.json b/package.json index 8115d5f..cee34ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hoc-react-loader", - "version": "5.0.1", + "version": "6.0.0", "description": "Higher order component to call a load function from props at mount.", "main": "build/index.js", "peerDependencies": { diff --git a/src/core.jsx b/src/core.jsx index 404e600..c5009d4 100644 --- a/src/core.jsx +++ b/src/core.jsx @@ -20,7 +20,6 @@ const isString = (stringToCheck) => { const getDisplayName = c => c.displayName || c.name || 'Component' export default ( - ComposedComponent, { LoadingIndicator, print, @@ -28,79 +27,86 @@ export default ( } = {}, ) => { const loadFunctionName = isString(load) ? load : 'load' + const isPrintArray = Array.isArray(print) + const isPrintFunction = isFunction(print) + const isLoadFunction = isFunction(load) + + const isLoaded = (props, context) => { + // Print is undefined, + // we rely on 'props.loaded' if present + // if not, we directly print the component + if (print === undefined) { + const { loaded } = props + return loaded === undefined ? true : !!loaded + } - return class extends Component { - static displayName = `Loader(${getDisplayName(ComposedComponent)})` + // Print is an array + // Implicitly meaning that this is an array of props + if (isPrintArray) { + return print + .map(p => Boolean(props[p])) + .reduce((allProps, currentProp) => allProps && currentProp) + } - state = { - props: {}, + // Print is a function + if (isPrintFunction) { + return !!print(props, context) } - isLoaded = () => { - // Print is undefined, - // we rely on 'props.loaded' if present - // if not, we directly print the component - if (print === undefined) { - const { loaded } = this.props - return loaded === undefined ? true : !!loaded - } + // Anything else + return !!print + } - // Print is an array - // Implicitly meaning that this is an array of props - if (Array.isArray(print)) { - return print - .map(p => Boolean(this.props[p])) - .reduce((allProps, currentProp) => allProps && currentProp) - } + return (ComposedComponent) => { + const displayName = `Loader(${getDisplayName(ComposedComponent)})` - // Print is a function - if (isFunction(print)) { - return !!print(this.props, this.context) - } + return class extends Component { + static displayName = displayName - // Anything else - return !!print - } + state = { + props: {}, + } - omitLoadInProps = (props) => { - const isLoadAFunction = isFunction(props[loadFunctionName]) - - if (isLoadAFunction) { - this.setState({ - props: { - ...props, - [loadFunctionName]: undefined, - }, - }) - } else { - this.setState({ props }) + omitLoadInProps = (props) => { + const isLoadAFunction = isFunction(props[loadFunctionName]) + + if (isLoadAFunction) { + this.setState({ + props: { + ...props, + [loadFunctionName]: undefined, + }, + }) + } else { + this.setState({ props }) + } + + return isLoadAFunction } - return isLoadAFunction - } + componentWillMount() { + // Load from hoc argument + if (isLoadFunction) { + load(this.props, this.context) + } - componentWillMount() { - // Load from hoc argument - if (isFunction(load)) { - load(this.props, this.context) + // Load from props + if (this.omitLoadInProps(this.props)) { + this.props[loadFunctionName](this.props, this.context) + } } - // Load from props - if (this.omitLoadInProps(this.props)) { - this.props[loadFunctionName](this.props, this.context) + componentWillReceiveProps = (nextProps) => { + this.omitLoadInProps(nextProps) } - } - componentWillReceiveProps = (nextProps) => { - this.omitLoadInProps(nextProps) - } + render() { + if (!isLoaded(this.props, this.context)) { + return + } - render() { - if (!this.isLoaded()) { - return + return } - - return } } } diff --git a/src/index.jsx b/src/index.jsx index 9472756..0294017 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -2,9 +2,8 @@ import core from './core' import TailSpin from './TailSpin' export default ( - ComposedComponent, { LoadingIndicator = TailSpin, ...rest } = {}, -) => core(ComposedComponent, { ...rest, LoadingIndicator }) +) => core({ ...rest, LoadingIndicator }) diff --git a/src/index.spec.js b/src/index.spec.js index cd0a77f..bae7849 100644 --- a/src/index.spec.js +++ b/src/index.spec.js @@ -15,7 +15,7 @@ import TailSpin from './TailSpin' const Component = () =>
const LoadingIndicator = () =>
const getWrapped = (config, props) => { - const Container = loader(Component, config) + const Container = loader(config)(Component) return mount() } @@ -192,7 +192,7 @@ describe('react-loader', () => { // Load function is called // Graphic component isn't called - // Loader should be Dots + // Loader should be TailSpin loadProp.should.have.been.called.once loadProp.should.have.been.called.with(props) loadParam.should.have.been.called.once @@ -210,7 +210,7 @@ describe('react-loader', () => { // Load function is called // Graphic component isn't called - // Loader should be Dots + // Loader should be TailSpin loadProp.should.have.been.called.once loadProp.should.have.been.called.with(props) expect(wrappedComponent.find(TailSpin).node).to.be.undefined @@ -222,7 +222,7 @@ describe('react-loader', () => { const wrappedComponent = getWrapped() // Graphic component isn't called - // Dots should be printed + // TailSpin should be printed expect(wrappedComponent.find(TailSpin).node).to.be.undefined wrappedComponent.find(Component).node.should.exists })