Skip to content

Commit a1be457

Browse files
author
Ari
committed
WIP
2 parents a7ad90f + e2f6ff5 commit a1be457

23 files changed

+5937
-218
lines changed

README.md

Lines changed: 110 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,81 @@ First, install the library:
1616
```shell
1717
npm install --save google-maps-react
1818
```
19+
## Automatically Lazy-loading Google API
1920

20-
Usage:
21+
The library includes a helper to wrap around the Google maps API. The `GoogleApiWrapper` Higher-Order component accepts a configuration object which *must* include an `apiKey`. See [lib/GoogleApi.js](https://github.com/fullstackreact/google-maps-react/blob/master/src/lib/GoogleApi.js#L4) for all options it accepts.
2122

2223
```javascript
23-
import Map from 'google-maps-react'
24+
import {GoogleApiWrapper} from 'google-maps-react';
2425

2526
// ...
2627

27-
<Map google={this.props.google} zoom={14}>
28+
export class MapContainer extends React.Component {}
2829

29-
<Marker onClick={this.onMarkerClick}
30-
name={'Current location'} />
30+
export default GoogleApiWrapper({
31+
apiKey: (YOUR_GOOGLE_API_KEY_GOES_HERE)
32+
})(MapContainer)
33+
```
3134

32-
<InfoWindow onClose={this.onInfoWindowClose}>
33-
<div>
34-
<h1>{this.state.selectedPlace.name}</h1>
35-
</div>
36-
</InfoWindow>
37-
</Map>
35+
## Sample Usage With Lazy-loading Google API:
36+
37+
```javascript
38+
import {Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps-react';
39+
40+
export class MapContainer extends Component {
41+
render() {
42+
return (
43+
<Map google={this.props.google} zoom={14}>
44+
45+
<Marker onClick={this.onMarkerClick}
46+
name={'Current location'} />
47+
48+
<InfoWindow onClose={this.onInfoWindowClose}>
49+
<div>
50+
<h1>{this.state.selectedPlace.name}</h1>
51+
</div>
52+
</InfoWindow>
53+
</Map>
54+
);
55+
}
56+
}
57+
58+
export default GoogleApiWrapper({
59+
apiKey: (YOUR_GOOGLE_API_KEY_GOES_HERE)
60+
})(MapContainer)
3861
```
62+
*Note: [Marker](#marker) and [InfoWindow](#infowindow--sample-event-handler-functions) components are disscussed below.*
3963

4064
![](http://d.pr/i/C7qr.png)
4165

42-
## Map
66+
## Additional Map Props
67+
The Map component takes a number of optional props.
4368

44-
The `<Map />` component _requires_ a `google` prop be included to work. Without the `google` prop, it will explode.
69+
Zoom: (Shown Above) takes a number with the higher value representing a tighter focus on the map's center.
70+
71+
Style: Takes CSS style object - commonly width and height.
4572

4673
```javascript
47-
<Map google={window.google} />
74+
const style = {
75+
width: '100%',
76+
height: '100%'
77+
}
78+
```
79+
initalCenter: Takes an object containing latitude and longitude coordinates. Sets the maps center upon loading.
80+
81+
```javascript
82+
<Map
83+
google={this.props.google}
84+
style={style}
85+
initialCenter={{
86+
lat: 40.854885,
87+
lng: -88.081807
88+
}}
89+
zoom={15}
90+
onClick={this.onMapClicked}
91+
>
4892
```
93+
It also takes event handlers described below:
4994

5095
### Events
5196

@@ -207,6 +252,39 @@ const Container = React.createClass({
207252
});
208253
```
209254

255+
### Polygon
256+
257+
To place a polygon on the Map, set `<Polygon />` as child of Map component.
258+
259+
```javascript
260+
render: function() {
261+
var triangleCoords = [
262+
{lat: 25.774, lng: -80.190},
263+
{lat: 18.466, lng: -66.118},
264+
{lat: 32.321, lng: -64.757},
265+
{lat: 25.774, lng: -80.190}
266+
];
267+
return(
268+
<Map google={this.props.google}
269+
style={{width: '100%', height: '100%', position: 'relative'}}
270+
className={'map'}
271+
zoom={14}>
272+
<Polygon
273+
paths={triangleCoords}
274+
strokeColor="#0000FF"
275+
strokeOpacity={0.8}
276+
strokeWeight={2}
277+
fillColor="#0000FF"
278+
fillOpacity={0.35} />
279+
</Map>
280+
)
281+
}
282+
```
283+
284+
#### Events
285+
286+
The `<Polygon />` component listens to `onClick`, `onMouseover` and `onMouseout` events.
287+
210288
### InfoWindow
211289

212290
The `<InfoWindow />` component included in this library is gives us the ability to pop up a "more info" window on our Google map.
@@ -215,16 +293,25 @@ The `<InfoWindow />` component included in this library is gives us the ability
215293

216294
The visibility of the `<InfoWindow />` component is controlled by a `visible` prop. The `visible` prop is a boolean (`PropTypes.bool`) that shows the `<InfoWindow />` when true and hides it when false.
217295

296+
There are two ways how to control a position of the `<InfoWindow />` component.
297+
You can use a `position` prop or connect the `<InfoWindow />` component directly to an existing `<Marker />` component by using a `marker` prop.
298+
218299
```javascript
219-
const WithMarkers = React.createClass({
220-
getInitialState: function() {
221-
return {
300+
//note: code formatted for ES6 here
301+
export class MapContainer extends Component {
302+
constructor(props) {
303+
super(props);
304+
this.state = {
222305
showingInfoWindow: false,
223306
activeMarker: {},
224307
selectedPlace: {},
225308
}
226-
},
227-
309+
310+
// binding this to event-handler functions
311+
this.onMarkerClick = this.onMarkerClick.bind(this);
312+
this.onMapClicked = this.onMapClicked.bind(this);
313+
}
314+
228315
onMarkerClick: function(props, marker, e) {
229316
this.setState({
230317
selectedPlace: props,
@@ -285,28 +372,17 @@ The `onClose` event is fired when the `<InfoWindow />` has been closed. It's use
285372

286373
The `onOpen` event is fired when the window has been mounted in the Google map instance. It's useful for keeping track of the state of the `<InfoWindow />` from within the parent component.
287374

288-
## Automatically Lazy-loading Google API
289-
290-
The library includes a helper to wrap around the Google maps API. The `GoogleApiWrapper` Higher-Order component accepts a configuration object which *must* include an `apiKey`. See [lib/GoogleApi.js](https://github.com/fullstackreact/google-maps-react/blob/master/src/lib/GoogleApi.js#L4) for all options it accepts.
291-
292-
```javascript
293-
import {GoogleApiWrapper} from 'GoogleMapsReactComponent'
294-
295-
// ...
296-
297-
export class Container extends React.Component {}
298-
299-
export default GoogleApiWrapper({
300-
apiKey: __GAPI_KEY__
301-
})(Container)
302-
```
303375

304376
The `GoogleApiWrapper` automatically passes the `google` instance loaded when the component mounts (and will only load it once).
305377

306378
## Manually loading the Google API
307379

308380
If you prefer not to use the automatic loading option, you can also pass the `window.google` instance as a `prop` to your `<Map />` component.
309381

382+
```javascript
383+
<Map google={window.google} />
384+
```
385+
310386
## Contributing
311387

312388
```shell

dist/GoogleApiComponent.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,16 @@
8383
options = options || {};
8484
var apiKey = options.apiKey;
8585
var libraries = options.libraries || ['places'];
86-
var version = options.version || '3';
86+
var version = options.version || '3.24';
87+
var language = options.language || 'en';
8788

8889
return (0, _ScriptCache.ScriptCache)({
89-
google: (0, _GoogleApi2.default)({ apiKey: apiKey, libraries: libraries, version: version })
90+
google: (0, _GoogleApi2.default)({
91+
apiKey: apiKey,
92+
language: language,
93+
libraries: libraries,
94+
version: version
95+
})
9096
});
9197
};
9298

dist/components/InfoWindow.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,15 @@
110110
this.renderInfoWindow();
111111
}
112112

113+
if (this.props.position !== prevProps.position) {
114+
this.updatePosition();
115+
}
116+
113117
if (this.props.children !== prevProps.children) {
114118
this.updateContent();
115119
}
116120

117-
if (this.props.visible !== prevProps.visible || this.props.marker !== prevProps.marker) {
121+
if (this.props.visible !== prevProps.visible || this.props.marker !== prevProps.marker || this.props.position !== prevProps.position) {
118122
this.props.visible ? this.openWindow() : this.closeWindow();
119123
}
120124
}
@@ -157,6 +161,15 @@
157161
value: function openWindow() {
158162
this.infowindow.open(this.props.map, this.props.marker);
159163
}
164+
}, {
165+
key: 'updatePosition',
166+
value: function updatePosition() {
167+
var pos = this.props.position;
168+
if (!(pos instanceof google.maps.LatLng)) {
169+
pos = pos && new google.maps.LatLng(pos.lat, pos.lng);
170+
}
171+
this.infowindow.setPosition(pos);
172+
}
160173
}, {
161174
key: 'updateContent',
162175
value: function updateContent() {
@@ -189,6 +202,7 @@
189202
children: _propTypes2.default.element.isRequired,
190203
map: _propTypes2.default.object,
191204
marker: _propTypes2.default.object,
205+
position: _propTypes2.default.object,
192206
visible: _propTypes2.default.bool,
193207

194208
// callbacks

dist/components/Marker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
7777
}
7878

79-
var evtNames = ['click', 'mouseover', 'recenter', 'dragend'];
79+
var evtNames = ['click', 'dblclick', 'dragend', 'mousedown', 'mouseout', 'mouseover', 'mouseup', 'recenter'];
8080

8181
var wrappedPromise = function wrappedPromise() {
8282
var wrappedPromise = {},
@@ -109,7 +109,7 @@
109109
}, {
110110
key: 'componentDidUpdate',
111111
value: function componentDidUpdate(prevProps) {
112-
if (this.props.map !== prevProps.map || this.props.position !== prevProps.position) {
112+
if (this.props.map !== prevProps.map || this.props.position !== prevProps.position || this.props.icon !== prevProps.icon) {
113113
if (this.marker) {
114114
this.marker.setMap(null);
115115
}

0 commit comments

Comments
 (0)