@geops/rvf-mobility-web-component 0.1.56 → 0.1.57

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 (123) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/docutils.js +1 -1
  3. package/global.d.ts +1 -0
  4. package/iframe.html +15 -0
  5. package/index.html +2 -1
  6. package/index.js +278 -330
  7. package/package.json +16 -17
  8. package/src/{RvfExportMenu/RvfExportMenu.tsx → ExportMenu/ExportMenu.tsx} +11 -11
  9. package/src/ExportMenu/index.tsx +1 -0
  10. package/src/{RvfExportMenuButton/RvfExportMenuButton.tsx → ExportMenuButton/ExportMenuButton.tsx} +5 -5
  11. package/src/ExportMenuButton/index.tsx +1 -0
  12. package/src/FeatureDetails/FeatureDetails.tsx +57 -0
  13. package/src/FeatureDetails/index.ts +1 -0
  14. package/src/FeaturesInfosListener/FeaturesInfosListener.tsx +73 -0
  15. package/src/FeaturesInfosListener/index.tsx +1 -0
  16. package/src/GeolocationButton/GeolocationButton.tsx +0 -1
  17. package/src/LayerTree/LayerTree.tsx +58 -0
  18. package/src/LayerTree/TreeItem/TreeItem.tsx +151 -0
  19. package/src/LayerTree/TreeItem/index.tsx +1 -0
  20. package/src/LayerTree/index.tsx +1 -0
  21. package/src/LayerTree/layersTreeContext.ts +4 -0
  22. package/src/LayerTree/layersTreeReducer.ts +158 -0
  23. package/src/{RvfLayerTreeButton/RvfLayerTreeButton.tsx → LayerTreeButton/LayerTreeButton.tsx} +5 -5
  24. package/src/LayerTreeButton/index.tsx +1 -0
  25. package/src/{RvfTopics/RvfTopics.tsx → LayerTreeMenu/LayerTreeMenu.tsx} +17 -13
  26. package/src/LayerTreeMenu/index.tsx +1 -0
  27. package/src/LayoutState/LayoutState.tsx +277 -0
  28. package/src/LayoutState/index.tsx +1 -0
  29. package/src/LinesNetworkPlanDetails/LinesNetworkPlanDetails.tsx +292 -0
  30. package/src/LinesNetworkPlanDetails/index.tsx +1 -0
  31. package/src/{RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx → LinesNetworkPlanLayer/LinesNetworkPlanLayer.tsx} +7 -9
  32. package/src/LinesNetworkPlanLayer/index.tsx +1 -0
  33. package/src/MobilityMap/MobilityMap.tsx +274 -60
  34. package/src/MobilityMap/MobilityMapAttributes.ts +27 -43
  35. package/src/NotificationDetails/NotificationDetails.tsx +468 -0
  36. package/src/NotificationDetails/index.ts +1 -0
  37. package/src/{NotificationLayer/NotificationLayer.tsx → NotificationsLayer/NotificationsLayer.tsx} +9 -4
  38. package/src/NotificationsLayer/index.tsx +1 -0
  39. package/src/Overlay/Overlay.tsx +1 -6
  40. package/src/OverlayContent/OverlayContent.tsx +87 -0
  41. package/src/OverlayContent/index.ts +1 -0
  42. package/src/OverlayDetails/OverlayDetails.tsx +47 -0
  43. package/src/OverlayDetails/index.ts +1 -0
  44. package/src/OverlayDetailsFooter/OverlayDetailsFooter.tsx +51 -0
  45. package/src/OverlayDetailsFooter/index.tsx +1 -0
  46. package/src/OverlayDetailsHeader/OverlayDetailsHeader.tsx +35 -0
  47. package/src/OverlayDetailsHeader/index.ts +1 -0
  48. package/src/OverlayFooter/OverlayFooter.tsx +41 -0
  49. package/src/OverlayFooter/index.tsx +1 -0
  50. package/src/OverlayHeader/OverlayHeader.tsx +44 -0
  51. package/src/OverlayHeader/index.tsx +1 -0
  52. package/src/PermalinkInput/PermalinkInput.tsx +28 -0
  53. package/src/PermalinkInput/index.tsx +1 -0
  54. package/src/RouteSchedule/RouteSchedule.tsx +22 -18
  55. package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +22 -50
  56. package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +108 -104
  57. package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +189 -154
  58. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +12 -14
  59. package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +5 -5
  60. package/src/RvfMainLinkButton/RvfMainLinkButton.tsx +65 -0
  61. package/src/RvfMainLinkButton/index.tsx +1 -0
  62. package/src/RvfMobilityMap/RvfMobilityMap.tsx +182 -394
  63. package/src/RvfOverlayContent/RvfOverlayContent.tsx +2 -2
  64. package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -2
  65. package/src/RvfSearch/RvfSearch.tsx +1 -1
  66. package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -2
  67. package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +23 -23
  68. package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -2
  69. package/src/Search/Search.tsx +11 -2
  70. package/src/{RvfSearchButton/RvfSearchButton.tsx → SearchButton/SearchButton.tsx} +5 -5
  71. package/src/SearchButton/index.tsx +1 -0
  72. package/src/ShadowOverflow/ShadowOverflow.tsx +20 -0
  73. package/src/ShadowOverflow/index.tsx +1 -0
  74. package/src/{RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx → ShareMenu/PermalinkButton/PermalinkButton.tsx} +4 -4
  75. package/src/ShareMenu/PermalinkButton/index.tsx +1 -0
  76. package/src/{RvfShare/RvfShare.tsx → ShareMenu/ShareMenu.tsx} +9 -11
  77. package/src/ShareMenu/index.tsx +1 -0
  78. package/src/{RvfShareMenuButton/RvfShareMenuButton.tsx → ShareMenuButton/ShareMenuButton.tsx} +6 -6
  79. package/src/ShareMenuButton/index.tsx +1 -0
  80. package/src/SingleClickListener/SingleClickListener.tsx +55 -113
  81. package/src/SingleClickListener/index.tsx +1 -1
  82. package/src/Station/Station.tsx +10 -3
  83. package/src/StationsLayer/StationsLayer.tsx +0 -1
  84. package/src/StopsSearch/StopsSearch.tsx +3 -4
  85. package/src/StopsSearch/index.tsx +2 -1
  86. package/src/WindowMessageListener/WindowMessageListener.tsx +7 -1
  87. package/src/{RvfZoomButtons/RvfZoomButtons.tsx → ZoomButtons/ZoomButtons.tsx} +9 -12
  88. package/src/ZoomButtons/index.tsx +1 -0
  89. package/src/icons/Geolocation/airport-14-svgrepo-com.svg +41 -0
  90. package/src/ui/Button/Button.tsx +9 -2
  91. package/src/ui/Checkbox/Checkbox.tsx +32 -0
  92. package/src/ui/Checkbox/index.tsx +1 -0
  93. package/src/ui/IconButton/IconButton.tsx +24 -4
  94. package/src/ui/Input/Input.tsx +17 -0
  95. package/src/ui/Input/index.tsx +1 -0
  96. package/src/ui/InputCopy/InputCopy.tsx +86 -0
  97. package/src/ui/InputCopy/index.tsx +1 -0
  98. package/src/ui/Select/Select.tsx +24 -0
  99. package/src/ui/Select/index.tsx +1 -0
  100. package/src/utils/constants.ts +43 -42
  101. package/src/utils/hooks/useInitialLayersVisiblity.tsx +1 -1
  102. package/src/utils/hooks/useLayerConfig.tsx +2 -2
  103. package/src/utils/hooks/useLayersConfig.tsx +3 -3
  104. package/src/utils/hooks/useMapContext.tsx +67 -8
  105. package/src/utils/hooks/useRvfContext.tsx +0 -44
  106. package/src/NotificationLayer/index.tsx +0 -1
  107. package/src/RvfEmbedNavigation/DragPanWarning.ts +0 -124
  108. package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +0 -51
  109. package/src/RvfEmbedNavigation/index.js +0 -1
  110. package/src/RvfExportMenu/index.tsx +0 -1
  111. package/src/RvfExportMenuButton/index.tsx +0 -1
  112. package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +0 -44
  113. package/src/RvfFloatingMenu/index.tsx +0 -1
  114. package/src/RvfLayerTreeButton/index.tsx +0 -1
  115. package/src/RvfLineNetworkPlanLayer/index.tsx +0 -1
  116. package/src/RvfPermalink/RvfPermalink.tsx +0 -18
  117. package/src/RvfPermalink/index.tsx +0 -1
  118. package/src/RvfSearchButton/index.tsx +0 -1
  119. package/src/RvfShare/RvfPermalinkButton/index.tsx +0 -1
  120. package/src/RvfShare/index.tsx +0 -1
  121. package/src/RvfShareMenuButton/index.tsx +0 -1
  122. package/src/RvfTopics/index.tsx +0 -1
  123. package/src/RvfZoomButtons/index.tsx +0 -1
@@ -1,40 +1,37 @@
1
1
  import { memo } from "preact/compat";
2
- import { useEffect, useMemo, useRef, useState } from "preact/hooks";
3
- import { LiaMapSolid } from "react-icons/lia";
2
+ import { useMemo, useRef, useState } from "preact/hooks";
4
3
  import { twMerge } from "tailwind-merge";
5
4
 
6
5
  import BaseLayer from "../BaseLayer";
7
6
  import Copyright from "../Copyright";
7
+ import EmbedNavigation from "../EmbedNavigation";
8
+ import ExportMenuButton from "../ExportMenuButton";
9
+ import FeaturesInfosListener from "../FeaturesInfosListener";
8
10
  import GeolocationButton from "../GeolocationButton";
11
+ import LayerTreeButton from "../LayerTreeButton";
12
+ import LayoutState from "../LayoutState";
13
+ import LinesNetworkPlanLayer from "../LinesNetworkPlanLayer";
9
14
  import Map from "../Map";
10
15
  import MapDispatchEvents from "../MapDispatchEvents";
11
16
  import MobilityMapAttributes from "../MobilityMap/MobilityMapAttributes";
12
- import NotificationLayer from "../NotificationLayer";
17
+ import NotificationsLayer from "../NotificationsLayer";
13
18
  import Overlay from "../Overlay";
19
+ import OverlayContent from "../OverlayContent";
20
+ import Permalink from "../Permalink";
14
21
  import RealtimeLayer from "../RealtimeLayer";
15
- import RvfEmbedNavigation from "../RvfEmbedNavigation/RvfEmbedNavigation";
16
- import RvfExportMenuButton from "../RvfExportMenuButton";
17
- // import RvfFloatingMenu from "../RvfFloatingMenu";
18
- // import RvfLayerTree from "../RvfLayerTree";
19
- import RvfLayerTreeButton from "../RvfLayerTreeButton";
20
- // Notificationurl example: https://mobility-web-component-tmp.vercel.app/geops-mobility?notificationurl=https%3A%2F%2Fmoco.geops.io%2Fapi%2Fv1%2Fexport%2Fpublication%2F%3Fsso_config%3Drvf&geolocation=false&realtime=false&search=false&notificationat=2024-01-25T22%3A59%3A00Z
21
- import RvfLineNetworkPlanLayer from "../RvfLineNetworkPlanLayer";
22
- import RvfOverlayContent from "../RvfOverlayContent/RvfOverlayContent";
23
- // import Modal from "../RvfModal";
22
+ import RvfMainLinkButton from "../RvfMainLinkButton";
24
23
  import RvfPoisLayer from "../RvfPoisLayer";
25
- import RvfSearchButton from "../RvfSearchButton";
26
24
  import RvfSelectedFeatureHighlightLayer from "../RvfSelectedFeatureHighlightLayer";
27
25
  import RvfSellingPointsLayer from "../RvfSellingPointsLayer";
28
26
  import RvfSharedMobilityLayerGroup from "../RvfSharedMobilityLayerGroup";
29
- import RvfShareMenuButton from "../RvfShareMenuButton";
30
27
  import RvfTarifZonenLayer from "../RvfTarifZonenLayer";
31
- import RvfZoomButtons from "../RvfZoomButtons";
32
28
  import ScaleLine from "../ScaleLine";
33
29
  import Search from "../Search";
30
+ import SearchButton from "../SearchButton";
31
+ import ShareMenuButton from "../ShareMenuButton";
34
32
  import SingleClickListener from "../SingleClickListener";
35
33
  import StationsLayer from "../StationsLayer";
36
- import IconButton from "../ui/IconButton";
37
- import { RVF_LAYERS_TITLES } from "../utils/constants";
34
+ import { LAYERS_TITLES } from "../utils/constants";
38
35
  import fullTrajectoryStyle from "../utils/fullTrajectoryStyle";
39
36
  import getBgColor from "../utils/getBgColor";
40
37
  import { getRadius } from "../utils/getRadius";
@@ -43,10 +40,10 @@ import { I18nContext } from "../utils/hooks/useI18n";
43
40
  import useInitialLayersVisiblity from "../utils/hooks/useInitialLayersVisiblity";
44
41
  import { MapContext } from "../utils/hooks/useMapContext";
45
42
  import { RvfContext } from "../utils/hooks/useRvfContext";
46
- import useUpdatePermalink from "../utils/hooks/useUpdatePermalink";
47
43
  import i18n from "../utils/i18n";
48
44
  import realtimeRVFStyle from "../utils/realtimeRVFStyle";
49
45
  import WindowMessageListener from "../WindowMessageListener";
46
+ import ZoomButtons from "../ZoomButtons";
50
47
 
51
48
  // @ts-expect-error bad type definition
52
49
  import tailwind from "../style.css";
@@ -57,8 +54,10 @@ import type {
57
54
  MaplibreLayer,
58
55
  MaplibreStyleLayer,
59
56
  RealtimeLayer as MbtRealtimeLayer,
57
+ MocoLayer,
60
58
  } from "mobility-toolbox-js/ol";
61
59
  import type {
60
+ LayerGetFeatureInfoResponse,
62
61
  RealtimeStation,
63
62
  RealtimeStationId,
64
63
  RealtimeStopSequence,
@@ -149,117 +148,129 @@ const realtimeLayerProps = {
149
148
  function RvfMobilityMap(props: RvfMobilityMapProps) {
150
149
  const eventNodeRef = useRef<HTMLDivElement>();
151
150
  const [baseLayer, setBaseLayer] = useState<MaplibreLayer>();
152
- const [isFollowing, setIsFollowing] = useState(false);
153
- const [isTracking, setIsTracking] = useState(false);
151
+ const [isFollowing, setIsFollowing] = useState<boolean>(false);
152
+ const [isTracking, setIsTracking] = useState<boolean>(false);
153
+ const [isEmbed, setIsEmbed] = useState<boolean>(false);
154
+ const [hasGeolocation, setHasGeolocation] = useState<boolean>(false);
155
+ const [hasLnp, setHasLnp] = useState<boolean>(false);
156
+ const [hasDetails, setHasDetails] = useState<boolean>(false);
157
+ const [hasNotification, setHasNotification] = useState<boolean>(false);
158
+ const [hasPermalink, setHasPermalink] = useState<boolean>(false);
159
+ const [hasPrint, setHasPrint] = useState<boolean>(false);
160
+ const [hasRealtime, setHasRealtime] = useState<boolean>(false);
161
+ const [hasSearch, setHasSearch] = useState<boolean>(false);
162
+ const [hasStations, setHasStations] = useState<boolean>(false);
163
+ const [hasToolbar, setHasToolbar] = useState<boolean>(false);
164
+ const [hasShare, setHasShare] = useState<boolean>(false);
165
+ const [hasLayerTree, setHasLayerTree] = useState<boolean>(false);
166
+ const [isOverlayOpen, setIsOverlayOpen] = useState<boolean>(false);
167
+ const [isExportMenuOpen, setIsExportMenuOpen] = useState<boolean>(false);
168
+ const [isShareMenuOpen, setIsShareMenuOpen] = useState<boolean>(false);
169
+ const [isLayerTreeOpen, setIsLayerTreeOpen] = useState<boolean>(false);
170
+ const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);
154
171
  const [stopSequence, setStopSequence] = useState<RealtimeStopSequence>();
155
172
  const [stationsLayer, setStationsLayer] = useState<MaplibreStyleLayer>();
156
173
  const [station, setStation] = useState<RealtimeStation>();
157
174
  const [realtimeLayer, setRealtimeLayer] = useState<MbtRealtimeLayer>();
175
+ const [notificationsLayer, setNotificationsLayer] = useState<MocoLayer>();
176
+ const [linesNetworkPlanLayer, setLinesNetworkPlanLayer] =
177
+ useState<MaplibreStyleLayer>();
158
178
  const [map, setMap] = useState<OlMap>();
159
179
  const [stationId, setStationId] = useState<RealtimeStationId>();
160
180
  const [trainId, setTrainId] = useState<RealtimeTrainId>();
161
- const [isExportMenuOpen, setIsExportMenuOpen] = useState<boolean>(false);
162
- const [isShareMenuOpen, setIsShareMenuOpen] = useState<boolean>(false);
181
+ const [featuresInfos, setFeaturesInfos] = useState<
182
+ LayerGetFeatureInfoResponse[]
183
+ >([]);
184
+ const [featuresInfosHovered, setFeaturesInfosHovered] = useState<
185
+ LayerGetFeatureInfoResponse[]
186
+ >([]);
163
187
  const [selectedFeature, setSelectedFeature] = useState<Feature>();
164
188
  const [selectedFeatures, setSelectedFeatures] = useState<Feature[]>();
165
- const [isLayerTreeOpen, setIsLayerTreeOpen] = useState<boolean>(false);
166
- const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);
189
+
190
+ const [permalinkUrlSearchParams, setPermalinkUrlSearchParams] =
191
+ useState<URLSearchParams>();
167
192
  const [sellingPointsLayer, setSellingPointsLayer] =
168
193
  useState<MaplibreStyleLayer>();
169
194
  const [tarifZonenLayer, setTarifZonenLayer] = useState<MaplibreStyleLayer>();
170
195
  const [poisLayer, setPoisLayer] = useState<MaplibreStyleLayer>();
171
- const [lineNetworkPlanLayer, setLineNetworkPlanLayer] =
172
- useState<MaplibreStyleLayer>();
173
196
  const [sharedMobilityLayerGroup, setSharedMobilityLayerGroup] =
174
197
  useState<Group>();
175
198
 
176
199
  const [previewNotifications, setPreviewNotifications] =
177
200
  useState<SituationType[]>();
178
201
 
179
- const {
180
- details,
181
- embed,
182
- geolocation,
183
- layers,
184
- layertree,
185
- mainlink,
186
- mainlinktitle,
187
- notification,
188
- permalink,
189
- print,
190
- realtime,
191
- search,
192
- share,
193
- tenant,
194
- toolbar,
195
- } = props;
196
-
197
- // Convert string boolean to boolean
198
- const hasToolbar = useMemo(() => {
199
- return toolbar === "true";
200
- }, [toolbar]);
201
-
202
- const hasLayerTree = useMemo(() => {
203
- return layertree === "true";
204
- }, [layertree]);
205
-
206
- const hasRealtime = useMemo(() => {
207
- return realtime === "true";
208
- }, [realtime]);
209
-
210
- const hasNotification = useMemo(() => {
211
- return notification === "true" || !!previewNotifications;
212
- }, [notification, previewNotifications]);
213
-
214
- const hasGeolocation = useMemo(() => {
215
- return geolocation === "true";
216
- }, [geolocation]);
217
-
218
- const hasSearch = useMemo(() => {
219
- return search === "true";
220
- }, [search]);
221
-
222
- const hasShare = useMemo(() => {
223
- return share === "true";
224
- }, [share]);
225
-
226
- const hasPrint = useMemo(() => {
227
- return print === "true";
228
- }, [print]);
229
-
230
- const hasDetails = useMemo(() => {
231
- return details === "true";
232
- }, [details]);
233
-
234
- const isEmbed = useMemo(() => {
235
- return embed === "true";
236
- }, [embed]);
202
+ const { layers, mainlink } = props;
237
203
 
238
204
  // Apply initial visibility of layers
239
205
  useInitialLayersVisiblity(map, layers);
240
206
 
241
- // TODO: this should be removed. The parent application should be responsible to do this
242
- // or we should find something that fit more usecases
243
- useUpdatePermalink(map, permalink === "true", eventNodeRef);
244
-
245
207
  const mapContextValue = useMemo(() => {
246
208
  return {
247
209
  // MobilityMapProps
248
210
  ...props,
249
211
  // MapContextProps
250
212
  baseLayer,
251
- geolocation,
213
+ featuresInfos,
214
+ featuresInfosHovered,
215
+ hasDetails,
216
+ hasGeolocation,
217
+ hasLayerTree,
218
+ hasLnp,
219
+ hasNotification,
220
+ hasPermalink,
221
+ hasPrint,
222
+ hasRealtime,
223
+ hasSearch,
224
+ hasShare,
225
+ hasStations,
226
+ hasToolbar,
227
+ isEmbed,
228
+ isExportMenuOpen,
252
229
  isFollowing,
230
+ isLayerTreeOpen,
231
+ isOverlayOpen,
232
+ isSearchOpen,
233
+ isShareMenuOpen,
253
234
  isTracking,
235
+ linesNetworkPlanLayer,
254
236
  map,
237
+ notificationsLayer,
238
+ permalinkUrlSearchParams,
255
239
  previewNotifications,
256
240
  realtimeLayer,
241
+ selectedFeature,
242
+ selectedFeatures,
257
243
  setBaseLayer,
244
+ setFeaturesInfos,
245
+ setFeaturesInfosHovered,
246
+ setHasDetails,
247
+ setHasGeolocation,
248
+ setHasLayerTree,
249
+ setHasLnp,
250
+ setHasNotification,
251
+ setHasPermalink,
252
+ setHasPrint,
253
+ setHasRealtime,
254
+ setHasSearch,
255
+ setHasShare,
256
+ setHasStations,
257
+ setHasToolbar,
258
+ setIsEmbed,
259
+ setIsExportMenuOpen,
258
260
  setIsFollowing,
261
+ setIsLayerTreeOpen,
262
+ setIsOverlayOpen,
263
+ setIsSearchOpen,
264
+ setIsShareMenuOpen,
259
265
  setIsTracking,
266
+ setLinesNetworkPlanLayer,
260
267
  setMap,
268
+ setNotificationsLayer,
269
+ setPermalinkUrlSearchParams,
261
270
  setPreviewNotifications,
262
271
  setRealtimeLayer,
272
+ setSelectedFeature,
273
+ setSelectedFeatures,
263
274
  setStation,
264
275
  setStationId,
265
276
  setStationsLayer,
@@ -274,12 +285,36 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
274
285
  }, [
275
286
  props,
276
287
  baseLayer,
277
- geolocation,
288
+ featuresInfos,
289
+ featuresInfosHovered,
290
+ hasDetails,
291
+ hasGeolocation,
292
+ hasLayerTree,
293
+ hasLnp,
294
+ hasNotification,
295
+ hasPermalink,
296
+ hasPrint,
297
+ hasRealtime,
298
+ hasSearch,
299
+ hasShare,
300
+ hasStations,
301
+ hasToolbar,
302
+ isEmbed,
303
+ isExportMenuOpen,
278
304
  isFollowing,
305
+ isLayerTreeOpen,
306
+ isOverlayOpen,
307
+ isSearchOpen,
308
+ isShareMenuOpen,
279
309
  isTracking,
310
+ linesNetworkPlanLayer,
280
311
  map,
312
+ notificationsLayer,
313
+ permalinkUrlSearchParams,
281
314
  previewNotifications,
282
315
  realtimeLayer,
316
+ selectedFeature,
317
+ selectedFeatures,
283
318
  station,
284
319
  stationId,
285
320
  stationsLayer,
@@ -289,25 +324,9 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
289
324
 
290
325
  const rvfContextValue = useMemo(() => {
291
326
  return {
292
- isExportMenuOpen,
293
- isLayerTreeOpen,
294
- isSearchOpen,
295
- isShareMenuOpen,
296
- layertree,
297
- lineNetworkPlanLayer,
298
327
  poisLayer,
299
- previewNotifications,
300
- selectedFeature,
301
- selectedFeatures,
302
328
  sellingPointsLayer,
303
- setIsExportMenuOpen,
304
- setIsLayerTreeOpen,
305
- setIsSearchOpen,
306
- setIsShareMenuOpen,
307
- setLineNetworkPlanLayer,
308
329
  setPoisLayer,
309
- setSelectedFeature,
310
- setSelectedFeatures,
311
330
  setSellingPointsLayer,
312
331
  setSharedMobilityLayerGroup,
313
332
  setTarifZonenLayer,
@@ -315,29 +334,12 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
315
334
  tarifZonenLayer,
316
335
  };
317
336
  }, [
318
- isExportMenuOpen,
319
- isLayerTreeOpen,
320
- isSearchOpen,
321
- isShareMenuOpen,
322
- layertree,
323
- lineNetworkPlanLayer,
324
337
  poisLayer,
325
- previewNotifications,
326
- selectedFeature,
327
- selectedFeatures,
328
338
  sellingPointsLayer,
329
339
  sharedMobilityLayerGroup,
330
340
  tarifZonenLayer,
331
341
  ]);
332
342
 
333
- // const onLayerTreeMenuClick = useCallback(() => {
334
- // setIsLayerTreeOpen(!isLayerTreeOpen);
335
- // }, [isLayerTreeOpen]);
336
-
337
- // const onExportMenuClose = useCallback(() => {
338
- // setIsExportMenuOpen(false);
339
- // }, []);
340
-
341
343
  const copyrightOptions = useMemo(() => {
342
344
  return {
343
345
  format: (copyrights) => {
@@ -369,109 +371,6 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
369
371
  };
370
372
  }, []);
371
373
 
372
- useEffect(() => {
373
- if (isSearchOpen) {
374
- setIsLayerTreeOpen(false);
375
- setIsExportMenuOpen(false);
376
- setIsShareMenuOpen(false);
377
- setStationId(null);
378
- setTrainId(null);
379
- setSelectedFeature(null);
380
- }
381
- }, [isSearchOpen]);
382
-
383
- useEffect(() => {
384
- if (isShareMenuOpen) {
385
- setIsLayerTreeOpen(false);
386
- setIsExportMenuOpen(false);
387
- setIsSearchOpen(false);
388
- setStationId(null);
389
- setTrainId(null);
390
- setSelectedFeature(null);
391
- }
392
- }, [isShareMenuOpen]);
393
-
394
- useEffect(() => {
395
- if (isLayerTreeOpen) {
396
- setIsExportMenuOpen(false);
397
- setIsLayerTreeOpen(isLayerTreeOpen);
398
- setIsSearchOpen(false);
399
- setSelectedFeature(null);
400
- setTrainId(null);
401
- setStationId(null);
402
- setIsShareMenuOpen(false);
403
- }
404
- }, [isLayerTreeOpen]);
405
-
406
- useEffect(() => {
407
- if (isExportMenuOpen) {
408
- setIsLayerTreeOpen(false);
409
- setIsExportMenuOpen(isExportMenuOpen);
410
- setIsSearchOpen(false);
411
- setSelectedFeature(null);
412
- setTrainId(null);
413
- setIsShareMenuOpen(false);
414
- setStationId(null);
415
- }
416
- }, [isExportMenuOpen]);
417
-
418
- useEffect(() => {
419
- if (selectedFeature) {
420
- setIsLayerTreeOpen(false);
421
- setIsSearchOpen(false);
422
- setIsExportMenuOpen(false);
423
- setTrainId(null);
424
- setIsShareMenuOpen(false);
425
- setStationId(null);
426
- }
427
- }, [selectedFeature]);
428
-
429
- useEffect(() => {
430
- if (stationId) {
431
- setIsLayerTreeOpen(false);
432
- setIsExportMenuOpen(false);
433
- setIsSearchOpen(false);
434
- setTrainId(null);
435
- setIsShareMenuOpen(false);
436
- setSelectedFeature(null);
437
- }
438
- }, [stationId]);
439
-
440
- useEffect(() => {
441
- if (trainId) {
442
- setIsLayerTreeOpen(false);
443
- setIsExportMenuOpen(false);
444
- setIsSearchOpen(false);
445
- setStationId(null);
446
- setIsShareMenuOpen(false);
447
- setSelectedFeature(null);
448
- }
449
- }, [trainId]);
450
-
451
- const isOverlayDisplayed = useMemo(() => {
452
- return (
453
- (hasDetails && !!selectedFeature) ||
454
- (hasPrint && isExportMenuOpen) ||
455
- (hasLayerTree && isLayerTreeOpen) ||
456
- (hasShare && isShareMenuOpen) ||
457
- (hasRealtime && !!trainId) ||
458
- (tenant && !!stationId)
459
- );
460
- }, [
461
- hasDetails,
462
- selectedFeature,
463
- hasPrint,
464
- isExportMenuOpen,
465
- hasLayerTree,
466
- isLayerTreeOpen,
467
- hasShare,
468
- isShareMenuOpen,
469
- hasRealtime,
470
- trainId,
471
- tenant,
472
- stationId,
473
- ]);
474
-
475
374
  return (
476
375
  <I18nContext.Provider value={i18n}>
477
376
  {/* There is a bug in tailwindcss@4 , variables are not imported in the shadow dom
@@ -530,8 +429,13 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
530
429
  <style>{style}</style>
531
430
  <MapContext.Provider value={mapContextValue}>
532
431
  <RvfContext.Provider value={rvfContextValue}>
432
+ <LayoutState />
433
+ <Permalink replaceState={hasPermalink} />
533
434
  <MapDispatchEvents node={eventNodeRef.current} wcAttributes={props} />
534
435
  <WindowMessageListener eventNode={eventNodeRef.current} />
436
+ <SingleClickListener />
437
+ <FeaturesInfosListener />
438
+
535
439
  <div
536
440
  className="@container/main relative size-full overflow-hidden font-sans"
537
441
  ref={eventNodeRef}
@@ -540,57 +444,40 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
540
444
  <div className="relative flex size-full flex-col text-base @lg/main:flex-row-reverse">
541
445
  <Map className="relative flex-1 overflow-visible">
542
446
  <BaseLayer {...baseLayerProps} />
543
- <SingleClickListener eventNode={eventNodeRef.current} />
544
- {isEmbed && <RvfEmbedNavigation />}
545
-
447
+ {isEmbed && <EmbedNavigation />}
546
448
  {hasNotification && (
547
- <NotificationLayer
449
+ <NotificationsLayer
548
450
  isQueryable={true}
549
- title={RVF_LAYERS_TITLES.meldungen}
451
+ title={LAYERS_TITLES.notifications}
550
452
  />
551
453
  )}
552
-
553
454
  <RvfSelectedFeatureHighlightLayer />
554
-
555
455
  {hasRealtime && (
556
456
  <RealtimeLayer
557
- title={RVF_LAYERS_TITLES.echtzeit}
457
+ title={LAYERS_TITLES.realtime}
558
458
  {...realtimeLayerProps}
559
459
  />
560
460
  )}
561
-
562
461
  <StationsLayer
563
462
  minZoom={10}
564
- title={RVF_LAYERS_TITLES.haltestellen}
565
463
  {...stationsLayerProps}
464
+ title={LAYERS_TITLES.stations}
566
465
  />
567
- <RvfTarifZonenLayer title={RVF_LAYERS_TITLES.tarifzonen} />
568
- <RvfSellingPointsLayer
569
- isQueryable={true}
570
- title={RVF_LAYERS_TITLES.verkaufsstellen}
571
- />
572
- <RvfLineNetworkPlanLayer
573
- isQueryable={true}
574
- title={RVF_LAYERS_TITLES.liniennetz}
575
- />
576
- <RvfPoisLayer title={RVF_LAYERS_TITLES.pois} />
466
+ <RvfTarifZonenLayer title={LAYERS_TITLES.tarifzonen} />
467
+ <RvfSellingPointsLayer title={LAYERS_TITLES.verkaufsstellen} />
468
+ {hasLnp && (
469
+ <LinesNetworkPlanLayer
470
+ title={LAYERS_TITLES.linesnetworkplan}
471
+ />
472
+ )}
473
+ <RvfPoisLayer title={LAYERS_TITLES.pois} />
577
474
  <RvfSharedMobilityLayerGroup
578
- title={RVF_LAYERS_TITLES.sharedMobility}
475
+ title={LAYERS_TITLES.sharedMobility}
579
476
  />
580
-
581
477
  {mainlink && (
582
- <IconButton
583
- className={
584
- "absolute inset-x-2 bottom-8 z-10 rounded-xl border-3 border-white"
585
- }
586
- href={mainlink}
587
- target="_blank"
588
- theme="primary"
589
- title={mainlinktitle}
590
- >
591
- <LiaMapSolid />
592
- </IconButton>
478
+ <RvfMainLinkButton className="absolute inset-x-2 bottom-8 z-10" />
593
479
  )}
480
+
594
481
  <div className="pointer-events-none absolute inset-x-2 bottom-2 z-10 flex items-end justify-between gap-2 text-[10px]">
595
482
  <ScaleLine className="bg-slate-50/70" />
596
483
  <Copyright
@@ -598,53 +485,44 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
598
485
  options={copyrightOptions}
599
486
  />
600
487
  </div>
601
-
602
488
  <div className="absolute top-2 right-2 z-10 flex">
603
489
  {hasGeolocation && (
604
490
  <GeolocationButton title={"Geolokalisierung"} />
605
491
  )}
606
492
  </div>
607
-
608
493
  <div className="absolute right-2 bottom-10 z-10 flex flex-col justify-between gap-2">
609
- <RvfZoomButtons />
610
-
611
- {/* {!hasToolbar && hasLayerTree && (
612
- <RvfFloatingMenu
613
- isOpen={isLayerTreeOpen}
614
- onClick={onLayerTreeMenuClick}
615
- title="Kartendaten"
616
- >
617
- <Topics className={"w-full px-2"} />
618
- </RvfFloatingMenu>
619
- )} */}
494
+ <ZoomButtons />
620
495
  </div>
621
496
  </Map>
622
497
 
623
498
  <div className="pointer-events-none absolute top-2 bottom-2 left-2 z-10 flex flex-col gap-2 *:pointer-events-auto">
624
- <div
625
- className={
626
- "relative z-10 w-fit rounded-2xl bg-black/10 p-0 backdrop-blur-sm"
627
- }
628
- // className="w-fit rounded-2xl bg-black/10 p-1 backdrop-blur-sm">
629
- >
499
+ {hasToolbar && (
630
500
  <div
631
- className={twMerge(
632
- "absolute top-12 left-0 h-[40px] w-0 p-0 opacity-0 transition-all @sm:top-0 @sm:left-[calc(100%-43px)] @md:left-[calc(100%-47px)]",
633
- isSearchOpen ? "w-64 opacity-100" : "",
634
- )}
501
+ className={
502
+ "relative z-10 w-fit rounded-2xl bg-black/10 p-0 backdrop-blur-sm"
503
+ }
504
+ // className="w-fit rounded-2xl bg-black/10 p-1 backdrop-blur-sm">
635
505
  >
636
- <Search
637
- className={
638
- "border-grey @container m-0 h-[40px] rounded-2xl border p-2 px-4 text-base @sm/main:h-[44px] @sm/main:rounded-l-none @sm/main:rounded-r-2xl @md/main:h-[48px]"
639
- }
640
- inputClassName="h-6 text-base"
641
- inputContainerClassName="border-none"
642
- resultClassName="text-base **:hover:cursor-pointer hover:text-red-500 p-2"
643
- resultsContainerClassName="@container rounded-b-2xl max-h-[200px] overflow-y-auto border border-grey border-t-0 "
644
- withResultsClassName="text-base !rounded-b-none"
645
- />
646
- </div>
647
- {hasToolbar && (
506
+ {hasSearch && (
507
+ <div
508
+ className={twMerge(
509
+ "absolute top-12 left-0 h-[40px] w-0 p-0 opacity-0 transition-all @sm:top-0 @sm:left-[calc(100%-43px)] @md:left-[calc(100%-47px)]",
510
+ isSearchOpen ? "w-64 opacity-100" : "",
511
+ )}
512
+ >
513
+ <Search
514
+ className={
515
+ "border-grey @container m-0 h-[40px] rounded-2xl border p-2 px-4 text-base @sm/main:h-[44px] @sm/main:rounded-l-none @sm/main:rounded-r-2xl @md/main:h-[48px]"
516
+ }
517
+ inputClassName="h-6 text-base"
518
+ inputContainerClassName="border-none"
519
+ resultClassName="text-base **:hover:cursor-pointer hover:text-red-500 p-2"
520
+ resultsContainerClassName="@container rounded-b-2xl max-h-[200px] overflow-y-auto border border-grey border-t-0 "
521
+ withResultsClassName="text-base !rounded-b-none"
522
+ />
523
+ </div>
524
+ )}
525
+
648
526
  <div
649
527
  className={twMerge(
650
528
  "border-grey relative flex gap-[1px] overflow-hidden rounded-2xl border",
@@ -656,18 +534,18 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
656
534
  : "",
657
535
  )}
658
536
  >
659
- {hasPrint && <RvfExportMenuButton title={"Drucken"} />}
660
- {hasShare && <RvfShareMenuButton title={"Share"} />}
661
- {hasLayerTree && <RvfLayerTreeButton title={"Layers"} />}
662
- {hasSearch && <RvfSearchButton title={"Suche"} />}
537
+ {hasPrint && <ExportMenuButton title={"Drucken"} />}
538
+ {hasShare && <ShareMenuButton title={"Share"} />}
539
+ {hasLayerTree && <LayerTreeButton title={"Layers"} />}
540
+ {hasSearch && <SearchButton title={"Suche"} />}
663
541
  </div>
664
- )}
665
- </div>
542
+ </div>
543
+ )}
666
544
 
667
545
  <div
668
546
  className={twMerge(
669
547
  "flex w-0 flex-1 flex-col overflow-hidden rounded-2xl",
670
- isOverlayDisplayed ? "@lg:min-w-60" : "p-0",
548
+ isOverlayOpen ? "@lg:min-w-60" : "p-0",
671
549
  )}
672
550
  style={{ containerType: "normal" }}
673
551
  >
@@ -677,7 +555,7 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
677
555
  }
678
556
  ScrollableHandlerProps={scrollableHandlerProps}
679
557
  >
680
- <RvfOverlayContent
558
+ <OverlayContent
681
559
  hasDetails={hasDetails}
682
560
  hasLayerTree={hasLayerTree}
683
561
  hasPrint={hasPrint}
@@ -692,13 +570,13 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
692
570
  {/* Mobile */}
693
571
  <Overlay
694
572
  className={
695
- isOverlayDisplayed
573
+ isOverlayOpen
696
574
  ? "absolute bottom-0 z-20 flex max-h-[70%] min-h-[75px] w-full flex-col border-t bg-white @lg:hidden"
697
575
  : "@lg:hidden"
698
576
  }
699
577
  ScrollableHandlerProps={scrollableHandlerProps}
700
578
  >
701
- <RvfOverlayContent
579
+ <OverlayContent
702
580
  hasDetails={hasDetails}
703
581
  hasLayerTree={hasLayerTree}
704
582
  hasPrint={hasPrint}
@@ -707,96 +585,6 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
707
585
  hasShare={hasShare}
708
586
  />
709
587
  </Overlay>
710
-
711
- {/* {hasToolbar && (
712
- <div
713
- className={
714
- "z-[100] flex justify-around overflow-x-hidden border-t bg-white p-1 *:border-none @lg/main:block @lg/main:border-t-0 @lg/main:border-r @lg/main:p-0"
715
- }
716
- >
717
- {hasLayerTree && (
718
- <RvfLayerTreeButton
719
- className={"border-none"}
720
- title="Layers"
721
- />
722
- )}
723
-
724
- {hasPrint && (
725
- <RvfExportMenuButton
726
- className={"border-none"}
727
- title="Drucken"
728
- />
729
- )}
730
-
731
- {hasShare && (
732
- <RvfShareMenuButton
733
- className={"border-none"}
734
- title="Share"
735
- />
736
- )}
737
- </div>
738
- )} */}
739
-
740
- {/* Modal display */}
741
- {/* {!hasToolbar && hasPrint && isExportMenuOpen && (
742
- <Modal onClose={onExportMenuClose}>
743
- <RvfOverlayHeader
744
- onClose={() => {
745
- setIsExportMenuOpen(false);
746
- }}
747
- title="Drucken"
748
- ></RvfOverlayHeader>
749
- <RvfExportMenu className="relative flex flex-col gap-4 overflow-x-hidden overflow-y-auto px-4 py-4" />
750
- </Modal>
751
- )}
752
-
753
- {!hasToolbar && hasShare && isShareMenuOpen && (
754
- <Modal
755
- onClose={() => {
756
- setIsShareMenuOpen(false);
757
- }}
758
- >
759
- <RvfOverlayHeader
760
- onClose={() => {
761
- setIsShareMenuOpen(false);
762
- }}
763
- title="Share"
764
- ></RvfOverlayHeader>
765
- <RvfShare className="relative flex flex-col gap-4 overflow-x-hidden overflow-y-auto px-4 py-4" />
766
- </Modal>
767
- )}
768
-
769
- {!hasToolbar && hasLayerTree && isLayerTreeOpen && (
770
- <Modal
771
- onClose={() => {
772
- setIsLayerTreeOpen(false);
773
- }}
774
- >
775
- <RvfOverlayHeader
776
- onClose={() => {
777
- setIsLayerTreeOpen(false);
778
- }}
779
- title="Layers"
780
- ></RvfOverlayHeader>
781
- <Topics className="overflow-x-hidden overflow-y-auto px-4" />
782
- </Modal>
783
- )}
784
-
785
- {!hasToolbar && hasSearch && isSearchOpen && (
786
- <Modal
787
- onClose={() => {
788
- setIsSearchOpen(false);
789
- }}
790
- >
791
- <RvfOverlayHeader
792
- onClose={() => {
793
- setIsSearchOpen(false);
794
- }}
795
- title="Search"
796
- ></RvfOverlayHeader>
797
- <Search />
798
- </Modal>
799
- )} */}
800
588
  </div>
801
589
  </div>
802
590
  </RvfContext.Provider>