import React from 'react';
import PropTypes from 'prop-types';
/**
* The component designed to implement the google.maps.Marker from the javascript api. <Marker /> components live within the context of any <Map /> component.
* @memberof Map
* @property {object} state
* @property {google.maps.Marker} state.Marker
* @property {object} props
* @property {google.maps.Map} props.map
* @property {google.maps} props.maps
* @property {object} props.coords Defines the coordinate pair where this marker should exits.
* @property {number} props.coords.lng Number defining longitude.
* @property {number} props.coords.lat Number defining latitude.
* @property {string|Icon} props.icon
* @property {google.maps.MarkerOptions} props.options See [Marker Options Documentation]{@link https://developers.google.com/maps/documentation/javascript/3.exp/reference#MarkerOptions}
*/
class Marker extends React.Component {
constructor(props) {
super(props);
this.displayName = 'Marker';
this.state = {
marker : null
}
this.getOptions = this.getOptions.bind(this);
}
componentWillMount() {
if(this.props.map && this.props.maps) {
var {map,maps, MarkerClusterer} = this.props;
var marker = new maps.Marker(this.getOptions());
marker.setMap(this.props.map);
const {opacity} = this.props;
if(opacity != null && !isNaN(Number(opacity))) {
marker.setOpacity(this.props.opacity);
}
this.setState({marker});
if(MarkerClusterer) {
MarkerClusterer.addMarker(marker);
}
if(typeof this.props.onClick === 'function')
this.props.maps.event.addListener(marker, 'click', e => {
if(this.props.onClick)
this.props.onClick({coords : marker.getPosition().toJSON()})
});
if(typeof this.props.onDragEnd === 'function')
this.props.maps.event.addListener(marker, 'dragend', e=> {
this.props.onDragEnd(e.latLng.toJSON(), e);
})
}
else {
// Whoah boy! We need a map bigly.
console.error(new Error("<Marker /> components must be instantiated within a Map component. Please check your component's context."))
}
}
componentWillUpdate() {
}
getOptions() {
var options = {
position : this.props.coords,
// map : this.props.map,
icon : this.props.icon ? this.props.icon : undefined
}
if(this.props.options)
options = Object.assign(options, this.props.options);
return options;
}
componentWillUnmount() {
if(this.state.marker) {
this.state.marker.setMap(null);
}
this.setState({marker : null});
}
componentDidUpdate(prevProps, prevState) {
if(this.state.marker) {
this.state.marker.setOptions(this.getOptions())
if(this.props.MarkerClusterer)
this.props.MarkerClusterer.addMarker(this.state.marker);
}
}
render() {
var children = [];
if(this.props.children)
children = React.Children.map(this.props.children, child => React.cloneElement(child, {
map : this.props.map,
maps : this.props.maps,
anchor : this.state.marker
}));
return <div>{children}</div>;
}
}
Marker.propTypes = {
maps : PropTypes.object,
map : PropTypes.object,
MarkerClusterer : PropTypes.object,
options : PropTypes.object,
anchor : PropTypes.object,
coords : PropTypes.shape({
lng : PropTypes.number,
lat : PropTypes.number
})
}
export default Marker;