├── .gitignore
├── .travis.yml
├── README.md
├── bower.json
├── demo
└── src
│ ├── GeometryCircle.js
│ ├── GeometryPolygons.js
│ ├── MarkerIcon.js
│ ├── MarkerLabel.js
│ ├── Markers.js
│ ├── Popups.js
│ ├── SimpleMap.js
│ └── index.js
├── nwb.config.js
├── package.json
├── src
├── Circle.js
├── CircleMarker.js
├── DivIcon.js
├── GeoJSON.js
├── Icon.js
├── Map.js
├── MapComponent.js
├── Marker.js
├── Polygon.js
├── Polyline.js
├── Popup.js
├── Rectangle.js
├── Ruler.js
├── Wkt.js
└── index.js
└── tests
├── .eslintrc
└── index-test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /coverage
2 | /demo/dist
3 | /es6
4 | /lib
5 | /node_modules
6 | /umd
7 | npm-debug.log
8 | .idea
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: node_js
4 | node_js:
5 | - 4.2.6
6 |
7 | cache:
8 | directories:
9 | - node_modules
10 |
11 | before_install:
12 | - npm install codecov.io coveralls
13 | - npm install nwb -g
14 |
15 | after_success:
16 | - cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js
17 | - cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
18 |
19 | branches:
20 | only:
21 | - master
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React component [Maps API 2GIS](https://github.com/2gis/mapsapi)
2 |
3 | :construction: WARNING: This package is no longer supported. Please use https://github.com/2gis/mapsapi instead. :construction:
4 |
5 | ## Installation
6 |
7 | For installation use command `npm install 2gis-maps-react 2gis-maps`
8 |
9 | [build-badge]: https://travis-ci.org/2gis/2gis-maps-react.svg?branch=master
10 | [build]: https://travis-ci.org/2gis/2gis-maps-react
11 |
12 | [npm-badge]: https://img.shields.io/npm/v/2gis-maps-react.svg?style=flat-square
13 | [npm]: https://www.npmjs.org/package/2gis-maps-react
14 |
15 | [coveralls-badge]: https://coveralls.io/repos/github/2gis/2gismaps-react/badge.svg?branch=master
16 | [coveralls]: https://coveralls.io/github/2gis/2gismaps-react?branch=master
17 |
18 |
19 | ## Getting started
20 |
21 | ##### Demo
22 |
23 | [Demo](http://2gis.github.io/2gis-maps-react/#simple-map)
24 | [Source code of the demo](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/SimpleMap.js)
25 |
26 | ##### Creation of simple map. [Api referense.](http://api.2gis.ru/doc/maps/manual/map/)
27 |
28 | A map is a basic component.
29 | For creating the map you need to specify center point, zoom level and size of dom element.
30 |
31 | ```jsx
32 |
37 | ```
38 |
39 | ##### Creation of popup inside the map. [Api referense.](http://api.2gis.ru/doc/maps/examples/popups/)
40 |
41 | A simple popup.
42 | For setting of maxWidth, minWith and maxHeight use prop sprawling. [Demo](http://2gis.github.io/2gis-maps-react/#popups) [Source code](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/Popups.js)
43 |
44 | ```jsx
45 |
57 | ```
58 |
59 | ##### Creation of Markers and Popups on Markers. [Api referense.](http://api.2gis.ru/doc/maps/examples/markers/)
60 |
61 | Simple Marker
62 |
63 | ```jsx
64 |
73 | ```
74 |
75 | Static and draggable markers.
76 | Popups on Markers. [Demo](http://2gis.github.io/2gis-maps-react/#markers-simple) [Source code](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/Markers.js)
77 |
78 | ```jsx
79 |
98 | ```
99 |
100 | Marker with icon and html icon. [Demo](http://2gis.github.io/2gis-maps-react/#markers-icon) [Source code](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/MarkerIcon.js)
101 |
102 | ```jsx
103 |
127 | ```
128 |
129 | Marker with label and static label. [Demo](http://2gis.github.io/2gis-maps-react/#markers-label) [Source code](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/MarkerLabel.js)
130 |
131 | ```jsx
132 |
147 | ```
148 |
149 | ##### Creating of vector objects. [Api referense.](http://api.2gis.ru/doc/maps/examples/geometries/)
150 |
151 | Circle and Circle Marker. [Demo](http://2gis.github.io/2gis-maps-react/#geometry-circle) [Source code](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/GeometryCircle.js)
152 |
153 | ```jsx
154 |
171 | ```
172 |
173 | Polygon, Polyline and Rectangle. [Demo](http://2gis.github.io/2gis-maps-react/#geometry-polygon) [Source code](https://github.com/2gis/2gis-maps-react/blob/master/demo/src/GeometryPolygons.js)
174 |
175 | ```jsx
176 |
207 | ```
208 |
209 | ### Events
210 |
211 | For binding 2gis-mapsapi events use props similar to `onEvent` where Event is 2gis-mapsapi event with a capital first character.
212 |
213 | ### Components
214 |
215 | #### Map
216 |
217 | Required props
218 |
219 | |Prop name |Dynamic|Description | Data example |
220 | |-----------------|:-----:|-----------------------------------------|--------------|
221 | | center | ✓ |Center position of map |[54.98, 82.89]|
222 | | zoom | ✓ |Zoom level of map |15 |
223 |
224 | Optional props
225 |
226 | |Prop name |Dynamic|Description | Data example |Default value|
227 | |-----------------|:-----:|-----------------------------------------|--------------------------------- |:-----------:|
228 | | minZoom | ✘ |Minimal zoom level |10 | null |
229 | | maxZoom | ✘ |Maximal zoom level |20 | null |
230 | |maxBounds | ✘ |Bounds of map |[ [54.98, 82.89], [54.98, 82.89] ]| null |
231 | | style | ✓ |CSS style of map container |{width: "500px", height: "500px"} | null |
232 | |geoclicker | ✘ |Show popup on click about place on map |true | false |
233 | |projectDetector | ✘ |Load current user project |true | false |
234 | |zoomControl | ✘ |Show zoom control button |false | true |
235 | |fullscreenControl| ✘ |Show fullscreen control button |false | true |
236 | |preferCanvas | ✘ |Use canvas element for rendering geometry|false | true |
237 | |touchZoom | ✘ |Zooming when touch (on mobile) |false | true |
238 | |scrollWheelZoom | ✘ |Zooming when scrolling |false | true |
239 | |doubleClickZoom | ✘ |Zooming when double click |false | true |
240 | |dragging | ✘ |Dragging map |false | true |
241 |
242 | #### Popup
243 |
244 | Can be bound to Marker, Map, Polygon, Polyline, Rectangle.
245 |
246 | Required props
247 |
248 | |Prop name|Dynamic|Description | Data example |
249 | |---------|:-----:|---------------------------------------------------------|--------------|
250 | | pos | ✓ |Position on map (not use if popup inside another element)|[54.98, 82.89]|
251 |
252 | Optional props
253 |
254 | |Prop name|Dynamic|Description | Data example |Default value|
255 | |---------|:-----:|-------------------------------|--------------|:-----------:|
256 | |className| ✘ |Class name of popup dom element|example-string| - |
257 | |maxWidth | ✘ |Max width of popup | 150 | 300 |
258 | |minWidth | ✘ |Min width of popup | 150 | 50 |
259 | |maxHeight| ✘ |Max height of popup | 150 | null |
260 | |sprawling| ✘ |Popup width on map width | true | false |
261 |
262 | #### Marker
263 |
264 | Required props
265 |
266 | |Prop name|Dynamic|Description | Data example |
267 | |---------|:-----:|---------------|--------------|
268 | | pos | ✓ |Position on map|[54.98, 82.89]|
269 |
270 | Optional props
271 |
272 | |Prop name |Dynamic|Description | Data example |Default value|
273 | |-----------|:-----:|-------------------------------------------|--------------|:-----------:|
274 | | label | ✓ |Text of marker label |[54.98, 82.89]| - |
275 | |staticLabel| ✓ |Text of marker label. Label will be static.|[54.98, 82.89]| - |
276 | | draggable | ✓ |Marker is draggable | true | false |
277 | | clickable | ✓ |Marker is clickable | false | true |
278 |
279 | #### Icon
280 |
281 | Can be inside Marker.
282 |
283 | Required props
284 |
285 | |Prop name|Dynamic|Description | Data example |
286 | |---------|:-----:|------------|---------------------------------------------|
287 | | iconUrl | ✓ |Url of icon |http://maps.api.2gis.ru/2.0/example_logo.png |
288 | | iconSize| ✓ |Size of icon|[48, 48] |
289 |
290 | #### DivIcon
291 |
292 | Can be inside Marker.
293 |
294 | Required props
295 |
296 | |Prop name |Dynamic|Description | Data example |Default value|
297 | |-----------------------|:-----:|------------|---------------------------------------------|:-----------:|
298 | | iconSize | ✓ |Size of icon|[48, 48] | - |
299 | |dangerouslySetInnerHTML| ✓ | Inner html |http://maps.api.2gis.ru/2.0/example_logo.png | - |
300 |
301 | #### Ruler
302 |
303 | Required props
304 |
305 | |Prop name|Dynamic|Description | Data example |
306 | |---------|:-----:|----------------|-----------------------------------------------------------|
307 | | points | ✓ |Points of ruler |[ [54.9827,82.8958], [54.9837,82.8968], [54.9837,82.8938] ]|
308 |
309 | #### Polyline
310 |
311 | Required props
312 |
313 | |Prop name|Dynamic|Description | Data example |
314 | |---------|:-----:|----------------|-----------------------------------------------------------|
315 | | points | ✓ |Points of line |[ [54.9827,82.8958], [54.9837,82.8968], [54.9837,82.8938] ]|
316 |
317 | Optional props
318 |
319 | |Prop name|Dynamic|Description | Data example |Default value|
320 | |---------|:-----:|----------------|--------------------------------|:-----------:|
321 | | label | ✓ |Text of label |example-string | - |
322 | | style | ✓ |Style of line |{color: '#FF0000'} | - |
323 |
324 | #### Polygon
325 |
326 | Required props
327 |
328 | |Prop name|Dynamic|Description | Data example |
329 | |---------|:-----:|------------------|-----------------------------------------------------------|
330 | | points | ✓ |Points of polygon |[ [54.9827,82.8958], [54.9837,82.8968], [54.9837,82.8938] ]|
331 |
332 | Optional props
333 |
334 | |Prop name|Dynamic|Description | Data example |Default value|
335 | |---------|:-----:|----------------|-----------------------|:-----------:|
336 | | label | ✓ |Text of label |example-string | - |
337 | | style | ✓ |Style of line |{color: '#FF0000'} | - |
338 |
339 | #### Rectangle
340 |
341 | Required props
342 |
343 | |Prop name|Dynamic|Description | Data example |
344 | |---------|:-----:|--------------------|----------------------------------------|
345 | | bounds | ✓ |Bounds of rectangle |[ [54.9827,82.8958], [54.9837,82.8968] ]|
346 |
347 | Optional props
348 |
349 | |Prop name|Dynamic|Description | Data example |Default value|
350 | |---------|:-----:|----------------|-----------------------|:-----------:|
351 | | label | ✓ |Text of label |example-string | - |
352 | | style | ✓ |Style of line |{color: '#FF0000'} | - |
353 |
354 | #### Circle
355 |
356 | Required props
357 |
358 | |Prop name|Dynamic|Description | Data example |
359 | |---------|:-----:|-----------------------|-------------------|
360 | | pos | ✓ |Position on map | [54.9827,82.8958] |
361 | | radius | ✓ |Circle radius in meters| 300 |
362 |
363 | Optional props
364 |
365 | |Prop name|Dynamic|Description | Data example |Default value|
366 | |---------|:-----:|----------------|-----------------------|:-----------:|
367 | | label | ✓ |Text of label |example-string | - |
368 | | style | ✓ |Style of line |{color: '#FF0000'} | - |
369 |
370 | #### CircleMarker
371 |
372 | Required props
373 |
374 | |Prop name|Dynamic|Description | Data example |
375 | |---------|:-----:|-----------------------|-------------------|
376 | | pos | ✓ |Position on map | [54.9827,82.8958] |
377 |
378 | Optional props
379 |
380 | |Prop name|Dynamic|Description | Data example |Default value|
381 | |---------|:-----:|-----------------------|-----------------------|:-----------:|
382 | | radius | ✓ |Circle radius in pixels| 300 | 10 |
383 | | label | ✓ |Text of label |example-string | - |
384 | | style | ✓ |Style of line |{color: '#FF0000'} | - |
385 |
386 | #### Wkt
387 |
388 | Required props
389 |
390 | |Prop name|Dynamic|Description | Data example |
391 | |---------|:-----:|-----------------------|-------------------------------------------------------------|
392 | | data | ✓ |Wkt data string | POLYGON((82.9155.04, 82.91 55.04, 82.91 55.04, 82.9155.04)) |
393 |
394 | Optional props
395 |
396 | |Prop name|Dynamic|Description | Data example |Default value|
397 | |---------|:-----:|-----------------------|-------------------|:-----------:|
398 | | style | ✓ |Style of objeck | {color: '#FF0000'}| - |
399 |
400 | #### GeoJSON
401 |
402 | Required props
403 |
404 | |Prop name|Dynamic|Description | Data example |
405 | |---------|:-----:|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
406 | | data | ✓ |GeoJSON data object | { "type": "Feature", "properties": { "address": "г. Новосибирск, пл. Карла Маркса, 7" }, "geometry": { "type": "Point", "coordinates": [82.8974, 54.9801] } }; |
407 |
408 | Optional props
409 |
410 | | Prop name |Dynamic|Description | Data example |Default value |
411 | |-------------|:-----:|---------------------------------|-------------------|:--------------------------:|
412 | |pointToLayer | ✓ |Function for render point | function() {} |Will be render simple Marker|
413 | |onEachFeature| ✓ |Function running on every element| function() {} | - |
414 | | filter | ✓ |Function for filter objects | function() {} | - |
415 | | style | ✓ |Style of object | {color: '#FF0000'}| - |
416 |
417 | ## Demo Development Server
418 |
419 | * `npm start` will run a development server with the component's demo app at [http://localhost:3000](http://localhost:3000) with hot module reloading.
420 |
421 | ## Building
422 |
423 | * `npm run build` will build the component for publishing to npm and also bundle the demo app.
424 |
425 | * `npm run clean` will delete built resources.
426 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "2gis-maps-react",
3 | "version": "0.0.3",
4 | "description": "2GIS Maps API React component",
5 | "main": "lib/index.js",
6 | "license": "MIT",
7 | "ignore": [],
8 | "authors": [],
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/2gis/2gis-maps-react.git"
12 | },
13 | "dependencies": {},
14 | "devDependencies": {
15 | "2gis/mapsapi": "^2.2.6",
16 | "insin/nwb": "0.9.x",
17 | "reactjs/react-bower": "^15.2.1"
18 | },
19 | "keywords": [
20 | "2gis",
21 | "map",
22 | "api",
23 | "react-component",
24 | "web-components"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/demo/src/GeometryCircle.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map, CircleMarker, Circle } from '../../src/'
3 |
4 | export default class GeometryCircle extends Component {
5 | state = {
6 | zoom: 17,
7 | center: [54.9827, 82.8958],
8 | geometry: [],
9 | pos: [54.9827, 82.8958],
10 | radius: 100,
11 | type: false // If is false then Circle, if is true then Circle Marker.
12 | };
13 |
14 | onChangePos = e => {
15 | this.setState({
16 | pos: e.target.value.split(',')
17 | });
18 | };
19 |
20 | onChangeRadius = e => {
21 | this.setState({
22 | radius: e.target.value
23 | });
24 | };
25 |
26 | onChangeCircleType = e => {
27 | if (e.target.value) {
28 | this.setState({
29 | type: false
30 | });
31 | }
32 | };
33 |
34 | onChangeCircleMarkerType = e => {
35 | if (e.target.value) {
36 | this.setState({
37 | type: true
38 | });
39 | }
40 | };
41 |
42 | addElement = e => {
43 | let geometry = this.state.geometry;
44 | const pos = this.state.pos;
45 | const radius = this.state.radius;
46 |
47 | if (this.state.type) {
48 | geometry.push(
49 |
58 | );
59 | }
60 | else {
61 | geometry.push(
62 |
68 | );
69 | }
70 | this.setState({
71 | geometry: geometry
72 | });
73 | };
74 |
75 | deleteElement = e => {
76 | let geometry = this.state.geometry;
77 | geometry.pop();
78 | this.setState({
79 | geometry: geometry
80 | });
81 | };
82 |
83 | render() {
84 | return (
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
107 |
108 | );
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/demo/src/GeometryPolygons.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map, Polygon, Rectangle , Polyline} from '../../src/'
3 |
4 | export default class GeometryPolygons extends Component {
5 | state = {
6 | zoom: 17,
7 | center: [54.9827, 82.8958],
8 | polygons: [],
9 | points: [
10 | [54.9827,82.8958],
11 | [54.9837,82.8968],
12 | [54.9837,82.8938]
13 | ],
14 | type: 0 // If is 0 then Line, if is 1 then Polygon, if is 2 then Rectangle.
15 | };
16 |
17 | onChangePoints = e => {
18 | this.setState({
19 | points: JSON.parse(e.target.value)
20 | });
21 | };
22 |
23 | onChangeLine = e => {
24 | if (e.target.value) {
25 | this.setState({
26 | type: 0
27 | });
28 | }
29 | };
30 |
31 | onChangePolygon = e => {
32 | if (e.target.value) {
33 | this.setState({
34 | type: 1
35 | });
36 | }
37 | };
38 |
39 | onChangeRectangle = e => {
40 | if (e.target.value) {
41 | this.setState({
42 | type: 2
43 | });
44 | }
45 | };
46 |
47 | addElement = e => {
48 | let polygons = this.state.polygons;
49 | const points = this.state.points;
50 |
51 | switch (this.state.type) {
52 | case 0:
53 | polygons.push(
54 |
59 | );
60 | break;
61 | case 1:
62 | polygons.push(
63 |
71 | );
72 | break;
73 | case 2:
74 | polygons.push(
75 |
83 | );
84 | break;
85 | }
86 |
87 | if (this.state.type) {
88 |
89 | }
90 | else {
91 |
92 | }
93 | this.setState({
94 | polygons: polygons
95 | });
96 | };
97 |
98 | deleteElement = e => {
99 | let polygons = this.state.polygons;
100 | polygons.pop();
101 | this.setState({
102 | polygons: polygons
103 | });
104 | };
105 |
106 | render() {
107 | return (
108 |
109 |
110 |
111 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
137 |
138 | );
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/demo/src/MarkerIcon.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map, Marker, Icon, DivIcon } from '../../src/'
3 |
4 | export default class MarkerIcon extends Component {
5 | state = {
6 | zoom: 13,
7 | center: [54.98, 82.89],
8 | url: 'http://maps.api.2gis.ru/2.0/example_logo.png',
9 | size: [48, 48],
10 | html: 'HTML-link',
11 | insideMarker: []
12 |
13 | };
14 |
15 | onChangeUrl = e => {
16 | this.setState({
17 | url: e.target.value
18 | });
19 | };
20 | onChangeSize= e => {
21 | this.setState({
22 | size: [e.target.value.split(',')[0], e.target.value.split(',')[1]]
23 | });
24 | };
25 |
26 | onChangeHtml = e => {
27 | this.setState({
28 | html: e.target.value
29 | });
30 | };
31 |
32 | changeToImage = () => {
33 | this.setState({
34 | insideMarker:
38 | });
39 | };
40 |
41 | changeToDiv = () => {
42 | this.setState({
43 | insideMarker:
47 |
48 | });
49 | };
50 |
51 | render() {
52 | return (
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
83 |
84 | );
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/demo/src/MarkerLabel.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map, Marker, Popup } from '../../src/'
3 |
4 | export default class MarkerLabel extends Component {
5 | state = {
6 | zoom: 13,
7 | center: [54.98, 82.89],
8 | markers: [],
9 | pos: [54.98, 82.89],
10 | staticLabel: false,
11 | labelContent: 'I\'m Label!'
12 | };
13 |
14 | onChangePos = e => {
15 | this.setState({
16 | pos: e.target.value.split(',')
17 | });
18 | };
19 |
20 | onChangeStaticLabel = () => {
21 | this.setState({
22 | staticLabel:!this.state.staticLabel
23 | });
24 | };
25 |
26 | onChangeLabelContent = e => {
27 | this.setState({
28 | labelContent: e.target.value
29 | });
30 | };
31 |
32 | addMarker = () => {
33 | let markers = this.state.markers;
34 | const pos = this.state.pos;
35 | const labelContent = this.state.labelContent;
36 |
37 | let staticLabel = false;
38 | let label = false;
39 |
40 | if (this.state.staticLabel) {
41 | staticLabel = labelContent;
42 | }
43 | else {
44 | label = labelContent;
45 | }
46 |
47 | markers.push(
48 |
53 | );
54 |
55 | this.setState({
56 | markers: markers
57 | });
58 | };
59 |
60 | removeMarker = () => {
61 | let markers = this.state.markers;
62 | markers.pop();
63 | this.setState({
64 | markers: markers
65 | });
66 | };
67 |
68 | render() {
69 | return (
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
96 |
97 | );
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/demo/src/Markers.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map, Marker, Popup } from '../../src/'
3 |
4 | export default class Markers extends Component {
5 | state = {
6 | zoom: 13,
7 | center: [54.98, 82.89],
8 | markers: [],
9 | pos: [54.98, 82.89],
10 | draggable: false,
11 | withPopup: false,
12 | popupContent: 'Hello world!'
13 | };
14 |
15 | onChangePos = e => {
16 | this.setState({
17 | pos: e.target.value.split(',')
18 | });
19 | };
20 |
21 | onChangeDraggable = () => {
22 | this.setState({
23 | draggable: !this.state.draggable
24 | });
25 | };
26 |
27 | onChangeWithPopup = () => {
28 | this.setState({
29 | withPopup:!this.state.withPopup
30 | });
31 | };
32 |
33 | onChangePopupContent = e => {
34 | this.setState({
35 | popupContent: e.target.value
36 | });
37 | };
38 |
39 | addMarker = () => {
40 | let markers = this.state.markers;
41 | const pos = this.state.pos;
42 | const draggable = this.state.draggable;
43 | const popupContent = this.state.popupContent;
44 | let popup = null;
45 | if (this.state.withPopup) {
46 | popup = (
47 |
48 | { popupContent }
49 |
50 | );
51 | }
52 | markers.push(
53 |
58 | { popup }
59 |
60 | );
61 | this.setState({
62 | markers: markers
63 | });
64 | };
65 |
66 | removeMarker = () => {
67 | let markers = this.state.markers;
68 | markers.pop();
69 | this.setState({
70 | markers: markers
71 | });
72 | };
73 |
74 | render() {
75 | return (
76 |
77 |
78 |
79 |
80 |
81 |
82 |
94 |
95 |
96 |
97 |
104 |
105 | );
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/demo/src/Popups.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map, Popup } from '../../src/'
3 |
4 | export default class Popups extends Component {
5 | state = {
6 | zoom: 13,
7 | center: [54.98, 82.89],
8 | popups: [],
9 | pos: [54.98, 82.89],
10 | popupContent: 'Hello world!',
11 | sprawling: false,
12 | maxWidth: 300,
13 | minWidth: 50,
14 | maxHeight: null
15 | };
16 |
17 | onChangePos = e => {
18 | this.setState({
19 | pos: e.target.value.split(',')
20 | });
21 | };
22 |
23 | onChangePopupContent = e => {
24 | this.setState({
25 | popupContent: e.target.value
26 | });
27 | };
28 |
29 | onChangeSprawling = e => {
30 | this.setState({
31 | sprawling: !this.state.sprawling
32 | });
33 | };
34 |
35 | onChangeMaxWidth = e => {
36 | this.setState({
37 | maxWidth: e.target.value
38 | });
39 | };
40 |
41 | onChangeMinWidth = e => {
42 | this.setState({
43 | minWidth: e.target.value
44 | });
45 | };
46 |
47 | onChangeMaxHeight = e => {
48 | this.setState({
49 | maxHeight: e.target.value
50 | });
51 | };
52 |
53 | addPopup = () => {
54 | const pos = this.state.pos;
55 | const popupContent = this.state.popupContent;
56 | const sprawling = this.state.sprawling;
57 | const maxWidth = this.state.maxWidth;
58 | const minWidth = this.state.minWidth;
59 | const maxHeight = this.state.maxHeight;
60 |
61 | let popups = this.state.popups;
62 |
63 | popups.push(
64 |
72 | { popupContent }
73 |
74 | );
75 | this.setState({
76 | popups: popups
77 | });
78 | };
79 |
80 | render() {
81 | return (
82 |
83 |
103 |
110 |
111 | );
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/demo/src/SimpleMap.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Map } from '../../src/'
3 |
4 | export default class SimpleMap extends Component {
5 | state = {
6 | zoom: 13,
7 | center: [54.98, 82.89]
8 | };
9 |
10 | onChangeZoom = e => {
11 | this.setState({
12 | zoom: e.target.value
13 | });
14 | };
15 |
16 | onChangeCenter = e => {
17 | this.setState({
18 | center: e.target.value.split(',')
19 | });
20 | };
21 |
22 | onZoomend = e => {
23 | this.setState({
24 | zoom: e.target.getZoom()
25 | });
26 | };
27 |
28 | onDrag = e => {
29 | this.setState({
30 | center: [
31 | e.target.getCenter().lat,
32 | e.target.getCenter().lng
33 | ]
34 | });
35 | };
36 |
37 | render() {
38 | return (
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
55 |
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/demo/src/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import ReactDOM from 'react-dom'
3 |
4 | import SimpleMap from './SimpleMap'
5 | import Popups from './Popups'
6 | import Markers from './Markers'
7 | import MarkerIcon from './MarkerIcon'
8 | import MarkerLabel from './MarkerLabel'
9 | import GeometryCircle from './GeometryCircle'
10 | import GeometryPolygons from './GeometryPolygons'
11 |
12 | class Examples extends Component {
13 | render() {
14 | return (
15 |
16 |
Simple map with editable zoom and center position #
17 |
18 |
19 |
20 |
21 |
22 |
Markers #
23 |
24 |
Markers with popup #
25 |
26 |
27 |
Marker with Icon #
28 |
29 |
30 |
Marker with Label #
31 |
32 |
33 |
Geometry #
34 |
35 |
Circle and Circle Marker #
36 |
37 |
38 |
Polygon and Rectangle #
39 |
40 |
41 | );
42 | };
43 | }
44 |
45 | const domElement = document.getElementById('demo');
46 | ReactDOM.render(, domElement);
47 |
--------------------------------------------------------------------------------
/nwb.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | type: 'react-component',
3 | build: {
4 | externals: {
5 | 'react': 'React'
6 | },
7 | global: 'y',
8 | jsNext: true,
9 | umd: true
10 | },
11 | babel: {
12 | stage: 0,
13 | optional: ['runtime']
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "2gis-maps-react",
3 | "version": "0.0.4",
4 | "description": "2gis-maps React component",
5 | "main": "lib/index.js",
6 | "jsnext:main": "es6/index.js",
7 | "files": [
8 | "css",
9 | "es6",
10 | "lib",
11 | "umd"
12 | ],
13 | "scripts": {
14 | "build": "nwb build",
15 | "clean": "nwb clean",
16 | "start": "nwb serve",
17 | "test": "nwb test",
18 | "test:watch": "nwb test --server"
19 | },
20 | "dependencies": {},
21 | "devDependencies": {
22 | "2gis-maps": "^2.2.6",
23 | "nwb": "0.9.x",
24 | "react": "^15.2.1",
25 | "react-dom": "^15.2.1"
26 | },
27 | "author": "",
28 | "homepage": "",
29 | "license": "MIT",
30 | "repository": "git@github.com:2gis/2gis-maps-react.git",
31 | "keywords": [
32 | "react-component",
33 | "web-components"
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/src/Circle.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Circle extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | pos: PropTypes.array,
9 | radius: PropTypes.number,
10 | label: PropTypes.string
11 | };
12 |
13 | state = {
14 | dgElement: null,
15 | childrenForRender: []
16 | };
17 |
18 | componentDidMount() {
19 | let dgElement = DG.circle(this.props.pos, this.props.radius);
20 |
21 | if (this.props.style) {
22 | dgElement.setStyle(this.props.style);
23 | }
24 |
25 | if (this.props.label) {
26 | dgElement.bindLabel(this.props.label);
27 | }
28 |
29 | this.setState({
30 | dgElement: dgElement
31 | });
32 |
33 | this.bindEvents(dgElement);
34 |
35 | this.props.element.addLayer(dgElement);
36 | }
37 |
38 | componentDidUpdate(prevProps) {
39 | let { dgElement } = this.state;
40 |
41 | this.updatePos(prevProps);
42 |
43 | if (this.checkPropsChange('radius', prevProps)) {
44 | dgElement.setRadius(this.props.radius);
45 | }
46 |
47 | this.updateLabel(prevProps);
48 |
49 | this.updateStyle(prevProps);
50 |
51 | this.updateEvents(dgElement, prevProps);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/CircleMarker.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class CircleMarker extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | pos: PropTypes.array,
9 | radius: PropTypes.number,
10 | label: PropTypes.string
11 | };
12 |
13 | state = {
14 | dgElement: null,
15 | childrenForRender: []
16 | };
17 |
18 | componentDidMount() {
19 | let dgElement = DG.circleMarker(this.props.pos);
20 |
21 | if (this.props.style) {
22 | dgElement.setStyle(this.props.style);
23 | }
24 |
25 | if (this.props.label) {
26 | dgElement.bindLabel(this.props.label);
27 | }
28 |
29 | if (this.props.radius) {
30 | dgElement.setRadius(this.props.radius);
31 | }
32 |
33 | this.setState({
34 | dgElement: dgElement
35 | });
36 |
37 | this.bindEvents(dgElement);
38 |
39 | this.props.element.addLayer(dgElement);
40 | }
41 |
42 | componentDidUpdate(prevProps) {
43 | let { dgElement } = this.state;
44 |
45 | this.updatePos(prevProps);
46 |
47 | if (this.checkPropsChange('radius', prevProps)) {
48 | dgElement.setRadius(this.props.radius);
49 | }
50 |
51 | this.updateLabel(prevProps);
52 |
53 | this.updateStyle(prevProps);
54 |
55 | this.updateEvents(dgElement, prevProps);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/DivIcon.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import ReactDOMServer from 'react-dom/server';
3 | import DG from '2gis-maps'
4 | import MapComponent from './MapComponent'
5 |
6 | export default class DivIcon extends MapComponent {
7 | static propsTypes = {
8 | iconSize: PropTypes.array,
9 | dangerouslySetInnerHTML: PropTypes.string
10 | };
11 |
12 | static defaultProps = {
13 | dangerouslySetInnerHTML: ''
14 | };
15 |
16 | componentDidMount() {
17 | let iconHtml = '';
18 | if (this.props.children) {
19 | iconHtml = ReactDOMServer.renderToString(
20 | { this.props.children }
25 | );
26 | }
27 | else {
28 | iconHtml = this.props.dangerouslySetInnerHTML;
29 | }
30 |
31 | let icon = DG.divIcon({
32 | iconSize: this.props.iconSize,
33 | html: iconHtml
34 | });
35 |
36 | this.props.element.setIcon(icon);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/GeoJSON.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class GeoJSON extends MapComponent {
6 | static propsTypes = {
7 | data: PropTypes.object,
8 | style: PropTypes.object,
9 | pointToLayer: PropTypes.func,
10 | onEachFeature: PropTypes.func,
11 | filter: PropTypes.func
12 | };
13 |
14 | static defaultProps = {
15 | style: null,
16 | pointToLayer: null,
17 | onEachFeature: null,
18 | filter: null
19 | };
20 |
21 | state = {
22 | dgElement: null
23 | };
24 |
25 | componentDidMount() {
26 | this.renderGeoJSON();
27 | }
28 |
29 | componentDidUpdate(prevProps) {
30 | if (this.checkPropsChange(['data', 'style', 'pointToLayer', 'onEachFeature', 'onEachFeature'], prevProps)) {
31 | this.renderGeoJSON();
32 | }
33 | }
34 |
35 | renderGeoJSON() {
36 | let options = {
37 | style: this.props.style,
38 | pointToLayer: this.props.pointToLayer,
39 | onEachFeature: this.props.onEachFeature,
40 | filter: this.props.filter
41 | };
42 |
43 | if (this.state.dgElement) {
44 | this.state.dgElement.remove();
45 | }
46 |
47 | let dgElement = DG.geoJson(this.props.data, options);
48 | this.props.element.addLayer(dgElement);
49 |
50 | this.setState({
51 | dgElement: dgElement
52 | });
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Icon.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Icon extends MapComponent {
6 | static propsTypes = {
7 | iconUrl: PropTypes.string,
8 | iconSize: PropTypes.array
9 | };
10 |
11 | componentDidMount() {
12 | this.setIcon();
13 | }
14 |
15 | componentDidUpdate(prevProps, prevState) {
16 | if (prevProps.iconUrl != this.props.iconUrl || prevProps.iconSize != this.props.iconSize) {
17 | this.setIcon();
18 | }
19 | this.props.element._bringToFront()
20 | }
21 |
22 | setIcon() {
23 | this.props.element.setIcon(DG.icon({
24 | iconUrl: this.props.iconUrl,
25 | iconSize: this.props.iconSize
26 | }));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Map.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import DG from '2gis-maps';
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Map extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | center: PropTypes.array,
9 | zoom: PropTypes.number,
10 | geoclicker: PropTypes.bool,
11 | projectDetector: PropTypes.bool,
12 | zoomControl: PropTypes.bool,
13 | fullscreenControl: PropTypes.bool,
14 | preferCanvas: PropTypes.bool,
15 | touchZoom: PropTypes.bool,
16 | scrollWheelZoom: PropTypes.bool,
17 | doubleClickZoom: PropTypes.bool,
18 | dragging: PropTypes.bool,
19 | maxBounds: PropTypes.array,
20 | minZoom: PropTypes.number,
21 | maxZoom: PropTypes.number
22 | };
23 |
24 | static defaultProps = {
25 | zoom: false,
26 | center: false,
27 | geoclicker: false,
28 | projectDetector: false,
29 | zoomControl: true,
30 | fullscreenControl: true,
31 | preferCanvas: true,
32 | touchZoom: true,
33 | scrollWheelZoom: true,
34 | doubleClickZoom: true,
35 | dragging: true
36 | };
37 |
38 | state = {
39 | dgElement: null,
40 | childrenForRender: []
41 | };
42 |
43 | componentDidMount() {
44 | const { container } = this.refs;
45 |
46 | // Map options.
47 | const {
48 | zoom, center, geoclicker, projectDetector, zoomControl, fullscreenControl, preferCanvas, touchZoom,
49 | scrollWheelZoom, doubleClickZoom, dragging, maxBounds, minZoom, maxZoom
50 | } = this.props;
51 |
52 | let options = {
53 | zoom, center, geoclicker, projectDetector, zoomControl, fullscreenControl, preferCanvas, touchZoom,
54 | scrollWheelZoom, doubleClickZoom, dragging, maxBounds, minZoom, maxZoom
55 | };
56 |
57 | // Check exist prop center.
58 | if (!center) {
59 | console.error('For initial map You should set prop \'center\'.');
60 | }
61 |
62 | // Check exist zoom center.
63 | if (!zoom) {
64 | console.error('For initial map You should set prop \'zoom\'.');
65 | }
66 |
67 | // Create Map.
68 | let dgElement = DG.map(container, options);
69 |
70 | if (this.props.onProjectChange) {
71 | dgElement.on('projectchange', e => this.props.onProjectChange(e));
72 | }
73 |
74 | if (this.props.onProjectLeave) {
75 | dgElement.on('projectleave', e => this.props.onProjectLeave(e));
76 | }
77 |
78 | this.setState({
79 | dgElement: dgElement
80 | });
81 |
82 | this.bindEvents(dgElement);
83 | }
84 |
85 | componentDidUpdate(prevProps, prevState) {
86 | const { dgElement } = this.state;
87 |
88 | if (this.checkPropsChange('center', prevProps)) {
89 | dgElement.setView(this.props.center);
90 | }
91 |
92 | if (this.checkPropsChange('zoom', prevProps)) {
93 | dgElement.setZoom(this.props.zoom);
94 | }
95 |
96 | if (this.checkPropsChange('style', prevProps)) {
97 | dgElement.invalidateSize();
98 | }
99 |
100 | this.updateEvents(dgElement, prevProps);
101 | }
102 |
103 | render() {
104 | return (
105 |
106 | { super.render() }
107 |
108 | );
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/MapComponent.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children, cloneElement } from 'react'
2 |
3 | export default class MapComponent extends Component {
4 | componentWillUnmount() {
5 | if (this.state && this.state.dgElement) {
6 | this.state.dgElement.remove();
7 | }
8 | }
9 |
10 | render() {
11 | let childrenForRender = [];
12 |
13 | if (this.state && this.state.dgElement && this.props.children ) {
14 | childrenForRender = Children.map(this.props.children,
15 | child => cloneElement(child, {
16 | element: this.state.dgElement
17 | })
18 | );
19 | }
20 |
21 | return (
22 |
25 | );
26 | }
27 |
28 | checkPropsChange(propsName, prevProps) {
29 | if (typeof propsName == 'string') {
30 | return prevProps[propsName] !== this.props[propsName];
31 | }
32 | else if (typeof propsName == 'object') {
33 | return propsName.some(name => {
34 | return prevProps[name] !== this.props[name]
35 | });
36 | }
37 | }
38 |
39 | updateLabel(prevProps) {
40 | if (this.checkPropsChange('label', prevProps)) {
41 | if (this.props.label) {
42 | this.state.dgElement.bindLabel(this.props.label);
43 | }
44 | else {
45 | this.state.dgElement.unbindLabel();
46 | }
47 | }
48 | }
49 |
50 | updatePos(prevProps) {
51 | if (this.checkPropsChange('pos', prevProps)) {
52 | this.state.dgElement.setLatLng(this.props.pos);
53 | }
54 | }
55 |
56 | updatePoints(prevProps) {
57 | if (this.checkPropsChange('points', prevProps)) {
58 | this.state.dgElement.setLatLngs(this.props.points);
59 | }
60 | }
61 |
62 | updateStyle(prevProps) {
63 | if (this.checkPropsChange('style', prevProps)) {
64 | this.state.dgElement.setStyle(this.props.style);
65 | }
66 | }
67 |
68 | insideMap() {
69 | return !!this.props.element.options.zoom
70 | }
71 |
72 | isFunction(variable) {
73 | return typeof variable === 'function';
74 | }
75 |
76 | bindEvents(dgElement) {
77 | for (let prop in this.props) {
78 | if (prop.slice(0, 2) === 'on' && this.isFunction(this.props[prop])) {
79 | dgElement.on(prop.slice(2).toLowerCase(), this.props[prop]);
80 | }
81 | }
82 | }
83 |
84 | updateEvents(dgElement, prevProps) {
85 | for (let prop in this.props) {
86 | if (prop.slice(0, 2) === 'on') {
87 | let dgPropName = prop.slice(2).toLowerCase();
88 |
89 | if (!prevProps[prop] && this.isFunction(this.props[prop])) {
90 | dgElement.on(dgPropName, this.props[prop]);
91 | }
92 |
93 | if (this.props[prop] !== prevProps[prop] && this.isFunction(this.props[prop])) {
94 | dgElement.off(dgPropName, prevProps[prop]);
95 | dgElement.on(dgPropName, this.props[prop]);
96 | }
97 |
98 | if (!this.props[prop] && this.isFunction(prevProps[prop])) {
99 | dgElement.off(dgPropName, prevProps[prop]);
100 | }
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/Marker.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Marker extends MapComponent {
6 | static propsTypes = {
7 | pos: PropTypes.array,
8 | label: PropTypes.string,
9 | staticLabel: PropTypes.string,
10 | draggable: PropTypes.bool,
11 | clickable: PropTypes.bool
12 | };
13 |
14 | static defaultProps = {
15 | draggable: false,
16 | clickable: true,
17 | label: false,
18 | staticLabel: false
19 | };
20 |
21 | state = {
22 | dgElement: null,
23 | childrenForRender: [],
24 | pos: this.props.pos || null
25 | };
26 |
27 | componentDidMount() {
28 | let dgElement = DG.marker(this.props.pos, {
29 | draggable: this.props.draggable,
30 | clickable: this.props.clickable
31 | });
32 |
33 | if (this.props.label) {
34 | dgElement.bindLabel(this.props.label);
35 | }
36 |
37 | this.setState({
38 | dgElement: dgElement
39 | }, () => {
40 | // For dragging Marker.
41 | if (this.props.draggable) {
42 | this.draggingSwitchTo(true);
43 | }
44 | });
45 |
46 | this.bindEvents(dgElement);
47 |
48 | // todo: fix it after fix https://github.com/2gis/mapsapi/issues/332
49 | if (this.props.staticLabel) {
50 | this.props.element.addLayer(dgElement);
51 |
52 | dgElement.bindLabel(this.props.staticLabel, { 'static': true });
53 | }
54 | else {
55 | this.props.element.addLayer(dgElement);
56 | }
57 | }
58 |
59 | componentDidUpdate(prevProps) {
60 | const { dgElement } = this.state;
61 |
62 | this.updatePos(prevProps);
63 |
64 | this.updateLabel(prevProps);
65 |
66 | // Update static label.
67 | if (this.checkPropsChange('staticLabel', prevProps)) {
68 | dgElement.bindLabel(this.props.staticLabel, { 'static': true });
69 | }
70 |
71 | // Update draggable.
72 | if (this.checkPropsChange('draggable', prevProps)) {
73 | this.draggingSwitchTo(this.props.draggable);
74 | }
75 |
76 | this.updateEvents(dgElement, prevProps);
77 | }
78 |
79 | dragging = e => {
80 | this.setState({
81 | dgElement: this.state.dgElement,
82 | childrenForRender: this.state.childrenForRender,
83 | pos: e.latlng
84 | });
85 | };
86 |
87 | draggingSwitchTo(isEnable) {
88 | const { dgElement } = this.state;
89 |
90 | if (isEnable) {
91 | dgElement.on('drag', this.dragging);
92 | dgElement.dragging.enable();
93 | }
94 | else {
95 | dgElement.off('drag', this.dragging);
96 | dgElement.dragging.disable();
97 | dgElement.setLatLng(this.state.pos);
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Polygon.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Polygon extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | points: PropTypes.array,
9 | label: PropTypes.string
10 | };
11 |
12 | state = {
13 | dgElement: null,
14 | childrenForRender: []
15 | };
16 |
17 | componentDidMount() {
18 | let dgElement = DG.polygon(this.props.points);
19 |
20 | if (this.props.style) {
21 | dgElement.setStyle(this.props.style);
22 | }
23 |
24 | if (this.props.label) {
25 | dgElement.bindLabel(this.props.label)
26 | }
27 |
28 | this.setState({
29 | dgElement: dgElement
30 | });
31 |
32 | this.bindEvents(dgElement);
33 |
34 | this.props.element.addLayer(dgElement);
35 | }
36 |
37 | componentDidUpdate(prevProps) {
38 | this.updatePoints(prevProps);
39 | this.updateLabel(prevProps);
40 | this.updateStyle(prevProps);
41 | this.updateEvents(this.state.dgElement);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Polyline.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Polyline extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | points: PropTypes.array,
9 | label: PropTypes.string
10 | };
11 |
12 | state = {
13 | dgElement: null
14 | };
15 |
16 | static defaultProps = {
17 | style: null
18 | };
19 |
20 | componentDidMount() {
21 | let dgElement = DG.polyline(this.props.points, this.props.style);
22 |
23 | if (this.props.label) {
24 | dgElement.bindLabel(this.props.label)
25 | }
26 |
27 | this.setState({
28 | dgElement: dgElement
29 | });
30 |
31 | this.bindEvents(dgElement);
32 |
33 | this.props.element.addLayer(dgElement);
34 | }
35 |
36 | componentDidUpdate(prevProps) {
37 | this.updatePoints(prevProps);
38 | this.updateLabel(prevProps);
39 | this.updateStyle(prevProps);
40 | this.updateEvents(this.state.dgElement);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Popup.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import ReactDOMServer from 'react-dom/server';
3 | import DG from '2gis-maps'
4 | import MapComponent from './MapComponent'
5 |
6 | export default class Popup extends MapComponent {
7 | static propsTypes = {
8 | pos: PropTypes.array,
9 | maxWidth: PropTypes.number,
10 | minWidth: PropTypes.number,
11 | maxHeight: PropTypes.number,
12 | sprawling: PropTypes.bool,
13 | className: PropTypes.string
14 | };
15 |
16 | static defaultProps = {
17 | maxWidth: 300,
18 | minWidth: 50,
19 | maxHeight: null,
20 | sprawling: false,
21 | className: ''
22 | };
23 |
24 | componentDidMount() {
25 | const popupHtml = this.renderChildren();
26 |
27 | let { element } = this.props;
28 |
29 | let dgElement = null;
30 |
31 | // Popup options.
32 | const {
33 | maxWidth, minWidth, maxHeight, sprawling, className
34 | } = this.props;
35 |
36 | let options = {
37 | maxWidth, minWidth, maxHeight, sprawling, className
38 | };
39 |
40 | if (this.insideMap()) {
41 | dgElement = DG.popup(options)
42 | .setLatLng(this.props.pos)
43 | .setContent(popupHtml)
44 | .openOn(element);
45 | } else {
46 | if (element.getPopup()) {
47 | element.setPopupContent(popupHtml);
48 | }
49 | else {
50 | element.bindPopup(popupHtml, options);
51 | }
52 |
53 | dgElement = element.getPopup()
54 | }
55 | }
56 |
57 | componentDidUpdate(prevProps, prevState) {
58 | let { element } = this.props;
59 |
60 | if (prevProps.children != this.props.children) {
61 | const popupHtml = this.renderChildren();
62 |
63 | if (this.insideMap()) {
64 | element.getPopup().setContent(popupHtml)
65 | }
66 | else {
67 | element.setPopupContent(popupHtml);
68 | }
69 | }
70 |
71 | this.updatePos(prevProps);
72 |
73 | if (element.getPopup) {
74 | this.updateEvents(element.getPopup());
75 | }
76 | }
77 |
78 | componentWillUnmount() {
79 | this.props.element.unbindPopup();
80 | }
81 |
82 | renderChildren() {
83 | return ReactDOMServer.renderToString(
84 | { this.props.children }
89 | );
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Rectangle.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Rectangle extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | bounds: PropTypes.array,
9 | label: PropTypes.string
10 | };
11 |
12 | state = {
13 | dgElement: null,
14 | childrenForRender: []
15 | };
16 |
17 | componentDidMount() {
18 | let dgElement = DG.rectangle(this.props.bounds);
19 |
20 | if (this.props.style) {
21 | dgElement.setStyle(this.props.style);
22 | }
23 |
24 | if (this.props.label) {
25 | dgElement.bindLabel(this.props.label)
26 | }
27 |
28 | this.setState({
29 | dgElement: dgElement
30 | });
31 |
32 | this.bindEvents(dgElement);
33 |
34 | this.props.element.addLayer(dgElement);
35 | }
36 |
37 | componentDidUpdate(prevProps) {
38 | let { dgElement } = this.state;
39 |
40 | if (this.checkPropsChange('bounds', prevProps)) {
41 | dgElement.setBounds(this.props.bounds);
42 | }
43 | this.updateLabel(prevProps);
44 | this.updateStyle(prevProps);
45 | this.updateEvents(dgElement, prevProps);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Ruler.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Ruler extends MapComponent {
6 | static propsTypes = {
7 | points: PropTypes.array
8 | };
9 |
10 | state = {
11 | dgElement: null
12 | };
13 |
14 | componentDidMount() {
15 | let dgElement = DG.ruler(this.props.points);
16 | this.props.element.addLayer(dgElement);
17 | this.setState({
18 | dgElement: dgElement
19 | });
20 | }
21 |
22 | componentDidUpdate(prevProps, prevState) {
23 | this.updatePoints(prevProps);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Wkt.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import DG from '2gis-maps'
3 | import MapComponent from './MapComponent'
4 |
5 | export default class Wkt extends MapComponent {
6 | static propsTypes = {
7 | style: PropTypes.object,
8 | data: PropTypes.string
9 | };
10 |
11 | static defaultProps = {
12 | style: null
13 | };
14 |
15 | state = {
16 | dgElement: null
17 | };
18 |
19 | componentDidMount() {
20 | this.renderWkt();
21 | }
22 |
23 | componentDidUpdate(prevProps) {
24 | if (this.checkPropsChange(['data', 'style'], prevProps)) {
25 | this.renderWkt();
26 | }
27 | }
28 |
29 | renderWkt() {
30 | let dgElement = DG.Wkt.geoJsonLayer(this.props.data, this.props.style);
31 |
32 | if (this.state.dgElement) {
33 | this.state.dgElement.remove();
34 | }
35 |
36 | this.props.element.addLayer(dgElement);
37 |
38 | this.setState({
39 | dgElement: dgElement
40 | });
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export Map from './Map.js';
2 | export Marker from './Marker.js';
3 | export Popup from './Popup.js';
4 | export Icon from './Icon.js';
5 | export DivIcon from './DivIcon.js';
6 | export Ruler from './Ruler.js';
7 | export GeoJSON from './GeoJSON.js';
8 | export Wkt from './Wkt.js';
9 | export Circle from './Circle.js';
10 | export CircleMarker from './CircleMarker.js';
11 | export Polyline from './Polyline.js';
12 | export Polygon from './Polygon.js';
13 | export Rectangle from './Rectangle.js';
14 |
--------------------------------------------------------------------------------
/tests/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/tests/index-test.js:
--------------------------------------------------------------------------------
1 | import expect from 'expect'
2 | import React from 'react'
3 | import { render, unmountComponentAtNode } from 'react-dom'
4 |
5 | import { Map, Marker } from 'src/'
6 |
7 | describe('Map component with Marker inside', () => {
8 | let node;
9 |
10 | const map = (
11 |
20 | );
21 |
22 | beforeEach(() => {
23 | node = document.createElement('div')
24 | });
25 |
26 | afterEach(() => {
27 | unmountComponentAtNode(node)
28 | });
29 |
30 | it('displays a static label', () => {
31 | render(map, node, () => {
32 | expect(node.innerHTML).toContain('I\'m marker on map.')
33 | });
34 | })
35 | });
36 |
--------------------------------------------------------------------------------