@defra/interactive-map 0.0.40-alpha → 0.0.42-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/button-definition.md +7 -8
- package/docs/api/control-definition.md +17 -1
- package/docs/api/panel-definition.md +5 -0
- package/docs/api/slots.md +50 -6
- package/docs/assets/images/slot-map.svg +61 -262
- package/docs/examples/add-polygons.mdx +8 -2
- package/docs/examples/add-symbols.mdx +8 -2
- package/docs/examples/draw-tools.mdx +3 -3
- package/docs/plugins/datasets.md +23 -15
- package/docs/plugins/draw.md +79 -16
- package/docs/plugins/map-key.md +147 -0
- package/docs/plugins/search.md +1 -1
- package/docs/plugins.md +5 -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/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/beta/use-location/dist/esm/im-use-location-plugin.js +1 -1
- package/plugins/beta/use-location/dist/umd/im-use-location-plugin.js +1 -1
- package/plugins/beta/use-location/src/manifest.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.test.js +175 -0
- package/plugins/datasets/src/adapters/esri/registry/esriDataset.test.js +55 -0
- package/plugins/datasets/src/adapters/loadLayerAdapter.test.js +61 -0
- package/plugins/datasets/src/adapters/maplibre/maplibreLayerAdapter.test.js +14 -0
- 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 -4
- 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 +13 -1
- package/plugins/datasets/src/registry/dataset.test.js +61 -0
- package/plugins/datasets/src/registry/datasetRegistry.js +12 -6
- package/plugins/datasets/src/registry/datasetRegistry.test.js +16 -4
- 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 +10 -2
- package/plugins/draw/src/DrawInit.test.jsx +51 -10
- package/plugins/draw/src/adapters/maplibre/MaplibreDrawAdapter.js +91 -11
- 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/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 +4 -27
- 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 +3 -53
- 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 +10 -3
- 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.test.js +12 -0
- package/plugins/draw/src/adapters/openlayers/draw/drawInput.js +8 -2
- package/plugins/draw/src/adapters/openlayers/edit/EditMode.test.js +31 -0
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.js +9 -5
- package/plugins/draw/src/adapters/openlayers/edit/keyboardHandler.test.js +33 -0
- 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 +10 -3
- package/plugins/draw/src/adapters/openlayers/edit/nudge.test.js +24 -1
- 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/createNewShape.js +41 -0
- package/plugins/draw/src/api/createNewShape.test.js +63 -0
- package/plugins/draw/src/api/editFeature.js +7 -4
- package/plugins/draw/src/api/editFeature.test.js +16 -0
- package/plugins/draw/src/api/newLine.js +2 -40
- package/plugins/draw/src/api/newPoint.js +42 -0
- package/plugins/draw/src/api/newPoint.test.js +117 -0
- package/plugins/draw/src/api/newPolygon.js +2 -40
- 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 +17 -10
- package/plugins/draw/src/events.test.js +14 -0
- 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/useHighlightSync.js +33 -12
- package/plugins/interact/src/hooks/useHighlightSync.test.js +96 -25
- package/plugins/interact/src/manifest.js +1 -1
- 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 +68 -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 +43 -0
- package/plugins/{datasets → map-key}/src/components/Key/Key.module.scss +21 -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 +26 -0
- package/plugins/map-key/src/components/Key/KeyItem.test.jsx +67 -0
- package/plugins/map-key/src/components/Key/KeySvg.jsx +41 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvg.test.jsx +14 -12
- package/plugins/map-key/src/components/Key/KeySvgLine.jsx +22 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgLine.test.jsx +1 -1
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.jsx +7 -2
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgPattern.test.jsx +8 -2
- package/plugins/map-key/src/components/Key/KeySvgRect.jsx +26 -0
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgRect.test.jsx +1 -1
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.jsx +8 -3
- package/plugins/{datasets → map-key}/src/components/Key/KeySvgSymbol.test.jsx +17 -6
- package/plugins/map-key/src/components/Key/MapKey.jsx +53 -0
- package/plugins/map-key/src/components/Key/MapKey.test.jsx +147 -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 +2 -3
- 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/src/App/components/Actions/Actions.test.jsx +47 -0
- package/src/App/components/Hints/Hints.test.jsx +13 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +25 -23
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +22 -5
- package/src/App/components/MoveControls/MoveControls.module.scss +41 -10
- package/src/App/components/Panel/Panel.jsx +65 -8
- package/src/App/components/Panel/Panel.module.scss +49 -15
- package/src/App/components/Panel/Panel.test.jsx +114 -1
- package/src/App/components/Tabs/Tabs.jsx +43 -17
- package/src/App/components/Tabs/Tabs.module.scss +32 -5
- package/src/App/components/Tabs/Tabs.test.jsx +40 -10
- package/src/App/components/Tooltip/Tooltip.test.jsx +12 -14
- 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/layout/Layout.jsx +9 -10
- package/src/App/layout/Layout.test.jsx +2 -0
- package/src/App/layout/layout.module.scss +31 -17
- package/src/App/registry/pluginRegistry.js +1 -1
- package/src/App/registry/pluginRegistry.test.js +12 -0
- package/src/App/renderer/HtmlElementHost.jsx +18 -5
- package/src/App/renderer/HtmlElementHost.test.jsx +54 -0
- package/src/App/renderer/groupByKey.js +28 -0
- package/src/App/renderer/groupByKey.test.js +39 -0
- package/src/App/renderer/groupIntoTabs.js +42 -0
- package/src/App/renderer/groupIntoTabs.test.js +95 -0
- package/src/App/renderer/mapButtons.js +97 -129
- package/src/App/renderer/mapButtons.test.js +67 -83
- package/src/App/renderer/mapControls.js +4 -1
- package/src/App/renderer/mapControls.test.js +32 -0
- package/src/App/renderer/mapPanels.js +53 -11
- package/src/App/renderer/mapPanels.test.js +95 -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 +1 -0
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +8 -0
- package/src/config/appConfig.js +2 -2
- package/src/config/events.js +2 -0
- 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/types.js +31 -3
- 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/KeySvgRect.jsx +0 -22
- 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
|
@@ -1,21 +1,28 @@
|
|
|
1
|
+
|
|
1
2
|
// When groups are present, every direct child gets a border-top
|
|
2
|
-
.im-c-
|
|
3
|
+
.im-c-map-key > *:first-child {
|
|
3
4
|
padding-top: 5px;
|
|
4
5
|
|
|
5
|
-
.im-c-
|
|
6
|
+
.im-c-map-key__group-heading {
|
|
6
7
|
padding-top: 0;
|
|
7
8
|
}
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
.im-c-
|
|
11
|
+
.im-c-map-key--has-groups > *:not(:first-child) {
|
|
11
12
|
border-top: 1px solid var(--button-hover-color);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
.im-c-
|
|
15
|
+
.im-c-map-key__group:not(:last-child) {
|
|
15
16
|
padding-bottom: 5px;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
.im-c-
|
|
19
|
+
.im-c-map-key__empty-message {
|
|
20
|
+
margin: 0;
|
|
21
|
+
font-size: 1rem;
|
|
22
|
+
color: var(--foreground-color);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.im-c-map-key__group-heading {
|
|
19
26
|
padding-top: 15px;
|
|
20
27
|
padding-bottom: 10px;
|
|
21
28
|
margin: 0;
|
|
@@ -24,7 +31,7 @@
|
|
|
24
31
|
color: var(--foreground-color);
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
.im-c-
|
|
34
|
+
.im-c-map-key__item {
|
|
28
35
|
display: flex;
|
|
29
36
|
align-items: start;
|
|
30
37
|
padding-top: 10px;
|
|
@@ -32,38 +39,38 @@
|
|
|
32
39
|
font-size: 1rem;
|
|
33
40
|
|
|
34
41
|
// First item inside a group — heading already provides top spacing
|
|
35
|
-
.im-c-
|
|
42
|
+
.im-c-map-key__group &:first-child {
|
|
36
43
|
padding-top: 0;
|
|
37
44
|
}
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
.im-c-
|
|
47
|
+
.im-c-map-key--has-groups > .im-c-map-key__item:not(:first-child) {
|
|
41
48
|
padding-top: 15px;
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
.im-c-
|
|
51
|
+
.im-c-map-key--has-groups > .im-c-map-key__item {
|
|
45
52
|
padding-bottom: 15px;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
.im-c-
|
|
55
|
+
.im-c-map-key__group .im-c-map-key__item {
|
|
49
56
|
padding-top: 10px;
|
|
50
57
|
padding-bottom: 10px;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
// Last item in all scenarios — flat or inside the last group
|
|
54
|
-
.im-c-
|
|
55
|
-
.im-c-
|
|
61
|
+
.im-c-map-key > .im-c-map-key__item:last-child,
|
|
62
|
+
.im-c-map-key__group:last-child .im-c-map-key__item:last-child {
|
|
56
63
|
padding-bottom: 5px;
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
// Symbol
|
|
60
67
|
|
|
61
|
-
.am-c-
|
|
68
|
+
.am-c-map-key-symbol {
|
|
62
69
|
position: relative;
|
|
63
70
|
flex-shrink: 0;
|
|
64
71
|
margin: 0 13px 0 3px;
|
|
65
72
|
}
|
|
66
73
|
|
|
67
|
-
.am-c-
|
|
74
|
+
.am-c-map-key-symbol--point {
|
|
68
75
|
margin: -12px 1px -12px -9px;
|
|
69
76
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react'
|
|
2
|
+
import { Key } from './Key'
|
|
3
|
+
|
|
4
|
+
jest.mock('./EmptyKey.jsx', () => ({
|
|
5
|
+
EmptyKey: ({ text }) => <div data-testid='empty-key'>{text}</div>
|
|
6
|
+
}))
|
|
7
|
+
|
|
8
|
+
jest.mock('./KeyItem.jsx', () => ({
|
|
9
|
+
KeyItem: () => <div data-testid='key-item' />
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
jest.mock('./KeyGroupItem.jsx', () => ({
|
|
13
|
+
KeyGroupItem: ({ label }) => <div data-testid='key-group-item'>{label}</div>
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
const mapStyle = { id: 'default' }
|
|
17
|
+
|
|
18
|
+
describe('Key', () => {
|
|
19
|
+
it('renders EmptyKey when keyGroups is undefined', () => {
|
|
20
|
+
render(<Key mapStyle={mapStyle} />)
|
|
21
|
+
expect(screen.getByTestId('empty-key')).toBeTruthy()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('renders EmptyKey when keyGroups is an empty array', () => {
|
|
25
|
+
render(<Key mapStyle={mapStyle} keyGroups={[]} />)
|
|
26
|
+
expect(screen.getByTestId('empty-key')).toBeTruthy()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('passes noKeyItemText to EmptyKey', () => {
|
|
30
|
+
render(<Key mapStyle={mapStyle} noKeyItemText='No items' />)
|
|
31
|
+
expect(screen.getByText('No items')).toBeTruthy()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('renders the wrapper div with the base class', () => {
|
|
35
|
+
const { container } = render(<Key mapStyle={mapStyle} keyGroups={[{ id: '1', keyDefinition: { id: '1' } }]} />)
|
|
36
|
+
expect(container.querySelector('.im-c-map-key')).toBeTruthy()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('adds the groups class when hasGroups is true', () => {
|
|
40
|
+
const { container } = render(<Key mapStyle={mapStyle} keyGroups={[{ id: '1', keyDefinition: { id: '1' } }]} hasGroups />)
|
|
41
|
+
expect(container.querySelector('.im-c-map-key--has-groups')).toBeTruthy()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('does not add the groups class when hasGroups is false', () => {
|
|
45
|
+
const { container } = render(<Key mapStyle={mapStyle} keyGroups={[{ id: '1', keyDefinition: { id: '1' } }]} hasGroups={false} />)
|
|
46
|
+
expect(container.querySelector('.im-c-map-key--has-groups')).toBeNull()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('renders KeyItem for a non-group item', () => {
|
|
50
|
+
render(<Key mapStyle={mapStyle} keyGroups={[{ id: '1', keyDefinition: { id: '1' } }]} />)
|
|
51
|
+
expect(screen.getByTestId('key-item')).toBeTruthy()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('renders KeyGroupItem for a group item', () => {
|
|
55
|
+
render(<Key mapStyle={mapStyle} keyGroups={[{ id: '1', type: 'group', groupLabel: 'Group A', keyDefinitions: [] }]} />)
|
|
56
|
+
expect(screen.getByTestId('key-group-item')).toBeTruthy()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('passes groupLabel to KeyGroupItem', () => {
|
|
60
|
+
render(<Key mapStyle={mapStyle} keyGroups={[{ id: '1', type: 'group', groupLabel: 'My Group', keyDefinitions: [] }]} />)
|
|
61
|
+
expect(screen.getByText('My Group')).toBeTruthy()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('renders mixed group and non-group items', () => {
|
|
65
|
+
const keyGroups = [
|
|
66
|
+
{ id: '1', keyDefinition: { id: '1' } },
|
|
67
|
+
{ id: '2', type: 'group', groupLabel: 'Group A', keyDefinitions: [] }
|
|
68
|
+
]
|
|
69
|
+
render(<Key mapStyle={mapStyle} keyGroups={keyGroups} />)
|
|
70
|
+
expect(screen.getAllByTestId('key-item')).toHaveLength(1)
|
|
71
|
+
expect(screen.getAllByTestId('key-group-item')).toHaveLength(1)
|
|
72
|
+
})
|
|
73
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { KeyItem } from './KeyItem.jsx'
|
|
2
|
+
|
|
3
|
+
export const KeyGroupItem = ({ headingId, label, keyDefinitions, mapStyle }) => {
|
|
4
|
+
return (
|
|
5
|
+
<section className='im-c-map-key__group' aria-labelledby={headingId}>
|
|
6
|
+
<h3 id={headingId} className='im-c-map-key__group-heading'>{label}</h3>
|
|
7
|
+
{keyDefinitions.map(keyDefinition =>
|
|
8
|
+
<KeyItem
|
|
9
|
+
key={`${keyDefinition.id}`}
|
|
10
|
+
keyDefinition={keyDefinition}
|
|
11
|
+
mapStyle={mapStyle}
|
|
12
|
+
/>
|
|
13
|
+
)}
|
|
14
|
+
</section>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react'
|
|
2
|
+
import { KeyGroupItem } from './KeyGroupItem'
|
|
3
|
+
|
|
4
|
+
jest.mock('./KeyItem.jsx', () => ({
|
|
5
|
+
KeyItem: ({ keyDefinition }) => <div data-testid='key-item'>{keyDefinition.id}</div>
|
|
6
|
+
}))
|
|
7
|
+
|
|
8
|
+
const mapStyle = { id: 'default' }
|
|
9
|
+
|
|
10
|
+
const baseProps = {
|
|
11
|
+
headingId: 'key-heading-1',
|
|
12
|
+
label: 'My Group',
|
|
13
|
+
keyDefinitions: [],
|
|
14
|
+
mapStyle
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('KeyGroupItem', () => {
|
|
18
|
+
it('renders a section with the group class', () => {
|
|
19
|
+
const { container } = render(<KeyGroupItem {...baseProps} />)
|
|
20
|
+
expect(container.querySelector('.im-c-map-key__group')).toBeTruthy()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('sets aria-labelledby to headingId on the section', () => {
|
|
24
|
+
const { container } = render(<KeyGroupItem {...baseProps} />)
|
|
25
|
+
expect(container.querySelector('section').getAttribute('aria-labelledby')).toBe('key-heading-1')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('renders the heading with the correct id', () => {
|
|
29
|
+
render(<KeyGroupItem {...baseProps} />)
|
|
30
|
+
expect(document.getElementById('key-heading-1')).toBeTruthy()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('renders the heading with the group-heading class', () => {
|
|
34
|
+
const { container } = render(<KeyGroupItem {...baseProps} />)
|
|
35
|
+
expect(container.querySelector('.im-c-map-key__group-heading')).toBeTruthy()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('renders the label text in the heading', () => {
|
|
39
|
+
render(<KeyGroupItem {...baseProps} />)
|
|
40
|
+
expect(screen.getByText('My Group')).toBeTruthy()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('renders a KeyItem for each keyDefinition', () => {
|
|
44
|
+
const keyDefinitions = [{ id: 'a' }, { id: 'b' }, { id: 'c' }]
|
|
45
|
+
render(<KeyGroupItem {...baseProps} keyDefinitions={keyDefinitions} />)
|
|
46
|
+
expect(screen.getAllByTestId('key-item')).toHaveLength(3)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('renders no KeyItems when keyDefinitions is empty', () => {
|
|
50
|
+
render(<KeyGroupItem {...baseProps} keyDefinitions={[]} />)
|
|
51
|
+
expect(screen.queryAllByTestId('key-item')).toHaveLength(0)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
|
|
2
|
+
import { KeySvg } from './KeySvg.jsx'
|
|
3
|
+
|
|
4
|
+
export const KeyItem = ({ keyDefinition, mapStyle }) => {
|
|
5
|
+
// Pure derivations of props — computed directly on every render rather than staged through
|
|
6
|
+
// useState/useEffect, so there's no post-mount frame where the label/description are blank
|
|
7
|
+
// (every panel reopen mounts this fresh, so that frame was visible as a flicker).
|
|
8
|
+
const label = keyDefinition.label
|
|
9
|
+
const symbolDescription = getValueForStyle(keyDefinition.symbolDescription, mapStyle.id)
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<dl className='im-c-map-key__item'>
|
|
13
|
+
<dt className='im-c-map-key__item-symbol'>
|
|
14
|
+
<KeySvg keyDefinition={keyDefinition} mapStyle={mapStyle} />
|
|
15
|
+
</dt>
|
|
16
|
+
<dd className='im-c-map-key__item-label'>
|
|
17
|
+
{label}
|
|
18
|
+
{symbolDescription && (
|
|
19
|
+
<span className='govuk-visually-hidden'>
|
|
20
|
+
({symbolDescription})
|
|
21
|
+
</span>
|
|
22
|
+
)}
|
|
23
|
+
</dd>
|
|
24
|
+
</dl>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react'
|
|
2
|
+
import { KeyItem } from './KeyItem'
|
|
3
|
+
import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
|
|
4
|
+
|
|
5
|
+
jest.mock('../../../../../src/utils/getValueForStyle.js', () => ({
|
|
6
|
+
getValueForStyle: jest.fn()
|
|
7
|
+
}))
|
|
8
|
+
|
|
9
|
+
jest.mock('./KeySvg.jsx', () => ({
|
|
10
|
+
KeySvg: () => <svg data-testid='key-svg' />
|
|
11
|
+
}))
|
|
12
|
+
|
|
13
|
+
const mapStyle = { id: 'default' }
|
|
14
|
+
|
|
15
|
+
const baseKeyDefinition = {
|
|
16
|
+
id: '1',
|
|
17
|
+
label: 'My Label',
|
|
18
|
+
symbolDescription: null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
getValueForStyle.mockReturnValue(null)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
describe('KeyItem', () => {
|
|
26
|
+
it('renders a dl with the item class', () => {
|
|
27
|
+
const { container } = render(<KeyItem keyDefinition={baseKeyDefinition} mapStyle={mapStyle} />)
|
|
28
|
+
expect(container.querySelector('.im-c-map-key__item')).toBeTruthy()
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('renders the symbol dt with the correct class', () => {
|
|
32
|
+
const { container } = render(<KeyItem keyDefinition={baseKeyDefinition} mapStyle={mapStyle} />)
|
|
33
|
+
expect(container.querySelector('.im-c-map-key__item-symbol')).toBeTruthy()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('renders KeySvg inside the symbol dt', () => {
|
|
37
|
+
render(<KeyItem keyDefinition={baseKeyDefinition} mapStyle={mapStyle} />)
|
|
38
|
+
expect(screen.getByTestId('key-svg')).toBeTruthy()
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('renders the label dd with the correct class', () => {
|
|
42
|
+
const { container } = render(<KeyItem keyDefinition={baseKeyDefinition} mapStyle={mapStyle} />)
|
|
43
|
+
expect(container.querySelector('.im-c-map-key__item-label')).toBeTruthy()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('renders the label text', () => {
|
|
47
|
+
render(<KeyItem keyDefinition={baseKeyDefinition} mapStyle={mapStyle} />)
|
|
48
|
+
expect(screen.getByText('My Label')).toBeTruthy()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('renders the symbol description when getValueForStyle returns a value', () => {
|
|
52
|
+
getValueForStyle.mockReturnValue('A marker symbol')
|
|
53
|
+
render(<KeyItem keyDefinition={{ ...baseKeyDefinition, symbolDescription: 'A marker symbol' }} mapStyle={mapStyle} />)
|
|
54
|
+
expect(screen.getByText('(A marker symbol)')).toBeTruthy()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('does not render the symbol description span when getValueForStyle returns null', () => {
|
|
58
|
+
render(<KeyItem keyDefinition={baseKeyDefinition} mapStyle={mapStyle} />)
|
|
59
|
+
expect(screen.queryByRole('presentation')).toBeNull()
|
|
60
|
+
expect(document.querySelector('.govuk-visually-hidden')).toBeNull()
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('calls getValueForStyle with the symbolDescription and mapStyle id', () => {
|
|
64
|
+
render(<KeyItem keyDefinition={{ ...baseKeyDefinition, symbolDescription: 'desc' }} mapStyle={mapStyle} />)
|
|
65
|
+
expect(getValueForStyle).toHaveBeenCalledWith('desc', 'default')
|
|
66
|
+
})
|
|
67
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { KeySvgPattern } from './KeySvgPattern.jsx'
|
|
2
|
+
import { KeySvgSymbol } from './KeySvgSymbol.jsx'
|
|
3
|
+
import { KeySvgLine } from './KeySvgLine.jsx'
|
|
4
|
+
import { KeySvgRect } from './KeySvgRect.jsx'
|
|
5
|
+
import { symbolRegistry } from '../../registry/index.js'
|
|
6
|
+
|
|
7
|
+
// Pure derivation of keyDefinition — computed directly during render (see KeyItem.jsx for why:
|
|
8
|
+
// staging this through useState/useEffect meant every fresh mount painted a blank symbol first).
|
|
9
|
+
const getSymbolShape = (keyDefinition) => {
|
|
10
|
+
if (!keyDefinition) {
|
|
11
|
+
return { symbolShape: null, symbolDef: null }
|
|
12
|
+
}
|
|
13
|
+
const { hasSymbol, hasPattern, style } = keyDefinition
|
|
14
|
+
if (hasSymbol) {
|
|
15
|
+
const symbolDef = symbolRegistry.getSymbolDef(style)
|
|
16
|
+
return { symbolShape: symbolDef ? 'symbol' : 'rect', symbolDef }
|
|
17
|
+
}
|
|
18
|
+
if (hasPattern) {
|
|
19
|
+
return { symbolShape: 'pattern', symbolDef: null }
|
|
20
|
+
}
|
|
21
|
+
if (style.keySymbolShape === 'line') {
|
|
22
|
+
return { symbolShape: 'line', symbolDef: null }
|
|
23
|
+
}
|
|
24
|
+
return { symbolShape: 'rect', symbolDef: null }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const KeySvg = ({ keyDefinition, mapStyle }) => {
|
|
28
|
+
const { symbolShape, symbolDef } = getSymbolShape(keyDefinition)
|
|
29
|
+
|
|
30
|
+
if (!symbolShape) {
|
|
31
|
+
return null
|
|
32
|
+
} else if (symbolShape === 'symbol') {
|
|
33
|
+
return <KeySvgSymbol mapStyle={mapStyle} keyDefinition={keyDefinition} symbolDef={symbolDef} />
|
|
34
|
+
} else if (symbolShape === 'pattern') {
|
|
35
|
+
return <KeySvgPattern mapStyle={mapStyle} keyDefinition={keyDefinition} />
|
|
36
|
+
} else if (symbolShape === 'line') {
|
|
37
|
+
return <KeySvgLine mapStyle={mapStyle} keyDefinition={keyDefinition} />
|
|
38
|
+
} else {
|
|
39
|
+
return <KeySvgRect mapStyle={mapStyle} keyDefinition={keyDefinition} />
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -2,7 +2,6 @@ import { render } from '@testing-library/react'
|
|
|
2
2
|
import { KeySvg } from './KeySvg'
|
|
3
3
|
|
|
4
4
|
import { symbolRegistry } from '../../../../../src/services/symbolRegistry.js'
|
|
5
|
-
import { patternRegistry } from '../../../../../src/services/patternRegistry.js'
|
|
6
5
|
|
|
7
6
|
const getSymbolDef = jest.spyOn(symbolRegistry, 'getSymbolDef')
|
|
8
7
|
|
|
@@ -22,17 +21,15 @@ jest.mock('./KeySvgRect.jsx', () => ({
|
|
|
22
21
|
KeySvgRect: () => <svg data-testid='key-svg-rect' />
|
|
23
22
|
}))
|
|
24
23
|
|
|
25
|
-
const
|
|
24
|
+
const baseKeyDefinition = {
|
|
26
25
|
hasSymbol: false,
|
|
27
26
|
hasPattern: false,
|
|
28
27
|
style: {}
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const baseProps = {
|
|
32
|
-
symbolRegistry,
|
|
33
|
-
patternRegistry,
|
|
34
31
|
mapStyle: { id: 'default' },
|
|
35
|
-
|
|
32
|
+
keyDefinition: baseKeyDefinition
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
beforeEach(() => {
|
|
@@ -42,17 +39,17 @@ beforeEach(() => {
|
|
|
42
39
|
describe('KeySvg', () => {
|
|
43
40
|
it('renders KeySvgSymbol when a symbolDef is resolved', () => {
|
|
44
41
|
getSymbolDef.mockReturnValue({ id: 'marker' })
|
|
45
|
-
const { getByTestId } = render(<KeySvg {...baseProps}
|
|
42
|
+
const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, hasSymbol: true }} />)
|
|
46
43
|
expect(getByTestId('key-svg-symbol')).toBeTruthy()
|
|
47
44
|
})
|
|
48
45
|
|
|
49
46
|
it('renders KeySvgPattern when hasPattern is true and no symbol', () => {
|
|
50
|
-
const { getByTestId } = render(<KeySvg {...baseProps}
|
|
47
|
+
const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, hasPattern: true }} />)
|
|
51
48
|
expect(getByTestId('key-svg-pattern')).toBeTruthy()
|
|
52
49
|
})
|
|
53
50
|
|
|
54
51
|
it('renders KeySvgLine when keySymbolShape is line and no symbol or pattern', () => {
|
|
55
|
-
const { getByTestId } = render(<KeySvg {...baseProps}
|
|
52
|
+
const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, style: { keySymbolShape: 'line' } }} />)
|
|
56
53
|
expect(getByTestId('key-svg-line')).toBeTruthy()
|
|
57
54
|
})
|
|
58
55
|
|
|
@@ -63,25 +60,30 @@ describe('KeySvg', () => {
|
|
|
63
60
|
|
|
64
61
|
it('prefers symbol over pattern when both are present', () => {
|
|
65
62
|
getSymbolDef.mockReturnValue({ id: 'marker' })
|
|
66
|
-
const { getByTestId, queryByTestId } = render(<KeySvg {...baseProps}
|
|
63
|
+
const { getByTestId, queryByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, hasSymbol: true, hasPattern: true }} />)
|
|
67
64
|
expect(getByTestId('key-svg-symbol')).toBeTruthy()
|
|
68
65
|
expect(queryByTestId('key-svg-pattern')).toBeNull()
|
|
69
66
|
})
|
|
70
67
|
|
|
71
68
|
it('prefers pattern over line when both conditions are met', () => {
|
|
72
|
-
const { getByTestId, queryByTestId } = render(<KeySvg {...baseProps}
|
|
69
|
+
const { getByTestId, queryByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, hasPattern: true, style: { keySymbolShape: 'line' } }} />)
|
|
73
70
|
expect(getByTestId('key-svg-pattern')).toBeTruthy()
|
|
74
71
|
expect(queryByTestId('key-svg-line')).toBeNull()
|
|
75
72
|
})
|
|
76
73
|
|
|
77
74
|
it('renders KeySvgRect when keySymbolShape is not line and no symbol or pattern', () => {
|
|
78
|
-
const { getByTestId } = render(<KeySvg {...baseProps}
|
|
75
|
+
const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, style: { keySymbolShape: 'polygon' } }} />)
|
|
79
76
|
expect(getByTestId('key-svg-rect')).toBeTruthy()
|
|
80
77
|
})
|
|
81
78
|
|
|
82
79
|
it('does not render KeySvgSymbol when hasSymbol is true but getSymbolDef returns null', () => {
|
|
83
80
|
getSymbolDef.mockReturnValue(null)
|
|
84
|
-
const { getByTestId } = render(<KeySvg {...baseProps}
|
|
81
|
+
const { getByTestId } = render(<KeySvg {...baseProps} keyDefinition={{ ...baseKeyDefinition, hasSymbol: true }} />)
|
|
85
82
|
expect(getByTestId('key-svg-rect')).toBeTruthy()
|
|
86
83
|
})
|
|
84
|
+
|
|
85
|
+
it('should return null if keyDefinition is undefined', () => {
|
|
86
|
+
const { container } = render(<KeySvg {...baseProps} keyDefinition={null} />)
|
|
87
|
+
expect(container.firstChild).toBeNull()
|
|
88
|
+
})
|
|
87
89
|
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { svgProps, SVG_SIZE, SVG_CENTER } from './svgProperties.js'
|
|
2
|
+
import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
|
|
3
|
+
|
|
4
|
+
export const KeySvgLine = ({ mapStyle, keyDefinition }) => {
|
|
5
|
+
const { style } = keyDefinition
|
|
6
|
+
const strokeWidth = style.strokeWidth
|
|
7
|
+
const stroke = getValueForStyle(style.stroke, mapStyle.id)
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<svg {...svgProps}>
|
|
11
|
+
<line
|
|
12
|
+
x1={strokeWidth / 2}
|
|
13
|
+
y1={SVG_CENTER}
|
|
14
|
+
x2={SVG_SIZE - strokeWidth / 2}
|
|
15
|
+
y2={SVG_CENTER}
|
|
16
|
+
stroke={stroke}
|
|
17
|
+
strokeWidth={strokeWidth}
|
|
18
|
+
strokeLinecap='round'
|
|
19
|
+
/>
|
|
20
|
+
</svg>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { svgProps } from './svgProperties.js'
|
|
2
|
+
import { patternRegistry } from '../../registry/index.js'
|
|
2
3
|
const PATTERN_INSET = 2
|
|
3
4
|
|
|
4
|
-
export const KeySvgPattern = ({
|
|
5
|
-
const { style } =
|
|
5
|
+
export const KeySvgPattern = ({ keyDefinition, mapStyle }) => {
|
|
6
|
+
const { style } = keyDefinition
|
|
6
7
|
const paths = patternRegistry.getKeyPatternPaths(style, mapStyle.id)
|
|
8
|
+
|
|
9
|
+
if (!paths) {
|
|
10
|
+
return null
|
|
11
|
+
}
|
|
7
12
|
return (
|
|
8
13
|
<svg {...svgProps}>
|
|
9
14
|
<g dangerouslySetInnerHTML={{ __html: paths.border }} />
|
|
@@ -4,7 +4,7 @@ import { patternRegistry } from '../../../../../src/services/patternRegistry.js'
|
|
|
4
4
|
|
|
5
5
|
const getKeyPatternPaths = jest.spyOn(patternRegistry, 'getKeyPatternPaths')
|
|
6
6
|
const defaultProps = {
|
|
7
|
-
|
|
7
|
+
keyDefinition: {
|
|
8
8
|
style: {
|
|
9
9
|
fillPattern: 'dots'
|
|
10
10
|
}
|
|
@@ -25,7 +25,7 @@ describe('KeySvgPattern', () => {
|
|
|
25
25
|
|
|
26
26
|
it('calls getKeyPatternPaths with props, the mapStyle id, and the patternRegistry', () => {
|
|
27
27
|
render(<KeySvgPattern {...defaultProps} />)
|
|
28
|
-
expect(getKeyPatternPaths).toHaveBeenCalledWith(defaultProps.
|
|
28
|
+
expect(getKeyPatternPaths).toHaveBeenCalledWith(defaultProps.keyDefinition.style, 'default')
|
|
29
29
|
})
|
|
30
30
|
|
|
31
31
|
it('renders two g elements for border and content', () => {
|
|
@@ -52,4 +52,10 @@ describe('KeySvgPattern', () => {
|
|
|
52
52
|
const { container } = render(<KeySvgPattern {...defaultProps} />)
|
|
53
53
|
expect(container.querySelector('#content-el')).toBeTruthy()
|
|
54
54
|
})
|
|
55
|
+
|
|
56
|
+
it('renders nothing when getKeyPatternPaths returns falsy', () => {
|
|
57
|
+
getKeyPatternPaths.mockReturnValue(null)
|
|
58
|
+
const { container } = render(<KeySvgPattern {...defaultProps} />)
|
|
59
|
+
expect(container.firstChild).toBeNull()
|
|
60
|
+
})
|
|
55
61
|
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getValueForStyle } from '../../../../../src/utils/getValueForStyle.js'
|
|
2
|
+
import { svgProps, SVG_SIZE } from './svgProperties.js'
|
|
3
|
+
|
|
4
|
+
export const KeySvgRect = ({ mapStyle, keyDefinition }) => {
|
|
5
|
+
const { style } = keyDefinition
|
|
6
|
+
const strokeWidth = style.strokeWidth
|
|
7
|
+
const fill = getValueForStyle(style.fill, mapStyle.id)
|
|
8
|
+
const stroke = getValueForStyle(style.stroke, mapStyle.id)
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<svg {...svgProps}>
|
|
12
|
+
<rect
|
|
13
|
+
x={strokeWidth / 2}
|
|
14
|
+
y={strokeWidth / 2}
|
|
15
|
+
width={SVG_SIZE - strokeWidth}
|
|
16
|
+
height={SVG_SIZE - strokeWidth}
|
|
17
|
+
rx={strokeWidth}
|
|
18
|
+
ry={strokeWidth}
|
|
19
|
+
fill={fill}
|
|
20
|
+
stroke={stroke}
|
|
21
|
+
strokeWidth={strokeWidth}
|
|
22
|
+
strokeLinejoin='round'
|
|
23
|
+
/>
|
|
24
|
+
</svg>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { getSymbolStyleColors, getSymbolViewBox } from '../../../../../src/utils/symbolUtils.js'
|
|
2
2
|
import { svgSymbolProps } from './svgProperties.js'
|
|
3
|
+
import { symbolRegistry } from '../../registry/index.js'
|
|
3
4
|
|
|
4
|
-
export const KeySvgSymbol = ({
|
|
5
|
-
const { style } =
|
|
5
|
+
export const KeySvgSymbol = ({ keyDefinition, mapStyle, symbolDef }) => {
|
|
6
|
+
const { style } = keyDefinition
|
|
6
7
|
const mapColorScheme = mapStyle?.appColorScheme ?? 'light'
|
|
7
8
|
const keyMapStyle = { ...mapStyle, mapColorScheme }
|
|
8
|
-
|
|
9
9
|
const resolvedSvg = symbolRegistry.resolve(symbolDef, getSymbolStyleColors(style), keyMapStyle)
|
|
10
10
|
const viewBox = getSymbolViewBox(style, symbolDef)
|
|
11
|
+
|
|
12
|
+
if (!(resolvedSvg && viewBox)) {
|
|
13
|
+
return null
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
return (
|
|
12
17
|
<svg {...svgSymbolProps} viewBox={viewBox}>
|
|
13
18
|
<g dangerouslySetInnerHTML={{ __html: resolvedSvg }} />
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { render } from '@testing-library/react'
|
|
2
2
|
import { KeySvgSymbol } from './KeySvgSymbol'
|
|
3
|
-
|
|
4
3
|
import { getSymbolStyleColors, getSymbolViewBox } from '../../../../../src/utils/symbolUtils.js'
|
|
4
|
+
import { symbolRegistry } from '../../registry/index.js'
|
|
5
5
|
|
|
6
6
|
jest.mock('../../../../../src/utils/symbolUtils.js', () => ({
|
|
7
7
|
getSymbolStyleColors: jest.fn(() => ({ foreground: '#000', background: '#fff' })),
|
|
8
8
|
getSymbolViewBox: jest.fn(() => '0 0 38 38')
|
|
9
9
|
}))
|
|
10
10
|
|
|
11
|
-
const mockResolve = jest.
|
|
11
|
+
const mockResolve = jest.spyOn(symbolRegistry, 'resolve')
|
|
12
12
|
|
|
13
13
|
const defaultProps = {
|
|
14
14
|
symbolDef: { id: 'marker' },
|
|
15
|
-
|
|
15
|
+
keyDefinition: {
|
|
16
16
|
style: {
|
|
17
17
|
stroke: '#000000'
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
symbolRegistry: { resolve: mockResolve },
|
|
21
20
|
mapStyle: { id: 'default' }
|
|
22
21
|
}
|
|
23
22
|
|
|
@@ -45,12 +44,12 @@ describe('KeySvgSymbol', () => {
|
|
|
45
44
|
|
|
46
45
|
it('calls getSymbolStyleColors with the dataset props', () => {
|
|
47
46
|
render(<KeySvgSymbol {...defaultProps} />)
|
|
48
|
-
expect(getSymbolStyleColors).toHaveBeenCalledWith(defaultProps.
|
|
47
|
+
expect(getSymbolStyleColors).toHaveBeenCalledWith(defaultProps.keyDefinition.style)
|
|
49
48
|
})
|
|
50
49
|
|
|
51
50
|
it('calls getSymbolViewBox with the dataset props and symbolDef', () => {
|
|
52
51
|
render(<KeySvgSymbol {...defaultProps} />)
|
|
53
|
-
expect(getSymbolViewBox).toHaveBeenCalledWith(defaultProps.
|
|
52
|
+
expect(getSymbolViewBox).toHaveBeenCalledWith(defaultProps.keyDefinition.style, defaultProps.symbolDef)
|
|
54
53
|
})
|
|
55
54
|
|
|
56
55
|
it('sets the viewBox from getSymbolViewBox', () => {
|
|
@@ -77,4 +76,16 @@ describe('KeySvgSymbol', () => {
|
|
|
77
76
|
const callArg = mockResolve.mock.calls[0][2]
|
|
78
77
|
expect(callArg.mapColorScheme).toBe('dark')
|
|
79
78
|
})
|
|
79
|
+
|
|
80
|
+
it('renders nothing when resolve returns falsy', () => {
|
|
81
|
+
mockResolve.mockReturnValue(null)
|
|
82
|
+
const { container } = render(<KeySvgSymbol {...defaultProps} />)
|
|
83
|
+
expect(container.firstChild).toBeNull()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('renders nothing when getSymbolViewBox returns falsy', () => {
|
|
87
|
+
getSymbolViewBox.mockReturnValue(null)
|
|
88
|
+
const { container } = render(<KeySvgSymbol {...defaultProps} />)
|
|
89
|
+
expect(container.firstChild).toBeNull()
|
|
90
|
+
})
|
|
80
91
|
})
|