@defra/interactive-map 0.0.40-alpha → 0.0.41-alpha

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 (351) hide show
  1. package/dist/css/index.css +1 -1
  2. package/dist/esm/im-core.js +1 -1
  3. package/dist/esm/im-shell.js +1 -1
  4. package/dist/umd/im-core.js +1 -1
  5. package/dist/umd/index.js +1 -1
  6. package/docs/api/control-definition.md +9 -1
  7. package/docs/api/slots.md +26 -5
  8. package/docs/assets/images/slot-map.svg +61 -262
  9. package/docs/examples/draw-tools.mdx +3 -3
  10. package/docs/plugins/draw.md +79 -16
  11. package/docs/plugins/search.md +1 -1
  12. package/govuk-prototype-kit.config.json +2 -0
  13. package/jest.setup.js +5 -0
  14. package/package.json +9 -1
  15. package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
  16. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  17. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  18. package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
  19. package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
  20. package/plugins/beta/map-styles/dist/umd/index.js +1 -1
  21. package/plugins/datasets/dist/css/index.css +1 -1
  22. package/plugins/datasets/dist/esm/esriLayerAdapter.js +1 -1
  23. package/plugins/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
  24. package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
  25. package/plugins/datasets/dist/umd/im-datasets-esri-adapter.js +1 -1
  26. package/plugins/datasets/dist/umd/im-datasets-ml-adapter.js +1 -1
  27. package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
  28. package/plugins/datasets/dist/umd/index.js +1 -1
  29. package/plugins/datasets/src/adapters/esri/esriLayerAdapter.test.js +175 -0
  30. package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
  31. package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
  32. package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +14 -0
  33. package/plugins/datasets/src/api/setOpacity.test.js +9 -0
  34. package/plugins/datasets/src/components/LayersMenu/LayersMenu.jsx +10 -25
  35. package/plugins/datasets/src/components/LayersMenu/LayersMenu.test.jsx +0 -42
  36. package/plugins/datasets/src/datasets.scss +0 -1
  37. package/plugins/datasets/src/fetch/createDynamicSource.js +135 -129
  38. package/plugins/datasets/src/fetch/createDynamicSource.test.js +318 -0
  39. package/plugins/datasets/src/fetch/fetchGeoJSON.test.js +83 -0
  40. package/plugins/datasets/src/index.test.js +36 -0
  41. package/plugins/datasets/src/initialise/DatasetsInit.jsx +17 -7
  42. package/plugins/datasets/src/initialise/DatasetsInit.test.jsx +262 -0
  43. package/plugins/datasets/src/initialise/initialiseDatasets.js +16 -4
  44. package/plugins/datasets/src/initialise/initialiseDatasets.test.js +42 -0
  45. package/plugins/datasets/src/manifest.js +0 -38
  46. package/plugins/datasets/src/manifest.test.js +49 -0
  47. package/plugins/datasets/src/reducers/datasetsToMenu.test.js +54 -1
  48. package/plugins/datasets/src/reducers/pluginState.js +3 -16
  49. package/plugins/datasets/src/reducers/pluginState.test.js +23 -0
  50. package/plugins/datasets/src/registry/dataset.js +13 -1
  51. package/plugins/datasets/src/registry/dataset.test.js +61 -0
  52. package/plugins/datasets/src/registry/datasetRegistry.js +12 -6
  53. package/plugins/datasets/src/registry/datasetRegistry.test.js +16 -4
  54. package/plugins/datasets/src/registry/isVisibleWhen.js +6 -3
  55. package/plugins/datasets/src/registry/isVisibleWhen.test.js +11 -1
  56. package/plugins/datasets/src/utils/bbox.test.js +125 -0
  57. package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -1
  58. package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -1
  59. package/plugins/draw/dist/esm/im-draw-plugin.js +1 -1
  60. package/plugins/draw/dist/esm/index.js +1 -1
  61. package/plugins/draw/dist/umd/im-draw-ml-adapter.js +2 -1
  62. package/plugins/draw/dist/umd/im-draw-ml-adapter.js.LICENSE.txt +1 -0
  63. package/plugins/draw/dist/umd/im-draw-ol-adapter.js +1 -1
  64. package/plugins/draw/dist/umd/im-draw-plugin.js +1 -1
  65. package/plugins/draw/dist/umd/index.js +1 -1
  66. package/plugins/draw/src/DrawInit.jsx +10 -2
  67. package/plugins/draw/src/DrawInit.test.jsx +51 -10
  68. package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +91 -11
  69. package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +246 -4
  70. package/plugins/draw/src/adapters/maplibre/mapboxDraw.js +109 -14
  71. package/plugins/draw/src/adapters/maplibre/mapboxDraw.test.js +174 -11
  72. package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +12 -0
  73. package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +9 -1
  74. package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +24 -3
  75. package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.js +194 -0
  76. package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.test.js +457 -0
  77. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/__helpers__/harness.js +102 -0
  78. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.js +82 -0
  79. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.test.js +83 -0
  80. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.js +55 -0
  81. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.test.js +62 -0
  82. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.js +138 -0
  83. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.test.js +197 -0
  84. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.js +92 -0
  85. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.test.js +101 -0
  86. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.js +46 -0
  87. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.test.js +42 -0
  88. package/plugins/draw/src/adapters/maplibre/modes/editPointMode.js +151 -0
  89. package/plugins/draw/src/adapters/maplibre/modes/editPointMode.test.js +156 -0
  90. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +4 -27
  91. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +24 -39
  92. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +4 -5
  93. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +20 -23
  94. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +25 -5
  95. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +6 -36
  96. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +7 -49
  97. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +3 -53
  98. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +8 -33
  99. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +29 -72
  100. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +10 -3
  101. package/plugins/draw/src/adapters/maplibre/pointSymbolImages.js +158 -0
  102. package/plugins/draw/src/adapters/maplibre/pointSymbolImages.test.js +314 -0
  103. package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.js +6 -1
  104. package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.test.js +21 -0
  105. package/plugins/draw/src/adapters/maplibre/snap/snapInstance.js +6 -2
  106. package/plugins/draw/src/adapters/maplibre/snap/snapInstance.test.js +12 -0
  107. package/plugins/draw/src/adapters/maplibre/styles.js +38 -11
  108. package/plugins/draw/src/adapters/maplibre/styles.test.js +39 -0
  109. package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.js +79 -0
  110. package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.test.js +135 -0
  111. package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.js +42 -0
  112. package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.test.js +85 -0
  113. package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.js +34 -0
  114. package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.test.js +78 -0
  115. package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.js +16 -3
  116. package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.test.js +21 -3
  117. package/plugins/draw/src/adapters/maplibre/utils/snapMovement.js +59 -0
  118. package/plugins/draw/src/adapters/maplibre/utils/snapMovement.test.js +73 -0
  119. package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.js +33 -0
  120. package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.test.js +70 -0
  121. package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +27 -2
  122. package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +93 -0
  123. package/plugins/draw/src/adapters/openlayers/__helpers__/harness.js +9 -0
  124. package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +19 -1
  125. package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +34 -1
  126. package/plugins/draw/src/adapters/openlayers/core/styles.js +73 -1
  127. package/plugins/draw/src/adapters/openlayers/core/styles.test.js +122 -3
  128. package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +12 -0
  129. package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +8 -2
  130. package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +31 -0
  131. package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
  132. package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +33 -0
  133. package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.js +5 -3
  134. package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.test.js +11 -0
  135. package/plugins/draw/src/adapters/openlayers/edit/nudge.js +10 -3
  136. package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +24 -1
  137. package/plugins/draw/src/adapters/openlayers/edit/touchHandler.js +18 -13
  138. package/plugins/draw/src/adapters/openlayers/edit/touchHandler.test.js +46 -1
  139. package/plugins/draw/src/adapters/openlayers/olDraw.js +11 -4
  140. package/plugins/draw/src/adapters/openlayers/olDraw.test.js +48 -6
  141. package/plugins/draw/src/adapters/openlayers/point/drawPointMode.js +156 -0
  142. package/plugins/draw/src/adapters/openlayers/point/drawPointMode.test.js +246 -0
  143. package/plugins/draw/src/adapters/openlayers/point/editPointMode.js +267 -0
  144. package/plugins/draw/src/adapters/openlayers/point/editPointMode.test.js +327 -0
  145. package/plugins/draw/src/adapters/openlayers/point/pointDragInteraction.js +71 -0
  146. package/plugins/draw/src/adapters/openlayers/point/pointOps.js +34 -0
  147. package/plugins/draw/src/adapters/openlayers/point/pointOps.test.js +32 -0
  148. package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.js +82 -0
  149. package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.test.js +107 -0
  150. package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.js +83 -0
  151. package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.test.js +214 -0
  152. package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.js +3 -1
  153. package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.js +6 -9
  154. package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.test.js +15 -4
  155. package/plugins/draw/src/adapters/openlayers/utils/olCoords.js +1 -1
  156. package/plugins/draw/src/api/addFeature.js +16 -1
  157. package/plugins/draw/src/api/addFeature.test.js +62 -5
  158. package/plugins/draw/src/api/editFeature.js +7 -4
  159. package/plugins/draw/src/api/editFeature.test.js +16 -0
  160. package/plugins/draw/src/api/newPoint.js +42 -0
  161. package/plugins/draw/src/api/newPoint.test.js +117 -0
  162. package/plugins/draw/src/api/setStyle.js +43 -0
  163. package/plugins/draw/src/api/setStyle.test.js +75 -0
  164. package/plugins/draw/src/events.js +17 -10
  165. package/plugins/draw/src/events.test.js +14 -0
  166. package/plugins/draw/src/manifest.js +18 -6
  167. package/plugins/draw/src/manifest.test.js +32 -1
  168. package/plugins/draw/src/reducer.test.js +7 -0
  169. package/plugins/draw/src/utils/stripInternalProperties.js +19 -0
  170. package/plugins/draw/src/utils/stripInternalProperties.test.js +50 -0
  171. package/plugins/draw/src/utils/symbolKeys.js +5 -0
  172. package/plugins/draw/src/validation/liveDrawChecks.test.js +54 -0
  173. package/plugins/draw/src/validation/liveStroke.test.js +64 -1
  174. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  175. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  176. package/plugins/interact/dist/umd/index.js +1 -1
  177. package/plugins/interact/src/hooks/useHighlightSync.js +33 -12
  178. package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
  179. package/plugins/interact/src/utils/featureQueries.js +18 -0
  180. package/plugins/interact/src/utils/featureQueries.test.js +15 -0
  181. package/plugins/interact/src/utils/spatial.js +9 -3
  182. package/plugins/interact/src/utils/spatial.test.js +12 -1
  183. package/plugins/map-key/dist/css/index.css +62 -0
  184. package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -0
  185. package/plugins/map-key/dist/esm/index.js +1 -0
  186. package/plugins/map-key/dist/umd/im-map-key-plugin.js +2 -0
  187. package/plugins/map-key/dist/umd/im-map-key-plugin.js.LICENSE.txt +1 -0
  188. package/plugins/map-key/dist/umd/index.js +2 -0
  189. package/plugins/map-key/dist/umd/index.js.LICENSE.txt +1 -0
  190. package/plugins/map-key/package.json +28 -0
  191. package/plugins/map-key/src/components/Key/EmptyKey.jsx +7 -0
  192. package/plugins/{datasets → map-key}/src/components/Key/EmptyKey.test.jsx +2 -2
  193. package/plugins/map-key/src/components/Key/Key.jsx +41 -0
  194. package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +15 -14
  195. package/plugins/map-key/src/components/Key/Key.test.jsx +73 -0
  196. package/plugins/map-key/src/components/Key/KeyGroupItem.jsx +16 -0
  197. package/plugins/map-key/src/components/Key/KeyGroupItem.test.jsx +53 -0
  198. package/plugins/map-key/src/components/Key/KeyItem.jsx +29 -0
  199. package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
  200. package/plugins/map-key/src/components/Key/KeySvg.jsx +42 -0
  201. package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
  202. package/plugins/map-key/src/components/Key/KeySvgLine.jsx +28 -0
  203. package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
  204. package/plugins/map-key/src/components/Key/KeySvgPattern.jsx +23 -0
  205. package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +2 -2
  206. package/plugins/map-key/src/components/Key/KeySvgRect.jsx +33 -0
  207. package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
  208. package/plugins/map-key/src/components/Key/KeySvgSymbol.jsx +27 -0
  209. package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +5 -6
  210. package/plugins/map-key/src/components/Key/MapKey.jsx +50 -0
  211. package/plugins/map-key/src/components/Key/MapKey.test.jsx +130 -0
  212. package/plugins/{datasets → map-key}/src/components/Key/svgProperties.js +2 -2
  213. package/plugins/{datasets → map-key}/src/components/Key/svgProperties.test.js +2 -2
  214. package/plugins/map-key/src/index.js +13 -0
  215. package/plugins/map-key/src/index.test.js +31 -0
  216. package/plugins/map-key/src/initialise/MapKeyInit.jsx +15 -0
  217. package/plugins/map-key/src/initialise/MapKeyInit.test.jsx +39 -0
  218. package/plugins/map-key/src/manifest.js +30 -0
  219. package/plugins/map-key/src/manifest.test.js +63 -0
  220. package/plugins/map-key/src/mapKey.scss +4 -0
  221. package/plugins/map-key/src/registry/getDatasetRegistry.js +6 -0
  222. package/plugins/map-key/src/registry/getDatasetRegistry.test.js +23 -0
  223. package/plugins/map-key/src/registry/index.js +3 -0
  224. package/plugins/map-key/src/registry/index.test.js +15 -0
  225. package/plugins/menu/dist/css/index.css +80 -0
  226. package/plugins/menu/dist/esm/im-menu-plugin.js +1 -0
  227. package/plugins/menu/dist/esm/index.js +1 -0
  228. package/plugins/menu/dist/umd/im-menu-plugin.js +1 -0
  229. package/plugins/menu/dist/umd/index.js +2 -0
  230. package/plugins/menu/dist/umd/index.js.LICENSE.txt +1 -0
  231. package/plugins/menu/package.json +28 -0
  232. package/plugins/menu/src/components/Menu/CheckboxGroupWrapper.jsx +21 -0
  233. package/plugins/menu/src/components/Menu/GroupLegend.jsx +17 -0
  234. package/plugins/menu/src/components/Menu/GroupLegend.test.jsx +68 -0
  235. package/plugins/menu/src/components/Menu/Menu.jsx +19 -0
  236. package/plugins/menu/src/components/Menu/Menu.module.scss +90 -0
  237. package/plugins/menu/src/components/Menu/Menu.test.jsx +161 -0
  238. package/plugins/menu/src/components/Menu/MenuCheckbox.jsx +35 -0
  239. package/plugins/menu/src/components/Menu/MenuCheckbox.test.jsx +93 -0
  240. package/plugins/menu/src/components/Menu/MenuGroup.jsx +11 -0
  241. package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.jsx → menu/src/components/Menu/MenuRadio.jsx} +6 -4
  242. package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.test.jsx → menu/src/components/Menu/MenuRadio.test.jsx} +18 -18
  243. package/plugins/menu/src/components/Menu/RadioGroupWrapper.jsx +32 -0
  244. package/plugins/{datasets/src/components/LayersMenu/LayersRadioGroupWrapper.test.jsx → menu/src/components/Menu/RadioGroupWrapper.test.jsx} +21 -21
  245. package/plugins/menu/src/components/Menu/useIdPrefix.jsx +4 -0
  246. package/plugins/menu/src/index.js +13 -0
  247. package/plugins/menu/src/index.test.js +31 -0
  248. package/plugins/menu/src/initialise/MenuInit.jsx +24 -0
  249. package/plugins/menu/src/initialise/MenuInit.test.jsx +50 -0
  250. package/plugins/menu/src/initialise/createMenu.js +10 -0
  251. package/plugins/menu/src/initialise/createMenu.test.js +37 -0
  252. package/plugins/menu/src/manifest.js +35 -0
  253. package/plugins/menu/src/manifest.test.js +63 -0
  254. package/plugins/menu/src/menu.scss +4 -0
  255. package/plugins/menu/src/reducers/menuStateReducer.test.js +38 -0
  256. package/plugins/menu/src/reducers/pluginState.js +35 -0
  257. package/plugins/menu/src/reducers/pluginState.test.js +57 -0
  258. package/plugins/menu/src/registry/getDatasetRegistry.js +9 -0
  259. package/plugins/menu/src/registry/getDatasetRegistry.test.js +23 -0
  260. package/plugins/menu/src/registry/index.js +3 -0
  261. package/plugins/menu/src/registry/index.test.js +15 -0
  262. package/plugins/menu/src/registry/isVisibleWhen.js +43 -0
  263. package/plugins/menu/src/registry/isVisibleWhen.test.js +48 -0
  264. package/plugins/search/dist/css/index.css +1 -1
  265. package/plugins/search/dist/esm/im-search-plugin.js +1 -1
  266. package/plugins/search/dist/esm/index.js +1 -1
  267. package/plugins/search/dist/umd/im-search-plugin.js +1 -1
  268. package/plugins/search/dist/umd/index.js +1 -1
  269. package/plugins/search/src/Search.jsx +2 -3
  270. package/plugins/search/src/components/Form/Form.module.scss +9 -20
  271. package/plugins/search/src/index.js +0 -1
  272. package/plugins/search/src/index.test.js +2 -4
  273. package/plugins/search/src/manifest.js +1 -1
  274. package/plugins/search/src/search.scss +17 -16
  275. package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
  276. package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
  277. package/providers/beta/openlayers/dist/umd/index.js +1 -1
  278. package/providers/beta/openlayers/src/openlayersProvider.js +4 -1
  279. package/providers/beta/openlayers/src/openlayersProvider.test.js +18 -0
  280. package/providers/beta/openlayers/src/utils/highlightFeatures.js +52 -5
  281. package/providers/beta/openlayers/src/utils/highlightFeatures.test.js +176 -0
  282. package/providers/beta/openlayers/src/utils/symbolImages.js +40 -0
  283. package/providers/beta/openlayers/src/utils/symbolImages.test.js +58 -0
  284. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  285. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  286. package/providers/maplibre/dist/umd/index.js +1 -1
  287. package/providers/maplibre/src/utils/drawLayerBuckets.js +14 -0
  288. package/providers/maplibre/src/utils/drawLayerBuckets.test.js +18 -0
  289. package/providers/maplibre/src/utils/highlightFeatures.js +80 -55
  290. package/providers/maplibre/src/utils/highlightFeatures.test.js +156 -17
  291. package/providers/maplibre/src/utils/hoverCursor.js +30 -14
  292. package/providers/maplibre/src/utils/hoverCursor.test.js +35 -0
  293. package/providers/maplibre/src/utils/patternImages.js +1 -1
  294. package/providers/maplibre/src/utils/symbolImages.js +41 -3
  295. package/providers/maplibre/src/utils/symbolImages.test.js +40 -6
  296. package/rollup.esm.mjs +11 -1
  297. package/src/App/components/Actions/Actions.test.jsx +47 -0
  298. package/src/App/components/Hints/Hints.test.jsx +13 -0
  299. package/src/App/components/MoveControls/MoveControls.module.scss +41 -10
  300. package/src/App/components/Panel/Panel.jsx +18 -3
  301. package/src/App/components/Panel/Panel.module.scss +18 -8
  302. package/src/App/components/Panel/Panel.test.jsx +34 -0
  303. package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
  304. package/src/App/hooks/useFeatureItems.js +16 -7
  305. package/src/App/hooks/useFeatureItems.test.js +57 -0
  306. package/src/App/hooks/useLayoutMeasurements.js +95 -84
  307. package/src/App/hooks/useLayoutMeasurements.test.js +61 -1
  308. package/src/App/layout/Layout.jsx +9 -10
  309. package/src/App/layout/Layout.test.jsx +2 -0
  310. package/src/App/layout/layout.module.scss +31 -17
  311. package/src/App/registry/pluginRegistry.js +1 -1
  312. package/src/App/registry/pluginRegistry.test.js +12 -0
  313. package/src/App/renderer/HtmlElementHost.jsx +18 -5
  314. package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
  315. package/src/App/renderer/mapButtons.js +28 -12
  316. package/src/App/renderer/mapButtons.test.js +17 -4
  317. package/src/App/renderer/mapControls.js +3 -1
  318. package/src/App/renderer/mapControls.test.js +16 -0
  319. package/src/App/renderer/mapPanels.js +44 -9
  320. package/src/App/renderer/mapPanels.test.js +51 -2
  321. package/src/App/renderer/orderItems.js +28 -0
  322. package/src/App/renderer/orderItems.test.js +50 -0
  323. package/src/App/renderer/slotAggregator.js +2 -18
  324. package/src/App/renderer/slotHelpers.js +3 -1
  325. package/src/App/renderer/slotHelpers.test.js +5 -0
  326. package/src/App/renderer/slots.js +3 -0
  327. package/src/App/store/AppProvider.jsx +1 -0
  328. package/src/App/store/appDispatchMiddleware.js +1 -1
  329. package/src/App/store/appDispatchMiddleware.test.js +8 -0
  330. package/src/config/events.js +2 -0
  331. package/src/scss/settings/_colors.scss +1 -0
  332. package/src/scss/settings/_dimensions.scss +2 -3
  333. package/src/scss/settings/_transition.scss +1 -1
  334. package/src/services/eventBus.js +44 -0
  335. package/src/services/eventBus.test.js +83 -0
  336. package/src/services/symbolRegistry.js +1 -1
  337. package/src/types.js +11 -1
  338. package/webpack.umd.mjs +2 -0
  339. package/plugins/datasets/src/components/Key/EmptyKey.jsx +0 -7
  340. package/plugins/datasets/src/components/Key/Key.jsx +0 -50
  341. package/plugins/datasets/src/components/Key/KeyGroupItem.jsx +0 -18
  342. package/plugins/datasets/src/components/Key/KeyItem.jsx +0 -23
  343. package/plugins/datasets/src/components/Key/KeySvg.jsx +0 -22
  344. package/plugins/datasets/src/components/Key/KeySvgLine.jsx +0 -19
  345. package/plugins/datasets/src/components/Key/KeySvgPattern.jsx +0 -13
  346. package/plugins/datasets/src/components/Key/KeySvgRect.jsx +0 -22
  347. package/plugins/datasets/src/components/Key/KeySvgSymbol.jsx +0 -16
  348. package/plugins/datasets/src/components/LayersMenu/LayersRadioGroupWrapper.jsx +0 -41
  349. /package/plugins/{datasets → menu}/src/reducers/menuStateReducer.js +0 -0
  350. /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.js +0 -0
  351. /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.test.js +0 -0
@@ -175,6 +175,89 @@ describe('emitWhenReady', () => {
175
175
  })
176
176
  })
177
177
 
178
+ describe('emitWhenRequested', () => {
179
+ let bus
180
+ beforeEach(() => { bus = createEventBus() })
181
+
182
+ it('immediately emits eventNameReady so an already-waiting listener receives the args', () => {
183
+ const handler = jest.fn()
184
+ bus.on('datasets:registryReady', handler)
185
+ bus.emitWhenRequested('datasets:registry', 'registryValue')
186
+ expect(handler).toHaveBeenCalledWith('registryValue')
187
+ })
188
+
189
+ it('emits eventNameReady with args whenever eventNameRequested fires after registration', () => {
190
+ const handler = jest.fn()
191
+ bus.on('datasets:registryReady', handler)
192
+ bus.emitWhenRequested('datasets:registry', 'registryValue')
193
+ handler.mockClear()
194
+ bus.emit('datasets:registryRequested')
195
+ expect(handler).toHaveBeenCalledWith('registryValue')
196
+ })
197
+
198
+ it('forwards multiple args to the Ready event', () => {
199
+ const handler = jest.fn()
200
+ bus.on('datasets:registryReady', handler)
201
+ bus.emitWhenRequested('datasets:registry', 'a', 'b')
202
+ expect(handler).toHaveBeenCalledWith('a', 'b')
203
+ })
204
+
205
+ it('returns a cleanup function that stops responding to future Requested events', () => {
206
+ const handler = jest.fn()
207
+ bus.on('datasets:registryReady', handler)
208
+ const remove = bus.emitWhenRequested('datasets:registry', 'registryValue')
209
+ handler.mockClear()
210
+ remove()
211
+ bus.emit('datasets:registryRequested')
212
+ expect(handler).not.toHaveBeenCalled()
213
+ })
214
+ })
215
+
216
+ describe('requestOnce', () => {
217
+ let bus
218
+ beforeEach(() => { bus = createEventBus() })
219
+
220
+ it('calls the handler when eventNameReady fires', () => {
221
+ const handler = jest.fn()
222
+ bus.requestOnce('datasets:registry', handler)
223
+ bus.emit('datasets:registryReady', 'registryValue')
224
+ expect(handler).toHaveBeenCalledWith('registryValue')
225
+ })
226
+
227
+ it('calls the handler only once even if eventNameReady fires multiple times', () => {
228
+ const handler = jest.fn()
229
+ bus.requestOnce('datasets:registry', handler)
230
+ bus.emit('datasets:registryReady', 'first')
231
+ bus.emit('datasets:registryReady', 'second')
232
+ expect(handler).toHaveBeenCalledTimes(1)
233
+ })
234
+
235
+ it('emits eventNameRequested so the provider side knows it is needed', () => {
236
+ const requestedHandler = jest.fn()
237
+ bus.on('datasets:registryRequested', requestedHandler)
238
+ bus.requestOnce('datasets:registry', jest.fn())
239
+ expect(requestedHandler).toHaveBeenCalled()
240
+ })
241
+
242
+ it('returns this for chaining', () => {
243
+ expect(bus.requestOnce('datasets:registry', jest.fn())).toBe(bus)
244
+ })
245
+
246
+ it('works with emitWhenRequested when requestOnce is called first', () => {
247
+ const handler = jest.fn()
248
+ bus.requestOnce('datasets:registry', handler)
249
+ bus.emitWhenRequested('datasets:registry', 'registryValue')
250
+ expect(handler).toHaveBeenCalledWith('registryValue')
251
+ })
252
+
253
+ it('works with emitWhenRequested when emitWhenRequested is called first', () => {
254
+ const handler = jest.fn()
255
+ bus.emitWhenRequested('datasets:registry', 'registryValue')
256
+ bus.requestOnce('datasets:registry', handler)
257
+ expect(handler).toHaveBeenCalledWith('registryValue')
258
+ })
259
+ })
260
+
178
261
  describe('createEventBus factory', () => {
179
262
  /**
180
263
  * Test to ensure coverage for the factory function (Line 50).
@@ -2,7 +2,7 @@ import { getValueForStyle } from '../utils/getValueForStyle.js'
2
2
  import { symbolDefaults, pin, circle, square, graphics } from '../config/symbolConfig.js'
3
3
  import { getSymbolStyleColors, getSymbolViewBox } from '../utils/symbolUtils.js'
4
4
  import { THEME_COLORS } from '../config/mapTheme.js'
5
- import { rasteriseToImageData } from '../../providers/maplibre/src/utils/rasteriseToImageData.js'
5
+ import { rasteriseToImageData } from '../utils/rasteriseToImageData.js'
6
6
 
7
7
  const symbols = new Map()
8
8
  // Module-level cache: imageId → ImageData. Avoids re-rasterising identical symbols.
package/src/types.js CHANGED
@@ -28,8 +28,18 @@
28
28
  *
29
29
  * @typedef {Object} ControlBreakpointConfig
30
30
  *
31
+ * @property {number} [order]
32
+ * The order the control appears within its slot (or, when targeting a panel, within that
33
+ * panel's body — see `slot` below).
34
+ *
31
35
  * @property {string} slot
32
- * Slot identifier.
36
+ * Slot identifier. In addition to the standard layout slots, a control may target a panel's
37
+ * body directly by setting this to `'<panelId>-panel'` (the panel id in kebab-case, suffixed
38
+ * with `-panel` — mirrors the `'<buttonId>-button'` convention panels use to render next to a
39
+ * specific button). Any plugin may target any panel this way, including one registered by a
40
+ * different plugin. The panel's own content and every control targeting it are ordered together
41
+ * via `order`. Only supported by panels with a `render` component — a panel using static `html`
42
+ * can't host injected controls, since `dangerouslySetInnerHTML` owns its body's children.
33
43
  */
34
44
 
35
45
  /**
package/webpack.umd.mjs CHANGED
@@ -145,6 +145,8 @@ const ALL_BUILDS = [
145
145
  { entryPath: './plugins/search/src/index.js', libraryPath: 'searchPlugin', outDir: 'plugins/search/dist/umd' },
146
146
  { entryPath: './plugins/interact/src/index.js', libraryPath: 'interactPlugin', outDir: 'plugins/interact/dist/umd' },
147
147
  { entryPath: './plugins/datasets/src/index.js', libraryPath: 'datasetsPlugin', outDir: 'plugins/datasets/dist/umd', cssOutDir: 'plugins/datasets/dist' },
148
+ { entryPath: './plugins/map-key/src/index.js', libraryPath: 'mapKeyPlugin', outDir: 'plugins/map-key/dist/umd', cssOutDir: 'plugins/map-key/dist' },
149
+ { entryPath: './plugins/menu/src/index.js', libraryPath: 'menuPlugin', outDir: 'plugins/menu/dist/umd', cssOutDir: 'plugins/menu/dist' },
148
150
  { entryPath: './plugins/beta/map-styles/src/index.js', libraryPath: 'mapStylesPlugin', outDir: 'plugins/beta/map-styles/dist/umd' },
149
151
  { entryPath: './plugins/draw/src/index.js', libraryPath: 'drawPlugin', outDir: 'plugins/draw/dist/umd' },
150
152
  { entryPath: './plugins/beta/draw-ml/src/index.js', libraryPath: 'drawMLPlugin', outDir: 'plugins/beta/draw-ml/dist/umd' },
@@ -1,7 +0,0 @@
1
- export const EmptyKey = ({ text }) => {
2
- return (
3
- <div className='im-c-datasets-key'>
4
- <p className='im-c-datasets-key__empty-message'>{text}</p>
5
- </div>
6
- )
7
- }
@@ -1,50 +0,0 @@
1
- import React from 'react'
2
- import { EmptyKey } from './EmptyKey.jsx'
3
- import { KeyItem } from './KeyItem.jsx'
4
- import { KeyGroupItem } from './KeyGroupItem.jsx'
5
- import { datasetRegistry } from '../../registry/datasetRegistry.js'
6
-
7
- export const Key = ({
8
- pluginConfig: { noKeyItemText },
9
- mapState: { mapStyle },
10
- services: { symbolRegistry, patternRegistry }
11
- }) => {
12
- const { items: keyGroups, hasGroups } = datasetRegistry.keyItems()
13
-
14
- if (!keyGroups?.length) {
15
- return (<EmptyKey text={noKeyItemText} />)
16
- }
17
-
18
- const containerClass = `im-c-datasets-key${hasGroups ? ' im-c-datasets-key--has-groups' : ''}`
19
- return (
20
- <div className={containerClass}>{keyGroups.map(item => {
21
- const key = item.type === 'group' ? item.groupLabel.toLowerCase().replaceAll(/\s+/g, '-') : item.dataset.id
22
-
23
- if (item.type === 'sublayers' || item.type === 'group') {
24
- const datasets = item.type === 'sublayers' ? item.sublayers : item.datasets
25
- const label = item.type === 'sublayers' ? item.dataset.label : item.groupLabel
26
- return (
27
- <KeyGroupItem
28
- key={key}
29
- headingId={`key-heading-${key}`}
30
- label={label}
31
- datasets={datasets}
32
- symbolRegistry={symbolRegistry}
33
- patternRegistry={patternRegistry}
34
- mapStyle={mapStyle}
35
- />
36
- )
37
- }
38
- return (
39
- <KeyItem
40
- key={key}
41
- registryDataset={item.dataset}
42
- symbolRegistry={symbolRegistry}
43
- patternRegistry={patternRegistry}
44
- mapStyle={mapStyle}
45
- />
46
- )
47
- })}
48
- </div>
49
- )
50
- }
@@ -1,18 +0,0 @@
1
- import { KeyItem } from './KeyItem.jsx'
2
-
3
- export const KeyGroupItem = ({ headingId, label, datasets, symbolRegistry, patternRegistry, mapStyle }) => {
4
- return (
5
- <section className='im-c-datasets-key__group' aria-labelledby={headingId}>
6
- <h3 id={headingId} className='im-c-datasets-key__group-heading'>{label}</h3>
7
- {datasets.map(dataset =>
8
- <KeyItem
9
- key={`${dataset.id}`}
10
- registryDataset={dataset}
11
- symbolRegistry={symbolRegistry}
12
- patternRegistry={patternRegistry}
13
- mapStyle={mapStyle}
14
- />
15
- )}
16
- </section>
17
- )
18
- }
@@ -1,23 +0,0 @@
1
- import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
2
- import { KeySvg } from './KeySvg.jsx'
3
-
4
- export const KeyItem = ({ registryDataset, symbolRegistry, patternRegistry, mapStyle }) => {
5
- if (!registryDataset.showInKey) {
6
- return null
7
- }
8
- return (
9
- <dl className='im-c-datasets-key__item'>
10
- <dt className='im-c-datasets-key__item-symbol'>
11
- <KeySvg registryDataset={registryDataset} symbolRegistry={symbolRegistry} patternRegistry={patternRegistry} mapStyle={mapStyle} />
12
- </dt>
13
- <dd className='im-c-datasets-key__item-label'>
14
- {registryDataset.label}
15
- {registryDataset.symbolDescription && (
16
- <span className='govuk-visually-hidden'>
17
- ({getValueForStyle(registryDataset.symbolDescription, mapStyle.id)})
18
- </span>
19
- )}
20
- </dd>
21
- </dl>
22
- )
23
- }
@@ -1,22 +0,0 @@
1
- import { KeySvgPattern } from './KeySvgPattern.jsx'
2
- import { KeySvgSymbol } from './KeySvgSymbol.jsx'
3
- import { KeySvgLine } from './KeySvgLine.jsx'
4
- import { KeySvgRect } from './KeySvgRect.jsx'
5
-
6
- export const KeySvg = ({ symbolRegistry, registryDataset, mapStyle, patternRegistry }) => {
7
- const { hasSymbol, hasPattern, style } = registryDataset
8
- const symbolDef = hasSymbol && symbolRegistry.getSymbolDef(style)
9
- if (symbolDef) {
10
- return <KeySvgSymbol mapStyle={mapStyle} registryDataset={registryDataset} symbolRegistry={symbolRegistry} symbolDef={symbolDef} />
11
- }
12
-
13
- if (hasPattern) {
14
- return <KeySvgPattern mapStyle={mapStyle} registryDataset={registryDataset} patternRegistry={patternRegistry} />
15
- }
16
-
17
- if (style.keySymbolShape === 'line') {
18
- return <KeySvgLine mapStyle={mapStyle} registryDataset={registryDataset} />
19
- }
20
-
21
- return <KeySvgRect mapStyle={mapStyle} registryDataset={registryDataset} />
22
- }
@@ -1,19 +0,0 @@
1
- import { svgProps, SVG_SIZE, SVG_CENTER } from './svgProperties.js'
2
- import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
3
-
4
- export const KeySvgLine = ({ mapStyle, registryDataset }) => {
5
- const { style } = registryDataset
6
- return (
7
- <svg {...svgProps}>
8
- <line
9
- x1={style.strokeWidth / 2}
10
- y1={SVG_CENTER}
11
- x2={SVG_SIZE - style.strokeWidth / 2}
12
- y2={SVG_CENTER}
13
- stroke={getValueForStyle(style.stroke, mapStyle.id)}
14
- strokeWidth={style.strokeWidth}
15
- strokeLinecap='round'
16
- />
17
- </svg>
18
- )
19
- }
@@ -1,13 +0,0 @@
1
- import { svgProps } from './svgProperties.js'
2
- const PATTERN_INSET = 2
3
-
4
- export const KeySvgPattern = ({ patternRegistry, registryDataset, mapStyle }) => {
5
- const { style } = registryDataset
6
- const paths = patternRegistry.getKeyPatternPaths(style, mapStyle.id)
7
- return (
8
- <svg {...svgProps}>
9
- <g dangerouslySetInnerHTML={{ __html: paths.border }} />
10
- <g transform={`translate(${PATTERN_INSET}, ${PATTERN_INSET})`} dangerouslySetInnerHTML={{ __html: paths.content }} />
11
- </svg>
12
- )
13
- }
@@ -1,22 +0,0 @@
1
- import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
2
- import { svgProps, SVG_SIZE } from './svgProperties.js'
3
-
4
- export const KeySvgRect = ({ mapStyle, registryDataset }) => {
5
- const { style } = registryDataset
6
- return (
7
- <svg {...svgProps}>
8
- <rect
9
- x={style.strokeWidth / 2}
10
- y={style.strokeWidth / 2}
11
- width={SVG_SIZE - style.strokeWidth}
12
- height={SVG_SIZE - style.strokeWidth}
13
- rx={style.strokeWidth}
14
- ry={style.strokeWidth}
15
- fill={getValueForStyle(style.fill, mapStyle.id)}
16
- stroke={getValueForStyle(style.stroke, mapStyle.id)}
17
- strokeWidth={style.strokeWidth}
18
- strokeLinejoin='round'
19
- />
20
- </svg>
21
- )
22
- }
@@ -1,16 +0,0 @@
1
- import { getSymbolStyleColors, getSymbolViewBox } from '../../../../../src/utils/symbolUtils.js'
2
- import { svgSymbolProps } from './svgProperties.js'
3
-
4
- export const KeySvgSymbol = ({ symbolRegistry, registryDataset, mapStyle, symbolDef }) => {
5
- const { style } = registryDataset
6
- const mapColorScheme = mapStyle?.appColorScheme ?? 'light'
7
- const keyMapStyle = { ...mapStyle, mapColorScheme }
8
-
9
- const resolvedSvg = symbolRegistry.resolve(symbolDef, getSymbolStyleColors(style), keyMapStyle)
10
- const viewBox = getSymbolViewBox(style, symbolDef)
11
- return (
12
- <svg {...svgSymbolProps} viewBox={viewBox}>
13
- <g dangerouslySetInnerHTML={{ __html: resolvedSvg }} />
14
- </svg>
15
- )
16
- }
@@ -1,41 +0,0 @@
1
- import React from 'react'
2
- import { isVisibleWhen } from '../../registry/isVisibleWhen.js'
3
- import { LayersMenuRadio } from './LayersMenuRadio.jsx'
4
-
5
- export const LayersRadioGroupWrapper = ({ pluginState, menuGroup }) => {
6
- const { id, items, visibleWhen } = menuGroup
7
- const visible = visibleWhen ? isVisibleWhen(visibleWhen) : true
8
- if (!visible) {
9
- return null
10
- }
11
-
12
- const { menuState, dispatch } = pluginState
13
- const value = menuState[id]
14
- const handleChange = (event) => {
15
- dispatch({ type: 'UPDATE_MENU_STATE', payload: { [id]: event.target.value } })
16
- }
17
-
18
- const wrapperClass = 'govuk-form-group im-c-datasets-layers-group'
19
- return (
20
- <div key={menuGroup.id} className={wrapperClass}>
21
- <fieldset className='im-c-datasets-layers-group__fieldset'>
22
- <legend className='im-c-datasets-layers-group__legend'>
23
- <h3>
24
- {menuGroup.label}
25
- </h3>
26
- </legend>
27
- <div className='govuk-radios govuk-radios--small' data-module='govuk-radios'>
28
- {items.map((menuGroupItem) =>
29
- <LayersMenuRadio
30
- key={menuGroupItem.id}
31
- menuGroupItem={menuGroupItem}
32
- name={id}
33
- checked={menuGroupItem.id === value}
34
- onChange={handleChange}
35
- />
36
- )}
37
- </div>
38
- </fieldset>
39
- </div>
40
- )
41
- }