@lyra/google-maps-input
Version:
Lyra plugin providing input handlers for geo-related input types using Google Maps
159 lines (127 loc) • 4.33 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _GeopointSelect = require('../styles/GeopointSelect.css');
var _GeopointSelect2 = _interopRequireDefault(_GeopointSelect);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class GeopointSelect extends _react2.default.Component {
constructor(props) {
super(props);
this.elementRefs = {};
}
componentDidMount() {
var _props$api = this.props.api;
const Circle = _props$api.Circle,
places = _props$api.places,
event = _props$api.event;
const GMap = this.props.api.Map;
const geoPoint = this.getValueLatLng();
const options = {
zoom: this.props.defaultZoom,
center: geoPoint
};
this.mapInstance = new GMap(this.elementRefs.map, options);
this.declareMarker();
const searchBounds = new Circle({ center: geoPoint, radius: 100 }).getBounds();
const input = this.elementRefs.searchInput;
this.autoComplete = new places.Autocomplete(input, {
bounds: searchBounds,
types: [] // return all kinds of places
});
event.addListener(this.autoComplete, 'place_changed', this.handlePlaceChanged.bind(this));
event.addListener(this.mapInstance, 'click', clickEvent => {
this.setValue(clickEvent.latLng);
});
}
getValueLatLng() {
var _props = this.props;
const api = _props.api,
value = _props.value,
defaultLocation = _props.defaultLocation;
return value ? new api.LatLng(value.lat, value.lng) : new api.LatLng(defaultLocation.lat, defaultLocation.lng);
}
declareMarker() {
if (this.marker) {
return this.marker;
}
var _props$api2 = this.props.api;
const Marker = _props$api2.Marker,
event = _props$api2.event;
this.marker = new Marker({
position: this.getValueLatLng(),
map: this.mapInstance,
draggable: true
});
event.addListener(this.marker, 'dragend', this.handleMarkerDragEnd.bind(this));
return this.marker;
}
handlePlaceChanged() {
const place = this.autoComplete.getPlace();
if (!place.geometry) {
return;
}
this.setValue(place.geometry.location);
}
handleMarkerDragEnd(event) {
this.setValue(event.latLng);
}
setValue(geoPoint) {
this.props.onChange(geoPoint);
}
componentDidUpdate() {
this.mapInstance.panTo(this.getValueLatLng());
this.marker.setPosition(this.getValueLatLng());
this.elementRefs.searchInput.value = '';
}
assignReference(type) {
return el => {
this.elementRefs[type] = el;
};
}
render() {
return _react2.default.createElement(
'div',
{ className: _GeopointSelect2.default.wrapper },
_react2.default.createElement('div', { ref: this.assignReference('map'), className: _GeopointSelect2.default.map }),
_react2.default.createElement(
'div',
{ className: _GeopointSelect2.default.searchInput },
_react2.default.createElement('input', {
name: 'place',
ref: this.assignReference('searchInput'),
placeholder: 'Search for place or address',
className: _GeopointSelect2.default.input
})
)
);
}
}
GeopointSelect.propTypes = {
onChange: _propTypes2.default.func.isRequired,
value: _propTypes2.default.shape({
lat: _propTypes2.default.number,
lng: _propTypes2.default.number
}),
api: _propTypes2.default.shape({
Map: _propTypes2.default.func.isRequired,
Circle: _propTypes2.default.func.isRequired,
Marker: _propTypes2.default.func.isRequired,
places: _propTypes2.default.shape({ Autocomplete: _propTypes2.default.func.isRequired }),
event: _propTypes2.default.shape({ addListener: _propTypes2.default.func.isRequired })
}).isRequired,
defaultLocation: _propTypes2.default.shape({
lat: _propTypes2.default.number,
lng: _propTypes2.default.number
}),
defaultZoom: _propTypes2.default.number
};
GeopointSelect.defaultProps = {
defaultZoom: 8,
defaultLocation: { lng: 10.74609, lat: 59.91273 }
};
exports.default = GeopointSelect;