@defra/interactive-map 0.0.31-alpha → 0.0.33-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/assets/images/bright-ofm-thumb.jpg +0 -0
- package/assets/images/dark-ofm-thumb.jpg +0 -0
- package/assets/images/road-ofm-thumb.jpg +0 -0
- package/assets/templates/add-polygons.njk +143 -0
- package/assets/templates/add-symbols.njk +119 -0
- package/assets/templates/{map.njk → basic-map.njk} +9 -17
- package/assets/templates/button-map.njk +56 -0
- package/assets/templates/draw-tools.njk +161 -0
- package/assets/templates/marker-panel.njk +91 -0
- package/assets/templates/place-marker.njk +104 -0
- package/assets/templates/search-control.njk +98 -0
- package/assets/templates/select-feature.njk +101 -0
- package/assets/templates/style-switcher.njk +87 -0
- package/assets/templates/toggle-marker-label.njk +74 -0
- 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/map-style-config.md +27 -3
- package/docs/api.md +55 -0
- package/docs/assets/css/docusaurus.scss +22 -6
- package/docs/assets/images/add-polygons.jpg +0 -0
- package/docs/assets/images/add-symbols.jpg +0 -0
- package/docs/assets/images/hero.png +0 -0
- package/docs/assets/images/place-marker.jpg +0 -0
- package/docs/assets/images/screenshot.jpg +0 -0
- package/docs/examples/add-marker-with-panel.mdx +1 -1
- package/docs/examples/add-polygons.mdx +225 -0
- package/docs/examples/add-symbols.mdx +177 -0
- package/docs/examples/{draw.mdx → draw-tools.mdx} +2 -2
- package/docs/examples/index.mdx +38 -2
- package/docs/examples/place-marker.mdx +151 -0
- package/docs/plugins/datasets.md +144 -96
- package/docs/plugins/interact.md +1 -4
- package/docusaurus.config.cjs +5 -2
- package/govuk-prototype-kit.config.json +52 -2
- package/package.json +1 -1
- package/plugins/beta/datasets/dist/css/index.css +1 -2
- package/plugins/beta/datasets/dist/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/im-datasets-ml-adapter.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/adapters/maplibre/registry/mapLibreDataset.js +27 -9
- package/plugins/beta/datasets/src/adapters/maplibre/registry/mapLibreDataset.test.js +46 -4
- package/plugins/beta/datasets/src/api/setFeatureVisibility.js +10 -1
- package/plugins/beta/datasets/src/api/setFeatureVisibility.test.js +48 -6
- package/plugins/beta/datasets/src/components/LayersMenu/Layers.module.scss +12 -12
- package/plugins/beta/datasets/src/reducers/datasetsToMenu.js +11 -6
- package/plugins/beta/datasets/src/reducers/datasetsToMenu.test.js +49 -0
- package/plugins/beta/datasets/src/reducers/mappedDatasetsReducer.js +8 -1
- package/plugins/beta/datasets/src/reducers/pluginState.js +1 -1
- package/plugins/beta/datasets/src/registry/dataset.js +7 -3
- package/plugins/beta/datasets/src/registry/dataset.test.js +14 -0
- package/plugins/beta/datasets/src/registry/dynamicGeoJson.js +1 -1
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-es/src/api/addFeature.js +12 -3
- package/plugins/beta/draw-es/src/events.js +8 -3
- package/plugins/beta/draw-es/src/events.test.js +2 -0
- package/plugins/beta/draw-es/src/graphic.js +26 -2
- 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/src/DrawInit.jsx +19 -0
- package/plugins/beta/draw-ml/src/api/newLine.js +1 -0
- package/plugins/beta/draw-ml/src/api/newPolygon.js +1 -0
- package/plugins/beta/draw-ml/src/modes/createDrawMode.js +52 -37
- package/plugins/beta/draw-ml/src/modes/editVertex/touchHandlers.js +1 -1
- package/plugins/beta/draw-ml/src/modes/editVertex/vertexOperations.js +5 -4
- package/plugins/beta/draw-ml/src/modes/editVertexMode.js +53 -21
- package/plugins/beta/draw-ol/dist/esm/DrawMode.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/EditMode.js +1 -1
- package/plugins/beta/draw-ol/dist/esm/im-draw-ol-plugin.js +1 -1
- package/plugins/beta/draw-ol/src/core/OLDrawManager.js +3 -0
- package/plugins/beta/draw-ol/src/draw/DrawMode.js +57 -49
- package/plugins/beta/draw-ol/src/draw/drawInput.js +76 -32
- package/plugins/beta/draw-ol/src/edit/EditMode.js +4 -4
- package/plugins/beta/draw-ol/src/edit/keyboardHandler.js +4 -2
- package/plugins/beta/draw-ol/src/manifest.js +5 -1
- package/plugins/beta/draw-ol/src/reducer.js +1 -1
- package/plugins/beta/draw-ol/src/snap/snapEngine.js +75 -31
- package/plugins/beta/draw-ol/src/snap/snapGeometry.js +23 -46
- package/plugins/beta/draw-ol/src/snap/snapInteraction.js +30 -29
- package/plugins/beta/draw-ol/src/snap/snapManager.js +10 -1
- package/plugins/beta/draw-ol/src/utils/geometryHelpers.js +9 -3
- package/plugins/beta/draw-ol/src/utils/olCoords.js +2 -2
- package/plugins/beta/draw-ol/src/utils/spatial.js +4 -8
- package/plugins/beta/map-styles/src/mapStyles.scss +41 -41
- 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 +1 -3
- package/plugins/interact/src/InteractInit.test.js +0 -2
- package/plugins/interact/src/events.test.js +1 -1
- package/plugins/interact/src/hooks/useCrossHairVisibility.js +4 -10
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +5 -10
- package/plugins/interact/src/hooks/useHighlightSync.js +1 -10
- package/plugins/interact/src/hooks/useHighlightSync.test.js +2 -21
- package/plugins/interact/src/hooks/useInteractionHandlers.js +5 -11
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +5 -25
- package/plugins/interact/src/reducer.js +4 -22
- package/plugins/interact/src/reducer.test.js +11 -39
- package/plugins/search/dist/css/index.css +5 -2
- package/plugins/search/src/components/Form/Form.module.scss +5 -2
- package/plugins/search/src/search.scss +4 -4
- package/providers/beta/openlayers/dist/esm/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/im-openlayers-provider.js +1 -1
- package/providers/beta/openlayers/dist/umd/index.js +1 -1
- package/providers/beta/openlayers/src/utils/tileLayers.js +29 -2
- package/providers/beta/openlayers/src/utils/tileLayers.test.js +53 -1
- package/src/App/components/CrossHair/CrossHair.module.scss +8 -8
- package/src/App/components/MapButton/MapButton.jsx +14 -10
- package/src/App/components/MapButton/MapButton.module.scss +1 -1
- package/src/App/components/MapButton/MapButton.test.jsx +1 -1
- package/src/App/components/PopupMenu/PopupMenu.test.jsx +79 -0
- package/src/App/components/PopupMenu/usePopupMenu.js +61 -12
- package/src/App/hooks/useLayoutMeasurements.js +10 -2
- package/src/App/hooks/useResizeObserver.js +4 -2
- package/src/InteractiveMap/InteractiveMap.js +4 -4
- package/src/InteractiveMap/InteractiveMap.test.js +3 -3
- package/src/InteractiveMap/behaviourController.js +3 -1
- package/src/InteractiveMap/behaviourController.test.js +6 -3
- package/src/InteractiveMap/domStateManager.js +2 -0
- package/src/config/events.js +21 -3
- package/src/types.js +12 -3
- package/src/utils/findNextTabStop.js +3 -3
- package/src/utils/findNextTabStop.test.js +25 -1
- package/webpack.dev.mjs +1 -0
- package/docs/assets/images/screens-blue.jpg +0 -0
- package/docs/assets/images/screens-white.jpg +0 -0
|
@@ -7,7 +7,7 @@ import * as queryString from '../utils/queryString.js'
|
|
|
7
7
|
import { updateDOMState } from './domStateManager.js'
|
|
8
8
|
|
|
9
9
|
jest.mock('../utils/queryString.js')
|
|
10
|
-
jest.mock('./domStateManager.js', () => ({ updateDOMState: jest.fn() }))
|
|
10
|
+
jest.mock('./domStateManager.js', () => ({ updateDOMState: jest.fn().mockReturnValue({ isFullscreen: false }) }))
|
|
11
11
|
|
|
12
12
|
describe('shouldLoadComponent', () => {
|
|
13
13
|
beforeEach(() => {
|
|
@@ -67,7 +67,8 @@ describe('setupBehavior', () => {
|
|
|
67
67
|
loadApp: jest.fn(),
|
|
68
68
|
removeApp: jest.fn(),
|
|
69
69
|
hideApp: jest.fn(),
|
|
70
|
-
showApp: jest.fn()
|
|
70
|
+
showApp: jest.fn(),
|
|
71
|
+
eventBus: { emit: jest.fn() }
|
|
71
72
|
}
|
|
72
73
|
// Default: viewport is wide
|
|
73
74
|
window.matchMedia = jest.fn().mockImplementation(() => ({
|
|
@@ -187,14 +188,16 @@ describe('setupBehavior', () => {
|
|
|
187
188
|
expect(mockMapInstance.showApp).not.toHaveBeenCalled()
|
|
188
189
|
})
|
|
189
190
|
|
|
190
|
-
it('calls updateDOMState when map is showing and should load', () => {
|
|
191
|
+
it('calls updateDOMState and emits APP_FULLSCREEN_CHANGE when map is showing and should load', () => {
|
|
191
192
|
mockMapInstance._isHidden = false
|
|
192
193
|
mockMapInstance._root = {} // has root
|
|
193
194
|
queryString.getQueryParam.mockReturnValue(null)
|
|
195
|
+
updateDOMState.mockReturnValue({ isFullscreen: false })
|
|
194
196
|
|
|
195
197
|
handleChange()
|
|
196
198
|
|
|
197
199
|
expect(updateDOMState).toHaveBeenCalledWith(mockMapInstance)
|
|
200
|
+
expect(mockMapInstance.eventBus.emit).toHaveBeenCalledWith('app:fullscreenchange', { isFullscreen: false })
|
|
198
201
|
expect(mockMapInstance.loadApp).not.toHaveBeenCalled()
|
|
199
202
|
expect(mockMapInstance.showApp).not.toHaveBeenCalled()
|
|
200
203
|
})
|
package/src/config/events.js
CHANGED
|
@@ -69,11 +69,13 @@ export const EVENTS = {
|
|
|
69
69
|
* Fired after initial load (`loadApp`) and when the app is shown again after being hidden (`showApp`).
|
|
70
70
|
* Subscribe to this event to react whenever the map becomes visible to the user.
|
|
71
71
|
*
|
|
72
|
-
* Payload:
|
|
72
|
+
* Payload:
|
|
73
|
+
* - `statePreserved: boolean` — `true` if the map state was preserved from a previous session.
|
|
74
|
+
* - `isFullscreen: boolean` — `true` if the map opened in fullscreen mode, `false` if inline.
|
|
73
75
|
*
|
|
74
76
|
* @example
|
|
75
|
-
* map.on(EVENTS.APP_OPENED, ({ statePreserved }) => {
|
|
76
|
-
* console.log('Map opened, state preserved:', statePreserved)
|
|
77
|
+
* map.on(EVENTS.APP_OPENED, ({ isFullscreen, statePreserved }) => {
|
|
78
|
+
* console.log('Map opened, fullscreen:', isFullscreen, 'state preserved:', statePreserved)
|
|
77
79
|
* })
|
|
78
80
|
*/
|
|
79
81
|
APP_OPENED: 'app:opened',
|
|
@@ -93,6 +95,22 @@ export const EVENTS = {
|
|
|
93
95
|
*/
|
|
94
96
|
APP_CLOSED: 'app:closed',
|
|
95
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Emitted when the map transitions between fullscreen and inline display while already visible.
|
|
100
|
+
*
|
|
101
|
+
* Fired during viewport resize in `hybrid` behaviour when the map crosses the fullscreen/inline
|
|
102
|
+
* threshold without being hidden and re-shown. Use this alongside `app:opened` and `app:closed`
|
|
103
|
+
* to track the map's display mode across all transitions.
|
|
104
|
+
*
|
|
105
|
+
* Payload: `{ isFullscreen: boolean }` — `true` if the map is now fullscreen, `false` if inline.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* map.on(EVENTS.APP_FULLSCREEN_CHANGE, ({ isFullscreen }) => {
|
|
109
|
+
* console.log('Display mode changed, fullscreen:', isFullscreen)
|
|
110
|
+
* })
|
|
111
|
+
*/
|
|
112
|
+
APP_FULLSCREEN_CHANGE: 'app:fullscreenchange',
|
|
113
|
+
|
|
96
114
|
/**
|
|
97
115
|
* Emitted when a panel is opened.
|
|
98
116
|
* Payload: { panelId: string }
|
package/src/types.js
CHANGED
|
@@ -403,18 +403,27 @@
|
|
|
403
403
|
* Falls back to `#0b0c0c` (light) or `#ffffff` (dark).
|
|
404
404
|
* Injected as the `--map-overlay-foreground-color` CSS custom property.
|
|
405
405
|
*
|
|
406
|
-
* @property {'raster' | 'ogc-vt'} [type]
|
|
406
|
+
* @property {'vector' | 'raster' | 'wms' | 'ogc-vt'} [type]
|
|
407
407
|
* Tile layer type. Controls how the map provider constructs the basemap source. Omit (or leave
|
|
408
408
|
* undefined) for the default Mapbox GL vector tile path. The OpenLayers provider supports all
|
|
409
|
-
*
|
|
409
|
+
* four types, enabling raster, WMS, standard vector tile, and OGC vector tile basemaps:
|
|
410
410
|
* - `'raster'` — XYZ raster tile source; `url` should be a tile URL template.
|
|
411
|
+
* - `'vector'` — Mapbox GL vector tile path; `url` should point to a Mapbox GL style document.
|
|
412
|
+
* - `'wms'` — WMS raster tile source; `url` should be the WMS service endpoint and `params`
|
|
413
|
+
* should provide the WMS request parameters.
|
|
414
|
+
* **Currently only supported by the OpenLayers provider.**
|
|
411
415
|
* - `'ogc-vt'` — OGC API - Tiles vector tile source; `url` should point to an OGC style endpoint
|
|
412
416
|
* that returns a Mapbox GL style document. **Currently only supported by the OpenLayers provider.**
|
|
413
417
|
*
|
|
414
418
|
* @property {string} url
|
|
415
419
|
* URL for the style. For the default vector tile path and `'ogc-vt'`, this should be a URL that
|
|
416
420
|
* returns a Mapbox GL style document (Mapbox Style Specification). For `'raster'`, this should
|
|
417
|
-
* be an XYZ tile URL template with `{x}`, `{y}`, `{z}` placeholders.
|
|
421
|
+
* be an XYZ tile URL template with `{x}`, `{y}`, `{z}` placeholders. For `'wms'`, this should
|
|
422
|
+
* be the WMS service endpoint (the GetMap URL).
|
|
423
|
+
*
|
|
424
|
+
* @property {Object} [params]
|
|
425
|
+
* WMS request parameters. Passed directly to the OpenLayers `TileWMS` source when `type` is `'wms'`.
|
|
426
|
+
* Most WMS GetMap requests should include `LAYERS`. Example: `{ LAYERS: 'MyLayer', FORMAT: 'image/jpeg' }`.
|
|
418
427
|
*/
|
|
419
428
|
|
|
420
429
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export function findTabStop ({ el, direction }) {
|
|
2
|
-
const focusableEls =
|
|
1
|
+
export function findTabStop ({ el, direction, root = document }) {
|
|
2
|
+
const focusableEls = root.querySelectorAll('input, button, select, textarea, a[href]')
|
|
3
3
|
const list = Array.prototype.filter.call(focusableEls, item => {
|
|
4
|
-
return item.tabIndex >= 0
|
|
4
|
+
return item.tabIndex >= 0 && !!item.offsetParent
|
|
5
5
|
})
|
|
6
6
|
const index = list.indexOf(el)
|
|
7
7
|
return list[direction === 'next' ? index + 1 : index - 1] || list[0]
|
|
@@ -7,9 +7,10 @@ import { findTabStop } from './findNextTabStop.js'
|
|
|
7
7
|
// --- MOCK SETUP ---
|
|
8
8
|
// Helper to create mock elements. The default value (tabIndex = 0)
|
|
9
9
|
// is covered below by creating 'el1' without the second argument.
|
|
10
|
-
const createMockElement = (id, tabIndex = 0) => ({
|
|
10
|
+
const createMockElement = (id, tabIndex = 0, offsetParent = {}) => ({
|
|
11
11
|
id,
|
|
12
12
|
tabIndex,
|
|
13
|
+
offsetParent,
|
|
13
14
|
// Required so Jest knows which element is which in the array lookup
|
|
14
15
|
toString: () => id
|
|
15
16
|
})
|
|
@@ -74,4 +75,27 @@ describe('findTabStop', () => {
|
|
|
74
75
|
// Assert: It wraps around to the first element, el1.
|
|
75
76
|
expect(result).toBe(el1)
|
|
76
77
|
})
|
|
78
|
+
|
|
79
|
+
// Test 4: Covers: skipping elements with no offsetParent (hidden, e.g. wrong-breakpoint duplicates).
|
|
80
|
+
it('should skip hidden elements (no offsetParent) even when tabIndex is valid', () => {
|
|
81
|
+
const el1 = createMockElement('el1', 0)
|
|
82
|
+
const hiddenEl = createMockElement('hidden', 0, null)
|
|
83
|
+
const el3 = createMockElement('el3', 0)
|
|
84
|
+
|
|
85
|
+
mockFocusableElements([el1, hiddenEl, el3])
|
|
86
|
+
|
|
87
|
+
const result = findTabStop({ el: el1, direction: 'next' })
|
|
88
|
+
|
|
89
|
+
expect(result).toBe(el3)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('accepts a custom root to scope the search', () => {
|
|
93
|
+
const el1 = createMockElement('el1')
|
|
94
|
+
const scopedRoot = { querySelectorAll: jest.fn(() => [el1]) }
|
|
95
|
+
|
|
96
|
+
findTabStop({ el: el1, direction: 'next', root: scopedRoot })
|
|
97
|
+
|
|
98
|
+
expect(scopedRoot.querySelectorAll).toHaveBeenCalledTimes(1)
|
|
99
|
+
expect(document.querySelectorAll).not.toHaveBeenCalled()
|
|
100
|
+
})
|
|
77
101
|
})
|
package/webpack.dev.mjs
CHANGED
|
@@ -87,6 +87,7 @@ export default {
|
|
|
87
87
|
NGD_BLACK_AND_WHITE_URL_27700: JSON.stringify(process.env.NGD_BLACK_AND_WHITE_URL_27700),
|
|
88
88
|
// Aerial photography
|
|
89
89
|
AERIAL_URL: JSON.stringify(process.env.AERIAL_URL),
|
|
90
|
+
APGB_WMS_URL: JSON.stringify(process.env.APGB_WMS_URL),
|
|
90
91
|
// OS Maps API (27700 raster)
|
|
91
92
|
MAPS_OUTDOOR_URL: JSON.stringify(process.env.MAPS_OUTDOOR_URL),
|
|
92
93
|
MAPS_ROAD_URL: JSON.stringify(process.env.MAPS_ROAD_URL),
|
|
Binary file
|
|
Binary file
|