@geops/rvf-mobility-web-component 0.1.45 → 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 (195) hide show
  1. package/.prettierrc.js +3 -1
  2. package/CHANGELOG.md +7 -0
  3. package/README.md +1 -1
  4. package/doc/package.json +4 -3
  5. package/doc/postcss.config.mjs +1 -1
  6. package/doc/src/app/components/GeopsMobilityDoc.tsx +13 -224
  7. package/doc/src/app/components/GeopsMobilitySearchDoc.tsx +11 -107
  8. package/doc/src/app/components/WebComponentDoc.tsx +45 -56
  9. package/doc/src/app/geops-mobility/page.tsx +7 -2
  10. package/doc/src/app/geops-mobility-search/page.tsx +6 -2
  11. package/doc/src/app/globals.css +47 -27
  12. package/doc/src/app/layout.tsx +4 -2
  13. package/docutils.js +33 -17
  14. package/eslint.config.mjs +28 -34
  15. package/iframe.html +5624 -201
  16. package/index.html +108 -88
  17. package/index.js +2229 -1976
  18. package/input.css +21 -3
  19. package/package.json +37 -40
  20. package/scripts/build.mjs +2 -2
  21. package/scripts/dev.mjs +3 -3
  22. package/search.html +70 -23
  23. package/src/BaseLayer/BaseLayer.tsx +2 -1
  24. package/src/Copyright/Copyright.tsx +4 -2
  25. package/src/DebugDeparture/DebugDeparture.tsx +16 -12
  26. package/src/DebugStop/DebugStop.tsx +2 -2
  27. package/src/Departure/Departure.tsx +2 -3
  28. package/src/EmbedNavigation/DragPanWarning.ts +125 -0
  29. package/src/EmbedNavigation/EmbedNavigation.tsx +52 -0
  30. package/src/EmbedNavigation/index.js +1 -0
  31. package/src/EmbedNavigation/index.tsx +1 -0
  32. package/src/GeolocationButton/GeolocationButton.tsx +11 -35
  33. package/src/GeolocationButton/index.tsx +1 -1
  34. package/src/Map/Map.tsx +5 -3
  35. package/src/MapDispatchEvents/MapDispatchEvents.tsx +78 -0
  36. package/src/MapDispatchEvents/index.tsx +1 -0
  37. package/src/MobilityMap/MobilityMap.tsx +117 -162
  38. package/src/MobilityMap/MobilityMapAttributes.test.ts +21 -0
  39. package/src/MobilityMap/MobilityMapAttributes.ts +243 -0
  40. package/src/MobilityMap/index.tsx +1 -0
  41. package/src/MobilitySearch/MobilitySearch.tsx +35 -0
  42. package/src/MobilitySearch/MobilitySearchAttributes.test.ts +21 -0
  43. package/src/MobilitySearch/MobilitySearchAttributes.ts +68 -0
  44. package/src/MobilitySearch/index.ts +2 -0
  45. package/src/NotificationLayer/NotificationLayer.tsx +27 -4
  46. package/src/Overlay/Overlay.tsx +24 -11
  47. package/src/Permalink/Permalink.tsx +77 -0
  48. package/src/Permalink/index.tsx +1 -0
  49. package/src/RealtimeLayer/RealtimeLayer.tsx +72 -33
  50. package/src/RouteDestination/RouteDestination.tsx +3 -3
  51. package/src/RouteIcon/RouteIcon.tsx +33 -25
  52. package/src/RouteIcon/index.tsx +1 -1
  53. package/src/RouteIdentifier/RouteIdentifer.tsx +6 -5
  54. package/src/RouteInfos/RouteInfos.tsx +7 -3
  55. package/src/RouteSchedule/RouteSchedule.tsx +3 -3
  56. package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +1 -1
  57. package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +7 -29
  58. package/src/RouteStop/RouteStop.tsx +8 -11
  59. package/src/RouteStopDelay/RouteStopDelay.tsx +2 -1
  60. package/src/RouteStopName/RouteStopName.tsx +2 -2
  61. package/src/RouteStopPlatform/RouteStopPlatform.tsx +2 -2
  62. package/src/RouteStopProgress/RouteStopProgress.tsx +2 -1
  63. package/src/RouteStopServices/RouteStopServices.tsx +2 -2
  64. package/src/RouteStopStation/RouteStopStation.tsx +8 -2
  65. package/src/RouteStopTime/RouteStopTime.tsx +2 -1
  66. package/src/RvfButton/RvfButton.tsx +14 -5
  67. package/src/RvfCheckbox/RvfCheckbox.tsx +8 -8
  68. package/src/RvfEmbedNavigation/DragPanWarning.ts +5 -5
  69. package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +1 -0
  70. package/src/RvfExportMenu/RvfExportMenu.tsx +14 -12
  71. package/src/RvfExportMenuButton/RvfExportMenuButton.tsx +6 -7
  72. package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +5 -5
  73. package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +164 -138
  74. package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +151 -109
  75. package/src/RvfFeatureDetails/RvfSellingPointDetails/RvfSellingPointDetails.tsx +2 -2
  76. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/FloatingVehiclesDetails/FloatingVehiclesDetails.tsx +3 -3
  77. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +8 -6
  78. package/src/RvfFeatureDetails/RvfSharedMobilityDetail/StationDetails/StationDetails.tsx +5 -4
  79. package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +81 -0
  80. package/src/RvfFeatureDetailsTitle/index.tsx +1 -0
  81. package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +4 -4
  82. package/src/RvfGeolocationButton/GeolocationButton.tsx +98 -0
  83. package/src/RvfGeolocationButton/index.tsx +1 -0
  84. package/src/RvfIconButton/RvfIconButton.tsx +20 -9
  85. package/src/RvfInputCopy/RvfInputCopy.tsx +8 -8
  86. package/src/RvfLayerTree/RvfLayerTree.tsx +5 -2
  87. package/src/RvfLayerTree/TreeItem/TreeItem.tsx +13 -16
  88. package/src/RvfLayerTree/layersTreeReducer.ts +23 -18
  89. package/src/RvfLayerTreeButton/RvfLayerTreeButton.tsx +6 -6
  90. package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +2 -1
  91. package/src/RvfLink/RvfLink.tsx +4 -3
  92. package/src/RvfMobilityMap/RvfMobilityMap.tsx +314 -322
  93. package/src/RvfModal/RvfModal.tsx +4 -3
  94. package/src/RvfOverlayContent/RvfOverlayContent.tsx +126 -0
  95. package/src/RvfOverlayContent/index.ts +0 -0
  96. package/src/RvfOverlayHeader/RvfOverlayHeader.tsx +13 -10
  97. package/src/RvfPermalink/RvfPermalink.tsx +2 -2
  98. package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -1
  99. package/src/RvfRadioButton/RvfRadioButton.tsx +1 -1
  100. package/src/RvfRouteIcon/RvfRouteIcon.tsx +10 -0
  101. package/src/RvfRouteIcon/index.tsx +1 -0
  102. package/src/RvfSearch/RvfSearch.tsx +4 -1
  103. package/src/RvfSearchButton/RvfSearchButton.tsx +27 -0
  104. package/src/RvfSearchButton/index.tsx +1 -0
  105. package/src/RvfSelect/RvfSelect.tsx +7 -5
  106. package/src/RvfSelectedFeatureHighlightLayer/RvfSelectedFeatureHighlightLayer.tsx +1 -2
  107. package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -1
  108. package/src/RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx +13 -12
  109. package/src/RvfShare/RvfShare.tsx +11 -10
  110. package/src/RvfShareMenuButton/RvfShareMenuButton.tsx +5 -5
  111. package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +25 -22
  112. package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +46 -31
  113. package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -1
  114. package/src/RvfTopics/RvfTopics.tsx +6 -5
  115. package/src/RvfZoomButtons/RvfZoomButtons.tsx +3 -3
  116. package/src/ScaleLine/ScaleLine.tsx +5 -4
  117. package/src/ScrollableHandler/ScrollableHandler.tsx +2 -1
  118. package/src/ScrollableHandler/index.tsx +1 -1
  119. package/src/SingleClickListener/SingleClickListener.tsx +47 -4
  120. package/src/Station/Station.tsx +5 -5
  121. package/src/StationName/StationName.tsx +3 -3
  122. package/src/StationServices/StationServices.tsx +3 -3
  123. package/src/StationsLayer/StationsLayer.tsx +5 -4
  124. package/src/StopsSearch/StopsSearch.tsx +115 -84
  125. package/src/WindowMessageListener/WindowMessageListener.tsx +67 -0
  126. package/src/WindowMessageListener/index.tsx +1 -0
  127. package/src/icons/Airport/Airport.tsx +4 -4
  128. package/src/icons/ArrowDown/ArrowDown.tsx +1 -1
  129. package/src/icons/ArrowUp/ArrowUp.tsx +1 -1
  130. package/src/icons/ArrowUpRight/ArrowUpRight.tsx +1 -1
  131. package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +2 -2
  132. package/src/icons/Bathroom/Bathroom.tsx +1 -1
  133. package/src/icons/Copy/Copy.tsx +1 -1
  134. package/src/icons/Doc/Doc.tsx +1 -1
  135. package/src/icons/Email/Email.tsx +1 -1
  136. package/src/icons/FilePdf/FilePdf.tsx +1 -1
  137. package/src/icons/Geolocation/Geolocation.tsx +3 -5
  138. package/src/icons/Image/Image.tsx +1 -1
  139. package/src/icons/Menu/Menu.tsx +1 -1
  140. package/src/icons/Minus/Minus.tsx +1 -1
  141. package/src/icons/NoRealtime/NoRealtime.tsx +1 -1
  142. package/src/icons/Plus/Plus.tsx +1 -1
  143. package/src/icons/Police/Police.tsx +3 -3
  144. package/src/icons/Share/Share.tsx +1 -1
  145. package/src/icons/Stack/Stack.tsx +1 -1
  146. package/src/icons/Tracking/Tracking.tsx +29 -0
  147. package/src/icons/Tracking/airport-14-svgrepo-com.svg +41 -0
  148. package/src/icons/Tracking/index.tsx +1 -0
  149. package/src/icons/WaitingAreas/WaitingAreas.tsx +1 -1
  150. package/src/icons/WheelChair/WheelChair.tsx +1 -1
  151. package/src/index.tsx +8 -46
  152. package/src/indexDoc.ts +13 -0
  153. package/src/ui/Button/Button.tsx +57 -0
  154. package/src/ui/Button/index.tsx +1 -0
  155. package/src/ui/IconButton/IconButton.tsx +44 -0
  156. package/src/ui/IconButton/index.tsx +1 -0
  157. package/src/utils/MobilityEvent.ts +4 -3
  158. package/src/utils/applyInitialLayerVisibility.ts +3 -3
  159. package/src/utils/centerOnStation.ts +3 -2
  160. package/src/utils/centerOnVehicle.ts +5 -4
  161. package/src/utils/constants.ts +17 -3
  162. package/src/utils/exportPdf.ts +26 -20
  163. package/src/utils/fullTrajectoryStyle.ts +2 -2
  164. package/src/utils/getAllLayers.ts +4 -3
  165. package/src/utils/getDelayColor.test.ts +1 -0
  166. package/src/utils/getDelayColorForVehicle.test.ts +2 -0
  167. package/src/utils/getDelayString.test.ts +3 -0
  168. package/src/utils/getDelayTextForVehicle.test.ts +4 -0
  169. package/src/utils/getFullTrajectoryAndFit.ts +4 -3
  170. package/src/utils/getHoursAndMinutes.test.ts +1 -0
  171. package/src/utils/getLayersAsFlatArray.ts +2 -2
  172. package/src/utils/getLinkByDevice.ts +1 -1
  173. package/src/utils/getMainColorForVehicle.ts +3 -3
  174. package/src/utils/getPermalinkParameters.ts +2 -2
  175. package/src/utils/getStopStatus.test.ts +2 -1
  176. package/src/utils/getStopStatus.ts +1 -1
  177. package/src/utils/getTextForVehicle.ts +1 -1
  178. package/src/utils/hooks/useDeparture.tsx +6 -5
  179. package/src/utils/hooks/useI18n.tsx +6 -4
  180. package/src/utils/hooks/useInitialLayersVisiblity.tsx +2 -1
  181. package/src/utils/hooks/useLayerConfig.tsx +39 -0
  182. package/src/utils/hooks/useMapContext.tsx +30 -18
  183. package/src/utils/hooks/useRouteStop.tsx +3 -2
  184. package/src/utils/hooks/useRvfContext.tsx +11 -3
  185. package/src/utils/hooks/useStation.tsx +2 -1
  186. package/src/utils/hooks/useUpdatePermalink.tsx +25 -24
  187. package/src/utils/hooks/useZoom.tsx +4 -4
  188. package/src/utils/realtimeRVFStyle.ts +5 -4
  189. package/src/utils/sharingGraphqlUtils.ts +3 -2
  190. package/src/utils/sharingStylesUtils.ts +7 -7
  191. package/src/utils/sharingWFSUtils.ts +9 -15
  192. package/tailwind.config.mjs +1 -0
  193. package/tsconfig.json +1 -1
  194. package/doc/tailwind.config.ts +0 -20
  195. package/src/utils/getFeatureInformationTitle.tsx +0 -54
@@ -1,7 +1,8 @@
1
- import { JSX, PreactDOMAttributes } from "preact";
2
1
  import { memo } from "preact/compat";
3
2
  import { useEffect, useState } from "preact/hooks";
4
3
 
4
+ import type { JSX, PreactDOMAttributes } from "preact";
5
+
5
6
  export type ModalProps = {
6
7
  onClose: () => void;
7
8
  } & JSX.HTMLAttributes<HTMLDialogElement> &
@@ -32,7 +33,7 @@ function RvfModal({ children, onClose, ...props }: ModalProps) {
32
33
  return (
33
34
  <dialog
34
35
  className={
35
- "absolute inset-0 z-50 flex size-full items-center justify-center bg-transparent"
36
+ "absolute inset-0 z-50 flex size-full flex-col items-center justify-center bg-transparent"
36
37
  }
37
38
  ref={(n) => {
38
39
  setNode(n);
@@ -44,7 +45,7 @@ function RvfModal({ children, onClose, ...props }: ModalProps) {
44
45
  className="absolute inset-0 z-0 size-full bg-black/60"
45
46
  onClick={onClose}
46
47
  ></button>
47
- <div className="z-10 h-3/4 w-1/2 bg-white">{children}</div>
48
+ <div className="z-10 flex h-3/4 w-1/2 flex-col bg-white">{children}</div>
48
49
  </dialog>
49
50
  );
50
51
  }
@@ -0,0 +1,126 @@
1
+ import { twMerge } from "tailwind-merge";
2
+
3
+ import RouteSchedule from "../RouteSchedule";
4
+ import RvfExportMenu from "../RvfExportMenu";
5
+ import RvfFeatureDetails from "../RvfFeatureDetails";
6
+ import RvfFeatureDetailsTitle from "../RvfFeatureDetailsTitle/RvfFeatureDetailsTitle";
7
+ import RvfOverlayHeader from "../RvfOverlayHeader";
8
+ import RvfShare from "../RvfShare";
9
+ import RvfTopics from "../RvfTopics";
10
+ import Search from "../Search";
11
+ import Station from "../Station";
12
+ import { RVF_LAYERS_TITLES } from "../utils/constants";
13
+ import useMapContext from "../utils/hooks/useMapContext";
14
+ import useRvfContext from "../utils/hooks/useRvfContext";
15
+
16
+ const contentClassName = `relative h-full overflow-x-hidden overflow-y-auto text-base`;
17
+
18
+ function RvfOverlayContent({
19
+ hasDetails,
20
+ hasLayerTree,
21
+ hasPrint,
22
+ hasRealtime,
23
+ hasSearch,
24
+ hasShare,
25
+ }: {
26
+ hasDetails: boolean;
27
+ hasLayerTree: boolean;
28
+ hasPrint: boolean;
29
+ hasRealtime: boolean;
30
+ hasSearch: boolean;
31
+ hasShare: boolean;
32
+ }) {
33
+ const {
34
+ isExportMenuOpen,
35
+ isLayerTreeOpen,
36
+ isSearchOpen,
37
+ isShareMenuOpen,
38
+ selectedFeature,
39
+ setIsExportMenuOpen,
40
+ setIsLayerTreeOpen,
41
+ setIsShareMenuOpen,
42
+ setSelectedFeature,
43
+ } = useRvfContext();
44
+ const { setStationId, setTrainId, stationId, tenant, trainId } =
45
+ useMapContext();
46
+ return (
47
+ <>
48
+ {hasRealtime && trainId && (
49
+ <>
50
+ <RvfOverlayHeader
51
+ onClose={() => {
52
+ setTrainId(null);
53
+ }}
54
+ title={RVF_LAYERS_TITLES.echtzeit}
55
+ ></RvfOverlayHeader>
56
+ <RouteSchedule className={contentClassName} />
57
+ </>
58
+ )}
59
+ {tenant && stationId && (
60
+ <>
61
+ <RvfOverlayHeader
62
+ onClose={() => {
63
+ setStationId(null);
64
+ }}
65
+ title="Station"
66
+ ></RvfOverlayHeader>
67
+ <Station className={twMerge(contentClassName, "flex flex-col p-2")} />
68
+ </>
69
+ )}
70
+ {hasDetails && selectedFeature && (
71
+ <>
72
+ <RvfOverlayHeader
73
+ onClose={() => {
74
+ setSelectedFeature(null);
75
+ }}
76
+ title={<RvfFeatureDetailsTitle feature={selectedFeature} />}
77
+ ></RvfOverlayHeader>
78
+ <RvfFeatureDetails
79
+ className={twMerge(contentClassName, "flex flex-col gap-4 p-4")}
80
+ />
81
+ </>
82
+ )}
83
+ {hasPrint && isExportMenuOpen && (
84
+ <>
85
+ <RvfOverlayHeader
86
+ onClose={() => {
87
+ setIsExportMenuOpen(false);
88
+ }}
89
+ title="Drucken"
90
+ ></RvfOverlayHeader>
91
+ <RvfExportMenu
92
+ className={twMerge(contentClassName, "flex flex-col gap-4 p-4")}
93
+ />
94
+ </>
95
+ )}
96
+ {hasLayerTree && isLayerTreeOpen && (
97
+ <>
98
+ <RvfOverlayHeader
99
+ onClose={() => {
100
+ setIsLayerTreeOpen(false);
101
+ }}
102
+ title="Layers"
103
+ ></RvfOverlayHeader>
104
+ <RvfTopics className="relative flex h-full flex-col overflow-x-hidden overflow-y-auto p-2 text-base" />
105
+ </>
106
+ )}
107
+ {hasShare && isShareMenuOpen && (
108
+ <>
109
+ <RvfOverlayHeader
110
+ onClose={() => {
111
+ setIsShareMenuOpen(false);
112
+ }}
113
+ title="Share"
114
+ ></RvfOverlayHeader>
115
+ <RvfShare className="relative flex h-full flex-col overflow-x-hidden overflow-y-auto p-4 text-base" />
116
+ </>
117
+ )}
118
+ {hasSearch && isSearchOpen && (
119
+ <>
120
+ <Search className="relative flex h-full flex-col overflow-x-hidden overflow-y-auto p-2 text-base" />
121
+ </>
122
+ )}
123
+ </>
124
+ );
125
+ }
126
+ export default RvfOverlayContent;
File without changes
@@ -1,15 +1,15 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { memo } from "preact/compat";
4
2
  import { twMerge } from "tailwind-merge";
5
3
 
6
4
  import Cancel from "../icons/Cancel";
7
- import RvfIconButton from "../RvfIconButton";
5
+ import IconButton from "../ui/IconButton";
6
+
7
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
8
8
 
9
9
  export type RvfOverlayHeaderProps = {
10
10
  onClose?: () => void;
11
- title?: string;
12
- } & JSX.HTMLAttributes<HTMLDivElement> &
11
+ title?: React.ReactNode;
12
+ } & HTMLAttributes<HTMLDivElement> &
13
13
  PreactDOMAttributes;
14
14
 
15
15
  function RvfOverlayHeader({
@@ -22,16 +22,19 @@ function RvfOverlayHeader({
22
22
  return (
23
23
  <div
24
24
  className={twMerge(
25
- "flex flex-row items-center justify-between gap-2 p-2 border-b pl-4" +
26
- (className || ""),
25
+ `flex flex-row items-center justify-between gap-2 border-b p-2 pl-4`,
26
+
27
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
28
+ className ? className.toString() : "",
27
29
  )}
28
30
  {...props}
29
31
  >
30
- {children || <span className={"font-bold"}>{title}</span>}
32
+ {/* We set text-base so the clamp works on overlay container, not main */}
33
+ {children || <span className={"text-base font-bold"}>{title}</span>}
31
34
  {onClose && (
32
- <RvfIconButton className={"!size-[32px] border-none"} onClick={onClose}>
35
+ <IconButton className={"!size-[32px] border-none"} onClick={onClose}>
33
36
  <Cancel />
34
- </RvfIconButton>
37
+ </IconButton>
35
38
  )}
36
39
  </div>
37
40
  );
@@ -1,7 +1,7 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import RvfInputCopy from "../RvfInputCopy";
4
2
 
3
+ import type { JSX, PreactDOMAttributes } from "preact";
4
+
5
5
  function RvfPermalink({
6
6
  ...props
7
7
  }: JSX.HTMLAttributes<HTMLDivElement> & PreactDOMAttributes) {
@@ -1,5 +1,4 @@
1
1
  import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
2
- import { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer";
3
2
  import { memo } from "preact/compat";
4
3
  import { useEffect, useMemo } from "preact/hooks";
5
4
 
@@ -7,6 +6,8 @@ import { RVF_LAYERS_NAMES } from "../utils/constants";
7
6
  import useMapContext from "../utils/hooks/useMapContext";
8
7
  import useRvfContext from "../utils/hooks/useRvfContext";
9
8
 
9
+ import type { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer";
10
+
10
11
  function RvfPoisLayer(props: MaplibreStyleLayerOptions) {
11
12
  const { baseLayer, map } = useMapContext();
12
13
  const { setPoisLayer } = useRvfContext();
@@ -6,7 +6,7 @@ export type RvfRadioButtonProps =
6
6
  function RvfRadioButton(props: RvfRadioButtonProps) {
7
7
  return (
8
8
  <input
9
- className="peer mr-2 size-[20px] rounded-full border-2 border-grey accent-red"
9
+ className="peer border-grey accent-red mr-2 size-[20px] rounded-full border-2"
10
10
  {...props}
11
11
  type="radio"
12
12
  />
@@ -0,0 +1,10 @@
1
+ import RouteIcon from "../RouteIcon/RouteIcon";
2
+
3
+ import type { RouteIconProps } from "../RouteIcon/RouteIcon";
4
+
5
+ function RvfRouteIcon(props: RouteIconProps) {
6
+ return (
7
+ <RouteIcon {...props} className={"border"} displayNoRealtimeIcon={true} />
8
+ );
9
+ }
10
+ export default RvfRouteIcon;
@@ -0,0 +1 @@
1
+ export { default } from "./RvfRouteIcon";
@@ -6,7 +6,9 @@ import centerOnStation from "../utils/centerOnStation";
6
6
  import { RVF_EXTENT_4326 } from "../utils/constants";
7
7
  import useMapContext from "../utils/hooks/useMapContext";
8
8
 
9
- function RvfSearch() {
9
+ import type { StopsSearchProps } from "../StopsSearch/StopsSearch";
10
+
11
+ function RvfSearch(props: StopsSearchProps) {
10
12
  const { apikey, map, stopsurl } = useMapContext();
11
13
 
12
14
  const onSelect = useCallback(
@@ -22,6 +24,7 @@ function RvfSearch() {
22
24
  bbox={RVF_EXTENT_4326.join(",")}
23
25
  onselect={onSelect}
24
26
  url={stopsurl}
27
+ {...props}
25
28
  />
26
29
  );
27
30
  }
@@ -0,0 +1,27 @@
1
+ import { memo } from "preact/compat";
2
+ import { useCallback } from "preact/hooks";
3
+
4
+ import Search from "../icons/Search";
5
+ import IconButton from "../ui/IconButton";
6
+ import useRvfContext from "../utils/hooks/useRvfContext";
7
+
8
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
9
+
10
+ export type RvfLayerTreeButtonProps = HTMLAttributes<HTMLButtonElement> &
11
+ PreactDOMAttributes;
12
+
13
+ function RvfSearchButton({ ...props }: RvfLayerTreeButtonProps) {
14
+ const { isSearchOpen, setIsSearchOpen } = useRvfContext();
15
+
16
+ const onClick = useCallback(() => {
17
+ setIsSearchOpen(!isSearchOpen);
18
+ }, [isSearchOpen, setIsSearchOpen]);
19
+
20
+ return (
21
+ <IconButton {...props} onClick={onClick} selected={isSearchOpen}>
22
+ <Search />
23
+ </IconButton>
24
+ );
25
+ }
26
+
27
+ export default memo(RvfSearchButton);
@@ -0,0 +1 @@
1
+ export { default } from "./RvfSearchButton";
@@ -1,15 +1,17 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import ArrowDown from "../icons/ArrowDown";
4
2
 
5
- export type RvfSelectProps = {} & JSX.HTMLAttributes<HTMLSelectElement> &
3
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
4
+
5
+ export type RvfSelectProps = {
6
+ className?: string;
7
+ } & HTMLAttributes<HTMLSelectElement> &
6
8
  PreactDOMAttributes;
7
9
 
8
10
  function RvfSelect({ children, className, onChange }: RvfSelectProps) {
9
11
  return (
10
- <div className="relative flex items-center text-grey">
12
+ <div className="text-grey relative flex items-center">
11
13
  <select
12
- className={`h-[32px] cursor-pointer appearance-none rounded-[12px] border border-current bg-white px-[13px] text-[16px] leading-[22px] disabled:cursor-default @sm/main:h-[36px] @md/main:h-[40px] ${className}`}
14
+ className={`h-[32px] cursor-pointer appearance-none rounded-[12px] border border-current bg-white px-[13px] text-[16px] leading-[22px] disabled:cursor-default @sm/main:h-[36px] @md/main:h-[40px] ${className}`}
13
15
  onChange={onChange}
14
16
  >
15
17
  {children}
@@ -1,4 +1,3 @@
1
- import { GeoJSONSource } from "maplibre-gl";
2
1
  import GeoJSON from "ol/format/GeoJSON";
3
2
  import { useEffect, useMemo } from "preact/hooks";
4
3
 
@@ -39,7 +38,7 @@ function SingleClickListener() {
39
38
  useEffect(() => {
40
39
  const vectorTileFeature = selectedFeature?.get("vectorTileFeature");
41
40
  selectedFeature?.set("selected", true);
42
- const source = mbMap?.getSource(SOURCE_SELECT) as GeoJSONSource;
41
+ const source = mbMap?.getSource(SOURCE_SELECT);
43
42
  if (selectedFeature) {
44
43
  const feature = selectedFeature.clone();
45
44
  feature.setStyle(null);
@@ -1,5 +1,4 @@
1
1
  import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
2
- import { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer";
3
2
  import { memo } from "preact/compat";
4
3
  import { useEffect, useMemo } from "preact/hooks";
5
4
 
@@ -10,6 +9,8 @@ import { RVF_LAYERS_NAMES } from "../utils/constants";
10
9
  import useMapContext from "../utils/hooks/useMapContext";
11
10
  import useRvfContext from "../utils/hooks/useRvfContext";
12
11
 
12
+ import type { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer";
13
+
13
14
  function RvfSellingPointsLayer(props: MaplibreStyleLayerOptions) {
14
15
  const { title } = props;
15
16
  const { baseLayer, map } = useMapContext();
@@ -1,16 +1,17 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { useState } from "preact/hooks";
4
2
 
5
3
  import Cancel from "../../icons/Cancel";
6
4
  import Share from "../../icons/Share";
7
- import RvfIconButton from "../../RvfIconButton";
8
5
  import RvfInputCopy from "../../RvfInputCopy";
6
+ import IconButton from "../../ui/IconButton";
7
+
8
+ import type { ButtonHTMLAttributes, PreactDOMAttributes } from "preact";
9
9
 
10
10
  function RvfPermalinkButton({
11
11
  className,
12
12
  ...props
13
- }: JSX.ButtonHTMLAttributes<HTMLButtonElement> & PreactDOMAttributes) {
13
+ }: { className?: string } & ButtonHTMLAttributes<HTMLButtonElement> &
14
+ PreactDOMAttributes) {
14
15
  const [showTooltip, setShowTooltip] = useState(null);
15
16
  const [positionTooltip, setPositionTooltip] = useState<DOMRect>();
16
17
 
@@ -21,37 +22,37 @@ function RvfPermalinkButton({
21
22
 
22
23
  return (
23
24
  <>
24
- <RvfIconButton
25
- className={"border-none " + className}
25
+ <IconButton
26
+ className={`border-none ${className}`}
26
27
  onClick={handleIconClick}
27
28
  selected={showTooltip}
28
29
  {...props}
29
30
  >
30
31
  <Share />
31
- </RvfIconButton>
32
+ </IconButton>
32
33
 
33
34
  {showTooltip && positionTooltip && (
34
35
  <div
35
- className="fixed rounded-lg border border-grey bg-white p-2 shadow-lg"
36
+ className="border-grey fixed rounded-lg border bg-white p-2 shadow-lg"
36
37
  style={{
37
38
  left: positionTooltip.left + 40,
38
39
  top: positionTooltip.top - 10,
39
40
  }}
40
41
  >
41
42
  <div className="pr-4">
42
- <RvfIconButton
43
- className="absolute right-[-5px] top-[-5px] border-none bg-transparent p-0"
43
+ <IconButton
44
+ className="absolute top-[-5px] right-[-5px] border-none bg-transparent p-0"
44
45
  onClick={handleIconClick}
45
46
  >
46
47
  <Cancel height="18px" width="18px" />
47
- </RvfIconButton>
48
+ </IconButton>
48
49
  <RvfInputCopy />
49
50
  <p className="py-2">
50
51
  Sie können auch den Link aus der Adresszeile des Browsers
51
52
  kopieren.
52
53
  </p>
53
54
  </div>
54
- <div className="absolute -left-1.5 top-4 size-2.5 rotate-45 border border-r-0 border-t-0 border-grey bg-white"></div>
55
+ <div className="border-grey absolute top-4 -left-1.5 size-2.5 rotate-45 border border-t-0 border-r-0 bg-white"></div>
55
56
  </div>
56
57
  )}
57
58
  </>
@@ -1,36 +1,37 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import CanvasSaveButton from "react-spatial/components/CanvasSaveButton";
4
2
  import { twMerge } from "tailwind-merge";
5
3
 
6
4
  import Email from "../icons/Email";
7
5
  import Image from "../icons/Image";
8
- import RvfButton from "../RvfButton";
9
6
  import RvfPermalink from "../RvfPermalink";
7
+ import Button from "../ui/Button";
10
8
  import useMapContext from "../utils/hooks/useMapContext";
11
9
 
10
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
11
+
12
12
  function RvfShare({
13
- className,
13
+ className = "",
14
14
  ...props
15
- }: JSX.HTMLAttributes<HTMLDivElement> & PreactDOMAttributes) {
15
+ }: HTMLAttributes<HTMLDivElement> & PreactDOMAttributes) {
16
16
  const { map } = useMapContext();
17
17
 
18
18
  return (
19
- <div className={twMerge("flex flex-col gap-6 " + className)} {...props}>
19
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions
20
+ <div className={twMerge(`flex flex-col gap-4 ${className}`)} {...props}>
20
21
  <a
21
22
  className="flex items-center gap-2"
22
23
  href={`mailto:?subject=Karte&body=${window?.location.href}`}
23
24
  >
24
- <RvfButton>
25
+ <Button>
25
26
  <Email />
26
27
  <span>Email senden</span>
27
- </RvfButton>
28
+ </Button>
28
29
  </a>
29
30
  <CanvasSaveButton map={map}>
30
- <RvfButton className={"w-fit"}>
31
+ <Button className={"w-fit"}>
31
32
  <Image />
32
33
  <span>Bild speichern</span>
33
- </RvfButton>
34
+ </Button>
34
35
  </CanvasSaveButton>
35
36
  <RvfPermalink />
36
37
  </div>
@@ -1,12 +1,12 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { memo } from "preact/compat";
4
2
  import { useCallback } from "preact/hooks";
5
3
 
6
4
  import Share from "../icons/Share";
7
- import RvfIconButton from "../RvfIconButton";
5
+ import IconButton from "../ui/IconButton";
8
6
  import useRvfContext from "../utils/hooks/useRvfContext";
9
7
 
8
+ import type { JSX, PreactDOMAttributes } from "preact";
9
+
10
10
  export type RvfShareMenuButtonProps = JSX.HTMLAttributes<HTMLButtonElement> &
11
11
  PreactDOMAttributes;
12
12
 
@@ -18,9 +18,9 @@ function RvfShareMenuButton({ ...props }: RvfShareMenuButtonProps) {
18
18
  }, [isShareMenuOpen, setIsShareMenuOpen]);
19
19
 
20
20
  return (
21
- <RvfIconButton {...props} onClick={onClick} selected={isShareMenuOpen}>
21
+ <IconButton {...props} onClick={onClick} selected={isShareMenuOpen}>
22
22
  <Share />
23
- </RvfIconButton>
23
+ </IconButton>
24
24
  );
25
25
  }
26
26
 
@@ -1,9 +1,4 @@
1
- import type { Options } from "ol/layer/Group";
2
-
3
- import { FeatureCollection, Point } from "geojson";
4
- import { GeoJSONSource } from "maplibre-gl";
5
1
  import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
6
- import { Extent } from "ol/extent";
7
2
  import { Group } from "ol/layer";
8
3
  import { unByKey } from "ol/Observable";
9
4
  import { transformExtent } from "ol/proj";
@@ -36,8 +31,14 @@ import {
36
31
  } from "../utils/constants";
37
32
  import useMapContext from "../utils/hooks/useMapContext";
38
33
  import useRvfContext from "../utils/hooks/useRvfContext";
39
- import {
40
- fetchSharingWFS,
34
+ import { fetchSharingWFS } from "../utils/sharingWFSUtils";
35
+
36
+ import type { FeatureCollection, Point } from "geojson";
37
+ import type { GeoJSONSource } from "maplibre-gl";
38
+ import type { Extent } from "ol/extent";
39
+ import type { Options } from "ol/layer/Group";
40
+
41
+ import type {
41
42
  SharingStationWFS,
42
43
  SharingVehicleWFS,
43
44
  } from "../utils/sharingWFSUtils";
@@ -114,16 +115,18 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
114
115
  abortController,
115
116
  extent,
116
117
  );
117
- const bikeStationsData: FeatureCollection<Point, SharingStationWFS> = {
118
+ const bikeStationsDatas: FeatureCollection<Point, SharingStationWFS> = {
119
+ features: [],
120
+ type: "FeatureCollection",
121
+ };
122
+ const cargoBikeStationsDatas: FeatureCollection<
123
+ Point,
124
+ SharingStationWFS
125
+ > = {
118
126
  features: [],
119
127
  type: "FeatureCollection",
120
128
  };
121
- const cargoBikeStationsData: FeatureCollection<Point, SharingStationWFS> =
122
- {
123
- features: [],
124
- type: "FeatureCollection",
125
- };
126
- const carStationsData: FeatureCollection<Point, SharingStationWFS> = {
129
+ const carStationsDatas: FeatureCollection<Point, SharingStationWFS> = {
127
130
  features: [],
128
131
  type: "FeatureCollection",
129
132
  };
@@ -132,21 +135,21 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
132
135
  if (station.properties.num_bicycles_available !== null) {
133
136
  station.properties.num_vehicles_available =
134
137
  station.properties.num_bicycles_available;
135
- bikeStationsData.features.push(station);
138
+ bikeStationsDatas.features.push(station);
136
139
  } else if (station.properties.num_cargo_bicycles_available !== null) {
137
140
  station.properties.num_vehicles_available =
138
141
  station.properties.num_cargo_bicycles_available;
139
- cargoBikeStationsData.features.push(station);
142
+ cargoBikeStationsDatas.features.push(station);
140
143
  } else if (station.properties.num_cars_available !== null) {
141
144
  station.properties.num_vehicles_available =
142
145
  station.properties.num_cars_available;
143
- carStationsData.features.push(station);
146
+ carStationsDatas.features.push(station);
144
147
  }
145
148
  });
146
149
 
147
- setBikeStationsData(bikeStationsData);
148
- setCargoBikeStationsData(cargoBikeStationsData);
149
- setCarStationsData(carStationsData);
150
+ setBikeStationsData(bikeStationsDatas);
151
+ setCargoBikeStationsData(cargoBikeStationsDatas);
152
+ setCarStationsData(carStationsDatas);
150
153
 
151
154
  // Fill free float data
152
155
  const freeFloatData = (await fetchSharingWFS(
@@ -190,7 +193,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
190
193
  setScooterFreeFloatData(scooter);
191
194
  };
192
195
 
193
- fetchData();
196
+ void fetchData();
194
197
 
195
198
  return () => {
196
199
  abortController.abort();
@@ -202,7 +205,7 @@ function RvfSharedMobilityLayerGroup(props: GroupOptions) {
202
205
  const key = map?.on("moveend", updateData);
203
206
 
204
207
  // @ts-expect-error - change property can have custom values
205
- const key2 = map?.on("change:" + LAYER_PROP_IS_EXPORTING, (evt) => {
208
+ const key2 = map?.on(`change:${LAYER_PROP_IS_EXPORTING}`, (evt) => {
206
209
  // Reupdate the data after finishing eporting the map
207
210
  if (!evt.target.get(LAYER_PROP_IS_EXPORTING)) {
208
211
  updateData();