UNPKG

google-map-react

Version:

isomorphic google map react component, allows render react components on the google map

277 lines (223 loc) 9.63 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactPureRenderFunction = require('react-pure-render/function'); var _reactPureRenderFunction2 = _interopRequireDefault(_reactPureRenderFunction); var mainStyle = { width: '100%', height: '100%', left: 0, top: 0, margin: 0, padding: 0, position: 'absolute' }; var style = { width: 0, height: 0, left: 0, top: 0, backgroundColor: 'transparent', position: 'absolute' }; var GoogleMapMarkers = (function (_Component) { function GoogleMapMarkers(props) { var _this = this; _classCallCheck(this, GoogleMapMarkers); _get(Object.getPrototypeOf(GoogleMapMarkers.prototype), 'constructor', this).call(this, props); this.shouldComponentUpdate = _reactPureRenderFunction2['default']; this._getState = function () { return { children: _this.props.dispatcher.getChildren(), updateCounter: _this.props.dispatcher.getUpdateCounter() }; }; this._onChangeHandler = function () { if (!_this.dimesionsCache_) { return; } var state = _this._getState(); _this.setState(state); }; this._onChildClick = function () { if (_this.props.onChildClick) { if (_this.hoverChildProps_) { var hoverKey = _this.hoverKey_; var childProps = _this.hoverChildProps_; // click works only on hovered item _this.props.onChildClick(hoverKey, childProps); } } }; this._onChildMouseEnter = function (hoverKey, childProps) { if (!_this.dimesionsCache_) { return; } if (_this.props.onChildMouseEnter) { _this.props.onChildMouseEnter(hoverKey, childProps); } _this.hoverChildProps_ = childProps; _this.hoverKey_ = hoverKey; _this.setState({ hoverKey: hoverKey }); }; this._onChildMouseLeave = function () { if (!_this.dimesionsCache_) { return; } var hoverKey = _this.hoverKey_; var childProps = _this.hoverChildProps_; if (hoverKey !== undefined && hoverKey !== null) { if (_this.props.onChildMouseLeave) { _this.props.onChildMouseLeave(hoverKey, childProps); } _this.hoverKey_ = null; _this.hoverChildProps_ = null; _this.setState({ hoverKey: null }); } }; this._onMouseAllow = function (value) { if (!value) { _this._onChildMouseLeave(); } _this.allowMouse_ = value; }; this._onMouseChangeHandler = function () { if (_this.allowMouse_) { _this._onMouseChangeHandler_raf(); } }; this._onMouseChangeHandler_raf = function () { if (!_this.dimesionsCache_) { return; } var mp = _this.props.dispatcher.getMousePosition(); if (mp) { (function () { var distances = []; _react2['default'].Children.forEach(_this.state.children, function (child, childIndex) { var childKey = child.key !== undefined && child.key !== null ? child.key : childIndex; var dist = _this.props.distanceToMouse(_this.dimesionsCache_[childKey], mp, child.props); if (dist < _this.props.hoverDistance) { distances.push({ key: childKey, dist: dist, props: child.props }); } }); if (distances.length) { distances.sort(function (a, b) { return a.dist - b.dist; }); var hoverKey = distances[0].key; var childProps = distances[0].props; if (_this.hoverKey_ !== hoverKey) { _this._onChildMouseLeave(); _this._onChildMouseEnter(hoverKey, childProps); } } else { _this._onChildMouseLeave(); } })(); } else { _this._onChildMouseLeave(); } }; this._getDimensions = function (key) { var childKey = key; return _this.dimesionsCache_[childKey]; }; this.props.dispatcher.on('kON_CHANGE', this._onChangeHandler); this.props.dispatcher.on('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler); this.props.dispatcher.on('kON_CLICK', this._onChildClick); this.dimesionsCache_ = {}; this.hoverKey_ = null; this.hoverChildProps_ = null; this.allowMouse_ = true; this.state = _extends({}, this._getState(), { hoverKey: null }); } _inherits(GoogleMapMarkers, _Component); _createClass(GoogleMapMarkers, [{ key: 'componentWillUnmount', value: function componentWillUnmount() { this.props.dispatcher.removeListener('kON_CHANGE', this._onChangeHandler); this.props.dispatcher.removeListener('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler); this.props.dispatcher.removeListener('kON_CLICK', this._onChildClick); this.dimesionsCache_ = null; } }, { key: 'render', value: function render() { var _this2 = this; var mainElementStyle = this.props.style || mainStyle; this.dimesionsCache_ = {}; var markers = _react2['default'].Children.map(this.state.children, function (child, childIndex) { var pt = _this2.props.geoService.project({ lat: child.props.lat, lng: child.props.lng }, _this2.props.projectFromLeftTop); var stylePtPos = { left: pt.x, top: pt.y }; var dx = 0; var dy = 0; if (!_this2.props.projectFromLeftTop) { // center projection if (_this2.props.geoService.hasSize()) { dx = _this2.props.geoService.getWidth() / 2; dy = _this2.props.geoService.getHeight() / 2; } } // to prevent rerender on child element i need to pass const params $getDimensions and $dimensionKey instead of dimension object var childKey = child.key !== undefined && child.key !== null ? child.key : childIndex; _this2.dimesionsCache_[childKey] = { x: pt.x + dx, y: pt.y + dy, lat: child.props.lat, lng: child.props.lng }; return _react2['default'].createElement( 'div', { key: childKey, style: _extends({}, style, stylePtPos) }, _react2['default'].cloneElement(child, { $hover: childKey === _this2.state.hoverKey, $getDimensions: _this2._getDimensions, $dimensionKey: childKey, $geoService: _this2.props.geoService, $onMouseAllow: _this2._onMouseAllow }) ); }); return _react2['default'].createElement( 'div', { style: mainElementStyle }, markers ); } }], [{ key: 'propTypes', value: { geoService: _react.PropTypes.any, style: _react.PropTypes.any, distanceToMouse: _react.PropTypes.func, dispatcher: _react.PropTypes.any, onChildClick: _react.PropTypes.func, onChildMouseLeave: _react.PropTypes.func, onChildMouseEnter: _react.PropTypes.func, hoverDistance: _react.PropTypes.number, projectFromLeftTop: _react.PropTypes.bool }, enumerable: true }, { key: 'defaultProps', value: { projectFromLeftTop: false }, enumerable: true }]); return GoogleMapMarkers; })(_react.Component); exports['default'] = GoogleMapMarkers; module.exports = exports['default'];