@defra/interactive-map 0.0.16-alpha → 0.0.18-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 (224) hide show
  1. package/assets/images/slot-map.svg +264 -0
  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/context.md +53 -7
  8. package/docs/api/map-style-config.md +41 -2
  9. package/docs/api/marker-config.md +53 -11
  10. package/docs/api/slots.md +16 -15
  11. package/docs/api/symbol-config.md +160 -0
  12. package/docs/api/symbol-registry.md +115 -0
  13. package/docs/api.md +25 -22
  14. package/docs/getting-started.md +4 -1
  15. package/docs/plugins/datasets.md +657 -0
  16. package/docs/plugins/interact.md +68 -43
  17. package/docs/plugins/search.md +15 -3
  18. package/docs/plugins.md +1 -1
  19. package/package.json +2 -2
  20. package/plugins/beta/datasets/dist/css/index.css +103 -15
  21. package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
  22. package/plugins/beta/datasets/dist/esm/index.js +1 -1
  23. package/plugins/beta/datasets/dist/umd/im-datasets-plugin.js +1 -1
  24. package/plugins/beta/datasets/dist/umd/index.js +1 -1
  25. package/plugins/beta/datasets/src/DatasetsInit.jsx +29 -9
  26. package/plugins/beta/datasets/src/adapters/maplibre/index.js +18 -0
  27. package/plugins/beta/datasets/src/adapters/maplibre/layerBuilders.js +159 -0
  28. package/plugins/beta/datasets/src/adapters/maplibre/layerIds.js +75 -0
  29. package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +440 -0
  30. package/plugins/beta/datasets/src/adapters/maplibre/patternImages.js +27 -0
  31. package/plugins/beta/datasets/src/adapters/maplibre/symbolImages.js +31 -0
  32. package/plugins/beta/datasets/src/api/addDataset.js +2 -8
  33. package/plugins/beta/datasets/src/api/getOpacity.js +17 -0
  34. package/plugins/beta/datasets/src/api/getStyle.js +13 -0
  35. package/plugins/beta/datasets/src/api/removeDataset.js +2 -44
  36. package/plugins/beta/datasets/src/api/setData.js +10 -0
  37. package/plugins/beta/datasets/src/api/setDatasetVisibility.js +37 -0
  38. package/plugins/beta/datasets/src/api/setFeatureVisibility.js +22 -0
  39. package/plugins/beta/datasets/src/api/setOpacity.js +29 -0
  40. package/plugins/beta/datasets/src/api/setStyle.js +22 -0
  41. package/plugins/beta/datasets/src/components/EmptyKey.jsx +7 -0
  42. package/plugins/beta/datasets/src/components/EmptyKey.test.jsx +21 -0
  43. package/plugins/beta/datasets/src/components/KeySvg.jsx +24 -0
  44. package/plugins/beta/datasets/src/components/KeySvgLine.jsx +19 -0
  45. package/plugins/beta/datasets/src/components/KeySvgPattern.jsx +15 -0
  46. package/plugins/beta/datasets/src/components/KeySvgRect.jsx +22 -0
  47. package/plugins/beta/datasets/src/components/KeySvgSymbol.jsx +16 -0
  48. package/plugins/beta/datasets/src/components/svgProperties.js +20 -0
  49. package/plugins/beta/datasets/src/datasets.js +39 -56
  50. package/plugins/beta/datasets/src/defaults.js +44 -8
  51. package/plugins/beta/datasets/src/fetch/createDynamicSource.js +34 -25
  52. package/plugins/beta/datasets/src/fetch/fetchGeoJSON.js +2 -2
  53. package/plugins/beta/datasets/src/index.js +2 -1
  54. package/plugins/beta/datasets/src/manifest.js +25 -17
  55. package/plugins/beta/datasets/src/panels/Key.jsx +51 -51
  56. package/plugins/beta/datasets/src/panels/Key.module.scss +59 -9
  57. package/plugins/beta/datasets/src/panels/Layers.jsx +132 -29
  58. package/plugins/beta/datasets/src/panels/Layers.module.scss +56 -8
  59. package/plugins/beta/datasets/src/reducer.js +134 -9
  60. package/plugins/beta/datasets/src/reducers/keyReducer.js +34 -0
  61. package/plugins/beta/datasets/src/utils/bbox.js +7 -5
  62. package/plugins/beta/datasets/src/utils/filters.js +5 -2
  63. package/plugins/beta/datasets/src/utils/mergeSublayer.js +86 -0
  64. package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
  65. package/plugins/beta/draw-es/src/DrawInit.jsx +3 -2
  66. package/plugins/beta/draw-ml/dist/css/index.css +21 -1
  67. package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
  68. package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
  69. package/plugins/beta/draw-ml/dist/umd/index.js +1 -1
  70. package/plugins/beta/draw-ml/src/DrawInit.jsx +4 -3
  71. package/plugins/beta/draw-ml/src/draw.scss +0 -7
  72. package/plugins/beta/draw-ml/src/manifest.js +16 -16
  73. package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -1
  74. package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -1
  75. package/plugins/beta/frame/src/Frame.jsx +5 -5
  76. package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
  77. package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
  78. package/plugins/beta/map-styles/dist/umd/index.js +1 -1
  79. package/plugins/beta/map-styles/src/MapStyles.jsx +5 -4
  80. package/plugins/beta/map-styles/src/MapStylesInit.jsx +5 -4
  81. package/plugins/beta/map-styles/src/manifest.js +1 -1
  82. package/plugins/beta/scale-bar/dist/css/index.css +1 -1
  83. package/plugins/beta/scale-bar/dist/esm/im-scale-bar-plugin.js +1 -1
  84. package/plugins/beta/scale-bar/dist/umd/im-scale-bar-plugin.js +1 -1
  85. package/plugins/beta/scale-bar/src/index.test.js +3 -3
  86. package/plugins/beta/scale-bar/src/manifest.js +3 -3
  87. package/plugins/beta/scale-bar/src/scaleBar.scss +2 -1
  88. package/plugins/interact/dist/css/index.css +1 -1
  89. package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
  90. package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
  91. package/plugins/interact/dist/umd/index.js +1 -1
  92. package/plugins/interact/src/InteractInit.jsx +14 -5
  93. package/plugins/interact/src/InteractInit.test.js +26 -6
  94. package/plugins/interact/src/api/enable.test.js +7 -7
  95. package/plugins/interact/src/defaults.js +4 -6
  96. package/plugins/interact/src/events.js +9 -6
  97. package/plugins/interact/src/events.test.js +28 -4
  98. package/plugins/interact/src/hooks/useHighlightSync.js +3 -3
  99. package/plugins/interact/src/hooks/useHighlightSync.test.js +6 -6
  100. package/plugins/interact/src/hooks/useHoverCursor.js +10 -0
  101. package/plugins/interact/src/hooks/useHoverCursor.test.js +44 -0
  102. package/plugins/interact/src/hooks/useInteractionHandlers.js +111 -69
  103. package/plugins/interact/src/hooks/useInteractionHandlers.test.js +147 -32
  104. package/plugins/interact/src/interact.scss +0 -7
  105. package/plugins/interact/src/manifest.js +14 -18
  106. package/plugins/interact/src/manifest.test.js +3 -1
  107. package/plugins/interact/src/reducer.js +23 -4
  108. package/plugins/interact/src/reducer.test.js +60 -11
  109. package/plugins/interact/src/utils/buildStylesMap.js +17 -4
  110. package/plugins/interact/src/utils/buildStylesMap.test.js +16 -2
  111. package/plugins/interact/src/utils/featureQueries.js +11 -6
  112. package/plugins/interact/src/utils/featureQueries.test.js +8 -1
  113. package/plugins/search/dist/css/index.css +1 -1
  114. package/plugins/search/dist/esm/im-search-plugin.js +1 -1
  115. package/plugins/search/dist/umd/im-search-plugin.js +1 -1
  116. package/plugins/search/src/Search.jsx +3 -1
  117. package/plugins/search/src/components/Form/Form.module.scss +2 -1
  118. package/plugins/search/src/events/fetchSuggestions.js +6 -4
  119. package/plugins/search/src/events/fetchSuggestions.test.js +26 -4
  120. package/plugins/search/src/events/formHandlers.js +3 -3
  121. package/plugins/search/src/events/formHandlers.test.js +1 -1
  122. package/plugins/search/src/events/suggestionHandlers.js +2 -2
  123. package/plugins/search/src/events/suggestionHandlers.test.js +1 -1
  124. package/plugins/search/src/utils/updateMap.js +3 -3
  125. package/plugins/search/src/utils/updateMap.test.js +3 -3
  126. package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
  127. package/providers/maplibre/dist/umd/im-maplibre-framework.js +1 -1
  128. package/providers/maplibre/dist/umd/im-maplibre-framework.js.LICENSE.txt +1 -1
  129. package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
  130. package/providers/maplibre/dist/umd/index.js +1 -1
  131. package/providers/maplibre/src/appEvents.js +7 -0
  132. package/providers/maplibre/src/appEvents.test.js +18 -4
  133. package/providers/maplibre/src/maplibreProvider.js +52 -0
  134. package/providers/maplibre/src/maplibreProvider.test.js +105 -1
  135. package/providers/maplibre/src/utils/highlightFeatures.js +37 -7
  136. package/providers/maplibre/src/utils/highlightFeatures.test.js +153 -95
  137. package/providers/maplibre/src/utils/hoverCursor.js +61 -0
  138. package/providers/maplibre/src/utils/hoverCursor.test.js +130 -0
  139. package/providers/maplibre/src/utils/patternImages.js +70 -0
  140. package/providers/maplibre/src/utils/patternImages.test.js +180 -0
  141. package/providers/maplibre/src/utils/queryFeatures.js +38 -16
  142. package/providers/maplibre/src/utils/queryFeatures.test.js +20 -3
  143. package/providers/maplibre/src/utils/rasteriseToImageData.js +30 -0
  144. package/providers/maplibre/src/utils/rasteriseToImageData.test.js +69 -0
  145. package/providers/maplibre/src/utils/symbolImages.js +147 -0
  146. package/providers/maplibre/src/utils/symbolImages.test.js +248 -0
  147. package/src/App/components/Actions/Actions.jsx +2 -2
  148. package/src/App/components/Actions/Actions.module.scss +0 -7
  149. package/src/App/components/Actions/Actions.test.jsx +1 -1
  150. package/src/App/components/Icon/Icon.jsx +3 -2
  151. package/src/App/components/Icon/Icon.module.scss +4 -0
  152. package/src/App/components/Icon/Icon.test.jsx +43 -4
  153. package/src/App/components/MapButton/MapButton.jsx +42 -17
  154. package/src/App/components/MapButton/MapButton.module.scss +4 -13
  155. package/src/App/components/MapButton/MapButton.test.jsx +27 -3
  156. package/src/App/components/Markers/Markers.jsx +122 -27
  157. package/src/App/components/Markers/Markers.module.scss +0 -10
  158. package/src/App/components/Markers/Markers.test.jsx +246 -0
  159. package/src/App/components/PopupMenu/PopupMenu.jsx +51 -274
  160. package/src/App/components/PopupMenu/PopupMenu.module.scss +14 -7
  161. package/src/App/components/PopupMenu/PopupMenu.test.jsx +70 -1
  162. package/src/App/components/PopupMenu/usePopupMenu.js +258 -0
  163. package/src/App/hooks/useButtonStateEvaluator.js +12 -2
  164. package/src/App/hooks/useButtonStateEvaluator.test.js +38 -4
  165. package/src/App/hooks/useInterfaceAPI.js +6 -0
  166. package/src/App/hooks/useInterfaceAPI.test.js +156 -0
  167. package/src/App/hooks/useLayoutMeasurements.js +84 -18
  168. package/src/App/hooks/useLayoutMeasurements.test.js +124 -17
  169. package/src/App/hooks/useMarkersAPI.js +2 -5
  170. package/src/App/hooks/useMarkersAPI.test.js +4 -4
  171. package/src/App/layout/Layout.jsx +14 -9
  172. package/src/App/layout/Layout.test.jsx +6 -4
  173. package/src/App/layout/layout.module.scss +67 -29
  174. package/src/App/registry/pluginRegistry.js +1 -1
  175. package/src/App/renderer/HtmlElementHost.jsx +2 -1
  176. package/src/App/renderer/HtmlElementHost.test.jsx +7 -7
  177. package/src/App/renderer/mapButtons.js +1 -1
  178. package/src/App/renderer/mapPanels.test.js +2 -2
  179. package/src/App/renderer/slotHelpers.js +2 -2
  180. package/src/App/renderer/slotHelpers.test.js +5 -5
  181. package/src/App/renderer/slots.js +9 -5
  182. package/src/App/store/AppProvider.jsx +3 -1
  183. package/src/App/store/AppProvider.test.jsx +1 -1
  184. package/src/App/store/ServiceProvider.jsx +8 -4
  185. package/src/App/store/appActionsMap.js +16 -0
  186. package/src/App/store/appActionsMap.test.js +27 -0
  187. package/src/App/store/appDispatchMiddleware.js +1 -1
  188. package/src/App/store/appDispatchMiddleware.test.js +2 -2
  189. package/src/App/store/appReducer.js +2 -0
  190. package/src/App/store/mapActionsMap.js +4 -6
  191. package/src/App/store/mapActionsMap.test.js +3 -2
  192. package/src/App/store/mapReducer.js +2 -1
  193. package/src/InteractiveMap/InteractiveMap.js +4 -0
  194. package/src/config/appConfig.js +5 -8
  195. package/src/config/appConfig.test.js +1 -2
  196. package/src/config/defaults.js +0 -2
  197. package/src/config/events.js +28 -0
  198. package/src/config/mapTheme.js +56 -0
  199. package/src/config/patternConfig.js +16 -0
  200. package/src/config/symbolConfig.js +80 -0
  201. package/src/scss/main.scss +1 -0
  202. package/src/scss/settings/_colors.scss +0 -9
  203. package/src/scss/settings/_dimensions.scss +0 -1
  204. package/src/services/patternRegistry.js +40 -0
  205. package/src/services/patternRegistry.test.js +48 -0
  206. package/src/services/symbolRegistry.js +113 -0
  207. package/src/services/symbolRegistry.test.js +262 -0
  208. package/src/types.js +93 -11
  209. package/src/utils/getSafeZoneInset.js +9 -7
  210. package/src/utils/getSafeZoneInset.test.js +10 -10
  211. package/src/utils/patternUtils.js +94 -0
  212. package/src/utils/patternUtils.test.js +160 -0
  213. package/src/utils/symbolUtils.js +85 -0
  214. package/src/utils/symbolUtils.test.js +156 -0
  215. package/webpack.dev.mjs +1 -1
  216. package/docs/api/slot-map.svg +0 -1
  217. package/plugins/beta/datasets/src/api/hideDataset.js +0 -14
  218. package/plugins/beta/datasets/src/api/hideFeatures.js +0 -41
  219. package/plugins/beta/datasets/src/api/showDataset.js +0 -14
  220. package/plugins/beta/datasets/src/api/showFeatures.js +0 -44
  221. package/plugins/beta/datasets/src/handleSetMapStyle.js +0 -54
  222. package/plugins/beta/datasets/src/mapLayers.js +0 -164
  223. /package/src/{utils → services}/logger.js +0 -0
  224. /package/src/{utils → services}/logger.test.js +0 -0
@@ -0,0 +1,160 @@
1
+ # Symbol Config
2
+
3
+ Symbol properties control the appearance of markers and point dataset features. The same properties apply whether you are configuring a marker, app-wide defaults via the constructor `symbolDefaults`, or a custom symbol registration.
4
+
5
+ ## How values are resolved
6
+
7
+ Each property is optional. A value set directly on a marker or dataset layer takes priority over everything else. If a property is not set there, the value registered with the symbol is used. If the symbol has no value for that property, the app-wide `symbolDefaults` from the constructor applies. If none of those are set, the built-in fallback listed under each property below is used.
8
+
9
+ `haloColor`, `selectedColor`, `haloWidth`, and `selectedWidth` are required tokens in the SVG structure (see [SVG structure](#svg-structure)). Include them in any custom `symbolSvgContent` — the app resolves their values automatically. Note that `haloColor` and `selectedColor` are always derived from the active map style and cannot be configured.
10
+
11
+ ## Style-keyed colours
12
+
13
+ Any colour property can be a plain string or an object keyed by map style ID. This lets a single config work across all basemaps:
14
+
15
+ ```js
16
+ backgroundColor: '#d4351c'
17
+ backgroundColor: { outdoor: '#d4351c', dark: '#ff6b6b' }
18
+ ```
19
+
20
+ ## Properties
21
+
22
+ ---
23
+
24
+ ### `symbol`
25
+ **Type:** `string`
26
+ **Default:** `'pin'`
27
+
28
+ Registered symbol ID to use. Built-in values: `'pin'`, `'circle'`, `'square'`. Ignored when `symbolSvgContent` is set.
29
+
30
+ ---
31
+
32
+ ### `symbolSvgContent`
33
+ **Type:** `string`
34
+
35
+ Inner SVG path content (no `<svg>` wrapper) to render as the symbol. Use `{{token}}` placeholders for colours. When set, `symbol` is ignored.
36
+
37
+ ```js
38
+ {
39
+ symbolSvgContent: `
40
+ <path d="..." fill="none" stroke="{{selectedColor}}" stroke-width="{{selectedWidth}}"/>
41
+ <path d="..." fill="{{backgroundColor}}" stroke="{{haloColor}}" stroke-width="{{haloWidth}}"/>
42
+ <path d="..." fill="{{foregroundColor}}"/>
43
+ `,
44
+ viewBox: '0 0 38 38',
45
+ anchor: [0.5, 1]
46
+ }
47
+ ```
48
+
49
+ See [SVG structure](#svg-structure) for the standard three-layer pattern.
50
+
51
+ ---
52
+
53
+ ### `viewBox`
54
+ **Type:** `string`
55
+ **Default:** registered symbol's viewBox, or `'0 0 38 38'`
56
+
57
+ SVG `viewBox` attribute. Use alongside `symbolSvgContent` when your paths use a different coordinate space.
58
+
59
+ ---
60
+
61
+ ### `anchor`
62
+ **Type:** `[number, number]`
63
+ **Default:** registered symbol's anchor, or `[0.5, 0.5]`
64
+
65
+ Normalised `[x, y]` anchor point where `[0, 0]` is the top-left and `[1, 1]` is the bottom-right of the symbol. Determines which point on the symbol aligns with the geographic coordinate.
66
+
67
+ ```js
68
+ anchor: [0.5, 1] // bottom-centre — tip of a pin
69
+ anchor: [0.5, 0.5] // centre — circle or dot
70
+ ```
71
+
72
+ ---
73
+
74
+ ### `backgroundColor`
75
+ **Type:** `string | Record<string, string>`
76
+ **Default:** `'#ca3535'`
77
+
78
+ Background fill colour of the symbol shape.
79
+
80
+ ---
81
+
82
+ ### `foregroundColor`
83
+ **Type:** `string | Record<string, string>`
84
+ **Default:** `'#ffffff'`
85
+
86
+ Foreground fill colour — the inner graphic element (e.g. the dot inside a pin).
87
+
88
+ ---
89
+
90
+ ### `haloWidth`
91
+ **Type:** `number`
92
+ **Default:** `1`
93
+
94
+ Stroke width of the halo around the symbol background shape. Can be set in constructor `symbolDefaults`, at symbol registration, or per marker/dataset layer.
95
+
96
+ ---
97
+
98
+ ### `selectedWidth`
99
+ **Type:** `number`
100
+ **Default:** `6`
101
+
102
+ Stroke width of the selection ring shown when a marker is selected. Can be set in constructor `symbolDefaults` or per marker/dataset layer.
103
+
104
+ ---
105
+
106
+ ### `graphic`
107
+ **Type:** `string`
108
+
109
+ SVG `d` attribute value for the foreground graphic path. Replaces the inner shape (e.g. the dot inside a pin) while keeping the background, halo and selection ring intact.
110
+
111
+ Pass a built-in name or supply your own path data:
112
+
113
+ ```js
114
+ // Named built-in — resolved automatically
115
+ { symbol: 'pin', graphic: 'cross' }
116
+
117
+ // Inline path data
118
+ { symbol: 'pin', graphic: 'M14 12 L24 20 L14 28 Z' }
119
+ ```
120
+
121
+ Built-in named graphics (16×16 coordinate space, centred at 8,8):
122
+
123
+ | Name | Shape |
124
+ |------|-------|
125
+ | `'dot'` | Small filled circle — the default for `pin` and `circle` |
126
+ | `'cross'` | Filled plus / cross |
127
+ | `'diamond'` | Filled diamond / rotated square |
128
+ | `'triangle'` | Filled upward-pointing triangle |
129
+ | `'square'` | Filled square |
130
+
131
+ `graphic` follows the full resolution order above — it can be set as a symbol default, a constructor default, or per item.
132
+
133
+ ---
134
+
135
+ ### Custom tokens
136
+
137
+ Any `{{token}}` placeholder in a symbol SVG beyond the built-in set is substituted automatically if a matching key is present anywhere in the resolution order:
138
+
139
+ ```js
140
+ // Symbol SVG contains: fill="{{accentColor}}"
141
+ markers.add('id', coords, { accentColor: '#ffdd00' })
142
+ ```
143
+
144
+ ## SVG structure
145
+
146
+ Symbols are defined as inner SVG path content (no `<svg>` wrapper) using `{{token}}` placeholders. The standard three-layer structure is:
147
+
148
+ ```js
149
+ svg: `
150
+ <path d="..." fill="none" stroke="{{selectedColor}}" stroke-width="{{selectedWidth}}"/>
151
+ <path d="..." fill="{{backgroundColor}}" stroke="{{haloColor}}" stroke-width="{{haloWidth}}"/>
152
+ <path d="..." fill="{{foregroundColor}}"/>
153
+ `
154
+ ```
155
+
156
+ - **Layer 1** — selection ring (stroke only, fill none) — hidden in normal rendering, visible when selected
157
+ - **Layer 2** — background shape with halo stroke
158
+ - **Layer 3** — foreground graphic (e.g. inner dot)
159
+
160
+ > `{{haloColor}}` and `{{selectedColor}}` are always injected from the active map style. They must be present in the SVG but cannot be configured.
@@ -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
@@ -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
- ### `markerShape`
289
- **Type:** `string`
290
- **Default:** `'pin'`
276
+ ### `symbolDefaults`
277
+ **Type:** `Partial<SymbolDefaults>`
291
278
 
292
- Default shape for map markers. Can be overridden per marker when calling `addMarker()`.
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
- > [!NOTE]
295
- > Currently only `'pin'` is available. Additional shapes are planned for a future release.
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], { color: '#0000ff' })
494
+ interactiveMap.addMarker('home', [-0.1276, 51.5074], { backgroundColor: '#1d70b8' })
492
495
  ```
493
496
 
494
497
  ---
@@ -560,9 +563,9 @@ See [PanelDefinition](./api/panel-definition.md) for configuration options. When
560
563
  interactiveMap.addPanel('info-panel', {
561
564
  label: 'Information',
562
565
  html: '<p>Panel content here</p>',
563
- mobile: { slot: 'bottom' },
564
- tablet: { slot: 'left' },
565
- desktop: { slot: 'left' }
566
+ mobile: { slot: 'drawer' },
567
+ tablet: { slot: 'left-top' },
568
+ desktop: { slot: 'left-top' }
566
569
  })
567
570
  ```
568
571
 
@@ -3,9 +3,12 @@
3
3
  ## Installation
4
4
 
5
5
  ```shell
6
- npm i @defra/interactive-map
6
+ npm i @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).
11
+
9
12
  ### MapLibre provider (recommended)
10
13
 
11
14
  **ESM:** `maplibre-gl` is a peer dependency, install it separately: