@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,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 NotificationLayer from "../NotificationLayer";
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 SingleClickListener from "../SingleClickListener/SingleClickListener";
18
- import Station from "../Station";
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
- <div className="absolute top-2 right-2 z-10 flex">
188
- {hasGeolocation && <GeolocationButton />}
315
+
316
+ <div className="absolute right-2 bottom-10 z-10 flex flex-col justify-between gap-2">
317
+ <ZoomButtons />
189
318
  </div>
190
- {hasSearch && (
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
- <Overlay
198
- className={"z-50"}
199
- ScrollableHandlerProps={{
200
- style: { width: "calc(100% - 60px)" },
201
- }}
202
- >
203
- {hasRealtime && trainId && (
204
- <RouteSchedule className="relative overflow-x-hidden overflow-y-auto" />
205
- )}
206
- {tenant && stationId && (
207
- <Station className="relative overflow-x-hidden overflow-y-auto" />
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
- </Overlay>
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
- RVF_EXTENT_3857,
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
- "Show shared mobility details in the sidebar when we click on an shared mobility feature.",
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: RVF_EXTENT_3857.join(","),
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(RVF_LAYERS_NAMES).join(", ")}.`,
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
- // defaultValue: "https://www.rvf.de/",
156
- description: "A link displayed on bottom left of the map.",
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, //`The ${geopsMapsApiLink} url to use.`,
151
+ description: null,
165
152
  },
166
153
  maxextent: {
167
- defaultValue: RVF_EXTENT_3857.join(","),
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, // `The ${geopsMocoApiLink} tenant to get the notification from.`,
179
+ description: null,
195
180
  },
196
181
  notificationurl: {
197
182
  defaultValue: "https://moco.geops.io/api/v2/",
198
- description: null, // `The ${geopsMocoApiLink} url to use.`,
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
- "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.",
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, //`Add the realtime layer to the map. Data comes from the ${geopsRealtimeApiLink} .`,
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, // `The ${geopsRealtimeApiLink} tenant to get the realtime data from.`,
211
+ description: null,
228
212
  },
229
213
  realtimeurl: {
230
214
  defaultValue: "wss://api.geops.io/tracker-ws/v1/ws",
231
- description: null, //`The ${geopsRealtimeApiLink} url to use.`,
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, // `The ${geopsStopsApiLink} to use.`,
235
+ description: null,
252
236
  },
253
237
  tenant: {
254
- description: null, //`The tenant to use by default for all geOps APIs (Stops, Realtime, MOCO ...). Can be override for each API by other XXXXtenant parameters.`,
238
+ description: null,
255
239
  },
256
240
  toolbar: {
257
241
  defaultValue: "true",