diff --git a/.babelrc b/.babelrc
index d146300..696db23 100644
--- a/.babelrc
+++ b/.babelrc
@@ -2,6 +2,9 @@
"presets": [
"react",
"env"
+ ],
+ "plugins": [
+ "inline-react-svg"
]
}
diff --git a/lib/CustomControl.js b/lib/CustomControl.js
new file mode 100644
index 0000000..1de8cfe
--- /dev/null
+++ b/lib/CustomControl.js
@@ -0,0 +1,78 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+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 _react = require("react");
+
+var _reactDom = require("react-dom");
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+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) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+/**
+ * This Component for add custom control to map
+ * (map.controls[position].push(component))
+ * NOTE:
+ * Can ref to map through context in constructor (or this.context expect contructor)
+ * User constructor to add div and render will createPortal
+ */
+var MapControl = function (_Component) {
+ _inherits(MapControl, _Component);
+
+ function MapControl(props, context) {
+ _classCallCheck(this, MapControl);
+
+ var _this = _possibleConstructorReturn(this, (MapControl.__proto__ || Object.getPrototypeOf(MapControl)).call(this, props));
+
+ _this.state = {
+ mounted: false
+ };
+ return _this;
+ }
+
+ _createClass(MapControl, [{
+ key: "componentDidUpdate",
+ value: function componentDidUpdate() {
+ if (this.props.map && !this.map) {
+ this.map = this.props.map;
+ this.controlDiv = document.createElement("div");
+ this.divIndex = this.map.controls[this.props.position].length;
+ this.map.controls[this.props.position].push(this.controlDiv);
+
+ this.setState({
+ mounted: true
+ });
+ }
+ }
+ }, {
+ key: "componentWillUnmount",
+ value: function componentWillUnmount() {
+ this.map.controls[this.props.position].removeAt(this.divIndex);
+ }
+ }, {
+ key: "render",
+ value: function render() {
+ var className = this.props.className;
+
+
+ if (!this.map) {
+ return null;
+ }
+
+ className && this.controlDiv.classList.add(className);
+
+ return (0, _reactDom.createPortal)(this.props.children, this.controlDiv);
+ }
+ }]);
+
+ return MapControl;
+}(_react.Component);
+
+exports.default = MapControl;
\ No newline at end of file
diff --git a/lib/GoogleMap.js b/lib/GoogleMap.js
index dfb127d..de3f14a 100644
--- a/lib/GoogleMap.js
+++ b/lib/GoogleMap.js
@@ -1,4 +1,4 @@
-'use strict';
+"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
@@ -6,63 +6,126 @@ Object.defineProperty(exports, "__esModule", {
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 _react = require('react');
+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 _react = require("react");
var _react2 = _interopRequireDefault(_react);
-var _withGoogleMap = require('react-google-maps/lib/withGoogleMap');
+var _withGoogleMap = require("react-google-maps/lib/withGoogleMap");
var _withGoogleMap2 = _interopRequireDefault(_withGoogleMap);
-var _GoogleMap = require('react-google-maps/lib/components/GoogleMap');
+var _GoogleMap = require("react-google-maps/lib/components/GoogleMap");
var _GoogleMap2 = _interopRequireDefault(_GoogleMap);
-var _Marker = require('react-google-maps/lib/components/Marker');
+var _Marker = require("react-google-maps/lib/components/Marker");
var _Marker2 = _interopRequireDefault(_Marker);
-var _Circle = require('react-google-maps/lib/components/Circle');
+var _Circle = require("react-google-maps/lib/components/Circle");
var _Circle2 = _interopRequireDefault(_Circle);
+var _SearchBox = require("./SearchBox");
+
+var _SearchBox2 = _interopRequireDefault(_SearchBox);
+
+var _CustomControl = require("./CustomControl");
+
+var _CustomControl2 = _interopRequireDefault(_CustomControl);
+
+var _constants = require("react-google-maps/lib/constants");
+
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 _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+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) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
/* Create map with withGoogleMap HOC */
/* https://github.com/tomchentw/react-google-maps */
-var Map = (0, _withGoogleMap2.default)(function (props) {
- var position = props.position,
- defaultZoom = props.defaultZoom,
- handleMarkerDragEnd = props.handleMarkerDragEnd,
- onZoomChanged = props.onZoomChanged,
- radius = props.radius,
- circleOptions = props.circleOptions,
- shouldRecenterMap = props.shouldRecenterMap,
- zoom = props.zoom;
-
-
- var circle = radius !== -1 ? _react2.default.createElement(_Circle2.default, {
- center: position,
- radius: radius,
- options: circleOptions
- }) : null;
- var mapExtraProps = shouldRecenterMap ? { center: position } : {};
- return _react2.default.createElement(
- _GoogleMap2.default,
- _extends({
- onZoomChanged: onZoomChanged,
- defaultZoom: defaultZoom,
- defaultCenter: position,
- zoom: zoom
- }, mapExtraProps),
- _react2.default.createElement(_Marker2.default, {
- draggable: true // Allow marker to drag
- , position: position,
- onDragEnd: handleMarkerDragEnd
- }),
- circle
- );
-});
-
-exports.default = Map;
\ No newline at end of file
+var Map = function (_Component) {
+ _inherits(Map, _Component);
+
+ function Map(props) {
+ _classCallCheck(this, Map);
+
+ var _this = _possibleConstructorReturn(this, (Map.__proto__ || Object.getPrototypeOf(Map)).call(this, props));
+
+ _this.state = {
+ mounted: false
+ };
+ return _this;
+ }
+
+ _createClass(Map, [{
+ key: "componentDidMount",
+ value: function componentDidMount() {
+ this.setState({ mounted: true });
+ }
+ }, {
+ key: "render",
+ value: function render() {
+ var _this2 = this;
+
+ var _props = this.props,
+ position = _props.position,
+ defaultZoom = _props.defaultZoom,
+ handleMarkerDragEnd = _props.handleMarkerDragEnd,
+ onZoomChanged = _props.onZoomChanged,
+ radius = _props.radius,
+ circleOptions = _props.circleOptions,
+ shouldRecenterMap = _props.shouldRecenterMap,
+ zoom = _props.zoom,
+ onChangeInput = _props.onChangeInput,
+ onChangeSuggestion = _props.onChangeSuggestion,
+ address = _props.address,
+ search = _props.search;
+ var mounted = this.state.mounted;
+
+
+ var circle = radius !== -1 ? _react2.default.createElement(_Circle2.default, { center: position, radius: radius, options: circleOptions }) : null;
+ var mapExtraProps = shouldRecenterMap ? { center: position } : {};
+
+ return _react2.default.createElement(
+ _GoogleMap2.default,
+ _extends({
+ onZoomChanged: onZoomChanged,
+ defaultZoom: defaultZoom,
+ defaultCenter: position,
+ defaultOptions: {
+ mapTypeControlOptions: { position: 12 },
+ fullscreenControlOptions: { position: 6 }
+ },
+ zoom: zoom,
+ ref: function ref(map) {
+ return _this2._map = map;
+ },
+ google: google
+ }, mapExtraProps),
+ _react2.default.createElement(
+ _CustomControl2.default,
+ { mounted: mounted, position: 3, map: this._map ? this._map.context[_constants.MAP] : undefined },
+ _react2.default.createElement(_SearchBox2.default, { onChangeInput: onChangeInput, onChangeSuggestion: onChangeSuggestion, search: search, address: address })
+ ),
+ _react2.default.createElement(_Marker2.default, {
+ draggable: true // Allow marker to drag
+ , position: position,
+ onDragEnd: handleMarkerDragEnd
+ }),
+ circle
+ );
+ }
+ }]);
+
+ return Map;
+}(_react.Component);
+
+;
+
+exports.default = (0, _withGoogleMap2.default)(Map);
\ No newline at end of file
diff --git a/lib/SearchBox.js b/lib/SearchBox.js
new file mode 100644
index 0000000..9b084b1
--- /dev/null
+++ b/lib/SearchBox.js
@@ -0,0 +1,99 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _searchBoxStyles;
+
+var _react = require("react");
+
+var _react2 = _interopRequireDefault(_react);
+
+var _reactGooglePlacesSuggest = require("react-google-places-suggest");
+
+var _reactGooglePlacesSuggest2 = _interopRequireDefault(_reactGooglePlacesSuggest);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+var Icon = function Icon(props) {
+ return _react2.default.createElement(
+ "svg",
+ props,
+ _react2.default.createElement("path", {
+ fill: "#757575",
+ d: "M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
+ }),
+ _react2.default.createElement("path", {
+ d: "M0 0h24v24H0z",
+ fill: "none"
+ })
+ );
+};
+
+Icon.defaultProps = {
+ xmlns: "http://www.w3.org/2000/svg",
+ width: "24",
+ height: "24",
+ viewBox: "0 0 24 24"
+};
+
+
+var searchBoxStyles = (_searchBoxStyles = {
+ alignItems: "center",
+ backgroundColor: "rgb(255, 255, 255)",
+ borderBottomLeftRadius: "4px",
+ borderBottomRightRadius: "4px",
+ borderTopLeftRadius: "4px",
+ borderTopRightRadius: "4px",
+ boxShadow: "rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px",
+ boxSizing: "border-box",
+ color: "rgba(0, 0, 0, 0.87)",
+ display: "flex",
+ fontFamily: "Roboto, Helvetica, Arial, sans-serif",
+ fontSize: "14px",
+ fontWeight: "400",
+ height: "48px",
+ letterSpacing: "0.14994px",
+ lineHeight: "20.02px",
+ marginTop: "0px",
+ outline: "none",
+ paddingBottom: "2px",
+ paddingLeft: "16px",
+ paddingRight: "12px",
+ paddingTop: "2px",
+ transitionDelay: "0s",
+ transitionDuration: "0.3s",
+ transitionProperty: "box-shadow",
+ transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)"
+}, _defineProperty(_searchBoxStyles, "marginTop", 14), _defineProperty(_searchBoxStyles, "marginRight", 14), _defineProperty(_searchBoxStyles, "maxWidth", 310), _defineProperty(_searchBoxStyles, "minWidth", 280), _defineProperty(_searchBoxStyles, "WebkitFontSmoothing", "antialiased"), _searchBoxStyles);
+
+var SearchBox = function SearchBox(props) {
+ return _react2.default.createElement(
+ "label",
+ { htmlFor: "locationPickerSearch", style: searchBoxStyles },
+ _react2.default.createElement(
+ _reactGooglePlacesSuggest2.default,
+ {
+ googleMaps: google.maps,
+ autocompletionRequest: { input: props.search },
+ onSelectSuggest: props.onChangeSuggestion
+ },
+ _react2.default.createElement("input", {
+ type: "text",
+ id: "locationPickerSearch",
+ value: props.address,
+ placeholder: "Search a location",
+ style: { border: "none", width: "100%", height: 44 },
+ onChange: function onChange(e) {
+ props.onChangeInput(e.target.value);
+ }
+ })
+ ),
+ _react2.default.createElement(Icon, null)
+ );
+};
+
+exports.default = SearchBox;
\ No newline at end of file
diff --git a/lib/index.js b/lib/index.js
index 49c8e6d..9603b59 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -54,10 +54,14 @@ var LocationPicker = function (_Component) {
_this.state = {
position: props.defaultPosition,
- shouldRecenterMap: false
+ shouldRecenterMap: false,
+ address: "",
+ search: ""
};
_this.handleMarkerDragEnd = _this.handleMarkerDragEnd.bind(_this);
+ _this.handleChangeInput = _this.handleChangeInput.bind(_this);
+ _this.handleChangeSuggestion = _this.handleChangeSuggestion.bind(_this);
return _this;
}
@@ -85,11 +89,16 @@ var LocationPicker = function (_Component) {
value: function notify(position, places) {
var onChange = this.props.onChange;
+ var address = places.length > 0 ? places[0].formatted_address : '';
+
var location = {
position: position,
places: places,
- address: places.length > 0 ? places[0].formatted_address : ''
+ address: address
};
+
+ this.setState({ address: address, position: position });
+
onChange && onChange(location);
}
/**
@@ -108,7 +117,7 @@ var LocationPicker = function (_Component) {
var lat = mouseEvent.latLng.lat();
var lng = mouseEvent.latLng.lng();
var position = { lat: lat, lng: lng };
- this.setState({ position: position, shouldRecenterMap: false });
+ this.setState({ shouldRecenterMap: false, search: "" });
this.geocodePosition(position).then(function (places) {
_this3.notify(position, places);
}).catch(function (err) {
@@ -117,6 +126,32 @@ var LocationPicker = function (_Component) {
});
}
+ /**
+ * Handle search box input change
+ * @param { string } value
+ */
+
+ }, {
+ key: 'handleChangeInput',
+ value: function handleChangeInput(value) {
+ this.setState({ address: value, search: value });
+ }
+
+ /**
+ * Handle change the position by search box
+ * @param { google.maps.GeocoderResult } suggestion // https://github.com/cedricdelpoux/react-google-places-suggest#props
+ */
+
+ }, {
+ key: 'handleChangeSuggestion',
+ value: function handleChangeSuggestion(suggestion) {
+ var position = suggestion.geometry.location;
+
+ this.setState({ shouldRecenterMap: true, search: "" });
+
+ this.notify({ lat: position.lat(), lng: position.lng() }, [suggestion]);
+ }
+
/**
* Geocode position to places
* @param { Object } position
@@ -150,7 +185,9 @@ var LocationPicker = function (_Component) {
mapElement = _props.mapElement;
var _state = this.state,
position = _state.position,
- shouldRecenterMap = _state.shouldRecenterMap;
+ shouldRecenterMap = _state.shouldRecenterMap,
+ address = _state.address,
+ search = _state.search;
return _react2.default.createElement(_GoogleMap2.default, {
@@ -162,7 +199,11 @@ var LocationPicker = function (_Component) {
radius: radius,
defaultZoom: zoom,
zoom: zoom,
- shouldRecenterMap: shouldRecenterMap
+ shouldRecenterMap: shouldRecenterMap,
+ onChangeInput: this.handleChangeInput,
+ onChangeSuggestion: this.handleChangeSuggestion,
+ address: address,
+ search: search
});
}
}]);
diff --git a/package.json b/package.json
index 02c6fb3..c50c4ca 100644
--- a/package.json
+++ b/package.json
@@ -16,21 +16,24 @@
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
+ "babel-plugin-inline-react-svg": "^0.5.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
+ "react": "^16.2.0",
"react-dom": "^16.2.0",
+ "react-svg-loader": "^3.0.3",
"webpack": "^3.6.0",
- "react": "^16.2.0",
"webpack-dev-server": "^2.8.2"
},
"dependencies": {
"prop-types": "^15.6.1",
- "react-google-maps": "^9.4.5"
+ "react-google-maps": "^9.4.5",
+ "react-google-places-suggest": "^3.9.0"
},
"peerDependencies": {
- "react": "^15.0.0 || ^16.0.0",
- "react-dom": "^15.0.0 || ^16.0.0",
"@types/googlemaps": "^3.37.6",
- "@types/react": "^16.9.2"
+ "@types/react": "^16.9.2",
+ "react": "^15.0.0 || ^16.0.0",
+ "react-dom": "^15.0.0 || ^16.0.0"
}
}
diff --git a/src/CustomControl.jsx b/src/CustomControl.jsx
new file mode 100644
index 0000000..1600914
--- /dev/null
+++ b/src/CustomControl.jsx
@@ -0,0 +1,48 @@
+import { Component } from "react";
+import { createPortal } from "react-dom";
+
+/**
+ * This Component for add custom control to map
+ * (map.controls[position].push(component))
+ * NOTE:
+ * Can ref to map through context in constructor (or this.context expect contructor)
+ * User constructor to add div and render will createPortal
+ */
+export default class MapControl extends Component {
+ constructor(props, context) {
+ super(props);
+
+ this.state = {
+ mounted: false
+ };
+ }
+
+ componentDidUpdate() {
+ if (this.props.map && !this.map) {
+ this.map = this.props.map;
+ this.controlDiv = document.createElement("div");
+ this.divIndex = this.map.controls[this.props.position].length;
+ this.map.controls[this.props.position].push(this.controlDiv);
+
+ this.setState({
+ mounted: true
+ });
+ }
+ }
+
+ componentWillUnmount() {
+ this.map.controls[this.props.position].removeAt(this.divIndex);
+ }
+
+ render() {
+ const { className } = this.props;
+
+ if (!this.map) {
+ return null;
+ }
+
+ className && this.controlDiv.classList.add(className);
+
+ return createPortal(this.props.children, this.controlDiv);
+ }
+}
diff --git a/src/GoogleMap.jsx b/src/GoogleMap.jsx
index 98cdb0d..e6ef289 100644
--- a/src/GoogleMap.jsx
+++ b/src/GoogleMap.jsx
@@ -1,51 +1,85 @@
-import React from 'react';
-import withGoogleMap from 'react-google-maps/lib/withGoogleMap';
-import GoogleMap from 'react-google-maps/lib/components/GoogleMap';
-import Marker from 'react-google-maps/lib/components/Marker';
-import Circle from 'react-google-maps/lib/components/Circle';
+import React,{Component} from "react";
+import withGoogleMap from "react-google-maps/lib/withGoogleMap";
+import GoogleMap from "react-google-maps/lib/components/GoogleMap";
+import Marker from "react-google-maps/lib/components/Marker";
+import Circle from "react-google-maps/lib/components/Circle";
+import SearchBox from "./SearchBox";
+import CustomControl from "./CustomControl";
+import { MAP } from "react-google-maps/lib/constants";
/* Create map with withGoogleMap HOC */
/* https://github.com/tomchentw/react-google-maps */
-const Map = withGoogleMap((props) => {
- const {
- position,
- defaultZoom,
- handleMarkerDragEnd,
- onZoomChanged,
- radius,
- circleOptions,
- shouldRecenterMap,
- zoom
- } = props;
-
- const circle = (radius !== -1) ?
- : null;
- const mapExtraProps = shouldRecenterMap ? { center: position }: {};
- return (
-
-
- {/* Map marker */}
-
-
- {/* Circle */}
- { circle }
-
- )
-});
-
-export default Map;
+class Map extends Component {
+
+ constructor(props){
+ super(props);
+
+ // We are keeping mounted status in states.
+ // Because we can not use useRef method. We are using react 15
+ this.state = {
+ mounted:false
+ }
+ }
+
+ componentDidMount(){
+ this.setState({mounted:true});
+ }
+
+ render(){
+ const {
+ position,
+ defaultZoom,
+ handleMarkerDragEnd,
+ onZoomChanged,
+ radius,
+ circleOptions,
+ shouldRecenterMap,
+ zoom,
+ onChangeInput,
+ onChangeSuggestion,
+ address,
+ search
+ } = this.props;
+
+ const {mounted} = this.state;
+
+ const circle =
+ radius !== -1 ? (
+
+ ) : null;
+ const mapExtraProps = shouldRecenterMap ? { center: position } : {};
+
+ return (
+ this._map=map}
+ google={google}
+ {...mapExtraProps}
+ >
+
+
+
+ {/* Map marker */}
+
+
+ {/* Circle */}
+ {circle}
+
+ );
+ }
+}
+;
+
+export default withGoogleMap(Map);
diff --git a/src/Search.svg b/src/Search.svg
new file mode 100644
index 0000000..6a414f4
--- /dev/null
+++ b/src/Search.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/src/SearchBox.jsx b/src/SearchBox.jsx
new file mode 100644
index 0000000..45d4850
--- /dev/null
+++ b/src/SearchBox.jsx
@@ -0,0 +1,62 @@
+import React from "react";
+import ReactGooglePlacesSuggest from "react-google-places-suggest";
+import Icon from "./Search.svg";
+
+const searchBoxStyles = {
+ alignItems: "center",
+ backgroundColor: "rgb(255, 255, 255)",
+ borderBottomLeftRadius: "4px",
+ borderBottomRightRadius: "4px",
+ borderTopLeftRadius: "4px",
+ borderTopRightRadius: "4px",
+ boxShadow:
+ "rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px",
+ boxSizing: "border-box",
+ color: "rgba(0, 0, 0, 0.87)",
+ display: "flex",
+ fontFamily: "Roboto, Helvetica, Arial, sans-serif",
+ fontSize: "14px",
+ fontWeight: "400",
+ height: "48px",
+ letterSpacing: "0.14994px",
+ lineHeight: "20.02px",
+ marginTop: "0px",
+ outline:"none",
+ paddingBottom: "2px",
+ paddingLeft: "16px",
+ paddingRight: "12px",
+ paddingTop: "2px",
+ transitionDelay: "0s",
+ transitionDuration: "0.3s",
+ transitionProperty: "box-shadow",
+ transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
+ marginTop:14,
+ marginRight:14,
+ maxWidth: 310,
+ minWidth: 280,
+ WebkitFontSmoothing: "antialiased"
+};
+
+const SearchBox = (props) => (
+
+)
+
+export default SearchBox;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index e64165b..22cfd2d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -28,10 +28,14 @@ class LocationPicker extends Component {
this.state = {
position: props.defaultPosition,
- shouldRecenterMap: false
+ shouldRecenterMap: false,
+ address:"",
+ search:""
};
this.handleMarkerDragEnd = this.handleMarkerDragEnd.bind(this);
+ this.handleChangeInput = this.handleChangeInput.bind(this);
+ this.handleChangeSuggestion = this.handleChangeSuggestion.bind(this);
}
componentWillReceiveProps(nextProps) {
@@ -59,11 +63,16 @@ class LocationPicker extends Component {
notify(position, places) {
const { onChange } = this.props;
+ const address = places.length > 0 ? places[0].formatted_address : '';
+
const location = {
position,
places,
- address: places.length > 0 ? places[0].formatted_address : ''
+ address
};
+
+ this.setState({address,position});
+
onChange && onChange(location);
}
/**
@@ -76,7 +85,7 @@ class LocationPicker extends Component {
const lat = mouseEvent.latLng.lat();
const lng = mouseEvent.latLng.lng();
const position = { lat, lng };
- this.setState({ position, shouldRecenterMap: false });
+ this.setState({shouldRecenterMap: false, search:"" });
this.geocodePosition(position)
.then(places => {
this.notify(position, places);
@@ -87,6 +96,26 @@ class LocationPicker extends Component {
});
}
+ /**
+ * Handle search box input change
+ * @param { string } value
+ */
+ handleChangeInput(value){
+ this.setState({address:value,search:value});
+ }
+
+ /**
+ * Handle change the position by search box
+ * @param { google.maps.GeocoderResult } suggestion // https://github.com/cedricdelpoux/react-google-places-suggest#props
+ */
+ handleChangeSuggestion(suggestion){
+ const position = suggestion.geometry.location;
+
+ this.setState({shouldRecenterMap:true,search:""});
+
+ this.notify({lat:position.lat(),lng: position.lng()},[suggestion])
+ }
+
/**
* Geocode position to places
* @param { Object } position
@@ -116,20 +145,25 @@ class LocationPicker extends Component {
mapElement
} = this.props;
- const { position, shouldRecenterMap } = this.state;
+ const { position, shouldRecenterMap, address, search } = this.state;
+
return (
-
+
);
}
}
diff --git a/webpack.config.js b/webpack.config.js
index 13e9abe..1075705 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -12,6 +12,23 @@ const config = {
test: /\.jsx?$/,
exclude: /node_modules/,
use: 'babel-loader'
+ },
+ {
+ test: /\.svg$/,
+ use: [
+ "babel-loader",
+ {
+ loader: "react-svg-loader",
+ options: {
+ svgo: {
+ plugins: [
+ { removeTitle: false }
+ ],
+ floatPrecision: 2
+ }
+ }
+ }
+ ]
}
]
},