@defra/interactive-map 0.0.17-alpha → 0.0.19-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/assets/css/docusaurus.css +58 -34
- 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/context.md +53 -7
- package/docs/api/map-style-config.md +41 -2
- package/docs/api/marker-config.md +53 -11
- package/docs/api/panel-definition.md +16 -0
- package/docs/api/symbol-config.md +160 -0
- package/docs/api/symbol-registry.md +115 -0
- package/docs/api.md +50 -23
- package/docs/assets/basic-map.jpg +0 -0
- package/docs/assets/button-first.jpg +0 -0
- package/docs/assets/maker-panel.jpg +0 -0
- package/docs/examples/add-marker-with-panel.mdx +59 -0
- package/docs/examples/basic-map.mdx +24 -0
- package/docs/examples/button-map.mdx +24 -0
- package/docs/examples/index.mdx +49 -0
- package/docs/index.mdx +1 -1
- package/docs/plugins/datasets.md +105 -9
- package/docs/plugins/interact.md +100 -44
- package/docs/plugins/search.md +15 -3
- package/docs/plugins.md +1 -1
- package/docusaurus.config.cjs +9 -1
- package/package.json +1 -1
- package/plugins/beta/datasets/dist/css/index.css +32 -14
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/esm/index.js +1 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/index.js +1 -1
- package/plugins/beta/datasets/src/DatasetsInit.jsx +9 -4
- package/plugins/beta/datasets/src/adapters/maplibre/layerBuilders.js +57 -11
- package/plugins/beta/datasets/src/adapters/maplibre/layerIds.js +14 -8
- package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +155 -53
- package/plugins/beta/datasets/src/adapters/maplibre/patternImages.js +27 -0
- package/plugins/beta/datasets/src/adapters/maplibre/symbolImages.js +31 -0
- package/plugins/beta/datasets/src/api/addDataset.js +1 -1
- package/plugins/beta/datasets/src/api/setData.js +4 -2
- package/plugins/beta/datasets/src/api/setStyle.js +2 -2
- package/plugins/beta/datasets/src/components/EmptyKey.jsx +7 -0
- package/plugins/beta/datasets/src/components/EmptyKey.test.jsx +21 -0
- package/plugins/beta/datasets/src/components/KeySvg.jsx +24 -0
- package/plugins/beta/datasets/src/components/KeySvgLine.jsx +19 -0
- package/plugins/beta/datasets/src/components/KeySvgPattern.jsx +15 -0
- package/plugins/beta/datasets/src/components/KeySvgRect.jsx +22 -0
- package/plugins/beta/datasets/src/components/KeySvgSymbol.jsx +16 -0
- package/plugins/beta/datasets/src/components/svgProperties.js +20 -0
- package/plugins/beta/datasets/src/datasets.js +13 -4
- package/plugins/beta/datasets/src/defaults.js +4 -2
- package/plugins/beta/datasets/src/index.js +2 -1
- package/plugins/beta/datasets/src/manifest.js +1 -1
- package/plugins/beta/datasets/src/panels/Key.jsx +11 -89
- package/plugins/beta/datasets/src/panels/Key.module.scss +24 -13
- package/plugins/beta/datasets/src/panels/Layers.module.scss +13 -7
- package/plugins/beta/datasets/src/reducer.js +6 -0
- package/plugins/beta/datasets/src/reducers/keyReducer.js +34 -0
- package/plugins/beta/datasets/src/utils/mergeSublayer.js +8 -0
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-es/src/DrawInit.jsx +3 -2
- package/plugins/beta/draw-ml/dist/css/index.css +3 -0
- 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-ml/dist/umd/index.js +1 -1
- package/plugins/beta/draw-ml/src/DrawInit.jsx +4 -3
- 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/beta/map-styles/src/MapStyles.jsx +5 -4
- package/plugins/beta/map-styles/src/MapStylesInit.jsx +5 -4
- package/plugins/beta/scale-bar/dist/css/index.css +1 -1
- package/plugins/beta/scale-bar/src/scaleBar.scss +1 -0
- 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/InteractInit.jsx +19 -8
- package/plugins/interact/src/InteractInit.test.js +26 -6
- package/plugins/interact/src/api/clear.js +1 -1
- package/plugins/interact/src/api/enable.test.js +7 -7
- package/plugins/interact/src/api/selectMarker.js +14 -0
- package/plugins/interact/src/api/selectMarker.test.js +25 -0
- package/plugins/interact/src/api/unselectMarker.js +14 -0
- package/plugins/interact/src/api/unselectMarker.test.js +14 -0
- package/plugins/interact/src/defaults.js +4 -6
- package/plugins/interact/src/events.js +27 -36
- package/plugins/interact/src/events.test.js +119 -90
- package/plugins/interact/src/hooks/useHighlightSync.js +3 -3
- package/plugins/interact/src/hooks/useHighlightSync.test.js +6 -6
- package/plugins/interact/src/hooks/useHoverCursor.js +10 -0
- package/plugins/interact/src/hooks/useHoverCursor.test.js +44 -0
- package/plugins/interact/src/hooks/useInteractionHandlers.js +111 -69
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +147 -32
- package/plugins/interact/src/manifest.js +10 -2
- package/plugins/interact/src/reducer.js +59 -5
- package/plugins/interact/src/reducer.test.js +100 -12
- package/plugins/interact/src/utils/buildStylesMap.js +17 -4
- package/plugins/interact/src/utils/buildStylesMap.test.js +16 -2
- package/plugins/interact/src/utils/featureQueries.js +11 -6
- package/plugins/interact/src/utils/featureQueries.test.js +8 -1
- package/plugins/interact/src/utils/interactionModes.js +12 -0
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/src/Search.jsx +3 -1
- package/plugins/search/src/events/fetchSuggestions.js +6 -4
- package/plugins/search/src/events/fetchSuggestions.test.js +26 -4
- package/plugins/search/src/events/formHandlers.js +3 -3
- package/plugins/search/src/events/formHandlers.test.js +1 -1
- package/plugins/search/src/events/suggestionHandlers.js +2 -2
- package/plugins/search/src/events/suggestionHandlers.test.js +1 -1
- package/plugins/search/src/utils/updateMap.js +3 -3
- package/plugins/search/src/utils/updateMap.test.js +3 -3
- 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/appEvents.js +7 -0
- package/providers/maplibre/src/appEvents.test.js +18 -4
- package/providers/maplibre/src/maplibreProvider.js +52 -0
- package/providers/maplibre/src/maplibreProvider.test.js +105 -1
- package/providers/maplibre/src/utils/highlightFeatures.js +36 -7
- package/providers/maplibre/src/utils/highlightFeatures.test.js +153 -96
- package/providers/maplibre/src/utils/hoverCursor.js +61 -0
- package/providers/maplibre/src/utils/hoverCursor.test.js +130 -0
- package/providers/maplibre/src/utils/patternImages.js +70 -0
- package/providers/maplibre/src/utils/patternImages.test.js +180 -0
- package/providers/maplibre/src/utils/queryFeatures.js +38 -16
- package/providers/maplibre/src/utils/queryFeatures.test.js +20 -3
- package/providers/maplibre/src/utils/rasteriseToImageData.js +30 -0
- package/providers/maplibre/src/utils/rasteriseToImageData.test.js +69 -0
- package/providers/maplibre/src/utils/symbolImages.js +147 -0
- package/providers/maplibre/src/utils/symbolImages.test.js +248 -0
- package/src/App/components/Markers/Markers.jsx +122 -27
- package/src/App/components/Markers/Markers.module.scss +0 -10
- package/src/App/components/Markers/Markers.test.jsx +246 -0
- package/src/App/components/Panel/Panel.jsx +6 -6
- package/src/App/components/Panel/Panel.test.jsx +37 -0
- package/src/App/components/Viewport/Viewport.jsx +5 -15
- package/src/App/components/Viewport/Viewport.module.scss +2 -0
- package/src/App/components/Viewport/Viewport.test.jsx +16 -33
- package/src/App/hooks/useInterfaceAPI.js +7 -7
- package/src/App/hooks/useInterfaceAPI.test.js +162 -0
- package/src/App/hooks/useLayoutMeasurements.js +64 -72
- package/src/App/hooks/useMarkersAPI.js +2 -5
- package/src/App/hooks/useMarkersAPI.test.js +4 -4
- package/src/App/layout/Layout.jsx +3 -3
- package/src/App/layout/Layout.test.jsx +4 -2
- package/src/App/layout/layout.module.scss +1 -8
- package/src/App/renderer/HtmlElementHost.jsx +10 -5
- package/src/App/renderer/mapPanels.js +2 -1
- package/src/App/store/ServiceProvider.jsx +7 -5
- package/src/App/store/appActionsMap.js +4 -4
- package/src/App/store/appActionsMap.test.js +10 -0
- package/src/App/store/mapActionsMap.js +4 -6
- package/src/App/store/mapActionsMap.test.js +3 -2
- package/src/App/store/mapReducer.js +2 -1
- package/src/InteractiveMap/InteractiveMap.js +59 -11
- package/src/InteractiveMap/InteractiveMap.test.js +126 -4
- package/src/InteractiveMap/domStateManager.js +18 -6
- package/src/InteractiveMap/domStateManager.test.js +21 -0
- package/src/InteractiveMap/historyManager.js +28 -16
- package/src/InteractiveMap/historyManager.test.js +17 -0
- package/src/config/appConfig.js +2 -7
- package/src/config/appConfig.test.js +4 -15
- package/src/config/defaults.js +2 -3
- package/src/config/events.js +20 -21
- package/src/config/mapTheme.js +56 -0
- package/src/config/patternConfig.js +16 -0
- package/src/config/symbolConfig.js +80 -0
- package/src/scss/settings/_colors.scss +0 -9
- package/src/services/closeApp.js +1 -10
- package/src/services/closeApp.test.js +3 -43
- package/src/services/patternRegistry.js +40 -0
- package/src/services/patternRegistry.test.js +48 -0
- package/src/services/symbolRegistry.js +113 -0
- package/src/services/symbolRegistry.test.js +262 -0
- package/src/types.js +99 -12
- package/src/utils/mapStateSync.js +48 -10
- package/src/utils/mapStateSync.test.js +29 -9
- package/src/utils/patternUtils.js +94 -0
- package/src/utils/patternUtils.test.js +160 -0
- package/src/utils/symbolUtils.js +85 -0
- package/src/utils/symbolUtils.test.js +156 -0
- package/docs/examples.mdx +0 -70
- package/plugins/beta/datasets/src/adapters/maplibre/patternRegistry.js +0 -48
- package/plugins/beta/datasets/src/styles/patterns.js +0 -157
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Symbol Registry
|
|
2
|
+
|
|
3
|
+
The symbol registry is a service that manages reusable named symbols for map markers. It is available to plugin authors via `services.symbolRegistry`.
|
|
4
|
+
|
|
5
|
+
> **Application code** that needs a one-off custom marker should pass [`symbolSvgContent`](./symbol-config.md#symbolsvgcontent) directly to `addMarker()` via `MarkerOptions` instead — no registration required.
|
|
6
|
+
|
|
7
|
+
## Built-in symbols
|
|
8
|
+
|
|
9
|
+
Two symbols are registered by default:
|
|
10
|
+
|
|
11
|
+
| ID | Anchor | Description |
|
|
12
|
+
|----|--------|-------------|
|
|
13
|
+
| `'pin'` | `[0.5, 1]` | Teardrop pin — tip aligns with the coordinate |
|
|
14
|
+
| `'circle'` | `[0.5, 0.5]` | Filled circle — centre aligns with the coordinate |
|
|
15
|
+
|
|
16
|
+
Both use the standard `{{token}}` placeholders and respect the resolution order described in [Symbol Config](./symbol-config.md#how-values-are-resolved).
|
|
17
|
+
|
|
18
|
+
## Methods
|
|
19
|
+
|
|
20
|
+
Available on `services.symbolRegistry` inside a plugin.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### `setDefaults(defaults)`
|
|
25
|
+
|
|
26
|
+
Set constructor-level defaults. Called automatically during app initialisation with the `symbolDefaults` constructor config. Plugin authors do not normally need to call this.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
### `getDefaults()`
|
|
31
|
+
|
|
32
|
+
Returns the merged app-wide defaults (hardcoded `symbolDefaults.js` + constructor overrides).
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
const defaults = services.symbolRegistry.getDefaults()
|
|
36
|
+
// { symbol: 'pin', backgroundColor: '#ca3535', selectedColor: { outdoor: '#0b0c0c', dark: '#ffffff' }, ... }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### `register(symbolDef)`
|
|
42
|
+
|
|
43
|
+
Register a custom symbol. Once registered it can be referenced by ID via `MarkerOptions.symbol` or a dataset `style.symbol`.
|
|
44
|
+
|
|
45
|
+
| Property | Type | Required | Description |
|
|
46
|
+
|----------|------|----------|-------------|
|
|
47
|
+
| `id` | `string` | Yes | Unique symbol identifier |
|
|
48
|
+
| `svg` | `string` | Yes | Inner SVG path content with `{{token}}` placeholders — see [SVG structure](./symbol-config.md#svg-structure) |
|
|
49
|
+
| `viewBox` | `string` | Yes | SVG viewBox, e.g. `'0 0 38 38'` |
|
|
50
|
+
| `anchor` | `[number, number]` | Yes | Normalised [x, y] anchor point |
|
|
51
|
+
| *(token)* | `string \| Record<string, string>` | No | Default token value for this symbol, e.g. `backgroundColor: '#1d70b8'`. `selectedColor` and `selectedWidth` are ignored here — set them via constructor `symbolDefaults`. |
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
services.symbolRegistry.register({
|
|
55
|
+
id: 'star',
|
|
56
|
+
viewBox: '0 0 38 38',
|
|
57
|
+
anchor: [0.5, 0.5],
|
|
58
|
+
backgroundColor: '#1d70b8',
|
|
59
|
+
svg: `
|
|
60
|
+
<path d="..." fill="none" stroke="{{selectedColor}}" stroke-width="{{selectedWidth}}"/>
|
|
61
|
+
<path d="..." fill="{{backgroundColor}}" stroke="{{haloColor}}" stroke-width="{{haloWidth}}"/>
|
|
62
|
+
<path d="..." fill="{{foregroundColor}}"/>
|
|
63
|
+
`
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
See [Symbol Config](./symbol-config.md) for the full list of token properties and the SVG structure convention.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### `get(id)`
|
|
72
|
+
|
|
73
|
+
Returns the symbol definition for the given ID, or `undefined` if not registered.
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
const symbolDef = services.symbolRegistry.get('pin')
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
### `list()`
|
|
82
|
+
|
|
83
|
+
Returns an array of all registered symbol definitions.
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
const symbols = services.symbolRegistry.list()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### `resolve(symbolDef, styleColors, mapStyleId)`
|
|
92
|
+
|
|
93
|
+
Resolves a symbol's SVG for **normal (unselected) rendering**. The `{{selectedColor}}` token is always replaced with an empty string — the selection ring is structurally present but invisible.
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
const svg = services.symbolRegistry.resolve(
|
|
97
|
+
services.symbolRegistry.get('pin'),
|
|
98
|
+
{ backgroundColor: '#d4351c' },
|
|
99
|
+
'outdoor'
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### `resolveSelected(symbolDef, styleColors, mapStyleId)`
|
|
106
|
+
|
|
107
|
+
Resolves a symbol's SVG for **selected rendering**. The `{{selectedColor}}` token uses the cascade value. Use this when rendering the highlight layer for an interact or datasets selection.
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
const svg = services.symbolRegistry.resolveSelected(
|
|
111
|
+
services.symbolRegistry.get('pin'),
|
|
112
|
+
{ backgroundColor: '#d4351c' },
|
|
113
|
+
'outdoor'
|
|
114
|
+
)
|
|
115
|
+
```
|
package/docs/api.md
CHANGED
|
@@ -161,7 +161,7 @@ The button is only displayed when the map is `inline`.
|
|
|
161
161
|
|
|
162
162
|
### `enableZoomControls`
|
|
163
163
|
**Type:** `boolean`
|
|
164
|
-
**Default:** `
|
|
164
|
+
**Default:** `true`
|
|
165
165
|
|
|
166
166
|
Whether zoom control buttons are displayed.
|
|
167
167
|
Zoom controls are not diplayed when the interface type is `touch`.
|
|
@@ -264,18 +264,6 @@ URL query parameter key used to persist map visibility state.
|
|
|
264
264
|
|
|
265
265
|
---
|
|
266
266
|
|
|
267
|
-
### `markerColor`
|
|
268
|
-
**Type:** `string | Object<string, string>`
|
|
269
|
-
**Default:** `'#ff0000'`
|
|
270
|
-
|
|
271
|
-
Default colour for map markers. Can be overridden per marker when calling `addMarker()`.
|
|
272
|
-
|
|
273
|
-
May be provided as:
|
|
274
|
-
- A single colour value applied to all map styles
|
|
275
|
-
- An object keyed by map style ID, allowing different colours per style
|
|
276
|
-
|
|
277
|
-
---
|
|
278
|
-
|
|
279
267
|
### `markers`
|
|
280
268
|
**Type:** `MarkerConfig[]`
|
|
281
269
|
|
|
@@ -285,14 +273,29 @@ See [MarkerConfig](./api/marker-config.md) for full details.
|
|
|
285
273
|
|
|
286
274
|
---
|
|
287
275
|
|
|
288
|
-
### `
|
|
289
|
-
**Type:** `
|
|
290
|
-
**Default:** `'pin'`
|
|
276
|
+
### `symbolDefaults`
|
|
277
|
+
**Type:** `Partial<SymbolDefaults>`
|
|
291
278
|
|
|
292
|
-
|
|
279
|
+
App-wide defaults for symbol and marker appearance. These values apply across all markers and datasets unless a more specific value is set at the symbol or per-marker level. Any property omitted here falls back to the built-in default:
|
|
293
280
|
|
|
294
|
-
|
|
295
|
-
|
|
281
|
+
| Property | Built-in default |
|
|
282
|
+
|---|---|
|
|
283
|
+
| `symbol` | `'pin'` |
|
|
284
|
+
| `backgroundColor` | `'#ca3535'` |
|
|
285
|
+
| `foregroundColor` | `'#ffffff'` |
|
|
286
|
+
| `haloWidth` | `'1'` |
|
|
287
|
+
| `selectedWidth` | `'6'` |
|
|
288
|
+
|
|
289
|
+
```js
|
|
290
|
+
new InteractiveMap('map', {
|
|
291
|
+
symbolDefaults: {
|
|
292
|
+
symbol: 'circle',
|
|
293
|
+
backgroundColor: { outdoor: '#1d70b8', dark: '#4c9ed9' }
|
|
294
|
+
}
|
|
295
|
+
})
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
See [Symbol Config](./api/symbol-config.md) for the full property list.
|
|
296
299
|
|
|
297
300
|
---
|
|
298
301
|
|
|
@@ -488,7 +491,7 @@ Add a marker to the map.
|
|
|
488
491
|
| `options` | [`MarkerOptions`](./api/marker-config.md#markeroptions) | Optional marker appearance options |
|
|
489
492
|
|
|
490
493
|
```js
|
|
491
|
-
interactiveMap.addMarker('home', [-0.1276, 51.5074], {
|
|
494
|
+
interactiveMap.addMarker('home', [-0.1276, 51.5074], { backgroundColor: '#1d70b8' })
|
|
492
495
|
```
|
|
493
496
|
|
|
494
497
|
---
|
|
@@ -547,7 +550,7 @@ interactiveMap.addButton('my-menu', {
|
|
|
547
550
|
|
|
548
551
|
### `addPanel(id, config)`
|
|
549
552
|
|
|
550
|
-
Add a panel to the UI at runtime.
|
|
553
|
+
Add a panel to the UI at runtime. Focus is moved to the panel by default — set `focus: false` in the config to suppress this when adding panels on page load.
|
|
551
554
|
|
|
552
555
|
| Parameter | Type | Description |
|
|
553
556
|
|-----------|------|-------------|
|
|
@@ -582,16 +585,20 @@ interactiveMap.removePanel('info-panel')
|
|
|
582
585
|
|
|
583
586
|
---
|
|
584
587
|
|
|
585
|
-
### `showPanel(id)`
|
|
588
|
+
### `showPanel(id, options?)`
|
|
586
589
|
|
|
587
|
-
Show a panel.
|
|
590
|
+
Show a panel. Focus is moved to the panel by default — set `focus: false` to suppress this, useful when showing a panel and you want focus to remain on the button.
|
|
588
591
|
|
|
589
592
|
| Parameter | Type | Description |
|
|
590
593
|
|-----------|------|-------------|
|
|
591
594
|
| `id` | `string` | Panel identifier to show |
|
|
595
|
+
| `options.focus` | `boolean` | Whether to move focus to the panel. Default: `true` |
|
|
592
596
|
|
|
593
597
|
```js
|
|
594
598
|
interactiveMap.showPanel('info-panel')
|
|
599
|
+
|
|
600
|
+
// Keep focus on the triggering button
|
|
601
|
+
interactiveMap.showPanel('info-panel', { focus: false })
|
|
595
602
|
```
|
|
596
603
|
|
|
597
604
|
---
|
|
@@ -711,6 +718,26 @@ interactiveMap.setView({ center: [-0.1276, 51.5074], zoom: 12 })
|
|
|
711
718
|
|
|
712
719
|
---
|
|
713
720
|
|
|
721
|
+
### `open()`
|
|
722
|
+
|
|
723
|
+
Programmatically open the map. Equivalent to the user clicking the open button. If the map has been hidden (e.g. in hybrid mode), it will be shown; otherwise the app will be loaded for the first time.
|
|
724
|
+
|
|
725
|
+
```js
|
|
726
|
+
interactiveMap.open()
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
### `close()`
|
|
732
|
+
|
|
733
|
+
Programmatically close the map. Triggers the same logic as the exit button. If `preserveStateOnClose` is `true`, the map is hidden but not destroyed; otherwise the app is removed entirely.
|
|
734
|
+
|
|
735
|
+
```js
|
|
736
|
+
interactiveMap.close()
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
714
741
|
## Events
|
|
715
742
|
|
|
716
743
|
Subscribe to events using `interactiveMap.on()` and unsubscribe with `interactiveMap.off()`.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import DemoMapMarkerPanel from '../../demo/DemoMapMarkerPanel.js'
|
|
2
|
+
|
|
3
|
+
# Add a marker with a panel
|
|
4
|
+
|
|
5
|
+
Add markers to the map and allow users to select them. Selecting a marker fires the `interact:selectionchange` event, which can be used to show a panel with relevant information.
|
|
6
|
+
|
|
7
|
+
<DemoMapMarkerPanel />
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import InteractiveMap from '@defra/interactive-map'
|
|
11
|
+
import maplibreProvider from '@defra/interactive-map/providers/maplibre'
|
|
12
|
+
import createInteractPlugin from '@defra/interactive-map/plugins/interact'
|
|
13
|
+
|
|
14
|
+
const interactPlugin = createInteractPlugin({
|
|
15
|
+
deselectOnClickOutside: true
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const map = new InteractiveMap('my-map', {
|
|
19
|
+
behaviour: 'inline',
|
|
20
|
+
mapProvider: maplibreProvider(),
|
|
21
|
+
mapStyle: {
|
|
22
|
+
url: 'https://your-tile-url/style.json',
|
|
23
|
+
attribution: 'Your tile attribution'
|
|
24
|
+
},
|
|
25
|
+
center: [-2.96, 54.43],
|
|
26
|
+
zoom: 15,
|
|
27
|
+
containerHeight: '500px',
|
|
28
|
+
plugins: [interactPlugin]
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
map.on('map:ready', () => {
|
|
32
|
+
map.addMarker('my-marker', [-2.96, 54.43])
|
|
33
|
+
interactPlugin.enable()
|
|
34
|
+
interactPlugin.selectMarker('my-marker')
|
|
35
|
+
|
|
36
|
+
map.addPanel('marker-info', {
|
|
37
|
+
focus: false,
|
|
38
|
+
label: 'Marker',
|
|
39
|
+
html: '<p class="govuk-body">Information about the selected marker</p>',
|
|
40
|
+
mobile: { slot: 'drawer', dismissible: true },
|
|
41
|
+
tablet: { slot: 'left-top', dismissible: true, width: '280px' },
|
|
42
|
+
desktop: { slot: 'left-top', dismissible: true, width: '280px' }
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
map.on('interact:selectionchange', ({ selectedMarkers }) => {
|
|
47
|
+
if (selectedMarkers.length > 0) {
|
|
48
|
+
map.showPanel('marker-info')
|
|
49
|
+
} else {
|
|
50
|
+
map.hidePanel('marker-info')
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
map.on('app:panelclosed', ({ panelId }) => {
|
|
55
|
+
if (panelId === 'marker-info') {
|
|
56
|
+
interactPlugin.unselectMarker('my-marker')
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import DemoMapBasic from '../../demo/DemoMapBasic.js'
|
|
2
|
+
|
|
3
|
+
# Basic map
|
|
4
|
+
|
|
5
|
+
Embed an interactive map directly on the page, allowing users to explore and interact with the map without leaving the current context.
|
|
6
|
+
|
|
7
|
+
<DemoMapBasic />
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import InteractiveMap from '@defra/interactive-map'
|
|
11
|
+
import maplibreProvider from '@defra/interactive-map/providers/maplibre'
|
|
12
|
+
|
|
13
|
+
new InteractiveMap('my-map', {
|
|
14
|
+
behaviour: 'inline',
|
|
15
|
+
mapProvider: maplibreProvider(),
|
|
16
|
+
mapStyle: {
|
|
17
|
+
url: 'https://your-tile-url/style.json',
|
|
18
|
+
attribution: 'Your tile attribution'
|
|
19
|
+
},
|
|
20
|
+
center: [-1.6, 53.1],
|
|
21
|
+
zoom: 6,
|
|
22
|
+
containerHeight: '500px'
|
|
23
|
+
})
|
|
24
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import DemoMapButton from '../../demo/DemoMapButton.js'
|
|
2
|
+
|
|
3
|
+
# Button-triggered map
|
|
4
|
+
|
|
5
|
+
Trigger the map to show on button press, allowing users to access the map when needed without it taking up space on the page by default.
|
|
6
|
+
|
|
7
|
+
<DemoMapButton />
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import InteractiveMap from '@defra/interactive-map'
|
|
11
|
+
import maplibreProvider from '@defra/interactive-map/providers/maplibre'
|
|
12
|
+
|
|
13
|
+
new InteractiveMap('my-map', {
|
|
14
|
+
behaviour: 'buttonFirst',
|
|
15
|
+
mapProvider: maplibreProvider(),
|
|
16
|
+
mapStyle: {
|
|
17
|
+
url: 'https://your-tile-url/style.json',
|
|
18
|
+
attribution: 'Your tile attribution'
|
|
19
|
+
},
|
|
20
|
+
center: [-1.6, 53.1],
|
|
21
|
+
zoom: 6,
|
|
22
|
+
hasExitButton: true
|
|
23
|
+
})
|
|
24
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import useBaseUrl from '@docusaurus/useBaseUrl'
|
|
2
|
+
import basicMapImg from '../assets/basic-map.jpg'
|
|
3
|
+
import buttonFirstImg from '../assets/button-first.jpg'
|
|
4
|
+
import makerPanelImg from '../assets/maker-panel.jpg'
|
|
5
|
+
|
|
6
|
+
export function ExampleCards() {
|
|
7
|
+
const basicHref = useBaseUrl('/examples/basic-map')
|
|
8
|
+
const buttonHref = useBaseUrl('/examples/button-map')
|
|
9
|
+
const interactHref = useBaseUrl('/examples/add-marker-with-panel')
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className='govuk-grid-row'>
|
|
13
|
+
<div className='govuk-grid-column-one-half'>
|
|
14
|
+
<div className='app-example-card'>
|
|
15
|
+
<img src={basicMapImg} alt='' />
|
|
16
|
+
<div className='app-example-card__body'>
|
|
17
|
+
<h2 className='govuk-heading-m'>
|
|
18
|
+
<a href={basicHref}>Basic map</a>
|
|
19
|
+
</h2>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
<div className='govuk-grid-column-one-half'>
|
|
24
|
+
<div className='app-example-card'>
|
|
25
|
+
<img src={buttonFirstImg} alt='' />
|
|
26
|
+
<div className='app-example-card__body'>
|
|
27
|
+
<h2 className='govuk-heading-m'>
|
|
28
|
+
<a href={buttonHref}>Button-triggered map</a>
|
|
29
|
+
</h2>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<div className='govuk-grid-column-one-half'>
|
|
34
|
+
<div className='app-example-card'>
|
|
35
|
+
<img src={makerPanelImg} alt='' />
|
|
36
|
+
<div className='app-example-card__body' style={{ 'border-top': '1px solid #cecece'}}>
|
|
37
|
+
<h2 className='govuk-heading-m'>
|
|
38
|
+
<a href={interactHref}>Add a marker with a panel</a>
|
|
39
|
+
</h2>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Examples
|
|
48
|
+
|
|
49
|
+
<ExampleCards />
|
package/docs/index.mdx
CHANGED
|
@@ -26,7 +26,7 @@ import Link from '@docusaurus/Link';
|
|
|
26
26
|
<h3><Link to="/getting-started" className="govuk-link">Getting Started</Link></h3>
|
|
27
27
|
<p>How to install and configure the component. Covers setup, initialisation options, and integration with common build tools.</p>
|
|
28
28
|
<h3><Link to="/examples" className="govuk-link">Examples</Link></h3>
|
|
29
|
-
<p>Live interactive demos showing the component in action, including
|
|
29
|
+
<p>Live interactive demos showing the component in action, including basic maps, button-triggered maps, and various configuration options.</p>
|
|
30
30
|
<h3><Link to="/api" className="govuk-link">API Reference</Link></h3>
|
|
31
31
|
<p>Full reference for all configuration options, events, methods, and plugin interfaces exposed by the component.</p>
|
|
32
32
|
<h3><Link to="/plugins" className="govuk-link">Plugins</Link></h3>
|
package/docs/plugins/datasets.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Datasets Plugin
|
|
2
2
|
|
|
3
|
-
The datasets plugin renders GeoJSON and vector tile datasets on the map, with support for sublayer style rules, layer visibility toggling, a key panel, and runtime style and data updates.
|
|
3
|
+
The datasets plugin renders GeoJSON and vector tile datasets on the map, with support for polygon, line, and symbol (point) layer types, sublayer style rules, layer visibility toggling, a key panel, and runtime style and data updates.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -263,6 +263,15 @@ Overrides the shape used to render the key symbol for this dataset. Defaults to
|
|
|
263
263
|
|
|
264
264
|
Visual style for the dataset. All style properties must be nested within this object.
|
|
265
265
|
|
|
266
|
+
**Common properties:**
|
|
267
|
+
|
|
268
|
+
| Property | Type | Description |
|
|
269
|
+
|----------|------|-------------|
|
|
270
|
+
| `opacity` | `number` | Layer opacity from `0` to `1` |
|
|
271
|
+
| `symbolDescription` | `string \| Record<string, string>` | Accessible description of the symbol shown in the key |
|
|
272
|
+
|
|
273
|
+
**Polygon/line properties:**
|
|
274
|
+
|
|
266
275
|
| Property | Type | Description |
|
|
267
276
|
|----------|------|-------------|
|
|
268
277
|
| `stroke` | `string \| Record<string, string>` | Stroke (outline) colour. Accepts a plain colour string or a map-style-keyed object e.g. `{ outdoor: '#ff0000', dark: '#ffffff' }` |
|
|
@@ -273,17 +282,56 @@ Visual style for the dataset. All style properties must be nested within this ob
|
|
|
273
282
|
| `fillPatternSvgContent` | `string` | Raw SVG content for a custom fill pattern |
|
|
274
283
|
| `fillPatternForegroundColor` | `string \| Record<string, string>` | Foreground colour for the fill pattern |
|
|
275
284
|
| `fillPatternBackgroundColor` | `string \| Record<string, string>` | Background colour for the fill pattern |
|
|
276
|
-
| `opacity` | `number` | Layer opacity from `0` to `1` |
|
|
277
|
-
| `symbolDescription` | `string \| Record<string, string>` | Accessible description of the symbol shown in the key |
|
|
278
285
|
| `keySymbolShape` | `'polygon' \| 'line'` | Shape used for the key symbol |
|
|
279
286
|
|
|
287
|
+
**Symbol (point) properties:**
|
|
288
|
+
|
|
289
|
+
Setting `symbol` or `symbolSvgContent` renders the dataset as a point layer instead of a polygon/line layer.
|
|
290
|
+
|
|
291
|
+
| Property | Type | Description |
|
|
292
|
+
|----------|------|-------------|
|
|
293
|
+
| `symbol` | `string` | Registered symbol ID e.g. `'pin'`, `'circle'`, `'square'` |
|
|
294
|
+
| `symbolSvgContent` | `string` | Inline SVG content for a fully custom symbol (no `<svg>` wrapper). Takes precedence over `symbol` |
|
|
295
|
+
| `symbolViewBox` | `string` | SVG viewBox for the symbol e.g. `'0 0 38 38'`. Defaults to the registered symbol's viewBox |
|
|
296
|
+
| `symbolAnchor` | `[number, number]` | Anchor point as a normalised `[x, y]` pair. Defaults to the registered symbol's anchor |
|
|
297
|
+
| `symbolBackgroundColor` | `string \| Record<string, string>` | Background fill colour of the symbol |
|
|
298
|
+
| `symbolForegroundColor` | `string \| Record<string, string>` | Foreground fill colour of the symbol (e.g. the inner dot) |
|
|
299
|
+
| `symbolHaloWidth` | `string` | Stroke width of the halo in SVG units |
|
|
300
|
+
| `symbolGraphic` | `string` | SVG `d` attribute for the foreground graphic path. Use named values (`'dot'`, `'cross'`, `'diamond'`, `'triangle'`, `'square'`) or supply your own path data |
|
|
301
|
+
|
|
302
|
+
Symbol colour properties use the `symbol` prefix to distinguish them from polygon/line properties in the same style object. They follow the same resolution order and support style-keyed colour objects in the same way as markers — see [Symbol Config](../api/symbol-config.md) for details.
|
|
303
|
+
|
|
304
|
+
`haloColor` and `selectedColor` are not settable here — they are basemap-level properties set on [`MapStyleConfig`](../api/map-style-config.md).
|
|
305
|
+
|
|
280
306
|
```js
|
|
307
|
+
// Polygon/line dataset
|
|
281
308
|
style: {
|
|
282
309
|
stroke: { outdoor: '#d4351c', dark: '#ffffff' },
|
|
283
310
|
strokeWidth: 2,
|
|
284
311
|
fill: 'rgba(212,53,28,0.1)',
|
|
285
312
|
symbolDescription: { outdoor: 'Red outline' }
|
|
286
313
|
}
|
|
314
|
+
|
|
315
|
+
// Point dataset — registered symbol with colour overrides
|
|
316
|
+
style: {
|
|
317
|
+
symbol: 'pin',
|
|
318
|
+
symbolBackgroundColor: '#1d70b8',
|
|
319
|
+
symbolForegroundColor: '#ffffff'
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Point dataset — style-keyed colours for multi-basemap support
|
|
323
|
+
style: {
|
|
324
|
+
symbol: 'pin',
|
|
325
|
+
symbolBackgroundColor: { outdoor: '#1d70b8', dark: '#5694ca' }
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Point dataset — custom inline SVG
|
|
329
|
+
style: {
|
|
330
|
+
symbolSvgContent: '<circle cx="19" cy="19" r="12" fill="{{backgroundColor}}"/>',
|
|
331
|
+
symbolViewBox: '0 0 38 38',
|
|
332
|
+
symbolAnchor: [0.5, 0.5],
|
|
333
|
+
symbolBackgroundColor: '#1d70b8'
|
|
334
|
+
}
|
|
287
335
|
```
|
|
288
336
|
|
|
289
337
|
---
|
|
@@ -292,9 +340,9 @@ style: {
|
|
|
292
340
|
|
|
293
341
|
**Type:** `Sublayer[]`
|
|
294
342
|
|
|
295
|
-
Array of sublayer rules that partition the dataset into visually distinct groups based on feature filters. Each sublayer is rendered as a separate
|
|
343
|
+
Array of sublayer rules that partition the dataset into visually distinct groups based on feature filters. Each sublayer is rendered as a separate map layer.
|
|
296
344
|
|
|
297
|
-
Sublayers inherit the parent dataset's style and only override what they specify.
|
|
345
|
+
Sublayers inherit the parent dataset's style and only override what they specify in their own `style` object. For polygon/line datasets, fill precedence is (highest to lowest): sublayer `fillPattern` → sublayer `fill` → parent `fillPattern` → parent `fill`. For symbol datasets, each symbol property is inherited individually from the parent unless the sublayer sets it explicitly.
|
|
298
346
|
|
|
299
347
|
#### `Sublayer` properties
|
|
300
348
|
|
|
@@ -303,10 +351,12 @@ Sublayers inherit the parent dataset's style and only override what they specify
|
|
|
303
351
|
| `id` | `string` | **Required.** Unique identifier within the dataset |
|
|
304
352
|
| `label` | `string` | Human-readable name shown in the Layers and Key panels |
|
|
305
353
|
| `filter` | `FilterExpression` | MapLibre filter expression to match features for this sublayer |
|
|
306
|
-
| `style` | `Object` | Style overrides
|
|
354
|
+
| `style` | `Object` | Style overrides. Accepts the same properties as the dataset `style` object |
|
|
307
355
|
| `showInKey` | `boolean` | Shows this sublayer in the Key panel. Inherits from dataset if not set |
|
|
308
356
|
| `toggleVisibility` | `boolean` | Shows this sublayer in the Layers panel. **Default:** `false` |
|
|
309
357
|
|
|
358
|
+
**Polygon/line example:**
|
|
359
|
+
|
|
310
360
|
```js
|
|
311
361
|
sublayers: [
|
|
312
362
|
{
|
|
@@ -334,6 +384,44 @@ sublayers: [
|
|
|
334
384
|
]
|
|
335
385
|
```
|
|
336
386
|
|
|
387
|
+
**Symbol (point) example — scheduled monuments by type:**
|
|
388
|
+
|
|
389
|
+
When the parent dataset has `symbol` set, each sublayer can override individual symbol properties to represent different categories. Properties not set on the sublayer are inherited from the parent.
|
|
390
|
+
|
|
391
|
+
```js
|
|
392
|
+
{
|
|
393
|
+
id: 'scheduled-monuments',
|
|
394
|
+
geojson: scheduledMonumentsData,
|
|
395
|
+
style: { symbol: 'square' },
|
|
396
|
+
sublayers: [
|
|
397
|
+
{
|
|
398
|
+
id: 'prehistoric',
|
|
399
|
+
label: 'Prehistoric sites',
|
|
400
|
+
filter: ['==', ['get', 'type'], 'prehistoric'],
|
|
401
|
+
showInKey: true,
|
|
402
|
+
toggleVisibility: true,
|
|
403
|
+
style: { symbolBackgroundColor: '#0f7a52' }
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
id: 'roman',
|
|
407
|
+
label: 'Roman sites',
|
|
408
|
+
filter: ['==', ['get', 'type'], 'roman'],
|
|
409
|
+
showInKey: true,
|
|
410
|
+
toggleVisibility: true,
|
|
411
|
+
style: { symbolBackgroundColor: '#54319f' }
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: 'medieval',
|
|
415
|
+
label: 'Medieval sites',
|
|
416
|
+
filter: ['==', ['get', 'type'], 'medieval'],
|
|
417
|
+
showInKey: true,
|
|
418
|
+
toggleVisibility: true,
|
|
419
|
+
style: { symbolBackgroundColor: '#ca357c' }
|
|
420
|
+
}
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
337
425
|
---
|
|
338
426
|
|
|
339
427
|
## Methods
|
|
@@ -436,24 +524,32 @@ datasetsPlugin.setFeatureVisibility(true, [123, 456], {
|
|
|
436
524
|
|
|
437
525
|
Update the visual style of a dataset or sublayer at runtime. When targeting a sublayer, only the properties specified are overridden — the sublayer inherits all other styles from the parent dataset.
|
|
438
526
|
|
|
527
|
+
For symbol datasets, pass `symbol` as the style property to change the symbol config.
|
|
528
|
+
|
|
439
529
|
| Argument | Type | Description |
|
|
440
530
|
|----------|------|-------------|
|
|
441
|
-
| `style` | `Object` | Style properties to apply. Accepts the same properties as `dataset.style` |
|
|
531
|
+
| `style` | `Object` | Style properties to apply. Accepts the same properties as `dataset.style`, plus `symbol` |
|
|
442
532
|
| `scope.datasetId` | `string` | ID of the dataset |
|
|
443
533
|
| `scope.sublayerId` | `string` | Optional. When provided, targets a single sublayer |
|
|
444
534
|
|
|
445
535
|
```js
|
|
446
|
-
//
|
|
536
|
+
// Polygon/line dataset
|
|
447
537
|
datasetsPlugin.setStyle(
|
|
448
538
|
{ stroke: '#0000ff', strokeWidth: 3 },
|
|
449
539
|
{ datasetId: 'my-parcels' }
|
|
450
540
|
)
|
|
451
541
|
|
|
452
|
-
// Sublayer
|
|
542
|
+
// Sublayer — polygon
|
|
453
543
|
datasetsPlugin.setStyle(
|
|
454
544
|
{ stroke: '#00703c', fillPattern: 'diagonal-cross-hatch', fillPatternForegroundColor: '#00703c' },
|
|
455
545
|
{ datasetId: 'my-parcels', sublayerId: 'active' }
|
|
456
546
|
)
|
|
547
|
+
|
|
548
|
+
// Sublayer — symbol colour override
|
|
549
|
+
datasetsPlugin.setStyle(
|
|
550
|
+
{ symbolBackgroundColor: '#912b88' },
|
|
551
|
+
{ datasetId: 'flood-warnings', sublayerId: 'severe' }
|
|
552
|
+
)
|
|
457
553
|
```
|
|
458
554
|
|
|
459
555
|
---
|