@defra/interactive-map 0.0.43-fmp-experimental → 0.0.45-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 (297) hide show
  1. package/assets/templates/add-polygons.njk +11 -7
  2. package/assets/templates/add-symbols.njk +5 -1
  3. package/assets/templates/select-feature.njk +72 -15
  4. package/dist/css/index.css +1 -1
  5. package/dist/esm/im-core.js +1 -1
  6. package/dist/esm/im-shell.js +1 -1
  7. package/dist/umd/im-core.js +1 -1
  8. package/dist/umd/index.js +1 -1
  9. package/docs/api/context.md +24 -0
  10. package/docs/api/keyboard-shortcut-definition.md +102 -0
  11. package/docs/api.md +18 -8
  12. package/docs/building-a-plugin.md +1 -0
  13. package/docs/examples/add-marker-with-panel.mdx +4 -0
  14. package/docs/examples/add-polygons.mdx +16 -12
  15. package/docs/examples/add-symbols.mdx +4 -0
  16. package/docs/examples/basic-map.mdx +4 -0
  17. package/docs/examples/button-map.mdx +4 -0
  18. package/docs/examples/draw-tools.mdx +4 -0
  19. package/docs/examples/place-marker.mdx +4 -0
  20. package/docs/examples/search-control.mdx +4 -0
  21. package/docs/examples/select-feature.mdx +4 -0
  22. package/docs/examples/style-switcher.mdx +36 -44
  23. package/docs/examples/toggle-marker-label.mdx +4 -0
  24. package/docs/plugins/draw.md +2 -2
  25. package/docs/plugins/plugin-manifest.md +9 -0
  26. package/package.json +4 -2
  27. package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
  28. package/plugins/beta/draw-es/src/api/newPolygon.js +1 -0
  29. package/plugins/beta/draw-es/src/events.js +17 -8
  30. package/plugins/beta/draw-es/src/reducer.js +8 -1
  31. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  32. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  33. package/plugins/beta/draw-ol/dist/css/index.css +1 -13
  34. package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
  35. package/plugins/beta/frame/dist/css/index.css +1 -11
  36. package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -1
  37. package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -1
  38. package/plugins/beta/frame/src/Frame.jsx +28 -2
  39. package/plugins/beta/map-styles/dist/css/index.css +1 -1
  40. package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
  41. package/plugins/beta/map-styles/dist/umd/index.js +1 -1
  42. package/plugins/beta/scale-bar/dist/css/index.css +1 -8
  43. package/plugins/datasets/dist/css/5648.index.css +1 -5
  44. package/plugins/datasets/dist/css/index.css +1 -1
  45. package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
  46. package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
  47. package/plugins/datasets/src/components/LayersMenu/Layers.module.scss +1 -0
  48. package/plugins/datasets/src/initialise/DatasetsInit.jsx +2 -2
  49. package/plugins/datasets/src/initialise/DatasetsInit.test.jsx +6 -5
  50. package/plugins/datasets/src/registry/dataset.js +8 -12
  51. package/plugins/datasets/src/registry/dataset.test.js +17 -0
  52. package/plugins/datasets/src/registry/datasetRegistry.js +4 -5
  53. package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -1
  54. package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -1
  55. package/plugins/draw/dist/esm/im-draw-plugin.js +1 -1
  56. package/plugins/draw/dist/esm/index.js +1 -1
  57. package/plugins/draw/dist/umd/im-draw-ml-adapter.js +1 -1
  58. package/plugins/draw/dist/umd/im-draw-ol-adapter.js +1 -1
  59. package/plugins/draw/dist/umd/im-draw-plugin.js +1 -1
  60. package/plugins/draw/dist/umd/index.js +1 -1
  61. package/plugins/draw/src/DrawInit.jsx +41 -26
  62. package/plugins/draw/src/DrawInit.test.jsx +55 -12
  63. package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +113 -114
  64. package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +82 -9
  65. package/plugins/draw/src/adapters/maplibre/drawEvents.js +3 -1
  66. package/plugins/draw/src/adapters/maplibre/modes/createDrawMode.test.js +1 -1
  67. package/plugins/draw/src/adapters/maplibre/modes/drawMode/__helpers__/harness.js +18 -9
  68. package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.js +9 -1
  69. package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +11 -1
  70. package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +23 -2
  71. package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +53 -0
  72. package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.js +29 -19
  73. package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.test.js +17 -2
  74. package/plugins/draw/src/adapters/maplibre/modes/drawMode/undoHandlers.test.js +1 -1
  75. package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.js +35 -29
  76. package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.test.js +24 -6
  77. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.js +22 -20
  78. package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.js +1 -1
  79. package/plugins/draw/src/adapters/maplibre/modes/editPointMode.js +2 -2
  80. package/plugins/draw/src/adapters/maplibre/modes/editPointMode.test.js +3 -3
  81. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/geometryHelpers.js +31 -0
  82. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/geometryHelpers.test.js +8 -1
  83. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +38 -30
  84. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +20 -3
  85. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +5 -5
  86. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +2 -2
  87. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +2 -2
  88. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +3 -3
  89. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +7 -7
  90. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +4 -4
  91. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +14 -14
  92. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexQueries.js +12 -32
  93. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexQueries.test.js +10 -10
  94. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +48 -22
  95. package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +74 -6
  96. package/plugins/draw/src/adapters/maplibre/utils/snapMovement.js +2 -2
  97. package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +6 -0
  98. package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +9 -0
  99. package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +15 -2
  100. package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +27 -1
  101. package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +1 -1
  102. package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +40 -17
  103. package/plugins/draw/src/adapters/openlayers/draw/drawInput.test.js +55 -1
  104. package/plugins/draw/src/adapters/openlayers/draw/vertexPlacement.js +13 -7
  105. package/plugins/draw/src/adapters/openlayers/draw/vertexPlacement.test.js +7 -15
  106. package/plugins/draw/src/adapters/openlayers/edit/EditMode.js +36 -4
  107. package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +41 -1
  108. package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +35 -25
  109. package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +40 -2
  110. package/plugins/draw/src/adapters/openlayers/edit/nudge.js +2 -2
  111. package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +2 -2
  112. package/plugins/draw/src/adapters/openlayers/point/drawPointMode.js +40 -54
  113. package/plugins/draw/src/adapters/openlayers/point/drawPointMode.test.js +32 -13
  114. package/plugins/draw/src/adapters/openlayers/point/editPointMode.js +1 -1
  115. package/plugins/draw/src/adapters/openlayers/point/editPointMode.test.js +17 -1
  116. package/plugins/draw/src/events.js +4 -4
  117. package/plugins/draw/src/events.test.js +1 -1
  118. package/plugins/draw/src/hooks/useSpatialList.js +180 -0
  119. package/plugins/draw/src/hooks/useSpatialList.test.js +339 -0
  120. package/plugins/draw/src/manifest.js +4 -1
  121. package/plugins/draw/src/manifest.test.js +19 -7
  122. package/plugins/draw/src/utils/spatial.js +1 -31
  123. package/plugins/draw/src/utils/spatial.test.js +1 -24
  124. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  125. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  126. package/plugins/interact/dist/umd/index.js +1 -1
  127. package/plugins/interact/src/InteractInit.jsx +2 -2
  128. package/plugins/interact/src/InteractInit.test.js +3 -3
  129. package/plugins/interact/src/events.js +11 -2
  130. package/plugins/interact/src/events.test.js +32 -0
  131. package/plugins/interact/src/hooks/useAttachEvents.js +20 -0
  132. package/plugins/interact/src/hooks/useAttachEvents.test.js +44 -1
  133. package/plugins/interact/src/hooks/useCrossHairVisibility.js +9 -4
  134. package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +7 -7
  135. package/plugins/interact/src/hooks/useSpatialList.js +251 -0
  136. package/plugins/interact/src/hooks/{useMapItemList.test.js → useSpatialList.test.js} +216 -70
  137. package/plugins/interact/src/manifest.js +12 -1
  138. package/plugins/interact/src/manifest.test.js +20 -0
  139. package/plugins/interact/src/utils/spatial.js +24 -1
  140. package/plugins/interact/src/utils/spatial.test.js +26 -1
  141. package/plugins/map-key/dist/css/index.css +1 -106
  142. package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -1
  143. package/plugins/map-key/dist/umd/im-map-key-plugin.js +1 -1
  144. package/plugins/map-key/dist/umd/index.js +1 -1
  145. package/plugins/map-key/src/components/Key/Key.jsx +3 -4
  146. package/plugins/map-key/src/components/Key/Key.module.scss +10 -8
  147. package/plugins/map-key/src/components/Key/KeyGroupItem.test.jsx +2 -2
  148. package/plugins/map-key/src/components/Key/KeyItem.jsx +2 -2
  149. package/plugins/map-key/src/components/Key/KeySvg.jsx +9 -7
  150. package/plugins/map-key/src/components/Key/KeySvg.test.jsx +4 -4
  151. package/plugins/map-key/src/components/Key/MapKey.jsx +5 -3
  152. package/plugins/map-key/src/manifest.js +1 -1
  153. package/plugins/map-key/src/utils/groupStyles.js +7 -0
  154. package/plugins/map-key/src/utils/mergeKeyGroupItems.js +12 -0
  155. package/plugins/map-key/src/utils/mergeKeyGroupItems.test.js +53 -0
  156. package/plugins/menu/dist/css/index.css +1 -80
  157. package/plugins/menu/dist/esm/im-menu-plugin.js +1 -1
  158. package/plugins/menu/dist/umd/im-menu-plugin.js +1 -1
  159. package/plugins/menu/dist/umd/index.js +1 -1
  160. package/plugins/menu/src/initialise/MenuInit.jsx +15 -3
  161. package/plugins/menu/src/initialise/MenuInit.test.jsx +25 -0
  162. package/plugins/menu/src/initialise/createMenu.js +3 -1
  163. package/plugins/menu/src/initialise/createMenu.test.js +20 -5
  164. package/plugins/menu/src/initialise/updateUrl.js +44 -0
  165. package/plugins/menu/src/initialise/updateUrl.test.js +91 -0
  166. package/plugins/menu/src/reducers/menuStateReducer.js +19 -1
  167. package/plugins/menu/src/reducers/menuStateReducer.test.js +53 -20
  168. package/plugins/menu/src/reducers/pluginState.js +1 -6
  169. package/plugins/menu/src/reducers/pluginState.test.js +0 -25
  170. package/plugins/search/dist/css/index.css +1 -1
  171. package/plugins/search/dist/esm/im-search-plugin.js +1 -1
  172. package/plugins/search/dist/umd/im-search-plugin.js +1 -1
  173. package/plugins/search/src/components/Form/Form.jsx +3 -3
  174. package/plugins/search/src/components/Suggestions/Suggestions.jsx +2 -2
  175. package/plugins/search/src/components/Suggestions/Suggestions.test.jsx +1 -1
  176. package/plugins/search/src/manifest.js +5 -9
  177. package/plugins/search/src/manifest.test.js +5 -0
  178. package/providers/beta/esri/dist/css/index.css +1 -34
  179. package/providers/beta/esri/dist/esm/im-esri-provider.js +1 -1
  180. package/providers/beta/esri/src/utils/spatial.js +15 -13
  181. package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
  182. package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
  183. package/providers/beta/openlayers/src/openlayersProvider.js +3 -3
  184. package/providers/beta/openlayers/src/openlayersProvider.test.js +6 -3
  185. package/providers/beta/openlayers/src/utils/queryFeatures.js +72 -0
  186. package/providers/beta/openlayers/src/utils/queryFeatures.test.js +122 -1
  187. package/providers/beta/openlayers/src/utils/spatial.js +16 -14
  188. package/providers/beta/openlayers/src/utils/spatial.test.js +10 -6
  189. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  190. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  191. package/providers/maplibre/dist/umd/index.js +1 -1
  192. package/providers/maplibre/src/defaults.test.js +26 -0
  193. package/providers/maplibre/src/maplibreProvider.js +1 -1
  194. package/providers/maplibre/src/utils/labels.js +2 -2
  195. package/providers/maplibre/src/utils/labels.test.js +5 -5
  196. package/providers/maplibre/src/utils/spatial.js +19 -74
  197. package/providers/maplibre/src/utils/spatial.test.js +8 -32
  198. package/rollup.esm.mjs +2 -1
  199. package/scripts/publish-package.sh +36 -0
  200. package/src/App/App.jsx +1 -1
  201. package/src/App/App.test.jsx +6 -1
  202. package/src/App/components/CrossHair/CrossHair.jsx +25 -11
  203. package/src/App/components/CrossHair/CrossHair.module.scss +37 -12
  204. package/src/App/components/CrossHair/CrossHair.test.jsx +40 -11
  205. package/src/App/components/Hints/Hints.jsx +3 -3
  206. package/src/App/components/Hints/Hints.test.jsx +3 -3
  207. package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +4 -1
  208. package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +17 -0
  209. package/src/App/components/MapButton/MapButton.jsx +19 -7
  210. package/src/App/components/MapButton/MapButton.module.scss +1 -2
  211. package/src/App/components/MapButton/MapButton.test.jsx +42 -4
  212. package/src/App/components/{MoveControls/MoveControls.jsx → MapControls/MapControls.jsx} +10 -10
  213. package/src/App/components/{MoveControls/MoveControls.module.scss → MapControls/MapControls.module.scss} +25 -25
  214. package/src/App/components/{MoveControls/MoveControls.test.jsx → MapControls/MapControls.test.jsx} +48 -48
  215. package/src/App/components/Markers/Markers.jsx +2 -2
  216. package/src/App/components/Markers/Markers.test.jsx +3 -3
  217. package/src/App/components/Markers/SymbolMarker.jsx +2 -3
  218. package/src/App/components/Markers/SymbolMarker.test.jsx +8 -9
  219. package/src/App/components/Panel/Panel.jsx +19 -20
  220. package/src/App/components/Panel/Panel.module.scss +9 -0
  221. package/src/App/components/Panel/Panel.test.jsx +69 -4
  222. package/src/App/components/PopupMenu/PopupMenu.jsx +7 -3
  223. package/src/App/components/PopupMenu/PopupMenu.test.jsx +71 -0
  224. package/src/App/components/PopupMenu/usePopupMenu.js +10 -9
  225. package/src/App/components/Viewport/MapStatus.jsx +1 -1
  226. package/src/App/components/Viewport/SpatialList.jsx +47 -0
  227. package/src/App/components/Viewport/{Features.module.scss → SpatialList.module.scss} +6 -6
  228. package/src/App/components/Viewport/SpatialList.test.jsx +285 -0
  229. package/src/App/components/Viewport/Viewport.jsx +21 -11
  230. package/src/App/components/Viewport/Viewport.test.jsx +18 -2
  231. package/src/App/controls/keyboardMappings.js +7 -2
  232. package/src/App/controls/keyboardMappings.test.js +21 -0
  233. package/src/App/controls/keyboardShortcuts.js +16 -2
  234. package/src/App/controls/keyboardShortcuts.test.js +21 -0
  235. package/src/App/hooks/useCrossHairAPI.js +29 -1
  236. package/src/App/hooks/useCrossHairAPI.test.js +17 -1
  237. package/src/App/hooks/useHintsAPI.js +5 -5
  238. package/src/App/hooks/useInterfaceAPI.js +2 -1
  239. package/src/App/hooks/useInterfaceAPI.test.js +9 -0
  240. package/src/App/hooks/useKeyboardShortcuts.js +66 -35
  241. package/src/App/hooks/useKeyboardShortcuts.test.js +52 -0
  242. package/src/App/hooks/useModalPanelBehaviour.js +48 -34
  243. package/src/App/hooks/useModalPanelBehaviour.test.js +59 -0
  244. package/src/App/hooks/useSpatialListFocus.js +296 -0
  245. package/src/App/hooks/useSpatialListFocus.test.js +957 -0
  246. package/src/App/hooks/useSpatialListItems.js +51 -0
  247. package/src/App/hooks/useSpatialListItems.test.js +217 -0
  248. package/src/App/initialiseApp.js +6 -3
  249. package/src/App/initialiseApp.test.js +11 -0
  250. package/src/App/layout/Layout.jsx +4 -2
  251. package/src/App/layout/Layout.test.jsx +21 -0
  252. package/src/App/layout/layout.module.scss +7 -1
  253. package/src/App/registry/keyboardShortcutRegistry.js +2 -2
  254. package/src/App/registry/keyboardShortcutRegistry.test.js +16 -0
  255. package/src/App/registry/pluginRegistry.js +13 -0
  256. package/src/App/registry/pluginRegistry.test.js +15 -0
  257. package/src/App/registry/spatialListRegistry.js +104 -0
  258. package/src/App/registry/spatialListRegistry.test.js +218 -0
  259. package/src/App/renderer/HtmlElementHost.jsx +12 -32
  260. package/src/App/renderer/mapButtons.js +4 -0
  261. package/src/App/renderer/mapButtons.test.js +20 -0
  262. package/src/App/renderer/mapPanels.js +33 -53
  263. package/src/App/renderer/mapPanels.test.js +29 -4
  264. package/src/App/renderer/slotHelpers.js +33 -0
  265. package/src/App/renderer/slotHelpers.test.js +79 -2
  266. package/src/App/store/AppProvider.jsx +3 -2
  267. package/src/App/store/ServiceProvider.jsx +5 -3
  268. package/src/App/store/ServiceProvider.test.jsx +20 -1
  269. package/src/InteractiveMap/InteractiveMap.js +13 -2
  270. package/src/InteractiveMap/InteractiveMap.test.js +33 -0
  271. package/src/config/appConfig.js +17 -17
  272. package/src/config/appConfig.test.js +19 -19
  273. package/src/config/defaults.js +2 -2
  274. package/src/config/events.js +8 -8
  275. package/src/scss/main.scss +2 -2
  276. package/src/scss/tools/_govuk-content.scss +29 -0
  277. package/src/scss/tools/_index.scss +2 -1
  278. package/src/test-utils.js +8 -0
  279. package/src/types.js +53 -11
  280. package/src/utils/findNearestItemInDirection.js +29 -0
  281. package/src/utils/findNearestItemInDirection.test.js +67 -0
  282. package/src/utils/getPanelElementId.js +4 -0
  283. package/src/utils/getPanelElementId.test.js +11 -0
  284. package/src/utils/getPanelRole.js +22 -0
  285. package/src/utils/getPanelRole.test.js +56 -0
  286. package/src/utils/globalAltShortcuts.js +12 -0
  287. package/src/utils/globalAltShortcuts.test.js +27 -0
  288. package/src/utils/spatialNavigate.js +49 -0
  289. package/src/utils/spatialNavigate.test.js +42 -0
  290. package/webpack.umd.mjs +6 -1
  291. package/plugins/interact/src/hooks/useMapItemList.js +0 -187
  292. package/src/App/components/Viewport/Features.jsx +0 -35
  293. package/src/App/components/Viewport/Features.test.jsx +0 -124
  294. package/src/App/hooks/useFeatureFocus.js +0 -199
  295. package/src/App/hooks/useFeatureFocus.test.js +0 -635
  296. package/src/App/hooks/useFeatureItems.js +0 -39
  297. package/src/App/hooks/useFeatureItems.test.js +0 -155
@@ -4,16 +4,18 @@ import { KeySvgLine } from './KeySvgLine.jsx'
4
4
  import { KeySvgRect } from './KeySvgRect.jsx'
5
5
  import { KeySvgRamp } from './KeySvgRamp.jsx'
6
6
  import { symbolRegistry } from '../../registry/index.js'
7
+ import { HORIZONTAL_RAMP } from '../../utils/groupStyles.js'
7
8
 
8
9
  // Pure derivation of keyDefinition — computed directly during render (see KeyItem.jsx for why:
9
10
  // staging this through useState/useEffect meant every fresh mount painted a blank symbol first).
10
- const getSymbolShape = (keyDefinition) => {
11
+
12
+ const getSymbolShape = (keyDefinition, groupStyle) => {
11
13
  if (!keyDefinition) {
12
14
  return { symbolShape: null, symbolDef: null }
13
15
  }
14
- const { hasSymbol, hasPattern, hasRampStyleKey, style } = keyDefinition
15
- if (hasRampStyleKey) {
16
- return { symbolShape: 'ramp', symbolDef: null }
16
+ const { hasSymbol, hasPattern, style } = keyDefinition
17
+ if (groupStyle === HORIZONTAL_RAMP) {
18
+ return { symbolShape: HORIZONTAL_RAMP, symbolDef: null }
17
19
  }
18
20
  if (hasSymbol) {
19
21
  const symbolDef = symbolRegistry.getSymbolDef(style)
@@ -28,8 +30,8 @@ const getSymbolShape = (keyDefinition) => {
28
30
  return { symbolShape: 'rect', symbolDef: null }
29
31
  }
30
32
 
31
- export const KeySvg = ({ keyDefinition, mapStyle }) => {
32
- const { symbolShape, symbolDef } = getSymbolShape(keyDefinition)
33
+ export const KeySvg = ({ keyDefinition, groupStyle, mapStyle }) => {
34
+ const { symbolShape, symbolDef } = getSymbolShape(keyDefinition, groupStyle)
33
35
 
34
36
  if (!symbolShape) {
35
37
  return null
@@ -39,7 +41,7 @@ export const KeySvg = ({ keyDefinition, mapStyle }) => {
39
41
  return <KeySvgPattern mapStyle={mapStyle} keyDefinition={keyDefinition} />
40
42
  } else if (symbolShape === 'line') {
41
43
  return <KeySvgLine mapStyle={mapStyle} keyDefinition={keyDefinition} />
42
- } else if (symbolShape === 'ramp') {
44
+ } else if (symbolShape === HORIZONTAL_RAMP) {
43
45
  return <KeySvgRamp mapStyle={mapStyle} keyDefinition={keyDefinition} />
44
46
  } else {
45
47
  return <KeySvgRect mapStyle={mapStyle} keyDefinition={keyDefinition} />
@@ -22,7 +22,7 @@ jest.mock('./KeySvgRect.jsx', () => ({
22
22
  }))
23
23
 
24
24
  jest.mock('./KeySvgRamp.jsx', () => ({
25
- KeySvgRamp: () => <svg data-testid='key-svg-ramp' />
25
+ KeySvgRamp: () => <svg data-testid='key-svg-horizontal-ramp' />
26
26
  }))
27
27
 
28
28
  const baseKeyDefinition = {
@@ -91,8 +91,8 @@ describe('KeySvg', () => {
91
91
  expect(container.firstChild).toBeNull()
92
92
  })
93
93
 
94
- it('renders KeySvgRamp when hasRampStyleKey is true', () => {
95
- const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, hasRampStyleKey: true }} />)
96
- expect(getByTestId('key-svg-ramp')).toBeTruthy()
94
+ it('renders KeySvgRamp when groupStyle is horizontal-ramp', () => {
95
+ const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition }} groupStyle='horizontal-ramp' />)
96
+ expect(getByTestId('key-svg-horizontal-ramp')).toBeTruthy()
97
97
  })
98
98
  })
@@ -1,11 +1,11 @@
1
1
  import React, { useState, useEffect } from 'react'
2
2
  import { getDatasetRegistry } from '../../registry/index.js'
3
-
3
+ import { mergeKeyGroupItems } from '../../utils/mergeKeyGroupItems.js'
4
4
  import { Key } from './Key.jsx'
5
5
 
6
6
  export function MapKey ({
7
7
  mapState: { mapStyle },
8
- pluginConfig: { noKeyItemText },
8
+ pluginConfig: { noKeyItemText, groups },
9
9
  services: { eventBus }
10
10
  }) {
11
11
  const [datasetRegistry, setDatasetRegistry] = useState(getDatasetRegistry())
@@ -17,7 +17,9 @@ export function MapKey ({
17
17
 
18
18
  const getKeyItems = () => {
19
19
  const { items, hasGroups: _hasGroups } = datasetRegistry.keyItems()
20
- setKeyGroups(items)
20
+ // Post Process the items - based on the map-key pluginConfig adding any groupConfigs
21
+ const groupItems = mergeKeyGroupItems(groups, items)
22
+ setKeyGroups(groupItems)
21
23
  setHasGroups(_hasGroups)
22
24
  }
23
25
 
@@ -18,7 +18,7 @@ export const manifest = {
18
18
  panelId: 'mapKey',
19
19
  label: 'Key',
20
20
  iconId: 'key',
21
- mobile: { slot: 'top-left', showLabel: false },
21
+ mobile: { slot: 'top-left', showLabel: true },
22
22
  tablet: { slot: 'top-left', showLabel: true },
23
23
  desktop: { slot: 'top-left', showLabel: true }
24
24
  }],
@@ -0,0 +1,7 @@
1
+ export const HORIZONTAL_RAMP = 'horizontal-ramp'
2
+
3
+ const groupStyles = {
4
+ HORIZONTAL_RAMP
5
+ }
6
+
7
+ export default groupStyles
@@ -0,0 +1,12 @@
1
+ export const mergeKeyGroupItems = (groups, items) => {
2
+ if (!groups) {
3
+ return items
4
+ }
5
+ return items.map((item) => {
6
+ const { id } = item
7
+ if (groups[id]) {
8
+ return { ...item, ...groups[id] }
9
+ }
10
+ return item
11
+ })
12
+ }
@@ -0,0 +1,53 @@
1
+ import { mergeKeyGroupItems } from './mergeKeyGroupItems'
2
+
3
+ describe('mergeKeyGroupItems', () => {
4
+ it('returns items unchanged when groups is not provided', () => {
5
+ const items = [{ id: 'a', label: 'A' }, { id: 'b', label: 'B' }]
6
+
7
+ expect(mergeKeyGroupItems(undefined, items)).toBe(items)
8
+ })
9
+
10
+ it('returns items unchanged when groups is null', () => {
11
+ const items = [{ id: 'a', label: 'A' }]
12
+
13
+ expect(mergeKeyGroupItems(null, items)).toBe(items)
14
+ })
15
+
16
+ it('merges matching group data into an item', () => {
17
+ const items = [{ id: 'a', label: 'A' }]
18
+ const groups = { a: { group: 'Group 1' } }
19
+
20
+ expect(mergeKeyGroupItems(groups, items)).toEqual([
21
+ { id: 'a', label: 'A', group: 'Group 1' }
22
+ ])
23
+ })
24
+
25
+ it('overrides item properties with matching group properties', () => {
26
+ const items = [{ id: 'a', label: 'A' }]
27
+ const groups = { a: { label: 'Overridden' } }
28
+
29
+ expect(mergeKeyGroupItems(groups, items)).toEqual([
30
+ { id: 'a', label: 'Overridden' }
31
+ ])
32
+ })
33
+
34
+ it('leaves items without a matching group unchanged', () => {
35
+ const items = [{ id: 'a', label: 'A' }, { id: 'b', label: 'B' }]
36
+ const groups = { a: { group: 'Group 1' } }
37
+
38
+ expect(mergeKeyGroupItems(groups, items)).toEqual([
39
+ { id: 'a', label: 'A', group: 'Group 1' },
40
+ { id: 'b', label: 'B' }
41
+ ])
42
+ })
43
+
44
+ it('returns an empty array when items is empty', () => {
45
+ expect(mergeKeyGroupItems({ a: { group: 'Group 1' } }, [])).toEqual([])
46
+ })
47
+
48
+ it('handles an empty groups object as no matches', () => {
49
+ const items = [{ id: 'a', label: 'A' }]
50
+
51
+ expect(mergeKeyGroupItems({}, items)).toEqual(items)
52
+ })
53
+ })
@@ -1,80 +1 @@
1
- .im-c-menu--has-groups > *:not(:first-child) {
2
- border-top: 1px solid var(--button-hover-color);
3
- }
4
-
5
- .im-c-menu > *:first-child {
6
- padding-top: 5px;
7
- }
8
-
9
- .im-c-menu > *:last-child {
10
- margin-bottom: -5px;
11
- }
12
-
13
- .im-c-menu-group:not(:last-child) {
14
- padding-bottom: 5px;
15
- }
16
-
17
- .im-c-menu__item {
18
- padding-bottom: 5px;
19
- }
20
- .im-c-menu__item:first-child {
21
- padding-top: 0;
22
- }
23
- .im-c-menu--has-groups > .im-c-menu__item:not(:first-child) {
24
- padding-top: 5px;
25
- }
26
- .im-c-menu-group .im-c-menu__item {
27
- padding-top: 0;
28
- padding-bottom: 0;
29
- }
30
- .im-c-menu-group .im-c-menu__item:not(:last-child) {
31
- margin-bottom: 0;
32
- }
33
- .im-c-menu__item .im-c-menu__item-label {
34
- width: 100%;
35
- max-width: none;
36
- align-items: start;
37
- padding-top: 12px;
38
- padding-bottom: 10px;
39
- align-self: auto;
40
- font-size: 1rem;
41
- line-height: 1.2;
42
- color: var(--foreground-color);
43
- }
44
-
45
- .im-c-menu__item .govuk-checkboxes__item,
46
- .im-c-menu__item .govuk-radios__item {
47
- flex-wrap: nowrap;
48
- }
49
- .im-c-menu__item .govuk-checkboxes__item .govuk-checkboxes__input, .im-c-menu__item .govuk-checkboxes__item .govuk-radios__input,
50
- .im-c-menu__item .govuk-radios__item .govuk-checkboxes__input,
51
- .im-c-menu__item .govuk-radios__item .govuk-radios__input {
52
- margin-left: -3px;
53
- }
54
-
55
- .im-c-menu-group__fieldset {
56
- border: none;
57
- padding: 0;
58
- margin: 0;
59
- min-width: 0;
60
- }
61
-
62
- .im-c-menu-group__legend {
63
- padding-top: 15px;
64
- padding-bottom: 10px;
65
- padding-inline: 0;
66
- font-size: 1rem;
67
- font-weight: bold;
68
- color: var(--foreground-color);
69
- }
70
- .im-c-menu-group__legend h3 {
71
- font-size: inherit;
72
- }
73
-
74
- .im-c-menu-group:first-child .im-c-menu-group__legend {
75
- padding-top: 0;
76
- }
77
-
78
- .im-c-menu .govuk-checkboxes__input[aria-disabled=true] + .govuk-checkboxes__label {
79
- opacity: 0.5;
80
- }
1
+ .im-c-menu--has-groups>:not(:first-child){border-top:1px solid var(--button-hover-color)}.im-c-menu>:first-child{padding-top:5px}.im-c-menu>:last-child{margin-bottom:-5px}.im-c-menu-group:not(:last-child),.im-c-menu__item{padding-bottom:5px}.im-c-menu__item:first-child{padding-top:0}.im-c-menu--has-groups>.im-c-menu__item:not(:first-child){padding-top:5px}.im-c-menu-group .im-c-menu__item{padding-bottom:0;padding-top:0}.im-c-menu-group .im-c-menu__item:not(:last-child){margin-bottom:0}.im-c-menu__item .im-c-menu__item-label{align-items:start;align-self:auto;color:var(--foreground-color);font-size:1rem;line-height:1.2;max-width:none;padding-bottom:10px;padding-top:12px;width:100%}.im-c-menu__item .govuk-checkboxes__item,.im-c-menu__item .govuk-radios__item{flex-wrap:nowrap}.im-c-menu__item .govuk-checkboxes__item .govuk-checkboxes__input,.im-c-menu__item .govuk-checkboxes__item .govuk-radios__input,.im-c-menu__item .govuk-radios__item .govuk-checkboxes__input,.im-c-menu__item .govuk-radios__item .govuk-radios__input{margin-left:-3px}.im-c-menu-group__fieldset{border:none;margin:0;min-width:0;padding:0}.im-c-menu-group__legend{color:var(--foreground-color);font-size:1rem;font-weight:700;padding-bottom:10px;padding-top:15px;padding-inline:0}.im-c-menu-group__legend h3{font-size:inherit}.im-c-menu-group:first-child .im-c-menu-group__legend{padding-top:0}.im-c-menu .govuk-checkboxes__input[aria-disabled=true]+.govuk-checkboxes__label{opacity:.5}
@@ -1 +1 @@
1
- import{createContext as e,useContext as t,useRef as a,useEffect as n}from"preact/compat";import{jsx as r,jsxs as i,Fragment as u}from"preact/jsx-runtime";import o from"@babel/runtime/helpers/defineProperty";var l={},c=e=>{var t,a=(null===(t=l)||void 0===t||null===(t=t.current)||void 0===t?void 0:t.menuState)||{};for(var[n,r]of Object.entries(e)){var i=a[n];if(!r.includes(i))return!1}return!0},m=e=>{if(null==e)return!0;if("boolean"==typeof e)return e;if("object"==typeof e){for(var[t,a]of Object.entries(e))if("menu"===t&&!c(a))return!1;return!0}return!0},s=e("map-menu"),d=e=>"".concat(t(s),"-").concat(e),p=e=>{var{menuGroupItem:t,name:a,checked:n,onChange:u}=e,o=d("radio-".concat(t.id)),{visibleWhen:l}=t;return!l||m(l)?r("div",{className:'im-c-menu__item govuk-radios govuk-radios--small"',"data-module":"govuk-radios",children:i("div",{className:"govuk-radios__item",children:[r("input",{id:o,className:"govuk-radios__input",type:"radio",name:a,value:t.id,checked:n,onChange:u}),r("label",{className:"im-c-menu__item-label govuk-label govuk-radios__label",htmlFor:o,children:t.label})]})}):null},h=e=>{var{menuGroup:t,children:a}=e,n=t.groupLabel||t.label;if(!n)return r(u,{children:a});return r("div",{className:"govuk-form-group im-c-menu-group",children:i("fieldset",{className:"im-c-menu-group__fieldset",children:[r("legend",{className:"im-c-menu-group__legend",children:i("h3",{children:[" ",n," "]})}),a]})},t.id)},v=e=>{var{menuState:t,dispatch:a,menuGroup:n}=e,{id:i,items:u,visibleWhen:o}=n;if(!(!o||m(o)))return null;var l=t[i],c=e=>{a({type:"UPDATE_MENU_STATE",payload:{[i]:e.target.value}})};return r(h,{menuGroup:n,children:r("div",{className:"govuk-radios govuk-radios--small","data-module":"govuk-radios",children:u.map(e=>r(p,{menuGroupItem:e,name:i,checked:e.id===l,onChange:c},e.id))})})},b=e=>{var{dispatch:t,menuGroupItem:a,onChange:n,checked:u}=e,o="im-c-menu__item govuk-checkboxes govuk-checkboxes--small".concat(u?"":" im-c-menu__item--checked"),l=d("checkbox-".concat(a.id));return r("div",{className:o,"data-module":"govuk-checkboxes",children:i("div",{className:"govuk-checkboxes__item",children:[r("input",{className:"govuk-checkboxes__input",id:l,name:l,type:"checkbox",checked:u,onChange:e=>{var r,i=Boolean(null===(r=e.target)||void 0===r?void 0:r.checked);n&&n(i),t({type:"UPDATE_MENU_STATE",payload:{[a.id]:i}})}}),r("label",{className:"im-c-menu__item-label govuk-label govuk-checkboxes__label",htmlFor:l,children:a.label})]})},l)},g=e=>{var{dispatch:t,menuGroup:a,menuState:n}=e;return i(h,{menuGroup:a,children:[" ",a.items.map(e=>r(b,{dispatch:t,menuGroupItem:e,checked:n[e.id],onChange:e.handleOnChange},e.id))]})},f=e=>{var{menuGroup:t,dispatch:a,menuState:n}=e;return"checkbox"===t.type?r(g,{menuGroup:t,dispatch:a,menuState:n}):r(v,{menuGroup:t,dispatch:a,menuState:n})},k=e=>{};function _(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),a.push.apply(a,n)}return a}function y(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?_(Object(a),!0).forEach(function(t){o(e,t,a[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):_(Object(a)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))})}return e}var S={InitComponent:function(e){var{pluginConfig:t,pluginState:r,mapState:i,services:u}=e,{dispatch:o}=r,{eventBus:c}=u,m=a(r);m.current=r,n(()=>{if(!i.isMapReady)return()=>{};(e=>{l=e})(m);var{menu:e}=t;return(e=>{var{menu:t,eventBus:a,dispatch:n,pluginStateRef:r}=e;return n({type:"SET_MENU",payload:{menu:t}}),a.requestOnce("datasets:registry",k),a.emitWhenRequested("menu:state",r)})({menu:e,eventBus:c,dispatch:o,pluginStateRef:m})},[i.isMapReady]),n(()=>c.emit("menu:changed",r.menuState),[r.menuState])},reducer:{initialState:{actionsArray:[],menu:[],menuState:{}},actions:{SET_MENU:(e,t)=>{var{menu:a}=t,n=(e=>{var t={};return e.forEach(e=>{var a;"radio"===e.type&&(t[e.id]=e.value||(null===(a=e.items)||void 0===a?void 0:a[0].value))}),t})(a);return y(y({},e),{},{menu:a,menuState:n})},UPDATE_MENU_STATE:(e,t)=>y(y({},e),{},{menuState:y(y({},e.menuState),t)})}},panels:[{id:"menu",label:"Layers",mobile:{slot:"drawer",modal:!0,dismissible:!0},tablet:{slot:"left-top",dismissible:!0,exclusive:!0,width:"260px"},desktop:{slot:"left-top",modal:!1,dismissible:!0,exclusive:!0,width:"280px"},render:e=>{var{pluginState:t,appConfig:a}=e,{menu:n=[],dispatch:u,menuState:o}=t,l=(null==a?void 0:a.id)||"map",c=n.some(e=>e.groupLabel),m="im-c-menu".concat(c?" im-c-menu--has-groups":"");return r(s,{value:"".concat(l,"-menu"),children:i("div",{className:m,children:[" ",n.map(e=>r(f,{menuGroup:e,dispatch:u,menuState:o},e.id))]})})}}],buttons:[{id:"menuButton",label:"Layers",panelId:"menu",iconId:"layersMenu",mobile:{slot:"top-left",showLabel:!0},tablet:{slot:"top-left",showLabel:!0},desktop:{slot:"top-left",showLabel:!0}}],icons:[{id:"layersMenu",svgContent:'<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"></path><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"></path><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"></path>'}]};export{S as manifest};
1
+ import{createContext as e,useContext as t,useState as a,useRef as r,useEffect as n}from"preact/compat";import{jsx as i,jsxs as o,Fragment as u}from"preact/jsx-runtime";import l from"@babel/runtime/helpers/defineProperty";var c={},m=e=>{var t,a=(null===(t=c)||void 0===t||null===(t=t.current)||void 0===t?void 0:t.menuState)||{};for(var[r,n]of Object.entries(e)){var i=a[r];if(!n.includes(i))return!1}return!0},s=e=>{if(null==e)return!0;if("boolean"==typeof e)return e;if("object"==typeof e){for(var[t,a]of Object.entries(e))if("menu"===t&&!m(a))return!1;return!0}return!0},d=e("map-menu"),p=e=>"".concat(t(d),"-").concat(e),h=e=>{var{menuGroupItem:t,name:a,checked:r,onChange:n}=e,u=p("radio-".concat(t.id)),{visibleWhen:l}=t;return!l||s(l)?i("div",{className:'im-c-menu__item govuk-radios govuk-radios--small"',"data-module":"govuk-radios",children:o("div",{className:"govuk-radios__item",children:[i("input",{id:u,className:"govuk-radios__input",type:"radio",name:a,value:t.id,checked:r,onChange:n}),i("label",{className:"im-c-menu__item-label govuk-label govuk-radios__label",htmlFor:u,children:t.label})]})}):null},v=e=>{var{menuGroup:t,children:a}=e,r=t.groupLabel||t.label;if(!r)return i(u,{children:a});return i("div",{className:"govuk-form-group im-c-menu-group",children:o("fieldset",{className:"im-c-menu-group__fieldset",children:[i("legend",{className:"im-c-menu-group__legend",children:o("h3",{children:[" ",r," "]})}),a]})},t.id)},b=e=>{var{menuState:t,dispatch:a,menuGroup:r}=e,{id:n,items:o,visibleWhen:u}=r;if(!(!u||s(u)))return null;var l=t[n],c=e=>{a({type:"UPDATE_MENU_STATE",payload:{[n]:e.target.value}})};return i(v,{menuGroup:r,children:i("div",{className:"govuk-radios govuk-radios--small","data-module":"govuk-radios",children:o.map(e=>i(h,{menuGroupItem:e,name:n,checked:e.id===l,onChange:c},e.id))})})},g=e=>{var{dispatch:t,menuGroupItem:a,onChange:r,checked:n}=e,u="im-c-menu__item govuk-checkboxes govuk-checkboxes--small".concat(n?"":" im-c-menu__item--checked"),l=p("checkbox-".concat(a.id));return i("div",{className:u,"data-module":"govuk-checkboxes",children:o("div",{className:"govuk-checkboxes__item",children:[i("input",{className:"govuk-checkboxes__input",id:l,name:l,type:"checkbox",checked:n,onChange:e=>{var n,i=Boolean(null===(n=e.target)||void 0===n?void 0:n.checked);r&&r(i),t({type:"UPDATE_MENU_STATE",payload:{[a.id]:i}})}}),i("label",{className:"im-c-menu__item-label govuk-label govuk-checkboxes__label",htmlFor:l,children:a.label})]})},l)},f=e=>{var{dispatch:t,menuGroup:a,menuState:r}=e;return o(v,{menuGroup:a,children:[" ",a.items.map(e=>i(g,{dispatch:t,menuGroupItem:e,checked:r[e.id],onChange:e.handleOnChange},e.id))]})},k=e=>{var{menuGroup:t,dispatch:a,menuState:r}=e;return"checkbox"===t.type?i(f,{menuGroup:t,dispatch:a,menuState:r}):i(b,{menuGroup:t,dispatch:a,menuState:r})},_=e=>{},y=e=>{var{menu:t,eventBus:a,dispatch:r,pluginStateRef:n}=e,i=(e=>{var t=new URL(window.location.href),{searchParams:a}=t,r={};return e.forEach(e=>{var t=a.get(e.id);if("radio"===e.type){var n;r[e.id]=t||e.value||(null===(n=e.items)||void 0===n?void 0:n[0].value)}else{var{items:i}=e;i.forEach(e=>{var{id:a,checked:n}=e,i=t?t.includes(a):n;r[a]=i})}}),r})(t);return r({type:"SET_MENU",payload:{menu:t,menuState:i}}),a.requestOnce("datasets:registry",_),a.emitWhenRequested("menu:state",n)};function S(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),a.push.apply(a,r)}return a}function O(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?S(Object(a),!0).forEach(function(t){l(e,t,a[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):S(Object(a)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))})}return e}var w={InitComponent:function(e){var{pluginConfig:t,pluginState:i,mapState:o,services:u}=e,{dispatch:l}=i,{eventBus:m}=u,[d,p]=a(!1),h=r(i);h.current=i,n(()=>{if(!o.isMapReady)return()=>{};(e=>{c=e})(h);var{menu:e}=t,a=y({menu:e,eventBus:m,dispatch:l,pluginStateRef:h});return p(!0),a},[o.isMapReady]),n(()=>{m.emit("menu:changed",i.menuState),d&&(e=>{var t=new URL(window.location.href),{searchParams:a}=t,{menu:r,menuState:n}=e;r.forEach(e=>{var{id:t,visibleWhen:r,type:i}=e;s(r)?"radio"===i?((e,t,a)=>{var{id:r}=e,n=t[r];a.set(r,n)})(e,n,a):((e,t,a)=>{var{id:r,items:n}=e,i=[];n.forEach(e=>{var{id:a}=e;t[a]&&i.push(a)}),i.length?a.set(r,i):a.delete(r)})(e,n,a):a.delete(t)}),t.search=decodeURIComponent(t.search),window.history.replaceState({},"",t.toString())})(i)},[i.menuState])},reducer:{initialState:{menu:[],menuState:{}},actions:{SET_MENU:(e,t)=>{var{menu:a,menuState:r}=t;return O(O({},e),{},{menu:a,menuState:r})},UPDATE_MENU_STATE:(e,t)=>O(O({},e),{},{menuState:O(O({},e.menuState),t)})}},panels:[{id:"menu",label:"Layers",mobile:{slot:"drawer",modal:!0,dismissible:!0},tablet:{slot:"left-top",dismissible:!0,exclusive:!0,width:"260px"},desktop:{slot:"left-top",modal:!1,dismissible:!0,exclusive:!0,width:"280px"},render:e=>{var{pluginState:t,appConfig:a}=e,{menu:r=[],dispatch:n,menuState:u}=t,l=(null==a?void 0:a.id)||"map",c=r.some(e=>e.groupLabel),m="im-c-menu".concat(c?" im-c-menu--has-groups":"");return i(d,{value:"".concat(l,"-menu"),children:o("div",{className:m,children:[" ",r.map(e=>i(k,{menuGroup:e,dispatch:n,menuState:u},e.id))]})})}}],buttons:[{id:"menuButton",label:"Layers",panelId:"menu",iconId:"layersMenu",mobile:{slot:"top-left",showLabel:!0},tablet:{slot:"top-left",showLabel:!0},desktop:{slot:"top-left",showLabel:!0}}],icons:[{id:"layersMenu",svgContent:'<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"></path><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"></path><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"></path>'}]};export{w as manifest};
@@ -1 +1 @@
1
- "use strict";(this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[]).push([[217],{77(e,t,n){n.r(t),n.d(t,{manifest:()=>w});var r=n(738);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],c=!0,l=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return u(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var a={},c=function(e){for(var t,n=(null===(t=a)||void 0===t||null===(t=t.current)||void 0===t?void 0:t.menuState)||{},r=0,o=Object.entries(e);r<o.length;r++){var u=i(o[r],2),c=u[0],l=u[1],s=n[c];if(!l.includes(s))return!1}return!0},l=function(e){if(null==e)return!0;if("boolean"==typeof e)return e;if("object"===o(e)){for(var t=0,n=Object.entries(e);t<n.length;t++){var r=i(n[t],2),u=r[0],a=r[1];if("menu"===u&&!c(a))return!1}return!0}return!0},s=(0,r.createContext)("map-menu"),m=function(e){return"".concat((0,r.useContext)(s),"-").concat(e)},f=n(287),p=function(e){var t=e.menuGroupItem,n=e.name,r=e.checked,o=e.onChange,i=m("radio-".concat(t.id)),u=t.visibleWhen;return!u||l(u)?(0,f.jsx)("div",{className:'im-c-menu__item govuk-radios govuk-radios--small"',"data-module":"govuk-radios",children:(0,f.jsxs)("div",{className:"govuk-radios__item",children:[(0,f.jsx)("input",{id:i,className:"govuk-radios__input",type:"radio",name:n,value:t.id,checked:r,onChange:o}),(0,f.jsx)("label",{className:"im-c-menu__item-label govuk-label govuk-radios__label",htmlFor:i,children:t.label})]})}):null},d=function(e){var t=e.menuGroup,n=e.children,r=t.groupLabel||t.label;return r?(0,f.jsx)("div",{className:"govuk-form-group im-c-menu-group",children:(0,f.jsxs)("fieldset",{className:"im-c-menu-group__fieldset",children:[(0,f.jsx)("legend",{className:"im-c-menu-group__legend",children:(0,f.jsxs)("h3",{children:[" ",r," "]})}),n]})},t.id):(0,f.jsx)(f.Fragment,{children:n})};function b(e){return b="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},b(e)}var v=function(e){var t=e.menuState,n=e.dispatch,r=e.menuGroup,o=r.id,i=r.items,u=r.visibleWhen;if(u&&!l(u))return null;var a=t[o],c=function(e){var t,r,i;n({type:"UPDATE_MENU_STATE",payload:(t={},r=o,i=e.target.value,(r=function(e){var t=function(e){if("object"!=b(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=b(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==b(t)?t:t+""}(r))in t?Object.defineProperty(t,r,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[r]=i,t)})};return(0,f.jsx)(d,{menuGroup:r,children:(0,f.jsx)("div",{className:"govuk-radios govuk-radios--small","data-module":"govuk-radios",children:i.map(function(e){return(0,f.jsx)(p,{menuGroupItem:e,name:o,checked:e.id===a,onChange:c},e.id)})})})};function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}var h=function(e){var t=e.dispatch,n=e.menuGroupItem,r=e.onChange,o=e.checked,i="im-c-menu__item govuk-checkboxes govuk-checkboxes--small".concat(o?"":" im-c-menu__item--checked"),u=m("checkbox-".concat(n.id));return(0,f.jsx)("div",{className:i,"data-module":"govuk-checkboxes",children:(0,f.jsxs)("div",{className:"govuk-checkboxes__item",children:[(0,f.jsx)("input",{className:"govuk-checkboxes__input",id:u,name:u,type:"checkbox",checked:o,onChange:function(e){var o,i,u,a,c=Boolean(null===(o=e.target)||void 0===o?void 0:o.checked);r&&r(c),t({type:"UPDATE_MENU_STATE",payload:(i={},u=n.id,a=c,(u=function(e){var t=function(e){if("object"!=y(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=y(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==y(t)?t:t+""}(u))in i?Object.defineProperty(i,u,{value:a,enumerable:!0,configurable:!0,writable:!0}):i[u]=a,i)})}}),(0,f.jsx)("label",{className:"im-c-menu__item-label govuk-label govuk-checkboxes__label",htmlFor:u,children:n.label})]})},u)},g=function(e){var t=e.dispatch,n=e.menuGroup,r=e.menuState;return(0,f.jsxs)(d,{menuGroup:n,children:[" ",n.items.map(function(e){return(0,f.jsx)(h,{dispatch:t,menuGroupItem:e,checked:r[e.id],onChange:e.handleOnChange},e.id)})]})},S=function(e){var t=e.menuGroup,n=e.dispatch,r=e.menuState;return"checkbox"===t.type?(0,f.jsx)(g,{menuGroup:t,dispatch:n,menuState:r}):(0,f.jsx)(v,{menuGroup:t,dispatch:n,menuState:r})},j=function(e){};function k(e){return k="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},k(e)}function x(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?x(Object(n),!0).forEach(function(t){O(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):x(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function O(e,t,n){return(t=function(e){var t=function(e){if("object"!=k(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=k(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==k(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var w={InitComponent:function(e){var t=e.pluginConfig,n=e.pluginState,o=e.mapState,i=e.services,u=n.dispatch,c=i.eventBus,l=(0,r.useRef)(n);l.current=n,(0,r.useEffect)(function(){return o.isMapReady?(function(e){a=e}(l),function(e){var t=e.eventBus,n=e.pluginStateRef;return(0,e.dispatch)({type:"SET_MENU",payload:{menu:e.menu}}),t.requestOnce("datasets:registry",j),t.emitWhenRequested("menu:state",n)}({menu:t.menu,eventBus:c,dispatch:u,pluginStateRef:l})):function(){}},[o.isMapReady]),(0,r.useEffect)(function(){return c.emit("menu:changed",n.menuState)},[n.menuState])},reducer:{initialState:{actionsArray:[],menu:[],menuState:{}},actions:{SET_MENU:function(e,t){var n=t.menu,r=function(e){var t={};return e.forEach(function(e){var n;"radio"===e.type&&(t[e.id]=e.value||(null===(n=e.items)||void 0===n?void 0:n[0].value))}),t}(n);return _(_({},e),{},{menu:n,menuState:r})},UPDATE_MENU_STATE:function(e,t){return _(_({},e),{},{menuState:_(_({},e.menuState),t)})}}},panels:[{id:"menu",label:"Layers",mobile:{slot:"drawer",modal:!0,dismissible:!0},tablet:{slot:"left-top",dismissible:!0,exclusive:!0,width:"260px"},desktop:{slot:"left-top",modal:!1,dismissible:!0,exclusive:!0,width:"280px"},render:function(e){var t=e.pluginState,n=e.appConfig,r=t.menu,o=void 0===r?[]:r,i=t.dispatch,u=t.menuState,a=(null==n?void 0:n.id)||"map",c=o.some(function(e){return e.groupLabel}),l="im-c-menu".concat(c?" im-c-menu--has-groups":"");return(0,f.jsx)(s,{value:"".concat(a,"-menu"),children:(0,f.jsxs)("div",{className:l,children:[" ",o.map(function(e){return(0,f.jsx)(S,{menuGroup:e,dispatch:i,menuState:u},e.id)})]})})}}],buttons:[{id:"menuButton",label:"Layers",panelId:"menu",iconId:"layersMenu",mobile:{slot:"top-left",showLabel:!0},tablet:{slot:"top-left",showLabel:!0},desktop:{slot:"top-left",showLabel:!0}}],icons:[{id:"layersMenu",svgContent:'<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"></path><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"></path><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"></path>'}]}}}]);
1
+ "use strict";(this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[]).push([[217],{742(e,t,n){n.r(t),n.d(t,{manifest:()=>E});var r=n(738);function o(e){return o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o(e)}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],c=!0,l=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return u(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var a={},c=function(e){for(var t,n=(null===(t=a)||void 0===t||null===(t=t.current)||void 0===t?void 0:t.menuState)||{},r=0,o=Object.entries(e);r<o.length;r++){var u=i(o[r],2),c=u[0],l=u[1],s=n[c];if(!l.includes(s))return!1}return!0},l=function(e){if(null==e)return!0;if("boolean"==typeof e)return e;if("object"===o(e)){for(var t=0,n=Object.entries(e);t<n.length;t++){var r=i(n[t],2),u=r[0],a=r[1];if("menu"===u&&!c(a))return!1}return!0}return!0},s=(0,r.createContext)("map-menu"),m=function(e){return"".concat((0,r.useContext)(s),"-").concat(e)},f=n(287),d=function(e){var t=e.menuGroupItem,n=e.name,r=e.checked,o=e.onChange,i=m("radio-".concat(t.id)),u=t.visibleWhen;return!u||l(u)?(0,f.jsx)("div",{className:'im-c-menu__item govuk-radios govuk-radios--small"',"data-module":"govuk-radios",children:(0,f.jsxs)("div",{className:"govuk-radios__item",children:[(0,f.jsx)("input",{id:i,className:"govuk-radios__input",type:"radio",name:n,value:t.id,checked:r,onChange:o}),(0,f.jsx)("label",{className:"im-c-menu__item-label govuk-label govuk-radios__label",htmlFor:i,children:t.label})]})}):null},p=function(e){var t=e.menuGroup,n=e.children,r=t.groupLabel||t.label;return r?(0,f.jsx)("div",{className:"govuk-form-group im-c-menu-group",children:(0,f.jsxs)("fieldset",{className:"im-c-menu-group__fieldset",children:[(0,f.jsx)("legend",{className:"im-c-menu-group__legend",children:(0,f.jsxs)("h3",{children:[" ",r," "]})}),n]})},t.id):(0,f.jsx)(f.Fragment,{children:n})};function b(e){return b="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},b(e)}var v=function(e){var t=e.menuState,n=e.dispatch,r=e.menuGroup,o=r.id,i=r.items,u=r.visibleWhen;if(u&&!l(u))return null;var a=t[o],c=function(e){var t,r,i;n({type:"UPDATE_MENU_STATE",payload:(t={},r=o,i=e.target.value,(r=function(e){var t=function(e){if("object"!=b(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=b(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==b(t)?t:t+""}(r))in t?Object.defineProperty(t,r,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[r]=i,t)})};return(0,f.jsx)(p,{menuGroup:r,children:(0,f.jsx)("div",{className:"govuk-radios govuk-radios--small","data-module":"govuk-radios",children:i.map(function(e){return(0,f.jsx)(d,{menuGroupItem:e,name:o,checked:e.id===a,onChange:c},e.id)})})})};function y(e){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y(e)}var h=function(e){var t=e.dispatch,n=e.menuGroupItem,r=e.onChange,o=e.checked,i="im-c-menu__item govuk-checkboxes govuk-checkboxes--small".concat(o?"":" im-c-menu__item--checked"),u=m("checkbox-".concat(n.id));return(0,f.jsx)("div",{className:i,"data-module":"govuk-checkboxes",children:(0,f.jsxs)("div",{className:"govuk-checkboxes__item",children:[(0,f.jsx)("input",{className:"govuk-checkboxes__input",id:u,name:u,type:"checkbox",checked:o,onChange:function(e){var o,i,u,a,c=Boolean(null===(o=e.target)||void 0===o?void 0:o.checked);r&&r(c),t({type:"UPDATE_MENU_STATE",payload:(i={},u=n.id,a=c,(u=function(e){var t=function(e){if("object"!=y(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=y(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==y(t)?t:t+""}(u))in i?Object.defineProperty(i,u,{value:a,enumerable:!0,configurable:!0,writable:!0}):i[u]=a,i)})}}),(0,f.jsx)("label",{className:"im-c-menu__item-label govuk-label govuk-checkboxes__label",htmlFor:u,children:n.label})]})},u)},g=function(e){var t=e.dispatch,n=e.menuGroup,r=e.menuState;return(0,f.jsxs)(p,{menuGroup:n,children:[" ",n.items.map(function(e){return(0,f.jsx)(h,{dispatch:t,menuGroupItem:e,checked:r[e.id],onChange:e.handleOnChange},e.id)})]})},S=function(e){var t=e.menuGroup,n=e.dispatch,r=e.menuState;return"checkbox"===t.type?(0,f.jsx)(g,{menuGroup:t,dispatch:n,menuState:r}):(0,f.jsx)(v,{menuGroup:t,dispatch:n,menuState:r})},j=function(e){};function k(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function x(e){return x="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},x(e)}function w(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?w(Object(n),!0).forEach(function(t){O(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):w(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function O(e,t,n){return(t=function(e){var t=function(e){if("object"!=x(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=x(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==x(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var E={InitComponent:function(e){var t,n,o=e.pluginConfig,i=e.pluginState,u=e.mapState,c=e.services,s=i.dispatch,m=c.eventBus,f=(t=(0,r.useState)(!1),n=2,function(e){if(Array.isArray(e))return e}(t)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],c=!0,l=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(l)throw o}}return a}}(t,n)||function(e,t){if(e){if("string"==typeof e)return k(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?k(e,t):void 0}}(t,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),d=f[0],p=f[1],b=(0,r.useRef)(i);b.current=i,(0,r.useEffect)(function(){if(!u.isMapReady)return function(){};!function(e){a=e}(b);var e=function(e){var t=e.menu,n=e.eventBus,r=e.dispatch,o=e.pluginStateRef,i=function(e){var t=new URL(window.location.href).searchParams,n={};return e.forEach(function(e){var r,o=t.get(e.id);"radio"===e.type?n[e.id]=o||e.value||(null===(r=e.items)||void 0===r?void 0:r[0].value):e.items.forEach(function(e){var t=e.id,r=e.checked,i=o?o.includes(t):r;n[t]=i})}),n}(t);return r({type:"SET_MENU",payload:{menu:t,menuState:i}}),n.requestOnce("datasets:registry",j),n.emitWhenRequested("menu:state",o)}({menu:o.menu,eventBus:m,dispatch:s,pluginStateRef:b});return p(!0),e},[u.isMapReady]),(0,r.useEffect)(function(){m.emit("menu:changed",i.menuState),d&&function(e){var t=new URL(window.location.href),n=t.searchParams,r=e.menu,o=e.menuState;r.forEach(function(e){var t=e.id,r=e.visibleWhen,i=e.type;l(r)?"radio"===i?function(e,t,n){var r=e.id,o=t[r];n.set(r,o)}(e,o,n):function(e,t,n){var r=e.id,o=e.items,i=[];o.forEach(function(e){var n=e.id;t[n]&&i.push(n)}),i.length?n.set(r,i):n.delete(r)}(e,o,n):n.delete(t)}),t.search=decodeURIComponent(t.search),window.history.replaceState({},"",t.toString())}(i)},[i.menuState])},reducer:{initialState:{menu:[],menuState:{}},actions:{SET_MENU:function(e,t){var n=t.menu,r=t.menuState;return _(_({},e),{},{menu:n,menuState:r})},UPDATE_MENU_STATE:function(e,t){return _(_({},e),{},{menuState:_(_({},e.menuState),t)})}}},panels:[{id:"menu",label:"Layers",mobile:{slot:"drawer",modal:!0,dismissible:!0},tablet:{slot:"left-top",dismissible:!0,exclusive:!0,width:"260px"},desktop:{slot:"left-top",modal:!1,dismissible:!0,exclusive:!0,width:"280px"},render:function(e){var t=e.pluginState,n=e.appConfig,r=t.menu,o=void 0===r?[]:r,i=t.dispatch,u=t.menuState,a=(null==n?void 0:n.id)||"map",c=o.some(function(e){return e.groupLabel}),l="im-c-menu".concat(c?" im-c-menu--has-groups":"");return(0,f.jsx)(s,{value:"".concat(a,"-menu"),children:(0,f.jsxs)("div",{className:l,children:[" ",o.map(function(e){return(0,f.jsx)(S,{menuGroup:e,dispatch:i,menuState:u},e.id)})]})})}}],buttons:[{id:"menuButton",label:"Layers",panelId:"menu",iconId:"layersMenu",mobile:{slot:"top-left",showLabel:!0},tablet:{slot:"top-left",showLabel:!0},desktop:{slot:"top-left",showLabel:!0}}],icons:[{id:"layersMenu",svgContent:'<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"></path><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"></path><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"></path>'}]}}}]);
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.menuPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat},287(e){e.exports=preactJsxRuntime}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e](i,i.exports,o),i.exports}o.m=r,o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-menu-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.menuPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({noKeyItemText:"No features displayed"},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"menu",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(217).then(o.bind(o,77));case 1:return t=e.v.manifest,e.a(2,t)}},e)}),t=function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){f(i,n,o,a,u,"next",e)}function u(e){f(i,n,o,a,u,"throw",e)}a(void 0)})},function(){return t.apply(this,arguments)})})}return o.d(i,{default:()=>d}),i.default})());
2
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.menuPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat},287(e){e.exports=preactJsxRuntime}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e](i,i.exports,o),i.exports}o.m=r,o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-menu-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.menuPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({noKeyItemText:"No features displayed"},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"menu",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(217).then(o.bind(o,742));case 1:return t=e.v.manifest,e.a(2,t)}},e)}),t=function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){f(i,n,o,a,u,"next",e)}function u(e){f(i,n,o,a,u,"throw",e)}a(void 0)})},function(){return t.apply(this,arguments)})})}return o.d(i,{default:()=>d}),i.default})());
@@ -1,11 +1,13 @@
1
- import { useEffect, useRef } from 'react'
1
+ import { useEffect, useRef, useState } from 'react'
2
2
  import { createMenu } from './createMenu.js'
3
3
  import { attachPluginStateRef } from '../registry/isVisibleWhen.js'
4
+ import { updateUrl } from './updateUrl.js'
4
5
 
5
6
  // additional possible params here are: appState, mapProvider,
6
7
  export function MenuInit ({ pluginConfig, pluginState, mapState, services }) {
7
8
  const { dispatch } = pluginState
8
9
  const { eventBus } = services
10
+ const [urlParsed, setUrlParsed] = useState(false)
9
11
 
10
12
  const pluginStateRef = useRef(pluginState)
11
13
  pluginStateRef.current = pluginState
@@ -16,9 +18,19 @@ export function MenuInit ({ pluginConfig, pluginState, mapState, services }) {
16
18
  }
17
19
  attachPluginStateRef(pluginStateRef)
18
20
  const { menu } = pluginConfig
19
- return createMenu({ menu, eventBus, dispatch, pluginStateRef })
21
+ // createMenu parses the url and combines the url parameters with the dataset defaults
22
+ // that are passed to the plugin as 'menu: {...}'
23
+ const teardown = createMenu({ menu, eventBus, dispatch, pluginStateRef })
24
+ setUrlParsed(true)
25
+ return teardown
20
26
  }, [mapState.isMapReady])
21
27
 
22
28
  // Notify any plugins, that are listening, to the menu's state change
23
- useEffect(() => eventBus.emit('menu:changed', pluginState.menuState), [pluginState.menuState])
29
+ // and update the url to reflect the new menu state
30
+ useEffect(() => {
31
+ eventBus.emit('menu:changed', pluginState.menuState)
32
+ if (urlParsed) { // Don't update the url until we have 1st parsed the url and initialised the menu
33
+ updateUrl(pluginState)
34
+ }
35
+ }, [pluginState.menuState])
24
36
  }
@@ -1,11 +1,16 @@
1
1
  import { render } from '@testing-library/react'
2
2
  import { MenuInit } from './MenuInit.jsx'
3
3
  import { createMenu } from './createMenu.js'
4
+ import { updateUrl } from './updateUrl.js'
4
5
 
5
6
  jest.mock('./createMenu.js', () => ({
6
7
  createMenu: jest.fn()
7
8
  }))
8
9
 
10
+ jest.mock('./updateUrl.js', () => ({
11
+ updateUrl: jest.fn()
12
+ }))
13
+
9
14
  const mockRemove = jest.fn()
10
15
  const mockDispatch = jest.fn()
11
16
  const eventBus = { on: jest.fn(), off: jest.fn(), emit: jest.fn(), emitWhenRequested: jest.fn() }
@@ -47,4 +52,24 @@ describe('MenuInit', () => {
47
52
  rerender(<MenuInit mapState={{ isMapReady: true }} services={services} pluginState={pluginState} pluginConfig={pluginConfig} />)
48
53
  expect(createMenu).toHaveBeenCalledTimes(1)
49
54
  })
55
+
56
+ it('emits menu:changed with the current menu state', () => {
57
+ const menuState = { datasets: 'floodZones' }
58
+ render(<MenuInit mapState={{ isMapReady: true }} services={services} pluginState={{ ...pluginState, menuState }} pluginConfig={pluginConfig} />)
59
+ expect(eventBus.emit).toHaveBeenCalledWith('menu:changed', menuState)
60
+ })
61
+
62
+ it('does not update the url before the url has been parsed', () => {
63
+ render(<MenuInit mapState={{ isMapReady: false }} services={services} pluginState={pluginState} pluginConfig={pluginConfig} />)
64
+ expect(updateUrl).not.toHaveBeenCalled()
65
+ })
66
+
67
+ it('updates the url when the menu state changes after the url has been parsed', () => {
68
+ const { rerender } = render(<MenuInit mapState={{ isMapReady: true }} services={services} pluginState={pluginState} pluginConfig={pluginConfig} />)
69
+ expect(updateUrl).not.toHaveBeenCalled()
70
+
71
+ const changedState = { ...pluginState, menuState: { datasets: 'coastalErosion' } }
72
+ rerender(<MenuInit mapState={{ isMapReady: true }} services={services} pluginState={changedState} pluginConfig={pluginConfig} />)
73
+ expect(updateUrl).toHaveBeenCalledWith(changedState)
74
+ })
50
75
  })
@@ -1,7 +1,9 @@
1
1
  import { setDatasetRegistry } from '../registry/getDatasetRegistry.js'
2
+ import { buildMenuState } from '../reducers/menuStateReducer.js'
2
3
 
3
4
  export const createMenu = ({ menu, eventBus, dispatch, pluginStateRef }) => {
4
- dispatch({ type: 'SET_MENU', payload: { menu } })
5
+ const menuState = buildMenuState(menu)
6
+ dispatch({ type: 'SET_MENU', payload: { menu, menuState } })
5
7
  // Request a handle on the datasetsRegistry singleton, so that the menu plugin can access it when needed
6
8
  eventBus.requestOnce('datasets:registry', setDatasetRegistry)
7
9
  // add a listener for the menu:state event, which will be emitted whenever requested by other plugins,
@@ -14,24 +14,39 @@ const makeEventBus = () => ({
14
14
  })
15
15
 
16
16
  describe('createMenu', () => {
17
- it('dispatches SET_MENU with the menu', () => {
17
+ const menu = [{ id: 'datasets', type: 'radio', value: 'floodZones' }]
18
+
19
+ it('dispatches SET_MENU with the menu and the built menu state', () => {
18
20
  const eventBus = makeEventBus()
19
21
  const dispatch = jest.fn()
20
- const menu = [{ id: 'layer1' }]
21
22
  createMenu({ menu, eventBus, dispatch, pluginStateRef: {} })
22
- expect(dispatch).toHaveBeenCalledWith({ type: 'SET_MENU', payload: { menu } })
23
+ expect(dispatch).toHaveBeenCalledWith({
24
+ type: 'SET_MENU',
25
+ payload: { menu, menuState: { datasets: 'floodZones' } }
26
+ })
27
+ })
28
+
29
+ it('builds the menu state from the URL search params', () => {
30
+ window.history.replaceState({}, '', '?datasets=other')
31
+ const dispatch = jest.fn()
32
+ createMenu({ menu, eventBus: makeEventBus(), dispatch, pluginStateRef: {} })
33
+ expect(dispatch).toHaveBeenCalledWith({
34
+ type: 'SET_MENU',
35
+ payload: { menu, menuState: { datasets: 'other' } }
36
+ })
37
+ window.history.replaceState({}, '', window.location.pathname)
23
38
  })
24
39
 
25
40
  it('calls requestOnce for the datasets registry', () => {
26
41
  const eventBus = makeEventBus()
27
- createMenu({ eventBus, dispatch: jest.fn(), pluginStateRef: {} })
42
+ createMenu({ menu, eventBus, dispatch: jest.fn(), pluginStateRef: {} })
28
43
  expect(eventBus.requestOnce).toHaveBeenCalledWith('datasets:registry', setDatasetRegistry)
29
44
  })
30
45
 
31
46
  it('calls emitWhenRequested for menu:state', () => {
32
47
  const eventBus = makeEventBus()
33
48
  const pluginStateRef = { current: {} }
34
- createMenu({ eventBus, dispatch: jest.fn(), pluginStateRef })
49
+ createMenu({ menu, eventBus, dispatch: jest.fn(), pluginStateRef })
35
50
  expect(eventBus.emitWhenRequested).toHaveBeenCalledWith('menu:state', pluginStateRef)
36
51
  })
37
52
  })
@@ -0,0 +1,44 @@
1
+ import { isVisibleWhen } from '../registry/isVisibleWhen.js'
2
+
3
+ const _setRadioParam = (item, menuState, searchParams) => {
4
+ const { id: paramId } = item
5
+ const paramValue = menuState[paramId]
6
+ searchParams.set(paramId, paramValue)
7
+ }
8
+
9
+ const _setCheckBoxParameters = (item, menuState, searchParams) => {
10
+ const { id: paramId, items: checkboxes } = item
11
+ const paramValues = []
12
+ checkboxes.forEach(subItem => {
13
+ const { id: checkBoxId } = subItem
14
+ const checked = menuState[checkBoxId]
15
+ if (checked) {
16
+ paramValues.push(checkBoxId)
17
+ }
18
+ })
19
+ if (paramValues.length) {
20
+ searchParams.set(paramId, paramValues)
21
+ } else {
22
+ searchParams.delete(paramId)
23
+ }
24
+ }
25
+
26
+ export const updateUrl = (pluginState) => {
27
+ const url = new URL(window.location.href)
28
+ const { searchParams } = url
29
+ const { menu, menuState } = pluginState
30
+ menu.forEach(item => {
31
+ const { id: paramId, visibleWhen, type } = item
32
+ if (!isVisibleWhen(visibleWhen)) {
33
+ searchParams.delete(paramId)
34
+ return
35
+ }
36
+ if (type === 'radio') {
37
+ _setRadioParam(item, menuState, searchParams)
38
+ } else {
39
+ _setCheckBoxParameters(item, menuState, searchParams)
40
+ }
41
+ })
42
+ url.search = decodeURIComponent(url.search)
43
+ window.history.replaceState({}, '', url.toString())
44
+ }