@defra/interactive-map 0.0.3-alpha → 0.0.4-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/README.md +16 -57
- package/dist/esm/im-core.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/button-definition.md +176 -0
- package/docs/api/context.md +124 -0
- package/docs/api/control-definition.md +72 -0
- package/docs/api/icon-definition.md +28 -0
- package/docs/api/map-style-config.md +76 -0
- package/docs/api/marker-config.md +51 -0
- package/docs/api/panel-definition.md +117 -0
- package/docs/api/slots.md +25 -0
- package/docs/api.md +713 -0
- package/docs/architecture.md +139 -0
- package/docs/building-a-plugin.md +149 -0
- package/docs/getting-started.md +46 -0
- package/docs/govuk-prototype.md +0 -0
- package/docs/plugins/interact.md +205 -0
- package/docs/plugins/map-styles.md +84 -0
- package/docs/plugins/plugin-context.md +67 -0
- package/docs/plugins/plugin-descriptor.md +71 -0
- package/docs/plugins/plugin-manifest.md +118 -0
- package/docs/plugins/scale-bar.md +62 -0
- package/docs/plugins/search.md +162 -0
- package/docs/plugins.md +116 -0
- package/govuk-prototype-kit.config.json +7 -7
- package/package.json +14 -1
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -0
- package/plugins/beta/datasets/dist/esm/index.js +2 -0
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +1 -0
- package/plugins/beta/datasets/dist/umd/index.js +2 -0
- package/plugins/{datasets → beta/datasets}/src/manifest.js +1 -1
- package/plugins/{datasets → beta/datasets}/src/mapLayers.js +1 -1
- package/plugins/{datasets → beta/datasets}/src/panels/Key.jsx +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -0
- package/plugins/beta/draw-ml/dist/esm/index.js +2 -0
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -0
- package/plugins/beta/draw-ml/dist/umd/index.js +2 -0
- package/plugins/{draw-ml → beta/draw-ml}/src/api/editFeature.js +1 -1
- package/plugins/beta/draw-ml/src/api/merge.js +9 -0
- package/plugins/beta/draw-ml/src/api/newLine.js +43 -0
- package/plugins/{draw-ml → beta/draw-ml}/src/api/newPolygon.js +5 -5
- package/plugins/beta/draw-ml/src/api/split.js +81 -0
- package/plugins/{draw-ml → beta/draw-ml}/src/defaults.js +2 -0
- package/plugins/{draw-ml → beta/draw-ml}/src/events.js +105 -3
- package/plugins/{draw-ml → beta/draw-ml}/src/manifest.js +17 -11
- package/plugins/{draw-ml → beta/draw-ml}/src/mapboxDraw.js +51 -2
- package/plugins/{draw-ml → beta/draw-ml}/src/mapboxSnap.js +2 -0
- package/plugins/beta/draw-ml/src/modes/createDrawMode.js +496 -0
- package/plugins/beta/draw-ml/src/modes/drawLineMode.js +18 -0
- package/plugins/beta/draw-ml/src/modes/drawPolygonMode.js +16 -0
- package/plugins/beta/draw-ml/src/modes/editVertexMode.js +792 -0
- package/plugins/{draw-ml → beta/draw-ml}/src/reducer.js +30 -2
- package/plugins/{draw-ml → beta/draw-ml}/src/styles.js +66 -36
- package/plugins/beta/draw-ml/src/undoStack.js +50 -0
- package/plugins/beta/draw-ml/src/utils/debounce.js +16 -0
- package/plugins/beta/draw-ml/src/utils/spatial.js +258 -0
- package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -0
- package/plugins/beta/frame/dist/esm/index.js +2 -0
- package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -0
- package/plugins/beta/frame/dist/umd/index.js +2 -0
- package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -0
- package/plugins/beta/map-styles/dist/esm/index.js +2 -0
- package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -0
- package/plugins/beta/map-styles/dist/umd/index.js +2 -0
- package/plugins/{map-styles → beta/map-styles}/src/MapStyles.jsx +1 -1
- package/plugins/{map-styles → beta/map-styles}/src/manifest.js +8 -10
- package/plugins/beta/scale-bar/dist/esm/im-scale-bar-plugin.js +1 -0
- package/plugins/beta/scale-bar/dist/esm/index.js +2 -0
- package/plugins/beta/scale-bar/dist/umd/im-scale-bar-plugin.js +1 -0
- package/plugins/beta/scale-bar/dist/umd/index.js +2 -0
- package/plugins/beta/use-location/dist/esm/im-use-location-plugin.js +1 -0
- package/plugins/beta/use-location/dist/esm/index.js +2 -0
- package/plugins/beta/use-location/dist/umd/im-use-location-plugin.js +1 -0
- package/plugins/beta/use-location/dist/umd/index.js +2 -0
- package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/esm/index.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/InteractInit.test.js +97 -0
- package/plugins/interact/src/api/clear.test.js +18 -0
- package/plugins/interact/src/api/disable.test.js +12 -0
- package/plugins/interact/src/api/enable.test.js +48 -0
- package/plugins/interact/src/api/selectFeature.test.js +33 -0
- package/plugins/interact/src/api/unselectFeature.test.js +33 -0
- package/plugins/interact/src/defaults.js +1 -0
- package/plugins/interact/src/events.test.js +151 -0
- package/plugins/interact/src/hooks/useHighlightSync.test.js +212 -0
- package/plugins/interact/src/hooks/useInteractionHandlers.js +14 -7
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +260 -0
- package/plugins/interact/src/index.test.js +22 -0
- package/plugins/interact/src/manifest.js +1 -1
- package/plugins/interact/src/manifest.test.js +94 -0
- package/plugins/interact/src/reducer.js +10 -1
- package/plugins/interact/src/reducer.test.js +142 -0
- package/plugins/interact/src/utils/buildStylesMap.test.js +57 -0
- package/plugins/interact/src/utils/featureQueries.test.js +56 -0
- package/plugins/interact/src/utils/turfHelpers.js +30 -0
- package/plugins/interact/src/utils/turfHelpers.test.js +30 -0
- 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/utils/parseOsNamesResults.js +3 -7
- package/providers/{esri → beta/esri}/src/mapEvents.js +2 -2
- package/providers/beta/open-names/dist/esm/im-reverse-geocode.js +2 -0
- package/providers/beta/open-names/dist/esm/index.js +2 -0
- package/providers/beta/open-names/dist/umd/im-reverse-geocode.js +2 -0
- package/providers/beta/open-names/dist/umd/index.js +2 -0
- package/providers/maplibre/dist/esm/im-maplibre-framework.js +1 -1
- package/providers/maplibre/dist/esm/im-maplibre-framework.js.LICENSE.txt +1 -1
- package/providers/maplibre/dist/esm/im-maplibre-legacy-framework.js +1 -1
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/esm/index.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-framework.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-framework.js.LICENSE.txt +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-legacy-framework.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/index.js +14 -1
- package/providers/maplibre/src/maplibreProvider.js +127 -0
- package/sonar-project.properties +1 -1
- package/src/App/hooks/useInterfaceAPI.js +24 -1
- package/src/App/renderer/mapButtons.js +1 -1
- package/src/App/store/appActionsMap.js +22 -1
- package/src/InteractiveMap/InteractiveMap.js +114 -6
- package/src/config/defaults.js +29 -20
- package/src/config/events.js +110 -4
- package/src/index.js +5 -2
- package/src/scss/tools/_border-focus.scss +20 -4
- package/src/types.js +585 -0
- package/webpack.esm.mjs +8 -8
- package/webpack.umd.mjs +8 -8
- package/plugins/datasets/dist/esm/im-datasets-plugin.js +0 -1
- package/plugins/datasets/dist/esm/index.js +0 -2
- package/plugins/datasets/dist/umd/im-datasets-plugin.js +0 -1
- package/plugins/datasets/dist/umd/index.js +0 -2
- package/plugins/draw-ml/dist/esm/im-draw-ml-plugin.js +0 -1
- package/plugins/draw-ml/dist/esm/index.js +0 -2
- package/plugins/draw-ml/dist/umd/im-draw-ml-plugin.js +0 -1
- package/plugins/draw-ml/dist/umd/index.js +0 -2
- package/plugins/draw-ml/src/modes/drawVertexMode.js +0 -275
- package/plugins/draw-ml/src/modes/editVertexMode.js +0 -426
- package/plugins/draw-ml/src/utils.js +0 -102
- package/plugins/frame/dist/esm/im-frame-plugin.js +0 -1
- package/plugins/frame/dist/esm/index.js +0 -2
- package/plugins/frame/dist/umd/im-frame-plugin.js +0 -1
- package/plugins/frame/dist/umd/index.js +0 -2
- package/plugins/map-styles/dist/esm/im-map-styles-plugin.js +0 -1
- package/plugins/map-styles/dist/esm/index.js +0 -2
- package/plugins/map-styles/dist/umd/im-map-styles-plugin.js +0 -1
- package/plugins/map-styles/dist/umd/index.js +0 -2
- package/plugins/scale-bar/dist/esm/im-scale-bar-plugin.js +0 -1
- package/plugins/scale-bar/dist/esm/index.js +0 -2
- package/plugins/scale-bar/dist/umd/im-scale-bar-plugin.js +0 -1
- package/plugins/scale-bar/dist/umd/index.js +0 -2
- package/plugins/use-location/dist/esm/im-use-location-plugin.js +0 -1
- package/plugins/use-location/dist/esm/index.js +0 -2
- package/plugins/use-location/dist/umd/im-use-location-plugin.js +0 -1
- package/plugins/use-location/dist/umd/index.js +0 -2
- package/providers/open-names/dist/esm/im-reverse-geocode.js +0 -2
- package/providers/open-names/dist/esm/index.js +0 -2
- package/providers/open-names/dist/umd/im-reverse-geocode.js +0 -2
- package/providers/open-names/dist/umd/index.js +0 -2
- /package/docs/architecture/{ARCHITECTURE_DIAGRAMS.md → architecture-diagrams.md} +0 -0
- /package/plugins/{datasets → beta/datasets}/dist/css/index.css +0 -0
- /package/plugins/{datasets → beta/datasets}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/plugins/{datasets → beta/datasets}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/plugins/{datasets → beta/datasets}/src/DatasetsInit.jsx +0 -0
- /package/plugins/{datasets → beta/datasets}/src/api/addDataset.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/api/hideDataset.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/api/hideFeatures.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/api/removeDataset.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/api/showDataset.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/api/showFeatures.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/datasets.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/datasets.scss +0 -0
- /package/plugins/{datasets → beta/datasets}/src/defaults.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/handleSetMapStyle.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/index.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/panels/Key.module.scss +0 -0
- /package/plugins/{datasets → beta/datasets}/src/panels/Layers.jsx +0 -0
- /package/plugins/{datasets → beta/datasets}/src/panels/Layers.module.scss +0 -0
- /package/plugins/{datasets → beta/datasets}/src/reducer.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/utils/bbox.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/utils/debounce.js +0 -0
- /package/plugins/{datasets → beta/datasets}/src/utils/filters.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/DrawInit.jsx +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/api/addFeature.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/api/deleteFeature.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/api/editFeature.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/api/newPolygon.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/events.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/graphic.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/index.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/manifest.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/reducer.js +0 -0
- /package/plugins/{draw-es → beta/draw-es}/src/sketchViewModel.js +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/dist/css/index.css +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/src/DrawInit.jsx +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/src/api/addFeature.js +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/src/api/deleteFeature.js +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/src/draw.scss +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/src/index.js +0 -0
- /package/plugins/{draw-ml → beta/draw-ml}/src/modes/disabledMode.js +0 -0
- /package/plugins/{draw-ml/src → beta/draw-ml/src/utils}/snapHelpers.js +0 -0
- /package/plugins/{frame → beta/frame}/dist/css/index.css +0 -0
- /package/plugins/{frame → beta/frame}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/plugins/{frame → beta/frame}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/plugins/{frame → beta/frame}/package.json +0 -0
- /package/plugins/{frame → beta/frame}/src/Frame.jsx +0 -0
- /package/plugins/{frame → beta/frame}/src/FrameInit.jsx +0 -0
- /package/plugins/{frame → beta/frame}/src/api/addFrame.js +0 -0
- /package/plugins/{frame → beta/frame}/src/api/editFeature.js +0 -0
- /package/plugins/{frame → beta/frame}/src/config.js +0 -0
- /package/plugins/{frame → beta/frame}/src/frame.scss +0 -0
- /package/plugins/{frame → beta/frame}/src/index.js +0 -0
- /package/plugins/{frame → beta/frame}/src/manifest.js +0 -0
- /package/plugins/{frame → beta/frame}/src/reducer.js +0 -0
- /package/plugins/{frame → beta/frame}/src/utils.js +0 -0
- /package/plugins/{map-styles → beta/map-styles}/dist/css/index.css +0 -0
- /package/plugins/{map-styles → beta/map-styles}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/plugins/{map-styles → beta/map-styles}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/plugins/{map-styles → beta/map-styles}/src/MapStylesInit.jsx +0 -0
- /package/plugins/{map-styles → beta/map-styles}/src/config.js +0 -0
- /package/plugins/{map-styles → beta/map-styles}/src/index.js +0 -0
- /package/plugins/{map-styles → beta/map-styles}/src/mapStyles.scss +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/dist/css/index.css +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/package.json +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/ScaleBar.jsx +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/ScaleBar.test.jsx +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/index.js +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/index.test.js +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/manifest.js +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/scaleBar.scss +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/utils.js +0 -0
- /package/plugins/{scale-bar → beta/scale-bar}/src/utils.test.js +0 -0
- /package/plugins/{use-location → beta/use-location}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/plugins/{use-location → beta/use-location}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/plugins/{use-location → beta/use-location}/src/UseLocation.jsx +0 -0
- /package/plugins/{use-location → beta/use-location}/src/UseLocationInit.jsx +0 -0
- /package/plugins/{use-location → beta/use-location}/src/defaults.js +0 -0
- /package/plugins/{use-location → beta/use-location}/src/events.js +0 -0
- /package/plugins/{use-location → beta/use-location}/src/index.js +0 -0
- /package/plugins/{use-location → beta/use-location}/src/manifest.js +0 -0
- /package/plugins/{use-location → beta/use-location}/src/reducer.js +0 -0
- /package/providers/{esri → beta/esri}/src/appEvents.js +0 -0
- /package/providers/{esri → beta/esri}/src/defaults.js +0 -0
- /package/providers/{esri → beta/esri}/src/esriProvider.js +0 -0
- /package/providers/{esri → beta/esri}/src/esriProvider.scss +0 -0
- /package/providers/{esri → beta/esri}/src/index.js +0 -0
- /package/providers/{esri → beta/esri}/src/utils/coords.js +0 -0
- /package/providers/{esri → beta/esri}/src/utils/detectWebGL.js +0 -0
- /package/providers/{esri → beta/esri}/src/utils/esriFixes.js +0 -0
- /package/providers/{esri → beta/esri}/src/utils/query.js +0 -0
- /package/providers/{esri → beta/esri}/src/utils/spatial.js +0 -0
- /package/providers/{open-names → beta/open-names}/dist/esm/im-reverse-geocode.js.LICENSE.txt +0 -0
- /package/providers/{open-names → beta/open-names}/dist/esm/index.js.LICENSE.txt +0 -0
- /package/providers/{open-names → beta/open-names}/dist/umd/im-reverse-geocode.js.LICENSE.txt +0 -0
- /package/providers/{open-names → beta/open-names}/dist/umd/index.js.LICENSE.txt +0 -0
- /package/providers/{open-names → beta/open-names}/src/index.js +0 -0
- /package/providers/{open-names → beta/open-names}/src/reverseGeocode.js +0 -0
- /package/providers/{open-names → beta/open-names}/src/utils/mapToLocationModel.js +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Architecture Overview
|
|
2
|
+
|
|
3
|
+
This framework is a **web mapping platform** designed to let teams add interactive maps to public-facing services in a consistent, extensible, and framework-agnostic way.
|
|
4
|
+
|
|
5
|
+
At its core, it provides:
|
|
6
|
+
* A stable map UI with consistent behaviour
|
|
7
|
+
* A plugin system for extending functionality
|
|
8
|
+
* An abstraction layer over multiple mapping engines
|
|
9
|
+
|
|
10
|
+
The system is designed so that **the core controls rendering and layout**, while **plugins declaratively contribute behaviour and UI.** ---
|
|
11
|
+
|
|
12
|
+
## High-level Structure
|
|
13
|
+
|
|
14
|
+
The framework consists of five main parts:
|
|
15
|
+
1. **Public API** (Vanilla JS wrapper)
|
|
16
|
+
2. **Core React component**
|
|
17
|
+
3. **Map provider abstraction**
|
|
18
|
+
4. **Plugin system**
|
|
19
|
+
5. **Rendering and slot system**
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Public API (Vanilla JS wrapper)
|
|
24
|
+
|
|
25
|
+
The framework is consumed via a **vanilla JavaScript API**, making it easy to integrate into a wide range of environments (including legacy stacks and non-React applications).
|
|
26
|
+
|
|
27
|
+
This wrapper:
|
|
28
|
+
|
|
29
|
+
* **Instantiates** the core component
|
|
30
|
+
* **Passes** configuration, plugins, and providers
|
|
31
|
+
* **Exposes** events and methods to the host application
|
|
32
|
+
|
|
33
|
+
> **Note:** Internally, the UI is implemented in React, but this is an implementation detail and not required knowledge for consumers.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Core Component
|
|
38
|
+
|
|
39
|
+
The core component is the orchestrator of the application. It:
|
|
40
|
+
* Owns application state
|
|
41
|
+
* Controls rendering and layout
|
|
42
|
+
* Provides consistent map interactions (search, identify, draw, pan, etc.)
|
|
43
|
+
* Manages plugins, providers, and UI composition
|
|
44
|
+
|
|
45
|
+
**Stability Guarantee:** Plugins never control the render lifecycle. The core always mounts and renders independently of plugin success or failure.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 3. Map Provider Abstraction
|
|
50
|
+
|
|
51
|
+
The framework is **not tied to a specific mapping library.** It uses a `mapProvider` interface defining semantic operations such as:
|
|
52
|
+
* Fitting the map to bounds
|
|
53
|
+
* Setting the view zoom and centre
|
|
54
|
+
* Querying features
|
|
55
|
+
|
|
56
|
+
This allows providers to be swapped without rewriting plugins or UI code.
|
|
57
|
+
|
|
58
|
+
### MapLibre (Recommended)
|
|
59
|
+
|
|
60
|
+
Our reference provider, offering the most complete and tested experience:
|
|
61
|
+
|
|
62
|
+
<table>
|
|
63
|
+
<tr>
|
|
64
|
+
<td><strong>Out of the box</strong></td>
|
|
65
|
+
<td>Works immediately with no additional</td>
|
|
66
|
+
</tr>
|
|
67
|
+
<tr>
|
|
68
|
+
<td><strong>Modern and lightweight</strong></td>
|
|
69
|
+
<td>Better performance with smaller bundle sizes</td>
|
|
70
|
+
</tr>
|
|
71
|
+
<tr>
|
|
72
|
+
<td><strong>Vector tile support</strong></td>
|
|
73
|
+
<td>Most comprehensive support for vector tiles</td>
|
|
74
|
+
</tr>
|
|
75
|
+
<tr>
|
|
76
|
+
<td><strong>Enhanced accessibility</strong></td>
|
|
77
|
+
<td>The most accessbile offering</td>
|
|
78
|
+
</tr>
|
|
79
|
+
</table>
|
|
80
|
+
|
|
81
|
+
### Esri (Experimental)
|
|
82
|
+
An alternative provider with specific advantages:
|
|
83
|
+
|
|
84
|
+
<table>
|
|
85
|
+
<tr>
|
|
86
|
+
<td><strong>British National Grid</strong></td>
|
|
87
|
+
<td>Native support for BNG coordinate systems</td>
|
|
88
|
+
</tr>
|
|
89
|
+
</table>
|
|
90
|
+
|
|
91
|
+
## 4. Plugin System
|
|
92
|
+
|
|
93
|
+
### Declarative by Design
|
|
94
|
+
Plugins describe what they add using a **manifest** (buttons, panels, shortcuts). They are contributors, not "render owners."
|
|
95
|
+
|
|
96
|
+
### Registration vs Rendering
|
|
97
|
+
* **Registration:** Reads manifests and populates central registries at load time.
|
|
98
|
+
* **Rendering:** Controlled entirely by the core, which decides where and how items appear based on current state.
|
|
99
|
+
|
|
100
|
+
### Isolation
|
|
101
|
+
Each plugin receives a **ring-fenced slice of state**. They have read access to `appState`, `mapState`, `appConfig`, and `services` (eventBus, geocoding, etc.).
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 5. Rendering and Slot System
|
|
106
|
+
|
|
107
|
+
The UI uses a **slot-based system**. Slots represent logical areas (e.g., actions, side panels, modals).
|
|
108
|
+
|
|
109
|
+
Plugins declare UI elements with layout hints (which slot to use, modal vs non-modal, mobile vs desktop behavior). The core evaluates these rules to guarantee:
|
|
110
|
+
* Consistent layout and accessibility
|
|
111
|
+
* Centralized responsive design
|
|
112
|
+
* UI stability (plugins cannot "block" the interface)
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Event Bus
|
|
117
|
+
|
|
118
|
+
Provides two-way, decoupled communication between the core, plugins, and the vanilla JS layer. This allows external applications to react to internal state changes without tight coupling.
|
|
119
|
+
|
|
120
|
+
## Mental Model for Developers
|
|
121
|
+
|
|
122
|
+
|||
|
|
123
|
+
| :--- | :--- |
|
|
124
|
+
| **Core** | The Platform |
|
|
125
|
+
| **Plugins** | Declarative Feature Descriptions |
|
|
126
|
+
| **Providers** | Adapters for Map Engines |
|
|
127
|
+
| **Slots** | Layout Positions |
|
|
128
|
+
| **State** | Shared Context |
|
|
129
|
+
|
|
130
|
+
## Tech stack
|
|
131
|
+
|
|
132
|
+
|||
|
|
133
|
+
| :--- | :--- |
|
|
134
|
+
| **React** | UI component framework |
|
|
135
|
+
| **MapLibre** | Primary mapping engine |
|
|
136
|
+
| **Webpack** | Module bundling (UMD, ESM builds) |
|
|
137
|
+
| **Jest** | Testing framework |
|
|
138
|
+
| **SCSS** | Styling |
|
|
139
|
+
| **Babel** | JavaScript compilation |
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Building Plugins
|
|
2
|
+
|
|
3
|
+
Plugins extend the InteractiveMap with custom buttons, panels, controls, and behaviours. This guide introduces the plugin system and links to the detailed reference documentation.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
A plugin is a module that registers UI elements and logic with the map. Plugins can:
|
|
8
|
+
|
|
9
|
+
- Add **buttons** to the toolbar with built-in styling and behaviour
|
|
10
|
+
- Add **panels** for content like search results or layer controls
|
|
11
|
+
- Add **controls** for fully custom UI elements
|
|
12
|
+
- Register **icons** for use across the application
|
|
13
|
+
- Expose **API methods** callable from outside the plugin
|
|
14
|
+
- Manage **state** with a reducer pattern
|
|
15
|
+
|
|
16
|
+
## How Plugins Work
|
|
17
|
+
|
|
18
|
+
A plugin consists of two parts:
|
|
19
|
+
|
|
20
|
+
1. **Factory function** - Exports a function that accepts configuration and returns a [PluginDescriptor](./plugins/plugin-descriptor.md)
|
|
21
|
+
2. **Manifest** - Defines the plugin's buttons, panels, controls, and other elements
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
// scale-bar/index.js
|
|
25
|
+
export default function createPlugin ({ units = 'metric' } = {}) {
|
|
26
|
+
return {
|
|
27
|
+
id: 'scaleBar',
|
|
28
|
+
units,
|
|
29
|
+
load: async () => {
|
|
30
|
+
const { manifest } = await import('./manifest.js')
|
|
31
|
+
return manifest
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The factory pattern allows configuration to be passed when registering the plugin. All properties (except `id` and `load`) are available as [pluginConfig](./plugins/plugin-context.md#pluginconfig) within the plugin.
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
import createScaleBarPlugin from '@defra/interactive-map-plugin-scale-bar'
|
|
41
|
+
|
|
42
|
+
const interactiveMap = new InteractiveMap({
|
|
43
|
+
// ... other options
|
|
44
|
+
plugins: [
|
|
45
|
+
createScaleBarPlugin({ units: 'imperial' })
|
|
46
|
+
]
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
When the map initialises, it calls each plugin's `load` function and registers the manifest's buttons, panels, controls, and other elements.
|
|
51
|
+
|
|
52
|
+
## Plugin Context
|
|
53
|
+
|
|
54
|
+
Plugin components and callbacks receive a [PluginContext](./plugins/plugin-context.md) object providing access to:
|
|
55
|
+
|
|
56
|
+
- **appConfig** - Application configuration
|
|
57
|
+
- **appState** - Current app state (breakpoint, interface type, etc.)
|
|
58
|
+
- **mapState** - Current map state (zoom, center, bounds)
|
|
59
|
+
- **mapProvider** - Methods to interact with the map
|
|
60
|
+
- **pluginConfig** - Configuration passed to the factory function
|
|
61
|
+
- **pluginState** - Plugin-specific state from your reducer
|
|
62
|
+
- **services** - Core services (announcements, reverse geocoding, event bus)
|
|
63
|
+
|
|
64
|
+
## Quick Example
|
|
65
|
+
|
|
66
|
+
The scale-bar plugin displays the current map scale. It accepts a `units` option to configure the display format.
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
// scale-bar/index.js
|
|
70
|
+
export default function createPlugin ({ units = 'metric' } = {}) {
|
|
71
|
+
return {
|
|
72
|
+
id: 'scaleBar',
|
|
73
|
+
units,
|
|
74
|
+
load: async () => {
|
|
75
|
+
const { manifest } = await import('./manifest.js')
|
|
76
|
+
return manifest
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
// scale-bar/manifest.js
|
|
84
|
+
import { ScaleBar } from './ScaleBar.jsx'
|
|
85
|
+
|
|
86
|
+
export const manifest = {
|
|
87
|
+
controls: [{
|
|
88
|
+
id: 'scaleBar',
|
|
89
|
+
label: 'Scale bar',
|
|
90
|
+
mobile: { slot: 'footer-right' },
|
|
91
|
+
tablet: { slot: 'footer-right' },
|
|
92
|
+
desktop: { slot: 'footer-right' },
|
|
93
|
+
render: ScaleBar
|
|
94
|
+
}]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```jsx
|
|
99
|
+
// scale-bar/ScaleBar.jsx
|
|
100
|
+
export function ScaleBar ({ mapState, pluginConfig }) {
|
|
101
|
+
const { resolution } = mapState
|
|
102
|
+
const { units } = pluginConfig
|
|
103
|
+
|
|
104
|
+
// Calculate scale based on resolution and units
|
|
105
|
+
const scale = calculateScale(resolution, units)
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div className="scale-bar">
|
|
109
|
+
{scale.label}
|
|
110
|
+
</div>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
// Usage
|
|
117
|
+
import createScaleBarPlugin from '@defra/interactive-map-plugin-scale-bar'
|
|
118
|
+
|
|
119
|
+
const interactiveMap = new InteractiveMap({
|
|
120
|
+
plugins: [
|
|
121
|
+
createScaleBarPlugin({ units: 'imperial' })
|
|
122
|
+
]
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Reference Documentation
|
|
127
|
+
|
|
128
|
+
For detailed specifications, see:
|
|
129
|
+
|
|
130
|
+
- [PluginDescriptor](./plugins/plugin-descriptor.md) - How to register a plugin
|
|
131
|
+
- [PluginManifest](./plugins/plugin-manifest.md) - What a plugin can contain
|
|
132
|
+
- [PluginContext](./plugins/plugin-context.md) - Context available to plugin code
|
|
133
|
+
- [ButtonDefinition](./api/button-definition.md) - Button configuration
|
|
134
|
+
- [PanelDefinition](./api/panel-definition.md) - Panel configuration
|
|
135
|
+
- [ControlDefinition](./api/control-definition.md) - Custom control configuration
|
|
136
|
+
- [IconDefinition](./api/icon-definition.md) - Icon registration
|
|
137
|
+
- [Slots](./api/slots.md) - UI slot system for positioning elements
|
|
138
|
+
|
|
139
|
+
## Events
|
|
140
|
+
|
|
141
|
+
Plugins can subscribe to application and map events via the `eventBus` service. See the [Events](./api.md#events) section in the API reference for available events.
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
const { eventBus, events } = context.services
|
|
145
|
+
|
|
146
|
+
eventBus.on(events.APP_PANEL_OPENED, ({ panelId }) => {
|
|
147
|
+
console.log('Panel opened:', panelId)
|
|
148
|
+
})
|
|
149
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
Run:
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
npm i @defra/interactive-map
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Use in production
|
|
12
|
+
|
|
13
|
+
In your html, you will need to add a container element for the map:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<div id="map"></div>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
You will need to initialise and configure InteractiveMap in your client side code:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
import InteractiveMap from '@defra/interactive-map'
|
|
23
|
+
import maplibreProvider from '@defra/interactive-map/providers/maplibre'
|
|
24
|
+
|
|
25
|
+
const interactiveMap = new InteractiveMap('map', {
|
|
26
|
+
mapProvider: maplibreProvider(),
|
|
27
|
+
behaviour: 'hybrid',
|
|
28
|
+
mapLabel: 'Ambleside',
|
|
29
|
+
zoom: 14,
|
|
30
|
+
center: [-2.968, 54.425],
|
|
31
|
+
containerHeight: '650px',
|
|
32
|
+
mapStyle: {
|
|
33
|
+
url: 'https://tiles.openfreemap.org/styles/liberty',
|
|
34
|
+
attribution: 'OpenFreeMap © OpenMapTiles Data from OpenStreetMap',
|
|
35
|
+
backgroundColor: '#f5f5f0'
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## GOV.UK Prototype kit plugin
|
|
41
|
+
|
|
42
|
+
Following installation the InteractiveMap plugin will be added to your prototype. You can now create pages with a map, and configure for specific use cases.
|
|
43
|
+
|
|
44
|
+
See [Install and use plugins](https://prototype-kit.service.gov.uk/docs/install-and-use-plugins).
|
|
45
|
+
|
|
46
|
+
See [Configuring InteractiveMap in a GOVUK Prototype](./docs/govuk-prototype).
|
|
File without changes
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Interact Plugin
|
|
2
|
+
|
|
3
|
+
Select features or place markers on the map. The interact plugin provides a unified way to handle user interactions for selecting map features or placing location markers.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import createInteractPlugin from '@defra/interactive-map/plugins/interact'
|
|
9
|
+
|
|
10
|
+
const interactPlugin = createInteractPlugin()
|
|
11
|
+
|
|
12
|
+
const interactiveMap = new InteractiveMap({
|
|
13
|
+
plugins: [interactPlugin]
|
|
14
|
+
})
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Options
|
|
18
|
+
|
|
19
|
+
Options are passed to the factory function when creating the plugin.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### `includeModes`
|
|
24
|
+
**Type:** `string[]`
|
|
25
|
+
|
|
26
|
+
Array of mode identifiers. When set, the plugin only renders when the app is in one of these modes.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
### `excludeModes`
|
|
31
|
+
**Type:** `string[]`
|
|
32
|
+
|
|
33
|
+
Array of mode identifiers. When set, the plugin does not render when the app is in one of these modes.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Methods
|
|
38
|
+
|
|
39
|
+
Methods are called on the plugin instance after the map is ready.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
### `enable()`
|
|
44
|
+
|
|
45
|
+
Enable interaction mode. Shows action buttons and enables feature selection or marker placement.
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
interactiveMap.on('map:ready', () => {
|
|
49
|
+
interactPlugin.enable()
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### `disable()`
|
|
56
|
+
|
|
57
|
+
Disable interaction mode. Hides action buttons and disables interactions.
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
interactPlugin.disable()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### `clear()`
|
|
66
|
+
|
|
67
|
+
Clear the current selection or marker.
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
interactPlugin.clear()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### `selectFeature(feature)`
|
|
76
|
+
|
|
77
|
+
Programmatically select a feature.
|
|
78
|
+
|
|
79
|
+
| Parameter | Type | Description |
|
|
80
|
+
|-----------|------|-------------|
|
|
81
|
+
| `feature` | `Object` | Feature object to select |
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
interactPlugin.selectFeature({ id: 'feature-1', bounds: [...] })
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### `unselectFeature()`
|
|
90
|
+
|
|
91
|
+
Clear the currently selected feature.
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
interactPlugin.unselectFeature()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Events
|
|
100
|
+
|
|
101
|
+
Subscribe to events using `interactiveMap.on()`.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### `interact:done`
|
|
106
|
+
|
|
107
|
+
Emitted when the user confirms their selection (clicks "Done").
|
|
108
|
+
|
|
109
|
+
**Payload:**
|
|
110
|
+
```js
|
|
111
|
+
{
|
|
112
|
+
marker: { coords: [lng, lat] } | null,
|
|
113
|
+
selection: { bounds: [...], feature: {...} } | null
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
interactiveMap.on('interact:done', ({ marker, selection }) => {
|
|
119
|
+
if (marker) {
|
|
120
|
+
console.log('Location selected:', marker.coords)
|
|
121
|
+
}
|
|
122
|
+
if (selection) {
|
|
123
|
+
console.log('Feature selected:', selection.feature)
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### `interact:cancel`
|
|
131
|
+
|
|
132
|
+
Emitted when the user cancels the interaction.
|
|
133
|
+
|
|
134
|
+
**Payload:** None
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
interactiveMap.on('interact:cancel', () => {
|
|
138
|
+
console.log('Interaction cancelled')
|
|
139
|
+
})
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### `interact:markerchange`
|
|
145
|
+
|
|
146
|
+
Emitted when the marker position changes.
|
|
147
|
+
|
|
148
|
+
**Payload:**
|
|
149
|
+
```js
|
|
150
|
+
{
|
|
151
|
+
coords: [lng, lat]
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```js
|
|
156
|
+
interactiveMap.on('interact:markerchange', ({ coords }) => {
|
|
157
|
+
console.log('Marker moved to:', coords)
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### `interact:selectionchange`
|
|
164
|
+
|
|
165
|
+
Emitted when the feature selection changes.
|
|
166
|
+
|
|
167
|
+
**Payload:**
|
|
168
|
+
```js
|
|
169
|
+
{
|
|
170
|
+
bounds: [west, south, east, north],
|
|
171
|
+
feature: { ... }
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
interactiveMap.on('interact:selectionchange', ({ bounds, feature }) => {
|
|
177
|
+
console.log('Selection changed:', feature)
|
|
178
|
+
})
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### `interact:selectFeature`
|
|
184
|
+
|
|
185
|
+
Emitted when a feature is programmatically selected via the API.
|
|
186
|
+
|
|
187
|
+
**Payload:**
|
|
188
|
+
```js
|
|
189
|
+
{
|
|
190
|
+
feature: { ... }
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### `interact:unselectFeature`
|
|
197
|
+
|
|
198
|
+
Emitted when a feature is programmatically unselected via the API.
|
|
199
|
+
|
|
200
|
+
**Payload:**
|
|
201
|
+
```js
|
|
202
|
+
{
|
|
203
|
+
feature: { ... }
|
|
204
|
+
}
|
|
205
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Map Styles Plugin
|
|
2
|
+
|
|
3
|
+
Map style switching plugin that adds a UI control for changing the basemap appearance and the map size.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import createMapStylesPlugin from '@defra/interactive-map/plugins/map-styles'
|
|
9
|
+
|
|
10
|
+
const mapStylesPlugin = createMapStylesPlugin({
|
|
11
|
+
mapStyles: [
|
|
12
|
+
{
|
|
13
|
+
id: 'default',
|
|
14
|
+
label: 'Default',
|
|
15
|
+
url: '/styles/default.json',
|
|
16
|
+
thumbnail: '/images/default-thumb.png'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'satellite',
|
|
20
|
+
label: 'Satellite',
|
|
21
|
+
url: '/styles/satellite.json',
|
|
22
|
+
thumbnail: '/images/satellite-thumb.png'
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const interactiveMap = new InteractiveMap({
|
|
28
|
+
plugins: [mapStylesPlugin]
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Options
|
|
33
|
+
|
|
34
|
+
Options are passed to the factory function when creating the plugin.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### `mapStyles`
|
|
39
|
+
**Type:** `MapStyleConfig[]`
|
|
40
|
+
**Required**
|
|
41
|
+
|
|
42
|
+
Array of map style configurations. Each style appears as an option in the style switcher UI.
|
|
43
|
+
|
|
44
|
+
See [MapStyleConfig](../api/map-style-config.md) for full details.
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
createMapStylesPlugin({
|
|
48
|
+
mapStyles: [
|
|
49
|
+
{
|
|
50
|
+
id: 'default',
|
|
51
|
+
label: 'Default',
|
|
52
|
+
url: '/styles/default.json',
|
|
53
|
+
appColorScheme: 'light',
|
|
54
|
+
mapColorScheme: 'light',
|
|
55
|
+
backgroundColor: '#f5f5f5',
|
|
56
|
+
thumbnail: '/images/default-thumb.png'
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### `includeModes`
|
|
65
|
+
**Type:** `string[]`
|
|
66
|
+
|
|
67
|
+
Array of mode identifiers. When set, the plugin only renders when the app is in one of these modes.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### `excludeModes`
|
|
72
|
+
**Type:** `string[]`
|
|
73
|
+
|
|
74
|
+
Array of mode identifiers. When set, the plugin does not render when the app is in one of these modes.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Methods
|
|
79
|
+
|
|
80
|
+
This plugin does not expose any public methods.
|
|
81
|
+
|
|
82
|
+
## Events
|
|
83
|
+
|
|
84
|
+
This plugin does not emit any custom events. Style changes are handled internally and update the map automatically.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# PluginContext
|
|
2
|
+
|
|
3
|
+
Plugin components and callbacks receive the base [Context](../api/context.md) plus the plugin-specific properties documented below.
|
|
4
|
+
|
|
5
|
+
PluginContext is received by:
|
|
6
|
+
- [InitComponent](./plugin-manifest.md#initcomponent) - as props
|
|
7
|
+
- [API methods](./plugin-manifest.md#api) - as the first argument
|
|
8
|
+
- [Panel render components](./panel-definition.md#render) - as props
|
|
9
|
+
- [Control render components](./control-definition.md#render) - as props
|
|
10
|
+
- [Button callbacks](./button-definition.md) (`onClick`, `enableWhen`, `hiddenWhen`, `excludeWhen`, `pressedWhen`) - as an argument (`onClick` receives event first, context second)
|
|
11
|
+
|
|
12
|
+
## Base Context Properties
|
|
13
|
+
|
|
14
|
+
See [Context](../api/context.md) for the following properties available to all contexts:
|
|
15
|
+
|
|
16
|
+
- `appConfig` - Application configuration
|
|
17
|
+
- `appState` - Current application state
|
|
18
|
+
- `iconRegistry` - Icon registry
|
|
19
|
+
- `mapProvider` - Map provider instance
|
|
20
|
+
- `mapState` - Current map state
|
|
21
|
+
- `services` - Core services
|
|
22
|
+
|
|
23
|
+
## Plugin-Specific Properties
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
### `pluginConfig`
|
|
28
|
+
**Type:** `Object`
|
|
29
|
+
|
|
30
|
+
Plugin-specific configuration. Contains all properties from the [PluginDescriptor](./plugin-descriptor.md) except `id` and `load`.
|
|
31
|
+
|
|
32
|
+
When using the factory function pattern, any options passed to the factory become available here:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
// When registering:
|
|
36
|
+
createScaleBarPlugin({ units: 'imperial' })
|
|
37
|
+
|
|
38
|
+
// Within the plugin:
|
|
39
|
+
const { units } = context.pluginConfig
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
See [Creating a Plugin Descriptor](./plugin-descriptor.md#creating-a-plugin-descriptor) for the full pattern.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### `pluginState`
|
|
47
|
+
**Type:** `Object`
|
|
48
|
+
|
|
49
|
+
Plugin-specific state managed by the plugin's reducer, plus utilities for updating state.
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
{
|
|
53
|
+
// State values from your reducer's initialState
|
|
54
|
+
isActive: false,
|
|
55
|
+
|
|
56
|
+
// Dispatch function for updating plugin state
|
|
57
|
+
dispatch: ({ type, payload }) => { /* ... */ }
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
// Access state
|
|
63
|
+
const { isActive } = context.pluginState
|
|
64
|
+
|
|
65
|
+
// Update state
|
|
66
|
+
context.pluginState.dispatch({ type: 'setActive', payload: true })
|
|
67
|
+
```
|