@geops/rvf-mobility-web-component 0.1.46 → 0.1.47-beta.0

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 (194) hide show
  1. package/.prettierrc.js +3 -1
  2. package/README.md +1 -1
  3. package/doc/package.json +4 -3
  4. package/doc/postcss.config.mjs +1 -1
  5. package/doc/src/app/components/GeopsMobilityDoc.tsx +13 -224
  6. package/doc/src/app/components/GeopsMobilitySearchDoc.tsx +11 -107
  7. package/doc/src/app/components/WebComponentDoc.tsx +45 -56
  8. package/doc/src/app/geops-mobility/page.tsx +7 -2
  9. package/doc/src/app/geops-mobility-search/page.tsx +6 -2
  10. package/doc/src/app/globals.css +47 -27
  11. package/doc/src/app/layout.tsx +4 -2
  12. package/docutils.js +33 -17
  13. package/eslint.config.mjs +28 -34
  14. package/iframe.html +5624 -201
  15. package/index.html +108 -88
  16. package/index.js +2229 -1976
  17. package/input.css +21 -3
  18. package/package.json +37 -40
  19. package/scripts/build.mjs +2 -2
  20. package/scripts/dev.mjs +3 -3
  21. package/search.html +70 -23
  22. package/src/BaseLayer/BaseLayer.tsx +2 -1
  23. package/src/Copyright/Copyright.tsx +4 -2
  24. package/src/DebugDeparture/DebugDeparture.tsx +16 -12
  25. package/src/DebugStop/DebugStop.tsx +2 -2
  26. package/src/Departure/Departure.tsx +2 -3
  27. package/src/EmbedNavigation/DragPanWarning.ts +125 -0
  28. package/src/EmbedNavigation/EmbedNavigation.tsx +52 -0
  29. package/src/EmbedNavigation/index.js +1 -0
  30. package/src/EmbedNavigation/index.tsx +1 -0
  31. package/src/GeolocationButton/GeolocationButton.tsx +11 -35
  32. package/src/GeolocationButton/index.tsx +1 -1
  33. package/src/Map/Map.tsx +5 -3
  34. package/src/MapDispatchEvents/MapDispatchEvents.tsx +78 -0
  35. package/src/MapDispatchEvents/index.tsx +1 -0
  36. package/src/MobilityMap/MobilityMap.tsx +117 -162
  37. package/src/MobilityMap/MobilityMapAttributes.test.ts +21 -0
  38. package/src/MobilityMap/MobilityMapAttributes.ts +243 -0
  39. package/src/MobilityMap/index.tsx +1 -0
  40. package/src/MobilitySearch/MobilitySearch.tsx +35 -0
  41. package/src/MobilitySearch/MobilitySearchAttributes.test.ts +21 -0
  42. package/src/MobilitySearch/MobilitySearchAttributes.ts +68 -0
  43. package/src/MobilitySearch/index.ts +2 -0
  44. package/src/NotificationLayer/NotificationLayer.tsx +27 -4
  45. package/src/Overlay/Overlay.tsx +24 -11
  46. package/src/Permalink/Permalink.tsx +77 -0
  47. package/src/Permalink/index.tsx +1 -0
  48. package/src/RealtimeLayer/RealtimeLayer.tsx +72 -33
  49. package/src/RouteDestination/RouteDestination.tsx +3 -3
  50. package/src/RouteIcon/RouteIcon.tsx +33 -25
  51. package/src/RouteIcon/index.tsx +1 -1
  52. package/src/RouteIdentifier/RouteIdentifer.tsx +6 -5
  53. package/src/RouteInfos/RouteInfos.tsx +7 -3
  54. package/src/RouteSchedule/RouteSchedule.tsx +3 -3
  55. package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +1 -1
  56. package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +7 -29
  57. package/src/RouteStop/RouteStop.tsx +8 -11
  58. package/src/RouteStopDelay/RouteStopDelay.tsx +2 -1
  59. package/src/RouteStopName/RouteStopName.tsx +2 -2
  60. package/src/RouteStopPlatform/RouteStopPlatform.tsx +2 -2
  61. package/src/RouteStopProgress/RouteStopProgress.tsx +2 -1
  62. package/src/RouteStopServices/RouteStopServices.tsx +2 -2
  63. package/src/RouteStopStation/RouteStopStation.tsx +8 -2
  64. package/src/RouteStopTime/RouteStopTime.tsx +2 -1
  65. package/src/RvfButton/RvfButton.tsx +14 -5
  66. package/src/RvfCheckbox/RvfCheckbox.tsx +8 -8
  67. package/src/RvfEmbedNavigation/DragPanWarning.ts +5 -5
  68. package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +1 -0
  69. package/src/RvfExportMenu/RvfExportMenu.tsx +14 -12
  70. package/src/RvfExportMenuButton/RvfExportMenuButton.tsx +6 -7
  71. package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +5 -5
  72. package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +164 -138
  73. package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +151 -109
  74. package/src/RvfFeatureDetails/RvfSellingPointDetails/RvfSellingPointDetails.tsx +2 -2
  75. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/FloatingVehiclesDetails/FloatingVehiclesDetails.tsx +3 -3
  76. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +8 -6
  77. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/StationDetails/StationDetails.tsx +5 -4
  78. package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +81 -0
  79. package/src/RvfFeatureDetailsTitle/index.tsx +1 -0
  80. package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +4 -4
  81. package/src/RvfGeolocationButton/GeolocationButton.tsx +98 -0
  82. package/src/RvfGeolocationButton/index.tsx +1 -0
  83. package/src/RvfIconButton/RvfIconButton.tsx +20 -9
  84. package/src/RvfInputCopy/RvfInputCopy.tsx +8 -8
  85. package/src/RvfLayerTree/RvfLayerTree.tsx +5 -2
  86. package/src/RvfLayerTree/TreeItem/TreeItem.tsx +13 -16
  87. package/src/RvfLayerTree/layersTreeReducer.ts +23 -18
  88. package/src/RvfLayerTreeButton/RvfLayerTreeButton.tsx +6 -6
  89. package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +2 -1
  90. package/src/RvfLink/RvfLink.tsx +4 -3
  91. package/src/RvfMobilityMap/RvfMobilityMap.tsx +314 -322
  92. package/src/RvfModal/RvfModal.tsx +4 -3
  93. package/src/RvfOverlayContent/RvfOverlayContent.tsx +126 -0
  94. package/src/RvfOverlayContent/index.ts +0 -0
  95. package/src/RvfOverlayHeader/RvfOverlayHeader.tsx +13 -10
  96. package/src/RvfPermalink/RvfPermalink.tsx +2 -2
  97. package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -1
  98. package/src/RvfRadioButton/RvfRadioButton.tsx +1 -1
  99. package/src/RvfRouteIcon/RvfRouteIcon.tsx +10 -0
  100. package/src/RvfRouteIcon/index.tsx +1 -0
  101. package/src/RvfSearch/RvfSearch.tsx +4 -1
  102. package/src/RvfSearchButton/RvfSearchButton.tsx +27 -0
  103. package/src/RvfSearchButton/index.tsx +1 -0
  104. package/src/RvfSelect/RvfSelect.tsx +7 -5
  105. package/src/RvfSelectedFeatureHighlightLayer/RvfSelectedFeatureHighlightLayer.tsx +1 -2
  106. package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -1
  107. package/src/RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx +13 -12
  108. package/src/RvfShare/RvfShare.tsx +11 -10
  109. package/src/RvfShareMenuButton/RvfShareMenuButton.tsx +5 -5
  110. package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +25 -22
  111. package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +46 -31
  112. package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -1
  113. package/src/RvfTopics/RvfTopics.tsx +6 -5
  114. package/src/RvfZoomButtons/RvfZoomButtons.tsx +3 -3
  115. package/src/ScaleLine/ScaleLine.tsx +5 -4
  116. package/src/ScrollableHandler/ScrollableHandler.tsx +2 -1
  117. package/src/ScrollableHandler/index.tsx +1 -1
  118. package/src/SingleClickListener/SingleClickListener.tsx +47 -4
  119. package/src/Station/Station.tsx +5 -5
  120. package/src/StationName/StationName.tsx +3 -3
  121. package/src/StationServices/StationServices.tsx +3 -3
  122. package/src/StationsLayer/StationsLayer.tsx +5 -4
  123. package/src/StopsSearch/StopsSearch.tsx +115 -84
  124. package/src/WindowMessageListener/WindowMessageListener.tsx +67 -0
  125. package/src/WindowMessageListener/index.tsx +1 -0
  126. package/src/icons/Airport/Airport.tsx +4 -4
  127. package/src/icons/ArrowDown/ArrowDown.tsx +1 -1
  128. package/src/icons/ArrowUp/ArrowUp.tsx +1 -1
  129. package/src/icons/ArrowUpRight/ArrowUpRight.tsx +1 -1
  130. package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +2 -2
  131. package/src/icons/Bathroom/Bathroom.tsx +1 -1
  132. package/src/icons/Copy/Copy.tsx +1 -1
  133. package/src/icons/Doc/Doc.tsx +1 -1
  134. package/src/icons/Email/Email.tsx +1 -1
  135. package/src/icons/FilePdf/FilePdf.tsx +1 -1
  136. package/src/icons/Geolocation/Geolocation.tsx +3 -5
  137. package/src/icons/Image/Image.tsx +1 -1
  138. package/src/icons/Menu/Menu.tsx +1 -1
  139. package/src/icons/Minus/Minus.tsx +1 -1
  140. package/src/icons/NoRealtime/NoRealtime.tsx +1 -1
  141. package/src/icons/Plus/Plus.tsx +1 -1
  142. package/src/icons/Police/Police.tsx +3 -3
  143. package/src/icons/Share/Share.tsx +1 -1
  144. package/src/icons/Stack/Stack.tsx +1 -1
  145. package/src/icons/Tracking/Tracking.tsx +29 -0
  146. package/src/icons/Tracking/airport-14-svgrepo-com.svg +41 -0
  147. package/src/icons/Tracking/index.tsx +1 -0
  148. package/src/icons/WaitingAreas/WaitingAreas.tsx +1 -1
  149. package/src/icons/WheelChair/WheelChair.tsx +1 -1
  150. package/src/index.tsx +8 -46
  151. package/src/indexDoc.ts +13 -0
  152. package/src/ui/Button/Button.tsx +57 -0
  153. package/src/ui/Button/index.tsx +1 -0
  154. package/src/ui/IconButton/IconButton.tsx +44 -0
  155. package/src/ui/IconButton/index.tsx +1 -0
  156. package/src/utils/MobilityEvent.ts +4 -3
  157. package/src/utils/applyInitialLayerVisibility.ts +3 -3
  158. package/src/utils/centerOnStation.ts +3 -2
  159. package/src/utils/centerOnVehicle.ts +5 -4
  160. package/src/utils/constants.ts +17 -3
  161. package/src/utils/exportPdf.ts +26 -20
  162. package/src/utils/fullTrajectoryStyle.ts +2 -2
  163. package/src/utils/getAllLayers.ts +4 -3
  164. package/src/utils/getDelayColor.test.ts +1 -0
  165. package/src/utils/getDelayColorForVehicle.test.ts +2 -0
  166. package/src/utils/getDelayString.test.ts +3 -0
  167. package/src/utils/getDelayTextForVehicle.test.ts +4 -0
  168. package/src/utils/getFullTrajectoryAndFit.ts +4 -3
  169. package/src/utils/getHoursAndMinutes.test.ts +1 -0
  170. package/src/utils/getLayersAsFlatArray.ts +2 -2
  171. package/src/utils/getLinkByDevice.ts +1 -1
  172. package/src/utils/getMainColorForVehicle.ts +3 -3
  173. package/src/utils/getPermalinkParameters.ts +2 -2
  174. package/src/utils/getStopStatus.test.ts +2 -1
  175. package/src/utils/getStopStatus.ts +1 -1
  176. package/src/utils/getTextForVehicle.ts +1 -1
  177. package/src/utils/hooks/useDeparture.tsx +6 -5
  178. package/src/utils/hooks/useI18n.tsx +6 -4
  179. package/src/utils/hooks/useInitialLayersVisiblity.tsx +2 -1
  180. package/src/utils/hooks/useLayerConfig.tsx +39 -0
  181. package/src/utils/hooks/useMapContext.tsx +30 -18
  182. package/src/utils/hooks/useRouteStop.tsx +3 -2
  183. package/src/utils/hooks/useRvfContext.tsx +11 -3
  184. package/src/utils/hooks/useStation.tsx +2 -1
  185. package/src/utils/hooks/useUpdatePermalink.tsx +25 -24
  186. package/src/utils/hooks/useZoom.tsx +4 -4
  187. package/src/utils/realtimeRVFStyle.ts +5 -4
  188. package/src/utils/sharingGraphqlUtils.ts +3 -2
  189. package/src/utils/sharingStylesUtils.ts +7 -7
  190. package/src/utils/sharingWFSUtils.ts +9 -15
  191. package/tailwind.config.mjs +1 -0
  192. package/tsconfig.json +1 -1
  193. package/doc/tailwind.config.ts +0 -20
  194. package/src/utils/getFeatureInformationTitle.tsx +0 -54
@@ -1,13 +1,13 @@
1
- import type { RealtimeMot, RealtimeTrainId } from "mobility-toolbox-js/types";
2
-
3
- import { RealtimeLayer as MtbRealtimeLayer } from "mobility-toolbox-js/ol";
4
- import { RealtimeLayerOptions } from "mobility-toolbox-js/ol/layers/RealtimeLayer";
1
+ import {
2
+ getGraphByZoom,
3
+ RealtimeLayer as MtbRealtimeLayer,
4
+ } from "mobility-toolbox-js/ol";
5
5
  import { unByKey } from "ol/Observable";
6
6
  import { memo } from "preact/compat";
7
7
  import { useEffect, useMemo } from "preact/hooks";
8
8
 
9
9
  import centerOnVehicle from "../utils/centerOnVehicle";
10
- import { RVF_LAYERS_NAMES } from "../utils/constants";
10
+ import { LAYER_NAME_REALTIME } from "../utils/constants";
11
11
  import getDelayColorForVehicle from "../utils/getDelayColorForVehicle";
12
12
  import getDelayFontForVehicle from "../utils/getDelayFontForVehicle";
13
13
  import getDelayTextForVehicle from "../utils/getDelayTextForVehicle";
@@ -15,17 +15,26 @@ import getTextFontForVehicle from "../utils/getTextFontForVehicle";
15
15
  import getTextForVehicle from "../utils/getTextForVehicle";
16
16
  import useMapContext from "../utils/hooks/useMapContext";
17
17
 
18
- const TRACKING_ZOOM = 16;
18
+ import type { RealtimeLayerOptions } from "mobility-toolbox-js/ol/layers/RealtimeLayer";
19
+ import type {
20
+ RealtimeMot,
21
+ RealtimeStation,
22
+ RealtimeTrainId,
23
+ StyleMetadataGraphs,
24
+ } from "mobility-toolbox-js/types";
19
25
 
20
- export type RealtimeLayerProps = RealtimeLayerOptions & Record<string, unknown>;
26
+ const TRACKING_ZOOM = 16;
27
+ const useGraphs = false;
21
28
 
22
- function RealtimeLayer(props: RealtimeLayerProps) {
29
+ function RealtimeLayer(props: Partial<RealtimeLayerOptions>) {
23
30
  const {
24
31
  apikey,
32
+ baseLayer,
25
33
  isFollowing,
26
34
  isTracking,
27
35
  map,
28
36
  mots,
37
+ realtimebboxparameters,
29
38
  realtimeurl,
30
39
  setIsFollowing,
31
40
  setIsTracking,
@@ -42,14 +51,25 @@ function RealtimeLayer(props: RealtimeLayerProps) {
42
51
  if (!apikey || !realtimeurl) {
43
52
  return null;
44
53
  }
45
- const layer = new MtbRealtimeLayer({
54
+ const lay = new MtbRealtimeLayer({
46
55
  apiKey: apikey,
56
+ bboxParameters: realtimebboxparameters
57
+ ?.split(" ")
58
+ .reduce((acc, string) => {
59
+ if (!string) {
60
+ return acc;
61
+ }
62
+ const [key, value] = string.split("=");
63
+ acc[key] = value;
64
+ return acc;
65
+ }, {}),
47
66
  getMotsByZoom: mots
48
67
  ? () => {
49
68
  return mots.split(",") as RealtimeMot[];
50
69
  }
51
70
  : undefined,
52
- name: RVF_LAYERS_NAMES.echtzeit,
71
+ isQueryable: true,
72
+ name: LAYER_NAME_REALTIME,
53
73
  tenant,
54
74
  url: realtimeurl,
55
75
  zIndex: 1,
@@ -64,8 +84,8 @@ function RealtimeLayer(props: RealtimeLayerProps) {
64
84
  },
65
85
  });
66
86
 
67
- return layer;
68
- }, [apikey, mots, realtimeurl, tenant, props]);
87
+ return lay;
88
+ }, [apikey, realtimeurl, realtimebboxparameters, mots, tenant, props]);
69
89
 
70
90
  useEffect(() => {
71
91
  if (!map || !layer) {
@@ -153,11 +173,11 @@ function RealtimeLayer(props: RealtimeLayerProps) {
153
173
  // Once the map is zoomed on the vehicle we follow him, only recenter , no zoom changes.
154
174
  if (success === true) {
155
175
  interval = setInterval(() => {
156
- centerOnVehicle(layer?.trajectories?.[stopSequence.id], map);
176
+ void centerOnVehicle(layer?.trajectories?.[stopSequence.id], map);
157
177
  }, 1000);
158
178
  }
159
179
  };
160
- followVehicle(stopSequence.id);
180
+ void followVehicle(stopSequence.id);
161
181
 
162
182
  return () => {
163
183
  clearInterval(interval);
@@ -179,14 +199,11 @@ function RealtimeLayer(props: RealtimeLayerProps) {
179
199
  if (!stationId || !layer?.api) {
180
200
  return;
181
201
  }
182
- const subscribe = async () => {
183
- layer?.api?.subscribe(`station ${stationId}`, ({ content }) => {
184
- if (content) {
185
- setStation(content);
186
- }
187
- });
188
- };
189
- subscribe();
202
+ layer?.api?.subscribe(`station ${stationId}`, ({ content }) => {
203
+ if (content) {
204
+ setStation(content as RealtimeStation);
205
+ }
206
+ });
190
207
 
191
208
  return () => {
192
209
  setStation(null);
@@ -202,18 +219,19 @@ function RealtimeLayer(props: RealtimeLayerProps) {
202
219
  return;
203
220
  }
204
221
  layer.selectedVehicleId = trainId;
205
- layer.highlightTrajectory(trainId);
206
- const subscribe = async () => {
207
- layer?.api?.subscribeStopSequence(trainId, ({ content }) => {
208
- if (content) {
209
- const [firstStopSequence] = content;
210
- if (firstStopSequence) {
211
- setStopSequence(firstStopSequence);
212
- }
222
+ layer.highlightTrajectory(trainId).catch((err) => {
223
+ // eslint-disable-next-line no-console
224
+ console.error("Error highlighting trajectory:", err);
225
+ });
226
+
227
+ layer?.api?.subscribeStopSequence(trainId, ({ content }) => {
228
+ if (content) {
229
+ const [firstStopSequence] = content;
230
+ if (firstStopSequence) {
231
+ setStopSequence(firstStopSequence);
213
232
  }
214
- });
215
- };
216
- subscribe();
233
+ }
234
+ });
217
235
 
218
236
  return () => {
219
237
  setStopSequence(null);
@@ -225,6 +243,27 @@ function RealtimeLayer(props: RealtimeLayerProps) {
225
243
  };
226
244
  }, [trainId, layer, layer?.api, setStopSequence]);
227
245
 
246
+ // Get graphs value
247
+ useEffect(() => {
248
+ if (!map || !baseLayer || !useGraphs) {
249
+ return;
250
+ }
251
+ const key = map.once("rendercomplete", () => {
252
+ const metadata = baseLayer.mapLibreMap?.getStyle()?.metadata as {
253
+ graphs: StyleMetadataGraphs;
254
+ };
255
+ const graphByZoom = [];
256
+ for (let i = 0; i < 26; i++) {
257
+ graphByZoom.push(getGraphByZoom(i, metadata?.graphs));
258
+ }
259
+ layer.engine.graphByZoom = graphByZoom;
260
+ layer.engine.setBbox();
261
+ });
262
+ return () => {
263
+ unByKey(key);
264
+ };
265
+ }, [map, baseLayer, layer]);
266
+
228
267
  return null;
229
268
  }
230
269
 
@@ -1,8 +1,8 @@
1
- import type { RealtimeStopSequence } from "mobility-toolbox-js/types";
2
-
3
- import { JSX, PreactDOMAttributes } from "preact";
4
1
  import { memo } from "preact/compat";
5
2
 
3
+ import type { RealtimeStopSequence } from "mobility-toolbox-js/types";
4
+ import type { JSX, PreactDOMAttributes } from "preact";
5
+
6
6
  export type RouteDestinationProps = {
7
7
  stopSequence?: RealtimeStopSequence;
8
8
  } & JSX.HTMLAttributes<HTMLSpanElement> &
@@ -1,10 +1,4 @@
1
- import {
2
- RealtimeDeparture,
3
- RealtimeLine,
4
- RealtimeStopSequence,
5
- RealtimeTrajectory,
6
- } from "mobility-toolbox-js/types";
7
- import { JSX, PreactDOMAttributes } from "preact";
1
+ import { twMerge } from "tailwind-merge";
8
2
 
9
3
  import NoRealtime from "../icons/NoRealtime";
10
4
  import getMainColorForVehicle from "../utils/getMainColorForVehicle";
@@ -12,18 +6,30 @@ import getTextColor from "../utils/getTextColor";
12
6
  import getTextFontForVehicle from "../utils/getTextFontForVehicle";
13
7
  import getTextForVehicle from "../utils/getTextForVehicle";
14
8
 
9
+ import type {
10
+ RealtimeDeparture,
11
+ RealtimeLine,
12
+ RealtimeStopSequence,
13
+ RealtimeTrajectory,
14
+ } from "mobility-toolbox-js/types";
15
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
16
+
15
17
  export type RouteIconProps = {
18
+ className?: string;
16
19
  departure?: RealtimeDeparture;
20
+ displayNoRealtimeIcon?: boolean;
17
21
  line?: RealtimeLine;
18
22
  stopSequence?: RealtimeStopSequence;
19
23
  trajectory?: RealtimeTrajectory;
20
- } & JSX.HTMLAttributes<HTMLSpanElement> &
24
+ } & HTMLAttributes<HTMLSpanElement> &
21
25
  PreactDOMAttributes;
22
26
  const fontSizesByNbLetters = [16, 16, 16, 14, 12];
23
27
 
24
28
  function RouteIcon({
25
29
  children,
30
+ className,
26
31
  departure,
32
+ displayNoRealtimeIcon = false,
27
33
  line,
28
34
  stopSequence,
29
35
  trajectory,
@@ -57,24 +63,26 @@ function RouteIcon({
57
63
  }
58
64
 
59
65
  return (
60
- <>
61
- <span
62
- className="relative flex h-[40px] min-w-[40px] items-center justify-center rounded-full border px-1"
63
- style={{
64
- backgroundColor,
65
- borderColor,
66
- color,
67
- font,
68
- }}
69
- {...props}
70
- >
71
- {children || text}
66
+ <span
67
+ className={twMerge(
68
+ "relative flex h-[40px] min-w-[40px] items-center justify-center rounded-full border-2 px-1",
69
+ className,
70
+ )}
71
+ style={{
72
+ backgroundColor,
73
+ borderColor,
74
+ color,
75
+ font,
76
+ }}
77
+ {...props}
78
+ >
79
+ {children || text}
72
80
 
73
- {showNoRealtimeIcon && !isCancelled && !hasRealtime && (
74
- <NoRealtime className={"absolute -left-2 -top-2"} />
75
- )}
76
- </span>
77
- </>
81
+ {displayNoRealtimeIcon &&
82
+ showNoRealtimeIcon &&
83
+ !isCancelled &&
84
+ !hasRealtime && <NoRealtime className={"absolute -top-2 -left-2"} />}
85
+ </span>
78
86
  );
79
87
  }
80
88
  export default RouteIcon;
@@ -1 +1 @@
1
- export { default } from "./RouteIcon";
1
+ export { default } from "../RvfRouteIcon";
@@ -1,7 +1,8 @@
1
- import { RealtimeStopSequence } from "mobility-toolbox-js/types";
2
- import { JSX, PreactDOMAttributes } from "preact";
3
1
  import { memo } from "preact/compat";
4
2
 
3
+ import type { RealtimeStopSequence } from "mobility-toolbox-js/types";
4
+ import type { JSX, PreactDOMAttributes } from "preact";
5
+
5
6
  export type RouteIdentifierProps = {
6
7
  stopSequence?: RealtimeStopSequence;
7
8
  } & JSX.HTMLAttributes<HTMLSpanElement> &
@@ -14,11 +15,11 @@ function RouteIdentifier({ stopSequence, ...props }: RouteIdentifierProps) {
14
15
  // first part of the id, without leading zeros.
15
16
  let id = routeIdentifier;
16
17
 
17
- if (/\./.test(routeIdentifier)) {
18
+ if (routeIdentifier.includes(".")) {
18
19
  [id] = routeIdentifier.split(".");
19
- } else if (/_/.test(routeIdentifier)) {
20
+ } else if (routeIdentifier.includes("_")) {
20
21
  [id] = routeIdentifier.split("_");
21
- } else if (/:/.test(routeIdentifier)) {
22
+ } else if (routeIdentifier.includes(":")) {
22
23
  [id] = routeIdentifier.split(":");
23
24
  }
24
25
 
@@ -1,10 +1,11 @@
1
- import { RealtimeStopSequence } from "mobility-toolbox-js/types";
2
- import { JSX, PreactDOMAttributes } from "preact";
3
1
  import { memo } from "preact/compat";
4
2
 
5
3
  import RouteDestination from "../RouteDestination";
6
4
  import RouteIdentifier from "../RouteIdentifier";
7
5
 
6
+ import type { RealtimeStopSequence } from "mobility-toolbox-js/types";
7
+ import type { JSX, PreactDOMAttributes } from "preact";
8
+
8
9
  export type RouteInfosProps = {
9
10
  stopSequence?: RealtimeStopSequence;
10
11
  } & JSX.HTMLAttributes<HTMLDivElement> &
@@ -13,7 +14,10 @@ export type RouteInfosProps = {
13
14
  function RouteInfos({ stopSequence, ...props }: RouteInfosProps) {
14
15
  return (
15
16
  <div {...props}>
16
- <RouteDestination className="font-bold" stopSequence={stopSequence} />
17
+ <RouteDestination
18
+ className="text-base font-bold"
19
+ stopSequence={stopSequence}
20
+ />
17
21
  <RouteIdentifier className="text-sm" stopSequence={stopSequence} />
18
22
  </div>
19
23
  );
@@ -1,6 +1,3 @@
1
- import type { RealtimeStop } from "mobility-toolbox-js/types";
2
- import type { JSX, PreactDOMAttributes } from "preact";
3
-
4
1
  import { memo } from "preact/compat";
5
2
  import { useEffect, useRef } from "preact/hooks";
6
3
 
@@ -9,6 +6,9 @@ import RouteScheduleHeader from "../RouteScheduleHeader";
9
6
  import RouteStop from "../RouteStop";
10
7
  import useMapContext from "../utils/hooks/useMapContext";
11
8
 
9
+ import type { RealtimeStop } from "mobility-toolbox-js/types";
10
+ import type { JSX, PreactDOMAttributes } from "preact";
11
+
12
12
  export type RouteScheduleProps = JSX.HTMLAttributes<HTMLDivElement> &
13
13
  PreactDOMAttributes;
14
14
 
@@ -25,7 +25,7 @@ function RouteScheduleFooter() {
25
25
 
26
26
  return (
27
27
  <>
28
- <div className="m-4 mb-0 flex flex-wrap text-sm text-gray-500 ">
28
+ <div className="m-4 mb-0 flex flex-wrap text-sm text-gray-500">
29
29
  {stopSequence.operator &&
30
30
  defaultRenderLink(stopSequence.operator, stopSequence.operatorUrl)}
31
31
  {stopSequence.operator && stopSequence.publisher && <span> - </span>}
@@ -1,7 +1,9 @@
1
1
  import { memo } from "preact/compat";
2
2
 
3
+ import Tracking from "../icons/Tracking";
3
4
  import RouteIcon from "../RouteIcon";
4
5
  import RouteInfos from "../RouteInfos";
6
+ import IconButton from "../ui/IconButton";
5
7
  import getBgColor from "../utils/getBgColor";
6
8
  import useMapContext from "../utils/hooks/useMapContext";
7
9
 
@@ -11,13 +13,11 @@ function RouteScheduleHeader() {
11
13
  const backgroundColor = stroke || getBgColor(type || vehicleType);
12
14
  const color = textColor || "black";
13
15
  return (
14
- <div className="flex items-center gap-x-4 bg-slate-100 p-4">
16
+ <div className="flex items-center gap-x-4 bg-slate-100 p-4 py-2">
15
17
  <RouteIcon stopSequence={stopSequence} />
16
18
  <RouteInfos className="flex grow flex-col" stopSequence={stopSequence} />
17
- <button
18
- className={`flex size-[38px] flex-none items-center justify-center rounded-full bg-white p-1.5 shadow-lg ${
19
- isFollowing ? "animate-pulse" : ""
20
- }`}
19
+ <IconButton
20
+ className={`${isFollowing ? "animate-pulse" : ""}`}
21
21
  onClick={() => {
22
22
  setIsFollowing(!isFollowing);
23
23
  }}
@@ -26,31 +26,9 @@ function RouteScheduleHeader() {
26
26
  backgroundColor: isFollowing ? backgroundColor : "white",
27
27
  color: isFollowing ? color : "black",
28
28
  }}
29
- type="button"
30
29
  >
31
- <svg
32
- fill="none"
33
- height="24"
34
- part="svg"
35
- viewBox="0 0 14 14"
36
- width="24"
37
- xmlns="http://www.w3.org/2000/svg"
38
- >
39
- <path
40
- clipRule="evenodd"
41
- d="M7 0.333344C7.375 0.333344 7.66667 0.62501 7.66667 0.97921V2.35414C9.7292 2.66668 11.3333 4.27081 11.625 6.33334H13C13.375 6.33334 13.6667 6.62501 13.6667 7.00001C13.6667 7.37501 13.375 7.66668 13 7.66668H11.625C11.3333 9.70834 9.70833 11.3333 7.66667 11.625V13C7.66667 13.375 7.375 13.6667 7 13.6667C6.64587 13.6667 6.33333 13.375 6.33333 13V11.625C4.29167 11.3333 2.68747 9.70834 2.39587 7.66668H1C0.625 7.66668 0.333333 7.37501 0.333333 7.00001C0.333333 6.62501 0.625 6.33334 1 6.33334H2.39587C2.68747 4.27081 4.29167 2.66668 6.33333 2.35414V0.97921C6.33333 0.62501 6.64587 0.333344 7 0.333344ZM7 3.66668C5.16667 3.66668 3.66667 5.16668 3.66667 7.00001C3.66667 8.79168 5.08333 10.3125 7 10.3125C8.89587 10.3125 10.3333 8.81254 10.3333 7.00001C10.3333 5.16668 8.83333 3.66668 7 3.66668Z"
42
- fill="currentColor"
43
- fillRule="evenodd"
44
- />
45
- <path
46
- clipRule="evenodd"
47
- d="M5.66667 7.00001C5.66667 6.27081 6.2708 5.66668 7 5.66668C7.7292 5.66668 8.33333 6.27081 8.33333 7.00001C8.33333 7.72921 7.7292 8.33334 7 8.33334C6.2708 8.33334 5.66667 7.72921 5.66667 7.00001Z"
48
- fill="currentColor"
49
- fillRule="evenodd"
50
- part="circle"
51
- />
52
- </svg>
53
- </button>
30
+ <Tracking />
31
+ </IconButton>
54
32
  </div>
55
33
  );
56
34
  }
@@ -1,6 +1,3 @@
1
- import type { RealtimeStation, RealtimeStop } from "mobility-toolbox-js/types";
2
-
3
- import { JSX, PreactDOMAttributes } from "preact";
4
1
  import { memo } from "preact/compat";
5
2
  import { useEffect, useMemo, useState } from "preact/hooks";
6
3
 
@@ -13,6 +10,9 @@ import getStopStatus from "../utils/getStopStatus";
13
10
  import useMapContext from "../utils/hooks/useMapContext";
14
11
  import { RouteStopContext } from "../utils/hooks/useRouteStop";
15
12
 
13
+ import type { RealtimeStation, RealtimeStop } from "mobility-toolbox-js/types";
14
+ import type { JSX, PreactDOMAttributes } from "preact";
15
+
16
16
  export type RouteScheduleStopProps = {
17
17
  classNameGreyOut?: string;
18
18
  index?: number;
@@ -58,14 +58,11 @@ function RouteStop({
58
58
  if (!stopUID || !realtimeLayer?.api) {
59
59
  return;
60
60
  }
61
- const subscribe = async () => {
62
- realtimeLayer?.api?.subscribe(`station ${stopUID}`, ({ content }) => {
63
- if (content) {
64
- setStation(content);
65
- }
66
- });
67
- };
68
- subscribe();
61
+ realtimeLayer?.api?.subscribe(`station ${stopUID}`, ({ content }) => {
62
+ if (content) {
63
+ setStation(content);
64
+ }
65
+ });
69
66
 
70
67
  return () => {
71
68
  setStation(null);
@@ -1,10 +1,11 @@
1
- import { JSX, PreactDOMAttributes } from "preact";
2
1
  import { memo } from "preact/compat";
3
2
 
4
3
  import getDelayColor from "../utils/getDelayColor";
5
4
  import getDelayString from "../utils/getDelayString";
6
5
  import useRouteStop from "../utils/hooks/useRouteStop";
7
6
 
7
+ import type { JSX, PreactDOMAttributes } from "preact";
8
+
8
9
  export type RouteStopDelayProps = JSX.HTMLAttributes<HTMLDivElement> &
9
10
  PreactDOMAttributes;
10
11
 
@@ -1,10 +1,10 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { memo } from "preact/compat";
4
2
 
5
3
  import RouteStopPlatform from "../RouteStopPlatform";
6
4
  import useRouteStop from "../utils/hooks/useRouteStop";
7
5
 
6
+ import type { JSX, PreactDOMAttributes } from "preact";
7
+
8
8
  export type RouteStopNameProps = JSX.HTMLAttributes<HTMLDivElement> &
9
9
  PreactDOMAttributes;
10
10
 
@@ -1,11 +1,11 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { memo } from "preact/compat";
4
2
 
5
3
  import useI18n from "../utils/hooks/useI18n";
6
4
  import useMapContext from "../utils/hooks/useMapContext";
7
5
  import useRouteStop from "../utils/hooks/useRouteStop";
8
6
 
7
+ import type { JSX, PreactDOMAttributes } from "preact";
8
+
9
9
  export type RouteStopPlatformProps = JSX.HTMLAttributes<HTMLSpanElement> &
10
10
  PreactDOMAttributes;
11
11
 
@@ -1,10 +1,11 @@
1
- import { JSX, PreactDOMAttributes } from "preact";
2
1
  import { memo } from "preact/compat";
3
2
 
4
3
  import getMainColorForVehicle from "../utils/getMainColorForVehicle";
5
4
  import useMapContext from "../utils/hooks/useMapContext";
6
5
  import useRouteStop from "../utils/hooks/useRouteStop";
7
6
 
7
+ import type { JSX, PreactDOMAttributes } from "preact";
8
+
8
9
  export type RouteStopProgressProps = {
9
10
  lineColor?: string;
10
11
  svgProps?: JSX.HTMLAttributes<SVGElement> & PreactDOMAttributes;
@@ -1,10 +1,10 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { memo } from "preact/compat";
4
2
 
5
3
  import StationServices from "../StationServices";
6
4
  import useRouteStop from "../utils/hooks/useRouteStop";
7
5
 
6
+ import type { JSX, PreactDOMAttributes } from "preact";
7
+
8
8
  export type RouteStopNameProps = JSX.HTMLAttributes<HTMLDivElement> &
9
9
  PreactDOMAttributes;
10
10
 
@@ -1,11 +1,14 @@
1
- import { JSX, PreactDOMAttributes } from "preact";
2
1
  import { memo } from "preact/compat";
2
+ import { twMerge } from "tailwind-merge";
3
3
 
4
4
  import RouteStopName from "../RouteStopName";
5
5
  import RouteStopServices from "../RouteStopServices";
6
6
  import useRouteStop from "../utils/hooks/useRouteStop";
7
7
 
8
+ import type { JSX, PreactDOMAttributes } from "preact";
9
+
8
10
  export type RouteStopStationProps = {
11
+ className?: string;
9
12
  classNameCancelled?: string;
10
13
  } & JSX.HTMLAttributes<HTMLDivElement> &
11
14
  PreactDOMAttributes;
@@ -21,7 +24,10 @@ function RouteStopStation({
21
24
  return (
22
25
  <div
23
26
  {...props}
24
- className={`${className} ${status.isCancelled ? classNameCancelled : ""}`}
27
+ className={twMerge(
28
+ className,
29
+ status.isCancelled ? classNameCancelled : "",
30
+ )}
25
31
  >
26
32
  <RouteStopName />
27
33
  <RouteStopServices className="flex flex-wrap gap-1" />
@@ -1,9 +1,10 @@
1
- import { JSX, PreactDOMAttributes } from "preact";
2
1
  import { memo } from "preact/compat";
3
2
 
4
3
  import getHoursAndMinutes from "../utils/getHoursAndMinutes";
5
4
  import useRouteStop from "../utils/hooks/useRouteStop";
6
5
 
6
+ import type { JSX, PreactDOMAttributes } from "preact";
7
+
7
8
  export type RouteStopTimeProps = JSX.HTMLAttributes<HTMLDivElement> &
8
9
  PreactDOMAttributes;
9
10
 
@@ -1,16 +1,16 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { memo, useMemo } from "preact/compat";
4
2
  import { twMerge } from "tailwind-merge";
5
3
 
4
+ import type { ButtonProps } from "../ui/Button/Button";
5
+
6
6
  export type RvfButtonProps = {
7
+ className?: string;
7
8
  selected?: boolean;
8
9
  theme?: "primary" | "secondary";
9
- } & JSX.ButtonHTMLAttributes<HTMLButtonElement> &
10
- PreactDOMAttributes;
10
+ } & ButtonProps;
11
11
 
12
12
  const baseClasses =
13
- "flex gap-2 text-[14px] @sm/main:text-[16px] @md/main:text-[18px] h-[32px] @sm/main:h-[36px] @md/main:h-[40px] px-[22px] @sm/main:px-[22.5px] @md/main:px-[27.5px] pt-[7px] pb-[5px] @sm/main:pt-[8px] @sm/main:pb-[6px] @md/main:pt-[8.5px] @md/main:pb-[6.5px] items-center justify-left rounded-full border font-semibold text-button";
13
+ "flex gap-2 text-[14px] @sm:text-[16px] @md:text-[18px] h-[32px] @sm:h-[36px] @md:h-[40px] px-[22px] @sm:px-[22.5px] @md:px-[27.5px] pt-[7px] pb-[5px] @sm:pt-[8px] @sm:pb-[6px] @md:pt-[8.5px] @md:pb-[6.5px] items-center justify-left rounded-full border font-semibold text-button cursor-pointer disabled:cursor-default";
14
14
 
15
15
  export const themes = {
16
16
  primary: {
@@ -28,6 +28,7 @@ export const themes = {
28
28
  function RvfButton({
29
29
  children,
30
30
  className,
31
+ href,
31
32
  selected = false,
32
33
  theme = "secondary",
33
34
  ...props
@@ -38,6 +39,14 @@ function RvfButton({
38
39
  );
39
40
  }, [className, selected, theme]);
40
41
 
42
+ if (href) {
43
+ return (
44
+ <a className={classes} href={href} {...props}>
45
+ {children}
46
+ </a>
47
+ );
48
+ }
49
+
41
50
  return (
42
51
  <button className={classes} {...props}>
43
52
  {children}
@@ -1,26 +1,26 @@
1
- import type { JSX } from "preact";
2
-
3
1
  import { memo } from "preact/compat";
4
2
  import { twMerge } from "tailwind-merge";
5
3
 
6
4
  // @ts-expect-error - required for htm to resolve the JSX pragma
7
5
  import ok from "../icons/Ok/ok-grey.svg";
8
6
 
7
+ import type { InputHTMLAttributes } from "preact";
8
+
9
9
  export type RvfCheckboxProps = {
10
10
  checkedIconUrl?: string;
11
- } & JSX.InputHTMLAttributes<HTMLInputElement>;
11
+ className?: string;
12
+ } & InputHTMLAttributes<HTMLInputElement>;
12
13
 
13
14
  function RvfCheckbox({ className, ...props }: RvfCheckboxProps) {
14
15
  const checkedIconUrl = props.checkedIconUrl || ok;
15
16
  return (
16
17
  <input
17
- className={twMerge(`
18
- box-border size-[20px] flex-none cursor-pointer appearance-none rounded border-2 border-grey bg-white bg-contain bg-center text-grey disabled:cursor-default disabled:border-lightgrey ${className}`)}
18
+ className={twMerge(
19
+ `border-grey text-grey disabled:border-lightgrey box-border size-[20px] flex-none cursor-pointer appearance-none rounded border-2 bg-white bg-contain bg-center disabled:cursor-default ${className}`,
20
+ )}
19
21
  style={{
20
22
  backgroundImage:
21
- props.checked && !props.disabled
22
- ? `url('` + checkedIconUrl + `')`
23
- : "",
23
+ props.checked && !props.disabled ? `url('${checkedIconUrl}')` : "",
24
24
  }}
25
25
  {...props}
26
26
  type="checkbox"