react-spatial 1.5.2 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/.github/workflows/conventional-pr-title.yml +21 -0
  2. package/.github/workflows/main.yml +28 -0
  3. package/.husky/commit-msg +4 -0
  4. package/.husky/post-checkout +4 -0
  5. package/.husky/post-merge +4 -0
  6. package/.husky/post-rebase +4 -0
  7. package/.husky/pre-commit +4 -0
  8. package/.nvmrc +1 -0
  9. package/.whitesource +8 -0
  10. package/CHANGELOG.md +65 -0
  11. package/DEVELOP.md +113 -0
  12. package/__mocks__/mapbox-gl.js +11 -0
  13. package/__mocks__/resize-observer-polyfill.js +9 -0
  14. package/babel.config.js +3 -0
  15. package/commitlint.config.js +1 -0
  16. package/data/topic1.js +119 -0
  17. package/data/topic2.js +28 -0
  18. package/doc/README.md +21 -0
  19. package/doc/doc-config.json +4 -0
  20. package/package.json +4 -3
  21. package/pull_request_template.md +16 -0
  22. package/renovate.json +4 -0
  23. package/scripts/read-pkg-json.js +17 -0
  24. package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.js +322 -0
  25. package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.test.js +69 -0
  26. package/src/components/BaseLayerSwitcher/README.md +61 -0
  27. package/src/components/BaseLayerSwitcher/__snapshots__/BaseLayerSwitcher.test.js.snap +88 -0
  28. package/src/components/BaseLayerSwitcher/index.js +1 -0
  29. package/src/components/BasicMap/BasicMap.js +413 -0
  30. package/src/components/BasicMap/BasicMap.test.js +281 -0
  31. package/src/components/BasicMap/README.md +18 -0
  32. package/src/components/BasicMap/index.js +1 -0
  33. package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.js +320 -93
  34. package/src/components/CanvasSaveButton/CanvasSaveButton.test.js +148 -0
  35. package/src/components/CanvasSaveButton/README.md +76 -0
  36. package/src/components/CanvasSaveButton/__snapshots__/CanvasSaveButton.test.js.snap +76 -0
  37. package/src/components/CanvasSaveButton/index.js +1 -0
  38. package/src/components/Copyright/Copyright.js +89 -0
  39. package/src/components/Copyright/Copyright.test.js +134 -0
  40. package/src/components/Copyright/README.md +36 -0
  41. package/src/components/Copyright/index.js +1 -0
  42. package/src/components/FeatureExportButton/FeatureExportButton.js +118 -0
  43. package/src/components/FeatureExportButton/FeatureExportButton.test.js +417 -0
  44. package/src/components/FeatureExportButton/README.md +76 -0
  45. package/src/components/FeatureExportButton/__snapshots__/FeatureExportButton.test.js.snap +67 -0
  46. package/src/components/FeatureExportButton/index.js +1 -0
  47. package/src/components/FitExtent/FitExtent.js +62 -0
  48. package/src/components/FitExtent/FitExtent.test.js +48 -0
  49. package/src/components/FitExtent/README.md +34 -0
  50. package/src/components/FitExtent/__snapshots__/FitExtent.test.js.snap +13 -0
  51. package/src/components/FitExtent/index.js +1 -0
  52. package/{components → src/components}/Geolocation/Geolocation.js +144 -61
  53. package/src/components/Geolocation/Geolocation.test.js +267 -0
  54. package/src/components/Geolocation/README.md +25 -0
  55. package/src/components/Geolocation/__snapshots__/Geolocation.test.js.snap +92 -0
  56. package/src/components/Geolocation/index.js +1 -0
  57. package/src/components/LayerTree/LayerTree.js +487 -0
  58. package/src/components/LayerTree/LayerTree.test.js +337 -0
  59. package/src/components/LayerTree/README.md +92 -0
  60. package/src/components/LayerTree/__snapshots__/LayerTree.test.js.snap +1746 -0
  61. package/src/components/LayerTree/index.js +1 -0
  62. package/src/components/MousePosition/MousePosition.js +175 -0
  63. package/src/components/MousePosition/MousePosition.test.js +132 -0
  64. package/src/components/MousePosition/README.md +50 -0
  65. package/src/components/MousePosition/__snapshots__/MousePosition.test.js.snap +76 -0
  66. package/src/components/MousePosition/index.js +1 -0
  67. package/src/components/NorthArrow/NorthArrow.js +75 -0
  68. package/src/components/NorthArrow/NorthArrow.test.js +104 -0
  69. package/src/components/NorthArrow/README.md +59 -0
  70. package/src/components/NorthArrow/__snapshots__/NorthArrow.test.js.snap +117 -0
  71. package/src/components/NorthArrow/index.js +1 -0
  72. package/src/components/Overlay/Overlay.js +176 -0
  73. package/src/components/Overlay/Overlay.test.js +149 -0
  74. package/src/components/Overlay/README.md +59 -0
  75. package/src/components/Overlay/__snapshots__/Overlay.test.js.snap +9 -0
  76. package/src/components/Overlay/index.js +1 -0
  77. package/src/components/Permalink/Permalink.js +326 -0
  78. package/src/components/Permalink/Permalink.test.js +285 -0
  79. package/src/components/Permalink/README.md +105 -0
  80. package/src/components/Permalink/index.js +1 -0
  81. package/{components → src/components}/Popup/Popup.js +165 -55
  82. package/src/components/Popup/Popup.test.js +307 -0
  83. package/src/components/Popup/README.md +93 -0
  84. package/src/components/Popup/__snapshots__/Popup.test.js.snap +180 -0
  85. package/src/components/Popup/index.js +1 -0
  86. package/src/components/README.md +41 -0
  87. package/{components → src/components}/ResizeHandler/ResizeHandler.js +50 -15
  88. package/src/components/ResizeHandler/ResizeHandler.test.js +344 -0
  89. package/src/components/ResizeHandler/index.js +1 -0
  90. package/src/components/RouteSchedule/README.md +118 -0
  91. package/src/components/RouteSchedule/RouteSchedule.js +370 -0
  92. package/src/components/RouteSchedule/RouteSchedule.test.js +113 -0
  93. package/src/components/RouteSchedule/__snapshots__/RouteSchedule.test.js.snap +248 -0
  94. package/src/components/RouteSchedule/index.js +1 -0
  95. package/src/components/ScaleLine/README.md +29 -0
  96. package/src/components/ScaleLine/ScaleLine.js +50 -0
  97. package/src/components/ScaleLine/ScaleLine.test.js +30 -0
  98. package/src/components/ScaleLine/__snapshots__/ScaleLine.test.js.snap +7 -0
  99. package/src/components/ScaleLine/index.js +1 -0
  100. package/src/components/StopsFinder/README.md +50 -0
  101. package/src/components/StopsFinder/StopsFinder.js +284 -0
  102. package/src/components/StopsFinder/StopsFinder.test.js +17 -0
  103. package/src/components/StopsFinder/StopsFinderOption.js +61 -0
  104. package/src/components/StopsFinder/__snapshots__/StopsFinder.test.js.snap +133 -0
  105. package/src/components/StopsFinder/index.js +1 -0
  106. package/src/components/Zoom/README.md +25 -0
  107. package/src/components/Zoom/Zoom.js +180 -0
  108. package/src/components/Zoom/Zoom.test.js +141 -0
  109. package/src/components/Zoom/__snapshots__/Zoom.test.js.snap +201 -0
  110. package/src/components/Zoom/index.js +1 -0
  111. package/{propTypes.js → src/propTypes.js} +16 -12
  112. package/{setupTests.js → src/setupTests.js} +1 -1
  113. package/src/styleguidist/ComponentsList.js +52 -0
  114. package/src/styleguidist/StyleGuide.js +277 -0
  115. package/src/styleguidist/styleguidist.css +38 -0
  116. package/src/utils/GlobalsForOle.js +99 -0
  117. package/src/utils/KML.js +594 -0
  118. package/src/utils/KML.test.js +337 -0
  119. package/src/utils/KMLFormat.js +100 -0
  120. package/src/utils/KMLFormat.test.js +50 -0
  121. package/{utils → src/utils}/Styles.js +20 -14
  122. package/src/utils/__snapshots__/KML.test.js.snap.KML-readFeatures()-and-writeFeatures()-should-read-and-write-lineDash-and-fillPattern-style-for-polygon.canvas-image.png +0 -0
  123. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-2-(cross)-color-and-(light-blue)-opacity.canvas-image.png +0 -0
  124. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-3-(diagonal-line-from-bottom-left-tot-top-right)-with-color-(light-blue)-and-opacity.canvas-image.png +0 -0
  125. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-4-(diagonal-line-from-top-left-to-bottom-right)-with-color-(light-blue)-and-opacity.canvas-image.png +0 -0
  126. package/{utils → src/utils}/getPolygonPattern.js +34 -6
  127. package/src/utils/getPolygonPattern.test.js +61 -0
  128. package/src/utils/timeUtils.js +52 -0
  129. package/src/utils/timeUtils.test.js +30 -0
  130. package/styleguide.config.js +251 -0
  131. package/components/BaseLayerSwitcher/BaseLayerSwitcher.js +0 -231
  132. package/components/BaseLayerSwitcher/BaseLayerSwitcher.js.map +0 -7
  133. package/components/BaseLayerSwitcher/index.js +0 -1
  134. package/components/BaseLayerSwitcher/index.js.map +0 -7
  135. package/components/BasicMap/BasicMap.js +0 -278
  136. package/components/BasicMap/BasicMap.js.map +0 -7
  137. package/components/BasicMap/index.js +0 -1
  138. package/components/BasicMap/index.js.map +0 -7
  139. package/components/CanvasSaveButton/CanvasSaveButton.js.map +0 -7
  140. package/components/CanvasSaveButton/index.js +0 -1
  141. package/components/CanvasSaveButton/index.js.map +0 -7
  142. package/components/Copyright/Copyright.js +0 -55
  143. package/components/Copyright/Copyright.js.map +0 -7
  144. package/components/Copyright/index.js +0 -1
  145. package/components/Copyright/index.js.map +0 -7
  146. package/components/FeatureExportButton/FeatureExportButton.js +0 -62
  147. package/components/FeatureExportButton/FeatureExportButton.js.map +0 -7
  148. package/components/FeatureExportButton/index.js +0 -1
  149. package/components/FeatureExportButton/index.js.map +0 -7
  150. package/components/FitExtent/FitExtent.js +0 -32
  151. package/components/FitExtent/FitExtent.js.map +0 -7
  152. package/components/FitExtent/index.js +0 -1
  153. package/components/FitExtent/index.js.map +0 -7
  154. package/components/Geolocation/Geolocation.js.map +0 -7
  155. package/components/Geolocation/index.js +0 -1
  156. package/components/Geolocation/index.js.map +0 -7
  157. package/components/LayerTree/LayerTree.js +0 -278
  158. package/components/LayerTree/LayerTree.js.map +0 -7
  159. package/components/LayerTree/index.js +0 -1
  160. package/components/LayerTree/index.js.map +0 -7
  161. package/components/MousePosition/MousePosition.js +0 -110
  162. package/components/MousePosition/MousePosition.js.map +0 -7
  163. package/components/MousePosition/index.js +0 -1
  164. package/components/MousePosition/index.js.map +0 -7
  165. package/components/NorthArrow/NorthArrow.js +0 -43
  166. package/components/NorthArrow/NorthArrow.js.map +0 -7
  167. package/components/NorthArrow/index.js +0 -1
  168. package/components/NorthArrow/index.js.map +0 -7
  169. package/components/Overlay/Overlay.js +0 -122
  170. package/components/Overlay/Overlay.js.map +0 -7
  171. package/components/Overlay/index.js +0 -1
  172. package/components/Overlay/index.js.map +0 -7
  173. package/components/Permalink/Permalink.js +0 -206
  174. package/components/Permalink/Permalink.js.map +0 -7
  175. package/components/Permalink/index.js +0 -1
  176. package/components/Permalink/index.js.map +0 -7
  177. package/components/Popup/Popup.js.map +0 -7
  178. package/components/Popup/index.js +0 -1
  179. package/components/Popup/index.js.map +0 -7
  180. package/components/ResizeHandler/ResizeHandler.js.map +0 -7
  181. package/components/ResizeHandler/index.js +0 -1
  182. package/components/ResizeHandler/index.js.map +0 -7
  183. package/components/RouteSchedule/RouteSchedule.js +0 -220
  184. package/components/RouteSchedule/RouteSchedule.js.map +0 -7
  185. package/components/RouteSchedule/index.js +0 -1
  186. package/components/RouteSchedule/index.js.map +0 -7
  187. package/components/ScaleLine/ScaleLine.js +0 -32
  188. package/components/ScaleLine/ScaleLine.js.map +0 -7
  189. package/components/ScaleLine/index.js +0 -1
  190. package/components/ScaleLine/index.js.map +0 -7
  191. package/components/StopsFinder/StopsFinder.js +0 -210
  192. package/components/StopsFinder/StopsFinder.js.map +0 -7
  193. package/components/StopsFinder/StopsFinderOption.js +0 -51
  194. package/components/StopsFinder/StopsFinderOption.js.map +0 -7
  195. package/components/StopsFinder/index.js +0 -1
  196. package/components/StopsFinder/index.js.map +0 -7
  197. package/components/Zoom/Zoom.js +0 -130
  198. package/components/Zoom/Zoom.js.map +0 -7
  199. package/components/Zoom/index.js +0 -1
  200. package/components/Zoom/index.js.map +0 -7
  201. package/propTypes.js.map +0 -7
  202. package/setupTests.js.map +0 -7
  203. package/utils/GlobalsForOle.js +0 -94
  204. package/utils/GlobalsForOle.js.map +0 -7
  205. package/utils/KML.js +0 -412
  206. package/utils/KML.js.map +0 -7
  207. package/utils/KMLFormat.js +0 -69
  208. package/utils/KMLFormat.js.map +0 -7
  209. package/utils/Styles.js.map +0 -7
  210. package/utils/getPolygonPattern.js.map +0 -7
  211. package/utils/timeUtils.js +0 -31
  212. package/utils/timeUtils.js.map +0 -7
  213. /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.md.scss +0 -0
  214. /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.scss +0 -0
  215. /package/{components → src/components}/BasicMap/BasicMap.md.scss +0 -0
  216. /package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.md.scss +0 -0
  217. /package/{components → src/components}/Copyright/Copyright.md.scss +0 -0
  218. /package/{components → src/components}/FeatureExportButton/FeatureExportButton.md.scss +0 -0
  219. /package/{components → src/components}/FitExtent/FitExtent.md.scss +0 -0
  220. /package/{components → src/components}/Geolocation/Geolocation.md.scss +0 -0
  221. /package/{components → src/components}/Geolocation/Geolocation.scss +0 -0
  222. /package/{components → src/components}/LayerTree/LayerTree.md.scss +0 -0
  223. /package/{components → src/components}/LayerTree/LayerTree.scss +0 -0
  224. /package/{components → src/components}/MousePosition/MousePosition.md.scss +0 -0
  225. /package/{components → src/components}/NorthArrow/NorthArrow.scss +0 -0
  226. /package/{components → src/components}/Overlay/Overlay.md.scss +0 -0
  227. /package/{components → src/components}/Overlay/Overlay.scss +0 -0
  228. /package/{components → src/components}/Permalink/Permalink.md.scss +0 -0
  229. /package/{components → src/components}/Popup/Popup.md.scss +0 -0
  230. /package/{components → src/components}/Popup/Popup.scss +0 -0
  231. /package/{components → src/components}/RouteSchedule/RouteSchedule.md.scss +0 -0
  232. /package/{components → src/components}/RouteSchedule/RouteSchedule.scss +0 -0
  233. /package/{components → src/components}/ScaleLine/ScaleLine.scss +0 -0
  234. /package/{components → src/components}/Zoom/Zoom.md.scss +0 -0
  235. /package/{components → src/components}/Zoom/Zoom.scss +0 -0
  236. /package/{images → src/images}/RouteSchedule/firstStation.png +0 -0
  237. /package/{images → src/images}/RouteSchedule/lastStation.png +0 -0
  238. /package/{images → src/images}/RouteSchedule/line.png +0 -0
  239. /package/{images → src/images}/RouteSchedule/station.png +0 -0
  240. /package/{images → src/images}/baselayer/baselayer.basebright.png +0 -0
  241. /package/{images → src/images}/baselayer/baselayer.osm.png +0 -0
  242. /package/{images → src/images}/baselayer/baselayer.travic.png +0 -0
  243. /package/{images → src/images}/baselayer/open.topo.map.png +0 -0
  244. /package/{images → src/images}/baselayer/osm.baselayer.hot.png +0 -0
  245. /package/{images → src/images}/baselayer/osm.baselayer.png +0 -0
  246. /package/{images → src/images}/favicon.png +0 -0
  247. /package/{images → src/images}/geops_logo.png +0 -0
  248. /package/{images → src/images}/geops_logo.svg +0 -0
  249. /package/{images → src/images}/geops_qr.png +0 -0
  250. /package/{images → src/images}/mots/bus_poi-blue-01.svg +0 -0
  251. /package/{images → src/images}/mots/bus_poi-grey-01.svg +0 -0
  252. /package/{images → src/images}/mots/bus_round-blue-01.svg +0 -0
  253. /package/{images → src/images}/mots/bus_round-grey-01.svg +0 -0
  254. /package/{images → src/images}/mots/bus_square-blue-01.svg +0 -0
  255. /package/{images → src/images}/mots/bus_square-grey-01.svg +0 -0
  256. /package/{images → src/images}/mots/cable_car_poi-blue-01.svg +0 -0
  257. /package/{images → src/images}/mots/cable_car_poi-grey-01.svg +0 -0
  258. /package/{images → src/images}/mots/cable_car_round-blue-01.svg +0 -0
  259. /package/{images → src/images}/mots/cable_car_round-grey-01.svg +0 -0
  260. /package/{images → src/images}/mots/cable_car_square-blue-01.svg +0 -0
  261. /package/{images → src/images}/mots/cable_car_square-grey-01.svg +0 -0
  262. /package/{images → src/images}/mots/ferry_poi-blue-01.svg +0 -0
  263. /package/{images → src/images}/mots/ferry_poi-grey-01.svg +0 -0
  264. /package/{images → src/images}/mots/ferry_round-blue-01.svg +0 -0
  265. /package/{images → src/images}/mots/ferry_round-grey-01.svg +0 -0
  266. /package/{images → src/images}/mots/ferry_square-blue-01.svg +0 -0
  267. /package/{images → src/images}/mots/ferry_square-grey-01.svg +0 -0
  268. /package/{images → src/images}/mots/funicular_round-blue-01.svg +0 -0
  269. /package/{images → src/images}/mots/funicular_round-grey-01.svg +0 -0
  270. /package/{images → src/images}/mots/funicular_square-blue-01.svg +0 -0
  271. /package/{images → src/images}/mots/gondola_round-blue-01.svg +0 -0
  272. /package/{images → src/images}/mots/rail_poi-blue-01.svg +0 -0
  273. /package/{images → src/images}/mots/rail_poi-grey-01.svg +0 -0
  274. /package/{images → src/images}/mots/rail_round-blue-01.svg +0 -0
  275. /package/{images → src/images}/mots/rail_round-grey-01.svg +0 -0
  276. /package/{images → src/images}/mots/rail_square-blue-01.svg +0 -0
  277. /package/{images → src/images}/mots/rail_square-grey-01.svg +0 -0
  278. /package/{images → src/images}/mots/subway_round blue-01.svg +0 -0
  279. /package/{images → src/images}/mots/subway_round-blue-01.svg +0 -0
  280. /package/{images → src/images}/mots/tram_poi-blue-01.svg +0 -0
  281. /package/{images → src/images}/mots/tram_poi-grey-01.svg +0 -0
  282. /package/{images → src/images}/mots/tram_round-blue-01.svg +0 -0
  283. /package/{images → src/images}/mots/tram_round-grey-01.svg +0 -0
  284. /package/{images → src/images}/mots/tram_square-blue-01.svg +0 -0
  285. /package/{images → src/images}/mots/tram_square-grey-01.svg +0 -0
  286. /package/{images → src/images}/northArrow.svg +0 -0
  287. /package/{images → src/images}/northArrow.url.svg +0 -0
  288. /package/{images → src/images}/northArrowCircle.svg +0 -0
  289. /package/{images → src/images}/northArrowCircle.url.svg +0 -0
  290. /package/{themes → src/themes}/README.md +0 -0
  291. /package/{themes → src/themes}/default/components.scss +0 -0
  292. /package/{themes → src/themes}/default/examples.scss +0 -0
  293. /package/{themes → src/themes}/default/index.scss +0 -0
  294. /package/{themes → src/themes}/default/mixins.scss +0 -0
  295. /package/{themes → src/themes}/default/variables.scss +0 -0
@@ -1,138 +1,233 @@
1
- import React, { PureComponent } from "react";
2
- import PropTypes from "prop-types";
3
- import { MdClose } from "react-icons/md";
4
- import OLMap from "ol/Map";
5
- import Feature from "ol/Feature";
6
- import { getCenter } from "ol/extent";
7
- import { unByKey } from "ol/Observable";
1
+ import React, { PureComponent } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import { MdClose } from 'react-icons/md';
5
+ import OLMap from 'ol/Map';
6
+ import Feature from 'ol/Feature';
7
+ import { getCenter } from 'ol/extent';
8
+ import { unByKey } from 'ol/Observable';
9
+
8
10
  const propTypes = {
11
+ /**
12
+ * React Children.
13
+ */
9
14
  children: PropTypes.node.isRequired,
15
+
16
+ /**
17
+ * An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
18
+ */
10
19
  map: PropTypes.instanceOf(OLMap).isRequired,
20
+
21
+ /**
22
+ * An [ol/Feature](https://openlayers.org/en/latest/apidoc/module-ol_Feature-Feature.html).
23
+ */
11
24
  feature: PropTypes.instanceOf(Feature),
25
+
26
+ /**
27
+ * Popup title.
28
+ */
12
29
  header: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
30
+
31
+ /**
32
+ * If true, the popup is panned in the map's viewport.
33
+ */
13
34
  panIntoView: PropTypes.bool,
35
+
36
+ /**
37
+ * Custom BoundingClientRect to fit popup into.
38
+ * Use if panIntoView is true. Default is the map's BoundingClientRect.
39
+ */
14
40
  panRect: PropTypes.objectOf(PropTypes.number),
41
+
42
+ /**
43
+ * Coordinate position of the popup.
44
+ */
15
45
  popupCoordinate: PropTypes.arrayOf(PropTypes.number),
46
+
47
+ /**
48
+ * Class name of the popup.
49
+ */
16
50
  className: PropTypes.string,
51
+
52
+ /**
53
+ * Title HTML attributes.
54
+ */
17
55
  titles: PropTypes.shape({
18
- closeButton: PropTypes.string
56
+ closeButton: PropTypes.string,
19
57
  }),
58
+
59
+ /**
60
+ * Function triggered on close button click.
61
+ */
20
62
  onCloseClick: PropTypes.func,
63
+
64
+ /**
65
+ * HTML tabIndex attribute.
66
+ */
21
67
  tabIndex: PropTypes.string,
68
+
69
+ /**
70
+ * Render the header
71
+ */
22
72
  renderHeader: PropTypes.func,
73
+
74
+ /**
75
+ * Render the close button
76
+ */
23
77
  renderCloseButton: PropTypes.func,
24
- renderFooter: PropTypes.func
78
+
79
+ /**
80
+ * Render the footer
81
+ */
82
+ renderFooter: PropTypes.func,
25
83
  };
84
+
26
85
  const defaultProps = {
27
86
  header: null,
28
87
  feature: null,
29
88
  panIntoView: false,
30
89
  panRect: null,
31
90
  popupCoordinate: null,
32
- className: "rs-popup",
33
- tabIndex: "",
34
- titles: { closeButton: "Close" },
35
- onCloseClick: () => {
36
- },
91
+ className: 'rs-popup',
92
+ tabIndex: '',
93
+ titles: { closeButton: 'Close' },
94
+ onCloseClick: () => {},
37
95
  renderHeader: null,
38
96
  renderCloseButton: null,
39
97
  renderFooter: () => {
40
98
  return null;
41
- }
99
+ },
42
100
  };
101
+
102
+ /**
103
+ * The Popup component renders a popup over an
104
+ * [ol/Feature](https://openlayers.org/en/latest/apidoc/module-ol_Feature-Feature.html)
105
+ * on click.
106
+ */
43
107
  class Popup extends PureComponent {
44
108
  static renderHeader(props) {
45
109
  const { header, renderCloseButton } = props;
46
- return /* @__PURE__ */ React.createElement("div", {
47
- className: "rs-popup-header"
48
- }, header, (renderCloseButton || Popup.renderCloseButton)(props));
110
+ return (
111
+ <div className="rs-popup-header">
112
+ {header}
113
+ {(renderCloseButton || Popup.renderCloseButton)(props)}
114
+ </div>
115
+ );
49
116
  }
117
+
50
118
  static renderCloseButton({ onCloseClick, titles }) {
51
- return /* @__PURE__ */ React.createElement("div", {
52
- role: "button",
53
- tabIndex: 0,
54
- className: "rs-popup-close-bt",
55
- title: titles.closeButton,
56
- "aria-label": titles.closeButton,
57
- onClick: () => {
58
- return onCloseClick();
59
- },
60
- onKeyPress: (evt) => {
61
- return evt.which === 13 && onCloseClick();
62
- }
63
- }, /* @__PURE__ */ React.createElement(MdClose, {
64
- focusable: false
65
- }));
119
+ return (
120
+ <div
121
+ role="button"
122
+ tabIndex={0}
123
+ className="rs-popup-close-bt"
124
+ title={titles.closeButton}
125
+ aria-label={titles.closeButton}
126
+ onClick={() => {
127
+ return onCloseClick();
128
+ }}
129
+ onKeyPress={(evt) => {
130
+ return evt.which === 13 && onCloseClick();
131
+ }}
132
+ >
133
+ <MdClose focusable={false} />
134
+ </div>
135
+ );
66
136
  }
137
+
67
138
  constructor(props) {
68
139
  super(props);
69
140
  this.state = {
70
141
  popupElement: null,
71
142
  top: 0,
72
- left: 0
143
+ left: 0,
73
144
  };
74
145
  this.postrenderKey = null;
75
146
  }
147
+
76
148
  componentDidMount() {
77
149
  const { map } = this.props;
78
150
  this.updatePixelPosition();
79
- this.postrenderKey = map.on("postrender", () => {
151
+
152
+ this.postrenderKey = map.on('postrender', () => {
80
153
  this.updatePixelPosition();
81
154
  });
82
155
  }
156
+
83
157
  componentDidUpdate(prevProps, prevState) {
84
158
  const { feature, panIntoView, popupCoordinate } = this.props;
85
159
  const { popupElement } = this.state;
86
- if (feature !== prevProps.feature || popupCoordinate !== prevProps.popupCoordinate) {
160
+ if (
161
+ feature !== prevProps.feature ||
162
+ popupCoordinate !== prevProps.popupCoordinate
163
+ ) {
87
164
  this.updatePixelPosition();
88
165
  }
89
- if (panIntoView && popupElement && popupElement !== prevState.popupElement) {
166
+
167
+ if (
168
+ panIntoView &&
169
+ popupElement &&
170
+ popupElement !== prevState.popupElement
171
+ ) {
90
172
  this.panIntoView();
91
173
  }
92
174
  }
175
+
93
176
  componentWillUnmount() {
94
177
  unByKey(this.postrenderKey);
95
178
  }
179
+
96
180
  panIntoView() {
97
181
  const { map, panRect } = this.props;
98
182
  const { popupElement } = this.state;
183
+
99
184
  const mapRect = panRect || map.getTarget().getBoundingClientRect();
100
185
  const popupRect = popupElement.getBoundingClientRect();
101
186
  const [x, y] = map.getView().getCenter();
102
187
  const res = map.getView().getResolution();
103
188
  const newCenter = [x, y];
189
+
104
190
  if (mapRect.top > popupRect.top) {
105
191
  newCenter[1] = y + (mapRect.top - popupRect.top) * res;
106
192
  }
193
+
107
194
  if (mapRect.left > popupRect.left) {
108
195
  newCenter[0] = x - (mapRect.left - popupRect.left) * res;
109
196
  }
197
+
110
198
  if (mapRect.right < popupRect.right) {
111
199
  newCenter[0] = x + (popupRect.right - mapRect.right) * res;
112
200
  }
201
+
113
202
  if (mapRect.bottom < popupRect.bottom) {
114
203
  newCenter[1] = y - (popupRect.bottom - mapRect.bottom) * res;
115
204
  }
205
+
116
206
  if (newCenter[0] !== x || newCenter[1] !== y) {
117
207
  map.getView().animate({ center: newCenter, duration: 500 });
118
208
  }
119
209
  }
210
+
120
211
  updatePixelPosition() {
121
212
  const { map, feature, popupCoordinate } = this.props;
122
213
  let coord = popupCoordinate;
214
+
123
215
  if (feature && !coord) {
124
216
  coord = getCenter(feature.getGeometry().getExtent());
125
217
  }
218
+
126
219
  if (coord) {
127
220
  const pos = map.getPixelFromCoordinate(coord);
221
+
128
222
  if (pos && pos.length === 2) {
129
223
  this.setState({
130
224
  left: pos[0],
131
- top: pos[1]
225
+ top: pos[1],
132
226
  });
133
227
  }
134
228
  }
135
229
  }
230
+
136
231
  render() {
137
232
  const {
138
233
  feature,
@@ -145,36 +240,51 @@ class Popup extends PureComponent {
145
240
  renderFooter,
146
241
  ...other
147
242
  } = this.props;
243
+
148
244
  if (!feature && !popupCoordinate) {
149
245
  return null;
150
246
  }
247
+
151
248
  delete other.panIntoView;
152
249
  delete other.panRect;
153
250
  delete other.map;
154
251
  delete other.header;
155
252
  delete other.onCloseClick;
156
253
  delete other.renderCloseButton;
254
+
157
255
  const { top, left } = this.state;
256
+
257
+ // force re-render if the feature or the coordinate changes.
258
+ // this is needed to update the popupElement ref
158
259
  const key = feature ? feature.getId() : popupCoordinate.join();
159
- return /* @__PURE__ */ React.createElement("div", {
160
- className: "rs-popup",
161
- style: {
162
- left,
163
- top
164
- },
165
- ...other
166
- }, /* @__PURE__ */ React.createElement("div", {
167
- className: "rs-popup-container",
168
- tabIndex,
169
- key,
170
- ref: (popupElement) => {
171
- this.setState({ popupElement });
172
- }
173
- }, (renderHeader || Popup.renderHeader)(this.props), /* @__PURE__ */ React.createElement("div", {
174
- className: "rs-popup-body"
175
- }, children), renderFooter(this.props)));
260
+ return (
261
+ <div
262
+ className="rs-popup"
263
+ style={{
264
+ left,
265
+ top,
266
+ }}
267
+ // eslint-disable-next-line react/jsx-props-no-spreading
268
+ {...other}
269
+ >
270
+ <div
271
+ className="rs-popup-container"
272
+ tabIndex={tabIndex}
273
+ key={key}
274
+ ref={(popupElement) => {
275
+ this.setState({ popupElement });
276
+ }}
277
+ >
278
+ {(renderHeader || Popup.renderHeader)(this.props)}
279
+ <div className="rs-popup-body">{children}</div>
280
+ {renderFooter(this.props)}
281
+ </div>
282
+ </div>
283
+ );
176
284
  }
177
285
  }
286
+
178
287
  Popup.propTypes = propTypes;
179
288
  Popup.defaultProps = defaultProps;
289
+
180
290
  export default Popup;
@@ -0,0 +1,307 @@
1
+ import React from 'react';
2
+ import renderer from 'react-test-renderer';
3
+ import { configure, mount, shallow } from 'enzyme';
4
+ import Adapter from '@cfaester/enzyme-adapter-react-18';
5
+ import 'jest-canvas-mock';
6
+
7
+ import OLMap from 'ol/Map';
8
+ import View from 'ol/View';
9
+ import Feature from 'ol/Feature';
10
+ import Point from 'ol/geom/Point';
11
+ import Line from 'ol/geom/LineString';
12
+ import Popup from './Popup';
13
+
14
+ let map;
15
+
16
+ configure({ adapter: new Adapter() });
17
+
18
+ const feat = new Feature({
19
+ geometry: new Point([1000, 1000]),
20
+ });
21
+
22
+ const featLine = new Feature({
23
+ geometry: new Line([
24
+ [1000, 1000],
25
+ [2000, 2000],
26
+ ]),
27
+ });
28
+
29
+ describe('Popup', () => {
30
+ beforeEach(() => {
31
+ map = new OLMap({});
32
+ });
33
+
34
+ describe('should match snapshot', () => {
35
+ test('without feature', () => {
36
+ const component = renderer.create(
37
+ <Popup map={map}>
38
+ <div id="foo" />
39
+ </Popup>,
40
+ );
41
+ const tree = component.toJSON();
42
+ expect(tree).toMatchSnapshot();
43
+ });
44
+
45
+ test('with default values.', () => {
46
+ const component = renderer.create(
47
+ <Popup map={map} feature={feat}>
48
+ <div id="foo" />
49
+ </Popup>,
50
+ );
51
+ const tree = component.toJSON();
52
+ expect(tree).toMatchSnapshot();
53
+ });
54
+
55
+ test('without close button.', () => {
56
+ const component = renderer.create(
57
+ <Popup
58
+ map={map}
59
+ feature={feat}
60
+ renderCloseButton={() => {
61
+ return null;
62
+ }}
63
+ >
64
+ <div id="bar" />
65
+ </Popup>,
66
+ );
67
+ const tree = component.toJSON();
68
+ expect(tree).toMatchSnapshot();
69
+ });
70
+
71
+ test('without header.', () => {
72
+ const component = renderer.create(
73
+ <Popup
74
+ map={map}
75
+ feature={feat}
76
+ renderHeader={() => {
77
+ return null;
78
+ }}
79
+ >
80
+ <div id="bar" />
81
+ </Popup>,
82
+ );
83
+ const tree = component.toJSON();
84
+ expect(tree).toMatchSnapshot();
85
+ });
86
+
87
+ test('with tabIndex defined.', () => {
88
+ const component = renderer.create(
89
+ <Popup map={map} feature={feat} tabIndex="0">
90
+ <div id="bar" />
91
+ </Popup>,
92
+ );
93
+ const tree = component.toJSON();
94
+ expect(tree).toMatchSnapshot();
95
+ });
96
+ });
97
+
98
+ [
99
+ ['click', {}],
100
+ ['keypress', { which: 13 }],
101
+ ].forEach((evt) => {
102
+ test(`should trigger onCloseClick function on ${evt[0]} event.`, () => {
103
+ const spy = jest.fn(() => {});
104
+
105
+ const component = mount(
106
+ <Popup map={map} feature={feat} onCloseClick={spy}>
107
+ <div id="gux" />
108
+ </Popup>,
109
+ );
110
+
111
+ component
112
+ .find('div')
113
+ .at(3)
114
+ .simulate(...evt);
115
+ expect(spy).toHaveBeenCalled();
116
+ });
117
+
118
+ test(`should trigger default onCloseClick function on ${evt[0]} event without errors.`, () => {
119
+ const component = mount(
120
+ <Popup map={map} feature={feat}>
121
+ <div id="gux" />
122
+ </Popup>,
123
+ );
124
+ // test if no js error triggered by the default value
125
+ try {
126
+ component
127
+ .find('div')
128
+ .at(3)
129
+ .simulate(...evt);
130
+ expect(true).toBe(true);
131
+ } catch (e) {
132
+ expect(false).toBe(true);
133
+ }
134
+ });
135
+ });
136
+
137
+ describe(`init position`, () => {
138
+ test(`using popupCoordinate.`, () => {
139
+ map.getPixelFromCoordinate = jest.fn(() => {
140
+ return [10010, 100200];
141
+ });
142
+ const component = mount(
143
+ <Popup map={map} popupCoordinate={[1001, 1002]}>
144
+ <div id="gux" />
145
+ </Popup>,
146
+ );
147
+ expect(component.state().left).toBe(10010);
148
+ expect(component.state().top).toBe(100200);
149
+ component.setProps({ feature: featLine });
150
+ map.getPixelFromCoordinate = jest.fn(() => {
151
+ return [10011, 100100];
152
+ });
153
+ component.setProps({ popupCoordinate: [1009, 1009] });
154
+ expect(component.state().left).toBe(10011);
155
+ expect(component.state().top).toBe(100100);
156
+ });
157
+
158
+ test(`using feature.`, () => {
159
+ map.getPixelFromCoordinate = jest.fn(() => {
160
+ return [10010, 100200];
161
+ });
162
+ const component = mount(
163
+ <Popup map={map} feature={feat}>
164
+ <div id="gux" />
165
+ </Popup>,
166
+ );
167
+ expect(component.state().left).toBe(10010);
168
+ expect(component.state().top).toBe(100200);
169
+ map.getPixelFromCoordinate = jest.fn(() => {
170
+ return [10011, 100100];
171
+ });
172
+ component.setProps({ feature: featLine });
173
+ expect(component.state().left).toBe(10011);
174
+ expect(component.state().top).toBe(100100);
175
+ });
176
+ });
177
+
178
+ describe(`updates position`, () => {
179
+ test(`on map postrender event.`, () => {
180
+ map.getPixelFromCoordinate = jest.fn(() => {
181
+ return [10, 200];
182
+ });
183
+ const component = shallow(
184
+ <Popup map={map} feature={feat}>
185
+ <div id="gux" />
186
+ </Popup>,
187
+ );
188
+ const spy = jest.spyOn(component.instance(), 'updatePixelPosition');
189
+ map.dispatchEvent({ type: 'postrender' });
190
+ expect(spy).toHaveBeenCalledTimes(1);
191
+ });
192
+ });
193
+
194
+ describe(`#panIntoView`, () => {
195
+ beforeEach(() => {
196
+ const target = document.createElement('div');
197
+ const { style } = target;
198
+ style.position = 'absolute';
199
+ style.left = '-1000px';
200
+ style.top = '-1000px';
201
+ style.width = '100px';
202
+ style.height = '100px';
203
+ document.body.appendChild(target);
204
+
205
+ map = new OLMap({
206
+ target,
207
+ view: new View({
208
+ center: [1000, 1000],
209
+ resolutions: [1],
210
+ zoom: 0,
211
+ }),
212
+ });
213
+ map.renderSync();
214
+ });
215
+
216
+ afterEach(() => {
217
+ const target = map.getTarget();
218
+ map.setTarget(null);
219
+ if (target && target.parentNode) {
220
+ target.parentNode.removeChild(target);
221
+ }
222
+ map.dispose();
223
+ });
224
+
225
+ test(`animate the map.`, () => {
226
+ map.getTarget().getBoundingClientRect = jest.fn(() => {
227
+ return {
228
+ bottom: -10,
229
+ left: 5,
230
+ right: -5,
231
+ top: 5,
232
+ };
233
+ });
234
+ map.getPixelFromCoordinate = jest.fn(() => {
235
+ return [10, 20];
236
+ });
237
+ const spy = jest.spyOn(map.getView(), 'animate');
238
+ mount(
239
+ <Popup map={map} feature={feat} panIntoView>
240
+ <div id="gux" />
241
+ </Popup>,
242
+ );
243
+ expect(spy).toHaveBeenCalledTimes(1);
244
+ expect(spy).toHaveBeenCalledWith({
245
+ center: [1005, 990],
246
+ duration: 500,
247
+ });
248
+ });
249
+
250
+ test(`using panRect`, () => {
251
+ map.getPixelFromCoordinate = jest.fn(() => {
252
+ return [10, 200];
253
+ });
254
+ const spy = jest.spyOn(map.getView(), 'animate');
255
+ mount(
256
+ <Popup
257
+ map={map}
258
+ feature={feat}
259
+ panIntoView
260
+ panRect={{ top: 0, left: 0, bottom: -10, right: 0 }}
261
+ >
262
+ <div id="gux" />
263
+ </Popup>,
264
+ );
265
+ expect(spy).toHaveBeenCalledTimes(1);
266
+ expect(spy).toHaveBeenCalledWith({
267
+ center: [1000, 990],
268
+ duration: 500,
269
+ });
270
+ });
271
+
272
+ test(`doesn't animate the map`, () => {
273
+ map.getPixelFromCoordinate = jest.fn(() => {
274
+ return [10, 200];
275
+ });
276
+ const spy = jest.spyOn(map.getView(), 'animate');
277
+ mount(
278
+ <Popup
279
+ map={map}
280
+ feature={feat}
281
+ panIntoView
282
+ panRect={{ top: 0, left: 0, bottom: 0, right: 0 }}
283
+ >
284
+ <div id="gux" />
285
+ </Popup>,
286
+ );
287
+ expect(spy).toHaveBeenCalledTimes(0);
288
+ });
289
+ });
290
+
291
+ test(`deregisters postrender on unmount.`, () => {
292
+ map.getPixelFromCoordinate = jest.fn(() => {
293
+ return [10, 200];
294
+ });
295
+ const component = shallow(
296
+ <Popup map={map} feature={featLine}>
297
+ <div id="gux" />
298
+ </Popup>,
299
+ );
300
+ const spy = jest.spyOn(component.instance(), 'updatePixelPosition');
301
+ map.dispatchEvent({ type: 'postrender' });
302
+ expect(spy).toHaveBeenCalledTimes(1);
303
+ component.unmount();
304
+ map.dispatchEvent({ type: 'postrender' });
305
+ expect(spy).toHaveBeenCalledTimes(1);
306
+ });
307
+ });