diff --git a/lib/index.js b/lib/index.js
index 7e5c6f4e..978dc278 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -13,6 +13,15 @@ Object.defineProperty(exports, "withScriptjs", {
},
})
+var _withLoadjs = require("./withLoadjs")
+
+Object.defineProperty(exports, "withLoadjs", {
+ enumerable: true,
+ get: function get() {
+ return _interopRequireDefault(_withLoadjs).default
+ },
+})
+
var _withGoogleMap = require("./withGoogleMap")
Object.defineProperty(exports, "withGoogleMap", {
diff --git a/lib/withLoadjs.js b/lib/withLoadjs.js
new file mode 100644
index 00000000..a394326a
--- /dev/null
+++ b/lib/withLoadjs.js
@@ -0,0 +1,209 @@
+"use strict"
+
+Object.defineProperty(exports, "__esModule", {
+ value: true,
+})
+
+var _objectWithoutProperties2 = require("babel-runtime/helpers/objectWithoutProperties")
+
+var _objectWithoutProperties3 = _interopRequireDefault(
+ _objectWithoutProperties2
+)
+
+var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of")
+
+var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf)
+
+var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck")
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2)
+
+var _createClass2 = require("babel-runtime/helpers/createClass")
+
+var _createClass3 = _interopRequireDefault(_createClass2)
+
+var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn")
+
+var _possibleConstructorReturn3 = _interopRequireDefault(
+ _possibleConstructorReturn2
+)
+
+var _inherits2 = require("babel-runtime/helpers/inherits")
+
+var _inherits3 = _interopRequireDefault(_inherits2)
+
+var _bind2 = require("lodash/bind")
+
+var _bind3 = _interopRequireDefault(_bind2)
+
+exports.withLoadjs = withLoadjs
+
+var _invariant = require("invariant")
+
+var _invariant2 = _interopRequireDefault(_invariant)
+
+var _canUseDom = require("can-use-dom")
+
+var _canUseDom2 = _interopRequireDefault(_canUseDom)
+
+var _recompose = require("recompose")
+
+var _propTypes = require("prop-types")
+
+var _propTypes2 = _interopRequireDefault(_propTypes)
+
+var _react = require("react")
+
+var _react2 = _interopRequireDefault(_react)
+
+function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj }
+}
+
+var LOADING_STATE_NONE = "NONE"
+var LOADING_STATE_BEGIN = "BEGIN"
+var LOADING_STATE_LOADED = "LOADED"
+var LOADING_STATE_FAILED = "FAILED"
+
+function withLoadjs(BaseComponent) {
+ var factory = _react2.default.createFactory(BaseComponent)
+
+ var Container = (function(_React$PureComponent) {
+ ;(0, _inherits3.default)(Container, _React$PureComponent)
+
+ function Container() {
+ var _ref
+
+ var _temp, _this, _ret
+
+ ;(0, _classCallCheck3.default)(this, Container)
+
+ for (
+ var _len = arguments.length, args = Array(_len), _key = 0;
+ _key < _len;
+ _key++
+ ) {
+ args[_key] = arguments[_key]
+ }
+
+ return (
+ (_ret = ((_temp = ((_this = (0, _possibleConstructorReturn3.default)(
+ this,
+ (_ref =
+ Container.__proto__ ||
+ (0, _getPrototypeOf2.default)(Container)).call.apply(
+ _ref,
+ [this].concat(args)
+ )
+ )),
+ _this)),
+ (_this.state = {
+ loadingState: LOADING_STATE_NONE,
+ }),
+ (_this.isUnmounted = false),
+ (_this.handleLoaded = (0, _bind3.default)(_this.handleLoaded, _this)),
+ _temp)),
+ (0, _possibleConstructorReturn3.default)(_this, _ret)
+ )
+ }
+
+ ;(0, _createClass3.default)(Container, [
+ {
+ key: "handleLoaded",
+ value: function handleLoaded(error) {
+ if (this.isUnmounted) {
+ return
+ }
+ this.setState({
+ loadingState: error ? LOADING_STATE_FAILED : LOADING_STATE_LOADED,
+ })
+ },
+ },
+ {
+ key: "componentWillMount",
+ value: function componentWillMount() {
+ var _props = this.props,
+ loadingElement = _props.loadingElement,
+ googleMapURL = _props.googleMapURL
+
+ ;(0, _invariant2.default)(
+ !!loadingElement && !!googleMapURL,
+ "Required props loadingElement or googleMapURL is missing. You need to provide both of them."
+ )
+ },
+ },
+ {
+ key: "componentDidMount",
+ value: function componentDidMount() {
+ var _this2 = this
+
+ var loadingState = this.state.loadingState
+
+ if (loadingState !== LOADING_STATE_NONE || !_canUseDom2.default) {
+ return
+ }
+ this.setState({
+ loadingState: LOADING_STATE_BEGIN,
+ })
+ // Don't load scriptjs as a dependency since we do not want this module be used on server side.
+ // eslint-disable-next-line global-require
+ var loadjs = require("load-js")
+ var googleMapURL = this.props.googleMapURL
+
+ loadjs([
+ {
+ url: googleMapURL,
+ async: true,
+ },
+ ])
+ .then(function() {
+ return _this2.handleLoaded()
+ })
+ .catch(this.handleLoaded)
+ },
+ },
+ {
+ key: "componentWillUnmount",
+ value: function componentWillUnmount() {
+ this.isUnmounted = true
+ },
+ },
+ {
+ key: "render",
+ value: function render() {
+ var _props2 = this.props,
+ loadingElement = _props2.loadingElement,
+ failedElement = _props2.failedElement,
+ googleMapURL = _props2.googleMapURL,
+ restProps = (0, _objectWithoutProperties3.default)(_props2, [
+ "loadingElement",
+ "failedElement",
+ "googleMapURL",
+ ])
+ var loadingState = this.state.loadingState
+
+ if (loadingState === LOADING_STATE_LOADED) {
+ return factory(restProps)
+ } else if (loadingState === LOADING_STATE_FAILED) {
+ return failedElement
+ } else {
+ return loadingElement
+ }
+ },
+ },
+ ])
+ return Container
+ })(_react2.default.PureComponent)
+
+ Container.displayName =
+ "withLoadjs(" + (0, _recompose.getDisplayName)(BaseComponent) + ")"
+ Container.propTypes = {
+ loadingElement: _propTypes2.default.node.isRequired,
+ failedElement: _propTypes2.default.node.isRequired,
+ googleMapURL: _propTypes2.default.string.isRequired,
+ }
+
+ return Container
+}
+
+exports.default = withLoadjs
diff --git a/package.json b/package.json
index e3d34ff9..0c2190bc 100644
--- a/package.json
+++ b/package.json
@@ -104,6 +104,7 @@
"can-use-dom": "^0.1.0",
"google-maps-infobox": "^2.0.0",
"invariant": "^2.2.1",
+ "load-js": "^3.0.2",
"lodash": "^4.16.2",
"marker-clusterer-plus": "^2.1.4",
"markerwithlabel": "^2.0.1",
diff --git a/src/index.js b/src/index.js
index 2b40d439..0744111d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,5 +1,7 @@
export { default as withScriptjs } from "./withScriptjs"
+export { default as withLoadjs } from "./withLoadjs"
+
export { default as withGoogleMap } from "./withGoogleMap"
export { default as GoogleMap } from "./components/GoogleMap"
diff --git a/src/withLoadjs.jsx b/src/withLoadjs.jsx
new file mode 100644
index 00000000..7a3074bb
--- /dev/null
+++ b/src/withLoadjs.jsx
@@ -0,0 +1,99 @@
+import _ from "lodash"
+import invariant from "invariant"
+import canUseDOM from "can-use-dom"
+import { getDisplayName } from "recompose"
+import PropTypes from "prop-types"
+import React from "react"
+
+const LOADING_STATE_NONE = `NONE`
+const LOADING_STATE_BEGIN = `BEGIN`
+const LOADING_STATE_LOADED = `LOADED`
+const LOADING_STATE_FAILED = `FAILED`
+
+export function withLoadjs(BaseComponent) {
+ const factory = React.createFactory(BaseComponent)
+
+ class Container extends React.PureComponent {
+ static displayName = `withLoadjs(${getDisplayName(BaseComponent)})`
+
+ static propTypes = {
+ loadingElement: PropTypes.node.isRequired,
+ failedElement: PropTypes.node.isRequired,
+ googleMapURL: PropTypes.string.isRequired,
+ }
+
+ state = {
+ loadingState: LOADING_STATE_NONE,
+ }
+
+ isUnmounted = false
+
+ handleLoaded = _.bind(this.handleLoaded, this)
+
+ handleLoaded(error) {
+ if (this.isUnmounted) {
+ return
+ }
+ this.setState({
+ loadingState: error ? LOADING_STATE_FAILED : LOADING_STATE_LOADED,
+ })
+ }
+
+ componentWillMount() {
+ const { loadingElement, googleMapURL } = this.props
+ invariant(
+ !!loadingElement && !!googleMapURL,
+ `Required props loadingElement or googleMapURL is missing. You need to provide both of them.`
+ )
+ }
+
+ componentDidMount() {
+ const { loadingState } = this.state
+ if (loadingState !== LOADING_STATE_NONE || !canUseDOM) {
+ return
+ }
+ this.setState({
+ loadingState: LOADING_STATE_BEGIN,
+ })
+ // Don't load scriptjs as a dependency since we do not want this module be used on server side.
+ // eslint-disable-next-line global-require
+ const loadjs = require(`load-js`)
+ const { googleMapURL } = this.props
+ loadjs([
+ {
+ url: googleMapURL,
+ async: true,
+ },
+ ])
+ .then(() => this.handleLoaded())
+ .catch(this.handleLoaded)
+ }
+
+ componentWillUnmount() {
+ this.isUnmounted = true
+ }
+
+ render() {
+ const {
+ loadingElement,
+ failedElement,
+ googleMapURL, // eslint-disable-line no-unused-vars
+ ...restProps
+ } = this.props
+
+ const { loadingState } = this.state
+
+ if (loadingState === LOADING_STATE_LOADED) {
+ return factory(restProps)
+ } else if (loadingState === LOADING_STATE_FAILED) {
+ return failedElement
+ } else {
+ return loadingElement
+ }
+ }
+ }
+
+ return Container
+}
+
+export default withLoadjs
diff --git a/src/withLoadjs.md b/src/withLoadjs.md
new file mode 100644
index 00000000..27e6925a
--- /dev/null
+++ b/src/withLoadjs.md
@@ -0,0 +1,35 @@
+### Props
+
+* googleMapURL: String
+* loadingElement: ReactElement
+* failedElement: ReactElement
+
+### Usage
+
+```jsx static
+import {
+ withLoadjs,
+ withGoogleMap,
+ GoogleMap,
+ Marker,
+} from "react-google-maps";
+
+const MapWithAMarker = withLoadjs(withGoogleMap(props =>
+
(wrappedComponent: ComponentClass
): ComponentClass
}
+declare module 'react-google-maps/lib/withLoadjs' {
+ import { ComponentClass, ReactElement } from 'react'
+
+ export interface WithLoadjsProps {
+ googleMapURL: string
+ loadingElement: ReactElement (wrappedComponent: ComponentClass ): ComponentClass
+}
+
declare module 'react-google-maps/lib/components/addons/InfoBox' {
import { Component } from 'react'
import { InfoBoxOptions } from 'google-maps-infobox'
diff --git a/yarn.lock b/yarn.lock
index 2a8bdddb..5487cce4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5345,6 +5345,10 @@ listr@^0.13.0:
stream-to-observable "^0.2.0"
strip-ansi "^3.0.1"
+load-js@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/load-js/-/load-js-3.0.2.tgz#3eb5c0a0f1fd1fc45567030d9f2622534b75462c"
+
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"