@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.
- package/assets/images/slot-map.svg +264 -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/context.md +53 -7
- package/docs/api/map-style-config.md +41 -2
- package/docs/api/marker-config.md +53 -11
- package/docs/api/slots.md +16 -15
- package/docs/api/symbol-config.md +160 -0
- package/docs/api/symbol-registry.md +115 -0
- package/docs/api.md +25 -22
- package/docs/getting-started.md +4 -1
- package/docs/plugins/datasets.md +657 -0
- package/docs/plugins/interact.md +68 -43
- package/docs/plugins/search.md +15 -3
- package/docs/plugins.md +1 -1
- package/package.json +2 -2
- package/plugins/beta/datasets/dist/css/index.css +103 -15
- 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 +29 -9
- package/plugins/beta/datasets/src/adapters/maplibre/index.js +18 -0
- package/plugins/beta/datasets/src/adapters/maplibre/layerBuilders.js +159 -0
- package/plugins/beta/datasets/src/adapters/maplibre/layerIds.js +75 -0
- package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +440 -0
- 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 +2 -8
- package/plugins/beta/datasets/src/api/getOpacity.js +17 -0
- package/plugins/beta/datasets/src/api/getStyle.js +13 -0
- package/plugins/beta/datasets/src/api/removeDataset.js +2 -44
- package/plugins/beta/datasets/src/api/setData.js +10 -0
- package/plugins/beta/datasets/src/api/setDatasetVisibility.js +37 -0
- package/plugins/beta/datasets/src/api/setFeatureVisibility.js +22 -0
- package/plugins/beta/datasets/src/api/setOpacity.js +29 -0
- package/plugins/beta/datasets/src/api/setStyle.js +22 -0
- 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 +39 -56
- package/plugins/beta/datasets/src/defaults.js +44 -8
- package/plugins/beta/datasets/src/fetch/createDynamicSource.js +34 -25
- package/plugins/beta/datasets/src/fetch/fetchGeoJSON.js +2 -2
- package/plugins/beta/datasets/src/index.js +2 -1
- package/plugins/beta/datasets/src/manifest.js +25 -17
- package/plugins/beta/datasets/src/panels/Key.jsx +51 -51
- package/plugins/beta/datasets/src/panels/Key.module.scss +59 -9
- package/plugins/beta/datasets/src/panels/Layers.jsx +132 -29
- package/plugins/beta/datasets/src/panels/Layers.module.scss +56 -8
- package/plugins/beta/datasets/src/reducer.js +134 -9
- package/plugins/beta/datasets/src/reducers/keyReducer.js +34 -0
- package/plugins/beta/datasets/src/utils/bbox.js +7 -5
- package/plugins/beta/datasets/src/utils/filters.js +5 -2
- package/plugins/beta/datasets/src/utils/mergeSublayer.js +86 -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 +21 -1
- 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/draw-ml/src/draw.scss +0 -7
- package/plugins/beta/draw-ml/src/manifest.js +16 -16
- package/plugins/beta/frame/dist/esm/im-frame-plugin.js +1 -1
- package/plugins/beta/frame/dist/umd/im-frame-plugin.js +1 -1
- package/plugins/beta/frame/src/Frame.jsx +5 -5
- 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/map-styles/src/manifest.js +1 -1
- package/plugins/beta/scale-bar/dist/css/index.css +1 -1
- package/plugins/beta/scale-bar/dist/esm/im-scale-bar-plugin.js +1 -1
- package/plugins/beta/scale-bar/dist/umd/im-scale-bar-plugin.js +1 -1
- package/plugins/beta/scale-bar/src/index.test.js +3 -3
- package/plugins/beta/scale-bar/src/manifest.js +3 -3
- package/plugins/beta/scale-bar/src/scaleBar.scss +2 -1
- package/plugins/interact/dist/css/index.css +1 -1
- 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 +14 -5
- package/plugins/interact/src/InteractInit.test.js +26 -6
- package/plugins/interact/src/api/enable.test.js +7 -7
- package/plugins/interact/src/defaults.js +4 -6
- package/plugins/interact/src/events.js +9 -6
- package/plugins/interact/src/events.test.js +28 -4
- 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/interact.scss +0 -7
- package/plugins/interact/src/manifest.js +14 -18
- package/plugins/interact/src/manifest.test.js +3 -1
- package/plugins/interact/src/reducer.js +23 -4
- package/plugins/interact/src/reducer.test.js +60 -11
- 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/search/dist/css/index.css +1 -1
- 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/components/Form/Form.module.scss +2 -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-framework.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-framework.js.LICENSE.txt +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 +37 -7
- package/providers/maplibre/src/utils/highlightFeatures.test.js +153 -95
- 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/Actions/Actions.jsx +2 -2
- package/src/App/components/Actions/Actions.module.scss +0 -7
- package/src/App/components/Actions/Actions.test.jsx +1 -1
- package/src/App/components/Icon/Icon.jsx +3 -2
- package/src/App/components/Icon/Icon.module.scss +4 -0
- package/src/App/components/Icon/Icon.test.jsx +43 -4
- package/src/App/components/MapButton/MapButton.jsx +42 -17
- package/src/App/components/MapButton/MapButton.module.scss +4 -13
- package/src/App/components/MapButton/MapButton.test.jsx +27 -3
- 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/PopupMenu/PopupMenu.jsx +51 -274
- package/src/App/components/PopupMenu/PopupMenu.module.scss +14 -7
- package/src/App/components/PopupMenu/PopupMenu.test.jsx +70 -1
- package/src/App/components/PopupMenu/usePopupMenu.js +258 -0
- package/src/App/hooks/useButtonStateEvaluator.js +12 -2
- package/src/App/hooks/useButtonStateEvaluator.test.js +38 -4
- package/src/App/hooks/useInterfaceAPI.js +6 -0
- package/src/App/hooks/useInterfaceAPI.test.js +156 -0
- package/src/App/hooks/useLayoutMeasurements.js +84 -18
- package/src/App/hooks/useLayoutMeasurements.test.js +124 -17
- package/src/App/hooks/useMarkersAPI.js +2 -5
- package/src/App/hooks/useMarkersAPI.test.js +4 -4
- package/src/App/layout/Layout.jsx +14 -9
- package/src/App/layout/Layout.test.jsx +6 -4
- package/src/App/layout/layout.module.scss +67 -29
- package/src/App/registry/pluginRegistry.js +1 -1
- package/src/App/renderer/HtmlElementHost.jsx +2 -1
- package/src/App/renderer/HtmlElementHost.test.jsx +7 -7
- package/src/App/renderer/mapButtons.js +1 -1
- package/src/App/renderer/mapPanels.test.js +2 -2
- package/src/App/renderer/slotHelpers.js +2 -2
- package/src/App/renderer/slotHelpers.test.js +5 -5
- package/src/App/renderer/slots.js +9 -5
- package/src/App/store/AppProvider.jsx +3 -1
- package/src/App/store/AppProvider.test.jsx +1 -1
- package/src/App/store/ServiceProvider.jsx +8 -4
- package/src/App/store/appActionsMap.js +16 -0
- package/src/App/store/appActionsMap.test.js +27 -0
- package/src/App/store/appDispatchMiddleware.js +1 -1
- package/src/App/store/appDispatchMiddleware.test.js +2 -2
- package/src/App/store/appReducer.js +2 -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 +4 -0
- package/src/config/appConfig.js +5 -8
- package/src/config/appConfig.test.js +1 -2
- package/src/config/defaults.js +0 -2
- package/src/config/events.js +28 -0
- package/src/config/mapTheme.js +56 -0
- package/src/config/patternConfig.js +16 -0
- package/src/config/symbolConfig.js +80 -0
- package/src/scss/main.scss +1 -0
- package/src/scss/settings/_colors.scss +0 -9
- package/src/scss/settings/_dimensions.scss +0 -1
- 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 +93 -11
- package/src/utils/getSafeZoneInset.js +9 -7
- package/src/utils/getSafeZoneInset.test.js +10 -10
- 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/webpack.dev.mjs +1 -1
- package/docs/api/slot-map.svg +0 -1
- package/plugins/beta/datasets/src/api/hideDataset.js +0 -14
- package/plugins/beta/datasets/src/api/hideFeatures.js +0 -41
- package/plugins/beta/datasets/src/api/showDataset.js +0 -14
- package/plugins/beta/datasets/src/api/showFeatures.js +0 -44
- package/plugins/beta/datasets/src/handleSetMapStyle.js +0 -54
- package/plugins/beta/datasets/src/mapLayers.js +0 -164
- /package/src/{utils → services}/logger.js +0 -0
- /package/src/{utils → services}/logger.test.js +0 -0
|
@@ -3,12 +3,15 @@ import { initialState, actions } from './reducer.js'
|
|
|
3
3
|
import { DatasetsInit } from './DatasetsInit.jsx'
|
|
4
4
|
import { Layers } from './panels/Layers.jsx'
|
|
5
5
|
import { Key } from './panels/Key.jsx'
|
|
6
|
-
import { showDataset } from './api/showDataset.js'
|
|
7
|
-
import { hideDataset } from './api/hideDataset.js'
|
|
8
6
|
import { addDataset } from './api/addDataset.js'
|
|
9
7
|
import { removeDataset } from './api/removeDataset.js'
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
8
|
+
import { setDatasetVisibility } from './api/setDatasetVisibility.js'
|
|
9
|
+
import { setFeatureVisibility } from './api/setFeatureVisibility.js'
|
|
10
|
+
import { setStyle } from './api/setStyle.js'
|
|
11
|
+
import { getStyle } from './api/getStyle.js'
|
|
12
|
+
import { setOpacity } from './api/setOpacity.js'
|
|
13
|
+
import { getOpacity } from './api/getOpacity.js'
|
|
14
|
+
import { setData } from './api/setData.js'
|
|
12
15
|
|
|
13
16
|
export const manifest = {
|
|
14
17
|
InitComponent: DatasetsInit,
|
|
@@ -22,7 +25,7 @@ export const manifest = {
|
|
|
22
25
|
id: 'datasetsLayers',
|
|
23
26
|
label: 'Layers',
|
|
24
27
|
mobile: {
|
|
25
|
-
slot: '
|
|
28
|
+
slot: 'drawer',
|
|
26
29
|
modal: true,
|
|
27
30
|
dismissible: true
|
|
28
31
|
},
|
|
@@ -30,30 +33,30 @@ export const manifest = {
|
|
|
30
33
|
slot: 'left-top',
|
|
31
34
|
dismissible: true,
|
|
32
35
|
exclusive: true,
|
|
33
|
-
width: '
|
|
36
|
+
width: '260px'
|
|
34
37
|
},
|
|
35
38
|
desktop: {
|
|
36
39
|
slot: 'left-top',
|
|
37
40
|
modal: false,
|
|
38
41
|
dismissible: true,
|
|
39
42
|
exclusive: true,
|
|
40
|
-
width: '
|
|
43
|
+
width: '280px'
|
|
41
44
|
},
|
|
42
45
|
render: Layers
|
|
43
46
|
}, {
|
|
44
47
|
id: 'datasetsKey',
|
|
45
48
|
label: 'Key',
|
|
46
49
|
mobile: {
|
|
47
|
-
slot: '
|
|
50
|
+
slot: 'drawer',
|
|
48
51
|
modal: true
|
|
49
52
|
},
|
|
50
53
|
tablet: {
|
|
51
54
|
slot: 'left-top',
|
|
52
|
-
width: '
|
|
55
|
+
width: '260px'
|
|
53
56
|
},
|
|
54
57
|
desktop: {
|
|
55
58
|
slot: 'left-top',
|
|
56
|
-
width: '
|
|
59
|
+
width: '280px'
|
|
57
60
|
},
|
|
58
61
|
render: Key
|
|
59
62
|
}],
|
|
@@ -63,7 +66,9 @@ export const manifest = {
|
|
|
63
66
|
label: 'Layers',
|
|
64
67
|
panelId: 'datasetsLayers',
|
|
65
68
|
iconId: 'layers',
|
|
66
|
-
excludeWhen: ({ pluginConfig }) => !pluginConfig.datasets.
|
|
69
|
+
excludeWhen: ({ pluginConfig }) => !pluginConfig.datasets.some(l =>
|
|
70
|
+
l.toggleVisibility || l.sublayers?.some(r => r.toggleVisibility)
|
|
71
|
+
),
|
|
67
72
|
mobile: {
|
|
68
73
|
slot: 'top-left',
|
|
69
74
|
showLabel: true
|
|
@@ -81,7 +86,7 @@ export const manifest = {
|
|
|
81
86
|
label: 'Key',
|
|
82
87
|
panelId: 'datasetsKey',
|
|
83
88
|
iconId: 'key',
|
|
84
|
-
excludeWhen: ({ pluginConfig }) => !pluginConfig.datasets.
|
|
89
|
+
excludeWhen: ({ pluginConfig }) => !pluginConfig.datasets.some(l => l.showInKey),
|
|
85
90
|
mobile: {
|
|
86
91
|
slot: 'top-left',
|
|
87
92
|
showLabel: false
|
|
@@ -98,18 +103,21 @@ export const manifest = {
|
|
|
98
103
|
|
|
99
104
|
icons: [{
|
|
100
105
|
id: 'layers',
|
|
101
|
-
svgContent: '<path d="
|
|
106
|
+
svgContent: '<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"></path><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"></path><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"></path>'
|
|
102
107
|
}, {
|
|
103
108
|
id: 'key',
|
|
104
109
|
svgContent: '<path d="M3 5h.01"/><path d="M3 12h.01"/><path d="M3 19h.01"/><path d="M8 5h13"/><path d="M8 12h13"/><path d="M8 19h13"/>'
|
|
105
110
|
}],
|
|
106
111
|
|
|
107
112
|
api: {
|
|
108
|
-
showDataset,
|
|
109
|
-
hideDataset,
|
|
110
113
|
addDataset,
|
|
111
114
|
removeDataset,
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
setDatasetVisibility,
|
|
116
|
+
setFeatureVisibility,
|
|
117
|
+
setStyle,
|
|
118
|
+
getStyle,
|
|
119
|
+
setOpacity,
|
|
120
|
+
getOpacity,
|
|
121
|
+
setData
|
|
114
122
|
}
|
|
115
123
|
}
|
|
@@ -1,62 +1,62 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { getValueForStyle } from '../../../../../src/utils/getValueForStyle'
|
|
3
|
+
import { mergeSublayer } from '../utils/mergeSublayer.js'
|
|
4
|
+
import { EmptyKey } from '../components/EmptyKey.jsx'
|
|
5
|
+
import { KeySvg } from '../components/KeySvg.jsx'
|
|
3
6
|
|
|
4
|
-
export const Key = ({ mapState, pluginState }) => {
|
|
7
|
+
export const Key = ({ pluginConfig, mapState, pluginState, services }) => {
|
|
8
|
+
if (!pluginState?.key?.items?.length) {
|
|
9
|
+
return (<EmptyKey text={pluginConfig.noKeyItemText} />)
|
|
10
|
+
}
|
|
5
11
|
const { mapStyle } = mapState
|
|
12
|
+
const { symbolRegistry, patternRegistry } = services
|
|
6
13
|
|
|
7
|
-
const
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
x2={20 - dataset.strokeWidth / 2}
|
|
22
|
-
y2='10'
|
|
23
|
-
stroke={getValueForStyle(dataset.stroke, mapStyle.id)}
|
|
24
|
-
strokeWidth={dataset.strokeWidth}
|
|
25
|
-
strokeLinecap='round'
|
|
26
|
-
/>
|
|
27
|
-
)
|
|
28
|
-
: (
|
|
29
|
-
<rect
|
|
30
|
-
x={dataset.strokeWidth / 2}
|
|
31
|
-
y={dataset.strokeWidth / 2}
|
|
32
|
-
width={20 - dataset.strokeWidth}
|
|
33
|
-
height={20 - dataset.strokeWidth}
|
|
34
|
-
rx={dataset.strokeWidth}
|
|
35
|
-
ry={dataset.strokeWidth}
|
|
36
|
-
fill={getValueForStyle(dataset.fill, mapStyle.id)}
|
|
37
|
-
stroke={getValueForStyle(dataset.stroke, mapStyle.id)}
|
|
38
|
-
strokeWidth={dataset.strokeWidth}
|
|
39
|
-
strokeLinejoin='round'
|
|
40
|
-
/>
|
|
41
|
-
)}
|
|
42
|
-
</svg>
|
|
14
|
+
const renderEntry = (key, config) => (
|
|
15
|
+
<dl key={key} className='im-c-datasets-key__item'>
|
|
16
|
+
<dt className='im-c-datasets-key__item-symbol'>
|
|
17
|
+
<KeySvg {...config} symbolRegistry={symbolRegistry} patternRegistry={patternRegistry} mapStyle={mapStyle} />
|
|
18
|
+
</dt>
|
|
19
|
+
<dd className='im-c-datasets-key__item-label'>
|
|
20
|
+
{config.label}
|
|
21
|
+
{config.symbolDescription && (
|
|
22
|
+
<span className='govuk-visually-hidden'>
|
|
23
|
+
({getValueForStyle(config.symbolDescription, mapStyle.id)})
|
|
24
|
+
</span>
|
|
25
|
+
)}
|
|
26
|
+
</dd>
|
|
27
|
+
</dl>
|
|
43
28
|
)
|
|
44
29
|
|
|
30
|
+
const { items: keyGroups, hasGroups } = pluginState.key
|
|
31
|
+
const containerClass = `im-c-datasets-key${hasGroups ? ' im-c-datasets-key--has-groups' : ''}`
|
|
32
|
+
|
|
45
33
|
return (
|
|
46
|
-
<div className=
|
|
47
|
-
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{dataset.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
34
|
+
<div className={containerClass}>
|
|
35
|
+
{keyGroups.map(item => {
|
|
36
|
+
if (item.type === 'sublayers') {
|
|
37
|
+
const headingId = `key-heading-${item.dataset.id}`
|
|
38
|
+
return (
|
|
39
|
+
<section key={item.dataset.id} className='im-c-datasets-key__group' aria-labelledby={headingId}>
|
|
40
|
+
<h3 id={headingId} className='im-c-datasets-key__group-heading'>{item.dataset.label}</h3>
|
|
41
|
+
{item.dataset.sublayers
|
|
42
|
+
.filter(sublayer => item.dataset.sublayerVisibility?.[sublayer.id] !== 'hidden')
|
|
43
|
+
.map(sublayer => renderEntry(`${item.dataset.id}-${sublayer.id}`, mergeSublayer(item.dataset, sublayer)))}
|
|
44
|
+
</section>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (item.type === 'group') {
|
|
49
|
+
const headingId = `key-heading-${item.groupLabel.toLowerCase().replaceAll(/\s+/g, '-')}`
|
|
50
|
+
return (
|
|
51
|
+
<section key={item.groupLabel} className='im-c-datasets-key__group' aria-labelledby={headingId}>
|
|
52
|
+
<h3 id={headingId} className='im-c-datasets-key__group-heading'>{item.groupLabel}</h3>
|
|
53
|
+
{item.datasets.map(dataset => renderEntry(dataset.id, dataset))}
|
|
54
|
+
</section>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return renderEntry(item.dataset.id, item.dataset)
|
|
59
|
+
})}
|
|
60
60
|
</div>
|
|
61
61
|
)
|
|
62
62
|
}
|
|
@@ -1,19 +1,69 @@
|
|
|
1
|
-
|
|
1
|
+
// When groups are present, every direct child gets a border-top
|
|
2
|
+
.im-c-datasets-key > *:first-child {
|
|
3
|
+
padding-top: 5px;
|
|
2
4
|
|
|
5
|
+
.im-c-datasets-key__group-heading {
|
|
6
|
+
padding-top: 0;
|
|
7
|
+
}
|
|
3
8
|
}
|
|
4
9
|
|
|
5
|
-
.im-c-datasets-
|
|
10
|
+
.im-c-datasets-key--has-groups > *:not(:first-child) {
|
|
11
|
+
border-top: 1px solid var(--button-hover-color);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.im-c-datasets-key__group:not(:last-child) {
|
|
15
|
+
padding-bottom: 5px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.im-c-datasets-key__group-heading {
|
|
19
|
+
padding-top: 15px;
|
|
20
|
+
padding-bottom: 10px;
|
|
21
|
+
margin: 0;
|
|
22
|
+
font-size: 1rem;
|
|
23
|
+
font-weight: bold;
|
|
24
|
+
color: var(--foreground-color);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.im-c-datasets-key__item {
|
|
6
28
|
display: flex;
|
|
7
29
|
align-items: start;
|
|
8
|
-
padding-top:
|
|
9
|
-
padding-bottom:
|
|
10
|
-
align-self: auto;
|
|
30
|
+
padding-top: 10px;
|
|
31
|
+
padding-bottom: 10px;
|
|
11
32
|
font-size: 1rem;
|
|
12
|
-
|
|
33
|
+
|
|
34
|
+
// First item inside a group — heading already provides top spacing
|
|
35
|
+
.im-c-datasets-key__group &:first-child {
|
|
36
|
+
padding-top: 0;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.im-c-datasets-key--has-groups > .im-c-datasets-key__item:not(:first-child) {
|
|
41
|
+
padding-top: 15px;
|
|
13
42
|
}
|
|
14
43
|
|
|
15
|
-
.im-c-datasets-
|
|
44
|
+
.im-c-datasets-key--has-groups > .im-c-datasets-key__item {
|
|
45
|
+
padding-bottom: 15px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.im-c-datasets-key__group .im-c-datasets-key__item {
|
|
49
|
+
padding-top: 10px;
|
|
50
|
+
padding-bottom: 10px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Last item in all scenarios — flat or inside the last group
|
|
54
|
+
.im-c-datasets-key > .im-c-datasets-key__item:last-child,
|
|
55
|
+
.im-c-datasets-key__group:last-child .im-c-datasets-key__item:last-child {
|
|
56
|
+
padding-bottom: 5px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Symbol
|
|
60
|
+
|
|
61
|
+
.am-c-datasets-key-symbol {
|
|
16
62
|
position: relative;
|
|
17
63
|
flex-shrink: 0;
|
|
18
|
-
margin:
|
|
19
|
-
}
|
|
64
|
+
margin: 0 13px 0 2px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.am-c-datasets-key-symbol--point {
|
|
68
|
+
margin: -9px 3px -9px -7px;
|
|
69
|
+
}
|
|
@@ -1,38 +1,141 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
3
|
-
import { hideDataset } from '../api/hideDataset'
|
|
2
|
+
import { setDatasetVisibility } from '../api/setDatasetVisibility'
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
const CHECKBOX_LABEL_CLASS = 'im-c-datasets-layers__item-label govuk-label govuk-checkboxes__label'
|
|
5
|
+
|
|
6
|
+
const hasToggleableSublayers = (dataset) => dataset.sublayers?.some(sublayer => sublayer.toggleVisibility)
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Collapse the filtered dataset list into ordered render items:
|
|
10
|
+
* { type: 'sublayers', dataset } — dataset with sublayers (takes precedence)
|
|
11
|
+
* { type: 'group', groupLabel, datasets } — datasets sharing a groupLabel
|
|
12
|
+
* { type: 'flat', dataset } — standalone dataset
|
|
13
|
+
*/
|
|
14
|
+
const buildRenderItems = (datasets) => {
|
|
15
|
+
const seenGroups = new Set()
|
|
16
|
+
const items = []
|
|
17
|
+
datasets.forEach(dataset => {
|
|
18
|
+
if (hasToggleableSublayers(dataset)) {
|
|
19
|
+
items.push({ type: 'sublayers', dataset })
|
|
20
|
+
return
|
|
12
21
|
}
|
|
22
|
+
if (dataset.groupLabel) {
|
|
23
|
+
if (seenGroups.has(dataset.groupLabel)) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
seenGroups.add(dataset.groupLabel)
|
|
27
|
+
items.push({
|
|
28
|
+
type: 'group',
|
|
29
|
+
groupLabel: dataset.groupLabel,
|
|
30
|
+
datasets: datasets.filter(d => !hasToggleableSublayers(d) && d.groupLabel === dataset.groupLabel)
|
|
31
|
+
})
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
items.push({ type: 'flat', dataset })
|
|
35
|
+
})
|
|
36
|
+
return items
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const Layers = ({ pluginState }) => {
|
|
40
|
+
const handleDatasetChange = (e) => {
|
|
41
|
+
const { value, checked } = e.target
|
|
42
|
+
setDatasetVisibility({ pluginState }, checked, { datasetId: value })
|
|
13
43
|
}
|
|
14
44
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
const handleSublayerChange = (e) => {
|
|
46
|
+
const { checked } = e.target
|
|
47
|
+
const datasetId = e.target.dataset.datasetId
|
|
48
|
+
const sublayerId = e.target.dataset.sublayerId
|
|
49
|
+
setDatasetVisibility({ pluginState }, checked, { datasetId, sublayerId })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const renderDatasetItem = (dataset) => {
|
|
53
|
+
const itemClass = `im-c-datasets-layers__item govuk-checkboxes govuk-checkboxes--small${dataset.visibility === 'hidden' ? '' : ' im-c-datasets-layers__item--checked'}`
|
|
54
|
+
return (
|
|
55
|
+
<div key={dataset.id} className={itemClass} data-module='govuk-checkboxes'>
|
|
56
|
+
<div className='govuk-checkboxes__item'>
|
|
57
|
+
<input
|
|
58
|
+
className='govuk-checkboxes__input'
|
|
59
|
+
id={dataset.id}
|
|
60
|
+
name='layers'
|
|
61
|
+
type='checkbox'
|
|
62
|
+
value={dataset.id}
|
|
63
|
+
checked={dataset.visibility !== 'hidden'}
|
|
64
|
+
onChange={handleDatasetChange}
|
|
65
|
+
/>
|
|
66
|
+
<label className={CHECKBOX_LABEL_CLASS} htmlFor={dataset.id}>
|
|
67
|
+
{dataset.label}
|
|
68
|
+
</label>
|
|
69
|
+
</div>
|
|
35
70
|
</div>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const visibleDatasets = (pluginState.datasets || [])
|
|
75
|
+
.filter(dataset => dataset.toggleVisibility || hasToggleableSublayers(dataset))
|
|
76
|
+
|
|
77
|
+
const renderItems = buildRenderItems(visibleDatasets)
|
|
78
|
+
const hasGroups = renderItems.some(item => item.type === 'sublayers' || item.type === 'group')
|
|
79
|
+
const containerClass = `im-c-datasets-layers${hasGroups ? ' im-c-datasets-layers--has-groups' : ''}`
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<div className={containerClass}>
|
|
83
|
+
{renderItems.map(item => {
|
|
84
|
+
if (item.type === 'sublayers') {
|
|
85
|
+
const { dataset } = item
|
|
86
|
+
const anySublayerChecked = dataset.sublayers
|
|
87
|
+
.filter(sublayer => sublayer.toggleVisibility)
|
|
88
|
+
.some(sublayer => dataset.sublayerVisibility?.[sublayer.id] !== 'hidden')
|
|
89
|
+
const wrapperClass = `govuk-form-group im-c-datasets-layers-group${anySublayerChecked ? ' im-c-datasets-layers-group--items-checked' : ''}`
|
|
90
|
+
return (
|
|
91
|
+
<div key={dataset.id} className={wrapperClass}>
|
|
92
|
+
<fieldset className='im-c-datasets-layers-group__fieldset'>
|
|
93
|
+
<legend className='im-c-datasets-layers-group__legend'>{dataset.label}</legend>
|
|
94
|
+
{dataset.sublayers
|
|
95
|
+
.filter(sublayer => sublayer.toggleVisibility)
|
|
96
|
+
.map(sublayer => {
|
|
97
|
+
const sublayerVisible = dataset.sublayerVisibility?.[sublayer.id] !== 'hidden'
|
|
98
|
+
const inputId = `${dataset.id}-${sublayer.id}`
|
|
99
|
+
const itemClass = `im-c-datasets-layers__item govuk-checkboxes govuk-checkboxes--small${sublayerVisible ? ' im-c-datasets-layers__item--checked' : ''}`
|
|
100
|
+
return (
|
|
101
|
+
<div key={sublayer.id} className={itemClass} data-module='govuk-checkboxes'>
|
|
102
|
+
<div className='govuk-checkboxes__item'>
|
|
103
|
+
<input
|
|
104
|
+
className='govuk-checkboxes__input'
|
|
105
|
+
id={inputId}
|
|
106
|
+
type='checkbox'
|
|
107
|
+
checked={sublayerVisible}
|
|
108
|
+
data-dataset-id={dataset.id}
|
|
109
|
+
data-sublayer-id={sublayer.id}
|
|
110
|
+
onChange={handleSublayerChange}
|
|
111
|
+
/>
|
|
112
|
+
<label className={CHECKBOX_LABEL_CLASS} htmlFor={inputId}>
|
|
113
|
+
{sublayer.label}
|
|
114
|
+
</label>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
)
|
|
118
|
+
})}
|
|
119
|
+
</fieldset>
|
|
120
|
+
</div>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (item.type === 'group') {
|
|
125
|
+
const anyDatasetChecked = item.datasets.some(d => d.visibility !== 'hidden')
|
|
126
|
+
const wrapperClass = `govuk-form-group im-c-datasets-layers-group${anyDatasetChecked ? ' im-c-datasets-layers-group--items-checked' : ''}`
|
|
127
|
+
return (
|
|
128
|
+
<div key={item.groupLabel} className={wrapperClass}>
|
|
129
|
+
<fieldset className='im-c-datasets-layers-group__fieldset'>
|
|
130
|
+
<legend className='im-c-datasets-layers-group__legend'>{item.groupLabel}</legend>
|
|
131
|
+
{item.datasets.map(dataset => renderDatasetItem(dataset))}
|
|
132
|
+
</fieldset>
|
|
133
|
+
</div>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return renderDatasetItem(item.dataset)
|
|
138
|
+
})}
|
|
36
139
|
</div>
|
|
37
140
|
)
|
|
38
141
|
}
|
|
@@ -1,8 +1,39 @@
|
|
|
1
|
+
// When groups are present, every direct child except the first gets a border-top
|
|
2
|
+
.im-c-datasets-layers--has-groups > *:not(:first-child) {
|
|
3
|
+
border-top: 1px solid var(--button-hover-color);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.im-c-datasets-layers > *:first-child {
|
|
7
|
+
padding-top: 5px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.im-c-datasets-layers > *:last-child {
|
|
11
|
+
margin-bottom: -5px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.im-c-datasets-layers-group:not(:last-child) {
|
|
15
|
+
padding-bottom: 5px;
|
|
16
|
+
}
|
|
17
|
+
|
|
1
18
|
.im-c-datasets-layers__item {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
&:
|
|
5
|
-
|
|
19
|
+
padding-bottom: 5px;
|
|
20
|
+
|
|
21
|
+
&:first-child {
|
|
22
|
+
padding-top: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.im-c-datasets-layers--has-groups > &:not(:first-child) {
|
|
26
|
+
padding-top: 5px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Items inside a group have no individual padding or spacing between them
|
|
30
|
+
.im-c-datasets-layers-group & {
|
|
31
|
+
padding-top: 0;
|
|
32
|
+
padding-bottom: 0;
|
|
33
|
+
|
|
34
|
+
&:not(:last-child) {
|
|
35
|
+
margin-bottom: 0;
|
|
36
|
+
}
|
|
6
37
|
}
|
|
7
38
|
}
|
|
8
39
|
|
|
@@ -19,10 +50,6 @@
|
|
|
19
50
|
color: var(--foreground-color);
|
|
20
51
|
}
|
|
21
52
|
|
|
22
|
-
.im-c-datasets-layers__item--checked {
|
|
23
|
-
border-color: var(--app-border-color);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
53
|
// GovUK style overide
|
|
27
54
|
.im-c-datasets-layers__item .govuk-checkboxes__item {
|
|
28
55
|
flex-wrap: nowrap;
|
|
@@ -31,3 +58,24 @@
|
|
|
31
58
|
margin-left: -3px;
|
|
32
59
|
}
|
|
33
60
|
}
|
|
61
|
+
|
|
62
|
+
.im-c-datasets-layers-group__fieldset {
|
|
63
|
+
// Reset browser fieldset defaults
|
|
64
|
+
border: none;
|
|
65
|
+
padding: 0;
|
|
66
|
+
margin: 0;
|
|
67
|
+
min-width: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.im-c-datasets-layers-group__legend {
|
|
71
|
+
padding-top: 15px;
|
|
72
|
+
padding-bottom: 10px;
|
|
73
|
+
padding-inline: 0;
|
|
74
|
+
font-size: 1rem;
|
|
75
|
+
font-weight: bold;
|
|
76
|
+
color: var(--foreground-color);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.im-c-datasets-layers-group:first-child .im-c-datasets-layers-group__legend {
|
|
80
|
+
padding-top: 0;
|
|
81
|
+
}
|