diff --git a/example/build/lib.js b/example/build/lib.js index a9f80818..a96e433f 100755 --- a/example/build/lib.js +++ b/example/build/lib.js @@ -1314,67 +1314,79 @@ var Popup = (function (_MapComponent) { var props = _objectWithoutProperties(_props, ['children', 'map']); this.leafletElement = (0, _leaflet.popup)(props); + this.leafletElement.on('open', this.renderPopupContent.bind(this)); + this.leafletElement.on('close', this.removePopupContent.bind(this)); } }, { - key: 'componentDidUpdate', - value: function componentDidUpdate(prevProps) { + key: 'componentDidMount', + value: function componentDidMount() { var _props2 = this.props; - var children = _props2.children; var map = _props2.map; var popupContainer = _props2.popupContainer; var position = _props2.position; - var props = _objectWithoutProperties(_props2, ['children', 'map', 'popupContainer', 'position']); + var el = this.leafletElement; - if (children !== prevProps.children) { - var content = _react2['default'].renderToStaticMarkup(children); - if (popupContainer) { - popupContainer.bindPopup(content, props); - } else { - var el = this.leafletElement; - el.setContent(content); - if (position !== prevProps.position) el.setLatLng(position); + if (popupContainer) { + // Attach to container component + popupContainer.bindPopup(el); + } else { + // Attach to a Map + if (position) { + el.setLatLng(position); } + el.openOn(map); + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate(prevProps) { + var position = this.props.position; + + if (position !== prevProps.position) { + this.leafletElement.setLatLng(position); + } + + if (this.leafletElement._isOpen) { + this.renderPopupContent(); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { _get(Object.getPrototypeOf(Popup.prototype), 'componentWillUnmount', this).call(this); + this.removePopupContent(); this.props.map.removeLayer(this.leafletElement); } + }, { + key: 'renderPopupContent', + value: function renderPopupContent() { + if (this.props.children) { + _react2['default'].render(_react.Children.only(this.props.children), this.leafletElement._contentNode); + + this.leafletElement._updateLayout(); + this.leafletElement._updatePosition(); + this.leafletElement._adjustPan(); + } else { + this.removePopupContent(); + } + } + }, { + key: 'removePopupContent', + value: function removePopupContent() { + _react2['default'].unmountComponentAtNode(this.leafletElement._contentNode); + } }, { key: 'render', value: function render() { - var _props3 = this.props; - var children = _props3.children; - var map = _props3.map; - var popupContainer = _props3.popupContainer; - var position = _props3.position; - - var props = _objectWithoutProperties(_props3, ['children', 'map', 'popupContainer', 'position']); - - if (children) { - var content = _react2['default'].renderToStaticMarkup(children); - // Attach to container component - if (popupContainer) { - popupContainer.bindPopup(content, props); - return null; - } - // Attach to a Map - var el = this.leafletElement; - el.setContent(content); - if (position) el.setLatLng(position); - el.openOn(map); - } return null; } }], [{ key: 'propTypes', value: { - children: _react.PropTypes.oneOfType([_react.PropTypes.arrayOf(_react.PropTypes.node), _react.PropTypes.node]), + children: _react.PropTypes.node, map: _react.PropTypes.instanceOf(_leaflet.Map), - popupContainer: _react.PropTypes.node, + popupContainer: _react.PropTypes.object, position: _typesLatlng2['default'] }, enumerable: true diff --git a/lib/Popup.js b/lib/Popup.js index 6d87fd6f..ac70c919 100644 --- a/lib/Popup.js +++ b/lib/Popup.js @@ -50,67 +50,79 @@ var Popup = (function (_MapComponent) { var props = _objectWithoutProperties(_props, ['children', 'map']); this.leafletElement = (0, _leaflet.popup)(props); + this.leafletElement.on('open', this.renderPopupContent.bind(this)); + this.leafletElement.on('close', this.removePopupContent.bind(this)); } }, { - key: 'componentDidUpdate', - value: function componentDidUpdate(prevProps) { + key: 'componentDidMount', + value: function componentDidMount() { var _props2 = this.props; - var children = _props2.children; var map = _props2.map; var popupContainer = _props2.popupContainer; var position = _props2.position; - var props = _objectWithoutProperties(_props2, ['children', 'map', 'popupContainer', 'position']); + var el = this.leafletElement; - if (children !== prevProps.children) { - var content = _react2['default'].renderToStaticMarkup(children); - if (popupContainer) { - popupContainer.bindPopup(content, props); - } else { - var el = this.leafletElement; - el.setContent(content); - if (position !== prevProps.position) el.setLatLng(position); + if (popupContainer) { + // Attach to container component + popupContainer.bindPopup(el); + } else { + // Attach to a Map + if (position) { + el.setLatLng(position); } + el.openOn(map); + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate(prevProps) { + var position = this.props.position; + + if (position !== prevProps.position) { + this.leafletElement.setLatLng(position); + } + + if (this.leafletElement._isOpen) { + this.renderPopupContent(); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { _get(Object.getPrototypeOf(Popup.prototype), 'componentWillUnmount', this).call(this); + this.removePopupContent(); this.props.map.removeLayer(this.leafletElement); } + }, { + key: 'renderPopupContent', + value: function renderPopupContent() { + if (this.props.children) { + _react2['default'].render(_react.Children.only(this.props.children), this.leafletElement._contentNode); + + this.leafletElement._updateLayout(); + this.leafletElement._updatePosition(); + this.leafletElement._adjustPan(); + } else { + this.removePopupContent(); + } + } + }, { + key: 'removePopupContent', + value: function removePopupContent() { + _react2['default'].unmountComponentAtNode(this.leafletElement._contentNode); + } }, { key: 'render', value: function render() { - var _props3 = this.props; - var children = _props3.children; - var map = _props3.map; - var popupContainer = _props3.popupContainer; - var position = _props3.position; - - var props = _objectWithoutProperties(_props3, ['children', 'map', 'popupContainer', 'position']); - - if (children) { - var content = _react2['default'].renderToStaticMarkup(children); - // Attach to container component - if (popupContainer) { - popupContainer.bindPopup(content, props); - return null; - } - // Attach to a Map - var el = this.leafletElement; - el.setContent(content); - if (position) el.setLatLng(position); - el.openOn(map); - } return null; } }], [{ key: 'propTypes', value: { - children: _react.PropTypes.oneOfType([_react.PropTypes.arrayOf(_react.PropTypes.node), _react.PropTypes.node]), + children: _react.PropTypes.node, map: _react.PropTypes.instanceOf(_leaflet.Map), - popupContainer: _react.PropTypes.node, + popupContainer: _react.PropTypes.object, position: _typesLatlng2['default'] }, enumerable: true diff --git a/src/Popup.js b/src/Popup.js index a96b1e22..22239857 100644 --- a/src/Popup.js +++ b/src/Popup.js @@ -1,4 +1,4 @@ -import React, { PropTypes } from 'react'; +import React, { Children, PropTypes } from 'react'; import { Map, popup } from 'leaflet'; import latlngType from './types/latlng'; @@ -6,56 +6,77 @@ import MapComponent from './MapComponent'; export default class Popup extends MapComponent { static propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]), + children: PropTypes.node, map: PropTypes.instanceOf(Map), - popupContainer: PropTypes.node, + popupContainer: PropTypes.object, position: latlngType, }; componentWillMount() { super.componentWillMount(); const { children, map, ...props } = this.props; + this.leafletElement = popup(props); + this.leafletElement.on('open', ::this.renderPopupContent); + this.leafletElement.on('close', ::this.removePopupContent); } - componentDidUpdate(prevProps) { - const { children, map, popupContainer, position, ...props } = this.props; - if (children !== prevProps.children) { - const content = React.renderToStaticMarkup(children); - if (popupContainer) { - popupContainer.bindPopup(content, props); - } - else { - const el = this.leafletElement; - el.setContent(content); - if (position !== prevProps.position) el.setLatLng(position); + componentDidMount() { + const { map, popupContainer, position } = this.props; + const el = this.leafletElement; + + if (popupContainer) { + // Attach to container component + popupContainer.bindPopup(el); + } + else { + // Attach to a Map + if (position) { + el.setLatLng(position); } + el.openOn(map); + } + } + + componentDidUpdate(prevProps) { + const { position } = this.props; + + if (position !== prevProps.position) { + this.leafletElement.setLatLng(position); + } + + if (this.leafletElement._isOpen) { + this.renderPopupContent(); } } componentWillUnmount() { super.componentWillUnmount(); + this.removePopupContent(); this.props.map.removeLayer(this.leafletElement); } - render() { - const { children, map, popupContainer, position, ...props } = this.props; - if (children) { - const content = React.renderToStaticMarkup(children); - // Attach to container component - if (popupContainer) { - popupContainer.bindPopup(content, props); - return null; - } - // Attach to a Map - const el = this.leafletElement; - el.setContent(content); - if (position) el.setLatLng(position); - el.openOn(map); + renderPopupContent() { + if (this.props.children) { + React.render( + Children.only(this.props.children), + this.leafletElement._contentNode + ); + + this.leafletElement._updateLayout(); + this.leafletElement._updatePosition(); + this.leafletElement._adjustPan(); } + else { + this.removePopupContent(); + } + } + + removePopupContent() { + React.unmountComponentAtNode(this.leafletElement._contentNode); + } + + render() { return null; } }