@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
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.interactPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat},287(e){e.exports=preactJsxRuntime}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e](i,i.exports,o),i.exports}o.m=r,o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-interact-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.interactPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"interact",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(936).then(o.bind(o,
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("defra",[],t):"object"==typeof exports?exports.defra=t():(e.defra=e.defra||{},e.defra.interactPlugin=t())}(this,()=>(()=>{"use strict";var e,t,r={738(e){e.exports=preactCompat},287(e){e.exports=preactJsxRuntime}},n={};function o(e){var t=n[e];if(void 0!==t)return t.exports;var i=n[e]={exports:{}};return r[e](i,i.exports,o),i.exports}o.m=r,o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>"im-interact-plugin.js",o.miniCssF=e=>{},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="defra.interactPlugin:",o.l=(r,n,i,a)=>{if(e[r])e[r].push(n);else{var u,c;if(void 0!==i)for(var f=document.getElementsByTagName("script"),p=0;p<f.length;p++){var l=f[p];if(l.getAttribute("src")==r||l.getAttribute("data-webpack")==t+i){u=l;break}}u||(c=!0,(u=document.createElement("script")).charset="utf-8",o.nc&&u.setAttribute("nonce",o.nc),u.setAttribute("data-webpack",t+i),u.src=r),e[r]=[n];var s=(t,n)=>{u.onerror=u.onload=null,clearTimeout(d);var o=e[r];if(delete e[r],u.parentNode&&u.parentNode.removeChild(u),o&&o.forEach(e=>e(n)),t)return t(n)},d=setTimeout(s.bind(null,void 0,{type:"timeout",target:u}),12e4);u.onerror=s.bind(null,u.onerror),u.onload=s.bind(null,u.onload),c&&document.head.appendChild(u)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=r[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={57:0};o.f.j=(t,r)=>{var n=o.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var i=new Promise((r,o)=>n=e[t]=[r,o]);r.push(n[2]=i);var a=o.p+o.u(t),u=new Error;o.l(a,r=>{if(o.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var i=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;u.message="Loading chunk "+t+" failed.\n("+i+": "+a+")",u.name="ChunkLoadError",u.type=i,u.request=a,n[1](u)}},"chunk-"+t,t)}};var t=(t,r)=>{var n,i,[a,u,c]=r,f=0;if(a.some(t=>0!==e[t])){for(n in u)o.o(u,n)&&(o.m[n]=u[n]);c&&c(o)}for(t&&t(r);f<a.length;f++)i=a[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0},r=this.webpackChunkdefra_DefraMap=this.webpackChunkdefra_DefraMap||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})();var i={};function a(e){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a(e)}function u(){var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var u=n&&n.prototype instanceof f?n:f,p=Object.create(u.prototype);return c(p,"_invoke",function(r,n,o){var i,u,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(t,r){return i=t,u=0,c=e,s.n=r,a}};function d(r,n){for(u=r,c=n,t=0;!l&&f&&!o&&t<p.length;t++){var o,i=p[t],d=s.p,b=i[2];r>3?(o=b===n)&&(c=i[(u=i[4])?5:(u=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(u=0,s.v=n,s.n=i[1]):d<b&&(o=r<3||i[0]>n||n>b)&&(i[4]=r,i[5]=n,s.n=b,u=0))}if(o||r>1)return a;throw l=!0,n}return function(o,p,b){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,b),u=p,c=b;(t=u<2?e:c)||!l;){i||(u?u<3?(u>1&&(s.n=-1),d(u,c)):s.n=c:s.v=c);try{if(f=2,i){if(u||(o="next"),t=i[o]){if(!(t=t.call(i,c)))throw TypeError("iterator result is not an object");if(!t.done)return t;c=t.value,u<2&&(u=0)}else 1===u&&(t=i.return)&&t.call(i),u<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),u=1);i=e}else if((t=(l=s.n<0)?c:r.call(n,s))!==a)break}catch(t){i=e,u=1,c=t}finally{f=1}}return{value:t,done:l}}}(r,o,i),!0),p}var a={};function f(){}function p(){}function l(){}t=Object.getPrototypeOf;var s=[][n]?t(t([][n]())):(c(t={},n,function(){return this}),t),d=l.prototype=f.prototype=Object.create(s);function b(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,l):(e.__proto__=l,c(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return p.prototype=l,c(d,"constructor",l),c(l,"constructor",p),p.displayName="GeneratorFunction",c(l,o,"GeneratorFunction"),c(d),c(d,o,"Generator"),c(d,n,function(){return this}),c(d,"toString",function(){return"[object Generator]"}),(u=function(){return{w:i,m:b}})()}function c(e,t,r,n){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}c=function(e,t,r,n){function i(t,r){c(e,t,function(e){return this._invoke(t,r,e)})}t?o?o(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(i("next",0),i("throw",1),i("return",2))},c(e,t,r,n)}function f(e,t,r,n,o,i,a){try{var u=e[i](a),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,o)}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach(function(t){s(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function s(e,t,r){return(t=function(e){var t=function(e){if("object"!=a(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=a(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==a(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(){var e,t;return l(l({},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"interact",load:(e=u().m(function e(){var t;return u().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,o.e(936).then(o.bind(o,394));case 1:return t=e.v.manifest,e.a(2,t)}},e)}),t=function(){var t=this,r=arguments;return new Promise(function(n,o){var i=e.apply(t,r);function a(e){f(i,n,o,a,u,"next",e)}function u(e){f(i,n,o,a,u,"throw",e)}a(void 0)})},function(){return t.apply(this,arguments)})})}return o.d(i,{default:()=>d}),i.default})());
|
|
@@ -8,13 +8,16 @@ export function useCrossHairVisibility ({ crossHair, enabled, selectMarkerOnly,
|
|
|
8
8
|
const crossHairRef = useRef(crossHair)
|
|
9
9
|
crossHairRef.current = crossHair
|
|
10
10
|
const listboxFocusRef = useRef(false)
|
|
11
|
+
// True while focus is inside an element (marked `data-map-keyboard-scope`) that actually routes cursor keys to the map, e.g. the viewport or MoveControl's D-pad.
|
|
12
|
+
const mapKeyboardScopedRef = useRef(false)
|
|
11
13
|
const interfaceTypeRef = useRef(appState.interfaceType)
|
|
12
14
|
interfaceTypeRef.current = appState.interfaceType
|
|
13
15
|
|
|
14
16
|
const updateCrossHair = useCallback(() => {
|
|
15
17
|
const type = interfaceTypeRef.current
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
+
const keyboardCanOperateMap = type === 'keyboard' && mapKeyboardScopedRef.current
|
|
19
|
+
const touchCanOperateMap = type === 'touch' && !selectMarkerOnlyRef.current && !listboxFocusRef.current
|
|
20
|
+
if (enabledRef.current && (keyboardCanOperateMap || touchCanOperateMap)) {
|
|
18
21
|
crossHairRef.current.fixAtCenter()
|
|
19
22
|
} else {
|
|
20
23
|
crossHairRef.current.hide()
|
|
@@ -28,10 +31,15 @@ export function useCrossHairVisibility ({ crossHair, enabled, selectMarkerOnly,
|
|
|
28
31
|
useEffect(() => {
|
|
29
32
|
const container = appState.layoutRefs?.appContainerRef?.current
|
|
30
33
|
if (!container) { return undefined }
|
|
34
|
+
mapKeyboardScopedRef.current = !!document.activeElement?.closest('[data-map-keyboard-scope]')
|
|
31
35
|
const handleFocusIn = (e) => {
|
|
32
36
|
const inListbox = !!e.target.closest('[role="listbox"], [role="option"]')
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
const inMapKeyboardScope = !!e.target.closest('[data-map-keyboard-scope]')
|
|
38
|
+
const changed = listboxFocusRef.current !== inListbox || mapKeyboardScopedRef.current !== inMapKeyboardScope
|
|
39
|
+
listboxFocusRef.current = inListbox
|
|
40
|
+
mapKeyboardScopedRef.current = inMapKeyboardScope
|
|
41
|
+
// Keep the refs current regardless, but only touch the crosshair while enabled — while disabled, another owner (e.g. draw mode) is responsible for it.
|
|
42
|
+
if (changed && enabledRef.current) {
|
|
35
43
|
updateCrossHair()
|
|
36
44
|
}
|
|
37
45
|
}
|
|
@@ -19,7 +19,7 @@ describe('useCrossHairVisibility', () => {
|
|
|
19
19
|
expect(crossHair.hide).toHaveBeenCalled()
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
it('shows crosshair on touch
|
|
22
|
+
it('shows crosshair on touch and hides when listbox has focus', () => {
|
|
23
23
|
const container = appState.layoutRefs.appContainerRef.current
|
|
24
24
|
appState.interfaceType = 'touch'
|
|
25
25
|
renderHook(() => useCrossHairVisibility({ crossHair, enabled: true, selectMarkerOnly: false, appState }))
|
|
@@ -46,4 +46,91 @@ describe('useCrossHairVisibility', () => {
|
|
|
46
46
|
act(() => otherEl.dispatchEvent(new FocusEvent('focusin', { bubbles: true })))
|
|
47
47
|
expect(crossHair.fixAtCenter).toHaveBeenCalledTimes(2)
|
|
48
48
|
})
|
|
49
|
+
|
|
50
|
+
it('hides crosshair in keyboard mode until focus enters the map keyboard scope', () => {
|
|
51
|
+
const container = appState.layoutRefs.appContainerRef.current
|
|
52
|
+
const viewportEl = document.createElement('div')
|
|
53
|
+
viewportEl.setAttribute('data-map-keyboard-scope', '')
|
|
54
|
+
container.appendChild(viewportEl)
|
|
55
|
+
appState.interfaceType = 'keyboard'
|
|
56
|
+
|
|
57
|
+
renderHook(() => useCrossHairVisibility({ crossHair, enabled: true, selectMarkerOnly: false, appState }))
|
|
58
|
+
|
|
59
|
+
// interfaceType is 'keyboard' but nothing in the map keyboard scope has focus yet
|
|
60
|
+
expect(crossHair.hide).toHaveBeenCalled()
|
|
61
|
+
expect(crossHair.fixAtCenter).not.toHaveBeenCalled()
|
|
62
|
+
|
|
63
|
+
// Viewport gains focus — cursor keys now actually operate the map
|
|
64
|
+
act(() => viewportEl.dispatchEvent(new FocusEvent('focusin', { bubbles: true })))
|
|
65
|
+
expect(crossHair.fixAtCenter).toHaveBeenCalled()
|
|
66
|
+
|
|
67
|
+
// Focus moves elsewhere (e.g. a popup menu closed with Escape, which also
|
|
68
|
+
// flips interfaceType to 'keyboard' but shouldn't leave the crosshair up)
|
|
69
|
+
const menuEl = document.createElement('ul')
|
|
70
|
+
menuEl.setAttribute('role', 'menu')
|
|
71
|
+
container.appendChild(menuEl)
|
|
72
|
+
act(() => menuEl.dispatchEvent(new FocusEvent('focusin', { bubbles: true })))
|
|
73
|
+
expect(crossHair.hide).toHaveBeenCalledTimes(2)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('shows the crosshair for a control (e.g. MoveControl) that forwards arrow keys to the map without moving DOM focus onto the viewport', () => {
|
|
77
|
+
const container = appState.layoutRefs.appContainerRef.current
|
|
78
|
+
const moveControlButton = document.createElement('button')
|
|
79
|
+
const moveControlScope = document.createElement('div')
|
|
80
|
+
moveControlScope.setAttribute('data-map-keyboard-scope', '')
|
|
81
|
+
moveControlScope.appendChild(moveControlButton)
|
|
82
|
+
container.appendChild(moveControlScope)
|
|
83
|
+
appState.interfaceType = 'keyboard'
|
|
84
|
+
|
|
85
|
+
renderHook(() => useCrossHairVisibility({ crossHair, enabled: true, selectMarkerOnly: false, appState }))
|
|
86
|
+
expect(crossHair.fixAtCenter).not.toHaveBeenCalled()
|
|
87
|
+
|
|
88
|
+
// Focus lands on a direction button nested inside the scoped control, not
|
|
89
|
+
// on the scope element itself — closest() must still pick it up.
|
|
90
|
+
act(() => moveControlButton.dispatchEvent(new FocusEvent('focusin', { bubbles: true })))
|
|
91
|
+
expect(crossHair.fixAtCenter).toHaveBeenCalled()
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('does not touch the crosshair on a focus change while disabled, leaving another owner (e.g. draw mode) in control', () => {
|
|
95
|
+
const container = appState.layoutRefs.appContainerRef.current
|
|
96
|
+
const viewportEl = document.createElement('div')
|
|
97
|
+
viewportEl.setAttribute('data-map-keyboard-scope', '')
|
|
98
|
+
container.appendChild(viewportEl)
|
|
99
|
+
appState.interfaceType = 'keyboard'
|
|
100
|
+
|
|
101
|
+
// interact starts disabled (e.g. a draw session already took over) — the crosshair
|
|
102
|
+
// is presumed to already be showing via that other owner, mirroring what
|
|
103
|
+
// DrawInit.jsx/drawInput.js would have set moments earlier.
|
|
104
|
+
renderHook(() => useCrossHairVisibility({ crossHair, enabled: false, selectMarkerOnly: false, appState }))
|
|
105
|
+
crossHair.fixAtCenter.mockClear()
|
|
106
|
+
crossHair.hide.mockClear()
|
|
107
|
+
|
|
108
|
+
// Focus moves into the map keyboard scope (e.g. draw's deferred focus-to-viewport
|
|
109
|
+
// after a menu selection) — interact must not call hide() here; it isn't the owner.
|
|
110
|
+
act(() => viewportEl.dispatchEvent(new FocusEvent('focusin', { bubbles: true })))
|
|
111
|
+
expect(crossHair.hide).not.toHaveBeenCalled()
|
|
112
|
+
expect(crossHair.fixAtCenter).not.toHaveBeenCalled()
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('does not show the crosshair for a menu-button Escape that never enters the map keyboard scope', () => {
|
|
116
|
+
const container = appState.layoutRefs.appContainerRef.current
|
|
117
|
+
const menuButton = document.createElement('button')
|
|
118
|
+
container.appendChild(menuButton)
|
|
119
|
+
appState.interfaceType = 'mouse'
|
|
120
|
+
|
|
121
|
+
const { rerender } = renderHook(
|
|
122
|
+
(props) => useCrossHairVisibility(props),
|
|
123
|
+
{ initialProps: { crossHair, enabled: true, selectMarkerOnly: false, appState } }
|
|
124
|
+
)
|
|
125
|
+
expect(crossHair.hide).toHaveBeenCalled()
|
|
126
|
+
|
|
127
|
+
// Menu opened by mouse, focus lands on it, then Escape closes it and
|
|
128
|
+
// returns focus to the instigating button — interfaceType flips to
|
|
129
|
+
// 'keyboard' along the way, but the map keyboard scope was never entered.
|
|
130
|
+
act(() => menuButton.dispatchEvent(new FocusEvent('focusin', { bubbles: true })))
|
|
131
|
+
appState = { ...appState, interfaceType: 'keyboard' }
|
|
132
|
+
rerender({ crossHair, enabled: true, selectMarkerOnly: false, appState })
|
|
133
|
+
|
|
134
|
+
expect(crossHair.fixAtCenter).not.toHaveBeenCalled()
|
|
135
|
+
})
|
|
49
136
|
})
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { useEffect, useMemo } from 'react'
|
|
2
2
|
import { buildStylesMap } from '../utils/buildStylesMap.js'
|
|
3
3
|
|
|
4
|
+
// How long after a map style/size change to keep re-applying highlights on every
|
|
5
|
+
// MAP_DATA_CHANGE — see the effect's own comment.
|
|
6
|
+
const SETTLE_WINDOW_MS = 3000
|
|
7
|
+
|
|
4
8
|
/**
|
|
5
9
|
* Keeps map highlight rendering in sync with the current selection and keyboard-active item.
|
|
6
10
|
*
|
|
7
11
|
* Calls mapProvider.updateHighlightedFeatures whenever selectedFeatures or listboxActiveItem
|
|
8
12
|
* changes, passing selected features (shown with the selection ring) and the active item
|
|
9
13
|
* (shown with the keyboard cursor ring) as separate arguments so the provider can style them
|
|
10
|
-
* differently. Also re-applies highlights after a map style reload
|
|
11
|
-
*
|
|
14
|
+
* differently. Also re-applies highlights after a map style reload or a map-size change,
|
|
15
|
+
* since both remove/rebuild highlight layers and/or leave a selected feature's own drawn
|
|
16
|
+
* symbol (colours, resolution) briefly stale until the draw plugin re-resolves it.
|
|
12
17
|
*/
|
|
13
18
|
export const useHighlightSync = ({
|
|
14
19
|
mapProvider,
|
|
@@ -43,19 +48,35 @@ export const useHighlightSync = ({
|
|
|
43
48
|
|
|
44
49
|
updateHighlightedFeatures()
|
|
45
50
|
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
// MAP_STYLE_CHANGE/MAP_SET_SIZE fire before layers are re-added or symbols re-resolved, so
|
|
52
|
+
// this arms a "keep re-applying" window rather than reacting once — MAP_DATA_CHANGE can
|
|
53
|
+
// fire more than once as things settle, and a single listen-once would miss the later,
|
|
54
|
+
// real update. A permanent listener isn't safe either, since updateHighlightedFeatures()
|
|
55
|
+
// itself can trigger further MAP_DATA_CHANGE events. Uses `on`/`off`, not `once` — its
|
|
56
|
+
// returned wrapper can't be off()'d by this same handler reference.
|
|
57
|
+
let settleUntil = 0
|
|
58
|
+
let armed = false
|
|
59
|
+
const reapply = () => {
|
|
60
|
+
updateHighlightedFeatures()
|
|
61
|
+
if (Date.now() >= settleUntil) {
|
|
62
|
+
eventBus.off(events.MAP_DATA_CHANGE, reapply)
|
|
63
|
+
armed = false
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const armSettleWindow = () => {
|
|
67
|
+
settleUntil = Date.now() + SETTLE_WINDOW_MS
|
|
68
|
+
if (!armed) {
|
|
69
|
+
armed = true
|
|
70
|
+
eventBus.on(events.MAP_DATA_CHANGE, reapply)
|
|
71
|
+
}
|
|
54
72
|
}
|
|
55
|
-
eventBus.on(events.MAP_STYLE_CHANGE,
|
|
73
|
+
eventBus.on(events.MAP_STYLE_CHANGE, armSettleWindow)
|
|
74
|
+
eventBus.on(events.MAP_SET_SIZE, armSettleWindow)
|
|
56
75
|
|
|
57
76
|
return () => {
|
|
58
|
-
eventBus.off(events.MAP_STYLE_CHANGE,
|
|
77
|
+
eventBus.off(events.MAP_STYLE_CHANGE, armSettleWindow)
|
|
78
|
+
eventBus.off(events.MAP_SET_SIZE, armSettleWindow)
|
|
79
|
+
eventBus.off(events.MAP_DATA_CHANGE, reapply)
|
|
59
80
|
}
|
|
60
81
|
}, [selectedFeatures, listboxActiveItem, mapProvider, stylesMap, eventBus])
|
|
61
82
|
}
|
|
@@ -7,19 +7,37 @@ jest.mock('../utils/buildStylesMap.js', () => ({
|
|
|
7
7
|
}))
|
|
8
8
|
|
|
9
9
|
const STYLE_CHANGE = 'map:stylechange'
|
|
10
|
+
const SET_SIZE = 'map:setsize'
|
|
10
11
|
const DATA_CHANGE = 'map:datachange'
|
|
11
12
|
|
|
13
|
+
// A minimal real-ish event bus (mirrors src/services/eventBus.js's on/once/off contract)
|
|
14
|
+
// rather than jest.fn() stubs — the re-arming logic under test depends on once() genuinely
|
|
15
|
+
// self-removing and on() genuinely supporting multiple independent listeners, which a bare
|
|
16
|
+
// mock can't exercise faithfully.
|
|
17
|
+
const createEventBus = () => {
|
|
18
|
+
const listeners = {}
|
|
19
|
+
return {
|
|
20
|
+
on: jest.fn((event, handler) => { (listeners[event] ??= []).push(handler) }),
|
|
21
|
+
once: jest.fn((event, handler) => {
|
|
22
|
+
const wrapper = (...args) => { bus.off(event, wrapper); handler(...args) }
|
|
23
|
+
listeners[event] ??= []
|
|
24
|
+
listeners[event].push(wrapper)
|
|
25
|
+
}),
|
|
26
|
+
off: jest.fn((event, handler) => { listeners[event] = (listeners[event] ?? []).filter(h => h !== handler) }),
|
|
27
|
+
emit: (event, ...args) => { (listeners[event] ?? []).slice().forEach(h => h(...args)) },
|
|
28
|
+
_listenerCount: (event) => (listeners[event] ?? []).length
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
let bus
|
|
32
|
+
|
|
12
33
|
let mockDeps
|
|
13
|
-
let capturedStyleChangeHandler
|
|
14
|
-
let capturedDataChangeHandler
|
|
15
34
|
|
|
16
35
|
const render = (overrides = {}) =>
|
|
17
36
|
renderHook(() => useHighlightSync({ ...mockDeps, ...overrides }))
|
|
18
37
|
|
|
19
38
|
beforeEach(() => {
|
|
20
39
|
jest.clearAllMocks()
|
|
21
|
-
|
|
22
|
-
capturedDataChangeHandler = null
|
|
40
|
+
bus = createEventBus()
|
|
23
41
|
|
|
24
42
|
mockDeps = {
|
|
25
43
|
mapProvider: {
|
|
@@ -30,20 +48,8 @@ beforeEach(() => {
|
|
|
30
48
|
layers: [{ layerId: 'layer1' }]
|
|
31
49
|
},
|
|
32
50
|
selectedFeatures: [],
|
|
33
|
-
events: { MAP_STYLE_CHANGE: STYLE_CHANGE, MAP_DATA_CHANGE: DATA_CHANGE },
|
|
34
|
-
eventBus:
|
|
35
|
-
on: jest.fn((event, handler) => {
|
|
36
|
-
if (event === STYLE_CHANGE) {
|
|
37
|
-
capturedStyleChangeHandler = handler
|
|
38
|
-
}
|
|
39
|
-
}),
|
|
40
|
-
once: jest.fn((event, handler) => {
|
|
41
|
-
if (event === DATA_CHANGE) {
|
|
42
|
-
capturedDataChangeHandler = handler
|
|
43
|
-
}
|
|
44
|
-
}),
|
|
45
|
-
off: jest.fn()
|
|
46
|
-
}
|
|
51
|
+
events: { MAP_STYLE_CHANGE: STYLE_CHANGE, MAP_SET_SIZE: SET_SIZE, MAP_DATA_CHANGE: DATA_CHANGE },
|
|
52
|
+
eventBus: bus
|
|
47
53
|
}
|
|
48
54
|
})
|
|
49
55
|
|
|
@@ -95,28 +101,93 @@ describe('useHighlightSync — styles memoization', () => {
|
|
|
95
101
|
})
|
|
96
102
|
})
|
|
97
103
|
|
|
98
|
-
// ─── useHighlightSync — style-change
|
|
104
|
+
// ─── useHighlightSync — style/size-change settle window ──────────────────────
|
|
99
105
|
|
|
100
|
-
describe('useHighlightSync — style-change
|
|
106
|
+
describe('useHighlightSync — style/size-change settle window', () => {
|
|
101
107
|
it('refreshes highlights after MAP_STYLE_CHANGE then MAP_DATA_CHANGE', () => {
|
|
102
108
|
mockDeps.selectedFeatures = [{ featureId: 'F1', layerId: 'layer1' }]
|
|
103
109
|
|
|
104
110
|
render()
|
|
105
111
|
mockDeps.mapProvider.updateHighlightedFeatures.mockClear()
|
|
106
112
|
|
|
107
|
-
act(() =>
|
|
108
|
-
act(() =>
|
|
113
|
+
act(() => bus.emit(STYLE_CHANGE))
|
|
114
|
+
act(() => bus.emit(DATA_CHANGE))
|
|
115
|
+
|
|
116
|
+
expect(mockDeps.mapProvider.updateHighlightedFeatures).toHaveBeenCalledTimes(1)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('also refreshes after MAP_SET_SIZE then MAP_DATA_CHANGE', () => {
|
|
120
|
+
mockDeps.selectedFeatures = [{ featureId: 'F1', layerId: 'layer1' }]
|
|
121
|
+
|
|
122
|
+
render()
|
|
123
|
+
mockDeps.mapProvider.updateHighlightedFeatures.mockClear()
|
|
124
|
+
|
|
125
|
+
act(() => bus.emit(SET_SIZE))
|
|
126
|
+
act(() => bus.emit(DATA_CHANGE))
|
|
127
|
+
|
|
128
|
+
expect(mockDeps.mapProvider.updateHighlightedFeatures).toHaveBeenCalledTimes(1)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
// The whole reason for re-arming rather than a single listen-once: MAP_DATA_CHANGE
|
|
132
|
+
// typically fires more than once during a settle (basemap loading before a drawn
|
|
133
|
+
// feature's own symbol re-resolution has finished) — the second, later firing must
|
|
134
|
+
// still be caught, not missed because the first already consumed a one-shot listener.
|
|
135
|
+
it('keeps re-applying on every MAP_DATA_CHANGE within the settle window, not just the first', () => {
|
|
136
|
+
mockDeps.selectedFeatures = [{ featureId: 'F1', layerId: 'layer1' }]
|
|
137
|
+
|
|
138
|
+
render()
|
|
139
|
+
mockDeps.mapProvider.updateHighlightedFeatures.mockClear()
|
|
140
|
+
|
|
141
|
+
act(() => bus.emit(STYLE_CHANGE))
|
|
142
|
+
act(() => bus.emit(DATA_CHANGE)) // early, still-stale settle
|
|
143
|
+
act(() => bus.emit(DATA_CHANGE)) // later, real settle
|
|
144
|
+
act(() => bus.emit(DATA_CHANGE))
|
|
145
|
+
|
|
146
|
+
expect(mockDeps.mapProvider.updateHighlightedFeatures).toHaveBeenCalledTimes(3)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('stops re-arming once the settle window has elapsed, so it does not listen forever', () => {
|
|
150
|
+
jest.useFakeTimers()
|
|
151
|
+
mockDeps.selectedFeatures = [{ featureId: 'F1', layerId: 'layer1' }]
|
|
152
|
+
|
|
153
|
+
render()
|
|
154
|
+
mockDeps.mapProvider.updateHighlightedFeatures.mockClear()
|
|
155
|
+
|
|
156
|
+
act(() => bus.emit(STYLE_CHANGE))
|
|
157
|
+
act(() => bus.emit(DATA_CHANGE)) // re-arms — within the window
|
|
158
|
+
expect(bus._listenerCount(DATA_CHANGE)).toBe(1)
|
|
159
|
+
|
|
160
|
+
jest.advanceTimersByTime(4000) // past the settle window
|
|
161
|
+
act(() => bus.emit(DATA_CHANGE)) // the last re-arm still fires once...
|
|
162
|
+
expect(bus._listenerCount(DATA_CHANGE)).toBe(0) // ...but does not re-arm again
|
|
163
|
+
|
|
164
|
+
jest.useRealTimers()
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('a second style/size change while still settling extends the window without double-registering', () => {
|
|
168
|
+
jest.useFakeTimers()
|
|
169
|
+
mockDeps.selectedFeatures = [{ featureId: 'F1', layerId: 'layer1' }]
|
|
170
|
+
|
|
171
|
+
render()
|
|
172
|
+
|
|
173
|
+
act(() => bus.emit(STYLE_CHANGE))
|
|
174
|
+
expect(bus._listenerCount(DATA_CHANGE)).toBe(1)
|
|
175
|
+
act(() => bus.emit(SET_SIZE)) // still armed — must not add a second listener
|
|
176
|
+
expect(bus._listenerCount(DATA_CHANGE)).toBe(1)
|
|
109
177
|
|
|
110
|
-
|
|
178
|
+
jest.useRealTimers()
|
|
111
179
|
})
|
|
112
180
|
|
|
113
|
-
it('unsubscribes on unmount', () => {
|
|
181
|
+
it('unsubscribes MAP_STYLE_CHANGE/MAP_SET_SIZE/MAP_DATA_CHANGE listeners on unmount', () => {
|
|
114
182
|
mockDeps.selectedFeatures = [{ featureId: 'F1', layerId: 'layer1' }]
|
|
115
183
|
|
|
116
184
|
const { unmount } = render()
|
|
185
|
+
act(() => bus.emit(STYLE_CHANGE)) // arm the MAP_DATA_CHANGE re-apply listener too
|
|
117
186
|
unmount()
|
|
118
187
|
|
|
119
|
-
expect(
|
|
188
|
+
expect(bus._listenerCount(STYLE_CHANGE)).toBe(0)
|
|
189
|
+
expect(bus._listenerCount(SET_SIZE)).toBe(0)
|
|
190
|
+
expect(bus._listenerCount(DATA_CHANGE)).toBe(0)
|
|
120
191
|
})
|
|
121
192
|
})
|
|
122
193
|
|
|
@@ -1,7 +1,25 @@
|
|
|
1
|
+
// mapbox-gl-draw (MapLibre only) splits every layer into a `.cold`/`.hot` sibling pair — see
|
|
2
|
+
// providers/maplibre/src/utils/drawLayerBuckets.js. Inlined here (not imported) since this file
|
|
3
|
+
// stays provider-agnostic and OpenLayers has no such split.
|
|
4
|
+
const drawBucketSiblingSuffix = { '.cold': '.hot', '.hot': '.cold' }
|
|
5
|
+
|
|
6
|
+
const siblingLayerId = (layerId) => {
|
|
7
|
+
for (const [suffix, sibling] of Object.entries(drawBucketSiblingSuffix)) {
|
|
8
|
+
if (layerId.endsWith(suffix)) {
|
|
9
|
+
return `${layerId.slice(0, -suffix.length)}${sibling}`
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return null
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
export const buildLayerConfigMap = dataLayers => {
|
|
2
16
|
const map = {}
|
|
3
17
|
for (const layer of dataLayers) {
|
|
4
18
|
map[layer.layerId] = layer
|
|
19
|
+
const sibling = siblingLayerId(layer.layerId)
|
|
20
|
+
if (sibling) {
|
|
21
|
+
map[sibling] = layer
|
|
22
|
+
}
|
|
5
23
|
}
|
|
6
24
|
return map
|
|
7
25
|
}
|
|
@@ -15,6 +15,21 @@ describe('buildLayerConfigMap', () => {
|
|
|
15
15
|
|
|
16
16
|
expect(buildLayerConfigMap([])).toEqual({})
|
|
17
17
|
})
|
|
18
|
+
|
|
19
|
+
// mapbox-gl-draw (MapLibre only) moves a feature out of its `.cold` layer/source into a
|
|
20
|
+
// `.hot` sibling the instant any of its own properties change — a click landing on a feature
|
|
21
|
+
// that's since moved would otherwise silently fail to match any registered config at all.
|
|
22
|
+
it('also registers the .cold/.hot sibling id, pointing at the same config', () => {
|
|
23
|
+
const dataLayers = [{ layerId: 'point-symbol.cold', idProperty: 'id' }]
|
|
24
|
+
const result = buildLayerConfigMap(dataLayers)
|
|
25
|
+
expect(result['point-symbol.cold']).toBe(result['point-symbol.hot'])
|
|
26
|
+
expect(result['point-symbol.hot']).toEqual({ layerId: 'point-symbol.cold', idProperty: 'id' })
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('does not add a sibling for a layer id with no cold/hot suffix', () => {
|
|
30
|
+
const result = buildLayerConfigMap([{ layerId: 'field-parcels' }])
|
|
31
|
+
expect(Object.keys(result)).toEqual(['field-parcels'])
|
|
32
|
+
})
|
|
18
33
|
})
|
|
19
34
|
|
|
20
35
|
describe('getFeaturesAtPoint', () => {
|
|
@@ -41,19 +41,25 @@ function isContiguousWithAny (feature, features) {
|
|
|
41
41
|
return features.some(f => !booleanDisjoint(toTurfGeometry(f), toTurfGeometry(feature)))
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
const isPolygonal = (type) => type === 'Polygon' || type === 'MultiPolygon'
|
|
45
|
+
|
|
44
46
|
/**
|
|
45
|
-
* Check if all features form a single contiguous group
|
|
47
|
+
* Check if all features are polygons/multi-polygons and form a single contiguous group
|
|
48
|
+
* (mergeable). Mixed geometry types (e.g. a line crossing a polygon) are never contiguous,
|
|
49
|
+
* regardless of spatial overlap, so the type check runs first and skips the spatial work
|
|
50
|
+
* entirely when it fails.
|
|
51
|
+
*
|
|
46
52
|
* Uses flood-fill to find connected components.
|
|
47
53
|
*
|
|
48
54
|
* @param {Array} features - Array of features to test
|
|
49
|
-
* @returns {boolean} True if 2+ features and all
|
|
55
|
+
* @returns {boolean} True if 2+ features, all polygonal, and all contiguous
|
|
50
56
|
*/
|
|
51
57
|
function areAllContiguous (features) {
|
|
52
58
|
if (features.length < 2) {
|
|
53
59
|
return false
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
if (features.some(
|
|
62
|
+
if (features.some(feature => !isPolygonal(feature.geometry?.type))) {
|
|
57
63
|
return false
|
|
58
64
|
}
|
|
59
65
|
|
|
@@ -67,9 +67,11 @@ describe('areAllContiguous', () => {
|
|
|
67
67
|
const B = poly([[2, 0], [4, 0], [4, 2], [2, 2], [2, 0]]) // touches A
|
|
68
68
|
const C = poly([[4, 0], [6, 0], [6, 2], [4, 2], [4, 0]]) // touches B
|
|
69
69
|
const D = poly([[10, 10], [12, 10], [12, 12], [10, 12], [10, 10]]) // isolated
|
|
70
|
+
const multiA = { geometry: { type: 'MultiPolygon', coordinates: [[[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]]] } } // same shape as A
|
|
70
71
|
|
|
71
72
|
const noGeom = { geometry: undefined }
|
|
72
73
|
const noType = { geometry: {} }
|
|
74
|
+
const lineThroughA = { geometry: { type: 'LineString', coordinates: [[1, -1], [1, 3]] } } // crosses straight through A's interior
|
|
73
75
|
|
|
74
76
|
it.each([
|
|
75
77
|
[[], false],
|
|
@@ -81,8 +83,17 @@ describe('areAllContiguous', () => {
|
|
|
81
83
|
[[noGeom, A], false],
|
|
82
84
|
[[A, noGeom], false],
|
|
83
85
|
[[noGeom, noGeom], false],
|
|
84
|
-
[[noType, A], false]
|
|
86
|
+
[[noType, A], false],
|
|
87
|
+
[[multiA, B], true],
|
|
88
|
+
[[A, lineThroughA], false]
|
|
85
89
|
])('returns expected result for %# features', (features, expected) => {
|
|
86
90
|
expect(areAllContiguous(features)).toBe(expected)
|
|
87
91
|
})
|
|
92
|
+
|
|
93
|
+
it('excludes a line from the contiguous group even when it spatially crosses a polygon', () => {
|
|
94
|
+
// Without the type restriction this would be true — isContiguousWithAny alone treats
|
|
95
|
+
// a line crossing a polygon's interior the same as a shared boundary.
|
|
96
|
+
expect(isContiguousWithAny(lineThroughA, [A])).toBe(true)
|
|
97
|
+
expect(areAllContiguous([A, lineThroughA])).toBe(false)
|
|
98
|
+
})
|
|
88
99
|
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
.im-c-map-key > *:first-child {
|
|
2
|
+
padding-top: 5px;
|
|
3
|
+
}
|
|
4
|
+
.im-c-map-key > *:first-child .im-c-map-key__group-heading {
|
|
5
|
+
padding-top: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.im-c-map-key--has-groups > *:not(:first-child) {
|
|
9
|
+
border-top: 1px solid var(--button-hover-color);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.im-c-map-key__group:not(:last-child) {
|
|
13
|
+
padding-bottom: 5px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.im-c-map-key__group-heading {
|
|
17
|
+
padding-top: 15px;
|
|
18
|
+
padding-bottom: 10px;
|
|
19
|
+
margin: 0;
|
|
20
|
+
font-size: 1rem;
|
|
21
|
+
font-weight: bold;
|
|
22
|
+
color: var(--foreground-color);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.im-c-map-key__item {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: start;
|
|
28
|
+
padding-top: 10px;
|
|
29
|
+
padding-bottom: 10px;
|
|
30
|
+
font-size: 1rem;
|
|
31
|
+
}
|
|
32
|
+
.im-c-map-key__group .im-c-map-key__item:first-child {
|
|
33
|
+
padding-top: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.im-c-map-key--has-groups > .im-c-map-key__item:not(:first-child) {
|
|
37
|
+
padding-top: 15px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.im-c-map-key--has-groups > .im-c-map-key__item {
|
|
41
|
+
padding-bottom: 15px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.im-c-map-key__group .im-c-map-key__item {
|
|
45
|
+
padding-top: 10px;
|
|
46
|
+
padding-bottom: 10px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.im-c-map-key > .im-c-map-key__item:last-child,
|
|
50
|
+
.im-c-map-key__group:last-child .im-c-map-key__item:last-child {
|
|
51
|
+
padding-bottom: 5px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.am-c-map-key-symbol {
|
|
55
|
+
position: relative;
|
|
56
|
+
flex-shrink: 0;
|
|
57
|
+
margin: 0 13px 0 3px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.am-c-map-key-symbol--point {
|
|
61
|
+
margin: -12px 1px -12px -9px;
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useState as e,useEffect as t}from"preact/compat";import{jsx as r,jsxs as o}from"preact/jsx-runtime";import n from"@babel/runtime/helpers/defineProperty";import l from"@babel/runtime/helpers/asyncToGenerator";var a=null,i=e=>a=e,c={"cross-hatch":'<path d="M0 4.486V3.485h3.5V.001h1v3.484h7.002V.001h1v3.484h3.5v1.001h-3.5v7h3.5v.999h-3.5v3.516h-1v-3.516H4.499v3.516h-1v-3.516H0v-.999h3.5v-7H0zm11.501 0H4.499v7h7.002v-7z" fill="{{foregroundColor}}"/>',"diagonal-cross-hatch":'<path d="M0 8.707V7.293L7.293 0h1.414L16 7.293v1.414L8.707 16H7.293L0 8.707zM.707 8L8 15.293 15.293 8 8 .707.707 8z" fill="{{foregroundColor}}"/>',"forward-diagonal-hatch":'<path d="M16 8.707V7.293L7.293 16h1.414L16 8.707zm-16 0L8.707 0H7.293L0 7.293v1.414z" fill="{{foregroundColor}}"/>',"backward-diagonal-hatch":'<path d="M0 8.707V7.293L8.707 16H7.293L0 8.707zm16 0L7.293 0h1.414L16 7.293v1.414z" fill="{{foregroundColor}}"/>',"horizontal-hatch":'<path d="M0 4.5V3.499h15.999V4.5H0zm0 7h15.999V12.5H0v-1.001z" fill="{{foregroundColor}}"/>',"vertical-hatch":'<path d="M3.501 16.001V0h1v16.001h-1zm7.998 0V0h1v16.001h-1z" fill="{{foregroundColor}}"/>',dot:'<path d="M3.999 2A2 2 0 0 1 6 3.999C6 5.103 5.103 6 3.999 6a2 2 0 0 1-1.999-2.001A2 2 0 0 1 3.999 2zm0 7.999C5.103 10 6 10.897 6 12.001A2 2 0 0 1 3.999 14a2 2 0 0 1-1.999-1.999A2 2 0 0 1 3.999 10zM11.999 2A2 2 0 0 1 14 3.999C14 5.103 13.103 6 11.999 6S10 5.103 10 3.999A2 2 0 0 1 11.999 2zm0 7.999c1.104 0 2.001.897 2.001 2.001A2 2 0 0 1 11.999 14 2 2 0 0 1 10 12.001c0-1.104.897-2.001 1.999-2.001z" fill="{{foregroundColor}}"/>',diamond:'<path d="M4 .465L7.535 4 4 7.535.465 4 4 .465zm0 7.999l3.535 3.535L4 15.535.465 11.999 4 8.464zm8-8l3.535 3.535-3.536 3.536L8.464 4 12 .464zm0 8.001L15.536 12 12 15.536 8.465 12 12 8.465z" fill="{{foregroundColor}}"/>'},s=(e,t)=>{if(!e)return null;if("string"==typeof e)return e.trim();if("object"==typeof e){if(t&&e[t])return e[t];var r=Object.values(e)[0];return null!=r?r:null}return null},f=(e,t,r)=>e.replace(/\{\{foregroundColor\}\}/g,t||"black").replace(/\{\{backgroundColor\}\}/g,r),p=new Map,d={register(e,t){p.set(e,{id:e,svgContent:t})},get:e=>p.get(e),list:()=>[...p.values()],clear(){p.clear()},initialise(){Object.entries(c).forEach(e=>{var[t,r]=e;this.register(t,r)})},getPatternInnerContent(e){return e.fillPatternSvgContent?e.fillPatternSvgContent:e.fillPattern&&null!==(t=null===(r=this.get(e.fillPattern))||void 0===r?void 0:r.svgContent)&&void 0!==t?t:null;var t,r},getKeyPatternPaths(e,t){var r=this.getPatternInnerContent(e);if(!r)return null;var o=s(e.fillPatternForegroundColor,t)||"black",n=s(e.fillPatternBackgroundColor,t)||"transparent",l=s(e.stroke,t)||o;return{border:f('<path d="M19 2.862v14.275c0 1.028-.835 1.862-1.862 1.862H2.863c-1.028 0-1.862-.835-1.862-1.862V2.862C1.001 1.834 1.836 1 2.863 1h14.275C18.166 1 19 1.835 19 2.862z" fill="{{backgroundColor}}" stroke="{{foregroundColor}}" stroke-width="2"/>',l,n),content:f(r,o,n)}},getPatternImageId(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,o=this.getPatternInnerContent(e);if(!o)return null;var n=s(e.fillPatternForegroundColor,t)||"black",l=s(e.fillPatternBackgroundColor,t)||"transparent",a=(e=>Math.max(2,2*e))(r);return"pattern-".concat((e=>{var t=0;for(var r of e)t=Math.trunc((t<<5)-t+r.codePointAt(0));return Math.abs(t).toString(36)})(o+n+l),"-").concat(a,"x")}};d.initialise();var u={symbol:"pin",backgroundColor:"#ca3535",foregroundColor:"#ffffff"},h={dot:"M8 3c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.241 5-5-2.24-5-5-5z",cross:"M6 3H10V6H13V10H10V13H6V10H3V6H6Z",diamond:"M8 2L14 8L8 14L2 8Z",triangle:"M8 2L14 14H2Z",square:"M3 3H13V13H3Z"},v={id:"pin",viewBox:"0 0 44 44",anchor:[.5,.9],graphic:h.dot,svg:'<path d="M22 40.999c-3.621 0-8.306-5.864-10.258-8.3C9.02 29.302 6 23.66 6 19.002a16.01 16.01 0 0 1 16-16 16.01 16.01 0 0 1 16 16c0 4.658-3.02 10.3-5.742 13.697-1.952 2.437-6.637 8.3-10.258 8.3z" fill="{{selectedColor}}" stroke="{{activeColor}}" stroke-width="6" paint-order="stroke fill"/>\n <path d="M22 7.001a12.01 12.01 0 0 1 12 12c0 7.623-10.377 17.998-12 17.998S10 26.624 10 19.001a12.01 12.01 0 0 1 12-12z" fill="{{backgroundColor}}" stroke="{{haloColor}}" stroke-width="2" paint-order="stroke fill"/>\n <g transform="translate(22, 19) scale(0.8) translate(-8, -8)"><path d="{{graphic}}" fill="{{foregroundColor}}"/></g>'},g={id:"circle",viewBox:"0 0 44 44",anchor:[.5,.5],graphic:h.dot,svg:'<circle cx="22" cy="22" r="16" fill="{{selectedColor}}" stroke="{{activeColor}}" stroke-width="6" paint-order="stroke fill"/>\n <circle cx="22" cy="22" r="12" fill="{{backgroundColor}}" stroke="{{haloColor}}" stroke-width="2" paint-order="stroke fill"/>\n <g transform="translate(22, 22) scale(0.8) translate(-8, -8)"><path d="{{graphic}}" fill="{{foregroundColor}}"/></g>'},m={id:"square",viewBox:"0 0 44 44",anchor:[.5,.5],graphic:h.dot,svg:'<path d="M13 6h18c3.863 0 7 3.137 7 7v18c0 3.863-3.137 7-7 7H13c-3.863 0-7-3.137-7-7V13c0-3.863 3.137-7 7-7" fill="{{selectedColor}}" stroke="{{activeColor}}" stroke-width="6" paint-order="stroke fill"/>\n <path d="M13 34a3 3 0 0 1-3-3V13a3 3 0 0 1 3-3h18a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H13z" fill-rule="nonzero" fill="{{backgroundColor}}" stroke="{{haloColor}}" stroke-width="2" paint-order="stroke fill"/>\n <g transform="translate(22, 22) scale(0.8) translate(-8, -8)"><path d="{{graphic}}" fill="{{foregroundColor}}"/></g>'},y=new Set(["symbolBackgroundColor","symbolForegroundColor","symbolHaloWidth","symbolGraphic"]),b=e=>{if(!(e=>!(!e.symbol&&!e.symbolSvgContent))(e))return{};var t={};return y.forEach(r=>{if(null!=e[r]){var o=r.charAt(6).toLowerCase()+r.slice(7);t[o]=e[r]}}),t},O=(e,t)=>{var r;return e.symbolViewBox?e.symbolViewBox:null!==(r=null==t?void 0:t.viewBox)&&void 0!==r?r:"0 0 38 38"},k={light:{haloColor:"#ffffff",selectedColor:"#0b0c0c",activeColor:"#ffdd00",foregroundColor:"#0b0c0c"},dark:{haloColor:"#0b0c0c",selectedColor:"#ffffff",activeColor:"#ffdd00",foregroundColor:"#ffffff"}};function w(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function C(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?w(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):w(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}var j=new Map,P=new Map,S={},D=e=>{var t=0;for(var r of e)t=Math.trunc((t<<5)-t+r.codePointAt(0));return Math.abs(t).toString(36)},M=new Set(["id","svg","viewBox","anchor","symbol","symbolSvgContent"]);function x(e,t,r){var o,n,l,a,i=null==r?void 0:r.id,c=Object.fromEntries(Object.entries(e||{}).filter(e=>{var[t]=e;return!M.has(t)})),f=Object.fromEntries(Object.entries(S).filter(e=>{var[t]=e;return!M.has(t)})),p=Object.fromEntries(Object.entries(t).filter(e=>{var[,t]=e;return null!=t})),d=C(C(C(C({},u),f),c),p),v=null!==(o=k[null==r?void 0:r.mapColorScheme])&&void 0!==o?o:k.light;return d.haloColor=null!==(n=null==r?void 0:r.haloColor)&&void 0!==n?n:v.haloColor,d.selectedColor=null!==(l=null==r?void 0:r.selectedColor)&&void 0!==l?l:v.selectedColor,d.activeColor=null!==(a=null==r?void 0:r.activeColor)&&void 0!==a?a:v.activeColor,"string"==typeof d.graphic&&h[d.graphic]&&(d.graphic=h[d.graphic]),Object.fromEntries(Object.entries(d).map(e=>{var[t,r]=e;return[t,s(r,i)||""]}))}function L(e,t){return Object.entries(t).reduce((e,t)=>{var[r,o]=t;return e.replaceAll("{{".concat(r,"}}"),o)},e)}var z={setDefaults(e){S=e||{}},getDefaults:()=>C(C({},u),S),register(e){j.set(e.id,e)},get:e=>j.get(e),list:()=>[...j.values()],clear(){j.clear()},initialise(){this.register(v),this.register(g),this.register(m)},resolve(e,t,r){var o=x(e,t||{},r);return e?(o.selectedColor="none",o.activeColor="none",L(e.svg,o)):""},resolveActive(e,t,r){var o=x(e,t||{},r);return e?L(e.svg,o):""},resolveSelected(e,t,r){var o=x(e,t||{},r);return e?(o.activeColor="none",L(e.svg,o)):""},getSymbolImageId(e,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:2,n=this.getSymbolDef(e);if(!n)return null;var l=b(e),a=r?this.resolveActive(n,l,t):this.resolve(n,l,t);return"symbol-".concat(r?"act-":"").concat(D(a),"-").concat(o,"x")},getSymbolDef(e){return e.symbolSvgContent?{svg:e.symbolSvgContent}:e.symbol?this.get(e.symbol):void 0},rasteriseSymbolImage(e,t,r,o){var n=this;return l(function*(){var l=n.getSymbolDef(e);if(!l)return null;var a,i,c=b(e);"active"===r?(a=n.resolveActive(l,c,t),i="act-"):"selected"===r?(a=n.resolveSelected(l,c,t),i="sel-"):(a=n.resolve(l,c,t),i="");var s="symbol-".concat(i).concat(D(a),"-").concat(o,"x"),f=P.get(s);if(!f){var p=O(e,l),[,,d,u]=p.split(" ").map(Number),h='<svg xmlns="http://www.w3.org/2000/svg" width="'.concat(d*o,'" height="').concat(u*o,'" viewBox="').concat(p,'">').concat(a,"</svg>");f=yield((e,t,r)=>new Promise((o,n)=>{var l="data:image/svg+xml;charset=utf-8,".concat(encodeURIComponent(e)),a=new Image(t,r);a.onload=()=>{var e=document.createElement("canvas");e.width=t,e.height=r;var n=e.getContext("2d");n.drawImage(a,0,0,t,r),o(n.getImageData(0,0,t,r))},a.onerror=()=>{n(new Error("Failed to rasterise SVG: ".concat(e.slice(0,80))))},a.src=l}))(h,d*o,u*o),P.set(s,f)}return{imageId:s,imageData:f}})()}};z.initialise();var I=e=>{var{text:t}=e;return r("div",{className:"im-c-map-key",children:r("p",{className:"im-c-map-key__empty-message",children:t})})};function H(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function V(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?H(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):H(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}var E=20,_={xmlns:"http://www.w3.org/2000/svg",width:E,height:E,viewBox:"0 0 ".concat(E," ").concat(E),className:"am-c-map-key-symbol","aria-hidden":"true",focusable:"false"},B=V(V({},_),{},{width:44,height:44,className:"am-c-map-key-symbol am-c-map-key-symbol--point"});function A(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function N(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?A(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):A(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}var K=n=>{var{keyDefinition:l,mapStyle:a}=n,[i,c]=e(null);return t(()=>{var{style:e}=l;c(d.getKeyPatternPaths(e,a.id))},[a.id,l]),i?o("svg",N(N({},_),{},{children:[r("g",{dangerouslySetInnerHTML:{__html:i.border}}),r("g",{transform:"translate(".concat(2,", ").concat(2,")"),dangerouslySetInnerHTML:{__html:i.content}})]})):null};function G(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function T(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?G(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):G(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}var W=o=>{var{keyDefinition:n,mapStyle:l,symbolDef:a}=o,[i,c]=e(null),[s,f]=e(null);return t(()=>{var e,{style:t}=n,r=null!==(e=null==l?void 0:l.appColorScheme)&&void 0!==e?e:"light",o=T(T({},l),{},{mapColorScheme:r});c(z.resolve(a,b(t),o)),f(O(t,a))},[l,n]),i&&s?r("svg",T(T({},B),{},{viewBox:s,children:r("g",{dangerouslySetInnerHTML:{__html:i}})})):null};function q(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function F(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?q(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):q(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}var Z=o=>{var{mapStyle:n,keyDefinition:l}=o,[a,i]=e(2),[c,f]=e("#ff0000");return t(()=>{var{style:e}=l;i(e.strokeWidth),f(s(e.stroke,n.id))},[n.id,l]),r("svg",F(F({},_),{},{children:r("line",{x1:a/2,y1:10,x2:E-a/2,y2:10,stroke:c,strokeWidth:a,strokeLinecap:"round"})}))};function R(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,o)}return r}function U(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?R(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):R(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}var J=o=>{var{mapStyle:n,keyDefinition:l}=o,[a,i]=e(2),[c,f]=e("#ff0000"),[p,d]=e("#ff0000");return t(()=>{var{style:e}=l;i(e.strokeWidth),f(s(e.fill,n.id)),d(s(e.stroke,n.id))},[n.id,l]),r("svg",U(U({},_),{},{children:r("rect",{x:a/2,y:a/2,width:E-a,height:E-a,rx:a,ry:a,fill:c,stroke:p,strokeWidth:a,strokeLinejoin:"round"})}))},Q=o=>{var{keyDefinition:n,mapStyle:l}=o,[a,i]=e(null),[c,s]=e(null);return t(()=>{if(n){var{hasSymbol:e,hasPattern:t,style:r}=n;if(e){var o=z.getSymbolDef(r);s(o),i(o?"symbol":"rect")}else t?i("pattern"):"line"===r.keySymbolShape?i("line"):i("rect")}else i(null)},[n]),a?"symbol"===a?r(W,{mapStyle:l,keyDefinition:n,symbolDef:c}):r("pattern"===a?K:"line"===a?Z:J,{mapStyle:l,keyDefinition:n}):null},X=n=>{var{keyDefinition:l,mapStyle:a}=n,[i,c]=e(""),[f,p]=e("");return t(()=>{c(l.label),p(s(l.symbolDescription,a.id))},[l,a.id]),o("dl",{className:"im-c-map-key__item",children:[r("dt",{className:"im-c-map-key__item-symbol",children:r(Q,{keyDefinition:l,mapStyle:a})}),o("dd",{className:"im-c-map-key__item-label",children:[i,f&&o("span",{className:"govuk-visually-hidden",children:["(",f,")"]})]})]})},Y=e=>{var{headingId:t,label:n,keyDefinitions:l,mapStyle:a}=e;return o("section",{className:"im-c-map-key__group","aria-labelledby":t,children:[r("h3",{id:t,className:"im-c-map-key__group-heading",children:n}),l.map(e=>r(X,{keyDefinition:e,mapStyle:a},"".concat(e.id)))]})},$="im-c-map-key",ee=e=>{var{item:t,mapStyle:o}=e;return"group"===t.type?r(Y,{headingId:"key-heading-".concat(t.id),label:t.groupLabel,keyDefinitions:t.keyDefinitions,mapStyle:o}):r(X,{keyDefinition:t.keyDefinition,mapStyle:o})},te=o=>{var{noKeyItemText:n,keyGroups:l,hasGroups:a,mapStyle:i}=o;if(null==l||!l.length)return r(I,{text:n});var[c,s]=e("im-c-map-key");return t(()=>s(a?"".concat($," ").concat("im-c-map-key--has-groups"):$),[a]),r("div",{className:c,children:l.map(e=>r(ee,{item:e,mapStyle:i},e.id))})};var re={InitComponent:function(e){var{mapState:r,services:o}=e,{eventBus:n}=o;t(()=>{r.isMapReady&&n.requestOnce("datasets:registry",i)},[r.isMapReady])},panels:[{id:"mapKey",label:"Key",mobile:{slot:"drawer",modal:!0},tablet:{slot:"left-top",width:"260px"},desktop:{slot:"left-top",width:"280px"},render:function(o){var{mapState:{mapStyle:n},pluginConfig:{noKeyItemText:l},services:{eventBus:i}}=o,[c,s]=e([]),[f,p]=e(!1),[d,u]=e(a),h=()=>{var{items:e,hasGroups:t}=d.keyItems();s(e),p(t)},v=e=>{d.invalidateKeyItemsOnMenuStateChange(e),h()};return t(()=>d?(h(),i.on("menu:changed",v).on("datasets:changed",h),()=>i.off("menu:changed",v).off("datasets:changed",h)):(i.requestOnce("datasets:registry",u),()=>{}),[d]),r(te,{noKeyItemText:l,keyGroups:c,hasGroups:f,mapStyle:n})}}],buttons:[{id:"mapKey",panelId:"mapKey",label:"Key",iconId:"key",mobile:{slot:"top-left",showLabel:!1},tablet:{slot:"top-left",showLabel:!0},desktop:{slot:"top-left",showLabel:!0}}],icons:[{id:"key",svgContent:'<path d="M3 5h.01"/><path d="M3 12h.01"/><path d="M3 19h.01"/><path d="M8 5h13"/><path d="M8 12h13"/><path d="M8 19h13"/>'}]};export{re as manifest};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"@babel/runtime/helpers/asyncToGenerator";import r from"@babel/runtime/helpers/defineProperty";function t(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,n)}return t}function n(e){for(var n=1;n<arguments.length;n++){var o=null!=arguments[n]?arguments[n]:{};n%2?t(Object(o),!0).forEach(function(t){r(e,t,o[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(o)):t(Object(o)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(o,r))})}return e}function o(){var r;return n(n({noKeyItemText:"No features displayed"},arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),{},{id:"mapKey",load:(r=e(function*(){return(yield import(/* webpackChunkName: "im-map-key-plugin" */ "./im-map-key-plugin.js")).manifest}),function(){return r.apply(this,arguments)})})}export{o as default};
|