@defra/interactive-map 0.0.18-alpha → 0.0.20-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.
Files changed (91) hide show
  1. package/README.md +1 -1
  2. package/dist/css/index.css +1 -1
  3. package/dist/esm/im-core.js +1 -1
  4. package/dist/esm/im-shell.js +1 -1
  5. package/dist/umd/im-core.js +1 -1
  6. package/dist/umd/index.js +1 -1
  7. package/docs/api/button-definition.md +22 -5
  8. package/docs/api/map-style-config.md +2 -11
  9. package/docs/api/marker-config.md +19 -5
  10. package/docs/api/panel-definition.md +16 -0
  11. package/docs/api.md +101 -48
  12. package/docs/architecture.md +0 -2
  13. package/docs/assets/css/docusaurus.css +205 -0
  14. package/docs/assets/images/basic-map.jpg +0 -0
  15. package/docs/assets/images/button-first.jpg +0 -0
  16. package/{assets → docs/assets}/images/hero.png +0 -0
  17. package/docs/assets/images/marker-panel.jpg +0 -0
  18. package/docs/examples/add-marker-with-panel.mdx +123 -0
  19. package/docs/examples/basic-map.mdx +53 -0
  20. package/docs/examples/button-map.mdx +53 -0
  21. package/docs/examples/index.mdx +49 -0
  22. package/docs/getting-started.md +80 -53
  23. package/docs/index.mdx +1 -1
  24. package/docs/plugins/interact.md +32 -1
  25. package/docs/plugins.md +1 -1
  26. package/docusaurus.config.cjs +14 -5
  27. package/package.json +3 -3
  28. package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
  29. package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +1 -1
  30. package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
  31. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  32. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  33. package/plugins/beta/scale-bar/dist/css/index.css +1 -1
  34. package/plugins/beta/scale-bar/src/scaleBar.scss +1 -0
  35. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  36. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  37. package/plugins/interact/dist/umd/index.js +1 -1
  38. package/plugins/interact/src/InteractInit.jsx +5 -3
  39. package/plugins/interact/src/api/clear.js +1 -1
  40. package/plugins/interact/src/api/selectMarker.js +14 -0
  41. package/plugins/interact/src/api/selectMarker.test.js +25 -0
  42. package/plugins/interact/src/api/unselectMarker.js +14 -0
  43. package/plugins/interact/src/api/unselectMarker.test.js +14 -0
  44. package/plugins/interact/src/events.js +18 -30
  45. package/plugins/interact/src/events.test.js +113 -108
  46. package/plugins/interact/src/manifest.js +10 -2
  47. package/plugins/interact/src/reducer.js +36 -1
  48. package/plugins/interact/src/reducer.test.js +40 -1
  49. package/plugins/interact/src/utils/interactionModes.js +12 -0
  50. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  51. package/providers/maplibre/dist/umd/im-maplibre-framework.js +1 -1
  52. package/providers/maplibre/dist/umd/im-maplibre-framework.js.LICENSE.txt +1 -1
  53. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  54. package/providers/maplibre/src/maplibreProvider.js +3 -2
  55. package/providers/maplibre/src/maplibreProvider.test.js +22 -0
  56. package/src/App/components/Panel/Panel.jsx +6 -6
  57. package/src/App/components/Panel/Panel.test.jsx +37 -0
  58. package/src/App/components/Viewport/Viewport.jsx +5 -15
  59. package/src/App/components/Viewport/Viewport.module.scss +2 -0
  60. package/src/App/components/Viewport/Viewport.test.jsx +16 -33
  61. package/src/App/hooks/useInterfaceAPI.js +7 -7
  62. package/src/App/hooks/useInterfaceAPI.test.js +15 -9
  63. package/src/App/hooks/useLayoutMeasurements.js +64 -72
  64. package/src/App/layout/Layout.jsx +1 -1
  65. package/src/App/layout/layout.module.scss +1 -8
  66. package/src/App/renderer/HtmlElementHost.jsx +10 -5
  67. package/src/App/renderer/mapPanels.js +2 -1
  68. package/src/App/store/appActionsMap.js +4 -4
  69. package/src/App/store/appActionsMap.test.js +10 -0
  70. package/src/InteractiveMap/InteractiveMap.js +61 -13
  71. package/src/InteractiveMap/InteractiveMap.test.js +130 -8
  72. package/src/InteractiveMap/domStateManager.js +18 -6
  73. package/src/InteractiveMap/domStateManager.test.js +21 -0
  74. package/src/InteractiveMap/historyManager.js +28 -16
  75. package/src/InteractiveMap/historyManager.test.js +17 -0
  76. package/src/config/appConfig.js +2 -1
  77. package/src/config/appConfig.test.js +3 -13
  78. package/src/config/defaults.js +2 -1
  79. package/src/config/events.js +20 -21
  80. package/src/services/closeApp.js +1 -10
  81. package/src/services/closeApp.test.js +3 -43
  82. package/src/services/eventBus.js +61 -0
  83. package/src/services/eventBus.test.js +70 -0
  84. package/src/types.js +6 -1
  85. package/src/utils/mapStateSync.js +48 -10
  86. package/src/utils/mapStateSync.test.js +29 -9
  87. package/assets/css/docusaurus.css +0 -104
  88. package/docs/examples.mdx +0 -70
  89. /package/docs/assets/{screens-blue.jpg → images/screens-blue.jpg} +0 -0
  90. /package/docs/assets/{screens-white.jpg → images/screens-white.jpg} +0 -0
  91. /package/{assets → docs/assets}/images/slot-map.svg +0 -0
@@ -0,0 +1,123 @@
1
+ import DemoMapMarkerPanel from '../../demo/DemoMapMarkerPanel.js'
2
+ import CodeTabs from '../../demo/js/codeTabs.js'
3
+
4
+ # Add a marker with a panel
5
+
6
+ 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.
7
+
8
+ <DemoMapMarkerPanel />
9
+
10
+ <CodeTabs tabs={[
11
+ {
12
+ label: 'ESM',
13
+ language: 'js',
14
+ code: `
15
+ import InteractiveMap from '@defra/interactive-map'
16
+ import maplibreProvider from '@defra/interactive-map/providers/maplibre'
17
+ import createInteractPlugin from '@defra/interactive-map/plugins/interact'
18
+
19
+ const interactPlugin = createInteractPlugin({
20
+ deselectOnClickOutside: true
21
+ })
22
+
23
+ const map = new InteractiveMap('my-map', {
24
+ behaviour: 'inline',
25
+ mapProvider: maplibreProvider(),
26
+ mapStyle: {
27
+ url: 'https://your-tile-url/style.json',
28
+ attribution: 'Your tile attribution'
29
+ },
30
+ center: [-2.96, 54.43],
31
+ zoom: 15,
32
+ containerHeight: '500px',
33
+ plugins: [interactPlugin]
34
+ })
35
+
36
+ map.on('map:ready', () => {
37
+ map.addMarker('my-marker', [-2.96, 54.43])
38
+ interactPlugin.enable()
39
+ interactPlugin.selectMarker('my-marker')
40
+
41
+ map.addPanel('marker-info', {
42
+ focus: false,
43
+ label: 'Marker',
44
+ html: '<p class="govuk-body">Information about the selected marker</p>',
45
+ mobile: { slot: 'drawer', dismissible: true },
46
+ tablet: { slot: 'left-top', dismissible: true, width: '280px' },
47
+ desktop: { slot: 'left-top', dismissible: true, width: '280px' }
48
+ })
49
+ })
50
+
51
+ map.on('interact:selectionchange', ({ selectedMarkers }) => {
52
+ if (selectedMarkers.length > 0) {
53
+ map.showPanel('marker-info')
54
+ } else {
55
+ map.hidePanel('marker-info')
56
+ }
57
+ })
58
+
59
+ map.on('app:panelclosed', ({ panelId }) => {
60
+ if (panelId === 'marker-info') {
61
+ interactPlugin.unselectMarker('my-marker')
62
+ }
63
+ })
64
+ `
65
+ },
66
+ {
67
+ label: 'UMD',
68
+ language: 'html',
69
+ code: `
70
+ <script src="/your-assets-path/interactive-map/index.js"></script>
71
+ <script src="/your-assets-path/maplibre-provider/index.js"></script>
72
+ <script src="/your-assets-path/interact-plugin/index.js"></script>
73
+
74
+ <script>
75
+ const interactPlugin = defra.interactPlugin({
76
+ deselectOnClickOutside: true
77
+ })
78
+
79
+ const map = new defra.InteractiveMap('my-map', {
80
+ behaviour: 'inline',
81
+ mapProvider: defra.maplibreProvider(),
82
+ mapStyle: {
83
+ url: 'https://your-tile-url/style.json',
84
+ attribution: 'Your tile attribution'
85
+ },
86
+ center: [-2.96, 54.43],
87
+ zoom: 15,
88
+ containerHeight: '500px',
89
+ plugins: [interactPlugin]
90
+ })
91
+
92
+ map.on('map:ready', () => {
93
+ map.addMarker('my-marker', [-2.96, 54.43])
94
+ interactPlugin.enable()
95
+ interactPlugin.selectMarker('my-marker')
96
+
97
+ map.addPanel('marker-info', {
98
+ focus: false,
99
+ label: 'Marker',
100
+ html: '<p class="govuk-body">Information about the selected marker</p>',
101
+ mobile: { slot: 'drawer', dismissible: true },
102
+ tablet: { slot: 'left-top', dismissible: true, width: '280px' },
103
+ desktop: { slot: 'left-top', dismissible: true, width: '280px' }
104
+ })
105
+ })
106
+
107
+ map.on('interact:selectionchange', ({ selectedMarkers }) => {
108
+ if (selectedMarkers.length > 0) {
109
+ map.showPanel('marker-info')
110
+ } else {
111
+ map.hidePanel('marker-info')
112
+ }
113
+ })
114
+
115
+ map.on('app:panelclosed', ({ panelId }) => {
116
+ if (panelId === 'marker-info') {
117
+ interactPlugin.unselectMarker('my-marker')
118
+ }
119
+ })
120
+ </script>
121
+ `
122
+ }
123
+ ]} />
@@ -0,0 +1,53 @@
1
+ import DemoMapBasic from '../../demo/DemoMapBasic.js'
2
+ import CodeTabs from '../../demo/js/codeTabs.js'
3
+
4
+ # Basic map
5
+
6
+ Embed an interactive map directly on the page, allowing users to explore and interact with the map without leaving the current context.
7
+
8
+ <DemoMapBasic />
9
+
10
+ <CodeTabs tabs={[
11
+ {
12
+ label: 'ESM',
13
+ language: 'js',
14
+ code: `
15
+ import InteractiveMap from '@defra/interactive-map'
16
+ import maplibreProvider from '@defra/interactive-map/providers/maplibre'
17
+
18
+ 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: [-1.6, 53.1],
26
+ zoom: 6,
27
+ containerHeight: '500px'
28
+ })
29
+ `
30
+ },
31
+ {
32
+ label: 'UMD',
33
+ language: 'html',
34
+ code: `
35
+ <script src="/your-assets-path/interactive-map/index.js"></script>
36
+ <script src="/your-assets-path/maplibre-provider/index.js"></script>
37
+
38
+ <script>
39
+ new defra.InteractiveMap('my-map', {
40
+ behaviour: 'inline',
41
+ mapProvider: defra.maplibreProvider(),
42
+ mapStyle: {
43
+ url: 'https://your-tile-url/style.json',
44
+ attribution: 'Your tile attribution'
45
+ },
46
+ center: [-1.6, 53.1],
47
+ zoom: 6,
48
+ containerHeight: '500px'
49
+ })
50
+ </script>
51
+ `
52
+ }
53
+ ]} />
@@ -0,0 +1,53 @@
1
+ import DemoMapButton from '../../demo/DemoMapButton.js'
2
+ import CodeTabs from '../../demo/js/codeTabs.js'
3
+
4
+ # Button-triggered map
5
+
6
+ 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.
7
+
8
+ <DemoMapButton />
9
+
10
+ <CodeTabs tabs={[
11
+ {
12
+ label: 'ESM',
13
+ language: 'js',
14
+ code: `
15
+ import InteractiveMap from '@defra/interactive-map'
16
+ import maplibreProvider from '@defra/interactive-map/providers/maplibre'
17
+
18
+ new InteractiveMap('my-map', {
19
+ behaviour: 'buttonFirst',
20
+ mapProvider: maplibreProvider(),
21
+ mapStyle: {
22
+ url: 'https://your-tile-url/style.json',
23
+ attribution: 'Your tile attribution'
24
+ },
25
+ center: [-1.6, 53.1],
26
+ zoom: 6,
27
+ hasExitButton: true
28
+ })
29
+ `
30
+ },
31
+ {
32
+ label: 'UMD',
33
+ language: 'html',
34
+ code: `
35
+ <script src="/your-assets-path/interactive-map/index.js"></script>
36
+ <script src="/your-assets-path/maplibre-provider/index.js"></script>
37
+
38
+ <script>
39
+ new defra.InteractiveMap('my-map', {
40
+ behaviour: 'buttonFirst',
41
+ mapProvider: defra.maplibreProvider(),
42
+ mapStyle: {
43
+ url: 'https://your-tile-url/style.json',
44
+ attribution: 'Your tile attribution'
45
+ },
46
+ center: [-1.6, 53.1],
47
+ zoom: 6,
48
+ hasExitButton: true
49
+ })
50
+ </script>
51
+ `
52
+ }
53
+ ]} />
@@ -0,0 +1,49 @@
1
+ import useBaseUrl from '@docusaurus/useBaseUrl'
2
+ import basicMapImg from '../assets/images/basic-map.jpg'
3
+ import buttonFirstImg from '../assets/images/button-first.jpg'
4
+ import markerPanelImg from '../assets/images/marker-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' style={{ borderTop: '1px solid #f4f8fb'}}>
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={markerPanelImg} alt='' />
36
+ <div className='app-example-card__body' style={{ borderTop: '1px solid #f4f8fb'}}>
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 />
@@ -3,62 +3,61 @@
3
3
  ## Installation
4
4
 
5
5
  ```shell
6
- npm i @defra/interactive-map@x.y.z-alpha
6
+ npm install @defra/interactive-map@x.y.z-alpha
7
7
  ```
8
8
 
9
- [!NOTE]
10
- Install using a fixed version (e.g. npm install @defra/interactive-map@x.y.z-alpha) as this package is currently in alpha and may introduce breaking changes. Check the GitHub releases page for the latest available [version](https://github.com/DEFRA/interactive-map/tags).
9
+ > [!NOTE]
10
+ Install using a fixed version (e.g. `npm install @defra/interactive-map@x.y.z-alpha`) as this package is currently in alpha and may introduce breaking changes. Check the GitHub releases page for the latest available [version](https://github.com/DEFRA/interactive-map/tags).
11
11
 
12
- ### MapLibre provider (recommended)
12
+ ## GOV.UK Prototype kit
13
13
 
14
- **ESM:** `maplibre-gl` is a peer dependency, install it separately:
14
+ The quickest way to get started is via the GOV.UK Prototype Kit. Once installed, the map component is available immediately — no build step or manual asset setup required.
15
15
 
16
- ```shell
17
- npm i maplibre-gl
18
- ```
16
+ The plugin automatically serves the required scripts and styles, and provides a ready-made map page template to build from.
19
17
 
20
- **UMD:** `maplibre-gl` is bundled no separate install needed.
18
+ See [GOV.UK Prototype Kit - Install and use plugins](https://prototype-kit.service.gov.uk/docs/install-and-use-plugins) for how to install plugins.
21
19
 
22
- ### ESRI provider (optional)
20
+ ## Manual setup
23
21
 
24
- If you are using the ESRI map provider instead, install `@arcgis/core`:
22
+ The package is distributed in two formats:
25
23
 
26
- ```shell
27
- npm i @arcgis/core
28
- ```
24
+ - **ESM** (ECMAScript Modules) — for projects using a bundler such as Webpack or Rollup. Import directly from the package in your JavaScript.
25
+ - **UMD** (Universal Module Definition) — for projects without a bundler. Copy the built files to your assets and load them via `<script>` tags.
29
26
 
30
- ### Include in your project
27
+ The map component also requires a **map provider** — a separate library that handles the underlying tile rendering engine. The provider is passed in at initialisation, which keeps the core package lean and lets you choose the engine that fits your needs.
31
28
 
32
- **ESM** import in your JavaScript:
29
+ ### MapLibre provider (recommended)
33
30
 
34
- ```js
35
- import InteractiveMap from '@defra/interactive-map'
36
- import maplibreProvider from '@defra/interactive-map/providers/maplibre'
31
+ **ESM:** `maplibre-gl` is a peer dependency, install it separately:
37
32
 
38
- import '@defra/interactive-map/css'
33
+ ```shell
34
+ npm install maplibre-gl
39
35
  ```
40
36
 
41
- **UMD** — copy the `dist/umd/` folders to your assets and include via script and link tags in your `<head>`:
37
+ **UMD:** `maplibre-gl` is bundled no separate install needed.
38
+
39
+ ### ESRI provider (optional)
42
40
 
43
- ```html
44
- <link rel="stylesheet" href="/assets/interactive-map.css">
45
- <script defer src="/assets/interactive-map/index.js"></script>
46
- <script defer src="/assets/maplibre-provider/index.js"></script>
47
- ```
41
+ The ESRI provider is available for ESM projects only. Install `@arcgis/core` separately:
48
42
 
49
- > Chunks are loaded dynamically — all files in each `umd/` folder must be served from the same directory as their `index.js`.
43
+ ```shell
44
+ npm install @arcgis/core
45
+ ```
50
46
 
51
47
  ## Basic usage
52
48
 
53
- Add a container element in your HTML:
49
+ **ESM** — add a container element to your HTML and initialise the map in your JavaScript:
54
50
 
55
51
  ```html
56
52
  <div id="map"></div>
57
53
  ```
58
54
 
59
- Initialise the map in your JavaScript. UMD users replace `InteractiveMap` and `maplibreProvider` with `defra.InteractiveMap` and `defra.maplibreProvider`:
60
-
61
55
  ```js
56
+ import InteractiveMap from '@defra/interactive-map'
57
+ import maplibreProvider from '@defra/interactive-map/providers/maplibre'
58
+
59
+ import '@defra/interactive-map/css'
60
+
62
61
  const interactiveMap = new InteractiveMap('map', {
63
62
  mapProvider: maplibreProvider(),
64
63
  behaviour: 'hybrid',
@@ -74,44 +73,72 @@ const interactiveMap = new InteractiveMap('map', {
74
73
  })
75
74
  ```
76
75
 
76
+ **UMD** — copy the `dist/umd/` folders to your assets, then use this page skeleton as a starting point:
77
+
78
+ ```html
79
+ <!DOCTYPE html>
80
+ <html lang="en">
81
+ <head>
82
+ <meta charset="UTF-8">
83
+ <title>Map</title>
84
+ <link rel="stylesheet" href="/your-assets-path/interactive-map.css">
85
+ <script defer src="/your-assets-path/interactive-map/index.js"></script>
86
+ <script defer src="/your-assets-path/maplibre-provider/index.js"></script>
87
+ <script defer>
88
+ document.addEventListener('DOMContentLoaded', function () {
89
+ const interactiveMap = new defra.InteractiveMap('map', {
90
+ mapProvider: defra.maplibreProvider(),
91
+ behaviour: 'hybrid',
92
+ mapLabel: 'Ambleside',
93
+ zoom: 14,
94
+ center: [-2.968, 54.425],
95
+ containerHeight: '650px',
96
+ mapStyle: {
97
+ url: 'https://tiles.openfreemap.org/styles/liberty',
98
+ attribution: 'OpenFreeMap © OpenMapTiles Data from OpenStreetMap',
99
+ backgroundColor: '#f5f5f0'
100
+ }
101
+ })
102
+ })
103
+ </script>
104
+ </head>
105
+ <body>
106
+ <div id="map"></div>
107
+ </body>
108
+ </html>
109
+ ```
110
+
111
+ > [!NOTE]
112
+ > Scripts are loaded dynamically — all files in each `umd/` folder must be served from the same directory as their `index.js`.
113
+
77
114
  ## Using plugins
78
115
 
79
- **ESM** — import each plugin and its CSS:
116
+ **ESM** — add the plugin import and its CSS alongside your existing core imports, then pass it to `plugins`:
80
117
 
81
118
  ```js
82
- import createSearchPlugin from '@defra/interactive-map/plugins/search'
83
119
  import createInteractPlugin from '@defra/interactive-map/plugins/interact'
84
-
85
- import '@defra/interactive-map/plugins/search/css'
86
120
  import '@defra/interactive-map/plugins/interact/css'
121
+
122
+ const interactiveMap = new InteractiveMap('map', {
123
+ // ...your existing options
124
+ plugins: [createInteractPlugin()]
125
+ })
87
126
  ```
88
127
 
89
- **UMD** — copy each plugin's `dist/umd/` folder and CSS file to your assets:
128
+ **UMD** — copy the plugin's `dist/umd/` folder to your assets if you haven't already, then add its script and CSS to your page skeleton:
90
129
 
91
130
  ```html
92
- <link rel="stylesheet" href="/assets/search-plugin.css">
93
- <link rel="stylesheet" href="/assets/interact-plugin.css">
94
- <script src="/assets/search-plugin/index.js"></script>
95
- <script src="/assets/interact-plugin/index.js"></script>
131
+ <link rel="stylesheet" href="/your-assets-path/interact-plugin.css">
132
+ <script defer src="/your-assets-path/interact-plugin/index.js"></script>
96
133
  ```
97
134
 
98
- Then pass plugins when initialising. UMD users replace `createSearchPlugin` and `createInteractPlugin` with `defra.searchPlugin` and `defra.interactPlugin`:
135
+ Then pass the plugin in your initialisation:
99
136
 
100
137
  ```js
101
- const interactiveMap = new InteractiveMap('map', {
102
- mapProvider: maplibreProvider(),
103
- plugins: [
104
- createSearchPlugin(),
105
- createInteractPlugin()
106
- ],
107
- // ... other options
138
+ const interactiveMap = new defra.InteractiveMap('map', {
139
+ // ...your existing options
140
+ plugins: [defra.interactPlugin()]
108
141
  })
109
142
  ```
110
143
 
111
144
  Each plugin distributes its own CSS. Import or copy only the CSS for the plugins you use. See [Plugins](./plugins.md) for the full list including their CSS paths.
112
-
113
- ## GOV.UK Prototype kit plugin
114
-
115
- 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.
116
-
117
- See [GOV.UK Prototype Kit - Install and use plugins](https://prototype-kit.service.gov.uk/docs/install-and-use-plugins).
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 inline maps, button-triggered maps, and various configuration options.</p>
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>
@@ -50,6 +50,9 @@ Controls which interactions are active when the user clicks the map. Values can
50
50
  - `'selectFeature'` — clicking the map attempts to match a feature from `layers`
51
51
  - `'placeMarker'` — if no feature is matched (or `selectFeature` is not active), places a location marker at the clicked coordinates
52
52
 
53
+ > [!NOTE]
54
+ > On touch and keyboard, a crosshair and "Select" action button are shown when interact is enabled. For touch users, this applies when `'placeMarker'` or `'selectFeature'` is included — modes where a precise point on the map needs to be chosen. When `'selectMarker'` is the only active mode, touch users tap markers directly and the crosshair is not shown.
55
+
53
56
  **Common combinations:**
54
57
 
55
58
  ```js
@@ -204,7 +207,7 @@ interactPlugin.disable()
204
207
 
205
208
  ### `clear()`
206
209
 
207
- Clear the current selection or marker.
210
+ Clear all selected features and markers, and remove the location marker.
208
211
 
209
212
  ```js
210
213
  interactPlugin.clear()
@@ -252,6 +255,34 @@ interactPlugin.unselectFeature({
252
255
 
253
256
  ---
254
257
 
258
+ ### `selectMarker(markerId)`
259
+
260
+ Programmatically select a marker. Idempotent — has no effect if the marker is already selected. In single-select mode, clears any selected features and replaces the marker selection. In multi-select mode, adds to the existing selection.
261
+
262
+ | Parameter | Type | Description |
263
+ |-----------|------|-------------|
264
+ | `markerId` | `string` | The ID of the marker to select |
265
+
266
+ ```js
267
+ interactPlugin.selectMarker('my-marker')
268
+ ```
269
+
270
+ ---
271
+
272
+ ### `unselectMarker(markerId)`
273
+
274
+ Programmatically unselect a specific marker. Idempotent — has no effect if the marker is not selected.
275
+
276
+ | Parameter | Type | Description |
277
+ |-----------|------|-------------|
278
+ | `markerId` | `string` | The ID of the marker to unselect |
279
+
280
+ ```js
281
+ interactPlugin.unselectMarker('my-marker')
282
+ ```
283
+
284
+ ---
285
+
255
286
  ## Events
256
287
 
257
288
  Subscribe to events using `interactiveMap.on()`.
package/docs/plugins.md CHANGED
@@ -10,7 +10,7 @@ The following plugins are available for use with InteractiveMap.
10
10
 
11
11
  ### [Interact](./plugins/interact.md)
12
12
 
13
- Select features or place markers on the map.
13
+ Select map features, select markers, or place a location marker on the map.
14
14
 
15
15
  ### [Map Styles](./plugins/map-styles.md)
16
16
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  /** @type {import('@docusaurus/types').Config} */
4
4
  const config = {
5
- staticDirectories: ['assets'],
5
+ staticDirectories: ['assets', 'docs/assets'],
6
6
  title: 'Defra Interactive Map',
7
7
  tagline: 'An accessibility-first interactive map component for government frontends',
8
8
  favicon: 'images/favicon.svg',
@@ -45,7 +45,7 @@ const config = {
45
45
  return {
46
46
  name: 'custom-css',
47
47
  getClientModules() {
48
- return [require.resolve('./assets/css/docusaurus.css')];
48
+ return [require.resolve('./docs/assets/css/docusaurus.css')];
49
49
  },
50
50
  };
51
51
  },
@@ -79,12 +79,21 @@ const config = {
79
79
  href: '/getting-started',
80
80
  sidebar: [
81
81
  { text: 'Installation', href: '/getting-started#installation' },
82
+ { text: 'GOV.UK Prototype kit', href: '/getting-started#govuk-prototype-kit' },
83
+ { text: 'Manual setup', href: '/getting-started#manual-setup' },
82
84
  { text: 'Basic usage', href: '/getting-started#basic-usage' },
83
- { text: 'Using plugins', href: '/getting-started#using-plugins' },
84
- { text: 'GOV.UK Prototype kit', href: '/getting-started#govuk-prototype-kit-plugin' }
85
+ { text: 'Using plugins', href: '/getting-started#using-plugins' }
86
+ ],
87
+ },
88
+ {
89
+ text: 'Examples',
90
+ href: '/examples',
91
+ sidebar: [
92
+ { text: 'Basic map', href: '/examples/basic-map' },
93
+ { text: 'Button-triggered map', href: '/examples/button-map' },
94
+ { text: 'Add a marker with a panel', href: '/examples/add-marker-with-panel' },
85
95
  ],
86
96
  },
87
- { text: 'Examples', href: '/examples', sidebar: 'auto' },
88
97
  {
89
98
  text: 'API',
90
99
  href: '/api',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra/interactive-map",
3
- "version": "0.0.18-alpha",
3
+ "version": "0.0.20-alpha",
4
4
  "description": "An accessible map component",
5
5
  "repository": {
6
6
  "type": "git",
@@ -127,7 +127,7 @@
127
127
  "@babel/plugin-transform-runtime": "^7.29.0",
128
128
  "@babel/preset-env": "^7.28.0",
129
129
  "@babel/preset-react": "^7.27.1",
130
- "@defra/docusaurus-theme-govuk": "^0.0.16-alpha",
130
+ "@defra/docusaurus-theme-govuk": "^0.0.18-alpha",
131
131
  "@docusaurus/core": "^3.9.2",
132
132
  "@docusaurus/module-type-aliases": "^3.9.2",
133
133
  "@docusaurus/plugin-content-docs": "^3.9.2",
@@ -218,7 +218,7 @@
218
218
  "@turf/polygon-to-line": "^7.3.3",
219
219
  "accessible-autocomplete": "^3.0.1",
220
220
  "govuk-frontend": "^5.13.0",
221
- "maplibre-gl": "^5.21.1",
221
+ "maplibre-gl": "^5.23.0",
222
222
  "polygon-splitter": "^0.0.11",
223
223
  "preact": "^10.27.2",
224
224
  "tslib": "^2.8.1"