@geops/rvf-mobility-web-component 0.1.46 → 0.1.47

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 (204) hide show
  1. package/.prettierrc.js +3 -1
  2. package/CHANGELOG.md +12 -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 +181 -207
  16. package/index.html +108 -88
  17. package/index.js +2345 -1976
  18. package/input.css +21 -3
  19. package/package.json +39 -41
  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 +252 -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 +36 -5
  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 +25 -21
  73. package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +131 -127
  74. package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +309 -111
  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/RvfFeatureDetailsFooter/RvfFeatureDetailsFooter.tsx +43 -0
  80. package/src/RvfFeatureDetailsFooter/index.tsx +1 -0
  81. package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +81 -0
  82. package/src/RvfFeatureDetailsTitle/index.tsx +1 -0
  83. package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +4 -4
  84. package/src/RvfGeolocationButton/GeolocationButton.tsx +98 -0
  85. package/src/RvfGeolocationButton/index.tsx +1 -0
  86. package/src/RvfIconButton/RvfIconButton.tsx +20 -9
  87. package/src/RvfInputCopy/RvfInputCopy.tsx +8 -8
  88. package/src/RvfLayerTree/RvfLayerTree.tsx +5 -2
  89. package/src/RvfLayerTree/TreeItem/TreeItem.tsx +13 -16
  90. package/src/RvfLayerTree/layersTreeReducer.ts +23 -18
  91. package/src/RvfLayerTreeButton/RvfLayerTreeButton.tsx +6 -6
  92. package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +2 -1
  93. package/src/RvfLink/RvfLink.tsx +4 -3
  94. package/src/RvfMobilityMap/RvfMobilityMap.tsx +324 -320
  95. package/src/RvfModal/RvfModal.tsx +4 -3
  96. package/src/RvfOverlayContent/RvfOverlayContent.tsx +128 -0
  97. package/src/RvfOverlayContent/index.ts +0 -0
  98. package/src/RvfOverlayHeader/RvfOverlayHeader.tsx +13 -10
  99. package/src/RvfPermalink/RvfPermalink.tsx +2 -2
  100. package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -1
  101. package/src/RvfRadioButton/RvfRadioButton.tsx +1 -1
  102. package/src/RvfRouteIcon/RvfRouteIcon.tsx +10 -0
  103. package/src/RvfRouteIcon/index.tsx +1 -0
  104. package/src/RvfSearch/RvfSearch.tsx +4 -1
  105. package/src/RvfSearchButton/RvfSearchButton.tsx +27 -0
  106. package/src/RvfSearchButton/index.tsx +1 -0
  107. package/src/RvfSelect/RvfSelect.tsx +7 -5
  108. package/src/RvfSelectedFeatureHighlightLayer/RvfSelectedFeatureHighlightLayer.tsx +1 -2
  109. package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -1
  110. package/src/RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx +13 -12
  111. package/src/RvfShare/RvfShare.tsx +11 -10
  112. package/src/RvfShareMenuButton/RvfShareMenuButton.tsx +5 -5
  113. package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +25 -22
  114. package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +102 -67
  115. package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -1
  116. package/src/RvfTopics/RvfTopics.tsx +6 -5
  117. package/src/RvfZoomButtons/RvfZoomButtons.tsx +3 -3
  118. package/src/ScaleLine/ScaleLine.tsx +5 -4
  119. package/src/ScrollableHandler/ScrollableHandler.tsx +2 -1
  120. package/src/ScrollableHandler/index.tsx +1 -1
  121. package/src/SingleClickListener/SingleClickListener.tsx +47 -4
  122. package/src/Station/Station.tsx +5 -5
  123. package/src/StationName/StationName.tsx +3 -3
  124. package/src/StationServices/StationServices.tsx +3 -3
  125. package/src/StationsLayer/StationsLayer.tsx +5 -4
  126. package/src/StopsSearch/StopsSearch.tsx +143 -88
  127. package/src/WindowMessageListener/WindowMessageListener.tsx +68 -0
  128. package/src/WindowMessageListener/index.tsx +1 -0
  129. package/src/icons/Airport/Airport.tsx +4 -4
  130. package/src/icons/ArrowDown/ArrowDown.tsx +1 -1
  131. package/src/icons/ArrowRight/ArrowRight.tsx +19 -0
  132. package/src/icons/ArrowRight/arrow-right.svg +16 -0
  133. package/src/icons/ArrowRight/index.tsx +1 -0
  134. package/src/icons/ArrowUp/ArrowUp.tsx +1 -1
  135. package/src/icons/ArrowUpRight/ArrowUpRight.tsx +1 -1
  136. package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +2 -2
  137. package/src/icons/Bathroom/Bathroom.tsx +1 -1
  138. package/src/icons/Copy/Copy.tsx +1 -1
  139. package/src/icons/Doc/Doc.tsx +1 -1
  140. package/src/icons/Email/Email.tsx +1 -1
  141. package/src/icons/FilePdf/FilePdf.tsx +1 -1
  142. package/src/icons/Geolocation/Geolocation.tsx +3 -5
  143. package/src/icons/Image/Image.tsx +1 -1
  144. package/src/icons/Menu/Menu.tsx +1 -1
  145. package/src/icons/Minus/Minus.tsx +1 -1
  146. package/src/icons/NoRealtime/NoRealtime.tsx +1 -1
  147. package/src/icons/Plus/Plus.tsx +1 -1
  148. package/src/icons/Police/Police.tsx +3 -3
  149. package/src/icons/Search/Search.tsx +0 -1
  150. package/src/icons/Share/Share.tsx +1 -1
  151. package/src/icons/Stack/Stack.tsx +1 -1
  152. package/src/icons/Tracking/Tracking.tsx +29 -0
  153. package/src/icons/Tracking/airport-14-svgrepo-com.svg +41 -0
  154. package/src/icons/Tracking/index.tsx +1 -0
  155. package/src/icons/WaitingAreas/WaitingAreas.tsx +1 -1
  156. package/src/icons/Warning/Warning.tsx +56 -0
  157. package/src/icons/Warning/index.tsx +1 -0
  158. package/src/icons/Warning/info-achtung-kreisrot-rot.svg +28 -0
  159. package/src/icons/WheelChair/WheelChair.tsx +1 -1
  160. package/src/index.tsx +8 -46
  161. package/src/indexDoc.ts +13 -0
  162. package/src/ui/Button/Button.tsx +57 -0
  163. package/src/ui/Button/index.tsx +1 -0
  164. package/src/ui/IconButton/IconButton.tsx +44 -0
  165. package/src/ui/IconButton/index.tsx +1 -0
  166. package/src/utils/MobilityEvent.ts +4 -3
  167. package/src/utils/applyInitialLayerVisibility.ts +3 -3
  168. package/src/utils/centerOnStation.ts +3 -2
  169. package/src/utils/centerOnVehicle.ts +5 -4
  170. package/src/utils/constants.ts +27 -3
  171. package/src/utils/exportPdf.ts +26 -20
  172. package/src/utils/fullTrajectoryStyle.ts +2 -2
  173. package/src/utils/getAllLayers.ts +4 -3
  174. package/src/utils/getDelayColor.test.ts +1 -0
  175. package/src/utils/getDelayColorForVehicle.test.ts +2 -0
  176. package/src/utils/getDelayString.test.ts +3 -0
  177. package/src/utils/getDelayTextForVehicle.test.ts +4 -0
  178. package/src/utils/getFullTrajectoryAndFit.ts +4 -3
  179. package/src/utils/getHoursAndMinutes.test.ts +1 -0
  180. package/src/utils/getLayersAsFlatArray.ts +2 -2
  181. package/src/utils/getLinkByDevice.ts +1 -1
  182. package/src/utils/getMainColorForVehicle.ts +3 -3
  183. package/src/utils/getPermalinkParameters.ts +2 -2
  184. package/src/utils/getStopStatus.test.ts +2 -1
  185. package/src/utils/getStopStatus.ts +1 -1
  186. package/src/utils/getTextForVehicle.ts +1 -1
  187. package/src/utils/hooks/useDeparture.tsx +6 -5
  188. package/src/utils/hooks/useI18n.tsx +6 -4
  189. package/src/utils/hooks/useInitialLayersVisiblity.tsx +2 -1
  190. package/src/utils/hooks/useLayerConfig.tsx +40 -0
  191. package/src/utils/hooks/useMapContext.tsx +30 -18
  192. package/src/utils/hooks/useRouteStop.tsx +3 -2
  193. package/src/utils/hooks/useRvfContext.tsx +11 -3
  194. package/src/utils/hooks/useStation.tsx +2 -1
  195. package/src/utils/hooks/useUpdatePermalink.tsx +25 -24
  196. package/src/utils/hooks/useZoom.tsx +4 -4
  197. package/src/utils/realtimeRVFStyle.ts +5 -4
  198. package/src/utils/sharingGraphqlUtils.ts +3 -2
  199. package/src/utils/sharingStylesUtils.ts +7 -7
  200. package/src/utils/sharingWFSUtils.ts +9 -15
  201. package/tailwind.config.mjs +1 -0
  202. package/tsconfig.json +1 -1
  203. package/doc/tailwind.config.ts +0 -20
  204. package/src/utils/getFeatureInformationTitle.tsx +0 -54
@@ -0,0 +1,81 @@
1
+ import { icons } from "../utils/addSourceAndLayers";
2
+ import {
3
+ RVF_LAYERS_NAMES,
4
+ RVF_LAYERS_TITLES,
5
+ TITLE_BY_CATEGORY,
6
+ TITLE_BY_FEED_ID,
7
+ } from "../utils/constants";
8
+ import useLayerConfig from "../utils/hooks/useLayerConfig";
9
+
10
+ import type { Feature } from "ol";
11
+
12
+ const defaultTitle = "Informations";
13
+
14
+ function RvfFeatureDetailsTitle({ feature }: { feature: Feature }) {
15
+ const features = feature.get("features");
16
+ const selectedFeature = features?.[0] || feature;
17
+ const {
18
+ category,
19
+ condition_group: conditionGroup,
20
+ disruption_type: disruptionType,
21
+ feed_id: feedId,
22
+ line_id: lineId,
23
+ tickets,
24
+ } = selectedFeature.getProperties();
25
+ const layerConfigLinienNetz = useLayerConfig(RVF_LAYERS_NAMES.liniennetz);
26
+ const layerConfigMeldungen = useLayerConfig(RVF_LAYERS_NAMES.meldungen);
27
+
28
+ // moco export v1
29
+ if (disruptionType) {
30
+ return (
31
+ <div className={"flex items-center gap-2 text-sm"}>
32
+ <div className="min-w-8 shrink-0 grow-0">
33
+ <img
34
+ alt={disruptionType}
35
+ className={"w-8"}
36
+ src={icons[disruptionType] || icons.warning}
37
+ ></img>
38
+ </div>
39
+ <div className={"flex flex-col gap-2 text-base font-bold"}>
40
+ {layerConfigMeldungen.title}
41
+ </div>
42
+ </div>
43
+ );
44
+ }
45
+
46
+ // moco export v2
47
+ if (conditionGroup) {
48
+ return (
49
+ <div className={"flex items-center gap-2 text-sm"}>
50
+ {icons[conditionGroup] && (
51
+ <div className="min-w-8 shrink-0 grow-0">
52
+ <img
53
+ alt={conditionGroup}
54
+ className={"w-8"}
55
+ src={icons[conditionGroup] || icons.warning}
56
+ ></img>
57
+ </div>
58
+ )}
59
+ <div className={"flex flex-col gap-2 text-base font-bold"}>
60
+ {layerConfigMeldungen.title}
61
+ </div>
62
+ </div>
63
+ );
64
+ }
65
+ if (category) {
66
+ return TITLE_BY_CATEGORY[category] || defaultTitle;
67
+ }
68
+ if (feedId) {
69
+ return TITLE_BY_FEED_ID[feedId] || defaultTitle;
70
+ }
71
+
72
+ if (lineId) {
73
+ return layerConfigLinienNetz.title;
74
+ }
75
+ if (tickets) {
76
+ return RVF_LAYERS_TITLES.verkaufsstellen;
77
+ }
78
+ return defaultTitle;
79
+ }
80
+
81
+ export default RvfFeatureDetailsTitle;
@@ -0,0 +1 @@
1
+ export { default } from "./RvfFeatureDetailsTitle";
@@ -1,9 +1,9 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import ArrowDown from "../icons/ArrowDown";
4
2
  import ArrowUp from "../icons/ArrowUp";
5
3
  import useMapContext from "../utils/hooks/useMapContext";
6
4
 
5
+ import type { JSX, PreactDOMAttributes } from "preact";
6
+
7
7
  export type RvfFloatingMenuProps = {
8
8
  isOpen: boolean;
9
9
  onClick: () => void;
@@ -23,8 +23,8 @@ function RvfFloatingMenu({
23
23
  }
24
24
 
25
25
  return (
26
- <div className="pointer-events-none absolute bottom-8 left-2 top-2 z-10 flex flex-col overflow-hidden rounded-lg">
27
- <div className="pointer-events-auto max-h-full w-48 rounded-lg border border-grey bg-white shadow-lg @lg/main:w-52">
26
+ <div className="pointer-events-none absolute top-2 bottom-8 left-2 z-10 flex flex-col overflow-hidden rounded-lg">
27
+ <div className="border-grey pointer-events-auto max-h-full w-48 rounded-lg border bg-white shadow-lg @lg/main:w-52">
28
28
  <button
29
29
  className="flex w-full items-center justify-between px-2 py-1.5 font-bold"
30
30
  onClick={onClick}
@@ -0,0 +1,98 @@
1
+ import { Feature, Geolocation } from "ol";
2
+ import { Point } from "ol/geom";
3
+ import VectorLayer from "ol/layer/Vector";
4
+ import { unByKey } from "ol/Observable";
5
+ import { fromLonLat } from "ol/proj";
6
+ import VectorSource from "ol/source/Vector";
7
+ import { Icon, Style } from "ol/style";
8
+ import { memo } from "preact/compat";
9
+ import { useEffect, useMemo } from "preact/hooks";
10
+
11
+ import GeolocationIcon from "../icons/Geolocation";
12
+ import locationSvg from "../icons/Geolocation/location.svg";
13
+ import IconButton from "../ui/IconButton";
14
+ import useMapContext from "../utils/hooks/useMapContext";
15
+
16
+ import type { JSX, PreactDOMAttributes } from "preact";
17
+
18
+ const point = new Point([0, 0]);
19
+ const feature = new Feature(point);
20
+ const layer = new VectorLayer({
21
+ source: new VectorSource({ features: [feature] }),
22
+ style: new Style({
23
+ image: new Icon({
24
+ anchor: [0.5, 1],
25
+ src: locationSvg,
26
+ }),
27
+ }),
28
+ });
29
+
30
+ export type GeolocationButtonProps = JSX.HTMLAttributes<HTMLButtonElement> &
31
+ PreactDOMAttributes;
32
+
33
+ const TRACKING_ZOOM = 16;
34
+
35
+ function GeolocationButton({ ...props }: GeolocationButtonProps) {
36
+ const mapContext = useMapContext();
37
+ const { isTracking, map, setIsTracking } = mapContext;
38
+
39
+ const geolocation = useMemo(() => {
40
+ return new Geolocation();
41
+ }, []);
42
+
43
+ useEffect(() => {
44
+ let keys = [];
45
+ if (!map || !geolocation) {
46
+ return;
47
+ }
48
+ keys = [
49
+ // First time we zoom and center on the position
50
+ geolocation.once("change:position", (evt) => {
51
+ const position = evt.target.getPosition();
52
+ if (evt.target.getPosition()) {
53
+ const coord = fromLonLat(position, "EPSG:3857");
54
+ map.getView().setZoom(TRACKING_ZOOM);
55
+ map.getView().setCenter(coord);
56
+ point.setCoordinates(coord);
57
+ }
58
+ }),
59
+ // then we only center the map.
60
+ geolocation.on("change:position", (evt) => {
61
+ const position = evt.target.getPosition();
62
+ if (evt.target.getPosition()) {
63
+ const coord = fromLonLat(position, "EPSG:3857");
64
+ map.getView().setCenter(coord);
65
+ point.setCoordinates(coord);
66
+ }
67
+ }),
68
+ ];
69
+
70
+ return () => {
71
+ unByKey(keys);
72
+ };
73
+ }, [map, geolocation]);
74
+
75
+ useEffect(() => {
76
+ geolocation.setTracking(isTracking);
77
+ if (isTracking) {
78
+ layer.setMap(map);
79
+ }
80
+ return () => {
81
+ layer.setMap(null);
82
+ };
83
+ }, [map, geolocation, isTracking]);
84
+
85
+ return (
86
+ <IconButton
87
+ onClick={() => {
88
+ setIsTracking(!isTracking);
89
+ }}
90
+ selected={isTracking}
91
+ {...props}
92
+ >
93
+ <GeolocationIcon className={isTracking ? "animate-pulse" : ""} />
94
+ </IconButton>
95
+ );
96
+ }
97
+
98
+ export default memo(GeolocationButton);
@@ -0,0 +1 @@
1
+ export { default } from "./GeolocationButton";
@@ -1,22 +1,23 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
- import { memo, SVGProps, useMemo } from "preact/compat";
1
+ import { memo, useMemo } from "preact/compat";
4
2
  import { twMerge } from "tailwind-merge";
5
3
 
6
- import { RvfButtonProps, themes } from "../RvfButton/RvfButton";
4
+ import { themes } from "../RvfButton/RvfButton";
5
+
6
+ import type { SVGProps } from "preact/compat";
7
+
8
+ import type { RvfButtonProps } from "../RvfButton/RvfButton";
7
9
 
8
10
  export type RvfIconButtonProps = {
9
11
  Icon?: (props: SVGProps<SVGSVGElement>) => preact.JSX.Element;
10
- } & JSX.ButtonHTMLAttributes<HTMLButtonElement> &
11
- PreactDOMAttributes &
12
- RvfButtonProps;
12
+ } & RvfButtonProps;
13
13
 
14
14
  const baseClasses =
15
- "flex size-[32px] @sm/main:size-[36px] @md/main:size-[40px] p-[7px] items-center justify-center rounded-full border";
15
+ "flex size-[32px] @sm/main:size-[36px] @md/main:size-[40px] p-[7px] items-center justify-center rounded-full border cursor-pointer disabled:cursor-default";
16
16
 
17
17
  function RvfIconButton({
18
18
  children,
19
19
  className,
20
+ href,
20
21
  Icon,
21
22
  selected = false,
22
23
  theme = "secondary",
@@ -24,10 +25,20 @@ function RvfIconButton({
24
25
  }: RvfIconButtonProps) {
25
26
  const classes = useMemo(() => {
26
27
  return twMerge(
27
- `${baseClasses} ${themes[theme].classes} ${selected ? themes[theme].selectedClasses : ""} ${className || ""}`,
28
+ baseClasses,
29
+ themes[theme].classes,
30
+ selected ? themes[theme].selectedClasses : "",
31
+ className,
28
32
  );
29
33
  }, [className, selected, theme]);
30
34
 
35
+ if (href) {
36
+ return (
37
+ <a className={classes} href={href} {...props}>
38
+ {children || <Icon height={"100%"} width={"100%"} />}
39
+ </a>
40
+ );
41
+ }
31
42
  return (
32
43
  <button className={classes} {...props}>
33
44
  {children || <Icon height={"100%"} width={"100%"} />}
@@ -1,9 +1,9 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
1
  import { useRef, useState } from "preact/hooks";
4
2
 
5
3
  import Copy from "../icons/Copy";
6
- import RvfIconButton from "../RvfIconButton";
4
+ import IconButton from "../ui/IconButton";
5
+
6
+ import type { JSX, PreactDOMAttributes } from "preact";
7
7
 
8
8
  function RvfInputCopy(props: JSX.InputHTMLAttributes & PreactDOMAttributes) {
9
9
  const [positionTooltip, setPositionTooltip] = useState<DOMRect>();
@@ -12,7 +12,7 @@ function RvfInputCopy(props: JSX.InputHTMLAttributes & PreactDOMAttributes) {
12
12
 
13
13
  const handleCopyClick = (event) => {
14
14
  setPositionTooltip(event.currentTarget.getBoundingClientRect());
15
- navigator.clipboard.writeText(window?.location.href).then(() => {
15
+ void navigator.clipboard.writeText(window?.location.href).then(() => {
16
16
  setIsTooltipShowed(true);
17
17
  setTimeout(() => {
18
18
  setIsTooltipShowed(false);
@@ -26,7 +26,7 @@ function RvfInputCopy(props: JSX.InputHTMLAttributes & PreactDOMAttributes) {
26
26
  };
27
27
 
28
28
  return (
29
- <div className="flex items-center text-grey">
29
+ <div className="text-grey flex items-center">
30
30
  <input
31
31
  className="h-7 w-full rounded-sm rounded-r-none border border-r-0 border-current p-1 leading-4 outline-none"
32
32
  onFocus={handleInputFocus}
@@ -35,14 +35,14 @@ function RvfInputCopy(props: JSX.InputHTMLAttributes & PreactDOMAttributes) {
35
35
  type="text"
36
36
  {...props}
37
37
  />
38
- <RvfIconButton
38
+ <IconButton
39
39
  className="!size-7 rounded-l-none rounded-r-sm border-current"
40
40
  onClick={handleCopyClick}
41
41
  >
42
42
  <Copy />
43
- </RvfIconButton>
43
+ </IconButton>
44
44
  <div
45
- className={`fixed rounded-md bg-grey p-1 text-sm text-white ${isTooptipShowed ? "block" : "hidden"}`}
45
+ className={`bg-grey fixed rounded-md p-1 text-sm text-white ${isTooptipShowed ? "block" : "hidden"}`}
46
46
  style={{
47
47
  left: positionTooltip?.left - 30,
48
48
  top: positionTooltip?.top - 40,
@@ -1,4 +1,3 @@
1
- import { JSX, PreactDOMAttributes } from "preact";
2
1
  import { memo } from "preact/compat";
3
2
  import { useEffect, useReducer } from "preact/hooks";
4
3
 
@@ -7,7 +6,11 @@ import {
7
6
  LayersTreeDispatchContext,
8
7
  } from "./layersTreeContext";
9
8
  import layersTreeReducer from "./layersTreeReducer";
10
- import TreeItem, { TreeItemProps } from "./TreeItem/TreeItem";
9
+ import TreeItem from "./TreeItem/TreeItem";
10
+
11
+ import type { JSX, PreactDOMAttributes } from "preact";
12
+
13
+ import type { TreeItemProps } from "./TreeItem/TreeItem";
11
14
 
12
15
  export type RvfLayerTreeProps = {
13
16
  layers: TreeItemProps[];
@@ -1,21 +1,17 @@
1
- import type { JSX, PreactDOMAttributes } from "preact";
2
-
3
- import BaseLayer from "ol/layer/Base";
4
- import {
5
- SVGProps,
6
- useContext,
7
- useEffect,
8
- useId,
9
- useState,
10
- } from "preact/compat";
1
+ import { useContext, useEffect, useId, useState } from "preact/compat";
11
2
 
12
3
  import ArrowDown from "../../icons/ArrowDown";
13
4
  import ArrowUp from "../../icons/ArrowUp";
14
5
  import minusGrey from "../../icons/Minus/minus-grey.svg";
15
6
  import RvfCheckbox from "../../RvfCheckbox";
16
7
  import RvfRadioButton from "../../RvfRadioButton";
8
+ import useLayerConfig from "../../utils/hooks/useLayerConfig";
17
9
  import { LayersTreeDispatchContext } from "../layersTreeContext";
18
10
 
11
+ import type BaseLayer from "ol/layer/Base";
12
+ import type { JSX, PreactDOMAttributes } from "preact";
13
+ import type { SVGProps } from "preact/compat";
14
+
19
15
  export enum SelectionType {
20
16
  CHECKBOX = "checkbox",
21
17
  RADIO = "radio",
@@ -46,6 +42,7 @@ function TreeItem({
46
42
  const dispatch = useContext(LayersTreeDispatchContext);
47
43
  const inputId = useId();
48
44
  const buttonId = useId();
45
+ const layerConfig = useLayerConfig(layer.get("name"));
49
46
 
50
47
  useEffect(() => {
51
48
  if (isCollapsedOnControlClick) {
@@ -59,7 +56,7 @@ function TreeItem({
59
56
  if (isCollapsedOnControlClick && !isContainerVisible) {
60
57
  dispatch({
61
58
  payload: {
62
- ...this["props"],
59
+ ...this.props,
63
60
  isControlChecked: true,
64
61
  },
65
62
  type: "SELECT_ITEM",
@@ -70,7 +67,7 @@ function TreeItem({
70
67
  const handleSelectionChange = (event) => {
71
68
  dispatch({
72
69
  payload: {
73
- ...this["props"],
70
+ ...this.props,
74
71
  isControlChecked: event.target.checked,
75
72
  },
76
73
  type: "SELECT_ITEM",
@@ -78,14 +75,14 @@ function TreeItem({
78
75
  };
79
76
 
80
77
  const renderedLayers = childItems
81
- .filter(({ title }) => {
82
- return !!title;
78
+ .filter(({ title: titlee }) => {
79
+ return !!titlee;
83
80
  })
84
81
  .map((item, idx) => {
85
82
  return <TreeItem key={idx} {...item} />;
86
83
  });
87
84
 
88
- if (!title) {
85
+ if (!title && !layerConfig.title) {
89
86
  return null;
90
87
  }
91
88
 
@@ -128,7 +125,7 @@ function TreeItem({
128
125
  className={`flex-1 cursor-pointer`}
129
126
  htmlFor={renderedLayers.length > 0 ? buttonId : inputId}
130
127
  >
131
- {title}
128
+ {layerConfig.title || title}
132
129
  </label>
133
130
  {renderedLayers.length > 0 && (
134
131
  <button
@@ -5,14 +5,6 @@ const ROOT = {
5
5
  parent: null,
6
6
  };
7
7
 
8
- const initTree = (tree) => {
9
- const initializedTree = { ...ROOT };
10
- initializedTree.childItems = tree;
11
- mapNode(initializedTree.childItems, initializedTree);
12
-
13
- return initializedTree;
14
- };
15
-
16
8
  const mapNode = (childItems, parent) => {
17
9
  for (const child of childItems) {
18
10
  child.parent = parent;
@@ -23,6 +15,14 @@ const mapNode = (childItems, parent) => {
23
15
  }
24
16
  };
25
17
 
18
+ const initTree = (tree) => {
19
+ const initializedTree = { ...ROOT };
20
+ initializedTree.childItems = tree;
21
+ mapNode(initializedTree.childItems, initializedTree);
22
+
23
+ return initializedTree;
24
+ };
25
+
26
26
  const findNodeInTree = (node, nodeToFind) => {
27
27
  if (node.id === nodeToFind.id) {
28
28
  return node;
@@ -38,16 +38,6 @@ const findNodeInTree = (node, nodeToFind) => {
38
38
  }
39
39
  };
40
40
 
41
- const setNewControlCheckedStatus = (tree, newItem) => {
42
- const currentItem = findNodeInTree(tree, newItem);
43
-
44
- if (currentItem) {
45
- updateCheckedControlStatus(currentItem, newItem, false);
46
- }
47
-
48
- return { ...tree };
49
- };
50
-
51
41
  const updateCheckedControlStatus = (currentItem, newItem, isParentUpdate) => {
52
42
  if (newItem.isControlChecked) {
53
43
  if (newItem.selectionType === SelectionType.CHECKBOX) {
@@ -58,6 +48,7 @@ const updateCheckedControlStatus = (currentItem, newItem, isParentUpdate) => {
58
48
  child.isControlChecked = child.id === currentItem.id;
59
49
 
60
50
  if (!child.isControlChecked) {
51
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
61
52
  updateRadioChildNodes(child);
62
53
  }
63
54
  }
@@ -71,17 +62,31 @@ const updateCheckedControlStatus = (currentItem, newItem, isParentUpdate) => {
71
62
 
72
63
  // check all children
73
64
  if (currentItem.childItems.length && !isParentUpdate) {
65
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
74
66
  updateChildNodes(currentItem);
75
67
  }
76
68
 
77
69
  // check all parents
70
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
78
71
  updateParentNodes(currentItem);
79
72
  };
80
73
 
74
+ const setNewControlCheckedStatus = (tree, newItem) => {
75
+ const currentItem = findNodeInTree(tree, newItem);
76
+
77
+ if (currentItem) {
78
+ updateCheckedControlStatus(currentItem, newItem, false);
79
+ }
80
+
81
+ return { ...tree };
82
+ };
83
+
81
84
  const updateChildNodes = (node) => {
82
85
  if (node.childItems[0].selectionType === SelectionType.RADIO) {
86
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
83
87
  updateRadioChildNodes(node);
84
88
  } else {
89
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
85
90
  updateCheckboxChildNodes(node);
86
91
  }
87
92
  };
@@ -1,13 +1,13 @@
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 Stack from "../icons/Stack";
7
- import RvfIconButton from "../RvfIconButton";
5
+ import IconButton from "../ui/IconButton";
8
6
  import useRvfContext from "../utils/hooks/useRvfContext";
9
7
 
10
- export type RvfLayerTreeButtonProps = JSX.HTMLAttributes<HTMLButtonElement> &
8
+ import type { HTMLAttributes, PreactDOMAttributes } from "preact";
9
+
10
+ export type RvfLayerTreeButtonProps = HTMLAttributes<HTMLButtonElement> &
11
11
  PreactDOMAttributes;
12
12
 
13
13
  function RvfLayerTreeButton({ ...props }: RvfLayerTreeButtonProps) {
@@ -18,9 +18,9 @@ function RvfLayerTreeButton({ ...props }: RvfLayerTreeButtonProps) {
18
18
  }, [isLayerTreeOpen, setIsLayerTreeOpen]);
19
19
 
20
20
  return (
21
- <RvfIconButton {...props} onClick={onClick} selected={isLayerTreeOpen}>
21
+ <IconButton {...props} onClick={onClick} selected={isLayerTreeOpen}>
22
22
  <Stack />
23
- </RvfIconButton>
23
+ </IconButton>
24
24
  );
25
25
  }
26
26
 
@@ -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 RvfLineNetworkPlanLayer(props: MaplibreStyleLayerOptions) {
11
12
  const { baseLayer, map } = useMapContext();
12
13
  const { setLineNetworkPlanLayer } = useRvfContext();
@@ -1,13 +1,13 @@
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
 
6
4
  import ArrowUpRight from "../icons/ArrowUpRight";
7
5
 
6
+ import type { AnchorHTMLAttributes, PreactDOMAttributes } from "preact";
7
+
8
8
  export type RvfLinkProps = {
9
9
  theme?: "primary" | "secondary";
10
- } & JSX.AnchorHTMLAttributes<HTMLAnchorElement> &
10
+ } & AnchorHTMLAttributes<HTMLAnchorElement> &
11
11
  PreactDOMAttributes;
12
12
 
13
13
  const baseClasses =
@@ -33,6 +33,7 @@ function RvfLink({
33
33
  }: RvfLinkProps) {
34
34
  const classes = useMemo(() => {
35
35
  return twMerge(
36
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions
36
37
  `${baseClasses} ${themes[theme].classes} ${className || ""}`,
37
38
  );
38
39
  }, [className, theme]);