@geops/rvf-mobility-web-component 0.1.56 → 0.1.58
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/CHANGELOG.md +31 -0
- package/docutils.js +1 -1
- package/global.d.ts +1 -0
- package/iframe.html +15 -0
- package/index.html +2 -1
- package/index.js +278 -330
- package/package.json +16 -17
- package/src/{RvfExportMenu/RvfExportMenu.tsx → ExportMenu/ExportMenu.tsx} +11 -11
- package/src/ExportMenu/index.tsx +1 -0
- package/src/{RvfExportMenuButton/RvfExportMenuButton.tsx → ExportMenuButton/ExportMenuButton.tsx} +5 -5
- package/src/ExportMenuButton/index.tsx +1 -0
- package/src/FeatureDetails/FeatureDetails.tsx +57 -0
- package/src/FeatureDetails/index.ts +1 -0
- package/src/FeaturesInfosListener/FeaturesInfosListener.tsx +73 -0
- package/src/FeaturesInfosListener/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +0 -1
- package/src/LayerTree/LayerTree.tsx +58 -0
- package/src/LayerTree/TreeItem/TreeItem.tsx +151 -0
- package/src/LayerTree/TreeItem/index.tsx +1 -0
- package/src/LayerTree/index.tsx +1 -0
- package/src/LayerTree/layersTreeContext.ts +4 -0
- package/src/LayerTree/layersTreeReducer.ts +158 -0
- package/src/{RvfLayerTreeButton/RvfLayerTreeButton.tsx → LayerTreeButton/LayerTreeButton.tsx} +5 -5
- package/src/LayerTreeButton/index.tsx +1 -0
- package/src/{RvfTopics/RvfTopics.tsx → LayerTreeMenu/LayerTreeMenu.tsx} +17 -13
- package/src/LayerTreeMenu/index.tsx +1 -0
- package/src/LayoutState/LayoutState.tsx +277 -0
- package/src/LayoutState/index.tsx +1 -0
- package/src/LinesNetworkPlanDetails/LinesNetworkPlanDetails.tsx +292 -0
- package/src/LinesNetworkPlanDetails/index.tsx +1 -0
- package/src/{RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx → LinesNetworkPlanLayer/LinesNetworkPlanLayer.tsx} +7 -9
- package/src/LinesNetworkPlanLayer/index.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +274 -60
- package/src/MobilityMap/MobilityMapAttributes.ts +27 -43
- package/src/NotificationDetails/NotificationDetails.tsx +468 -0
- package/src/NotificationDetails/index.ts +1 -0
- package/src/{NotificationLayer/NotificationLayer.tsx → NotificationsLayer/NotificationsLayer.tsx} +9 -4
- package/src/NotificationsLayer/index.tsx +1 -0
- package/src/Overlay/Overlay.tsx +1 -6
- package/src/OverlayContent/OverlayContent.tsx +87 -0
- package/src/OverlayContent/index.ts +1 -0
- package/src/OverlayDetails/OverlayDetails.tsx +47 -0
- package/src/OverlayDetails/index.ts +1 -0
- package/src/OverlayDetailsFooter/OverlayDetailsFooter.tsx +51 -0
- package/src/OverlayDetailsFooter/index.tsx +1 -0
- package/src/OverlayDetailsHeader/OverlayDetailsHeader.tsx +35 -0
- package/src/OverlayDetailsHeader/index.ts +1 -0
- package/src/OverlayFooter/OverlayFooter.tsx +41 -0
- package/src/OverlayFooter/index.tsx +1 -0
- package/src/OverlayHeader/OverlayHeader.tsx +44 -0
- package/src/OverlayHeader/index.tsx +1 -0
- package/src/PermalinkInput/PermalinkInput.tsx +28 -0
- package/src/PermalinkInput/index.tsx +1 -0
- package/src/RouteSchedule/RouteSchedule.tsx +22 -18
- package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +22 -50
- package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +108 -104
- package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +189 -154
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +12 -14
- package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +5 -5
- package/src/RvfMainLinkButton/RvfMainLinkButton.tsx +62 -0
- package/src/RvfMainLinkButton/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +182 -394
- package/src/RvfOverlayContent/RvfOverlayContent.tsx +2 -2
- package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -2
- package/src/RvfSearch/RvfSearch.tsx +1 -1
- package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -2
- package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +23 -23
- package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -2
- package/src/Search/Search.tsx +11 -2
- package/src/{RvfSearchButton/RvfSearchButton.tsx → SearchButton/SearchButton.tsx} +5 -5
- package/src/SearchButton/index.tsx +1 -0
- package/src/ShadowOverflow/ShadowOverflow.tsx +20 -0
- package/src/ShadowOverflow/index.tsx +1 -0
- package/src/{RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx → ShareMenu/PermalinkButton/PermalinkButton.tsx} +4 -4
- package/src/ShareMenu/PermalinkButton/index.tsx +1 -0
- package/src/{RvfShare/RvfShare.tsx → ShareMenu/ShareMenu.tsx} +9 -11
- package/src/ShareMenu/index.tsx +1 -0
- package/src/{RvfShareMenuButton/RvfShareMenuButton.tsx → ShareMenuButton/ShareMenuButton.tsx} +6 -6
- package/src/ShareMenuButton/index.tsx +1 -0
- package/src/SingleClickListener/SingleClickListener.tsx +55 -113
- package/src/SingleClickListener/index.tsx +1 -1
- package/src/Station/Station.tsx +10 -3
- package/src/StationsLayer/StationsLayer.tsx +0 -1
- package/src/StopsSearch/StopsSearch.tsx +3 -4
- package/src/StopsSearch/index.tsx +2 -1
- package/src/WindowMessageListener/WindowMessageListener.tsx +7 -1
- package/src/{RvfZoomButtons/RvfZoomButtons.tsx → ZoomButtons/ZoomButtons.tsx} +9 -12
- package/src/ZoomButtons/index.tsx +1 -0
- package/src/icons/Geolocation/airport-14-svgrepo-com.svg +41 -0
- package/src/ui/Button/Button.tsx +9 -2
- package/src/ui/Checkbox/Checkbox.tsx +32 -0
- package/src/ui/Checkbox/index.tsx +1 -0
- package/src/ui/IconButton/IconButton.tsx +24 -4
- package/src/ui/Input/Input.tsx +17 -0
- package/src/ui/Input/index.tsx +1 -0
- package/src/ui/InputCopy/InputCopy.tsx +86 -0
- package/src/ui/InputCopy/index.tsx +1 -0
- package/src/ui/Select/Select.tsx +24 -0
- package/src/ui/Select/index.tsx +1 -0
- package/src/utils/constants.ts +43 -42
- package/src/utils/hooks/useInitialLayersVisiblity.tsx +1 -1
- package/src/utils/hooks/useLayerConfig.tsx +2 -2
- package/src/utils/hooks/useLayersConfig.tsx +3 -3
- package/src/utils/hooks/useMapContext.tsx +67 -8
- package/src/utils/hooks/useRvfContext.tsx +0 -44
- package/src/NotificationLayer/index.tsx +0 -1
- package/src/RvfEmbedNavigation/DragPanWarning.ts +0 -124
- package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +0 -51
- package/src/RvfEmbedNavigation/index.js +0 -1
- package/src/RvfExportMenu/index.tsx +0 -1
- package/src/RvfExportMenuButton/index.tsx +0 -1
- package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +0 -44
- package/src/RvfFloatingMenu/index.tsx +0 -1
- package/src/RvfLayerTreeButton/index.tsx +0 -1
- package/src/RvfLineNetworkPlanLayer/index.tsx +0 -1
- package/src/RvfPermalink/RvfPermalink.tsx +0 -18
- package/src/RvfPermalink/index.tsx +0 -1
- package/src/RvfSearchButton/index.tsx +0 -1
- package/src/RvfShare/RvfPermalinkButton/index.tsx +0 -1
- package/src/RvfShare/index.tsx +0 -1
- package/src/RvfShareMenuButton/index.tsx +0 -1
- package/src/RvfTopics/index.tsx +0 -1
- package/src/RvfZoomButtons/index.tsx +0 -1
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
import { memo } from "preact/compat";
|
|
2
2
|
import { useMemo, useRef, useState } from "preact/hooks";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
3
4
|
|
|
4
5
|
import BaseLayer from "../BaseLayer";
|
|
5
6
|
import Copyright from "../Copyright";
|
|
6
7
|
import EmbedNavigation from "../EmbedNavigation";
|
|
8
|
+
import ExportMenuButton from "../ExportMenuButton";
|
|
9
|
+
import FeaturesInfosListener from "../FeaturesInfosListener";
|
|
7
10
|
import GeolocationButton from "../GeolocationButton";
|
|
11
|
+
import LayerTreeButton from "../LayerTreeButton";
|
|
12
|
+
import LayoutState from "../LayoutState";
|
|
13
|
+
import LinesNetworkPlanLayer from "../LinesNetworkPlanLayer";
|
|
8
14
|
import Map from "../Map";
|
|
9
15
|
import MapDispatchEvents from "../MapDispatchEvents";
|
|
10
|
-
import
|
|
16
|
+
import NotificationsLayer from "../NotificationsLayer";
|
|
11
17
|
import Overlay from "../Overlay";
|
|
18
|
+
import OverlayContent from "../OverlayContent";
|
|
12
19
|
import Permalink from "../Permalink";
|
|
13
20
|
import RealtimeLayer from "../RealtimeLayer";
|
|
14
|
-
import RouteSchedule from "../RouteSchedule";
|
|
15
21
|
import ScaleLine from "../ScaleLine";
|
|
16
22
|
import Search from "../Search";
|
|
17
|
-
import
|
|
18
|
-
import
|
|
23
|
+
import SearchButton from "../SearchButton";
|
|
24
|
+
import ShareMenuButton from "../ShareMenuButton";
|
|
25
|
+
import SingleClickListener from "../SingleClickListener";
|
|
19
26
|
import StationsLayer from "../StationsLayer";
|
|
20
27
|
import { I18nContext } from "../utils/hooks/useI18n";
|
|
21
28
|
import { MapContext } from "../utils/hooks/useMapContext";
|
|
22
29
|
import i18n from "../utils/i18n";
|
|
23
30
|
import WindowMessageListener from "../WindowMessageListener";
|
|
31
|
+
import ZoomButtons from "../ZoomButtons";
|
|
24
32
|
|
|
25
33
|
import MobilityMapAttributes from "./MobilityMapAttributes";
|
|
26
34
|
|
|
@@ -33,8 +41,10 @@ import type {
|
|
|
33
41
|
MaplibreLayer,
|
|
34
42
|
MaplibreStyleLayer,
|
|
35
43
|
RealtimeLayer as MbtRealtimeLayer,
|
|
44
|
+
MocoLayer,
|
|
36
45
|
} from "mobility-toolbox-js/ol";
|
|
37
46
|
import type {
|
|
47
|
+
LayerGetFeatureInfoResponse,
|
|
38
48
|
RealtimeStation,
|
|
39
49
|
RealtimeStationId,
|
|
40
50
|
RealtimeStopSequence,
|
|
@@ -50,18 +60,49 @@ export type MobilityMapProps = Record<
|
|
|
50
60
|
null | string | undefined
|
|
51
61
|
>;
|
|
52
62
|
|
|
63
|
+
const scrollableHandlerProps = {
|
|
64
|
+
style: { width: "calc(100% - 60px)" },
|
|
65
|
+
};
|
|
66
|
+
|
|
53
67
|
function MobilityMap(props: MobilityMapProps) {
|
|
54
68
|
const eventNodeRef = useRef<HTMLDivElement>();
|
|
55
69
|
const [baseLayer, setBaseLayer] = useState<MaplibreLayer>();
|
|
56
|
-
const [isFollowing, setIsFollowing] = useState(false);
|
|
57
|
-
const [isTracking, setIsTracking] = useState(false);
|
|
70
|
+
const [isFollowing, setIsFollowing] = useState<boolean>(false);
|
|
71
|
+
const [isTracking, setIsTracking] = useState<boolean>(false);
|
|
72
|
+
const [isEmbed, setIsEmbed] = useState<boolean>(false);
|
|
73
|
+
const [hasGeolocation, setHasGeolocation] = useState<boolean>(false);
|
|
74
|
+
const [hasLnp, setHasLnp] = useState<boolean>(false);
|
|
75
|
+
const [hasDetails, setHasDetails] = useState<boolean>(false);
|
|
76
|
+
const [hasNotification, setHasNotification] = useState<boolean>(false);
|
|
77
|
+
const [hasPermalink, setHasPermalink] = useState<boolean>(false);
|
|
78
|
+
const [hasPrint, setHasPrint] = useState<boolean>(false);
|
|
79
|
+
const [hasRealtime, setHasRealtime] = useState<boolean>(false);
|
|
80
|
+
const [hasSearch, setHasSearch] = useState<boolean>(false);
|
|
81
|
+
const [hasStations, setHasStations] = useState<boolean>(false);
|
|
82
|
+
const [hasToolbar, setHasToolbar] = useState<boolean>(false);
|
|
83
|
+
const [hasShare, setHasShare] = useState<boolean>(false);
|
|
84
|
+
const [hasLayerTree, setHasLayerTree] = useState<boolean>(false);
|
|
85
|
+
const [isOverlayOpen, setIsOverlayOpen] = useState<boolean>(false);
|
|
86
|
+
const [isExportMenuOpen, setIsExportMenuOpen] = useState<boolean>(false);
|
|
87
|
+
const [isShareMenuOpen, setIsShareMenuOpen] = useState<boolean>(false);
|
|
88
|
+
const [isLayerTreeOpen, setIsLayerTreeOpen] = useState<boolean>(false);
|
|
89
|
+
const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);
|
|
58
90
|
const [stopSequence, setStopSequence] = useState<RealtimeStopSequence>();
|
|
59
91
|
const [stationsLayer, setStationsLayer] = useState<MaplibreStyleLayer>();
|
|
60
92
|
const [station, setStation] = useState<RealtimeStation>();
|
|
61
93
|
const [realtimeLayer, setRealtimeLayer] = useState<MbtRealtimeLayer>();
|
|
94
|
+
const [notificationsLayer, setNotificationsLayer] = useState<MocoLayer>();
|
|
95
|
+
const [linesNetworkPlanLayer, setLinesNetworkPlanLayer] =
|
|
96
|
+
useState<MaplibreStyleLayer>();
|
|
62
97
|
const [map, setMap] = useState<OlMap>();
|
|
63
98
|
const [stationId, setStationId] = useState<RealtimeStationId>();
|
|
64
99
|
const [trainId, setTrainId] = useState<RealtimeTrainId>();
|
|
100
|
+
const [featuresInfos, setFeaturesInfos] = useState<
|
|
101
|
+
LayerGetFeatureInfoResponse[]
|
|
102
|
+
>([]);
|
|
103
|
+
const [featuresInfosHovered, setFeaturesInfosHovered] = useState<
|
|
104
|
+
LayerGetFeatureInfoResponse[]
|
|
105
|
+
>([]);
|
|
65
106
|
const [selectedFeature, setSelectedFeature] = useState<Feature>(null);
|
|
66
107
|
const [selectedFeatures, setSelectedFeatures] = useState<Feature[]>([]);
|
|
67
108
|
const [permalinkUrlSearchParams, setPermalinkUrlSearchParams] =
|
|
@@ -70,40 +111,6 @@ function MobilityMap(props: MobilityMapProps) {
|
|
|
70
111
|
const [previewNotifications, setPreviewNotifications] =
|
|
71
112
|
useState<SituationType[]>();
|
|
72
113
|
|
|
73
|
-
const {
|
|
74
|
-
embed,
|
|
75
|
-
geolocation,
|
|
76
|
-
notification,
|
|
77
|
-
permalink,
|
|
78
|
-
realtime,
|
|
79
|
-
search,
|
|
80
|
-
tenant,
|
|
81
|
-
} = props;
|
|
82
|
-
|
|
83
|
-
const hasRealtime = useMemo(() => {
|
|
84
|
-
return realtime === "true";
|
|
85
|
-
}, [realtime]);
|
|
86
|
-
|
|
87
|
-
const hasNotification = useMemo(() => {
|
|
88
|
-
return notification === "true" || !!previewNotifications;
|
|
89
|
-
}, [notification, previewNotifications]);
|
|
90
|
-
|
|
91
|
-
const hasGeolocation = useMemo(() => {
|
|
92
|
-
return geolocation === "true";
|
|
93
|
-
}, [geolocation]);
|
|
94
|
-
|
|
95
|
-
const hasPermalink = useMemo(() => {
|
|
96
|
-
return permalink === "true";
|
|
97
|
-
}, [permalink]);
|
|
98
|
-
|
|
99
|
-
const hasSearch = useMemo(() => {
|
|
100
|
-
return search === "true";
|
|
101
|
-
}, [search]);
|
|
102
|
-
|
|
103
|
-
const isEmbed = useMemo(() => {
|
|
104
|
-
return embed === "true";
|
|
105
|
-
}, [embed]);
|
|
106
|
-
|
|
107
114
|
// Object representing all the web-component attributes and the map context values.
|
|
108
115
|
const mapContextValue = useMemo(() => {
|
|
109
116
|
return {
|
|
@@ -111,19 +118,61 @@ function MobilityMap(props: MobilityMapProps) {
|
|
|
111
118
|
...props,
|
|
112
119
|
// MapContextProps
|
|
113
120
|
baseLayer,
|
|
121
|
+
featuresInfos,
|
|
122
|
+
featuresInfosHovered,
|
|
123
|
+
hasDetails,
|
|
124
|
+
hasGeolocation,
|
|
125
|
+
hasLayerTree,
|
|
126
|
+
hasLnp,
|
|
127
|
+
hasNotification,
|
|
128
|
+
hasPermalink,
|
|
129
|
+
hasPrint,
|
|
130
|
+
hasRealtime,
|
|
131
|
+
hasSearch,
|
|
132
|
+
hasShare,
|
|
133
|
+
hasToolbar,
|
|
114
134
|
isEmbed,
|
|
135
|
+
isExportMenuOpen,
|
|
115
136
|
isFollowing,
|
|
137
|
+
isLayerTreeOpen,
|
|
138
|
+
isOverlayOpen,
|
|
139
|
+
isSearchOpen,
|
|
140
|
+
isShareMenuOpen,
|
|
116
141
|
isTracking,
|
|
142
|
+
linesNetworkPlanLayer,
|
|
117
143
|
map,
|
|
144
|
+
notificationsLayer,
|
|
118
145
|
permalinkUrlSearchParams,
|
|
119
146
|
previewNotifications,
|
|
120
147
|
realtimeLayer,
|
|
121
148
|
selectedFeature,
|
|
122
149
|
selectedFeatures,
|
|
123
150
|
setBaseLayer,
|
|
151
|
+
setFeaturesInfos,
|
|
152
|
+
setFeaturesInfosHovered,
|
|
153
|
+
setHasDetails,
|
|
154
|
+
setHasGeolocation,
|
|
155
|
+
setHasLayerTree,
|
|
156
|
+
setHasLnp,
|
|
157
|
+
setHasNotification,
|
|
158
|
+
setHasPermalink,
|
|
159
|
+
setHasPrint,
|
|
160
|
+
setHasRealtime,
|
|
161
|
+
setHasSearch,
|
|
162
|
+
setHasShare,
|
|
163
|
+
setHasStations,
|
|
164
|
+
setHasToolbar,
|
|
165
|
+
setIsEmbed,
|
|
166
|
+
setIsExportMenuOpen,
|
|
124
167
|
setIsFollowing,
|
|
168
|
+
setIsLayerTreeOpen,
|
|
169
|
+
setIsOverlayOpen,
|
|
170
|
+
setIsSearchOpen,
|
|
171
|
+
setIsShareMenuOpen,
|
|
125
172
|
setIsTracking,
|
|
173
|
+
setLinesNetworkPlanLayer,
|
|
126
174
|
setMap,
|
|
175
|
+
setNotificationsLayer,
|
|
127
176
|
setPermalinkUrlSearchParams,
|
|
128
177
|
setPreviewNotifications,
|
|
129
178
|
setRealtimeLayer,
|
|
@@ -143,10 +192,30 @@ function MobilityMap(props: MobilityMapProps) {
|
|
|
143
192
|
}, [
|
|
144
193
|
props,
|
|
145
194
|
baseLayer,
|
|
195
|
+
featuresInfos,
|
|
196
|
+
featuresInfosHovered,
|
|
197
|
+
hasDetails,
|
|
198
|
+
hasGeolocation,
|
|
199
|
+
hasLayerTree,
|
|
200
|
+
hasLnp,
|
|
201
|
+
hasNotification,
|
|
202
|
+
hasPermalink,
|
|
203
|
+
hasPrint,
|
|
204
|
+
hasRealtime,
|
|
205
|
+
hasSearch,
|
|
206
|
+
hasShare,
|
|
207
|
+
hasToolbar,
|
|
146
208
|
isEmbed,
|
|
209
|
+
isExportMenuOpen,
|
|
147
210
|
isFollowing,
|
|
211
|
+
isLayerTreeOpen,
|
|
212
|
+
isOverlayOpen,
|
|
213
|
+
isSearchOpen,
|
|
214
|
+
isShareMenuOpen,
|
|
148
215
|
isTracking,
|
|
216
|
+
linesNetworkPlanLayer,
|
|
149
217
|
map,
|
|
218
|
+
notificationsLayer,
|
|
150
219
|
permalinkUrlSearchParams,
|
|
151
220
|
previewNotifications,
|
|
152
221
|
realtimeLayer,
|
|
@@ -161,52 +230,197 @@ function MobilityMap(props: MobilityMapProps) {
|
|
|
161
230
|
|
|
162
231
|
return (
|
|
163
232
|
<I18nContext.Provider value={i18n}>
|
|
233
|
+
{/* There is a bug in tailwindcss@4 , variables are not imported in the shadow dom
|
|
234
|
+
see https://github.com/tailwindlabs/tailwindcss/issues/15005*/}
|
|
235
|
+
<style>
|
|
236
|
+
{`:host {
|
|
237
|
+
--tw-divide-y-reverse: 0;
|
|
238
|
+
--tw-border-style: solid;
|
|
239
|
+
--tw-font-weight: initial;
|
|
240
|
+
--tw-tracking: initial;
|
|
241
|
+
--tw-translate-x: 0;
|
|
242
|
+
--tw-translate-y: 0;
|
|
243
|
+
--tw-translate-z: 0;
|
|
244
|
+
--tw-rotate-x: rotateX(0);
|
|
245
|
+
--tw-rotate-y: rotateY(0);
|
|
246
|
+
--tw-rotate-z: rotateZ(0);
|
|
247
|
+
--tw-skew-x: skewX(0);
|
|
248
|
+
--tw-skew-y: skewY(0);
|
|
249
|
+
--tw-space-x-reverse: 0;
|
|
250
|
+
--tw-gradient-position: initial;
|
|
251
|
+
--tw-gradient-from: #0000;
|
|
252
|
+
--tw-gradient-via: #0000;
|
|
253
|
+
--tw-gradient-to: #0000;
|
|
254
|
+
--tw-gradient-stops: initial;
|
|
255
|
+
--tw-gradient-via-stops: initial;
|
|
256
|
+
--tw-gradient-from-position: 0%;
|
|
257
|
+
--tw-gradient-via-position: 50%;
|
|
258
|
+
--tw-gradient-to-position: 100%;
|
|
259
|
+
--tw-shadow: 0 0 #0000;
|
|
260
|
+
--tw-shadow-color: initial;
|
|
261
|
+
--tw-inset-shadow: 0 0 #0000;
|
|
262
|
+
--tw-inset-shadow-color: initial;
|
|
263
|
+
--tw-ring-color: initial;
|
|
264
|
+
--tw-ring-shadow: 0 0 #0000;
|
|
265
|
+
--tw-inset-ring-color: initial;
|
|
266
|
+
--tw-inset-ring-shadow: 0 0 #0000;
|
|
267
|
+
--tw-ring-inset: initial;
|
|
268
|
+
--tw-ring-offset-width: 0px;
|
|
269
|
+
--tw-ring-offset-color: #fff;
|
|
270
|
+
--tw-ring-offset-shadow: 0 0 #0000;
|
|
271
|
+
--tw-blur: initial;
|
|
272
|
+
--tw-brightness: initial;
|
|
273
|
+
--tw-contrast: initial;
|
|
274
|
+
--tw-grayscale: initial;
|
|
275
|
+
--tw-hue-rotate: initial;
|
|
276
|
+
--tw-invert: initial;
|
|
277
|
+
--tw-opacity: initial;
|
|
278
|
+
--tw-saturate: initial;
|
|
279
|
+
--tw-sepia: initial;
|
|
280
|
+
--tw-drop-shadow: initial;
|
|
281
|
+
--tw-duration: initial;
|
|
282
|
+
--tw-ease: initial;
|
|
283
|
+
}`}
|
|
284
|
+
</style>
|
|
164
285
|
<style>{tailwind}</style>
|
|
165
286
|
<style>{style}</style>
|
|
166
287
|
<MapContext.Provider value={mapContextValue}>
|
|
288
|
+
<LayoutState />
|
|
167
289
|
<Permalink replaceState={hasPermalink} />
|
|
168
290
|
<MapDispatchEvents node={eventNodeRef.current} wcAttributes={props} />
|
|
169
291
|
<WindowMessageListener eventNode={eventNodeRef.current} />
|
|
292
|
+
<SingleClickListener />
|
|
293
|
+
<FeaturesInfosListener />
|
|
294
|
+
|
|
295
|
+
{/* Layers */}
|
|
296
|
+
<BaseLayer />
|
|
297
|
+
{hasNotification && <NotificationsLayer />}
|
|
298
|
+
{hasRealtime && <RealtimeLayer />}
|
|
299
|
+
{hasStations && <StationsLayer />}
|
|
300
|
+
{hasLnp && <LinesNetworkPlanLayer />}
|
|
301
|
+
|
|
302
|
+
{/* Layout */}
|
|
170
303
|
<div
|
|
171
304
|
className="@container/main relative size-full border font-sans"
|
|
172
305
|
ref={eventNodeRef}
|
|
173
306
|
>
|
|
174
307
|
<div className="relative flex size-full flex-col @lg/main:flex-row-reverse">
|
|
175
308
|
<Map className="relative flex-1 overflow-visible">
|
|
176
|
-
<BaseLayer />
|
|
177
|
-
<SingleClickListener />
|
|
178
309
|
<EmbedNavigation />
|
|
179
310
|
|
|
180
|
-
{hasNotification && <NotificationLayer />}
|
|
181
|
-
{hasRealtime && <RealtimeLayer />}
|
|
182
|
-
{tenant && <StationsLayer />}
|
|
183
311
|
<div className="absolute inset-x-2 bottom-2 z-10 flex items-end justify-between gap-2 text-[10px]">
|
|
184
312
|
<ScaleLine className="bg-slate-50/70" />
|
|
185
313
|
<Copyright className="bg-slate-50/70" />
|
|
186
314
|
</div>
|
|
187
|
-
|
|
188
|
-
|
|
315
|
+
|
|
316
|
+
<div className="absolute right-2 bottom-10 z-10 flex flex-col justify-between gap-2">
|
|
317
|
+
<ZoomButtons />
|
|
189
318
|
</div>
|
|
190
|
-
|
|
319
|
+
|
|
320
|
+
{hasGeolocation && (
|
|
321
|
+
<div className="absolute top-2 right-2 z-10 flex flex-col gap-2">
|
|
322
|
+
<GeolocationButton />
|
|
323
|
+
</div>
|
|
324
|
+
)}
|
|
325
|
+
|
|
326
|
+
{!hasToolbar && hasSearch && (
|
|
191
327
|
<div className="absolute top-2 right-12 left-2 z-10 flex max-h-[90%] max-w-96 min-w-64 flex-col">
|
|
192
328
|
<Search />
|
|
193
329
|
</div>
|
|
194
330
|
)}
|
|
195
331
|
</Map>
|
|
196
332
|
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
333
|
+
<div className="pointer-events-none absolute top-2 bottom-2 left-2 z-10 flex flex-col gap-2 *:pointer-events-auto">
|
|
334
|
+
<div
|
|
335
|
+
className={
|
|
336
|
+
"relative z-10 w-fit rounded-2xl bg-black/10 p-0 backdrop-blur-sm"
|
|
337
|
+
}
|
|
338
|
+
>
|
|
339
|
+
{hasToolbar && (
|
|
340
|
+
<div
|
|
341
|
+
className={twMerge(
|
|
342
|
+
"border-grey relative z-10 flex gap-[1px] overflow-hidden rounded-2xl border",
|
|
343
|
+
"*:size-[46px] *:rounded-none *:border-none",
|
|
344
|
+
"*:first:!rounded-l-2xl",
|
|
345
|
+
"*:last:!rounded-r-2xl",
|
|
346
|
+
isSearchOpen
|
|
347
|
+
? "@sm:rounded-r-none @sm:border-r-0 @sm:*:last:!rounded-r-none @sm:*:last:border-r-0"
|
|
348
|
+
: "",
|
|
349
|
+
)}
|
|
350
|
+
>
|
|
351
|
+
{hasPrint && <ExportMenuButton title={"Drucken"} />}
|
|
352
|
+
{hasShare && <ShareMenuButton title={"Share"} />}
|
|
353
|
+
{hasLayerTree && <LayerTreeButton title={"Layers"} />}
|
|
354
|
+
{hasSearch && <SearchButton title={"Suche"} />}
|
|
355
|
+
</div>
|
|
356
|
+
)}
|
|
357
|
+
|
|
358
|
+
{hasToolbar && hasSearch && (
|
|
359
|
+
<div
|
|
360
|
+
className={twMerge(
|
|
361
|
+
"absolute top-14 left-0 z-5 h-[48px] w-0 p-0 opacity-0 transition-all @sm:top-0 @sm:left-[calc(100%-47px)]",
|
|
362
|
+
isSearchOpen ? "w-64 opacity-100" : "",
|
|
363
|
+
)}
|
|
364
|
+
>
|
|
365
|
+
<Search
|
|
366
|
+
className={
|
|
367
|
+
"border-grey @container m-0 h-[40px] gap-4 rounded-2xl border p-2 px-4 text-base @sm/main:h-[48px] @sm/main:rounded-l-none @sm/main:rounded-r-2xl"
|
|
368
|
+
}
|
|
369
|
+
// inputClassName="h-6 text-base"
|
|
370
|
+
inputContainerClassName="border-none"
|
|
371
|
+
resultClassName="text-base **:hover:cursor-pointer p-2"
|
|
372
|
+
resultsContainerClassName="@container rounded-b-2xl max-h-[200px] overflow-y-auto border border-t-0 "
|
|
373
|
+
withResultsClassName="text-base !rounded-b-none"
|
|
374
|
+
/>
|
|
375
|
+
</div>
|
|
376
|
+
)}
|
|
377
|
+
</div>
|
|
378
|
+
|
|
379
|
+
{/* Desktop (>= lg) */}
|
|
380
|
+
{isOverlayOpen && (
|
|
381
|
+
<div
|
|
382
|
+
className={twMerge(
|
|
383
|
+
"flex w-0 flex-1 flex-col overflow-hidden rounded-2xl @lg:min-w-64",
|
|
384
|
+
)}
|
|
385
|
+
style={{ containerType: "normal" }}
|
|
386
|
+
>
|
|
387
|
+
<Overlay
|
|
388
|
+
className={
|
|
389
|
+
"border-grey @container/overlay pointer-events-auto relative hidden flex-col overflow-hidden rounded-2xl border bg-white text-base shadow-lg @lg:flex"
|
|
390
|
+
}
|
|
391
|
+
ScrollableHandlerProps={scrollableHandlerProps}
|
|
392
|
+
>
|
|
393
|
+
<OverlayContent
|
|
394
|
+
hasDetails={hasDetails}
|
|
395
|
+
hasLayerTree={hasLayerTree}
|
|
396
|
+
hasPrint={hasPrint}
|
|
397
|
+
hasRealtime={hasRealtime}
|
|
398
|
+
hasSearch={false}
|
|
399
|
+
hasShare={hasShare}
|
|
400
|
+
/>
|
|
401
|
+
</Overlay>
|
|
402
|
+
</div>
|
|
208
403
|
)}
|
|
209
|
-
</
|
|
404
|
+
</div>
|
|
405
|
+
|
|
406
|
+
{/* Mobile (< lg) */}
|
|
407
|
+
{isOverlayOpen && (
|
|
408
|
+
<Overlay
|
|
409
|
+
className={
|
|
410
|
+
"absolute bottom-0 z-20 flex max-h-[70%] min-h-[75px] w-full flex-col border-t bg-white @lg:hidden"
|
|
411
|
+
}
|
|
412
|
+
ScrollableHandlerProps={scrollableHandlerProps}
|
|
413
|
+
>
|
|
414
|
+
<OverlayContent
|
|
415
|
+
hasDetails={hasDetails}
|
|
416
|
+
hasLayerTree={hasLayerTree}
|
|
417
|
+
hasPrint={hasPrint}
|
|
418
|
+
hasRealtime={hasRealtime}
|
|
419
|
+
hasSearch={false}
|
|
420
|
+
hasShare={hasShare}
|
|
421
|
+
/>
|
|
422
|
+
</Overlay>
|
|
423
|
+
)}
|
|
210
424
|
</div>
|
|
211
425
|
</div>
|
|
212
426
|
</MapContext.Provider>
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
DEFAULT_QUERYABLE_LAYERS,
|
|
5
|
+
LAYERS_NAMES,
|
|
5
6
|
LAYERS_WITH_LINK,
|
|
6
|
-
|
|
7
|
-
RVF_LAYERS_NAMES,
|
|
7
|
+
MAX_EXTENT,
|
|
8
8
|
} from "../utils/constants";
|
|
9
9
|
|
|
10
10
|
// import type { LayersConfig } from "../utils/hooks/useLayerConfig";
|
|
@@ -32,6 +32,7 @@ export type MobilityMapAttributeName =
|
|
|
32
32
|
| "layers"
|
|
33
33
|
| "layersconfig"
|
|
34
34
|
| "layertree"
|
|
35
|
+
| "lnp"
|
|
35
36
|
| "mainlink"
|
|
36
37
|
| "mainlinktitle"
|
|
37
38
|
| "mapsurl"
|
|
@@ -79,7 +80,7 @@ const attrs: MobilityMapAttributes = {
|
|
|
79
80
|
details: {
|
|
80
81
|
defaultValue: "true",
|
|
81
82
|
description:
|
|
82
|
-
"
|
|
83
|
+
"When a feature of a queryable layer is clicked, it displays informations about it.",
|
|
83
84
|
type: "boolean",
|
|
84
85
|
},
|
|
85
86
|
embed: {
|
|
@@ -89,7 +90,7 @@ const attrs: MobilityMapAttributes = {
|
|
|
89
90
|
type: "boolean",
|
|
90
91
|
},
|
|
91
92
|
extent: {
|
|
92
|
-
defaultValue:
|
|
93
|
+
defaultValue: MAX_EXTENT.join(","),
|
|
93
94
|
description:
|
|
94
95
|
"The map's extent in EPSG:3857 coordinates.<br/>Ex: 831634,5933959,940649,6173660 .<br/>Parameter required if center and zoom are not set.",
|
|
95
96
|
},
|
|
@@ -100,29 +101,11 @@ const attrs: MobilityMapAttributes = {
|
|
|
100
101
|
},
|
|
101
102
|
layers: {
|
|
102
103
|
defaultValue: null,
|
|
103
|
-
description: `A comma separated list of layers's name to make visible on load, others are hidden. If empty, all layers will be hidden except the baselayer.<br/>Layers available are ${Object.values(
|
|
104
|
+
description: `A comma separated list of layers's name to make visible on load, others are hidden. If empty, all layers will be hidden except the baselayer.<br/>Layers available are ${Object.values(LAYERS_NAMES).join(", ")}.`,
|
|
104
105
|
},
|
|
105
106
|
layersconfig: {
|
|
106
|
-
// defaultValue:
|
|
107
|
-
// JSON.stringify({
|
|
108
|
-
// [RVF_LAYERS_NAMES.liniennetz]: {
|
|
109
|
-
// link: {
|
|
110
|
-
// href: "https://www.rvf.de/fahrtinfo/netzplan",
|
|
111
|
-
// show: true,
|
|
112
|
-
// text: "Zu den Liniennetzplänen",
|
|
113
|
-
// },
|
|
114
|
-
// title: "Liniennetzpläne",
|
|
115
|
-
// },
|
|
116
|
-
// [RVF_LAYERS_NAMES.meldungen]: {
|
|
117
|
-
// link: {
|
|
118
|
-
// href: "https://moco.geops.io/situation/{{id}}",
|
|
119
|
-
// show: true,
|
|
120
|
-
// text: "Zum Moco",
|
|
121
|
-
// },
|
|
122
|
-
// },
|
|
123
|
-
// } as LayersConfig),
|
|
124
107
|
description: `A JSON string to configure the layers and other components associated to it.<br/>
|
|
125
|
-
The layers available are : ${LAYERS_WITH_LINK}.<br/>
|
|
108
|
+
The layers available are : ${LAYERS_WITH_LINK.toString()}.<br/>
|
|
126
109
|
Definition for a layer :
|
|
127
110
|
<pre style="font-size: 12px; overflow: auto;">{
|
|
128
111
|
"liniennetz": {
|
|
@@ -139,7 +122,7 @@ where:
|
|
|
139
122
|
<ul style="list-style-type: disc; padding-left: 20px;">
|
|
140
123
|
<li><i>link</i> defined a external link displayed at the bottom of the detail view</li>
|
|
141
124
|
<ul style="list-style-type: disc; padding-left: 40px;">
|
|
142
|
-
<li><i>href</i> is the target of the link. The <i>href</i> can be template, for example for the meldungen layer you can use {{id}} to insert the id of the notification in the url.</li
|
|
125
|
+
<li><i>href</i> is the target of the link. The <i>href</i> can be template, for example for the meldungen layer you can use {{id}} to insert the id of the notification in the url.</li>
|
|
143
126
|
<li><i>text</i> is the text display as a link</li>
|
|
144
127
|
<li><i>show</i> show/hide the link in the details view</li>
|
|
145
128
|
</ul>
|
|
@@ -151,20 +134,24 @@ where:
|
|
|
151
134
|
description: "Show/hide the layers tree button in the toolbar.",
|
|
152
135
|
type: "boolean",
|
|
153
136
|
},
|
|
137
|
+
lnp: {
|
|
138
|
+
defaultValue: "true",
|
|
139
|
+
description: null,
|
|
140
|
+
type: "boolean",
|
|
141
|
+
},
|
|
154
142
|
mainlink: {
|
|
155
|
-
|
|
156
|
-
|
|
143
|
+
description:
|
|
144
|
+
"A link displayed on bottom left of the map. The link can be template, for example you can use {{x}} {{y}} {{z}} to insert the current position of the map in the url.<br/>Ex: http://mywebsite/mypage#{{x}}/{{y}}/{{z}}.",
|
|
157
145
|
},
|
|
158
146
|
mainlinktitle: {
|
|
159
|
-
// defaultValue: "Gesamte Karte",
|
|
160
147
|
description: "A title for the mainlink, used as tooltip.",
|
|
161
148
|
},
|
|
162
149
|
mapsurl: {
|
|
163
150
|
defaultValue: "https://maps.geops.io",
|
|
164
|
-
description: null,
|
|
151
|
+
description: null,
|
|
165
152
|
},
|
|
166
153
|
maxextent: {
|
|
167
|
-
defaultValue:
|
|
154
|
+
defaultValue: MAX_EXTENT.join(","),
|
|
168
155
|
description:
|
|
169
156
|
"The maximum extent of the map in EPSG:3857 coordinates.<br/>Ex: 831634,5933959,940649,6173660 .",
|
|
170
157
|
},
|
|
@@ -177,7 +164,6 @@ where:
|
|
|
177
164
|
},
|
|
178
165
|
mots: {
|
|
179
166
|
description: null,
|
|
180
|
-
// "Commas separated list of mots to display on the Realtime layer.<br/>Ex: rail,bus,coach,foot,tram,subway,gondola,funicular,ferry,car .",
|
|
181
167
|
},
|
|
182
168
|
notification: {
|
|
183
169
|
defaultValue: "true",
|
|
@@ -187,15 +173,14 @@ where:
|
|
|
187
173
|
},
|
|
188
174
|
notificationat: {
|
|
189
175
|
description: null,
|
|
190
|
-
// "An ISO date string used to display active notification at this date in the notification layer. If not defined the current date will be used.<br/>Ex: 2025-08-01T00:00:00Z .",
|
|
191
176
|
},
|
|
192
177
|
notificationtenant: {
|
|
193
178
|
defaultValue: "rvf",
|
|
194
|
-
description: null,
|
|
179
|
+
description: null,
|
|
195
180
|
},
|
|
196
181
|
notificationurl: {
|
|
197
182
|
defaultValue: "https://moco.geops.io/api/v2/",
|
|
198
|
-
description: null,
|
|
183
|
+
description: null,
|
|
199
184
|
},
|
|
200
185
|
permalink: {
|
|
201
186
|
defaultValue: "false",
|
|
@@ -209,26 +194,25 @@ where:
|
|
|
209
194
|
type: "boolean",
|
|
210
195
|
},
|
|
211
196
|
queryablelayers: {
|
|
212
|
-
defaultValue: DEFAULT_QUERYABLE_LAYERS,
|
|
213
|
-
description:
|
|
214
|
-
|
|
197
|
+
defaultValue: DEFAULT_QUERYABLE_LAYERS.toString(),
|
|
198
|
+
description: `A comma separated list of layers's name. The data of these layers will be queryable by click on the map (see selectedfeature event). If empty, all layers will not be queryable.<br/>
|
|
199
|
+
Layers available are ${Object.values(LAYERS_NAMES).join(", ")}`,
|
|
215
200
|
},
|
|
216
201
|
realtime: {
|
|
217
202
|
defaultValue: "true",
|
|
218
|
-
description: null,
|
|
203
|
+
description: null,
|
|
219
204
|
type: "boolean",
|
|
220
205
|
},
|
|
221
206
|
realtimebboxparameters: {
|
|
222
207
|
defaultValue: "line_tags=RVF",
|
|
223
208
|
description: null,
|
|
224
|
-
// "A space separated list of parameters to add to the realtime BBOX request to define custom behavior.<br/>Ex: graph=XXX line_tags=XXX.",
|
|
225
209
|
},
|
|
226
210
|
realtimetenant: {
|
|
227
|
-
description: null,
|
|
211
|
+
description: null,
|
|
228
212
|
},
|
|
229
213
|
realtimeurl: {
|
|
230
214
|
defaultValue: "wss://api.geops.io/tracker-ws/v1/ws",
|
|
231
|
-
description: null,
|
|
215
|
+
description: null,
|
|
232
216
|
},
|
|
233
217
|
runs: {
|
|
234
218
|
defaultValue: "false",
|
|
@@ -248,10 +232,10 @@ where:
|
|
|
248
232
|
},
|
|
249
233
|
stopsurl: {
|
|
250
234
|
defaultValue: "https://api.geops.io/stops/v1/",
|
|
251
|
-
description: null,
|
|
235
|
+
description: null,
|
|
252
236
|
},
|
|
253
237
|
tenant: {
|
|
254
|
-
description: null,
|
|
238
|
+
description: null,
|
|
255
239
|
},
|
|
256
240
|
toolbar: {
|
|
257
241
|
defaultValue: "true",
|