@defra/interactive-map 0.0.39-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.
- package/dist/css/index.css +1 -1
- package/dist/esm/im-core.js +1 -1
- package/dist/esm/im-shell.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/control-definition.md +9 -1
- package/docs/api/slots.md +26 -5
- package/docs/api.md +4 -4
- package/docs/assets/images/slot-map.svg +61 -262
- package/docs/examples/draw-tools.mdx +3 -3
- package/docs/plugins/draw.md +80 -17
- package/docs/plugins/search.md +1 -1
- package/govuk-prototype-kit.config.json +2 -0
- package/jest.setup.js +5 -0
- package/package.json +9 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/datasets/dist/css/index.css +1 -1
- package/plugins/datasets/dist/esm/esriLayerAdapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-esri-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-ml-adapter.js +1 -1
- package/plugins/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/datasets/dist/umd/index.js +1 -1
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.js +2 -3
- package/plugins/datasets/src/adapters/esri/esriLayerAdapter.test.js +175 -0
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.js +1 -1
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
- package/plugins/datasets/src/adapters/loadLayerAdapter.js +1 -1
- package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +1 -3
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +17 -3
- package/plugins/datasets/src/api/setOpacity.test.js +9 -0
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.jsx +10 -25
- package/plugins/datasets/src/components/LayersMenu/LayersMenu.test.jsx +0 -42
- package/plugins/datasets/src/datasets.scss +0 -1
- package/plugins/datasets/src/fetch/createDynamicSource.js +135 -129
- package/plugins/datasets/src/fetch/createDynamicSource.test.js +318 -0
- package/plugins/datasets/src/fetch/fetchGeoJSON.test.js +83 -0
- package/plugins/datasets/src/index.test.js +36 -0
- package/plugins/datasets/src/initialise/DatasetsInit.jsx +17 -7
- package/plugins/datasets/src/initialise/DatasetsInit.test.jsx +262 -0
- package/plugins/datasets/src/initialise/initialiseDatasets.js +16 -5
- package/plugins/datasets/src/initialise/initialiseDatasets.test.js +42 -0
- package/plugins/datasets/src/manifest.js +0 -38
- package/plugins/datasets/src/manifest.test.js +49 -0
- package/plugins/datasets/src/reducers/datasetsToMenu.test.js +54 -1
- package/plugins/datasets/src/reducers/pluginState.js +3 -16
- package/plugins/datasets/src/reducers/pluginState.test.js +23 -0
- package/plugins/datasets/src/registry/dataset.js +15 -4
- package/plugins/datasets/src/registry/dataset.test.js +61 -0
- package/plugins/datasets/src/registry/datasetRegistry.js +12 -9
- package/plugins/datasets/src/registry/datasetRegistry.test.js +17 -5
- package/plugins/datasets/src/registry/globalDataset.js +0 -3
- package/plugins/datasets/src/registry/isVisibleWhen.js +6 -3
- package/plugins/datasets/src/registry/isVisibleWhen.test.js +11 -1
- package/plugins/datasets/src/utils/bbox.test.js +125 -0
- package/plugins/draw/dist/esm/im-draw-ml-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/esm/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/esm/index.js +1 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js +2 -1
- package/plugins/draw/dist/umd/im-draw-ml-adapter.js.LICENSE.txt +1 -0
- package/plugins/draw/dist/umd/im-draw-ol-adapter.js +1 -1
- package/plugins/draw/dist/umd/im-draw-plugin.js +1 -1
- package/plugins/draw/dist/umd/index.js +1 -1
- package/plugins/draw/src/DrawInit.jsx +12 -4
- package/plugins/draw/src/DrawInit.test.jsx +51 -10
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +92 -12
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.test.js +246 -4
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.js +109 -14
- package/plugins/draw/src/adapters/maplibre/mapboxDraw.test.js +174 -11
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/clickHandlers.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.js +9 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/lifecycle.test.js +24 -3
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawMode/pointerHandlers.test.js +1 -1
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.js +194 -0
- package/plugins/draw/src/adapters/maplibre/modes/drawPointMode.test.js +457 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/__helpers__/harness.js +102 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.js +82 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/keyboardHandlers.test.js +83 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.js +55 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointOperations.test.js +62 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.js +138 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/pointerHandlers.test.js +197 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.js +92 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/touchHandlers.test.js +101 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.js +46 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode/undoHandlers.test.js +42 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.js +151 -0
- package/plugins/draw/src/adapters/maplibre/modes/editPointMode.test.js +156 -0
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.js +5 -28
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/keyboardHandlers.test.js +24 -39
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/pointerHandlers.js +4 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.js +20 -23
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/touchHandlers.test.js +25 -5
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.js +6 -36
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/undoHandlers.test.js +7 -49
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.js +4 -54
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode/vertexOperations.test.js +8 -33
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.js +29 -72
- package/plugins/draw/src/adapters/maplibre/modes/editVertexMode.test.js +11 -4
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.js +158 -0
- package/plugins/draw/src/adapters/maplibre/pointSymbolImages.test.js +314 -0
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.js +6 -1
- package/plugins/draw/src/adapters/maplibre/snap/prototypePatches.test.js +21 -0
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.js +6 -2
- package/plugins/draw/src/adapters/maplibre/snap/snapInstance.test.js +12 -0
- package/plugins/draw/src/adapters/maplibre/styles.js +38 -11
- package/plugins/draw/src/adapters/maplibre/styles.test.js +39 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.js +79 -0
- package/plugins/draw/src/adapters/maplibre/utils/editModeEvents.test.js +135 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.js +42 -0
- package/plugins/draw/src/adapters/maplibre/utils/geometryValidation.test.js +85 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.js +34 -0
- package/plugins/draw/src/adapters/maplibre/utils/keyboardShortcuts.test.js +78 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.js +16 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapHelpers.test.js +21 -3
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.js +59 -0
- package/plugins/draw/src/adapters/maplibre/utils/snapMovement.test.js +73 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.js +33 -0
- package/plugins/draw/src/adapters/maplibre/utils/touchDragMath.test.js +70 -0
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.js +27 -2
- package/plugins/draw/src/adapters/openlayers/OLDrawAdapter.test.js +93 -0
- package/plugins/draw/src/adapters/openlayers/__helpers__/harness.js +9 -0
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.js +19 -1
- package/plugins/draw/src/adapters/openlayers/core/OLDrawManager.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.js +73 -1
- package/plugins/draw/src/adapters/openlayers/core/styles.test.js +122 -3
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.js +1 -0
- package/plugins/draw/src/adapters/openlayers/draw/DrawMode.test.js +27 -1
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +24 -4
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.test.js +47 -3
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.js +1 -1
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +32 -1
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +34 -1
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.js +5 -3
- package/plugins/draw/src/adapters/openlayers/edit/modifyInteraction.test.js +11 -0
- package/plugins/draw/src/adapters/openlayers/edit/nudge.js +12 -5
- package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +26 -3
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.js +18 -13
- package/plugins/draw/src/adapters/openlayers/edit/touchHandler.test.js +46 -1
- package/plugins/draw/src/adapters/openlayers/olDraw.js +11 -4
- package/plugins/draw/src/adapters/openlayers/olDraw.test.js +48 -6
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.js +156 -0
- package/plugins/draw/src/adapters/openlayers/point/drawPointMode.test.js +246 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.js +267 -0
- package/plugins/draw/src/adapters/openlayers/point/editPointMode.test.js +327 -0
- package/plugins/draw/src/adapters/openlayers/point/pointDragInteraction.js +71 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.js +34 -0
- package/plugins/draw/src/adapters/openlayers/point/pointOps.test.js +32 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.js +82 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSelectionState.test.js +107 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.js +83 -0
- package/plugins/draw/src/adapters/openlayers/point/pointSymbolImages.test.js +214 -0
- package/plugins/draw/src/adapters/openlayers/snap/snapIndicator.js +3 -1
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.js +6 -9
- package/plugins/draw/src/adapters/openlayers/snap/snapInteraction.test.js +15 -4
- package/plugins/draw/src/adapters/openlayers/utils/olCoords.js +1 -1
- package/plugins/draw/src/api/addFeature.js +16 -1
- package/plugins/draw/src/api/addFeature.test.js +62 -5
- package/plugins/draw/src/api/editFeature.js +7 -4
- package/plugins/draw/src/api/editFeature.test.js +16 -0
- package/plugins/draw/src/api/newPoint.js +42 -0
- package/plugins/draw/src/api/newPoint.test.js +117 -0
- package/plugins/draw/src/api/setStyle.js +43 -0
- package/plugins/draw/src/api/setStyle.test.js +75 -0
- package/plugins/draw/src/events.js +21 -14
- package/plugins/draw/src/events.test.js +15 -1
- package/plugins/draw/src/manifest.js +18 -6
- package/plugins/draw/src/manifest.test.js +32 -1
- package/plugins/draw/src/reducer.test.js +7 -0
- package/plugins/draw/src/utils/stripInternalProperties.js +19 -0
- package/plugins/draw/src/utils/stripInternalProperties.test.js +50 -0
- package/plugins/draw/src/utils/symbolKeys.js +5 -0
- package/plugins/draw/src/validation/liveDrawChecks.test.js +54 -0
- package/plugins/draw/src/validation/liveStroke.test.js +64 -1
- package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/index.js +1 -1
- package/plugins/interact/src/hooks/useCrossHairVisibility.js +12 -4
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +88 -1
- package/plugins/interact/src/hooks/useHighlightSync.js +33 -12
- package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
- package/plugins/interact/src/utils/featureQueries.js +18 -0
- package/plugins/interact/src/utils/featureQueries.test.js +15 -0
- package/plugins/interact/src/utils/spatial.js +9 -3
- package/plugins/interact/src/utils/spatial.test.js +12 -1
- package/plugins/map-key/dist/css/index.css +62 -0
- package/plugins/map-key/dist/esm/im-map-key-plugin.js +1 -0
- package/plugins/map-key/dist/esm/index.js +1 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js +2 -0
- package/plugins/map-key/dist/umd/im-map-key-plugin.js.LICENSE.txt +1 -0
- package/plugins/map-key/dist/umd/index.js +2 -0
- package/plugins/map-key/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/map-key/package.json +28 -0
- package/plugins/map-key/src/components/Key/EmptyKey.jsx +7 -0
- package/plugins/{datasets → map-key}/src/components/Key/EmptyKey.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/Key.jsx +41 -0
- package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +15 -14
- package/plugins/map-key/src/components/Key/Key.test.jsx +73 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.jsx +16 -0
- package/plugins/map-key/src/components/Key/KeyGroupItem.test.jsx +53 -0
- package/plugins/map-key/src/components/Key/KeyItem.jsx +29 -0
- package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
- package/plugins/map-key/src/components/Key/KeySvg.jsx +42 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
- package/plugins/map-key/src/components/Key/KeySvgLine.jsx +28 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgPattern.jsx +23 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +2 -2
- package/plugins/map-key/src/components/Key/KeySvgRect.jsx +33 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
- package/plugins/map-key/src/components/Key/KeySvgSymbol.jsx +27 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +5 -6
- package/plugins/map-key/src/components/Key/MapKey.jsx +50 -0
- package/plugins/map-key/src/components/Key/MapKey.test.jsx +130 -0
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.js +2 -2
- package/plugins/{datasets → map-key}/src/components/Key/svgProperties.test.js +2 -2
- package/plugins/map-key/src/index.js +13 -0
- package/plugins/map-key/src/index.test.js +31 -0
- package/plugins/map-key/src/initialise/MapKeyInit.jsx +15 -0
- package/plugins/map-key/src/initialise/MapKeyInit.test.jsx +39 -0
- package/plugins/map-key/src/manifest.js +30 -0
- package/plugins/map-key/src/manifest.test.js +63 -0
- package/plugins/map-key/src/mapKey.scss +4 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.js +6 -0
- package/plugins/map-key/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/map-key/src/registry/index.js +3 -0
- package/plugins/map-key/src/registry/index.test.js +15 -0
- package/plugins/menu/dist/css/index.css +80 -0
- package/plugins/menu/dist/esm/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/esm/index.js +1 -0
- package/plugins/menu/dist/umd/im-menu-plugin.js +1 -0
- package/plugins/menu/dist/umd/index.js +2 -0
- package/plugins/menu/dist/umd/index.js.LICENSE.txt +1 -0
- package/plugins/menu/package.json +28 -0
- package/plugins/menu/src/components/Menu/CheckboxGroupWrapper.jsx +21 -0
- package/plugins/menu/src/components/Menu/GroupLegend.jsx +17 -0
- package/plugins/menu/src/components/Menu/GroupLegend.test.jsx +68 -0
- package/plugins/menu/src/components/Menu/Menu.jsx +19 -0
- package/plugins/menu/src/components/Menu/Menu.module.scss +90 -0
- package/plugins/menu/src/components/Menu/Menu.test.jsx +161 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.jsx +35 -0
- package/plugins/menu/src/components/Menu/MenuCheckbox.test.jsx +93 -0
- package/plugins/menu/src/components/Menu/MenuGroup.jsx +11 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.jsx → menu/src/components/Menu/MenuRadio.jsx} +6 -4
- package/plugins/{datasets/src/components/LayersMenu/LayersMenuRadio.test.jsx → menu/src/components/Menu/MenuRadio.test.jsx} +18 -18
- package/plugins/menu/src/components/Menu/RadioGroupWrapper.jsx +32 -0
- package/plugins/{datasets/src/components/LayersMenu/LayersRadioGroupWrapper.test.jsx → menu/src/components/Menu/RadioGroupWrapper.test.jsx} +21 -21
- package/plugins/menu/src/components/Menu/useIdPrefix.jsx +4 -0
- package/plugins/menu/src/index.js +13 -0
- package/plugins/menu/src/index.test.js +31 -0
- package/plugins/menu/src/initialise/MenuInit.jsx +24 -0
- package/plugins/menu/src/initialise/MenuInit.test.jsx +50 -0
- package/plugins/menu/src/initialise/createMenu.js +10 -0
- package/plugins/menu/src/initialise/createMenu.test.js +37 -0
- package/plugins/menu/src/manifest.js +35 -0
- package/plugins/menu/src/manifest.test.js +63 -0
- package/plugins/menu/src/menu.scss +4 -0
- package/plugins/menu/src/reducers/menuStateReducer.test.js +38 -0
- package/plugins/menu/src/reducers/pluginState.js +35 -0
- package/plugins/menu/src/reducers/pluginState.test.js +57 -0
- package/plugins/menu/src/registry/getDatasetRegistry.js +9 -0
- package/plugins/menu/src/registry/getDatasetRegistry.test.js +23 -0
- package/plugins/menu/src/registry/index.js +3 -0
- package/plugins/menu/src/registry/index.test.js +15 -0
- package/plugins/menu/src/registry/isVisibleWhen.js +43 -0
- package/plugins/menu/src/registry/isVisibleWhen.test.js +48 -0
- package/plugins/search/dist/css/index.css +1 -1
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/esm/index.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/index.js +1 -1
- package/plugins/search/src/Search.jsx +7 -5
- package/plugins/search/src/components/Form/Form.module.scss +9 -20
- package/plugins/search/src/index.js +0 -1
- package/plugins/search/src/index.test.js +2 -4
- package/plugins/search/src/manifest.js +1 -1
- package/plugins/search/src/search.scss +17 -16
- package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/index.js +1 -1
- package/providers/beta/openlayers/src/openlayersProvider.js +4 -1
- package/providers/beta/openlayers/src/openlayersProvider.test.js +18 -0
- package/providers/beta/openlayers/src/utils/highlightFeatures.js +52 -5
- package/providers/beta/openlayers/src/utils/highlightFeatures.test.js +176 -0
- package/providers/beta/openlayers/src/utils/symbolImages.js +40 -0
- package/providers/beta/openlayers/src/utils/symbolImages.test.js +58 -0
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/index.js +1 -1
- package/providers/maplibre/src/utils/drawLayerBuckets.js +14 -0
- package/providers/maplibre/src/utils/drawLayerBuckets.test.js +18 -0
- package/providers/maplibre/src/utils/highlightFeatures.js +80 -55
- package/providers/maplibre/src/utils/highlightFeatures.test.js +156 -17
- package/providers/maplibre/src/utils/hoverCursor.js +30 -14
- package/providers/maplibre/src/utils/hoverCursor.test.js +35 -0
- package/providers/maplibre/src/utils/patternImages.js +1 -1
- package/providers/maplibre/src/utils/symbolImages.js +41 -3
- package/providers/maplibre/src/utils/symbolImages.test.js +40 -6
- package/rollup.esm.mjs +11 -1
- package/sonar-project.properties +7 -1
- package/src/App/components/Actions/Actions.test.jsx +47 -0
- package/src/App/components/Attributions/Attributions.module.scss +10 -0
- package/src/App/components/Hints/Hints.jsx +7 -2
- package/src/App/components/Hints/Hints.test.jsx +13 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +2 -3
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +3 -6
- package/src/App/components/{MoveControl/MoveControl.jsx → MoveControls/MoveControls.jsx} +10 -10
- package/src/App/components/{MoveControl/MoveControl.module.scss → MoveControls/MoveControls.module.scss} +60 -29
- package/src/App/components/{MoveControl/MoveControl.test.jsx → MoveControls/MoveControls.test.jsx} +48 -48
- package/src/App/components/Panel/Panel.jsx +18 -3
- package/src/App/components/Panel/Panel.module.scss +18 -8
- package/src/App/components/Panel/Panel.test.jsx +34 -0
- package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
- package/src/App/components/Viewport/Viewport.jsx +9 -1
- package/src/App/components/Viewport/Viewport.test.jsx +11 -0
- package/src/App/hooks/useFeatureItems.js +16 -7
- package/src/App/hooks/useFeatureItems.test.js +57 -0
- package/src/App/hooks/useLayoutMeasurements.js +95 -84
- package/src/App/hooks/useLayoutMeasurements.test.js +61 -1
- package/src/App/initialiseApp.js +11 -8
- package/src/App/initialiseApp.test.js +15 -3
- package/src/App/layout/Layout.jsx +12 -11
- package/src/App/layout/Layout.test.jsx +2 -0
- package/src/App/layout/layout.module.scss +31 -17
- package/src/App/registry/keyboardShortcutRegistry.js +25 -13
- package/src/App/registry/keyboardShortcutRegistry.test.js +49 -32
- package/src/App/registry/pluginRegistry.js +2 -3
- package/src/App/registry/pluginRegistry.test.js +16 -3
- package/src/App/renderer/HtmlElementHost.jsx +18 -5
- package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
- package/src/App/renderer/mapButtons.js +28 -12
- package/src/App/renderer/mapButtons.test.js +17 -4
- package/src/App/renderer/mapControls.js +3 -1
- package/src/App/renderer/mapControls.test.js +16 -0
- package/src/App/renderer/mapPanels.js +44 -9
- package/src/App/renderer/mapPanels.test.js +51 -2
- package/src/App/renderer/orderItems.js +28 -0
- package/src/App/renderer/orderItems.test.js +50 -0
- package/src/App/renderer/slotAggregator.js +2 -18
- package/src/App/renderer/slotHelpers.js +3 -1
- package/src/App/renderer/slotHelpers.test.js +5 -0
- package/src/App/renderer/slots.js +3 -0
- package/src/App/store/AppProvider.jsx +4 -2
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +8 -0
- package/src/InteractiveMap/InteractiveMap.js +8 -2
- package/src/InteractiveMap/InteractiveMap.test.js +20 -3
- package/src/config/appConfig.js +17 -15
- package/src/config/appConfig.test.js +22 -22
- package/src/config/defaults.js +3 -1
- package/src/config/events.js +2 -0
- package/src/config/mergeConfig.js +7 -0
- package/src/config/mergeConfig.test.js +20 -0
- package/src/scss/main.scss +1 -1
- package/src/scss/settings/_colors.scss +1 -0
- package/src/scss/settings/_dimensions.scss +2 -3
- package/src/scss/settings/_transition.scss +1 -1
- package/src/services/eventBus.js +44 -0
- package/src/services/eventBus.test.js +83 -0
- package/src/services/symbolRegistry.js +1 -1
- package/src/test-utils.js +5 -0
- package/src/types.js +25 -7
- package/webpack.umd.mjs +2 -0
- package/plugins/datasets/src/components/Key/EmptyKey.jsx +0 -7
- package/plugins/datasets/src/components/Key/Key.jsx +0 -50
- package/plugins/datasets/src/components/Key/KeyGroupItem.jsx +0 -18
- package/plugins/datasets/src/components/Key/KeyItem.jsx +0 -23
- package/plugins/datasets/src/components/Key/KeySvg.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgLine.jsx +0 -19
- package/plugins/datasets/src/components/Key/KeySvgPattern.jsx +0 -13
- package/plugins/datasets/src/components/Key/KeySvgRect.jsx +0 -22
- package/plugins/datasets/src/components/Key/KeySvgSymbol.jsx +0 -16
- package/plugins/datasets/src/components/LayersMenu/LayersRadioGroupWrapper.jsx +0 -41
- /package/plugins/{datasets → menu}/src/reducers/menuStateReducer.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.js +0 -0
- /package/{providers/maplibre/src → src}/utils/rasteriseToImageData.test.js +0 -0
|
@@ -29,6 +29,12 @@ jest.mock('@arcgis/core/layers/GroupLayer.js', () =>
|
|
|
29
29
|
}
|
|
30
30
|
})
|
|
31
31
|
)
|
|
32
|
+
jest.mock('@arcgis/core/layers/FeatureLayer.js', () =>
|
|
33
|
+
jest.fn().mockImplementation((opts = {}) => ({
|
|
34
|
+
...opts,
|
|
35
|
+
when: jest.fn().mockResolvedValue(undefined)
|
|
36
|
+
}))
|
|
37
|
+
)
|
|
32
38
|
|
|
33
39
|
// Uncovered: 124,145-149
|
|
34
40
|
|
|
@@ -290,4 +296,173 @@ describe('esriLayerAdapter', () => {
|
|
|
290
296
|
expect(applyStyleLayerVisibilitySpy.mock.calls).toHaveLength(7)
|
|
291
297
|
})
|
|
292
298
|
})
|
|
299
|
+
|
|
300
|
+
// ─── _reorderLayers with sketch layers ───────────────────────────────────────
|
|
301
|
+
|
|
302
|
+
describe('_reorderLayers', () => {
|
|
303
|
+
it('reorders sketch layers to the top when allLayers is present', () => {
|
|
304
|
+
const sketchLayer = { id: 'ketchLayer-0' }
|
|
305
|
+
const normalLayer = { id: 'roads' }
|
|
306
|
+
map.allLayers = { items: [normalLayer, sketchLayer] }
|
|
307
|
+
map.reorder = jest.fn()
|
|
308
|
+
|
|
309
|
+
adapter._reorderLayers()
|
|
310
|
+
|
|
311
|
+
expect(map.reorder).toHaveBeenCalledWith(sketchLayer, 2)
|
|
312
|
+
expect(map.reorder).not.toHaveBeenCalledWith(normalLayer, expect.anything())
|
|
313
|
+
})
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
// ─── _addFeatureLayers ────────────────────────────────────────────────────────
|
|
317
|
+
|
|
318
|
+
describe('_addFeatureLayers', () => {
|
|
319
|
+
beforeEach(() => {
|
|
320
|
+
datasetRegistry.mockExtend({
|
|
321
|
+
'feature-service': {
|
|
322
|
+
id: 'feature-service',
|
|
323
|
+
type: 'FeatureService',
|
|
324
|
+
tiles: 'https://example.com/featureserver/0',
|
|
325
|
+
visible: true,
|
|
326
|
+
style: {}
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
it('adds a FeatureLayer to the map and populates internal state', async () => {
|
|
332
|
+
const dataset = datasetRegistry.getDataset('feature-service')
|
|
333
|
+
await adapter._addFeatureLayers(dataset)
|
|
334
|
+
expect(adapter._mapVisibilityLayers['feature-service']).toBeDefined()
|
|
335
|
+
expect(adapter._mapOpacityLayers['feature-service']).toBeDefined()
|
|
336
|
+
expect(map.add).toHaveBeenCalled()
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
it('logs an error and returns null when map.add throws', async () => {
|
|
340
|
+
const { logger } = require('../../../../../src/services/logger.js')
|
|
341
|
+
const error = new Error('map add failed')
|
|
342
|
+
map.add = jest.fn().mockImplementation(() => { throw error })
|
|
343
|
+
|
|
344
|
+
const dataset = datasetRegistry.getDataset('feature-service')
|
|
345
|
+
const result = await adapter._addFeatureLayers(dataset)
|
|
346
|
+
|
|
347
|
+
expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('feature-service'), error)
|
|
348
|
+
expect(result).toBeNull()
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
// ─── _addLayers for FeatureService ───────────────────────────────────────────
|
|
353
|
+
|
|
354
|
+
describe('_addLayers for FeatureService type', () => {
|
|
355
|
+
it('delegates to _addFeatureLayers when dataset type is FeatureService', async () => {
|
|
356
|
+
datasetRegistry.mockExtend({
|
|
357
|
+
'fs-dataset': {
|
|
358
|
+
id: 'fs-dataset',
|
|
359
|
+
type: 'FeatureService',
|
|
360
|
+
tiles: 'https://example.com/fs/0',
|
|
361
|
+
visible: true,
|
|
362
|
+
style: {}
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
const addFeatureLayersSpy = jest.spyOn(adapter, '_addFeatureLayers')
|
|
366
|
+
const dataset = datasetRegistry.getDataset('fs-dataset')
|
|
367
|
+
await adapter._addLayers(dataset)
|
|
368
|
+
expect(addFeatureLayersSpy).toHaveBeenCalledWith(dataset)
|
|
369
|
+
})
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
// ─── _applyRegistryDatasetVisibility – visible=false branch ──────────────────
|
|
373
|
+
|
|
374
|
+
describe('_applyRegistryDatasetVisibility visible=false', () => {
|
|
375
|
+
it('sets vectorTileLayer.visible to false and skips sublayer style update', async () => {
|
|
376
|
+
const dataset = datasetRegistry.getDataset('esri-grouped')
|
|
377
|
+
await adapter._addLayers(dataset)
|
|
378
|
+
await adapter._applyRegistryDatasetVisibility(dataset)
|
|
379
|
+
expect(adapter._mapVisibilityLayers['esri-grouped'].visible).toBe(false)
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
it('returns early when the vector tile layer is not yet in the adapter', () => {
|
|
383
|
+
const dataset = datasetRegistry.getDataset('esri-standalone')
|
|
384
|
+
// No layers added — _mapVisibilityLayers is empty
|
|
385
|
+
expect(() => adapter._applyRegistryDatasetVisibility(dataset)).not.toThrow()
|
|
386
|
+
})
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
// ─── _addLayers – no tiles ────────────────────────────────────────────────────
|
|
390
|
+
|
|
391
|
+
describe('_addLayers with no tiles', () => {
|
|
392
|
+
it('returns null when the dataset has no tiles', async () => {
|
|
393
|
+
datasetRegistry.mockExtend({
|
|
394
|
+
'no-tiles': { id: 'no-tiles', visible: true, style: {} }
|
|
395
|
+
})
|
|
396
|
+
const result = await adapter._addLayers(datasetRegistry.getDataset('no-tiles'))
|
|
397
|
+
expect(result).toBeNull()
|
|
398
|
+
})
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
// ─── stub methods ─────────────────────────────────────────────────────────────
|
|
402
|
+
|
|
403
|
+
describe('stub adapter methods', () => {
|
|
404
|
+
it('applyFeatureFilter logs and resolves', async () => {
|
|
405
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
406
|
+
await adapter.applyFeatureFilter('roads')
|
|
407
|
+
expect(consoleSpy).toHaveBeenCalledWith('TODO: applyFeatureFilter', ['roads'])
|
|
408
|
+
consoleSpy.mockRestore()
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
it('setData logs and resolves', async () => {
|
|
412
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
413
|
+
await adapter.setData('roads', {})
|
|
414
|
+
expect(consoleSpy).toHaveBeenCalledWith('TODO: setData', ['roads', {}])
|
|
415
|
+
consoleSpy.mockRestore()
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
it('applyStyle logs and resolves', async () => {
|
|
419
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
420
|
+
await adapter.applyStyle('roads', {})
|
|
421
|
+
expect(consoleSpy).toHaveBeenCalledWith('TODO: applyStyle', ['roads', {}])
|
|
422
|
+
consoleSpy.mockRestore()
|
|
423
|
+
})
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
// ─── _applyStyleLayerPaintProperties – null paint properties ─────────────────
|
|
427
|
+
|
|
428
|
+
describe('_applyStyleLayerPaintProperties', () => {
|
|
429
|
+
it('does nothing when getPaintProperties returns null', async () => {
|
|
430
|
+
await adapter._addLayers(datasetRegistry.getDataset('esri-standalone'))
|
|
431
|
+
const vtl = adapter._mapVisibilityLayers['esri-standalone']
|
|
432
|
+
vtl.getPaintProperties = jest.fn().mockReturnValue(null)
|
|
433
|
+
|
|
434
|
+
adapter._applyStyleLayerPaintProperties(datasetRegistry.getDataset('esri-standalone'), vtl)
|
|
435
|
+
|
|
436
|
+
expect(vtl.setPaintProperties).not.toHaveBeenCalled()
|
|
437
|
+
})
|
|
438
|
+
})
|
|
439
|
+
|
|
440
|
+
// ─── onMapStyleChange for FeatureService ─────────────────────────────────────
|
|
441
|
+
|
|
442
|
+
describe('onMapStyleChange for FeatureService', () => {
|
|
443
|
+
it('sets renderer on FeatureLayer instead of applying style layer visibility', async () => {
|
|
444
|
+
datasetRegistry.mockExtend({
|
|
445
|
+
'fs-style': {
|
|
446
|
+
id: 'fs-style',
|
|
447
|
+
type: 'FeatureService',
|
|
448
|
+
tiles: 'https://example.com/fs/0',
|
|
449
|
+
visible: true,
|
|
450
|
+
style: {}
|
|
451
|
+
}
|
|
452
|
+
})
|
|
453
|
+
await adapter._addLayers(datasetRegistry.getDataset('fs-style'))
|
|
454
|
+
const featureLayer = adapter._mapVisibilityLayers['fs-style']
|
|
455
|
+
const setStyleLayerVisibilitySpy = jest.spyOn(adapter, '_applyStyleLayerVisibility')
|
|
456
|
+
|
|
457
|
+
await adapter.onMapStyleChange()
|
|
458
|
+
|
|
459
|
+
// The renderer property should be set (even if undefined for no-renderer datasets)
|
|
460
|
+
expect(Object.prototype.hasOwnProperty.call(featureLayer, 'renderer')).toBe(true)
|
|
461
|
+
// _applyStyleLayerVisibility should not be called for the FeatureService dataset
|
|
462
|
+
const fsCall = setStyleLayerVisibilitySpy.mock.calls.find(
|
|
463
|
+
([ds]) => ds?.id === 'fs-style'
|
|
464
|
+
)
|
|
465
|
+
expect(fsCall).toBeUndefined()
|
|
466
|
+
})
|
|
467
|
+
})
|
|
293
468
|
})
|
|
@@ -34,7 +34,7 @@ export class EsriDataset extends Dataset {
|
|
|
34
34
|
return undefined
|
|
35
35
|
}
|
|
36
36
|
const { mapStyle } = datasetRegistry
|
|
37
|
-
const renderer =
|
|
37
|
+
const renderer = structuredClone(rendererDefinition)
|
|
38
38
|
if (renderer.symbol?.color) {
|
|
39
39
|
renderer.symbol.color = getValueForStyle(renderer.symbol.color, mapStyle.id)
|
|
40
40
|
}
|
|
@@ -70,4 +70,59 @@ describe('EsriDataset', () => {
|
|
|
70
70
|
expect(datasetRegistry.getDataset('land-covers-other').useServerStyle).toBe(false)
|
|
71
71
|
})
|
|
72
72
|
})
|
|
73
|
+
|
|
74
|
+
// ─── renderer ───────────────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
describe('renderer', () => {
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
datasetRegistry.mockExtend({
|
|
79
|
+
'fs-no-renderer': { id: 'fs-no-renderer', type: 'FeatureService' },
|
|
80
|
+
'fs-with-renderer': {
|
|
81
|
+
id: 'fs-with-renderer',
|
|
82
|
+
type: 'FeatureService',
|
|
83
|
+
style: { renderer: { type: 'simple', symbol: { type: 'simple-fill' } } }
|
|
84
|
+
},
|
|
85
|
+
'fs-with-color': {
|
|
86
|
+
id: 'fs-with-color',
|
|
87
|
+
type: 'FeatureService',
|
|
88
|
+
style: {
|
|
89
|
+
renderer: {
|
|
90
|
+
type: 'simple',
|
|
91
|
+
symbol: {
|
|
92
|
+
color: { outdoor: '#ff0000', dark: '#ffffff' },
|
|
93
|
+
outline: { color: { outdoor: '#000000', dark: '#888888' } }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
'non-feature-service': { id: 'non-feature-service', type: 'VectorTileService' }
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('returns undefined for non-FeatureService datasets', () => {
|
|
103
|
+
expect(datasetRegistry.getDataset('non-feature-service').renderer).toBeUndefined()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('returns undefined for FeatureService dataset with no renderer definition', () => {
|
|
107
|
+
expect(datasetRegistry.getDataset('fs-no-renderer').renderer).toBeUndefined()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('returns cloned renderer object for dataset with renderer', () => {
|
|
111
|
+
const ds = datasetRegistry.getDataset('fs-with-renderer')
|
|
112
|
+
const renderer = ds.renderer
|
|
113
|
+
expect(renderer).toEqual({ type: 'simple', symbol: { type: 'simple-fill' } })
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('resolves symbol.color via getValueForStyle', () => {
|
|
117
|
+
const ds = datasetRegistry.getDataset('fs-with-color')
|
|
118
|
+
const renderer = ds.renderer
|
|
119
|
+
expect(renderer.symbol.color).toBe('#ff0000')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('resolves symbol.outline.color via getValueForStyle', () => {
|
|
123
|
+
const ds = datasetRegistry.getDataset('fs-with-color')
|
|
124
|
+
const renderer = ds.renderer
|
|
125
|
+
expect(renderer.symbol.outline.color).toBe('#000000')
|
|
126
|
+
})
|
|
127
|
+
})
|
|
73
128
|
})
|
|
@@ -8,7 +8,7 @@ const importLayerAdapter = async (mapProvider) => {
|
|
|
8
8
|
const { default: LayerAdapter } = await import(/* webpackChunkName: "im-datasets-esri-adapter" */ './esri/esriLayerAdapter.js')
|
|
9
9
|
return LayerAdapter
|
|
10
10
|
}
|
|
11
|
-
//
|
|
11
|
+
// Once they are ready, add cases for OpenLayersProvider and potentially LeafletProvider
|
|
12
12
|
default: {
|
|
13
13
|
throw new Error(`No layer adapter available for map provider ${mapProvider.name}. Please provide a compatible layer adapter.`)
|
|
14
14
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { loadLayerAdapter, layerAdapter } from './loadLayerAdapter.js'
|
|
2
|
+
|
|
3
|
+
const makeAdapterInstance = (type) => ({
|
|
4
|
+
type,
|
|
5
|
+
removeDataset: jest.fn(),
|
|
6
|
+
setData: jest.fn(),
|
|
7
|
+
applyStyle: jest.fn(),
|
|
8
|
+
applyDatasetVisibility: jest.fn(),
|
|
9
|
+
applyGlobalVisibility: jest.fn(),
|
|
10
|
+
applyDatasetOpacity: jest.fn(),
|
|
11
|
+
applyGlobalOpacity: jest.fn(),
|
|
12
|
+
addDataset: jest.fn(),
|
|
13
|
+
applyFeatureFilter: jest.fn(),
|
|
14
|
+
onMapStyleChange: jest.fn(),
|
|
15
|
+
onMapSizeChange: jest.fn()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
jest.mock('./maplibre/maplibreLayerAdapter.js', () => ({
|
|
19
|
+
__esModule: true,
|
|
20
|
+
default: jest.fn().mockImplementation(() => makeAdapterInstance('maplibre'))
|
|
21
|
+
}))
|
|
22
|
+
jest.mock('./esri/esriLayerAdapter.js', () => ({
|
|
23
|
+
__esModule: true,
|
|
24
|
+
default: jest.fn().mockImplementation(() => makeAdapterInstance('esri'))
|
|
25
|
+
}))
|
|
26
|
+
|
|
27
|
+
const makeMapProvider = (name) => ({ name })
|
|
28
|
+
const symbolRegistry = {}
|
|
29
|
+
const patternRegistry = {}
|
|
30
|
+
|
|
31
|
+
describe('loadLayerAdapter', () => {
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
jest.clearAllMocks()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('loads the MapLibre adapter for MapLibreProvider', async () => {
|
|
37
|
+
const mapProvider = makeMapProvider('MapLibreProvider')
|
|
38
|
+
const adapter = await loadLayerAdapter(mapProvider, symbolRegistry, patternRegistry)
|
|
39
|
+
expect(adapter.type).toBe('maplibre')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('loads the Esri adapter for EsriProvider', async () => {
|
|
43
|
+
const mapProvider = makeMapProvider('EsriProvider')
|
|
44
|
+
const adapter = await loadLayerAdapter(mapProvider, symbolRegistry, patternRegistry)
|
|
45
|
+
expect(adapter.type).toBe('esri')
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('throws for an unknown provider', async () => {
|
|
49
|
+
const mapProvider = makeMapProvider('UnknownProvider')
|
|
50
|
+
await expect(loadLayerAdapter(mapProvider, symbolRegistry, patternRegistry))
|
|
51
|
+
.rejects.toThrow('No layer adapter available for map provider UnknownProvider')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('assigns adapter methods to the layerAdapter proxy object', async () => {
|
|
55
|
+
const mapProvider = makeMapProvider('MapLibreProvider')
|
|
56
|
+
await loadLayerAdapter(mapProvider, symbolRegistry, patternRegistry)
|
|
57
|
+
expect(typeof layerAdapter.addDataset).toBe('function')
|
|
58
|
+
expect(typeof layerAdapter.removeDataset).toBe('function')
|
|
59
|
+
expect(typeof layerAdapter.setData).toBe('function')
|
|
60
|
+
})
|
|
61
|
+
})
|
|
@@ -103,7 +103,6 @@ export default class MaplibreLayerAdapter extends LayerAdapter {
|
|
|
103
103
|
this._applyFeatureFilter(registryDataset)
|
|
104
104
|
})
|
|
105
105
|
|
|
106
|
-
// TODO: check dynamicSources still work
|
|
107
106
|
// Re-push cached data for dynamic sources
|
|
108
107
|
this.dynamicSources.forEach(source => source.reapply())
|
|
109
108
|
}
|
|
@@ -165,8 +164,7 @@ export default class MaplibreLayerAdapter extends LayerAdapter {
|
|
|
165
164
|
|
|
166
165
|
// Remove source if no other dataset is using it
|
|
167
166
|
const sourceIsShared = datasetRegistry.topLevelDatasets()
|
|
168
|
-
.
|
|
169
|
-
.length > 0
|
|
167
|
+
.some(dataset => dataset.id !== datasetId && dataset.sourceId === sourceId)
|
|
170
168
|
|
|
171
169
|
if (!sourceIsShared && this._map.getSource(sourceId)) {
|
|
172
170
|
this._map.removeSource(sourceId)
|
|
@@ -260,7 +260,7 @@ describe('removeDataset', () => {
|
|
|
260
260
|
it('does nothing when the dataset is not in the registry', () => {
|
|
261
261
|
const removeBefore = map.removeLayer.mock.calls.length
|
|
262
262
|
adapter.removeDataset('nonexistent')
|
|
263
|
-
expect(map.removeLayer.mock.calls
|
|
263
|
+
expect(map.removeLayer.mock.calls).toHaveLength(removeBefore)
|
|
264
264
|
})
|
|
265
265
|
})
|
|
266
266
|
|
|
@@ -313,7 +313,7 @@ describe('applyDatasetVisibility', () => {
|
|
|
313
313
|
it('does nothing for an unknown dataset', () => {
|
|
314
314
|
const before = map.setLayoutProperty.mock.calls.length
|
|
315
315
|
adapter.applyDatasetVisibility('unknown')
|
|
316
|
-
expect(map.setLayoutProperty.mock.calls
|
|
316
|
+
expect(map.setLayoutProperty.mock.calls).toHaveLength(before)
|
|
317
317
|
})
|
|
318
318
|
|
|
319
319
|
it('skips setLayoutProperty for a layer that has been removed from the map', () => {
|
|
@@ -418,7 +418,7 @@ describe('applyDatasetOpacity', () => {
|
|
|
418
418
|
it('does nothing for an unknown dataset', () => {
|
|
419
419
|
const before = map.setPaintProperty.mock.calls.length
|
|
420
420
|
adapter.applyDatasetOpacity('unknown')
|
|
421
|
-
expect(map.setPaintProperty.mock.calls
|
|
421
|
+
expect(map.setPaintProperty.mock.calls).toHaveLength(before)
|
|
422
422
|
})
|
|
423
423
|
|
|
424
424
|
it('does not call setPaintProperty for a layer that has been removed from the map (covers _setPaintOpacity early return)', () => {
|
|
@@ -556,3 +556,17 @@ describe('onMapSizeChange', () => {
|
|
|
556
556
|
expect(symbolUpdates).toHaveLength(0)
|
|
557
557
|
})
|
|
558
558
|
})
|
|
559
|
+
|
|
560
|
+
// ─── onMapStyleChange – dynamic source reapply ────────────────────────────────
|
|
561
|
+
|
|
562
|
+
describe('onMapStyleChange with dynamic sources', () => {
|
|
563
|
+
beforeEach(async () => { await adapter.init() })
|
|
564
|
+
|
|
565
|
+
it('calls reapply() on each attached dynamic source after style change', async () => {
|
|
566
|
+
const source = { reapply: jest.fn() }
|
|
567
|
+
const sources = new Map([['parcels', source]])
|
|
568
|
+
adapter.attachDynamicSources(sources)
|
|
569
|
+
await adapter.onMapStyleChange(MAP_STYLE, new Map())
|
|
570
|
+
expect(source.reapply).toHaveBeenCalled()
|
|
571
|
+
})
|
|
572
|
+
})
|
|
@@ -28,4 +28,13 @@ describe('setOpacity', () => {
|
|
|
28
28
|
payload: { opacity: 0.8 }
|
|
29
29
|
})
|
|
30
30
|
})
|
|
31
|
+
|
|
32
|
+
it('dispatches SET_GLOBAL_OPACITY when options argument is omitted', () => {
|
|
33
|
+
setOpacity({ pluginState: { dispatch } }, 0.5)
|
|
34
|
+
|
|
35
|
+
expect(dispatch).toHaveBeenCalledWith({
|
|
36
|
+
type: 'SET_GLOBAL_OPACITY',
|
|
37
|
+
payload: { opacity: 0.5 }
|
|
38
|
+
})
|
|
39
|
+
})
|
|
31
40
|
})
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { setDatasetVisibility } from '../../api/setDatasetVisibility.js'
|
|
3
3
|
import { LayersMenuCheckbox } from './LayersMenuCheckbox.jsx'
|
|
4
|
-
import { LayersRadioGroupWrapper } from './LayersRadioGroupWrapper.jsx'
|
|
5
4
|
import { LayersMenuGroupWrapper } from './LayersMenuGroupWrapper.jsx'
|
|
6
5
|
|
|
7
6
|
export const LayersMenu = ({ pluginState }) => {
|
|
@@ -17,32 +16,18 @@ export const LayersMenu = ({ pluginState }) => {
|
|
|
17
16
|
return (
|
|
18
17
|
<div className={containerClass}>
|
|
19
18
|
{// Each menuGroup
|
|
20
|
-
menu.map(menuGroup =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
menuGroupItem={menuGroupItem}
|
|
30
|
-
onChange={handleDatasetChange}
|
|
31
|
-
/>)
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
</LayersMenuGroupWrapper>
|
|
35
|
-
)
|
|
36
|
-
} else {
|
|
37
|
-
return (
|
|
38
|
-
<LayersRadioGroupWrapper
|
|
39
|
-
key={menuGroup.id}
|
|
40
|
-
menuGroup={menuGroup}
|
|
41
|
-
pluginState={pluginState}
|
|
42
|
-
/>
|
|
19
|
+
menu.map(menuGroup => (
|
|
20
|
+
<LayersMenuGroupWrapper key={menuGroup.id} menuGroup={menuGroup}> {
|
|
21
|
+
// Each menuGroupItem
|
|
22
|
+
menuGroup.items.map(menuGroupItem => (
|
|
23
|
+
<LayersMenuCheckbox
|
|
24
|
+
key={menuGroupItem.id}
|
|
25
|
+
menuGroupItem={menuGroupItem}
|
|
26
|
+
onChange={handleDatasetChange}
|
|
27
|
+
/>)
|
|
43
28
|
)
|
|
44
29
|
}
|
|
45
|
-
|
|
30
|
+
</LayersMenuGroupWrapper>)
|
|
46
31
|
)
|
|
47
32
|
}
|
|
48
33
|
</div>
|
|
@@ -20,12 +20,6 @@ jest.mock('./LayersMenuCheckbox.jsx', () => ({
|
|
|
20
20
|
}
|
|
21
21
|
}))
|
|
22
22
|
|
|
23
|
-
jest.mock('./LayersRadioGroupWrapper.jsx', () => ({
|
|
24
|
-
LayersRadioGroupWrapper: ({ menuGroup }) => (
|
|
25
|
-
<div data-testid='layers-radio-group-wrapper' data-group-id={menuGroup.id} />
|
|
26
|
-
)
|
|
27
|
-
}))
|
|
28
|
-
|
|
29
23
|
jest.mock('./LayersMenuGroupWrapper.jsx', () => ({
|
|
30
24
|
LayersMenuGroupWrapper: ({ menuGroup, children }) => (
|
|
31
25
|
<div data-testid='layers-menu-group-wrapper' data-group-id={menuGroup.id}>
|
|
@@ -108,42 +102,6 @@ describe('LayersMenu', () => {
|
|
|
108
102
|
})
|
|
109
103
|
})
|
|
110
104
|
|
|
111
|
-
describe('radio groups', () => {
|
|
112
|
-
it('renders a LayersRadioGroupWrapper for non-checkbox groups', () => {
|
|
113
|
-
const pluginState = makePluginState([
|
|
114
|
-
{ id: 'r1', type: 'radio', items: [{ id: 'opt1' }, { id: 'opt2' }] }
|
|
115
|
-
])
|
|
116
|
-
const { getAllByTestId } = render(<LayersMenu pluginState={pluginState} />)
|
|
117
|
-
expect(getAllByTestId('layers-radio-group-wrapper')).toHaveLength(1)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('passes the correct group to LayersRadioGroupWrapper', () => {
|
|
121
|
-
const pluginState = makePluginState([
|
|
122
|
-
{ id: 'radio-group-1', type: 'radio', items: [] }
|
|
123
|
-
])
|
|
124
|
-
const { getByTestId } = render(<LayersMenu pluginState={pluginState} />)
|
|
125
|
-
expect(getByTestId('layers-radio-group-wrapper').dataset.groupId).toBe('radio-group-1')
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it('does not render a LayersMenuGroupWrapper for radio groups', () => {
|
|
129
|
-
const pluginState = makePluginState([{ id: 'r1', type: 'radio', items: [] }])
|
|
130
|
-
const { queryByTestId } = render(<LayersMenu pluginState={pluginState} />)
|
|
131
|
-
expect(queryByTestId('layers-menu-group-wrapper')).toBeNull()
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
describe('mixed groups', () => {
|
|
136
|
-
it('renders both checkbox and radio wrappers when both types are present', () => {
|
|
137
|
-
const pluginState = makePluginState([
|
|
138
|
-
{ id: 'c1', type: 'checkbox', items: [] },
|
|
139
|
-
{ id: 'r1', type: 'radio', items: [] }
|
|
140
|
-
])
|
|
141
|
-
const { getByTestId } = render(<LayersMenu pluginState={pluginState} />)
|
|
142
|
-
expect(getByTestId('layers-menu-group-wrapper')).toBeTruthy()
|
|
143
|
-
expect(getByTestId('layers-radio-group-wrapper')).toBeTruthy()
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
|
|
147
105
|
describe('handleDatasetChange', () => {
|
|
148
106
|
it('calls setDatasetVisibility with the correct arguments when a checkbox changes', () => {
|
|
149
107
|
const pluginState = makePluginState([
|