react-spatial 1.4.0 → 1.4.1

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 (296) 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 +54 -0
  11. package/DEVELOP.md +113 -0
  12. package/README.md +1 -1
  13. package/__mocks__/mapbox-gl.js +11 -0
  14. package/__mocks__/resize-observer-polyfill.js +9 -0
  15. package/babel.config.js +3 -0
  16. package/commitlint.config.js +1 -0
  17. package/data/topic1.js +119 -0
  18. package/data/topic2.js +28 -0
  19. package/doc/README.md +21 -0
  20. package/doc/doc-config.json +4 -0
  21. package/netlify.toml +3 -0
  22. package/package.json +30 -41
  23. package/pull_request_template.md +16 -0
  24. package/renovate.json +4 -0
  25. package/scripts/read-pkg-json.js +17 -0
  26. package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.js +322 -0
  27. package/src/components/BaseLayerSwitcher/BaseLayerSwitcher.test.js +69 -0
  28. package/src/components/BaseLayerSwitcher/README.md +61 -0
  29. package/src/components/BaseLayerSwitcher/__snapshots__/BaseLayerSwitcher.test.js.snap +88 -0
  30. package/src/components/BaseLayerSwitcher/index.js +1 -0
  31. package/src/components/BasicMap/BasicMap.js +413 -0
  32. package/src/components/BasicMap/BasicMap.test.js +281 -0
  33. package/src/components/BasicMap/README.md +18 -0
  34. package/src/components/BasicMap/index.js +1 -0
  35. package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.js +320 -93
  36. package/src/components/CanvasSaveButton/CanvasSaveButton.test.js +148 -0
  37. package/src/components/CanvasSaveButton/README.md +76 -0
  38. package/src/components/CanvasSaveButton/__snapshots__/CanvasSaveButton.test.js.snap +76 -0
  39. package/src/components/CanvasSaveButton/index.js +1 -0
  40. package/src/components/Copyright/Copyright.js +89 -0
  41. package/src/components/Copyright/Copyright.test.js +134 -0
  42. package/src/components/Copyright/README.md +36 -0
  43. package/src/components/Copyright/index.js +1 -0
  44. package/src/components/FeatureExportButton/FeatureExportButton.js +118 -0
  45. package/src/components/FeatureExportButton/FeatureExportButton.test.js +417 -0
  46. package/src/components/FeatureExportButton/README.md +76 -0
  47. package/src/components/FeatureExportButton/__snapshots__/FeatureExportButton.test.js.snap +67 -0
  48. package/src/components/FeatureExportButton/index.js +1 -0
  49. package/src/components/FitExtent/FitExtent.js +62 -0
  50. package/src/components/FitExtent/FitExtent.test.js +48 -0
  51. package/src/components/FitExtent/README.md +34 -0
  52. package/src/components/FitExtent/__snapshots__/FitExtent.test.js.snap +13 -0
  53. package/src/components/FitExtent/index.js +1 -0
  54. package/{components → src/components}/Geolocation/Geolocation.js +144 -61
  55. package/src/components/Geolocation/Geolocation.test.js +267 -0
  56. package/src/components/Geolocation/README.md +25 -0
  57. package/src/components/Geolocation/__snapshots__/Geolocation.test.js.snap +92 -0
  58. package/src/components/Geolocation/index.js +1 -0
  59. package/src/components/LayerTree/LayerTree.js +487 -0
  60. package/src/components/LayerTree/LayerTree.test.js +337 -0
  61. package/src/components/LayerTree/README.md +92 -0
  62. package/src/components/LayerTree/__snapshots__/LayerTree.test.js.snap +1746 -0
  63. package/src/components/LayerTree/index.js +1 -0
  64. package/src/components/MousePosition/MousePosition.js +175 -0
  65. package/src/components/MousePosition/MousePosition.test.js +132 -0
  66. package/src/components/MousePosition/README.md +50 -0
  67. package/src/components/MousePosition/__snapshots__/MousePosition.test.js.snap +76 -0
  68. package/src/components/MousePosition/index.js +1 -0
  69. package/src/components/NorthArrow/NorthArrow.js +75 -0
  70. package/src/components/NorthArrow/NorthArrow.test.js +104 -0
  71. package/src/components/NorthArrow/README.md +59 -0
  72. package/src/components/NorthArrow/__snapshots__/NorthArrow.test.js.snap +117 -0
  73. package/src/components/NorthArrow/index.js +1 -0
  74. package/src/components/Overlay/Overlay.js +176 -0
  75. package/src/components/Overlay/Overlay.test.js +149 -0
  76. package/src/components/Overlay/README.md +59 -0
  77. package/src/components/Overlay/__snapshots__/Overlay.test.js.snap +9 -0
  78. package/src/components/Overlay/index.js +1 -0
  79. package/src/components/Permalink/Permalink.js +326 -0
  80. package/src/components/Permalink/Permalink.test.js +285 -0
  81. package/src/components/Permalink/README.md +105 -0
  82. package/src/components/Permalink/index.js +1 -0
  83. package/{components → src/components}/Popup/Popup.js +165 -55
  84. package/src/components/Popup/Popup.test.js +307 -0
  85. package/src/components/Popup/README.md +93 -0
  86. package/src/components/Popup/__snapshots__/Popup.test.js.snap +180 -0
  87. package/src/components/Popup/index.js +1 -0
  88. package/src/components/README.md +41 -0
  89. package/{components → src/components}/ResizeHandler/ResizeHandler.js +50 -15
  90. package/src/components/ResizeHandler/ResizeHandler.test.js +344 -0
  91. package/src/components/ResizeHandler/index.js +1 -0
  92. package/src/components/RouteSchedule/README.md +118 -0
  93. package/src/components/RouteSchedule/RouteSchedule.js +364 -0
  94. package/src/components/RouteSchedule/RouteSchedule.test.js +113 -0
  95. package/src/components/RouteSchedule/__snapshots__/RouteSchedule.test.js.snap +248 -0
  96. package/src/components/RouteSchedule/index.js +1 -0
  97. package/src/components/ScaleLine/README.md +29 -0
  98. package/src/components/ScaleLine/ScaleLine.js +50 -0
  99. package/src/components/ScaleLine/ScaleLine.test.js +30 -0
  100. package/src/components/ScaleLine/__snapshots__/ScaleLine.test.js.snap +7 -0
  101. package/src/components/ScaleLine/index.js +1 -0
  102. package/src/components/StopsFinder/README.md +50 -0
  103. package/src/components/StopsFinder/StopsFinder.js +284 -0
  104. package/src/components/StopsFinder/StopsFinder.test.js +17 -0
  105. package/src/components/StopsFinder/StopsFinderOption.js +61 -0
  106. package/src/components/StopsFinder/__snapshots__/StopsFinder.test.js.snap +133 -0
  107. package/src/components/StopsFinder/index.js +1 -0
  108. package/src/components/Zoom/README.md +25 -0
  109. package/src/components/Zoom/Zoom.js +180 -0
  110. package/src/components/Zoom/Zoom.test.js +141 -0
  111. package/src/components/Zoom/__snapshots__/Zoom.test.js.snap +201 -0
  112. package/src/components/Zoom/index.js +1 -0
  113. package/{propTypes.js → src/propTypes.js} +16 -12
  114. package/{setupTests.js → src/setupTests.js} +1 -1
  115. package/src/styleguidist/ComponentsList.js +52 -0
  116. package/src/styleguidist/StyleGuide.js +277 -0
  117. package/src/styleguidist/styleguidist.css +38 -0
  118. package/src/utils/GlobalsForOle.js +99 -0
  119. package/src/utils/KML.js +594 -0
  120. package/src/utils/KML.test.js +337 -0
  121. package/src/utils/KMLFormat.js +100 -0
  122. package/src/utils/KMLFormat.test.js +50 -0
  123. package/{utils → src/utils}/Styles.js +20 -14
  124. 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
  125. package/src/utils/__snapshots__/getPolygonPattern.test.js.snap.getPolygonPattern()-render-pattern-2-(cross)-color-and-(light-blue)-opacity.canvas-image.png +0 -0
  126. 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
  127. 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
  128. package/{utils → src/utils}/getPolygonPattern.js +34 -6
  129. package/src/utils/getPolygonPattern.test.js +61 -0
  130. package/{utils → src/utils}/timeUtils.js +22 -5
  131. package/src/utils/timeUtils.test.js +30 -0
  132. package/styleguide.config.js +251 -0
  133. package/components/BaseLayerSwitcher/BaseLayerSwitcher.js +0 -231
  134. package/components/BaseLayerSwitcher/BaseLayerSwitcher.js.map +0 -7
  135. package/components/BaseLayerSwitcher/index.js +0 -1
  136. package/components/BaseLayerSwitcher/index.js.map +0 -7
  137. package/components/BasicMap/BasicMap.js +0 -278
  138. package/components/BasicMap/BasicMap.js.map +0 -7
  139. package/components/BasicMap/index.js +0 -1
  140. package/components/BasicMap/index.js.map +0 -7
  141. package/components/CanvasSaveButton/CanvasSaveButton.js.map +0 -7
  142. package/components/CanvasSaveButton/index.js +0 -1
  143. package/components/CanvasSaveButton/index.js.map +0 -7
  144. package/components/Copyright/Copyright.js +0 -55
  145. package/components/Copyright/Copyright.js.map +0 -7
  146. package/components/Copyright/index.js +0 -1
  147. package/components/Copyright/index.js.map +0 -7
  148. package/components/FeatureExportButton/FeatureExportButton.js +0 -62
  149. package/components/FeatureExportButton/FeatureExportButton.js.map +0 -7
  150. package/components/FeatureExportButton/index.js +0 -1
  151. package/components/FeatureExportButton/index.js.map +0 -7
  152. package/components/FitExtent/FitExtent.js +0 -32
  153. package/components/FitExtent/FitExtent.js.map +0 -7
  154. package/components/FitExtent/index.js +0 -1
  155. package/components/FitExtent/index.js.map +0 -7
  156. package/components/Geolocation/Geolocation.js.map +0 -7
  157. package/components/Geolocation/index.js +0 -1
  158. package/components/Geolocation/index.js.map +0 -7
  159. package/components/LayerTree/LayerTree.js +0 -278
  160. package/components/LayerTree/LayerTree.js.map +0 -7
  161. package/components/LayerTree/index.js +0 -1
  162. package/components/LayerTree/index.js.map +0 -7
  163. package/components/MousePosition/MousePosition.js +0 -110
  164. package/components/MousePosition/MousePosition.js.map +0 -7
  165. package/components/MousePosition/index.js +0 -1
  166. package/components/MousePosition/index.js.map +0 -7
  167. package/components/NorthArrow/NorthArrow.js +0 -43
  168. package/components/NorthArrow/NorthArrow.js.map +0 -7
  169. package/components/NorthArrow/index.js +0 -1
  170. package/components/NorthArrow/index.js.map +0 -7
  171. package/components/Overlay/Overlay.js +0 -122
  172. package/components/Overlay/Overlay.js.map +0 -7
  173. package/components/Overlay/index.js +0 -1
  174. package/components/Overlay/index.js.map +0 -7
  175. package/components/Permalink/Permalink.js +0 -206
  176. package/components/Permalink/Permalink.js.map +0 -7
  177. package/components/Permalink/index.js +0 -1
  178. package/components/Permalink/index.js.map +0 -7
  179. package/components/Popup/Popup.js.map +0 -7
  180. package/components/Popup/index.js +0 -1
  181. package/components/Popup/index.js.map +0 -7
  182. package/components/ResizeHandler/ResizeHandler.js.map +0 -7
  183. package/components/ResizeHandler/index.js +0 -1
  184. package/components/ResizeHandler/index.js.map +0 -7
  185. package/components/RouteSchedule/RouteSchedule.js +0 -220
  186. package/components/RouteSchedule/RouteSchedule.js.map +0 -7
  187. package/components/RouteSchedule/index.js +0 -1
  188. package/components/RouteSchedule/index.js.map +0 -7
  189. package/components/ScaleLine/ScaleLine.js +0 -32
  190. package/components/ScaleLine/ScaleLine.js.map +0 -7
  191. package/components/ScaleLine/index.js +0 -1
  192. package/components/ScaleLine/index.js.map +0 -7
  193. package/components/StopsFinder/StopsFinder.js +0 -210
  194. package/components/StopsFinder/StopsFinder.js.map +0 -7
  195. package/components/StopsFinder/StopsFinderOption.js +0 -50
  196. package/components/StopsFinder/StopsFinderOption.js.map +0 -7
  197. package/components/StopsFinder/index.js +0 -1
  198. package/components/StopsFinder/index.js.map +0 -7
  199. package/components/Zoom/Zoom.js +0 -120
  200. package/components/Zoom/Zoom.js.map +0 -7
  201. package/components/Zoom/index.js +0 -1
  202. package/components/Zoom/index.js.map +0 -7
  203. package/propTypes.js.map +0 -7
  204. package/setupTests.js.map +0 -7
  205. package/utils/GlobalsForOle.js +0 -94
  206. package/utils/GlobalsForOle.js.map +0 -7
  207. package/utils/KML.js +0 -412
  208. package/utils/KML.js.map +0 -7
  209. package/utils/KMLFormat.js +0 -69
  210. package/utils/KMLFormat.js.map +0 -7
  211. package/utils/Styles.js.map +0 -7
  212. package/utils/getPolygonPattern.js.map +0 -7
  213. package/utils/timeUtils.js.map +0 -7
  214. /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.md.scss +0 -0
  215. /package/{components → src/components}/BaseLayerSwitcher/BaseLayerSwitcher.scss +0 -0
  216. /package/{components → src/components}/BasicMap/BasicMap.md.scss +0 -0
  217. /package/{components → src/components}/CanvasSaveButton/CanvasSaveButton.md.scss +0 -0
  218. /package/{components → src/components}/Copyright/Copyright.md.scss +0 -0
  219. /package/{components → src/components}/FeatureExportButton/FeatureExportButton.md.scss +0 -0
  220. /package/{components → src/components}/FitExtent/FitExtent.md.scss +0 -0
  221. /package/{components → src/components}/Geolocation/Geolocation.md.scss +0 -0
  222. /package/{components → src/components}/Geolocation/Geolocation.scss +0 -0
  223. /package/{components → src/components}/LayerTree/LayerTree.md.scss +0 -0
  224. /package/{components → src/components}/LayerTree/LayerTree.scss +0 -0
  225. /package/{components → src/components}/MousePosition/MousePosition.md.scss +0 -0
  226. /package/{components → src/components}/NorthArrow/NorthArrow.scss +0 -0
  227. /package/{components → src/components}/Overlay/Overlay.md.scss +0 -0
  228. /package/{components → src/components}/Overlay/Overlay.scss +0 -0
  229. /package/{components → src/components}/Permalink/Permalink.md.scss +0 -0
  230. /package/{components → src/components}/Popup/Popup.md.scss +0 -0
  231. /package/{components → src/components}/Popup/Popup.scss +0 -0
  232. /package/{components → src/components}/RouteSchedule/RouteSchedule.md.scss +0 -0
  233. /package/{components → src/components}/RouteSchedule/RouteSchedule.scss +0 -0
  234. /package/{components → src/components}/ScaleLine/ScaleLine.scss +0 -0
  235. /package/{components → src/components}/Zoom/Zoom.md.scss +0 -0
  236. /package/{components → src/components}/Zoom/Zoom.scss +0 -0
  237. /package/{images → src/images}/RouteSchedule/firstStation.png +0 -0
  238. /package/{images → src/images}/RouteSchedule/lastStation.png +0 -0
  239. /package/{images → src/images}/RouteSchedule/line.png +0 -0
  240. /package/{images → src/images}/RouteSchedule/station.png +0 -0
  241. /package/{images → src/images}/baselayer/baselayer.basebright.png +0 -0
  242. /package/{images → src/images}/baselayer/baselayer.osm.png +0 -0
  243. /package/{images → src/images}/baselayer/baselayer.travic.png +0 -0
  244. /package/{images → src/images}/baselayer/open.topo.map.png +0 -0
  245. /package/{images → src/images}/baselayer/osm.baselayer.hot.png +0 -0
  246. /package/{images → src/images}/baselayer/osm.baselayer.png +0 -0
  247. /package/{images → src/images}/favicon.png +0 -0
  248. /package/{images → src/images}/geops_logo.png +0 -0
  249. /package/{images → src/images}/geops_logo.svg +0 -0
  250. /package/{images → src/images}/geops_qr.png +0 -0
  251. /package/{images → src/images}/mots/bus_poi-blue-01.svg +0 -0
  252. /package/{images → src/images}/mots/bus_poi-grey-01.svg +0 -0
  253. /package/{images → src/images}/mots/bus_round-blue-01.svg +0 -0
  254. /package/{images → src/images}/mots/bus_round-grey-01.svg +0 -0
  255. /package/{images → src/images}/mots/bus_square-blue-01.svg +0 -0
  256. /package/{images → src/images}/mots/bus_square-grey-01.svg +0 -0
  257. /package/{images → src/images}/mots/cable_car_poi-blue-01.svg +0 -0
  258. /package/{images → src/images}/mots/cable_car_poi-grey-01.svg +0 -0
  259. /package/{images → src/images}/mots/cable_car_round-blue-01.svg +0 -0
  260. /package/{images → src/images}/mots/cable_car_round-grey-01.svg +0 -0
  261. /package/{images → src/images}/mots/cable_car_square-blue-01.svg +0 -0
  262. /package/{images → src/images}/mots/cable_car_square-grey-01.svg +0 -0
  263. /package/{images → src/images}/mots/ferry_poi-blue-01.svg +0 -0
  264. /package/{images → src/images}/mots/ferry_poi-grey-01.svg +0 -0
  265. /package/{images → src/images}/mots/ferry_round-blue-01.svg +0 -0
  266. /package/{images → src/images}/mots/ferry_round-grey-01.svg +0 -0
  267. /package/{images → src/images}/mots/ferry_square-blue-01.svg +0 -0
  268. /package/{images → src/images}/mots/ferry_square-grey-01.svg +0 -0
  269. /package/{images → src/images}/mots/funicular_round-blue-01.svg +0 -0
  270. /package/{images → src/images}/mots/funicular_round-grey-01.svg +0 -0
  271. /package/{images → src/images}/mots/funicular_square-blue-01.svg +0 -0
  272. /package/{images → src/images}/mots/gondola_round-blue-01.svg +0 -0
  273. /package/{images → src/images}/mots/rail_poi-blue-01.svg +0 -0
  274. /package/{images → src/images}/mots/rail_poi-grey-01.svg +0 -0
  275. /package/{images → src/images}/mots/rail_round-blue-01.svg +0 -0
  276. /package/{images → src/images}/mots/rail_round-grey-01.svg +0 -0
  277. /package/{images → src/images}/mots/rail_square-blue-01.svg +0 -0
  278. /package/{images → src/images}/mots/rail_square-grey-01.svg +0 -0
  279. /package/{images → src/images}/mots/subway_round blue-01.svg +0 -0
  280. /package/{images → src/images}/mots/subway_round-blue-01.svg +0 -0
  281. /package/{images → src/images}/mots/tram_poi-blue-01.svg +0 -0
  282. /package/{images → src/images}/mots/tram_poi-grey-01.svg +0 -0
  283. /package/{images → src/images}/mots/tram_round-blue-01.svg +0 -0
  284. /package/{images → src/images}/mots/tram_round-grey-01.svg +0 -0
  285. /package/{images → src/images}/mots/tram_square-blue-01.svg +0 -0
  286. /package/{images → src/images}/mots/tram_square-grey-01.svg +0 -0
  287. /package/{images → src/images}/northArrow.svg +0 -0
  288. /package/{images → src/images}/northArrow.url.svg +0 -0
  289. /package/{images → src/images}/northArrowCircle.svg +0 -0
  290. /package/{images → src/images}/northArrowCircle.url.svg +0 -0
  291. /package/{themes → src/themes}/README.md +0 -0
  292. /package/{themes → src/themes}/default/components.scss +0 -0
  293. /package/{themes → src/themes}/default/examples.scss +0 -0
  294. /package/{themes → src/themes}/default/index.scss +0 -0
  295. /package/{themes → src/themes}/default/mixins.scss +0 -0
  296. /package/{themes → src/themes}/default/variables.scss +0 -0
@@ -0,0 +1,180 @@
1
+ import React, {
2
+ useEffect,
3
+ useRef,
4
+ useCallback,
5
+ useState,
6
+ useMemo,
7
+ } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { FaPlus, FaMinus } from 'react-icons/fa';
10
+ import { ZoomSlider } from 'ol/control';
11
+ import OLMap from 'ol/Map';
12
+ import { easeOut } from 'ol/easing';
13
+ import { unByKey } from 'ol/Observable';
14
+
15
+ const propTypes = {
16
+ /**
17
+ * An [ol/map](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html).
18
+ */
19
+ map: PropTypes.instanceOf(OLMap).isRequired,
20
+
21
+ /**
22
+ * The zoom delta applied on each click.
23
+ */
24
+ delta: PropTypes.number,
25
+
26
+ /**
27
+ * Titles HTML attribtues for button.
28
+ */
29
+ titles: PropTypes.shape({
30
+ zoomIn: PropTypes.string,
31
+ zoomOut: PropTypes.string,
32
+ }),
33
+
34
+ /**
35
+ * Children content of the zoom in button.
36
+ */
37
+ zoomInChildren: PropTypes.node,
38
+
39
+ /**
40
+ * Children content of the zoom out button.
41
+ */
42
+ zoomOutChildren: PropTypes.node,
43
+
44
+ /**
45
+ * Display a slider to zoom.
46
+ */
47
+ zoomSlider: PropTypes.bool,
48
+ };
49
+
50
+ const defaultProps = {
51
+ titles: {
52
+ zoomIn: 'Zoom in',
53
+ zoomOut: 'Zoom out',
54
+ },
55
+ zoomInChildren: <FaPlus focusable={false} />,
56
+ zoomOutChildren: <FaMinus focusable={false} />,
57
+ zoomSlider: false,
58
+ delta: 1,
59
+ };
60
+
61
+ const updateZoom = (map, delta) => {
62
+ const view = map.getView();
63
+ const currentZoom = view.getZoom();
64
+ const newZoom = currentZoom + delta;
65
+ const constrainedZoom = view.getConstrainedZoom(newZoom);
66
+ if (view.getAnimating()) {
67
+ view.cancelAnimations();
68
+ }
69
+ view.animate({
70
+ zoom: constrainedZoom,
71
+ duration: 250,
72
+ easing: easeOut,
73
+ });
74
+ };
75
+
76
+ /**
77
+ * The Zoom component creates a zoom wrapper containing zoom-in and zoom-out buttons
78
+ * and an optional [ol/ZoomSlider](https://openlayers.org/en/latest/apidoc/module-ol_control_ZoomSlider-ZoomSlider.html).
79
+ */
80
+ function Zoom({
81
+ map,
82
+ titles,
83
+ zoomInChildren,
84
+ zoomOutChildren,
85
+ zoomSlider,
86
+ delta,
87
+ ...other
88
+ }) {
89
+ const ref = useRef();
90
+ const [currentZoom, setZoom] = useState();
91
+
92
+ const zoomIn = useCallback(
93
+ (evt) => {
94
+ if (!evt.which || evt.which === 13) {
95
+ updateZoom(map, delta);
96
+ }
97
+ },
98
+ [delta, map],
99
+ );
100
+
101
+ const zoomOut = useCallback(
102
+ (evt) => {
103
+ if (!evt.which || evt.which === 13) {
104
+ updateZoom(map, -delta);
105
+ }
106
+ },
107
+ [delta, map],
108
+ );
109
+
110
+ const zoomInDisabled = useMemo(() => {
111
+ return (
112
+ currentZoom >=
113
+ map.getView().getConstrainedZoom(map.getView().getMaxZoom())
114
+ );
115
+ }, [currentZoom, map]);
116
+
117
+ const zoomOutDisabled = useMemo(() => {
118
+ return (
119
+ currentZoom <=
120
+ map.getView().getConstrainedZoom(map.getView().getMinZoom())
121
+ );
122
+ }, [currentZoom, map]);
123
+
124
+ useEffect(() => {
125
+ // Trigger zoom update to disable zooms on max and min
126
+ const listenerKey = map.on('moveend', () => {
127
+ setZoom(map.getView().getZoom());
128
+ });
129
+
130
+ let control;
131
+ if (zoomSlider && ref.current) {
132
+ control = new ZoomSlider();
133
+ // We don't want to navigate to the zoom slider using TAB navigation.
134
+ control.element.firstElementChild.tabIndex = -1;
135
+ // Set the zoom slider in the custom control wrapper.
136
+ control.setTarget(ref.current);
137
+ map.addControl(control);
138
+ }
139
+ return () => {
140
+ unByKey(listenerKey);
141
+ if (control) {
142
+ map.removeControl(control);
143
+ }
144
+ };
145
+ }, [map, zoomSlider]);
146
+
147
+ return (
148
+ // eslint-disable-next-line react/jsx-props-no-spreading
149
+ <div className="rs-zooms-bar" {...other}>
150
+ <button
151
+ type="button"
152
+ tabIndex={0}
153
+ className="rs-zoom-in"
154
+ title={titles.zoomIn}
155
+ onClick={zoomIn}
156
+ onKeyPress={zoomIn}
157
+ disabled={zoomInDisabled}
158
+ >
159
+ {zoomInChildren}
160
+ </button>
161
+ {zoomSlider ? <div className="rs-zoomslider-wrapper" ref={ref} /> : null}
162
+ <button
163
+ type="button"
164
+ tabIndex={0}
165
+ className="rs-zoom-out"
166
+ title={titles.zoomOut}
167
+ onClick={zoomOut}
168
+ onKeyPress={zoomOut}
169
+ disabled={zoomOutDisabled}
170
+ >
171
+ {zoomOutChildren}
172
+ </button>
173
+ </div>
174
+ );
175
+ }
176
+
177
+ Zoom.propTypes = propTypes;
178
+ Zoom.defaultProps = defaultProps;
179
+
180
+ export default React.memo(Zoom);
@@ -0,0 +1,141 @@
1
+ import React from 'react';
2
+ import renderer from 'react-test-renderer';
3
+ import { configure, shallow, mount } from 'enzyme';
4
+ import Adapter from '@cfaester/enzyme-adapter-react-18';
5
+ import { act } from 'react-dom/test-utils';
6
+ import MapEvent from 'ol/MapEvent';
7
+ import OLView from 'ol/View';
8
+ import OLMap from 'ol/Map';
9
+ import Zoom from './Zoom';
10
+
11
+ configure({ adapter: new Adapter() });
12
+
13
+ describe('Zoom', () => {
14
+ test('should match snapshot.', () => {
15
+ const map = new OLMap({});
16
+ const component = renderer.create(<Zoom map={map} />);
17
+ const tree = component.toJSON();
18
+ expect(tree).toMatchSnapshot();
19
+ });
20
+
21
+ test('should match snapshot with custom attributes', () => {
22
+ const map = new OLMap({});
23
+ const component = renderer.create(
24
+ <Zoom map={map} className="foo" tabIndex={-1} title="bar" />,
25
+ );
26
+ const tree = component.toJSON();
27
+ expect(tree).toMatchSnapshot();
28
+ });
29
+
30
+ test('should match snapshot with zoom slider', () => {
31
+ const map = new OLMap({});
32
+ const component = renderer.create(<Zoom map={map} zoomSlider />);
33
+ const tree = component.toJSON();
34
+ expect(tree).toMatchSnapshot();
35
+ });
36
+
37
+ [
38
+ ['click', {}],
39
+ ['keypress', { which: 13 }],
40
+ ].forEach((evt) => {
41
+ test(`should zoom in on ${evt[0]}.`, () => {
42
+ const map = new OLMap({ view: new OLView({ zoom: 5 }) });
43
+ const zooms = shallow(<Zoom map={map} />);
44
+ zooms
45
+ .find('.rs-zoom-in')
46
+ .first()
47
+ .simulate(...evt);
48
+
49
+ expect(map.getView().getZoom()).toBe(6);
50
+ });
51
+
52
+ test(`should zoom in on ${evt[0]} (delta: 0.3).`, () => {
53
+ const map = new OLMap({ view: new OLView({ zoom: 5 }) });
54
+ const zooms = shallow(<Zoom map={map} delta={0.3} />);
55
+ zooms
56
+ .find('.rs-zoom-in')
57
+ .first()
58
+ .simulate(...evt);
59
+
60
+ expect(map.getView().getZoom()).toBe(5.3);
61
+ });
62
+
63
+ test(`should zoom out on ${evt[0]}.`, () => {
64
+ const map = new OLMap({ view: new OLView({ zoom: 5 }) });
65
+ const zooms = shallow(<Zoom map={map} />);
66
+ zooms
67
+ .find('.rs-zoom-out')
68
+ .first()
69
+ .simulate(...evt);
70
+
71
+ expect(map.getView().getZoom()).toBe(4);
72
+ });
73
+
74
+ test(`should zoom out on ${evt[0]} (delta: 0.3).`, () => {
75
+ const map = new OLMap({ view: new OLView({ zoom: 5 }) });
76
+ const zooms = shallow(<Zoom map={map} delta={0.3} />);
77
+ zooms
78
+ .find('.rs-zoom-out')
79
+ .first()
80
+ .simulate(...evt);
81
+
82
+ expect(map.getView().getZoom()).toBe(4.7);
83
+ });
84
+ });
85
+
86
+ test('should remove zoomSlider control on unmount.', () => {
87
+ const map = new OLMap({});
88
+ const spy = jest.spyOn(map, 'removeControl');
89
+ const spy2 = jest.spyOn(map, 'addControl');
90
+ const wrapper = mount(<Zoom map={map} zoomSlider />);
91
+ expect(spy).toHaveBeenCalledTimes(0);
92
+ wrapper.unmount();
93
+ expect(spy).toHaveBeenCalledTimes(1);
94
+ expect(spy.mock.calls[0][0]).toBe(spy2.mock.calls[0][0]);
95
+ });
96
+
97
+ test('should disable zoom-in button on mount with max zoom..', () => {
98
+ const map = new OLMap({
99
+ view: new OLView({ maxZoom: 20, zoom: 20 }),
100
+ });
101
+ const spy = jest.spyOn(map.getView(), 'setZoom');
102
+ const wrapper = mount(<Zoom map={map} />);
103
+ act(() => {
104
+ map.dispatchEvent(new MapEvent('moveend', map));
105
+ });
106
+ wrapper.update();
107
+ expect(wrapper.find('.rs-zoom-in').prop('disabled')).toEqual(true);
108
+ wrapper.find('.rs-zoom-in').first().simulate('click');
109
+ expect(spy).toHaveBeenCalledTimes(0);
110
+ });
111
+
112
+ test('should disable zoom-out button on mount with min zoom.', () => {
113
+ const map = new OLMap({
114
+ view: new OLView({ minZoom: 2, zoom: 2 }),
115
+ });
116
+ const spy = jest.spyOn(map.getView(), 'setZoom');
117
+ const wrapper = mount(<Zoom map={map} />);
118
+ act(() => {
119
+ map.dispatchEvent(new MapEvent('moveend', map));
120
+ });
121
+ wrapper.update();
122
+ expect(wrapper.find('.rs-zoom-out').prop('disabled')).toEqual(true);
123
+ wrapper.find('.rs-zoom-out').first().simulate('click');
124
+ expect(spy).toHaveBeenCalledTimes(0);
125
+ });
126
+ });
127
+
128
+ test('should disable zoom-out button when reaching min zoom.', () => {
129
+ const map = new OLMap({
130
+ view: new OLView({ minZoom: 2, zoom: 3 }),
131
+ });
132
+ const spy = jest.spyOn(map.getView(), 'setZoom');
133
+ const wrapper = mount(<Zoom map={map} />);
134
+ wrapper.find('.rs-zoom-out').first().simulate('click');
135
+ expect(spy).toHaveBeenCalledTimes(1);
136
+ act(() => {
137
+ map.dispatchEvent(new MapEvent('moveend', map));
138
+ });
139
+ wrapper.update();
140
+ expect(wrapper.find('.rs-zoom-out').prop('disabled')).toEqual(true);
141
+ });
@@ -0,0 +1,201 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Zoom should match snapshot with custom attributes 1`] = `
4
+ <div
5
+ className="foo"
6
+ tabIndex={-1}
7
+ title="bar"
8
+ >
9
+ <button
10
+ className="rs-zoom-in"
11
+ disabled={false}
12
+ onClick={[Function]}
13
+ onKeyPress={[Function]}
14
+ tabIndex={0}
15
+ title="Zoom in"
16
+ type="button"
17
+ >
18
+ <svg
19
+ fill="currentColor"
20
+ focusable={false}
21
+ height="1em"
22
+ stroke="currentColor"
23
+ strokeWidth="0"
24
+ style={
25
+ {
26
+ "color": undefined,
27
+ }
28
+ }
29
+ viewBox="0 0 448 512"
30
+ width="1em"
31
+ xmlns="http://www.w3.org/2000/svg"
32
+ >
33
+ <path
34
+ d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
35
+ />
36
+ </svg>
37
+ </button>
38
+ <button
39
+ className="rs-zoom-out"
40
+ disabled={false}
41
+ onClick={[Function]}
42
+ onKeyPress={[Function]}
43
+ tabIndex={0}
44
+ title="Zoom out"
45
+ type="button"
46
+ >
47
+ <svg
48
+ fill="currentColor"
49
+ focusable={false}
50
+ height="1em"
51
+ stroke="currentColor"
52
+ strokeWidth="0"
53
+ style={
54
+ {
55
+ "color": undefined,
56
+ }
57
+ }
58
+ viewBox="0 0 448 512"
59
+ width="1em"
60
+ xmlns="http://www.w3.org/2000/svg"
61
+ >
62
+ <path
63
+ d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
64
+ />
65
+ </svg>
66
+ </button>
67
+ </div>
68
+ `;
69
+
70
+ exports[`Zoom should match snapshot with zoom slider 1`] = `
71
+ <div
72
+ className="rs-zooms-bar"
73
+ >
74
+ <button
75
+ className="rs-zoom-in"
76
+ disabled={false}
77
+ onClick={[Function]}
78
+ onKeyPress={[Function]}
79
+ tabIndex={0}
80
+ title="Zoom in"
81
+ type="button"
82
+ >
83
+ <svg
84
+ fill="currentColor"
85
+ focusable={false}
86
+ height="1em"
87
+ stroke="currentColor"
88
+ strokeWidth="0"
89
+ style={
90
+ {
91
+ "color": undefined,
92
+ }
93
+ }
94
+ viewBox="0 0 448 512"
95
+ width="1em"
96
+ xmlns="http://www.w3.org/2000/svg"
97
+ >
98
+ <path
99
+ d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
100
+ />
101
+ </svg>
102
+ </button>
103
+ <div
104
+ className="rs-zoomslider-wrapper"
105
+ />
106
+ <button
107
+ className="rs-zoom-out"
108
+ disabled={false}
109
+ onClick={[Function]}
110
+ onKeyPress={[Function]}
111
+ tabIndex={0}
112
+ title="Zoom out"
113
+ type="button"
114
+ >
115
+ <svg
116
+ fill="currentColor"
117
+ focusable={false}
118
+ height="1em"
119
+ stroke="currentColor"
120
+ strokeWidth="0"
121
+ style={
122
+ {
123
+ "color": undefined,
124
+ }
125
+ }
126
+ viewBox="0 0 448 512"
127
+ width="1em"
128
+ xmlns="http://www.w3.org/2000/svg"
129
+ >
130
+ <path
131
+ d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
132
+ />
133
+ </svg>
134
+ </button>
135
+ </div>
136
+ `;
137
+
138
+ exports[`Zoom should match snapshot. 1`] = `
139
+ <div
140
+ className="rs-zooms-bar"
141
+ >
142
+ <button
143
+ className="rs-zoom-in"
144
+ disabled={false}
145
+ onClick={[Function]}
146
+ onKeyPress={[Function]}
147
+ tabIndex={0}
148
+ title="Zoom in"
149
+ type="button"
150
+ >
151
+ <svg
152
+ fill="currentColor"
153
+ focusable={false}
154
+ height="1em"
155
+ stroke="currentColor"
156
+ strokeWidth="0"
157
+ style={
158
+ {
159
+ "color": undefined,
160
+ }
161
+ }
162
+ viewBox="0 0 448 512"
163
+ width="1em"
164
+ xmlns="http://www.w3.org/2000/svg"
165
+ >
166
+ <path
167
+ d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
168
+ />
169
+ </svg>
170
+ </button>
171
+ <button
172
+ className="rs-zoom-out"
173
+ disabled={false}
174
+ onClick={[Function]}
175
+ onKeyPress={[Function]}
176
+ tabIndex={0}
177
+ title="Zoom out"
178
+ type="button"
179
+ >
180
+ <svg
181
+ fill="currentColor"
182
+ focusable={false}
183
+ height="1em"
184
+ stroke="currentColor"
185
+ strokeWidth="0"
186
+ style={
187
+ {
188
+ "color": undefined,
189
+ }
190
+ }
191
+ viewBox="0 0 448 512"
192
+ width="1em"
193
+ xmlns="http://www.w3.org/2000/svg"
194
+ >
195
+ <path
196
+ d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
197
+ />
198
+ </svg>
199
+ </button>
200
+ </div>
201
+ `;
@@ -0,0 +1 @@
1
+ export { default } from './Zoom';
@@ -1,22 +1,25 @@
1
- import PropTypes from "prop-types";
2
- const STATE_BOARDING = "BOARDING";
3
- const STATE_LEAVING = "LEAVING";
1
+ import PropTypes from 'prop-types';
2
+
3
+ const STATE_BOARDING = 'BOARDING';
4
+ const STATE_LEAVING = 'LEAVING';
5
+
4
6
  const station = PropTypes.shape({
5
- arrivalDelay: PropTypes.number,
6
- aimedArrivalTime: PropTypes.number,
7
- arrivalTime: PropTypes.number,
7
+ arrivalDelay: PropTypes.number, // time in milliseconds.
8
+ aimedArrivalTime: PropTypes.number, // time in milliseconds.
9
+ arrivalTime: PropTypes.number, // time in milliseconds with the delay included.
8
10
  cancelled: PropTypes.bool,
9
11
  coordinates: PropTypes.arrayOf(PropTypes.number),
10
- aimedDepartureTime: PropTypes.number,
11
- departureDelay: PropTypes.number,
12
- departureTime: PropTypes.number,
12
+ aimedDepartureTime: PropTypes.number, // time in milliseconds.
13
+ departureDelay: PropTypes.number, // time in milliseconds.
14
+ departureTime: PropTypes.number, // time in milliseconds with the delay included
13
15
  noDropOff: PropTypes.bool,
14
16
  noPickUp: PropTypes.bool,
15
17
  stationId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
16
18
  stationName: PropTypes.string,
17
19
  wheelchairAccessible: PropTypes.bool,
18
- state: PropTypes.oneOf([null, STATE_BOARDING, STATE_LEAVING])
20
+ state: PropTypes.oneOf([null, STATE_BOARDING, STATE_LEAVING]),
19
21
  });
22
+
20
23
  const lineInfos = PropTypes.shape({
21
24
  backgroundColor: PropTypes.string,
22
25
  bicyclesAllowed: PropTypes.bool,
@@ -39,11 +42,12 @@ const lineInfos = PropTypes.shape({
39
42
  shortName: PropTypes.string,
40
43
  stations: PropTypes.arrayOf(station),
41
44
  vehicleType: PropTypes.number,
42
- wheelchairAccessible: PropTypes.bool
45
+ wheelchairAccessible: PropTypes.bool,
43
46
  });
47
+
44
48
  export default {
45
49
  lineInfos,
46
50
  station,
47
51
  STATE_BOARDING,
48
- STATE_LEAVING
52
+ STATE_LEAVING,
49
53
  };
@@ -1,3 +1,3 @@
1
1
  global.URL.createObjectURL = jest.fn(() => {
2
- return "fooblob";
2
+ return 'fooblob';
3
3
  });
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ // Import default implementation from react-styleguidist using the full path
4
+ import ComponentsListRenderer from 'react-styleguidist/lib/client/rsg-components/ComponentsList/ComponentsListRenderer';
5
+ import getUrl from 'react-styleguidist/lib/client/utils/getUrl';
6
+
7
+ const propTypes = {
8
+ items: PropTypes.array.isRequired,
9
+ classes: PropTypes.object,
10
+ hashPath: PropTypes.array,
11
+ useRouterLinks: PropTypes.bool,
12
+ useHashId: PropTypes.bool,
13
+ };
14
+
15
+ const defaultProps = {
16
+ classes: null,
17
+ hashPath: [],
18
+ useRouterLinks: false,
19
+ useHashId: true,
20
+ };
21
+
22
+ function ComponentsList({
23
+ classes,
24
+ items,
25
+ useRouterLinks = false,
26
+ useHashId,
27
+ hashPath,
28
+ }) {
29
+ const mappedItems = items.map((item) => {
30
+ return {
31
+ ...item,
32
+ href: item.href
33
+ ? item.href
34
+ : // Conflict with Permalink Component: Remove the first '/' to avoid page reload on click
35
+ getUrl({
36
+ name: item.name,
37
+ slug: item.slug,
38
+ anchor: !useRouterLinks,
39
+ hashPath: useRouterLinks ? hashPath : false,
40
+ id: useRouterLinks ? useHashId : false,
41
+ })
42
+ .replace(/^\/index.html+/g, '')
43
+ .replace(/^\/+/g, ''),
44
+ };
45
+ });
46
+ return <ComponentsListRenderer classes={classes} items={mappedItems} />;
47
+ }
48
+
49
+ ComponentsList.propTypes = propTypes;
50
+ ComponentsList.defaultProps = defaultProps;
51
+
52
+ export default ComponentsList;