@mapcomponents/react-maplibre 0.1.37 → 0.1.40

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 (184) hide show
  1. package/.storybook/main.js +1 -0
  2. package/CHANGELOG.md +9 -3
  3. package/coverage/clover.xml +435 -351
  4. package/coverage/coverage-final.json +29 -26
  5. package/coverage/lcov-report/index.html +74 -59
  6. package/coverage/lcov-report/src/components/MapLibreMap/MapLibreMap.tsx.html +75 -27
  7. package/coverage/lcov-report/src/components/MapLibreMap/index.html +13 -13
  8. package/coverage/lcov-report/src/components/MlCreatePdfButton/MlCreatePdfButton.tsx.html +9 -9
  9. package/coverage/lcov-report/src/components/MlCreatePdfButton/index.html +11 -11
  10. package/coverage/lcov-report/src/components/MlFeatureEditor/MlFeatureEditor.tsx.html +3 -6
  11. package/coverage/lcov-report/src/components/MlFeatureEditor/index.html +1 -1
  12. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/MlFillExtrusionLayer.tsx.html +3 -3
  13. package/coverage/lcov-report/src/components/MlFillExtrusionLayer/index.html +1 -1
  14. package/coverage/lcov-report/src/components/MlFollowGps/MlFollowGps.tsx.html +3 -3
  15. package/coverage/lcov-report/src/components/MlFollowGps/index.html +1 -1
  16. package/coverage/lcov-report/src/components/MlGPXViewer/MlGPXViewer.tsx.html +3 -3
  17. package/coverage/lcov-report/src/components/MlGPXViewer/gpxConverter.js.html +8 -8
  18. package/coverage/lcov-report/src/components/MlGPXViewer/index.html +1 -1
  19. package/coverage/lcov-report/src/components/MlGeoJsonLayer/MlGeoJsonLayer.tsx.html +2 -2
  20. package/coverage/lcov-report/src/components/MlGeoJsonLayer/index.html +1 -1
  21. package/coverage/lcov-report/src/components/MlImageMarkerLayer/MlImageMarkerLayer.tsx.html +2 -2
  22. package/coverage/lcov-report/src/components/MlImageMarkerLayer/index.html +1 -1
  23. package/coverage/lcov-report/src/components/MlLayer/MlLayer.tsx.html +2 -2
  24. package/coverage/lcov-report/src/components/MlLayer/index.html +1 -1
  25. package/coverage/lcov-report/src/components/MlLayerMagnify/MlLayerMagnify.tsx.html +15 -27
  26. package/coverage/lcov-report/src/components/MlLayerMagnify/index.html +18 -18
  27. package/coverage/lcov-report/src/components/MlLayerSwipe/MlLayerSwipe.tsx.html +13 -28
  28. package/coverage/lcov-report/src/components/MlLayerSwipe/index.html +19 -19
  29. package/coverage/lcov-report/src/components/MlLayerSwitcher/MlLayerSwitcher.js.html +2 -2
  30. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/LayerBox.js.html +1 -1
  31. package/coverage/lcov-report/src/components/MlLayerSwitcher/components/index.html +1 -1
  32. package/coverage/lcov-report/src/components/MlLayerSwitcher/index.html +1 -1
  33. package/coverage/lcov-report/src/components/MlMarker/MlMarker.tsx.html +9 -9
  34. package/coverage/lcov-report/src/components/MlMarker/index.html +11 -11
  35. package/coverage/lcov-report/src/components/MlNavigationCompass/MlNavigationCompass.tsx.html +6 -6
  36. package/coverage/lcov-report/src/components/MlNavigationCompass/index.html +1 -1
  37. package/coverage/lcov-report/src/components/MlNavigationTools/MlNavigationTools.tsx.html +7 -7
  38. package/coverage/lcov-report/src/components/MlNavigationTools/index.html +11 -11
  39. package/coverage/lcov-report/src/components/MlOsmLayer/MlOsmLayer.js.html +3 -3
  40. package/coverage/lcov-report/src/components/MlOsmLayer/index.html +1 -1
  41. package/coverage/lcov-report/src/components/MlScaleReference/MlScaleReference.js.html +1 -1
  42. package/coverage/lcov-report/src/components/MlScaleReference/index.html +1 -1
  43. package/coverage/lcov-report/src/components/MlShareMapState/MlShareMapState.js.html +2 -2
  44. package/coverage/lcov-report/src/components/MlShareMapState/index.html +1 -1
  45. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.js.html +9 -36
  46. package/coverage/lcov-report/src/components/MlSpatialElevationProfile/index.html +1 -1
  47. package/coverage/lcov-report/src/components/MlThreeJsLayer/MlThreeJsLayer.js.html +2 -2
  48. package/coverage/lcov-report/src/components/MlThreeJsLayer/index.html +1 -1
  49. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/MlTransitionGeoJsonLayer.tsx.html +3 -3
  50. package/coverage/lcov-report/src/components/MlTransitionGeoJsonLayer/index.html +1 -1
  51. package/coverage/lcov-report/src/components/MlUseMapDebugger/MlUseMapDebugger.js.html +1 -1
  52. package/coverage/lcov-report/src/components/MlUseMapDebugger/index.html +1 -1
  53. package/coverage/lcov-report/src/components/MlVectorTileLayer/MlVectorTileLayer.tsx.html +3 -3
  54. package/coverage/lcov-report/src/components/MlVectorTileLayer/index.html +1 -1
  55. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js.html +2 -2
  56. package/coverage/lcov-report/src/components/MlWmsFeatureInfoPopup/index.html +1 -1
  57. package/coverage/lcov-report/src/components/MlWmsLayer/MlWmsLayer.tsx.html +5 -5
  58. package/coverage/lcov-report/src/components/MlWmsLayer/index.html +1 -1
  59. package/coverage/lcov-report/src/components/MlWmsLoader/MlWmsLoader.tsx.html +3 -6
  60. package/coverage/lcov-report/src/components/MlWmsLoader/index.html +1 -1
  61. package/coverage/lcov-report/src/contexts/MapContext.tsx.html +358 -0
  62. package/coverage/lcov-report/src/contexts/SimpleDataContext.js.html +103 -0
  63. package/coverage/lcov-report/src/contexts/SimpleDataProvider.js.html +277 -0
  64. package/coverage/lcov-report/src/contexts/index.html +146 -0
  65. package/coverage/lcov-report/src/hooks/index.html +11 -11
  66. package/coverage/lcov-report/src/hooks/useLayer.ts.html +15 -126
  67. package/coverage/lcov-report/src/hooks/useMap.ts.html +13 -61
  68. package/coverage/lcov-report/src/hooks/useMapState.ts.html +6 -6
  69. package/coverage/lcov-report/src/hooks/useWms.js.html +7 -7
  70. package/coverage/lcov-report/src/index.html +1 -1
  71. package/coverage/lcov-report/src/index.ts.html +15 -3
  72. package/coverage/lcov.info +790 -615
  73. package/dist/index.esm.js +12093 -37213
  74. package/dist/index.esm.js.map +1 -1
  75. package/docs-build/{0.fd1aa3ea21956d993519.manager.bundle.js → 0.20735a16c2ad9677fe7d.manager.bundle.js} +1 -1
  76. package/docs-build/{0.d0c23b79.iframe.bundle.js → 0.93d0ce3d.iframe.bundle.js} +2 -2
  77. package/docs-build/0.93d0ce3d.iframe.bundle.js.map +1 -0
  78. package/docs-build/{1.34075652.iframe.bundle.js → 1.2b1ae3fa.iframe.bundle.js} +2 -2
  79. package/docs-build/1.2b1ae3fa.iframe.bundle.js.map +1 -0
  80. package/docs-build/{16.ca488dae.iframe.bundle.js → 16.2c8135a1.iframe.bundle.js} +2 -2
  81. package/docs-build/16.2c8135a1.iframe.bundle.js.map +1 -0
  82. package/docs-build/{17.e40eac7f.iframe.bundle.js → 17.9a16865a.iframe.bundle.js} +2 -2
  83. package/docs-build/17.9a16865a.iframe.bundle.js.map +1 -0
  84. package/docs-build/{18.62af0912.iframe.bundle.js → 18.4c47f37e.iframe.bundle.js} +2 -2
  85. package/docs-build/18.4c47f37e.iframe.bundle.js.map +1 -0
  86. package/docs-build/{19.0a217189.iframe.bundle.js → 19.cdf25e28.iframe.bundle.js} +2 -2
  87. package/docs-build/19.cdf25e28.iframe.bundle.js.map +1 -0
  88. package/docs-build/{2.f15ae19a.iframe.bundle.js → 2.4518b817.iframe.bundle.js} +2 -2
  89. package/docs-build/2.4518b817.iframe.bundle.js.map +1 -0
  90. package/docs-build/{4.f741dafe1833630ec8bf.manager.bundle.js → 4.8ac31bba1926f4f011b0.manager.bundle.js} +2 -2
  91. package/docs-build/{4.f741dafe1833630ec8bf.manager.bundle.js.LICENSE.txt → 4.8ac31bba1926f4f011b0.manager.bundle.js.LICENSE.txt} +0 -0
  92. package/docs-build/{5.d4de191e7daeefb036ca.manager.bundle.js → 5.daf044a6c0f55d839078.manager.bundle.js} +1 -1
  93. package/docs-build/{6.2b178c5444648ee5c0fa.manager.bundle.js → 6.99fba2cf6af0473f8209.manager.bundle.js} +2 -2
  94. package/docs-build/{6.2b178c5444648ee5c0fa.manager.bundle.js.LICENSE.txt → 6.99fba2cf6af0473f8209.manager.bundle.js.LICENSE.txt} +0 -0
  95. package/docs-build/{7.7c16aea8ec7ea6e91994.manager.bundle.js → 7.b6a48b90f61cb575c2e4.manager.bundle.js} +1 -1
  96. package/docs-build/{8.52fa838fdf937b29676a.manager.bundle.js → 8.50518a5391398d9d5812.manager.bundle.js} +1 -1
  97. package/docs-build/assets/3D/godzilla_simple.glb +0 -0
  98. package/docs-build/catalogue/mc_meta.json +1 -1
  99. package/docs-build/iframe.html +1 -1
  100. package/docs-build/index.html +1 -1
  101. package/docs-build/{main.8a7ec710ea1c16b5e13f.manager.bundle.js → main.ef9704b1252e8efa56a0.manager.bundle.js} +1 -1
  102. package/docs-build/main~24120820.e0a66582.iframe.bundle.js +2 -0
  103. package/docs-build/main~24120820.e0a66582.iframe.bundle.js.map +1 -0
  104. package/docs-build/{runtime~main.67aa1de2d72f40a81164.manager.bundle.js → runtime~main.6e6ed7dc9ea4785ef286.manager.bundle.js} +1 -1
  105. package/docs-build/stories.json +416 -168
  106. package/docs-build/vendors~main.4b570b3072ba06ee44b5.manager.bundle.js +2 -0
  107. package/docs-build/{vendors~main.351900838c49e9200954.manager.bundle.js.LICENSE.txt → vendors~main.4b570b3072ba06ee44b5.manager.bundle.js.LICENSE.txt} +27 -24
  108. package/docs-build/{vendors~main~0ad7406a.a6abfed7.iframe.bundle.js → vendors~main~0ad7406a.22b96f8e.iframe.bundle.js} +2 -2
  109. package/docs-build/vendors~main~0ad7406a.22b96f8e.iframe.bundle.js.map +1 -0
  110. package/docs-build/{vendors~main~0f485567.1d7a15b7.iframe.bundle.js → vendors~main~0f485567.df27e62a.iframe.bundle.js} +2 -2
  111. package/docs-build/vendors~main~0f485567.df27e62a.iframe.bundle.js.map +1 -0
  112. package/docs-build/{vendors~main~41a6ab2c.525ecc56.iframe.bundle.js → vendors~main~41a6ab2c.7f3a1ced.iframe.bundle.js} +2 -2
  113. package/docs-build/vendors~main~41a6ab2c.7f3a1ced.iframe.bundle.js.map +1 -0
  114. package/docs-build/{vendors~main~73914085.227c6747.iframe.bundle.js → vendors~main~73914085.3d4f5bbf.iframe.bundle.js} +4 -4
  115. package/docs-build/{vendors~main~73914085.227c6747.iframe.bundle.js.map → vendors~main~73914085.3d4f5bbf.iframe.bundle.js.map} +1 -1
  116. package/docs-build/{vendors~main~9c5b28f6.f02cc741.iframe.bundle.js → vendors~main~9c5b28f6.f8614bdc.iframe.bundle.js} +3 -3
  117. package/docs-build/vendors~main~9c5b28f6.f8614bdc.iframe.bundle.js.map +1 -0
  118. package/docs-build/{vendors~main~b5906859.4083ac60.iframe.bundle.js → vendors~main~b5906859.b606e812.iframe.bundle.js} +3 -3
  119. package/docs-build/vendors~main~b5906859.b606e812.iframe.bundle.js.map +1 -0
  120. package/docs-build/vendors~main~b9cf3951.a6200a51.iframe.bundle.js +63 -0
  121. package/docs-build/vendors~main~b9cf3951.a6200a51.iframe.bundle.js.map +1 -0
  122. package/docs-build/{vendors~main~d939e436.92c27fbf.iframe.bundle.js → vendors~main~d939e436.aa5d1533.iframe.bundle.js} +2 -2
  123. package/docs-build/vendors~main~d939e436.aa5d1533.iframe.bundle.js.map +1 -0
  124. package/docs-build/{vendors~main~dab50aa4.b0d58038.iframe.bundle.js → vendors~main~dab50aa4.277284e0.iframe.bundle.js} +4 -4
  125. package/docs-build/{vendors~main~dab50aa4.b0d58038.iframe.bundle.js.map → vendors~main~dab50aa4.277284e0.iframe.bundle.js.map} +1 -1
  126. package/package.json +6 -4
  127. package/rollup.config.js +5 -6
  128. package/src/components/MapLibreMap/MapLibreMap.stories.js +1 -1
  129. package/src/components/MapLibreMap/MapLibreMap.test.js +1 -1
  130. package/src/components/MapLibreMap/MapLibreMap.tsx +32 -16
  131. package/src/components/MapLibreMap/lib/MapLibreGlWrapper.test.js +1 -1
  132. package/src/components/MapLibreMap/lib/MapLibreGlWrapper.ts +2 -2
  133. package/src/components/MlBasicComponent.js +4 -1
  134. package/src/components/MlFeatureEditor/MlFeatureEditor.test.js +1 -1
  135. package/src/components/MlFeatureEditor/MlFeatureEditor.tsx +0 -1
  136. package/src/components/MlFollowGps/MlFollowGps.test.js +1 -1
  137. package/src/components/MlLayer/MlLayer.test.js +1 -1
  138. package/src/components/MlLayerMagnify/MlLayerMagnify.test.js +1 -1
  139. package/src/components/MlLayerMagnify/MlLayerMagnify.tsx +3 -7
  140. package/src/components/MlLayerSwipe/MlLayerSwipe.test.js +1 -1
  141. package/src/components/MlLayerSwipe/MlLayerSwipe.tsx +2 -7
  142. package/src/components/MlLayerSwitcher/MlLayerSwitcher.js +1 -1
  143. package/src/components/MlNavigationCompass/MlNavigationCompass.test.js +1 -1
  144. package/src/components/MlShareMapState/MlShareMapState.js +1 -1
  145. package/src/components/MlSpatialElevationProfile/MlSpatialElevationProfile.js +4 -13
  146. package/src/components/MlThreeJsLayer/MlThreeJsLayer.js +1 -1
  147. package/src/components/MlTransitionGeoJsonLayer/MlTransitionGeoJsonLayer.stories.js +1 -1
  148. package/src/components/MlWmsFeatureInfoPopup/MlWmsFeatureInfoPopup.js +1 -1
  149. package/src/components/MlWmsLoader/MlWmsLoader.tsx +1 -2
  150. package/src/contexts/MapComponentsProvider.test.js +260 -0
  151. package/src/contexts/MapContext.tsx +92 -0
  152. package/src/contexts/SimpleDataContext.js +6 -0
  153. package/src/contexts/SimpleDataProvider.js +64 -0
  154. package/src/contexts/SimpleDataProvider.test.js +68 -0
  155. package/src/custom.d.tsx +1 -1
  156. package/src/decorators/MapContextDecorator.js +1 -1
  157. package/src/decorators/MultiMapContextDecorator.js +1 -1
  158. package/src/hooks/useLayer.ts +12 -49
  159. package/src/hooks/useMap.ts +9 -26
  160. package/src/hooks/useMapState.ts +3 -3
  161. package/src/index.ts +5 -1
  162. package/src/ui_components/LoadingOverlayContext.js +1 -1
  163. package/src/util/layerRemovalTest.js +1 -1
  164. package/src/util/sourceRemovalTest.js +1 -1
  165. package/tsconfig.json +4 -0
  166. package/docs-build/0.d0c23b79.iframe.bundle.js.map +0 -1
  167. package/docs-build/1.34075652.iframe.bundle.js.map +0 -1
  168. package/docs-build/16.ca488dae.iframe.bundle.js.map +0 -1
  169. package/docs-build/17.e40eac7f.iframe.bundle.js.map +0 -1
  170. package/docs-build/18.62af0912.iframe.bundle.js.map +0 -1
  171. package/docs-build/19.0a217189.iframe.bundle.js.map +0 -1
  172. package/docs-build/2.f15ae19a.iframe.bundle.js.map +0 -1
  173. package/docs-build/main~24120820.ba6665a8.iframe.bundle.js +0 -2
  174. package/docs-build/main~24120820.ba6665a8.iframe.bundle.js.map +0 -1
  175. package/docs-build/vendors~main.351900838c49e9200954.manager.bundle.js +0 -2
  176. package/docs-build/vendors~main~0ad7406a.a6abfed7.iframe.bundle.js.map +0 -1
  177. package/docs-build/vendors~main~0f485567.1d7a15b7.iframe.bundle.js.map +0 -1
  178. package/docs-build/vendors~main~41a6ab2c.525ecc56.iframe.bundle.js.map +0 -1
  179. package/docs-build/vendors~main~9c5b28f6.f02cc741.iframe.bundle.js.map +0 -1
  180. package/docs-build/vendors~main~b5906859.4083ac60.iframe.bundle.js.map +0 -1
  181. package/docs-build/vendors~main~b9cf3951.45da142d.iframe.bundle.js +0 -68
  182. package/docs-build/vendors~main~b9cf3951.45da142d.iframe.bundle.js.map +0 -1
  183. package/docs-build/vendors~main~d939e436.92c27fbf.iframe.bundle.js.map +0 -1
  184. package/public/stories.json +0 -331
@@ -0,0 +1,260 @@
1
+ import React, { useContext } from "react";
2
+ import MapContext from "./MapContext";
3
+ import { MapComponentsProvider } from "./MapContext";
4
+ import { mount } from "enzyme";
5
+
6
+ const MapObjectTestBlock = ({ mapId }) => {
7
+ const mapContext = useContext(MapContext);
8
+
9
+ return (
10
+ <>
11
+ <button
12
+ className={"register_" + mapId}
13
+ onClick={() => {
14
+ mapContext.registerMap(mapId, { id: mapId });
15
+ }}
16
+ >
17
+ set {mapId}
18
+ </button>
19
+ <button
20
+ className={"remove_" + mapId}
21
+ onClick={() => {
22
+ mapContext.removeMap(mapId);
23
+ }}
24
+ >
25
+ set {mapId}
26
+ </button>
27
+ <div className={mapId + "_found"}>{mapContext.mapExists(mapId) ? "true" : "false"}</div>
28
+ <div className={mapId + "_id"}>
29
+ {mapContext.mapExists(mapId) ? mapContext.getMap(mapId).id : ""}
30
+ </div>
31
+ <div className={mapId + "_id_position_in_map_ids"}>{mapContext.mapIds.indexOf(mapId)}</div>
32
+ </>
33
+ );
34
+ };
35
+
36
+ const MapContextTestComponent = () => {
37
+ const mapContext = useContext(MapContext);
38
+
39
+ return (
40
+ <>
41
+ <div className="map_count">{mapContext.mapIds.length}</div>
42
+ <div className="typeof_map">{typeof mapContext.map}</div>
43
+ <button
44
+ className="set_anonymous_map"
45
+ onClick={() => {
46
+ mapContext.setMap({});
47
+ }}
48
+ >
49
+ set anonymous map
50
+ </button>
51
+ <button
52
+ className="remove_anonymous_map"
53
+ onClick={() => {
54
+ mapContext.removeMap();
55
+ }}
56
+ >
57
+ set anonymous map
58
+ </button>
59
+ <div className="anonymous_map_found">{mapContext.mapExists() ? "true" : "false"}</div>
60
+ <div className="get_anonymous_map">{mapContext.getMap() ? "true" : "false"}</div>
61
+
62
+ {["map_1", "map_2"].map((mapId) => (
63
+ <MapObjectTestBlock mapId={mapId} key={mapId} />
64
+ ))}
65
+ </>
66
+ );
67
+ };
68
+
69
+ describe("MapComponentsProvider.setMap", () => {
70
+ it("should add an anonymous map object to mapContext", () => {
71
+ const wrapper = mount(
72
+ <MapComponentsProvider>
73
+ <MapContextTestComponent />
74
+ </MapComponentsProvider>
75
+ );
76
+
77
+ expect(wrapper.find(".typeof_map").text()).toEqual("undefined");
78
+ expect(wrapper.find(".map_count").text()).toEqual("0");
79
+
80
+ wrapper.find(".set_anonymous_map").simulate("click");
81
+
82
+ expect(wrapper.find(".typeof_map").text()).toEqual("object");
83
+ expect(wrapper.find(".map_count").text()).toEqual("1");
84
+ });
85
+ });
86
+
87
+ describe("MapComponentsProvider.getMap", () => {
88
+ it("should return the map object referenced by mapContext.map if no parameters are passed", () => {
89
+ const wrapper = mount(
90
+ <MapComponentsProvider>
91
+ <MapContextTestComponent />
92
+ </MapComponentsProvider>
93
+ );
94
+
95
+ expect(wrapper.find(".get_anonymous_map").text()).toEqual("false");
96
+
97
+ wrapper.find(".set_anonymous_map").simulate("click");
98
+
99
+ expect(wrapper.find(".get_anonymous_map").text()).toEqual("true");
100
+ });
101
+ });
102
+
103
+ describe("MapComponentsProvider.mapExists", () => {
104
+ it("should return true if an anonymous map object has been set using setMap", () => {
105
+ const wrapper = mount(
106
+ <MapComponentsProvider>
107
+ <MapContextTestComponent />
108
+ </MapComponentsProvider>
109
+ );
110
+
111
+ expect(wrapper.find(".typeof_map").text()).toEqual("undefined");
112
+ expect(wrapper.find(".map_count").text()).toEqual("0");
113
+ expect(wrapper.find(".anonymous_map_found").text()).toEqual("false");
114
+
115
+ wrapper.find(".set_anonymous_map").simulate("click");
116
+
117
+ expect(wrapper.find(".typeof_map").text()).toEqual("object");
118
+ expect(wrapper.find(".map_count").text()).toEqual("1");
119
+ expect(wrapper.find(".anonymous_map_found").text()).toEqual("true");
120
+ });
121
+
122
+ it("should return true if a map object has been registered using registerMap", () => {
123
+ const wrapper = mount(
124
+ <MapComponentsProvider>
125
+ <MapContextTestComponent />
126
+ </MapComponentsProvider>
127
+ );
128
+
129
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
130
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
131
+ expect(wrapper.find(".anonymous_map_found").text()).toEqual("false");
132
+
133
+ wrapper.find(".register_map_1").simulate("click");
134
+
135
+ expect(wrapper.find(".map_1_found").text()).toEqual("true");
136
+ expect(wrapper.find(".map_1_id").text()).toEqual("map_1");
137
+ expect(wrapper.find(".anonymous_map_found").text()).toEqual("true");
138
+ });
139
+ });
140
+
141
+ describe("MapComponentsProvider.registerMap", () => {
142
+ it("should register a map object with the id map_1 to mapContext", () => {
143
+ const wrapper = mount(
144
+ <MapComponentsProvider>
145
+ <MapContextTestComponent />
146
+ </MapComponentsProvider>
147
+ );
148
+
149
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
150
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
151
+
152
+ wrapper.find(".register_map_1").simulate("click");
153
+
154
+ expect(wrapper.find(".map_1_found").text()).toEqual("true");
155
+ expect(wrapper.find(".map_1_id").text()).toEqual("map_1");
156
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).not.toEqual("-1");
157
+ });
158
+
159
+ it("should register a map object with the id map_1 and another on with the id map_2 to mapContext", () => {
160
+ const wrapper = mount(
161
+ <MapComponentsProvider>
162
+ <MapContextTestComponent />
163
+ </MapComponentsProvider>
164
+ );
165
+
166
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
167
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
168
+ expect(wrapper.find(".map_2_found").text()).toEqual("false");
169
+ expect(wrapper.find(".map_2_id_position_in_map_ids").text()).toEqual("-1");
170
+
171
+ wrapper.find(".register_map_1").simulate("click");
172
+ wrapper.find(".register_map_2").simulate("click");
173
+
174
+ expect(wrapper.find(".map_1_found").text()).toEqual("true");
175
+ expect(wrapper.find(".map_1_id").text()).toEqual("map_1");
176
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).not.toEqual("-1");
177
+ expect(wrapper.find(".map_2_found").text()).toEqual("true");
178
+ expect(wrapper.find(".map_2_id").text()).toEqual("map_2");
179
+ expect(wrapper.find(".map_2_id_position_in_map_ids").text()).not.toEqual("-1");
180
+ });
181
+ });
182
+
183
+ describe("MapComponentsProvider.removeMap", () => {
184
+ it("should remove an anonymous map object from mapContext", () => {
185
+ const wrapper = mount(
186
+ <MapComponentsProvider>
187
+ <MapContextTestComponent />
188
+ </MapComponentsProvider>
189
+ );
190
+
191
+ expect(wrapper.find(".typeof_map").text()).toEqual("undefined");
192
+ expect(wrapper.find(".map_count").text()).toEqual("0");
193
+
194
+ wrapper.find(".set_anonymous_map").simulate("click");
195
+
196
+ expect(wrapper.find(".typeof_map").text()).toEqual("object");
197
+ expect(wrapper.find(".map_count").text()).toEqual("1");
198
+
199
+ wrapper.find(".remove_anonymous_map").simulate("click");
200
+
201
+ expect(wrapper.find(".typeof_map").text()).toEqual("undefined");
202
+ expect(wrapper.find(".map_count").text()).toEqual("0");
203
+ });
204
+
205
+ it("should remove a map object with the id map_1 from mapContext", () => {
206
+ const wrapper = mount(
207
+ <MapComponentsProvider>
208
+ <MapContextTestComponent />
209
+ </MapComponentsProvider>
210
+ );
211
+
212
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
213
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
214
+
215
+ wrapper.find(".register_map_1").simulate("click");
216
+
217
+ expect(wrapper.find(".map_1_found").text()).toEqual("true");
218
+ expect(wrapper.find(".map_1_id").text()).toEqual("map_1");
219
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).not.toEqual("-1");
220
+
221
+ wrapper.find(".remove_map_1").simulate("click");
222
+
223
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
224
+ expect(wrapper.find(".map_1_id").text()).toEqual("");
225
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
226
+ });
227
+
228
+ it("should remove a map object with the id map_1 and another on with the id map_2 from mapContext", () => {
229
+ const wrapper = mount(
230
+ <MapComponentsProvider>
231
+ <MapContextTestComponent />
232
+ </MapComponentsProvider>
233
+ );
234
+
235
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
236
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
237
+ expect(wrapper.find(".map_2_found").text()).toEqual("false");
238
+ expect(wrapper.find(".map_2_id_position_in_map_ids").text()).toEqual("-1");
239
+
240
+ wrapper.find(".register_map_1").simulate("click");
241
+ wrapper.find(".register_map_2").simulate("click");
242
+
243
+ expect(wrapper.find(".map_1_found").text()).toEqual("true");
244
+ expect(wrapper.find(".map_1_id").text()).toEqual("map_1");
245
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).not.toEqual("-1");
246
+ expect(wrapper.find(".map_2_found").text()).toEqual("true");
247
+ expect(wrapper.find(".map_2_id").text()).toEqual("map_2");
248
+ expect(wrapper.find(".map_2_id_position_in_map_ids").text()).not.toEqual("-1");
249
+
250
+ wrapper.find(".remove_map_1").simulate("click");
251
+ wrapper.find(".remove_map_2").simulate("click");
252
+
253
+ expect(wrapper.find(".map_1_found").text()).toEqual("false");
254
+ expect(wrapper.find(".map_1_id").text()).toEqual("");
255
+ expect(wrapper.find(".map_1_id_position_in_map_ids").text()).toEqual("-1");
256
+ expect(wrapper.find(".map_2_found").text()).toEqual("false");
257
+ expect(wrapper.find(".map_2_id").text()).toEqual("");
258
+ expect(wrapper.find(".map_2_id_position_in_map_ids").text()).toEqual("-1");
259
+ });
260
+ });
@@ -0,0 +1,92 @@
1
+ import React, { useState, useRef } from "react";
2
+ import MapLibreGlWrapper from '../components/MapLibreMap/lib/MapLibreGlWrapper';
3
+
4
+ const MapContext = React.createContext({} as MapContextType);
5
+
6
+
7
+ /**
8
+ * MapComponentsProvider must be imported and wrapped around component where at least one of its child nodes requires access to a MapLibre-gl or openlayers instance that is registered in this mapContext.
9
+ MapComponentsProvider must be used one level higher than the first use of MapContext.
10
+ *
11
+ * MapComponentsProvider requires at least one use of the MapLibreMap component somewhere down the component tree that will create the MapLibre-gl object and set the reference at MapContext.map. For MapLibre maps it is a good idea to provide a mapId attribute to the MapLibreMap Component even if you are only using a single map instance at start. It will make a later transition to using multiple instances within the same project much easier.
12
+ */
13
+
14
+ const MapComponentsProvider = ({ children }:{children:any}) => {
15
+ const [map, setMap] = useState<(MapLibreGlWrapper | undefined)>(undefined);
16
+ const [mapIds, setMapIds] = useState<[...string[]]>([]);
17
+ let mapIds_raw = useRef<[...string[]]>([]);
18
+ let maps = useRef<any>({});
19
+
20
+
21
+ const removeMap = (mapId:string) => {
22
+ if (mapId) {
23
+ if (typeof maps.current[mapId] !== "undefined") {
24
+ delete maps.current[mapId];
25
+ }
26
+ let mapIdIndex = mapIds_raw.current.indexOf(mapId);
27
+ if (mapIdIndex > -1) {
28
+ mapIds_raw.current.splice(mapIdIndex, 1);
29
+ }
30
+ setMapIds([...mapIds_raw.current]);
31
+
32
+ if (mapIds.length === 1 && map) {
33
+ setMap(undefined);
34
+ }
35
+ } else {
36
+ setMap(undefined);
37
+ removeMap("anonymous_map");
38
+ }
39
+ };
40
+
41
+ const setMapHandler = (mapInstance:MapLibreGlWrapper) => {
42
+ setMap(mapInstance);
43
+
44
+ if (mapIds.length === 0) {
45
+ let mapId = "anonymous_map";
46
+ setMapIds([...mapIds, mapId]);
47
+ maps.current[mapId] = mapInstance;
48
+ }
49
+ };
50
+
51
+ const value = {
52
+ map: map,
53
+ setMap: setMapHandler,
54
+ maps: maps.current,
55
+ mapIds: mapIds,
56
+ registerMap: (mapId:string, mapInstance:MapLibreGlWrapper) => {
57
+ if (mapId && mapInstance) {
58
+ maps.current[mapId] = mapInstance;
59
+ mapIds_raw.current.push(mapId);
60
+ setMapIds([...mapIds_raw.current]);
61
+
62
+ if (!map) {
63
+ setMap(mapInstance);
64
+ }
65
+ }
66
+ },
67
+ removeMap,
68
+ mapExists: (mapId:string) => {
69
+ if (mapId && Object.keys(maps.current).indexOf(mapId) === -1) {
70
+ return false;
71
+ } else if (!mapId && !map) {
72
+ return false;
73
+ }
74
+ return true;
75
+ },
76
+ getMap: (mapId:string):(MapLibreGlWrapper | null) => {
77
+ if (mapId && mapIds.indexOf(mapId) !== -1) {
78
+ return maps.current[mapId];
79
+ } else if (!mapId && map) {
80
+ return map;
81
+ }
82
+
83
+ return null;
84
+ },
85
+ };
86
+
87
+ //@ts-ignore
88
+ return <MapContext.Provider value={value}>{children}</MapContext.Provider>;
89
+ };
90
+
91
+ export { MapComponentsProvider };
92
+ export default MapContext;
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+
3
+ const SimpleDataContext = React.createContext({});
4
+
5
+ export const SimpleDataContextProvider = SimpleDataContext.Provider;
6
+ export default SimpleDataContext;
@@ -0,0 +1,64 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { SimpleDataContextProvider } from "./SimpleDataContext";
4
+ import * as d3 from "d3";
5
+
6
+ const SimpleDataProvider = (props) => {
7
+ const [data, setData] = useState(null);
8
+ useEffect(() => {
9
+ if (!props.url) return;
10
+
11
+ let data_promise = null;
12
+ if (props.format === "json") {
13
+ data_promise = d3.json(props.url);
14
+ } else if (props.format === "csv") {
15
+ data_promise = d3.csv(props.url);
16
+ } else if (props.format === "xml") {
17
+ data_promise = d3.xml(props.url);
18
+ }
19
+
20
+ if (data_promise) {
21
+ data_promise.then((received_data) => {
22
+ if (props.format === "xml") {
23
+ if (props.nodeType) {
24
+ let dataTmp = [];
25
+ received_data.querySelectorAll(props.nodeType).forEach((el) => {
26
+
27
+ dataTmp.push(props.formatData(el));
28
+ });
29
+ setData(dataTmp);
30
+ }
31
+ } else {
32
+ if (props.data_property) {
33
+ received_data = received_data[props.data_property];
34
+ }
35
+ if (typeof props.formatData === "function") {
36
+ setData(received_data.map(props.formatData));
37
+ } else {
38
+ setData(received_data);
39
+ }
40
+ }
41
+ if (typeof props.onData === "function") {
42
+ props.onData();
43
+ }
44
+ });
45
+ }
46
+ }, [props.url, props]);
47
+
48
+ const value = {
49
+ data: data,
50
+ setData: setData,
51
+ };
52
+
53
+ return (
54
+ <SimpleDataContextProvider value={value}>
55
+ {props.children}
56
+ </SimpleDataContextProvider>
57
+ );
58
+ };
59
+
60
+ SimpleDataProvider.propTypes = {
61
+ children: PropTypes.node.isRequired,
62
+ };
63
+
64
+ export default SimpleDataProvider;
@@ -0,0 +1,68 @@
1
+ import React, {useContext} from 'react';
2
+ import SimpleDataContext from './SimpleDataContext';
3
+ import SimpleDataProvider from './SimpleDataProvider';
4
+ import { waitFor } from '@testing-library/react';
5
+ import {mount} from 'enzyme';
6
+ import * as d3 from "d3";
7
+
8
+
9
+ jest.mock('d3');
10
+
11
+
12
+ const SimpleDataContextTestComponent = () => {
13
+
14
+ const simpleDataContext = useContext(SimpleDataContext);
15
+
16
+ return <>
17
+ <div className="data">{JSON.stringify(simpleDataContext.data)}</div>
18
+ </>;
19
+ }
20
+
21
+ const mockData = {id:12,title:'Testtitle'};
22
+ const nestedMockData = {data:mockData};
23
+ const xmlMockData = (new DOMParser()).parseFromString('<?xml version="1.0" encoding="UTF-8" ?><records> <record> <id>1</id> <title>Macey, Josephine, Robert, Clark</title> </record> <record> <id>2</id> <title>Summer, Channing, Colette, Josephine</title> </record></records>',"text/xml");;
24
+
25
+ describe('SimpleDataProvider',() => {
26
+
27
+ it('should retrieve data and provide it through simpleDataContext.data (format: "csv")', async () => {
28
+ d3.csv.mockResolvedValue(mockData);
29
+
30
+ const wrapper = mount(<SimpleDataProvider format="csv" url="test"><SimpleDataContextTestComponent /></SimpleDataProvider>);
31
+
32
+ await waitFor(() => expect(d3.csv).toHaveBeenCalledTimes(1))
33
+
34
+ expect(wrapper.find('.data').text()).toEqual(JSON.stringify(mockData));
35
+ });
36
+
37
+ it('should retrieve data and provide it through simpleDataContext.data (format: "xml")', async () => {
38
+ d3.xml.mockResolvedValue(xmlMockData);
39
+
40
+ const wrapper = mount(<SimpleDataProvider format="xml" nodeType="record" formatData={(record) => { return {id:record.querySelector('id').innerHTML,title:record.querySelector('title').innerHTML}}} url="test"><SimpleDataContextTestComponent /></SimpleDataProvider>);
41
+
42
+ await waitFor(() => expect(d3.xml).toHaveBeenCalledTimes(1))
43
+
44
+ expect(wrapper.find('.data').text()).toEqual('[{"id":"1","title":"Macey, Josephine, Robert, Clark"},{"id":"2","title":"Summer, Channing, Colette, Josephine"}]');
45
+ });
46
+
47
+ it('should retrieve data and provide it through simpleDataContext.data (format: "json")', async () => {
48
+ d3.json.mockResolvedValue(mockData);
49
+
50
+ const wrapper = mount(<SimpleDataProvider format="json" url="test"><SimpleDataContextTestComponent /></SimpleDataProvider>);
51
+
52
+ await waitFor(() => expect(d3.json).toHaveBeenCalledTimes(1))
53
+
54
+ expect(wrapper.find('.data').text()).toEqual(JSON.stringify(mockData));
55
+ });
56
+
57
+ it('should retrieve data and provide the content of the key props.dataProperty on the retrieved data through simpleDataContext.data (format: "json")', async () => {
58
+ d3.json.mockResolvedValue(nestedMockData);
59
+
60
+ const wrapper = mount(<SimpleDataProvider format="json" data_property="data" url="test"><SimpleDataContextTestComponent /></SimpleDataProvider>);
61
+
62
+ await waitFor(() => expect(d3.json).toHaveBeenCalledTimes(1))
63
+
64
+ expect(wrapper.find('.data').text()).toEqual(JSON.stringify(mockData));
65
+ });
66
+
67
+
68
+ });
package/src/custom.d.tsx CHANGED
@@ -9,7 +9,7 @@ declare module "*.js" {
9
9
  export default content;
10
10
  }
11
11
 
12
- //declare module '@mapcomponents/react-core';
12
+ //declare module '../index';
13
13
  type MapContextType= {
14
14
  mapIds: [string?];
15
15
  mapExists: Function;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { MapComponentsProvider } from "@mapcomponents/react-core";
3
+ import { MapComponentsProvider } from "../index";
4
4
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
5
5
  import "./style.css";
6
6
  import { createTheme, ThemeProvider } from "@mui/material/styles";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { MapComponentsProvider } from "@mapcomponents/react-core";
3
+ import { MapComponentsProvider } from "../index";
4
4
 
5
5
  import MapLibreMap from "../components/MapLibreMap/MapLibreMap";
6
6
 
@@ -53,8 +53,7 @@ function useLayer(props: useLayerProps): useLayerType {
53
53
 
54
54
  const initializedRef = useRef<boolean>(false);
55
55
  const layerId = useRef(
56
- props.layerId ||
57
- (props.idPrefix ? props.idPrefix : "Layer-") + mapHook.componentId
56
+ props.layerId || (props.idPrefix ? props.idPrefix : "Layer-") + mapHook.componentId
58
57
  );
59
58
 
60
59
  const createLayer = useCallback(() => {
@@ -85,30 +84,15 @@ function useLayer(props: useLayerProps): useLayerType {
85
84
  setLayer(mapHook.map.map.getLayer(layerId.current));
86
85
 
87
86
  if (typeof props.onHover !== "undefined") {
88
- mapHook.map.on(
89
- "mousemove",
90
- layerId.current,
91
- props.onHover,
92
- mapHook.componentId
93
- );
87
+ mapHook.map.on("mousemove", layerId.current, props.onHover, mapHook.componentId);
94
88
  }
95
89
 
96
90
  if (typeof props.onClick !== "undefined") {
97
- mapHook.map.on(
98
- "click",
99
- layerId.current,
100
- props.onClick,
101
- mapHook.componentId
102
- );
91
+ mapHook.map.on("click", layerId.current, props.onClick, mapHook.componentId);
103
92
  }
104
93
 
105
94
  if (typeof props.onLeave !== "undefined") {
106
- mapHook.map.on(
107
- "mouseleave",
108
- layerId.current,
109
- props.onLeave,
110
- mapHook.componentId
111
- );
95
+ mapHook.map.on("mouseleave", layerId.current, props.onLeave, mapHook.componentId);
112
96
  }
113
97
 
114
98
  layerPaintConfRef.current = JSON.stringify(props.options?.paint);
@@ -140,22 +124,15 @@ function useLayer(props: useLayerProps): useLayerType {
140
124
  }, [mapHook.map, props.options, createLayer]);
141
125
 
142
126
  useEffect(() => {
143
- if (
144
- !initializedRef.current ||
145
- !mapHook?.map?.map.getSource(layerId.current)
146
- )
127
+ if (!initializedRef.current || !mapHook.map?.map?.getSource(layerId.current))
147
128
  return;
148
129
 
149
- // @ts-ignore
150
- mapHook.map.map.getSource(layerId.current).setData(props.geojson);
130
+ //@ts-ignore setData only exists on GeoJsonSource
131
+ mapHook.map.map.getSource(layerId.current)?.setData?.(props.geojson);
151
132
  }, [props.geojson, mapHook.map, props.options.type]);
152
133
 
153
134
  useEffect(() => {
154
- if (
155
- !mapHook.map ||
156
- !mapHook.map?.map?.getLayer?.(layerId.current) ||
157
- !initializedRef.current
158
- )
135
+ if (!mapHook.map || !mapHook.map?.map?.getLayer?.(layerId.current) || !initializedRef.current)
159
136
  return;
160
137
 
161
138
  var key;
@@ -165,15 +142,8 @@ function useLayer(props: useLayerProps): useLayerType {
165
142
  let oldLayout = JSON.parse(layerLayoutConfRef.current);
166
143
 
167
144
  for (key in props.options.layout) {
168
- if (
169
- props.options.layout?.[key] &&
170
- props.options.layout[key] !== oldLayout[key]
171
- ) {
172
- mapHook.map.map.setLayoutProperty(
173
- layerId.current,
174
- key,
175
- props.options.layout[key]
176
- );
145
+ if (props.options.layout?.[key] && props.options.layout[key] !== oldLayout[key]) {
146
+ mapHook.map.map.setLayoutProperty(layerId.current, key, props.options.layout[key]);
177
147
  }
178
148
  }
179
149
  layerLayoutConfRef.current = layoutString;
@@ -183,15 +153,8 @@ function useLayer(props: useLayerProps): useLayerType {
183
153
  if (paintString !== layerPaintConfRef.current) {
184
154
  let oldPaint = JSON.parse(layerPaintConfRef.current);
185
155
  for (key in props.options.paint) {
186
- if (
187
- props.options.paint?.[key] &&
188
- props.options.paint[key] !== oldPaint[key]
189
- ) {
190
- mapHook.map.map.setPaintProperty(
191
- layerId.current,
192
- key,
193
- props.options.paint[key]
194
- );
156
+ if (props.options.paint?.[key] && props.options.paint[key] !== oldPaint[key]) {
157
+ mapHook.map.map.setPaintProperty(layerId.current, key, props.options.paint[key]);
195
158
  }
196
159
  }
197
160
  layerPaintConfRef.current = paintString;